summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CREDITS9
-rw-r--r--Documentation/CodingStyle17
-rw-r--r--Documentation/DocBook/Makefile19
-rw-r--r--Documentation/DocBook/kernel-api.tmpl63
-rw-r--r--Documentation/DocBook/librs.tmpl16
-rw-r--r--Documentation/DocBook/man/Makefile3
-rw-r--r--Documentation/SubmittingDrivers15
-rw-r--r--Documentation/accounting/getdelays.c20
-rw-r--r--Documentation/blackfin/00-INDEX11
-rw-r--r--Documentation/blackfin/Filesystems169
-rw-r--r--Documentation/blackfin/cache-lock.txt48
-rw-r--r--Documentation/blackfin/cachefeatures.txt65
-rw-r--r--Documentation/cciss.txt13
-rw-r--r--Documentation/fb/deferred_io.txt75
-rw-r--r--Documentation/fb/s3fb.txt12
-rw-r--r--Documentation/feature-removal-schedule.txt30
-rw-r--r--Documentation/filesystems/Locking2
-rw-r--r--Documentation/filesystems/jfs.txt8
-rw-r--r--Documentation/filesystems/proc.txt38
-rw-r--r--Documentation/filesystems/vfat.txt7
-rw-r--r--Documentation/filesystems/vfs.txt23
-rw-r--r--Documentation/hwmon/coretemp36
-rw-r--r--Documentation/hwmon/max665053
-rw-r--r--Documentation/hwmon/smsc47m111
-rw-r--r--Documentation/hwmon/smsc47m1927
-rw-r--r--Documentation/hwmon/sysfs-interface7
-rw-r--r--Documentation/ia64/aliasing-test.c247
-rw-r--r--Documentation/ia64/aliasing.txt71
-rw-r--r--Documentation/ia64/err_inject.txt1068
-rw-r--r--Documentation/ioctl-number.txt3
-rw-r--r--Documentation/kbuild/modules.txt2
-rw-r--r--Documentation/kernel-parameters.txt40
-rw-r--r--Documentation/kprobes.txt34
-rw-r--r--Documentation/laptop-mode.txt2
-rw-r--r--Documentation/oops-tracing.txt3
-rw-r--r--Documentation/pcmcia/driver.txt30
-rw-r--r--Documentation/power/basic-pm-debugging.txt106
-rw-r--r--Documentation/power/drivers-testing.txt42
-rw-r--r--Documentation/power/interface.txt8
-rw-r--r--Documentation/powerpc/booting-without-of.txt4
-rw-r--r--Documentation/rtc.txt7
-rw-r--r--Documentation/sh/clk.txt32
-rw-r--r--Documentation/spi/pxa2xx2
-rw-r--r--Documentation/spi/spi-summary43
-rw-r--r--Documentation/spi/spidev307
-rw-r--r--Documentation/sysctl/vm.txt23
-rw-r--r--Documentation/sysrq.txt4
-rw-r--r--Documentation/tty.txt4
-rw-r--r--Documentation/vm/slabinfo.c943
-rw-r--r--Documentation/vm/slub.txt113
-rw-r--r--Kbuild11
-rw-r--r--MAINTAINERS69
-rw-r--r--Makefile15
-rw-r--r--arch/alpha/Kconfig.debug8
-rw-r--r--arch/alpha/boot/bootpz.c6
-rw-r--r--arch/alpha/boot/tools/objstrip.c1
-rw-r--r--arch/alpha/kernel/osf_sys.c21
-rw-r--r--arch/alpha/kernel/process.c1
-rw-r--r--arch/alpha/kernel/setup.c9
-rw-r--r--arch/alpha/kernel/signal.c1
-rw-r--r--arch/alpha/kernel/smp.c1
-rw-r--r--arch/alpha/kernel/srmcons.c4
-rw-r--r--arch/alpha/mm/fault.c1
-rw-r--r--arch/arm/Kconfig20
-rw-r--r--arch/arm/boot/compressed/head-at91rm9200.S6
-rw-r--r--arch/arm/common/sa1111.c1
-rw-r--r--arch/arm/common/via82c505.c1
-rw-r--r--arch/arm/configs/ixp4xx_defconfig2
-rw-r--r--arch/arm/configs/picotux200_defconfig1386
-rw-r--r--arch/arm/kernel/Makefile4
-rw-r--r--arch/arm/kernel/ecard.c31
-rw-r--r--arch/arm/kernel/ecard.h56
-rw-r--r--arch/arm/kernel/head.S6
-rw-r--r--arch/arm/kernel/irq.c3
-rw-r--r--arch/arm/kernel/process.c4
-rw-r--r--arch/arm/kernel/ptrace.c22
-rw-r--r--arch/arm/kernel/ptrace.h39
-rw-r--r--arch/arm/kernel/signal.c22
-rw-r--r--arch/arm/kernel/stacktrace.c73
-rw-r--r--arch/arm/kernel/stacktrace.h9
-rw-r--r--arch/arm/kernel/time.c4
-rw-r--r--arch/arm/kernel/traps.c38
-rw-r--r--arch/arm/kernel/vmlinux.lds.S3
-rw-r--r--arch/arm/lib/backtrace.S165
-rw-r--r--arch/arm/lib/getuser.S2
-rw-r--r--arch/arm/lib/putuser.S2
-rw-r--r--arch/arm/mach-aaec2000/core.c2
-rw-r--r--arch/arm/mach-at91/Kconfig7
-rw-r--r--arch/arm/mach-at91/Makefile1
-rw-r--r--arch/arm/mach-at91/at91rm9200.c19
-rw-r--r--arch/arm/mach-at91/at91rm9200_time.c2
-rw-r--r--arch/arm/mach-at91/at91sam9260.c7
-rw-r--r--arch/arm/mach-at91/at91sam9261.c19
-rw-r--r--arch/arm/mach-at91/at91sam9261_devices.c10
-rw-r--r--arch/arm/mach-at91/at91sam9263.c48
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c124
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c2
-rw-r--r--arch/arm/mach-at91/board-picotux200.c166
-rw-r--r--arch/arm/mach-at91/board-sam9260ek.c10
-rw-r--r--arch/arm/mach-at91/board-sam9261ek.c52
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c70
-rw-r--r--arch/arm/mach-clps711x/time.c2
-rw-r--r--arch/arm/mach-clps7500/core.c2
-rw-r--r--arch/arm/mach-ebsa110/core.c2
-rw-r--r--arch/arm/mach-ebsa110/io.c40
-rw-r--r--arch/arm/mach-ep93xx/clock.c5
-rw-r--r--arch/arm/mach-ep93xx/core.c2
-rw-r--r--arch/arm/mach-footbridge/dc21285-timer.c2
-rw-r--r--arch/arm/mach-footbridge/dc21285.c1
-rw-r--r--arch/arm/mach-footbridge/isa-timer.c2
-rw-r--r--arch/arm/mach-h720x/cpu-h7201.c2
-rw-r--r--arch/arm/mach-h720x/cpu-h7202.c2
-rw-r--r--arch/arm/mach-imx/time.c2
-rw-r--r--arch/arm/mach-integrator/core.c2
-rw-r--r--arch/arm/mach-integrator/pci.c1
-rw-r--r--arch/arm/mach-integrator/pci_v3.c1
-rw-r--r--arch/arm/mach-iop13xx/Makefile1
-rw-r--r--arch/arm/mach-iop13xx/io.c10
-rw-r--r--arch/arm/mach-iop13xx/iq81340mc.c5
-rw-r--r--arch/arm/mach-iop13xx/iq81340sc.c5
-rw-r--r--arch/arm/mach-iop13xx/pci.c16
-rw-r--r--arch/arm/mach-iop13xx/setup.c6
-rw-r--r--arch/arm/mach-iop13xx/tpmi.c234
-rw-r--r--arch/arm/mach-iop32x/Kconfig8
-rw-r--r--arch/arm/mach-iop32x/iq31244.c11
-rw-r--r--arch/arm/mach-iop32x/iq80321.c3
-rw-r--r--arch/arm/mach-iop33x/Kconfig8
-rw-r--r--arch/arm/mach-iop33x/iq80331.c3
-rw-r--r--arch/arm/mach-iop33x/iq80332.c3
-rw-r--r--arch/arm/mach-ixp2000/core.c24
-rw-r--r--arch/arm/mach-ixp2000/enp2611.c6
-rw-r--r--arch/arm/mach-ixp23xx/core.c2
-rw-r--r--arch/arm/mach-ixp4xx/Kconfig22
-rw-r--r--arch/arm/mach-ixp4xx/Makefile2
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c4
-rw-r--r--arch/arm/mach-ixp4xx/common.c124
-rw-r--r--arch/arm/mach-ixp4xx/dsmg600-pci.c74
-rw-r--r--arch/arm/mach-ixp4xx/dsmg600-power.c125
-rw-r--r--arch/arm/mach-ixp4xx/dsmg600-setup.c175
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-pci.c2
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-setup.c18
-rw-r--r--arch/arm/mach-lh7a40x/irq-lh7a400.c1
-rw-r--r--arch/arm/mach-lh7a40x/irq-lh7a404.c1
-rw-r--r--arch/arm/mach-lh7a40x/irq-lpd7a40x.c1
-rw-r--r--arch/arm/mach-lh7a40x/time.c2
-rw-r--r--arch/arm/mach-netx/time.c2
-rw-r--r--arch/arm/mach-ns9xxx/Kconfig15
-rw-r--r--arch/arm/mach-ns9xxx/Makefile1
-rw-r--r--arch/arm/mach-ns9xxx/board-jscc9p9360.c17
-rw-r--r--arch/arm/mach-ns9xxx/board-jscc9p9360.h13
-rw-r--r--arch/arm/mach-ns9xxx/mach-cc9p9360js.c29
-rw-r--r--arch/arm/mach-ns9xxx/time.c2
-rw-r--r--arch/arm/mach-omap1/irq.c1
-rw-r--r--arch/arm/mach-omap1/time.c206
-rw-r--r--arch/arm/mach-omap2/timer-gp.c2
-rw-r--r--arch/arm/mach-pnx4008/time.c2
-rw-r--r--arch/arm/mach-pxa/generic.c4
-rw-r--r--arch/arm/mach-pxa/irq.c73
-rw-r--r--arch/arm/mach-pxa/lpd270.c4
-rw-r--r--arch/arm/mach-pxa/lubbock.c2
-rw-r--r--arch/arm/mach-pxa/mainstone.c4
-rw-r--r--arch/arm/mach-pxa/pxa27x.c4
-rw-r--r--arch/arm/mach-pxa/ssp.c12
-rw-r--r--arch/arm/mach-pxa/time.c2
-rw-r--r--arch/arm/mach-realview/core.c2
-rw-r--r--arch/arm/mach-rpc/riscpc.c35
-rw-r--r--arch/arm/mach-s3c2410/bast-irq.c1
-rw-r--r--arch/arm/mach-s3c2410/irq.c1
-rw-r--r--arch/arm/mach-s3c2410/mach-amlm5900.c7
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c12
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c9
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c8
-rw-r--r--arch/arm/mach-s3c2410/mach-otom.c12
-rw-r--r--arch/arm/mach-s3c2410/mach-qt2410.c8
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2410.c14
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c16
-rw-r--r--arch/arm/mach-s3c2412/Kconfig9
-rw-r--r--arch/arm/mach-s3c2412/irq.c1
-rw-r--r--arch/arm/mach-s3c2412/mach-smdk2413.c7
-rw-r--r--arch/arm/mach-s3c2412/mach-vstms.c12
-rw-r--r--arch/arm/mach-s3c2440/irq.c1
-rw-r--r--arch/arm/mach-s3c2440/mach-anubis.c17
-rw-r--r--arch/arm/mach-s3c2440/mach-nexcoder.c13
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c16
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c8
-rw-r--r--arch/arm/mach-s3c2440/mach-smdk2440.c7
-rw-r--r--arch/arm/mach-s3c2443/irq.c1
-rw-r--r--arch/arm/mach-s3c2443/mach-smdk2443.c7
-rw-r--r--arch/arm/mach-sa1100/clock.c24
-rw-r--r--arch/arm/mach-sa1100/h3600.c2
-rw-r--r--arch/arm/mach-sa1100/irq.c1
-rw-r--r--arch/arm/mach-sa1100/neponset.c1
-rw-r--r--arch/arm/mach-sa1100/time.c2
-rw-r--r--arch/arm/mach-shark/core.c2
-rw-r--r--arch/arm/mach-shark/irq.c1
-rw-r--r--arch/arm/mach-versatile/core.c131
-rw-r--r--arch/arm/mach-versatile/pci.c1
-rw-r--r--arch/arm/mm/alignment.c1
-rw-r--r--arch/arm/mm/fault.c7
-rw-r--r--arch/arm/mm/init.c1
-rw-r--r--arch/arm/mm/ioremap.c80
-rw-r--r--arch/arm/mm/mm.h10
-rw-r--r--arch/arm/mm/mmap.c3
-rw-r--r--arch/arm/mm/mmu.c349
-rw-r--r--arch/arm/mm/nommu.c12
-rw-r--r--arch/arm/mm/proc-xscale.S28
-rw-r--r--arch/arm/oprofile/backtrace.c69
-rw-r--r--arch/arm/plat-iop/io.c4
-rw-r--r--arch/arm/plat-iop/pci.c140
-rw-r--r--arch/arm/plat-iop/time.c10
-rw-r--r--arch/arm/plat-omap/Kconfig1
-rw-r--r--arch/arm/plat-omap/common.c50
-rw-r--r--arch/arm/plat-omap/devices.c6
-rw-r--r--arch/arm/plat-omap/dmtimer.c2
-rw-r--r--arch/arm/plat-omap/gpio.c613
-rw-r--r--arch/arm/plat-omap/mcbsp.c15
-rw-r--r--arch/arm/plat-omap/timer32k.c141
-rw-r--r--arch/arm/plat-s3c24xx/clock.c12
-rw-r--r--arch/arm/plat-s3c24xx/cpu.c38
-rw-r--r--arch/arm/plat-s3c24xx/dma.c13
-rw-r--r--arch/arm/plat-s3c24xx/irq.c1
-rw-r--r--arch/arm/plat-s3c24xx/s3c244x-irq.c1
-rw-r--r--arch/arm/plat-s3c24xx/time.c2
-rw-r--r--arch/arm/vfp/vfpdouble.c1
-rw-r--r--arch/arm/vfp/vfpsingle.c1
-rw-r--r--arch/arm26/Kconfig3
-rw-r--r--arch/arm26/kernel/armksyms.c1
-rw-r--r--arch/arm26/kernel/ptrace.c1
-rw-r--r--arch/arm26/kernel/signal.c1
-rw-r--r--arch/arm26/mm/memc.c8
-rw-r--r--arch/avr32/kernel/kprobes.c2
-rw-r--r--arch/avr32/kernel/ptrace.c5
-rw-r--r--arch/avr32/kernel/traps.c14
-rw-r--r--arch/avr32/mm/fault.c2
-rw-r--r--arch/blackfin/Kconfig989
-rw-r--r--arch/blackfin/Makefile80
-rw-r--r--arch/blackfin/boot/Makefile27
-rw-r--r--arch/blackfin/defconfig1314
-rw-r--r--arch/blackfin/kernel/Makefile14
-rw-r--r--arch/blackfin/kernel/asm-offsets.c136
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c742
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c637
-rw-r--r--arch/blackfin/kernel/bfin_ksyms.c119
-rw-r--r--arch/blackfin/kernel/dma-mapping.c183
-rw-r--r--arch/blackfin/kernel/dualcore_test.c49
-rw-r--r--arch/blackfin/kernel/entry.S94
-rw-r--r--arch/blackfin/kernel/flat.c101
-rw-r--r--arch/blackfin/kernel/init_task.c60
-rw-r--r--arch/blackfin/kernel/irqchip.c147
-rw-r--r--arch/blackfin/kernel/module.c429
-rw-r--r--arch/blackfin/kernel/process.c394
-rw-r--r--arch/blackfin/kernel/ptrace.c430
-rw-r--r--arch/blackfin/kernel/setup.c902
-rw-r--r--arch/blackfin/kernel/signal.c356
-rw-r--r--arch/blackfin/kernel/sys_bfin.c115
-rw-r--r--arch/blackfin/kernel/time.c326
-rw-r--r--arch/blackfin/kernel/traps.c649
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S228
-rw-r--r--arch/blackfin/lib/Makefile11
-rw-r--r--arch/blackfin/lib/ashldi3.c58
-rw-r--r--arch/blackfin/lib/ashrdi3.c59
-rw-r--r--arch/blackfin/lib/checksum.c140
-rw-r--r--arch/blackfin/lib/divsi3.S216
-rw-r--r--arch/blackfin/lib/gcclib.h47
-rw-r--r--arch/blackfin/lib/ins.S69
-rw-r--r--arch/blackfin/lib/lshrdi3.c72
-rw-r--r--arch/blackfin/lib/memchr.S70
-rw-r--r--arch/blackfin/lib/memcmp.S110
-rw-r--r--arch/blackfin/lib/memcpy.S142
-rw-r--r--arch/blackfin/lib/memmove.S103
-rw-r--r--arch/blackfin/lib/memset.S109
-rw-r--r--arch/blackfin/lib/modsi3.S79
-rw-r--r--arch/blackfin/lib/muldi3.c99
-rw-r--r--arch/blackfin/lib/outs.S62
-rw-r--r--arch/blackfin/lib/smulsi3_highpart.S30
-rw-r--r--arch/blackfin/lib/strcmp.c11
-rw-r--r--arch/blackfin/lib/strcpy.c11
-rw-r--r--arch/blackfin/lib/strncmp.c11
-rw-r--r--arch/blackfin/lib/strncpy.c11
-rw-r--r--arch/blackfin/lib/udivsi3.S298
-rw-r--r--arch/blackfin/lib/umodsi3.S66
-rw-r--r--arch/blackfin/lib/umulsi3_highpart.S23
-rw-r--r--arch/blackfin/mach-bf533/Kconfig92
-rw-r--r--arch/blackfin/mach-bf533/Makefile9
-rw-r--r--arch/blackfin/mach-bf533/boards/Makefile8
-rw-r--r--arch/blackfin/mach-bf533/boards/cm_bf533.c267
-rw-r--r--arch/blackfin/mach-bf533/boards/ezkit.c224
-rw-r--r--arch/blackfin/mach-bf533/boards/generic_board.c95
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c321
-rw-r--r--arch/blackfin/mach-bf533/cpu.c161
-rw-r--r--arch/blackfin/mach-bf533/head.S774
-rw-r--r--arch/blackfin/mach-bf533/ints-priority.c65
-rw-r--r--arch/blackfin/mach-bf537/Kconfig141
-rw-r--r--arch/blackfin/mach-bf537/Makefile9
-rw-r--r--arch/blackfin/mach-bf537/boards/Makefile9
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537.c364
-rw-r--r--arch/blackfin/mach-bf537/boards/eth_mac.c51
-rw-r--r--arch/blackfin/mach-bf537/boards/generic_board.c445
-rw-r--r--arch/blackfin/mach-bf537/boards/led.S183
-rw-r--r--arch/blackfin/mach-bf537/boards/pnav10.c523
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c615
-rw-r--r--arch/blackfin/mach-bf537/cpu.c161
-rw-r--r--arch/blackfin/mach-bf537/head.S602
-rw-r--r--arch/blackfin/mach-bf537/ints-priority.c74
-rw-r--r--arch/blackfin/mach-bf561/Kconfig222
-rw-r--r--arch/blackfin/mach-bf561/Makefile9
-rw-r--r--arch/blackfin/mach-bf561/boards/Makefile7
-rw-r--r--arch/blackfin/mach-bf561/boards/cm_bf561.c289
-rw-r--r--arch/blackfin/mach-bf561/boards/ezkit.c147
-rw-r--r--arch/blackfin/mach-bf561/boards/generic_board.c82
-rw-r--r--arch/blackfin/mach-bf561/coreb.c402
-rw-r--r--arch/blackfin/mach-bf561/head.S512
-rw-r--r--arch/blackfin/mach-bf561/ints-priority.c108
-rw-r--r--arch/blackfin/mach-common/Makefile12
-rw-r--r--arch/blackfin/mach-common/cache.S253
-rw-r--r--arch/blackfin/mach-common/cacheinit.S137
-rw-r--r--arch/blackfin/mach-common/cplbhdlr.S130
-rw-r--r--arch/blackfin/mach-common/cplbinfo.c211
-rw-r--r--arch/blackfin/mach-common/cplbmgr.S607
-rw-r--r--arch/blackfin/mach-common/dpmc.S418
-rw-r--r--arch/blackfin/mach-common/entry.S1207
-rw-r--r--arch/blackfin/mach-common/interrupt.S253
-rw-r--r--arch/blackfin/mach-common/ints-priority-dc.c476
-rw-r--r--arch/blackfin/mach-common/ints-priority-sc.c577
-rw-r--r--arch/blackfin/mach-common/irqpanic.c194
-rw-r--r--arch/blackfin/mach-common/lock.S204
-rw-r--r--arch/blackfin/mach-common/pm.c181
-rw-r--r--arch/blackfin/mm/Makefile5
-rw-r--r--arch/blackfin/mm/blackfin_sram.c540
-rw-r--r--arch/blackfin/mm/blackfin_sram.h38
-rw-r--r--arch/blackfin/mm/init.c208
-rw-r--r--arch/blackfin/oprofile/Kconfig29
-rw-r--r--arch/blackfin/oprofile/Makefile14
-rw-r--r--arch/blackfin/oprofile/common.c168
-rw-r--r--arch/blackfin/oprofile/op_blackfin.h98
-rw-r--r--arch/blackfin/oprofile/op_model_bf533.c161
-rw-r--r--arch/blackfin/oprofile/timer_int.c74
-rw-r--r--arch/cris/arch-v10/kernel/ptrace.c1
-rw-r--r--arch/cris/arch-v10/kernel/signal.c1
-rw-r--r--arch/cris/arch-v32/drivers/pci/dma.c2
-rw-r--r--arch/cris/arch-v32/kernel/fasttimer.c30
-rw-r--r--arch/cris/arch-v32/kernel/ptrace.c1
-rw-r--r--arch/cris/kernel/crisksyms.c1
-rw-r--r--arch/cris/kernel/profile.c81
-rw-r--r--arch/cris/kernel/ptrace.c1
-rw-r--r--arch/frv/Kconfig4
-rw-r--r--arch/frv/kernel/irq.c1
-rw-r--r--arch/frv/kernel/ptrace.c1
-rw-r--r--arch/frv/kernel/semaphore.c2
-rw-r--r--arch/frv/kernel/signal.c1
-rw-r--r--arch/frv/kernel/sys_frv.c1
-rw-r--r--arch/frv/mm/elf-fdpic.c4
-rw-r--r--arch/frv/mm/pgalloc.c4
-rw-r--r--arch/h8300/Kconfig8
-rw-r--r--arch/h8300/Makefile2
-rw-r--r--arch/h8300/boot/Makefile12
-rw-r--r--arch/h8300/boot/compressed/Makefile37
-rw-r--r--arch/h8300/boot/compressed/head.S47
-rw-r--r--arch/h8300/boot/compressed/misc.c219
-rw-r--r--arch/h8300/kernel/Makefile6
-rw-r--r--arch/h8300/kernel/irq.c211
-rw-r--r--arch/h8300/kernel/ptrace.c1
-rw-r--r--arch/h8300/kernel/setup.c3
-rw-r--r--arch/h8300/kernel/sys_h8300.c1
-rw-r--r--arch/h8300/kernel/time.c54
-rw-r--r--arch/h8300/mm/kmap.c4
-rw-r--r--arch/h8300/platform/h8300h/Makefile2
-rw-r--r--arch/h8300/platform/h8300h/entry.S4
-rw-r--r--arch/h8300/platform/h8300h/generic/Makefile2
-rw-r--r--arch/h8300/platform/h8300h/ints_h8300h.c85
-rw-r--r--arch/h8300/platform/h8s/entry.S17
-rw-r--r--arch/i386/Kconfig4
-rw-r--r--arch/i386/kernel/Makefile1
-rw-r--r--arch/i386/kernel/alternative.c4
-rw-r--r--arch/i386/kernel/apic.c1
-rw-r--r--arch/i386/kernel/apm.c3
-rw-r--r--arch/i386/kernel/crash.c2
-rw-r--r--arch/i386/kernel/efi.c12
-rw-r--r--arch/i386/kernel/i8259.c1
-rw-r--r--arch/i386/kernel/io_apic.c1
-rw-r--r--arch/i386/kernel/ioport.c1
-rw-r--r--arch/i386/kernel/kprobes.c27
-rw-r--r--arch/i386/kernel/ldt.c1
-rw-r--r--arch/i386/kernel/legacy_serial.c67
-rw-r--r--arch/i386/kernel/mpparse.c1
-rw-r--r--arch/i386/kernel/msr.c106
-rw-r--r--arch/i386/kernel/nmi.c2
-rw-r--r--arch/i386/kernel/pci-dma.c2
-rw-r--r--arch/i386/kernel/process.c1
-rw-r--r--arch/i386/kernel/ptrace.c1
-rw-r--r--arch/i386/kernel/signal.c1
-rw-r--r--arch/i386/kernel/smp.c1
-rw-r--r--arch/i386/kernel/smpboot.c1
-rw-r--r--arch/i386/kernel/sys_i386.c1
-rw-r--r--arch/i386/kernel/syscall_table.S1
-rw-r--r--arch/i386/kernel/traps.c21
-rw-r--r--arch/i386/kernel/vm86.c1
-rw-r--r--arch/i386/lib/msr-on-cpu.c73
-rw-r--r--arch/i386/mach-default/setup.c2
-rw-r--r--arch/i386/mach-visws/setup.c2
-rw-r--r--arch/i386/mach-visws/visws_apic.c1
-rw-r--r--arch/i386/mach-voyager/setup.c2
-rw-r--r--arch/i386/mach-voyager/voyager_smp.c1
-rw-r--r--arch/i386/mach-voyager/voyager_thread.c1
-rw-r--r--arch/i386/mm/fault.c4
-rw-r--r--arch/i386/mm/hugetlbpage.c7
-rw-r--r--arch/i386/mm/init.c24
-rw-r--r--arch/i386/oprofile/nmi_int.c2
-rw-r--r--arch/i386/oprofile/nmi_timer_int.c3
-rw-r--r--arch/ia64/Kconfig10
-rw-r--r--arch/ia64/defconfig1
-rw-r--r--arch/ia64/hp/sim/boot/fw-emu.c2
-rw-r--r--arch/ia64/ia32/ia32_ldt.c1
-rw-r--r--arch/ia64/ia32/ia32_signal.c1
-rw-r--r--arch/ia64/ia32/ia32_support.c6
-rw-r--r--arch/ia64/kernel/Makefile1
-rw-r--r--arch/ia64/kernel/crash.c4
-rw-r--r--arch/ia64/kernel/efi.c56
-rw-r--r--arch/ia64/kernel/entry.S7
-rw-r--r--arch/ia64/kernel/err_inject.c293
-rw-r--r--arch/ia64/kernel/iosapic.c1
-rw-r--r--arch/ia64/kernel/irq_ia64.c1
-rw-r--r--arch/ia64/kernel/ivt.S19
-rw-r--r--arch/ia64/kernel/kprobes.c32
-rw-r--r--arch/ia64/kernel/mca.c3
-rw-r--r--arch/ia64/kernel/mca_asm.S24
-rw-r--r--arch/ia64/kernel/mca_drv.c1
-rw-r--r--arch/ia64/kernel/patch.c20
-rw-r--r--arch/ia64/kernel/perfmon.c1
-rw-r--r--arch/ia64/kernel/process.c3
-rw-r--r--arch/ia64/kernel/salinfo.c1
-rw-r--r--arch/ia64/kernel/setup.c7
-rw-r--r--arch/ia64/kernel/signal.c1
-rw-r--r--arch/ia64/kernel/smpboot.c1
-rw-r--r--arch/ia64/kernel/sys_ia64.c8
-rw-r--r--arch/ia64/kernel/time.c2
-rw-r--r--arch/ia64/kernel/traps.c18
-rw-r--r--arch/ia64/kernel/unaligned.c1
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S7
-rw-r--r--arch/ia64/mm/discontig.c2
-rw-r--r--arch/ia64/mm/fault.c3
-rw-r--r--arch/ia64/mm/hugetlbpage.c9
-rw-r--r--arch/ia64/mm/init.c13
-rw-r--r--arch/ia64/mm/ioremap.c78
-rw-r--r--arch/ia64/pci/pci.c3
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c4
-rw-r--r--arch/m32r/kernel/m32r_ksyms.c1
-rw-r--r--arch/m32r/kernel/signal.c1
-rw-r--r--arch/m32r/kernel/smpboot.c1
-rw-r--r--arch/m32r/kernel/sys_m32r.c1
-rw-r--r--arch/m32r/mm/fault-nommu.c1
-rw-r--r--arch/m32r/mm/fault.c1
-rw-r--r--arch/m68k/amiga/amiints.c2
-rw-r--r--arch/m68k/amiga/cia.c4
-rw-r--r--arch/m68k/apollo/dn_ints.c2
-rw-r--r--arch/m68k/atari/ataints.c2
-rw-r--r--arch/m68k/atari/atasound.h33
-rw-r--r--arch/m68k/kernel/ints.c4
-rw-r--r--arch/m68k/kernel/ptrace.c1
-rw-r--r--arch/m68k/mac/macints.c2
-rw-r--r--arch/m68k/mvme16x/rtc.c1
-rw-r--r--arch/m68k/q40/q40ints.c2
-rw-r--r--arch/m68k/sun3/sun3ints.c2
-rw-r--r--arch/m68knommu/kernel/ptrace.c1
-rw-r--r--arch/m68knommu/kernel/sys_m68k.c1
-rw-r--r--arch/mips/Kconfig5
-rw-r--r--arch/mips/configs/rbhma4500_defconfig31
-rw-r--r--arch/mips/kernel/early_printk.c5
-rw-r--r--arch/mips/kernel/irixelf.c1
-rw-r--r--arch/mips/kernel/irixioctl.c1
-rw-r--r--arch/mips/kernel/irixsig.c1
-rw-r--r--arch/mips/kernel/ptrace.c1
-rw-r--r--arch/mips/kernel/signal.c1
-rw-r--r--arch/mips/kernel/signal32.c1
-rw-r--r--arch/mips/kernel/signal_n32.c1
-rw-r--r--arch/mips/kernel/stacktrace.c22
-rw-r--r--arch/mips/kernel/syscall.c1
-rw-r--r--arch/mips/kernel/traps.c1
-rw-r--r--arch/mips/kernel/unaligned.c1
-rw-r--r--arch/mips/math-emu/dsemul.c1
-rw-r--r--arch/mips/mm/fault.c1
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_serial.c165
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c1
-rw-r--r--arch/mips/sni/irq.c2
-rw-r--r--arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c19
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/setup.c20
-rw-r--r--arch/parisc/hpux/fs.c1
-rw-r--r--arch/parisc/hpux/ioctl.c1
-rw-r--r--arch/parisc/kernel/irq.c2
-rw-r--r--arch/parisc/kernel/ptrace.c1
-rw-r--r--arch/parisc/kernel/signal.c1
-rw-r--r--arch/parisc/kernel/signal32.c1
-rw-r--r--arch/parisc/kernel/sys_parisc.c6
-rw-r--r--arch/parisc/kernel/traps.c1
-rw-r--r--arch/parisc/kernel/unwind.c5
-rw-r--r--arch/powerpc/Kconfig32
-rw-r--r--arch/powerpc/Kconfig.debug22
-rw-r--r--arch/powerpc/Makefile2
-rw-r--r--arch/powerpc/boot/44x.c40
-rw-r--r--arch/powerpc/boot/44x.h16
-rw-r--r--arch/powerpc/boot/Makefile49
-rw-r--r--arch/powerpc/boot/cuboot-ebony.c42
-rw-r--r--arch/powerpc/boot/dcr.h87
-rw-r--r--arch/powerpc/boot/dts/ebony.dts307
-rw-r--r--arch/powerpc/boot/dts/holly.dts198
-rw-r--r--arch/powerpc/boot/dts/lite5200.dts11
-rw-r--r--arch/powerpc/boot/dts/lite5200b.dts11
-rw-r--r--arch/powerpc/boot/dts/mpc832x_mds.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc832x_rdb.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc836x_mds.dts4
-rw-r--r--arch/powerpc/boot/dts/mpc8568mds.dts6
-rw-r--r--arch/powerpc/boot/ebony.c129
-rw-r--r--arch/powerpc/boot/holly.c38
-rw-r--r--arch/powerpc/boot/mktree.c10
-rw-r--r--arch/powerpc/boot/treeboot-ebony.c34
-rwxr-xr-xarch/powerpc/boot/wrapper36
-rw-r--r--arch/powerpc/configs/ebony_defconfig905
-rw-r--r--arch/powerpc/configs/holly_defconfig1070
-rw-r--r--arch/powerpc/configs/mpc832x_mds_defconfig67
-rw-r--r--arch/powerpc/configs/mpc832x_rdb_defconfig28
-rw-r--r--arch/powerpc/configs/mpc836x_mds_defconfig42
-rw-r--r--arch/powerpc/configs/ps3_defconfig329
-rw-r--r--arch/powerpc/kernel/Makefile4
-rw-r--r--arch/powerpc/kernel/asm-offsets.c4
-rw-r--r--arch/powerpc/kernel/head_44x.S48
-rw-r--r--arch/powerpc/kernel/idle.c5
-rw-r--r--arch/powerpc/kernel/idle_power4.S21
-rw-r--r--arch/powerpc/kernel/irq.c38
-rw-r--r--arch/powerpc/kernel/kprobes.c41
-rw-r--r--arch/powerpc/kernel/legacy_serial.c17
-rw-r--r--arch/powerpc/kernel/msi.c38
-rw-r--r--arch/powerpc/kernel/of_device.c7
-rw-r--r--arch/powerpc/kernel/of_platform.c1
-rw-r--r--arch/powerpc/kernel/pci_32.c2
-rw-r--r--arch/powerpc/kernel/pci_64.c9
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c1
-rw-r--r--arch/powerpc/kernel/process.c1
-rw-r--r--arch/powerpc/kernel/prom_init.c12
-rw-r--r--arch/powerpc/kernel/prom_parse.c25
-rw-r--r--arch/powerpc/kernel/ptrace.c1
-rw-r--r--arch/powerpc/kernel/signal_32.c1
-rw-r--r--arch/powerpc/kernel/signal_64.c1
-rw-r--r--arch/powerpc/kernel/smp.c73
-rw-r--r--arch/powerpc/kernel/swsusp.c43
-rw-r--r--arch/powerpc/kernel/swsusp_64.c24
-rw-r--r--arch/powerpc/kernel/swsusp_asm64.S228
-rw-r--r--arch/powerpc/kernel/syscalls.c1
-rw-r--r--arch/powerpc/kernel/sysfs.c2
-rw-r--r--arch/powerpc/kernel/traps.c16
-rw-r--r--arch/powerpc/kernel/udbg.c22
-rw-r--r--arch/powerpc/kernel/udbg_16550.c23
-rw-r--r--arch/powerpc/kernel/vdso.c1
-rw-r--r--arch/powerpc/kernel/vio.c2
-rw-r--r--arch/powerpc/lib/dma-noncoherent.c4
-rw-r--r--arch/powerpc/mm/44x_mmu.c82
-rw-r--r--arch/powerpc/mm/fault.c44
-rw-r--r--arch/powerpc/mm/hash_native_64.c84
-rw-r--r--arch/powerpc/mm/hash_utils_64.c2
-rw-r--r--arch/powerpc/mm/hugetlbpage.c25
-rw-r--r--arch/powerpc/mm/init_64.c6
-rw-r--r--arch/powerpc/mm/mem.c1
-rw-r--r--arch/powerpc/mm/mmu_decl.h3
-rw-r--r--arch/powerpc/mm/pgtable_32.c28
-rw-r--r--arch/powerpc/mm/stab.c2
-rw-r--r--arch/powerpc/platforms/44x/44x.h8
-rw-r--r--arch/powerpc/platforms/44x/Kconfig56
-rw-r--r--arch/powerpc/platforms/44x/Makefile2
-rw-r--r--arch/powerpc/platforms/44x/ebony.c73
-rw-r--r--arch/powerpc/platforms/44x/misc_44x.S57
-rw-r--r--arch/powerpc/platforms/52xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/52xx/Makefile2
-rw-r--r--arch/powerpc/platforms/52xx/efika.c15
-rw-r--r--arch/powerpc/platforms/52xx/lite5200.c28
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pm.c191
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_sleep.S154
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.c1
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_rdb.c1
-rw-r--r--arch/powerpc/platforms/83xx/mpc836x_mds.c1
-rw-r--r--arch/powerpc/platforms/85xx/mpc8544_ds.c2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c1
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c2
-rw-r--r--arch/powerpc/platforms/Kconfig1
-rw-r--r--arch/powerpc/platforms/Makefile3
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c6
-rw-r--r--arch/powerpc/platforms/cell/setup.c2
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c4
-rw-r--r--arch/powerpc/platforms/cell/spufs/backing_ops.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/hw_ops.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c3
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c1
-rw-r--r--arch/powerpc/platforms/chrp/pci.c2
-rw-r--r--arch/powerpc/platforms/chrp/setup.c2
-rw-r--r--arch/powerpc/platforms/chrp/smp.c1
-rw-r--r--arch/powerpc/platforms/embedded6xx/Kconfig14
-rw-r--r--arch/powerpc/platforms/embedded6xx/Makefile1
-rw-r--r--arch/powerpc/platforms/embedded6xx/holly.c317
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c21
-rw-r--r--arch/powerpc/platforms/iseries/smp.c1
-rw-r--r--arch/powerpc/platforms/iseries/viopath.c1
-rw-r--r--arch/powerpc/platforms/maple/pci.c12
-rw-r--r--arch/powerpc/platforms/maple/setup.c2
-rw-r--r--arch/powerpc/platforms/pasemi/cpufreq.c4
-rw-r--r--arch/powerpc/platforms/pasemi/pci.c13
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c8
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_64.c8
-rw-r--r--arch/powerpc/platforms/powermac/feature.c26
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c2
-rw-r--r--arch/powerpc/platforms/powermac/nvram.c4
-rw-r--r--arch/powerpc/platforms/powermac/pci.c30
-rw-r--r--arch/powerpc/platforms/powermac/pic.c2
-rw-r--r--arch/powerpc/platforms/powermac/setup.c121
-rw-r--r--arch/powerpc/platforms/powermac/smp.c19
-rw-r--r--arch/powerpc/platforms/ps3/htab.c3
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c234
-rw-r--r--arch/powerpc/platforms/ps3/mm.c1
-rw-r--r--arch/powerpc/platforms/ps3/setup.c7
-rw-r--r--arch/powerpc/platforms/ps3/smp.c6
-rw-r--r--arch/powerpc/platforms/ps3/spu.c18
-rw-r--r--arch/powerpc/platforms/pseries/Makefile1
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c30
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c6
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c4
-rw-r--r--arch/powerpc/platforms/pseries/msi.c270
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c1
-rw-r--r--arch/powerpc/platforms/pseries/setup.c2
-rw-r--r--arch/powerpc/platforms/pseries/xics.c4
-rw-r--r--arch/powerpc/sysdev/Makefile5
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c46
-rw-r--r--arch/powerpc/sysdev/mpic.c162
-rw-r--r--arch/powerpc/sysdev/mpic.h38
-rw-r--r--arch/powerpc/sysdev/mpic_msi.c183
-rw-r--r--arch/powerpc/sysdev/mpic_u3msi.c186
-rw-r--r--arch/powerpc/sysdev/rom.c32
-rw-r--r--arch/powerpc/sysdev/tsi108_dev.c7
-rw-r--r--arch/powerpc/sysdev/tsi108_pci.c12
-rw-r--r--arch/powerpc/sysdev/uic.c2
-rw-r--r--arch/powerpc/xmon/xmon.c3
-rw-r--r--arch/ppc/kernel/ppc_htab.c1
-rw-r--r--arch/ppc/kernel/smp.c1
-rw-r--r--arch/ppc/syslib/ppc4xx_sgdma.c2
-rw-r--r--arch/ppc/syslib/virtex_devices.h7
-rw-r--r--arch/s390/Kconfig3
-rw-r--r--arch/s390/kernel/compat_signal.c1
-rw-r--r--arch/s390/kernel/dis.c2
-rw-r--r--arch/s390/kernel/kprobes.c27
-rw-r--r--arch/s390/kernel/process.c1
-rw-r--r--arch/s390/kernel/signal.c1
-rw-r--r--arch/s390/kernel/smp.c1
-rw-r--r--arch/s390/kernel/stacktrace.c18
-rw-r--r--arch/s390/kernel/sys_s390.c1
-rw-r--r--arch/s390/kernel/time.c1
-rw-r--r--arch/s390/kernel/traps.c17
-rw-r--r--arch/s390/mm/fault.c2
-rw-r--r--arch/sh/Kconfig97
-rw-r--r--arch/sh/Kconfig.debug20
-rw-r--r--arch/sh/Makefile6
-rw-r--r--arch/sh/boards/hp6xx/Makefile4
-rw-r--r--arch/sh/boards/hp6xx/setup.c67
-rw-r--r--arch/sh/boards/landisk/Makefile2
-rw-r--r--arch/sh/boards/landisk/gio.c167
-rw-r--r--arch/sh/boards/landisk/io.c250
-rw-r--r--arch/sh/boards/landisk/irq.c83
-rw-r--r--arch/sh/boards/landisk/landisk_pwb.c346
-rw-r--r--arch/sh/boards/landisk/psw.c143
-rw-r--r--arch/sh/boards/landisk/rtc.c91
-rw-r--r--arch/sh/boards/landisk/setup.c163
-rw-r--r--arch/sh/boards/lboxre2/Makefile5
-rw-r--r--arch/sh/boards/lboxre2/irq.c31
-rw-r--r--arch/sh/boards/lboxre2/setup.c85
-rw-r--r--arch/sh/boards/renesas/r7780rp/Kconfig18
-rw-r--r--arch/sh/boards/renesas/r7780rp/Makefile6
-rw-r--r--arch/sh/boards/renesas/r7780rp/irq-r7780rp.c21
-rw-r--r--arch/sh/boards/renesas/r7780rp/irq-r7785rp.c29
-rw-r--r--arch/sh/boards/renesas/r7780rp/irq.c25
-rw-r--r--arch/sh/boards/renesas/r7780rp/setup.c78
-rw-r--r--arch/sh/boards/se/770x/io.c2
-rw-r--r--arch/sh/boards/se/770x/irq.c57
-rw-r--r--arch/sh/boards/se/770x/setup.c30
-rw-r--r--arch/sh/boards/se/7722/Makefile10
-rw-r--r--arch/sh/boards/se/7722/irq.c101
-rw-r--r--arch/sh/boards/se/7722/setup.c148
-rw-r--r--arch/sh/boards/se/7751/setup.c148
-rw-r--r--arch/sh/boards/se/7780/Makefile10
-rw-r--r--arch/sh/boards/se/7780/irq.c89
-rw-r--r--arch/sh/boards/se/7780/setup.c122
-rw-r--r--arch/sh/configs/lboxre2_defconfig1271
-rw-r--r--arch/sh/configs/r7780rp_defconfig108
-rw-r--r--arch/sh/configs/r7785rp_defconfig1334
-rw-r--r--arch/sh/configs/se7705_defconfig106
-rw-r--r--arch/sh/configs/se7712_defconfig1088
-rw-r--r--arch/sh/configs/se7722_defconfig980
-rw-r--r--arch/sh/configs/se7780_defconfig1309
-rw-r--r--arch/sh/drivers/Kconfig10
-rw-r--r--arch/sh/drivers/heartbeat.c13
-rw-r--r--arch/sh/drivers/pci/Makefile5
-rw-r--r--arch/sh/drivers/pci/fixups-lboxre2.c41
-rw-r--r--arch/sh/drivers/pci/fixups-se7780.c60
-rw-r--r--arch/sh/drivers/pci/ops-landisk.c4
-rw-r--r--arch/sh/drivers/pci/ops-lboxre2.c63
-rw-r--r--arch/sh/drivers/pci/ops-r7780rp.c27
-rw-r--r--arch/sh/drivers/pci/ops-se7780.c96
-rw-r--r--arch/sh/drivers/pci/ops-sh4.c6
-rw-r--r--arch/sh/drivers/pci/pci-sh4.h2
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.c15
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c45
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.h19
-rw-r--r--arch/sh/drivers/pci/pci-st40.c1
-rw-r--r--arch/sh/kernel/Makefile1
-rw-r--r--arch/sh/kernel/cf-enabler.c28
-rw-r--r--arch/sh/kernel/cpu/clock.c102
-rw-r--r--arch/sh/kernel/cpu/init.c19
-rw-r--r--arch/sh/kernel/cpu/irq/Makefile2
-rw-r--r--arch/sh/kernel/cpu/irq/intc2.c3
-rw-r--r--arch/sh/kernel/cpu/irq/pint.c56
-rw-r--r--arch/sh/kernel/cpu/sh3/Makefile1
-rw-r--r--arch/sh/kernel/cpu/sh3/probe.c3
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c54
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7709.c29
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7710.c60
-rw-r--r--arch/sh/kernel/cpu/sh4/clock-sh4-202.c3
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c8
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile4
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7722.c600
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7785.c162
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c103
-rw-r--r--arch/sh/kernel/crash_dump.c46
-rw-r--r--arch/sh/kernel/early_printk.c18
-rw-r--r--arch/sh/kernel/irq.c5
-rw-r--r--arch/sh/kernel/kgdb_stub.c490
-rw-r--r--arch/sh/kernel/machine_kexec.c29
-rw-r--r--arch/sh/kernel/process.c14
-rw-r--r--arch/sh/kernel/ptrace.c1
-rw-r--r--arch/sh/kernel/setup.c267
-rw-r--r--arch/sh/kernel/sh_ksyms.c2
-rw-r--r--arch/sh/kernel/signal.c1
-rw-r--r--arch/sh/kernel/stacktrace.c9
-rw-r--r--arch/sh/kernel/sys_sh.c1
-rw-r--r--arch/sh/kernel/timers/timer-cmt.c2
-rw-r--r--arch/sh/kernel/timers/timer-mtu2.c2
-rw-r--r--arch/sh/kernel/timers/timer-tmu.c6
-rw-r--r--arch/sh/kernel/traps.c73
-rw-r--r--arch/sh/kernel/vmlinux.lds.S47
-rw-r--r--arch/sh/lib/Makefile4
-rw-r--r--arch/sh/lib/udivdi3.c16
-rw-r--r--arch/sh/mm/Kconfig20
-rw-r--r--arch/sh/mm/fault-nommu.c1
-rw-r--r--arch/sh/mm/fault.c39
-rw-r--r--arch/sh/mm/hugetlbpage.c1
-rw-r--r--arch/sh/mm/init.c197
-rw-r--r--arch/sh/mm/pmb.c6
-rw-r--r--arch/sh/tools/mach-types2
-rw-r--r--arch/sh64/kernel/early_printk.c8
-rw-r--r--arch/sh64/kernel/irq.c1
-rw-r--r--arch/sh64/kernel/pci_sh5.c1
-rw-r--r--arch/sh64/kernel/sh_ksyms.c1
-rw-r--r--arch/sh64/kernel/signal.c1
-rw-r--r--arch/sh64/kernel/sys_sh64.c1
-rw-r--r--arch/sh64/kernel/traps.c1
-rw-r--r--arch/sh64/kernel/unwind.c6
-rw-r--r--arch/sh64/mm/fault.c1
-rw-r--r--arch/sh64/mm/hugetlbpage.c1
-rw-r--r--arch/sh64/mm/tlbmiss.c1
-rw-r--r--arch/sparc/kernel/head.S2
-rw-r--r--arch/sparc/kernel/irq.c1
-rw-r--r--arch/sparc/kernel/process.c1
-rw-r--r--arch/sparc/kernel/setup.c2
-rw-r--r--arch/sparc/kernel/signal.c1
-rw-r--r--arch/sparc/kernel/smp.c1
-rw-r--r--arch/sparc/kernel/sun4d_irq.c1
-rw-r--r--arch/sparc/kernel/sun4d_smp.c1
-rw-r--r--arch/sparc/kernel/sun4m_smp.c3
-rw-r--r--arch/sparc/kernel/sunos_ioctl.c1
-rw-r--r--arch/sparc/kernel/sys_solaris.c1
-rw-r--r--arch/sparc/kernel/traps.c2
-rw-r--r--arch/sparc/lib/bitext.c1
-rw-r--r--arch/sparc/mm/fault.c3
-rw-r--r--arch/sparc/mm/srmmu.c2
-rw-r--r--arch/sparc64/Kconfig4
-rw-r--r--arch/sparc64/defconfig71
-rw-r--r--arch/sparc64/kernel/Makefile2
-rw-r--r--arch/sparc64/kernel/central.c6
-rw-r--r--arch/sparc64/kernel/irq.c16
-rw-r--r--arch/sparc64/kernel/kprobes.c2
-rw-r--r--arch/sparc64/kernel/pci.c38
-rw-r--r--arch/sparc64/kernel/pci_fire.c418
-rw-r--r--arch/sparc64/kernel/pci_iommu.c22
-rw-r--r--arch/sparc64/kernel/process.c1
-rw-r--r--arch/sparc64/kernel/prom.c112
-rw-r--r--arch/sparc64/kernel/signal.c1
-rw-r--r--arch/sparc64/kernel/signal32.c1
-rw-r--r--arch/sparc64/kernel/smp.c1
-rw-r--r--arch/sparc64/kernel/stacktrace.c20
-rw-r--r--arch/sparc64/kernel/sunos_ioctl32.c1
-rw-r--r--arch/sparc64/kernel/sys_sparc.c1
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c14
-rw-r--r--arch/sparc64/kernel/traps.c16
-rw-r--r--arch/sparc64/kernel/unaligned.c1
-rw-r--r--arch/sparc64/mm/fault.c3
-rw-r--r--arch/sparc64/mm/hugetlbpage.c7
-rw-r--r--arch/sparc64/mm/init.c24
-rw-r--r--arch/sparc64/mm/tsb.c5
-rw-r--r--arch/sparc64/solaris/ipc.c1
-rw-r--r--arch/sparc64/solaris/misc.c1
-rw-r--r--arch/sparc64/solaris/signal.c1
-rw-r--r--arch/sparc64/solaris/socket.c1
-rw-r--r--arch/sparc64/solaris/socksys.c1
-rw-r--r--arch/um/drivers/chan_kern.c1
-rw-r--r--arch/um/drivers/chan_user.c14
-rw-r--r--arch/um/drivers/cow_sys.h18
-rw-r--r--arch/um/drivers/daemon_user.c31
-rw-r--r--arch/um/drivers/fd.c1
-rw-r--r--arch/um/drivers/harddog_user.c1
-rw-r--r--arch/um/drivers/line.c1
-rw-r--r--arch/um/drivers/mcast_user.c16
-rw-r--r--arch/um/drivers/mconsole_kern.c1
-rw-r--r--arch/um/drivers/mconsole_user.c1
-rw-r--r--arch/um/drivers/mmapper_kern.c1
-rw-r--r--arch/um/drivers/net_kern.c165
-rw-r--r--arch/um/drivers/net_user.c4
-rw-r--r--arch/um/drivers/pcap_kern.c27
-rw-r--r--arch/um/drivers/pcap_user.c61
-rw-r--r--arch/um/drivers/port_user.c1
-rw-r--r--arch/um/drivers/pty.c2
-rw-r--r--arch/um/drivers/slip_user.c7
-rw-r--r--arch/um/drivers/slirp_user.c4
-rw-r--r--arch/um/drivers/ssl.c5
-rw-r--r--arch/um/drivers/stdio_console.c5
-rw-r--r--arch/um/drivers/tty.c1
-rw-r--r--arch/um/drivers/ubd_kern.c351
-rw-r--r--arch/um/drivers/ubd_user.c16
-rw-r--r--arch/um/drivers/xterm.c1
-rw-r--r--arch/um/include/arch.h15
-rw-r--r--arch/um/include/as-layout.h35
-rw-r--r--arch/um/include/common-offsets.h2
-rw-r--r--arch/um/include/kern_util.h13
-rw-r--r--arch/um/include/net_kern.h2
-rw-r--r--arch/um/include/net_user.h2
-rw-r--r--arch/um/include/os.h17
-rw-r--r--arch/um/include/skas/mode_kern_skas.h2
-rw-r--r--arch/um/include/tlb.h8
-rw-r--r--arch/um/include/tt/uaccess-tt.h2
-rw-r--r--arch/um/include/um_malloc.h1
-rw-r--r--arch/um/include/user.h29
-rw-r--r--arch/um/include/user_util.h69
-rw-r--r--arch/um/kernel/exec.c2
-rw-r--r--arch/um/kernel/init_task.c1
-rw-r--r--arch/um/kernel/initrd.c33
-rw-r--r--arch/um/kernel/irq.c16
-rw-r--r--arch/um/kernel/ksyms.c2
-rw-r--r--arch/um/kernel/mem.c4
-rw-r--r--arch/um/kernel/physmem.c230
-rw-r--r--arch/um/kernel/process.c125
-rw-r--r--arch/um/kernel/reboot.c1
-rw-r--r--arch/um/kernel/signal.c1
-rw-r--r--arch/um/kernel/skas/exec.c12
-rw-r--r--arch/um/kernel/skas/process.c2
-rw-r--r--arch/um/kernel/skas/tlb.c87
-rw-r--r--arch/um/kernel/smp.c28
-rw-r--r--arch/um/kernel/syscall.c1
-rw-r--r--arch/um/kernel/sysrq.c1
-rw-r--r--arch/um/kernel/time.c19
-rw-r--r--arch/um/kernel/tlb.c226
-rw-r--r--arch/um/kernel/trap.c50
-rw-r--r--arch/um/kernel/tt/exec_kern.c1
-rw-r--r--arch/um/kernel/tt/exec_user.c1
-rw-r--r--arch/um/kernel/tt/gdb.c3
-rw-r--r--arch/um/kernel/tt/include/mode_kern-tt.h52
-rw-r--r--arch/um/kernel/tt/mem.c1
-rw-r--r--arch/um/kernel/tt/mem_user.c1
-rw-r--r--arch/um/kernel/tt/process_kern.c4
-rw-r--r--arch/um/kernel/tt/ptproxy/proxy.c6
-rw-r--r--arch/um/kernel/tt/ptproxy/ptrace.c1
-rw-r--r--arch/um/kernel/tt/ptproxy/sysdep.c1
-rw-r--r--arch/um/kernel/tt/ptproxy/wait.c1
-rw-r--r--arch/um/kernel/tt/syscall_user.c1
-rw-r--r--arch/um/kernel/tt/tlb.c1
-rw-r--r--arch/um/kernel/tt/tracer.c1
-rw-r--r--arch/um/kernel/tt/trap_user.c1
-rw-r--r--arch/um/kernel/tt/uaccess_user.c1
-rw-r--r--arch/um/kernel/um_arch.c84
-rw-r--r--arch/um/os-Linux/aio.c61
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c66
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c44
-rw-r--r--arch/um/os-Linux/file.c47
-rw-r--r--arch/um/os-Linux/helper.c31
-rw-r--r--arch/um/os-Linux/irq.c1
-rw-r--r--arch/um/os-Linux/main.c23
-rw-r--r--arch/um/os-Linux/mem.c15
-rw-r--r--arch/um/os-Linux/process.c45
-rw-r--r--arch/um/os-Linux/sigio.c164
-rw-r--r--arch/um/os-Linux/signal.c1
-rw-r--r--arch/um/os-Linux/skas/mem.c75
-rw-r--r--arch/um/os-Linux/skas/process.c190
-rw-r--r--arch/um/os-Linux/skas/trap.c49
-rw-r--r--arch/um/os-Linux/start_up.c173
-rw-r--r--arch/um/os-Linux/sys-i386/tls.c2
-rw-r--r--arch/um/os-Linux/time.c1
-rw-r--r--arch/um/os-Linux/trap.c1
-rw-r--r--arch/um/os-Linux/tt.c4
-rw-r--r--arch/um/os-Linux/tty_log.c28
-rw-r--r--arch/um/os-Linux/util.c26
-rw-r--r--arch/um/sys-i386/bugs.c78
-rw-r--r--arch/um/sys-i386/fault.c18
-rw-r--r--arch/um/sys-i386/ptrace_user.c17
-rw-r--r--arch/um/sys-i386/signal.c84
-rw-r--r--arch/um/sys-i386/tls.c11
-rw-r--r--arch/um/sys-i386/user-offsets.c10
-rw-r--r--arch/um/sys-ppc/sigcontext.c1
-rw-r--r--arch/um/sys-x86_64/bugs.c104
-rw-r--r--arch/um/sys-x86_64/fault.c30
-rw-r--r--arch/um/sys-x86_64/signal.c32
-rw-r--r--arch/um/sys-x86_64/user-offsets.c6
-rw-r--r--arch/v850/Kconfig4
-rw-r--r--arch/v850/kernel/process.c1
-rw-r--r--arch/v850/kernel/ptrace.c1
-rw-r--r--arch/v850/kernel/signal.c1
-rw-r--r--arch/v850/kernel/syscalls.c1
-rw-r--r--arch/v850/kernel/time.c75
-rw-r--r--arch/x86_64/ia32/ia32_signal.c1
-rw-r--r--arch/x86_64/ia32/ia32entry.S3
-rw-r--r--arch/x86_64/kernel/Makefile2
-rw-r--r--arch/x86_64/kernel/apic.c1
-rw-r--r--arch/x86_64/kernel/crash.c2
-rw-r--r--arch/x86_64/kernel/e820.c26
-rw-r--r--arch/x86_64/kernel/early_printk.c20
-rw-r--r--arch/x86_64/kernel/i8259.c1
-rw-r--r--arch/x86_64/kernel/io_apic.c1
-rw-r--r--arch/x86_64/kernel/ioport.c1
-rw-r--r--arch/x86_64/kernel/kprobes.c29
-rw-r--r--arch/x86_64/kernel/ldt.c1
-rw-r--r--arch/x86_64/kernel/machine_kexec.c16
-rw-r--r--arch/x86_64/kernel/mce.c2
-rw-r--r--arch/x86_64/kernel/mpparse.c1
-rw-r--r--arch/x86_64/kernel/nmi.c2
-rw-r--r--arch/x86_64/kernel/pci-gart.c2
-rw-r--r--arch/x86_64/kernel/process.c2
-rw-r--r--arch/x86_64/kernel/ptrace.c1
-rw-r--r--arch/x86_64/kernel/reboot.c2
-rw-r--r--arch/x86_64/kernel/setup.c9
-rw-r--r--arch/x86_64/kernel/signal.c1
-rw-r--r--arch/x86_64/kernel/smp.c3
-rw-r--r--arch/x86_64/kernel/smpboot.c3
-rw-r--r--arch/x86_64/kernel/stacktrace.c8
-rw-r--r--arch/x86_64/kernel/sys_x86_64.c4
-rw-r--r--arch/x86_64/kernel/time.c5
-rw-r--r--arch/x86_64/kernel/traps.c20
-rw-r--r--arch/x86_64/mm/fault.c4
-rw-r--r--arch/x86_64/mm/init.c37
-rw-r--r--arch/x86_64/mm/ioremap.c9
-rw-r--r--arch/x86_64/mm/pageattr.c16
-rw-r--r--arch/xtensa/kernel/process.c1
-rw-r--r--arch/xtensa/kernel/ptrace.c1
-rw-r--r--arch/xtensa/kernel/signal.c1
-rw-r--r--arch/xtensa/platform-iss/network.c2
-rw-r--r--block/as-iosched.c6
-rw-r--r--block/cfq-iosched.c6
-rw-r--r--block/ioctl.c4
-rw-r--r--block/ll_rw_blk.c1
-rw-r--r--drivers/acpi/glue.c46
-rw-r--r--drivers/acpi/numa.c4
-rw-r--r--drivers/acpi/osl.c1
-rw-r--r--drivers/acpi/scan.c2
-rw-r--r--drivers/acpi/sleep/proc.c21
-rw-r--r--drivers/ata/Kconfig10
-rw-r--r--drivers/ata/Makefile1
-rw-r--r--drivers/ata/ahci.c28
-rw-r--r--drivers/ata/ata_piix.c6
-rw-r--r--drivers/ata/libata-core.c225
-rw-r--r--drivers/ata/libata-eh.c62
-rw-r--r--drivers/ata/pata_amd.c11
-rw-r--r--drivers/ata/pata_artop.c11
-rw-r--r--drivers/ata/pata_atiixp.c4
-rw-r--r--drivers/ata/pata_cs5535.c1
-rw-r--r--drivers/ata/pata_efar.c5
-rw-r--r--drivers/ata/pata_hpt366.c4
-rw-r--r--drivers/ata/pata_hpt37x.c9
-rw-r--r--drivers/ata/pata_hpt3x2n.c5
-rw-r--r--drivers/ata/pata_icside.c686
-rw-r--r--drivers/ata/pata_it8213.c6
-rw-r--r--drivers/ata/pata_jmicron.c7
-rw-r--r--drivers/ata/pata_marvell.c7
-rw-r--r--drivers/ata/pata_mpiix.c5
-rw-r--r--drivers/ata/pata_ns87410.c6
-rw-r--r--drivers/ata/pata_oldpiix.c6
-rw-r--r--drivers/ata/pata_opti.c6
-rw-r--r--drivers/ata/pata_optidma.c5
-rw-r--r--drivers/ata/pata_pdc2027x.c5
-rw-r--r--drivers/ata/pata_serverworks.c4
-rw-r--r--drivers/ata/pata_sil680.c6
-rw-r--r--drivers/ata/pata_sis.c8
-rw-r--r--drivers/ata/pata_sl82c105.c5
-rw-r--r--drivers/ata/pata_triflex.c6
-rw-r--r--drivers/ata/pata_via.c5
-rw-r--r--drivers/ata/sata_inic162x.c15
-rw-r--r--drivers/ata/sata_nv.c5
-rw-r--r--drivers/ata/sata_sil24.c10
-rw-r--r--drivers/ata/sata_svw.c2
-rw-r--r--drivers/ata/sata_via.c5
-rw-r--r--drivers/base/Makefile4
-rw-r--r--drivers/base/platform.c18
-rw-r--r--drivers/block/acsi_slm.c1
-rw-r--r--drivers/block/amiflop.c2
-rw-r--r--drivers/block/cciss.c288
-rw-r--r--drivers/block/cciss_scsi.c1
-rw-r--r--drivers/block/floppy.c7
-rw-r--r--drivers/block/loop.c188
-rw-r--r--drivers/block/rd.c2
-rw-r--r--drivers/block/umem.c1
-rw-r--r--drivers/bluetooth/hci_usb.c6
-rw-r--r--drivers/cdrom/cdrom.c2
-rw-r--r--drivers/char/Kconfig12
-rw-r--r--drivers/char/Makefile2
-rw-r--r--drivers/char/agp/uninorth-agp.c2
-rw-r--r--drivers/char/amiserial.c4
-rw-r--r--drivers/char/briq_panel.c2
-rw-r--r--drivers/char/consolemap.c6
-rw-r--r--drivers/char/cs5535_gpio.c1
-rw-r--r--drivers/char/cyclades.c2581
-rw-r--r--drivers/char/digi.h71
-rw-r--r--drivers/char/drm/README.drm16
-rw-r--r--drivers/char/drm/ati_pcigart.c84
-rw-r--r--drivers/char/drm/drm.h4
-rw-r--r--drivers/char/drm/drmP.h30
-rw-r--r--drivers/char/drm/drm_bufs.c75
-rw-r--r--drivers/char/drm/drm_drv.c15
-rw-r--r--drivers/char/drm/drm_fops.c96
-rw-r--r--drivers/char/drm/drm_hashtab.c17
-rw-r--r--drivers/char/drm/drm_hashtab.h1
-rw-r--r--drivers/char/drm/drm_irq.c4
-rw-r--r--drivers/char/drm/drm_lock.c134
-rw-r--r--drivers/char/drm/drm_mm.c2
-rw-r--r--drivers/char/drm/drm_os_linux.h3
-rw-r--r--drivers/char/drm/drm_pciids.h4
-rw-r--r--drivers/char/drm/drm_proc.c2
-rw-r--r--drivers/char/drm/drm_stub.c1
-rw-r--r--drivers/char/drm/drm_vm.c102
-rw-r--r--drivers/char/drm/i915_dma.c3
-rw-r--r--drivers/char/drm/r128_cce.c3
-rw-r--r--drivers/char/drm/r128_drv.h2
-rw-r--r--drivers/char/drm/radeon_cp.c79
-rw-r--r--drivers/char/drm/radeon_drm.h1
-rw-r--r--drivers/char/drm/radeon_drv.h24
-rw-r--r--drivers/char/drm/radeon_state.c52
-rw-r--r--drivers/char/drm/sis_drv.c2
-rw-r--r--drivers/char/drm/via_dma.c111
-rw-r--r--drivers/char/drm/via_drv.c3
-rw-r--r--drivers/char/drm/via_drv.h5
-rw-r--r--drivers/char/drm/via_mm.h40
-rw-r--r--drivers/char/ds1620.c1
-rw-r--r--drivers/char/dsp56k.c1
-rw-r--r--drivers/char/dtlk.c15
-rw-r--r--drivers/char/ec3104_keyb.c1
-rw-r--r--drivers/char/epca.c2
-rw-r--r--drivers/char/genrtc.c2
-rw-r--r--drivers/char/hangcheck-timer.c1
-rw-r--r--drivers/char/hvc_console.c12
-rw-r--r--drivers/char/hvc_iseries.c2
-rw-r--r--drivers/char/hvc_vio.c2
-rw-r--r--drivers/char/hw_random/intel-rng.c219
-rw-r--r--drivers/char/i8k.c1
-rw-r--r--drivers/char/ip27-rtc.c1
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c235
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c136
-rw-r--r--drivers/char/isicom.c3
-rw-r--r--drivers/char/keyboard.c2
-rw-r--r--drivers/char/lp.c8
-rw-r--r--drivers/char/mem.c9
-rw-r--r--drivers/char/misc.c27
-rw-r--r--drivers/char/moxa.c8
-rw-r--r--drivers/char/mxser.c1
-rw-r--r--drivers/char/mxser_new.c1
-rw-r--r--drivers/char/n_r3964.c4
-rw-r--r--drivers/char/ppdev.c3
-rw-r--r--drivers/char/riscom8.c2
-rw-r--r--drivers/char/rocket.c33
-rw-r--r--drivers/char/rocket_int.h4
-rw-r--r--drivers/char/rtc.c2
-rw-r--r--drivers/char/selection.c2
-rw-r--r--drivers/char/serial167.c2
-rw-r--r--drivers/char/synclink.c7
-rw-r--r--drivers/char/synclink_gt.c34
-rw-r--r--drivers/char/sysrq.c1
-rw-r--r--drivers/char/tipar.c2
-rw-r--r--drivers/char/tpm/tpm.c36
-rw-r--r--drivers/char/tpm/tpm.h5
-rw-r--r--drivers/char/tpm/tpm_atmel.h4
-rw-r--r--drivers/char/tpm/tpm_infineon.c231
-rw-r--r--drivers/char/tty_io.c58
-rw-r--r--drivers/char/vc_screen.c19
-rw-r--r--drivers/char/vt.c304
-rw-r--r--drivers/char/vt_ioctl.c2
-rw-r--r--drivers/char/watchdog/omap_wdt.c1
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c2
-rw-r--r--drivers/edac/i82875p_edac.c13
-rw-r--r--drivers/eisa/virtual_root.c2
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/hwmon/Kconfig170
-rw-r--r--drivers/hwmon/Makefile4
-rw-r--r--drivers/hwmon/ad7418.c373
-rw-r--r--drivers/hwmon/ams/ams-core.c9
-rw-r--r--drivers/hwmon/ams/ams-i2c.c10
-rw-r--r--drivers/hwmon/ams/ams-pmu.c2
-rw-r--r--drivers/hwmon/applesmc.c1339
-rw-r--r--drivers/hwmon/coretemp.c406
-rw-r--r--drivers/hwmon/f71805f.c16
-rw-r--r--drivers/hwmon/hdaps.c38
-rw-r--r--drivers/hwmon/hwmon-vid.c6
-rw-r--r--drivers/hwmon/lm75.c82
-rw-r--r--drivers/hwmon/lm78.c662
-rw-r--r--drivers/hwmon/lm87.c2
-rw-r--r--drivers/hwmon/max6650.c693
-rw-r--r--drivers/hwmon/pc87427.c15
-rw-r--r--drivers/hwmon/smsc47b397.c228
-rw-r--r--drivers/hwmon/smsc47m1.c606
-rw-r--r--drivers/hwmon/smsc47m192.c4
-rw-r--r--drivers/hwmon/vt1211.c13
-rw-r--r--drivers/hwmon/w83627hf.c670
-rw-r--r--drivers/hwmon/w83781d.c1205
-rw-r--r--drivers/i2c/busses/i2c-parport.c1
-rw-r--r--drivers/i2c/busses/i2c-pxa.c18
-rw-r--r--drivers/i2c/busses/scx200_acb.c1
-rw-r--r--drivers/i2c/chips/tps65010.c4
-rw-r--r--drivers/i2c/i2c-dev.c1
-rw-r--r--drivers/ide/pci/pdc202xx_new.c2
-rw-r--r--drivers/ide/ppc/pmac.c18
-rw-r--r--drivers/ieee1394/dv1394.c1
-rw-r--r--drivers/ieee1394/raw1394.c1
-rw-r--r--drivers/ieee1394/video1394.c1
-rw-r--r--drivers/infiniband/core/fmr_pool.c32
-rw-r--r--drivers/infiniband/core/mad.c2
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c1
-rw-r--r--drivers/infiniband/core/uverbs_main.c2
-rw-r--r--drivers/infiniband/core/verbs.c4
-rw-r--r--drivers/infiniband/hw/amso1100/c2.h2
-rw-r--r--drivers/infiniband/hw/amso1100/c2_cq.c16
-rw-r--r--drivers/infiniband/hw/amso1100/c2_provider.c3
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.c3
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_wr.h1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.c19
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.h6
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.c14
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_qp.c69
-rw-r--r--drivers/infiniband/hw/ehca/ehca_cq.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_iverbs.h4
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c5
-rw-r--r--drivers/infiniband/hw/ehca/ehca_reqs.c14
-rw-r--r--drivers/infiniband/hw/ehca/ipz_pt_fn.h8
-rw-r--r--drivers/infiniband/hw/ipath/ipath_cq.c68
-rw-r--r--drivers/infiniband/hw/ipath/ipath_fs.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mmap.c64
-rw-r--r--drivers/infiniband/hw/ipath/ipath_qp.c52
-rw-r--r--drivers/infiniband/hw/ipath/ipath_rc.c55
-rw-r--r--drivers/infiniband/hw/ipath/ipath_srq.c55
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.h24
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c12
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c13
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c14
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c89
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_verbs.c2
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c3
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c27
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.h1
-rw-r--r--drivers/input/Kconfig2
-rw-r--r--drivers/input/Makefile1
-rw-r--r--drivers/input/evdev.c7
-rw-r--r--drivers/input/ff-core.c3
-rw-r--r--drivers/input/input.c1
-rw-r--r--drivers/input/joydev.c1
-rw-r--r--drivers/input/joystick/Kconfig18
-rw-r--r--drivers/input/joystick/Makefile1
-rw-r--r--drivers/input/joystick/analog.c2
-rw-r--r--drivers/input/joystick/db9.c18
-rw-r--r--drivers/input/joystick/gamecon.c17
-rw-r--r--drivers/input/joystick/iforce/iforce.h2
-rw-r--r--drivers/input/joystick/turbografx.c18
-rw-r--r--drivers/input/joystick/xpad.c (renamed from drivers/usb/input/xpad.c)1
-rw-r--r--drivers/input/keyboard/Kconfig1
-rw-r--r--drivers/input/keyboard/aaed2000_kbd.c62
-rw-r--r--drivers/input/misc/Kconfig88
-rw-r--r--drivers/input/misc/Makefile9
-rw-r--r--drivers/input/misc/ati_remote.c (renamed from drivers/usb/input/ati_remote.c)0
-rw-r--r--drivers/input/misc/ati_remote2.c (renamed from drivers/usb/input/ati_remote2.c)4
-rw-r--r--drivers/input/misc/keyspan_remote.c (renamed from drivers/usb/input/keyspan_remote.c)0
-rw-r--r--drivers/input/misc/map_to_7segment.h (renamed from drivers/usb/input/map_to_7segment.h)0
-rw-r--r--drivers/input/misc/powermate.c (renamed from drivers/usb/input/powermate.c)10
-rw-r--r--drivers/input/misc/uinput.c1
-rw-r--r--drivers/input/misc/yealink.c (renamed from drivers/usb/input/yealink.c)25
-rw-r--r--drivers/input/misc/yealink.h (renamed from drivers/usb/input/yealink.h)0
-rw-r--r--drivers/input/mouse/Kconfig38
-rw-r--r--drivers/input/mouse/Makefile1
-rw-r--r--drivers/input/mouse/appletouch.c (renamed from drivers/usb/input/appletouch.c)0
-rw-r--r--drivers/input/mouse/synaptics.c2
-rw-r--r--drivers/input/mousedev.c1
-rw-r--r--drivers/input/serio/i8042.c35
-rw-r--r--drivers/input/tablet/Kconfig74
-rw-r--r--drivers/input/tablet/Makefile12
-rw-r--r--drivers/input/tablet/acecad.c (renamed from drivers/usb/input/acecad.c)2
-rw-r--r--drivers/input/tablet/aiptek.c (renamed from drivers/usb/input/aiptek.c)0
-rw-r--r--drivers/input/tablet/gtco.c (renamed from drivers/usb/input/gtco.c)0
-rw-r--r--drivers/input/tablet/kbtab.c (renamed from drivers/usb/input/kbtab.c)2
-rw-r--r--drivers/input/tablet/wacom.h (renamed from drivers/usb/input/wacom.h)2
-rw-r--r--drivers/input/tablet/wacom_sys.c (renamed from drivers/usb/input/wacom_sys.c)2
-rw-r--r--drivers/input/tablet/wacom_wac.c (renamed from drivers/usb/input/wacom_wac.c)2
-rw-r--r--drivers/input/tablet/wacom_wac.h (renamed from drivers/usb/input/wacom_wac.h)4
-rw-r--r--drivers/input/touchscreen/Kconfig60
-rw-r--r--drivers/input/touchscreen/Makefile17
-rw-r--r--drivers/input/touchscreen/hp680_ts_input.c2
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c (renamed from drivers/usb/input/usbtouchscreen.c)5
-rw-r--r--drivers/input/tsdev.c1
-rw-r--r--drivers/isdn/capi/capi.c34
-rw-r--r--drivers/isdn/capi/capiutil.c8
-rw-r--r--drivers/isdn/divert/divert_procfs.c1
-rw-r--r--drivers/isdn/hardware/eicon/capimain.c1
-rw-r--r--drivers/isdn/hardware/eicon/dbgioctl.h198
-rw-r--r--drivers/isdn/hardware/eicon/divamnt.c1
-rw-r--r--drivers/isdn/hardware/eicon/divasi.c1
-rw-r--r--drivers/isdn/hardware/eicon/divasmain.c1
-rw-r--r--drivers/isdn/hardware/eicon/main_if.h50
-rw-r--r--drivers/isdn/hardware/eicon/platform.h1
-rw-r--r--drivers/isdn/hisax/hfc_usb.c1
-rw-r--r--drivers/isdn/hysdn/boardergo.c2
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c4
-rw-r--r--drivers/isdn/isdnloop/isdnloop.c2
-rw-r--r--drivers/kvm/kvm.h100
-rw-r--r--drivers/kvm/kvm_main.c792
-rw-r--r--drivers/kvm/kvm_svm.h13
-rw-r--r--drivers/kvm/kvm_vmx.h14
-rw-r--r--drivers/kvm/mmu.c154
-rw-r--r--drivers/kvm/paging_tmpl.h12
-rw-r--r--drivers/kvm/svm.c197
-rw-r--r--drivers/kvm/svm.h6
-rw-r--r--drivers/kvm/vmx.c273
-rw-r--r--drivers/kvm/x86_emulate.c51
-rw-r--r--drivers/kvm/x86_emulate.h32
-rw-r--r--drivers/macintosh/Kconfig12
-rw-r--r--drivers/macintosh/apm_emu.c521
-rw-r--r--drivers/macintosh/mac_hid.c8
-rw-r--r--drivers/macintosh/macio_sysfs.c27
-rw-r--r--drivers/macintosh/smu.c2
-rw-r--r--drivers/macintosh/therm_adt746x.c5
-rw-r--r--drivers/macintosh/therm_pm72.c1
-rw-r--r--drivers/macintosh/via-pmu-led.c35
-rw-r--r--drivers/macintosh/via-pmu.c12
-rw-r--r--drivers/macintosh/windfarm_core.c1
-rw-r--r--drivers/macintosh/windfarm_lm75_sensor.c4
-rw-r--r--drivers/macintosh/windfarm_max6690_sensor.c2
-rw-r--r--drivers/macintosh/windfarm_smu_controls.c2
-rw-r--r--drivers/macintosh/windfarm_smu_sat.c2
-rw-r--r--drivers/md/bitmap.c8
-rw-r--r--drivers/md/md.c2
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h1
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c1
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c1
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c1
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c1
-rw-r--r--drivers/media/radio/dsbr100.c1
-rw-r--r--drivers/media/video/cpia.h1
-rw-r--r--drivers/media/video/cpia_pp.c1
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c2
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c1
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c1
-rw-r--r--drivers/media/video/cx88/cx88-video.c2
-rw-r--r--drivers/media/video/dabusb.c1
-rw-r--r--drivers/media/video/ov511.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c1
-rw-r--r--drivers/media/video/se401.h1
-rw-r--r--drivers/media/video/tvaudio.c1
-rw-r--r--drivers/media/video/usbvideo/usbvideo.c1
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c1
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c1
-rw-r--r--drivers/media/video/v4l1-compat.c1
-rw-r--r--drivers/media/video/v4l2-common.c1
-rw-r--r--drivers/media/video/videodev.c1
-rw-r--r--drivers/media/video/zoran_driver.c2
-rw-r--r--drivers/message/i2o/i2o_lan.h159
-rw-r--r--drivers/mfd/ucb1x00-ts.c1
-rw-r--r--drivers/misc/Kconfig18
-rw-r--r--drivers/misc/Makefile2
-rw-r--r--drivers/misc/blink.c27
-rw-r--r--drivers/misc/phantom.c463
-rw-r--r--drivers/misc/tifm_7xx1.c27
-rw-r--r--drivers/mmc/Kconfig10
-rw-r--r--drivers/mmc/card/Kconfig3
-rw-r--r--drivers/mmc/core/Kconfig1
-rw-r--r--drivers/mmc/core/core.c10
-rw-r--r--drivers/mmc/host/Kconfig19
-rw-r--r--drivers/mmc/host/pxamci.c4
-rw-r--r--drivers/mmc/host/tifm_sd.c13
-rw-r--r--drivers/mtd/devices/Kconfig4
-rw-r--r--drivers/mtd/devices/block2mtd.c6
-rw-r--r--drivers/mtd/maps/physmap_of.c8
-rw-r--r--drivers/mtd/mtd_blkdevs.c4
-rw-r--r--drivers/mtd/ubi/eba.c3
-rw-r--r--drivers/net/Kconfig11
-rw-r--r--drivers/net/arm/at91_ether.c49
-rw-r--r--drivers/net/arm/at91_ether.h49
-rw-r--r--drivers/net/atl1/atl1_ethtool.c19
-rw-r--r--drivers/net/atl1/atl1_hw.c44
-rw-r--r--drivers/net/atl1/atl1_main.c83
-rw-r--r--drivers/net/atl1/atl1_param.c32
-rw-r--r--drivers/net/bmac.c5
-rw-r--r--drivers/net/cxgb3/version.h4
-rw-r--r--drivers/net/dm9000.c15
-rw-r--r--drivers/net/ehea/ehea_main.c19
-rw-r--r--drivers/net/irda/pxaficp_ir.c12
-rw-r--r--drivers/net/irda/sir_dev.c1
-rw-r--r--drivers/net/irda/sir_dongle.c1
-rw-r--r--drivers/net/irda/smsc-ircc2.c112
-rw-r--r--drivers/net/irda/vlsi_ir.c1
-rw-r--r--drivers/net/mace.c4
-rw-r--r--drivers/net/myri10ge/myri10ge.c261
-rw-r--r--drivers/net/myri10ge/myri10ge_mcp.h20
-rw-r--r--drivers/net/natsemi.c70
-rw-r--r--drivers/net/ne.c123
-rw-r--r--drivers/net/ns83820.c1
-rw-r--r--drivers/net/pasemi_mac.c404
-rw-r--r--drivers/net/pasemi_mac.h23
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c14
-rw-r--r--drivers/net/ppp_generic.c1
-rw-r--r--drivers/net/skge.c9
-rw-r--r--drivers/net/sky2.c17
-rw-r--r--drivers/net/smc91x.h81
-rw-r--r--drivers/net/spider_net.c4
-rw-r--r--drivers/net/sungem.c2
-rw-r--r--drivers/net/sungem_phy.c2
-rw-r--r--drivers/net/tc35815.c1
-rw-r--r--drivers/net/tg3.c40
-rw-r--r--drivers/net/tg3.h10
-rw-r--r--drivers/net/tsi108_eth.c12
-rw-r--r--drivers/net/tsi108_eth.h9
-rw-r--r--drivers/net/ucc_geth.c18
-rw-r--r--drivers/net/ucc_geth_mii.c4
-rw-r--r--drivers/net/wan/cosa.c1
-rw-r--r--drivers/net/wireless/Kconfig14
-rw-r--r--drivers/net/wireless/airo.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c1
-rw-r--r--drivers/parisc/lba_pci.c1
-rw-r--r--drivers/parport/parport_cs.c2
-rw-r--r--drivers/parport/parport_mfc3.c1
-rw-r--r--drivers/parport/parport_pc.c70
-rw-r--r--drivers/parport/parport_serial.c10
-rw-r--r--drivers/parport/parport_sunbpp.c1
-rw-r--r--drivers/parport/share.c5
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c1
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c1
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c1
-rw-r--r--drivers/pci/hotplug/ibmphp_hpc.c1
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c1
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c11
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c1
-rw-r--r--drivers/pci/msi.c1
-rw-r--r--drivers/pci/proc.c1
-rw-r--r--drivers/pcmcia/at91_cf.c3
-rw-r--r--drivers/pcmcia/ds.c113
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c1
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c1
-rw-r--r--drivers/pnp/core.c11
-rw-r--r--drivers/pnp/pnpacpi/core.c55
-rw-r--r--drivers/pnp/pnpbios/core.c17
-rw-r--r--drivers/pnp/quirks.c30
-rw-r--r--drivers/ps3/vuart.c8
-rw-r--r--drivers/rtc/Kconfig272
-rw-r--r--drivers/rtc/Makefile9
-rw-r--r--drivers/rtc/class.c118
-rw-r--r--drivers/rtc/hctosys.c14
-rw-r--r--drivers/rtc/interface.c86
-rw-r--r--drivers/rtc/rtc-at91rm9200.c32
-rw-r--r--drivers/rtc/rtc-bfin.c445
-rw-r--r--drivers/rtc/rtc-cmos.c79
-rw-r--r--drivers/rtc/rtc-core.h70
-rw-r--r--drivers/rtc/rtc-dev.c184
-rw-r--r--drivers/rtc/rtc-ds1553.c2
-rw-r--r--drivers/rtc/rtc-lib.c81
-rw-r--r--drivers/rtc/rtc-max6900.c311
-rw-r--r--drivers/rtc/rtc-omap.c57
-rw-r--r--drivers/rtc/rtc-pl031.c2
-rw-r--r--drivers/rtc/rtc-proc.c68
-rw-r--r--drivers/rtc/rtc-rs5c313.c405
-rw-r--r--drivers/rtc/rtc-s3c.c26
-rw-r--r--drivers/rtc/rtc-sa1100.c4
-rw-r--r--drivers/rtc/rtc-sh.c6
-rw-r--r--drivers/rtc/rtc-sysfs.c129
-rw-r--r--drivers/rtc/rtc-test.c6
-rw-r--r--drivers/rtc/rtc-vr41xx.c32
-rw-r--r--drivers/s390/cio/qdio.c37
-rw-r--r--drivers/s390/cio/qdio.h4
-rw-r--r--drivers/s390/net/netiucv.c5
-rw-r--r--drivers/s390/net/qeth_eddp.c4
-rw-r--r--drivers/s390/net/qeth_eddp.h3
-rw-r--r--drivers/s390/net/qeth_main.c45
-rw-r--r--drivers/s390/net/qeth_mpc.c101
-rw-r--r--drivers/s390/net/qeth_mpc.h219
-rw-r--r--drivers/s390/net/qeth_sys.c2
-rw-r--r--drivers/sbus/char/bpp.c1
-rw-r--r--drivers/sbus/char/rtc.c1
-rw-r--r--drivers/sbus/char/vfc_dev.c1
-rw-r--r--drivers/scsi/Kconfig4
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h1
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h1
-rw-r--r--drivers/scsi/dpt_i2o.c1
-rw-r--r--drivers/scsi/esp_scsi.c2
-rw-r--r--drivers/scsi/ibmvscsi/ibmvstgt.c8
-rw-r--r--drivers/scsi/ibmvscsi/rpa_vscsi.c4
-rw-r--r--drivers/scsi/mac53c94.c2
-rw-r--r--drivers/scsi/mesh.c2
-rw-r--r--drivers/scsi/scsi_debug.c1
-rw-r--r--drivers/scsi/sg.c1
-rw-r--r--drivers/scsi/sni_53c710.c2
-rw-r--r--drivers/scsi/sun_esp.c1
-rw-r--r--drivers/serial/8250.c125
-rw-r--r--drivers/serial/Kconfig117
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/amba-pl010.c295
-rw-r--r--drivers/serial/atmel_serial.c9
-rw-r--r--drivers/serial/atmel_serial.h3
-rw-r--r--drivers/serial/bfin_5xx.c1012
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c12
-rw-r--r--drivers/serial/crisv10.h136
-rw-r--r--drivers/serial/icom.c1
-rw-r--r--drivers/serial/imx.c268
-rw-r--r--drivers/serial/jsm/jsm_neo.c7
-rw-r--r--drivers/serial/jsm/jsm_tty.c1
-rw-r--r--drivers/serial/mpc52xx_uart.c7
-rw-r--r--drivers/serial/mpsc.c25
-rw-r--r--drivers/serial/of_serial.c7
-rw-r--r--drivers/serial/pmac_zilog.c8
-rw-r--r--drivers/serial/pxa.c8
-rw-r--r--drivers/serial/s3c2410.c6
-rw-r--r--drivers/serial/serial_core.c41
-rw-r--r--drivers/serial/serial_txx9.c32
-rw-r--r--drivers/serial/sh-sci.c113
-rw-r--r--drivers/serial/sh-sci.h83
-rw-r--r--drivers/serial/sunsu.c8
-rw-r--r--drivers/spi/Kconfig27
-rw-r--r--drivers/spi/Makefile5
-rw-r--r--drivers/spi/au1550_spi.c974
-rw-r--r--drivers/spi/spi.c33
-rw-r--r--drivers/spi/spi_bfin5xx.c1313
-rw-r--r--drivers/spi/spi_butterfly.c83
-rw-r--r--drivers/spi/spi_s3c24xx.c2
-rw-r--r--drivers/spi/spidev.c584
-rw-r--r--drivers/telephony/ixj.c3
-rw-r--r--drivers/usb/Kconfig2
-rw-r--r--drivers/usb/Makefile9
-rw-r--r--drivers/usb/atm/usbatm.c1
-rw-r--r--drivers/usb/class/cdc-acm.c1
-rw-r--r--drivers/usb/class/usblp.c1
-rw-r--r--drivers/usb/core/hub.c1
-rw-r--r--drivers/usb/core/inode.c1
-rw-r--r--drivers/usb/core/usb.c1
-rw-r--r--drivers/usb/gadget/at91_udc.c1
-rw-r--r--drivers/usb/gadget/dummy_hcd.c1
-rw-r--r--drivers/usb/gadget/ether.c1
-rw-r--r--drivers/usb/gadget/goku_udc.c1
-rw-r--r--drivers/usb/gadget/net2280.c1
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c4
-rw-r--r--drivers/usb/gadget/serial.c1
-rw-r--r--drivers/usb/gadget/zero.c1
-rw-r--r--drivers/usb/host/ehci-hcd.c1
-rw-r--r--drivers/usb/host/ehci-ps3.c11
-rw-r--r--drivers/usb/host/ohci-hcd.c1
-rw-r--r--drivers/usb/host/ohci-ppc-of.c4
-rw-r--r--drivers/usb/host/ohci-ps3.c12
-rw-r--r--drivers/usb/host/ohci-pxa27x.c4
-rw-r--r--drivers/usb/host/sl811-hcd.c1
-rw-r--r--drivers/usb/host/u132-hcd.c1
-rw-r--r--drivers/usb/image/mdc800.c1
-rw-r--r--drivers/usb/image/microtek.c1
-rw-r--r--drivers/usb/input/Kconfig225
-rw-r--r--drivers/usb/input/Makefile24
-rw-r--r--drivers/usb/misc/idmouse.c1
-rw-r--r--drivers/usb/misc/legousbtower.c1
-rw-r--r--drivers/usb/misc/rio500.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_con.c3
-rw-r--r--drivers/usb/mon/mon_main.c1
-rw-r--r--drivers/usb/serial/usb-serial.c1
-rw-r--r--drivers/usb/storage/usb.h1
-rw-r--r--drivers/video/Kconfig161
-rw-r--r--drivers/video/Makefile22
-rw-r--r--drivers/video/arcfb.c28
-rw-r--r--drivers/video/aty/ati_ids.h2
-rw-r--r--drivers/video/aty/aty128fb.c29
-rw-r--r--drivers/video/aty/atyfb_base.c37
-rw-r--r--drivers/video/aty/mach64_ct.c8
-rw-r--r--drivers/video/aty/radeon_base.c11
-rw-r--r--drivers/video/aty/radeon_monitor.c11
-rw-r--r--drivers/video/aty/radeon_pm.c12
-rw-r--r--drivers/video/aty/radeonfb.h4
-rw-r--r--drivers/video/backlight/Kconfig8
-rw-r--r--drivers/video/backlight/Makefile1
-rw-r--r--drivers/video/backlight/cr_bllcd.c287
-rw-r--r--drivers/video/cfbcopyarea.c14
-rw-r--r--drivers/video/cfbfillrect.c68
-rw-r--r--drivers/video/cirrusfb.c69
-rw-r--r--drivers/video/console/fbcon.c136
-rw-r--r--drivers/video/console/fonts.c10
-rw-r--r--drivers/video/console/mdacon.c3
-rw-r--r--drivers/video/console/promcon.c3
-rw-r--r--drivers/video/console/sticon.c2
-rw-r--r--drivers/video/console/sticore.c2
-rw-r--r--drivers/video/console/vgacon.c17
-rw-r--r--drivers/video/display/Kconfig24
-rw-r--r--drivers/video/display/Makefile6
-rw-r--r--drivers/video/display/display-sysfs.c217
-rw-r--r--drivers/video/epson1355fb.c21
-rw-r--r--drivers/video/fb_defio.c151
-rw-r--r--drivers/video/fb_draw.h72
-rw-r--r--drivers/video/fb_sys_fops.c104
-rw-r--r--drivers/video/fbmem.c127
-rw-r--r--drivers/video/fbmon.c169
-rw-r--r--drivers/video/fbsysfs.c2
-rw-r--r--drivers/video/hecubafb.c471
-rw-r--r--drivers/video/i810/i810.h2
-rw-r--r--drivers/video/intelfb/intelfbhw.c34
-rw-r--r--drivers/video/logo/Kconfig30
-rw-r--r--drivers/video/modedb.c4
-rw-r--r--drivers/video/neofb.c1
-rw-r--r--drivers/video/nvidia/nv_accel.c76
-rw-r--r--drivers/video/nvidia/nv_hw.c15
-rw-r--r--drivers/video/nvidia/nv_i2c.c94
-rw-r--r--drivers/video/nvidia/nv_local.h4
-rw-r--r--drivers/video/nvidia/nv_of.c8
-rw-r--r--drivers/video/nvidia/nv_setup.c5
-rw-r--r--drivers/video/nvidia/nv_type.h8
-rw-r--r--drivers/video/nvidia/nvidia.c81
-rw-r--r--drivers/video/offb.c32
-rw-r--r--drivers/video/pm2fb.c246
-rw-r--r--drivers/video/ps3fb.c12
-rw-r--r--drivers/video/pvr2fb.c4
-rw-r--r--drivers/video/pxafb.c6
-rw-r--r--drivers/video/riva/fbdev.c22
-rw-r--r--drivers/video/riva/nv4ref.h2445
-rw-r--r--drivers/video/riva/nv_driver.c6
-rw-r--r--drivers/video/riva/riva_hw.c12
-rw-r--r--drivers/video/riva/rivafb-i2c.c41
-rw-r--r--drivers/video/riva/rivafb.h2
-rw-r--r--drivers/video/s3fb.c66
-rw-r--r--drivers/video/savage/savagefb-i2c.c22
-rw-r--r--drivers/video/savage/savagefb.h10
-rw-r--r--drivers/video/savage/savagefb_driver.c39
-rw-r--r--drivers/video/sis/osdef.h5
-rw-r--r--drivers/video/sis/sis.h51
-rw-r--r--drivers/video/sis/sis_main.c106
-rw-r--r--drivers/video/skeletonfb.c217
-rw-r--r--drivers/video/sm501fb.c2
-rw-r--r--drivers/video/sunxvr2500.c277
-rw-r--r--drivers/video/sunxvr500.c443
-rw-r--r--drivers/video/svgalib.c38
-rw-r--r--drivers/video/syscopyarea.c378
-rw-r--r--drivers/video/sysfillrect.c334
-rw-r--r--drivers/video/sysimgblt.c291
-rw-r--r--drivers/video/tgafb.c425
-rw-r--r--drivers/video/vermilion/Makefile5
-rw-r--r--drivers/video/vermilion/cr_pll.c208
-rw-r--r--drivers/video/vermilion/vermilion.c1195
-rw-r--r--drivers/video/vermilion/vermilion.h260
-rw-r--r--drivers/video/vfb.c8
-rw-r--r--drivers/video/vga16fb.c2
-rw-r--r--drivers/video/vgastate.c26
-rw-r--r--drivers/video/xilinxfb.c381
-rw-r--r--drivers/w1/masters/Kconfig8
-rw-r--r--drivers/w1/masters/Makefile2
-rw-r--r--drivers/w1/masters/ds1wm.c468
-rw-r--r--drivers/w1/w1.c2
-rw-r--r--drivers/w1/w1_int.c3
-rw-r--r--fs/9p/vfs_addr.c1
-rw-r--r--fs/9p/vfs_dentry.c1
-rw-r--r--fs/9p/vfs_dir.c1
-rw-r--r--fs/9p/vfs_file.c1
-rw-r--r--fs/9p/vfs_inode.c1
-rw-r--r--fs/9p/vfs_super.c1
-rw-r--r--fs/Kconfig2
-rw-r--r--fs/Kconfig.binfmt2
-rw-r--r--fs/adfs/super.c3
-rw-r--r--fs/affs/super.c3
-rw-r--r--fs/afs/dir.c3
-rw-r--r--fs/afs/mntpt.c11
-rw-r--r--fs/afs/super.c3
-rw-r--r--fs/aio.c6
-rw-r--r--fs/attr.c1
-rw-r--r--fs/autofs4/inode.c1
-rw-r--r--fs/autofs4/root.c1
-rw-r--r--fs/bad_inode.c1
-rw-r--r--fs/befs/linuxvfs.c3
-rw-r--r--fs/bfs/inode.c3
-rw-r--r--fs/binfmt_elf.c5
-rw-r--r--fs/binfmt_elf_fdpic.c1
-rw-r--r--fs/binfmt_em86.c1
-rw-r--r--fs/binfmt_misc.c4
-rw-r--r--fs/binfmt_script.c1
-rw-r--r--fs/bio.c3
-rw-r--r--fs/block_dev.c15
-rw-r--r--fs/buffer.c26
-rw-r--r--fs/cifs/cifsfs.c3
-rw-r--r--fs/cifs/file.c1
-rw-r--r--fs/cifs/readdir.c1
-rw-r--r--fs/coda/inode.c3
-rw-r--r--fs/compat.c225
-rw-r--r--fs/compat_ioctl.c1004
-rw-r--r--fs/cramfs/inode.c3
-rw-r--r--fs/dcache.c144
-rw-r--r--fs/devpts/inode.c5
-rw-r--r--fs/dlm/Kconfig31
-rw-r--r--fs/dlm/Makefile6
-rw-r--r--fs/dlm/ast.c1
-rw-r--r--fs/dlm/config.c10
-rw-r--r--fs/dlm/config.h3
-rw-r--r--fs/dlm/dlm_internal.h11
-rw-r--r--fs/dlm/lock.c955
-rw-r--r--fs/dlm/lock.h2
-rw-r--r--fs/dlm/lockspace.c4
-rw-r--r--fs/dlm/lowcomms-sctp.c1210
-rw-r--r--fs/dlm/lowcomms.c (renamed from fs/dlm/lowcomms-tcp.c)788
-rw-r--r--fs/dlm/user.c163
-rw-r--r--fs/dquot.c10
-rw-r--r--fs/ecryptfs/file.c1
-rw-r--r--fs/ecryptfs/main.c3
-rw-r--r--fs/ecryptfs/mmap.c11
-rw-r--r--fs/efs/super.c3
-rw-r--r--fs/eventpoll.c238
-rw-r--r--fs/exec.c51
-rw-r--r--fs/exportfs/expfs.c1
-rw-r--r--fs/ext2/dir.c4
-rw-r--r--fs/ext2/ext2.h1
-rw-r--r--fs/ext2/fsync.c1
-rw-r--r--fs/ext2/inode.c26
-rw-r--r--fs/ext2/ioctl.c1
-rw-r--r--fs/ext2/super.c3
-rw-r--r--fs/ext2/xattr_security.c1
-rw-r--r--fs/ext2/xattr_trusted.c1
-rw-r--r--fs/ext3/dir.c1
-rw-r--r--fs/ext3/inode.c27
-rw-r--r--fs/ext3/ioctl.c1
-rw-r--r--fs/ext3/namei.c27
-rw-r--r--fs/ext3/resize.c1
-rw-r--r--fs/ext3/super.c7
-rw-r--r--fs/ext3/xattr_security.c1
-rw-r--r--fs/ext3/xattr_trusted.c1
-rw-r--r--fs/ext3/xattr_user.c1
-rw-r--r--fs/ext4/dir.c1
-rw-r--r--fs/ext4/extents.c1
-rw-r--r--fs/ext4/inode.c7
-rw-r--r--fs/ext4/namei.c27
-rw-r--r--fs/ext4/resize.c1
-rw-r--r--fs/ext4/super.c7
-rw-r--r--fs/ext4/xattr_security.c1
-rw-r--r--fs/ext4/xattr_trusted.c1
-rw-r--r--fs/ext4/xattr_user.c1
-rw-r--r--fs/fat/cache.c3
-rw-r--r--fs/fat/dir.c199
-rw-r--r--fs/fat/inode.c24
-rw-r--r--fs/fifo.c1
-rw-r--r--fs/file_table.c1
-rw-r--r--fs/filesystems.c21
-rw-r--r--fs/freevxfs/vxfs_bmap.c2
-rw-r--r--fs/freevxfs/vxfs_inode.c2
-rw-r--r--fs/freevxfs/vxfs_subr.c3
-rw-r--r--fs/fuse/file.c3
-rw-r--r--fs/fuse/inode.c5
-rw-r--r--fs/gfs2/dir.c38
-rw-r--r--fs/gfs2/glock.c619
-rw-r--r--fs/gfs2/glock.h8
-rw-r--r--fs/gfs2/glops.c5
-rw-r--r--fs/gfs2/incore.h14
-rw-r--r--fs/gfs2/locking/dlm/lock.c14
-rw-r--r--fs/gfs2/locking/dlm/lock_dlm.h3
-rw-r--r--fs/gfs2/locking/dlm/plock.c109
-rw-r--r--fs/gfs2/locking/nolock/main.c9
-rw-r--r--fs/gfs2/lops.c20
-rw-r--r--fs/gfs2/main.c10
-rw-r--r--fs/gfs2/mount.c239
-rw-r--r--fs/gfs2/ops_address.c21
-rw-r--r--fs/gfs2/ops_dentry.c1
-rw-r--r--fs/gfs2/ops_file.c13
-rw-r--r--fs/gfs2/ops_fstype.c4
-rw-r--r--fs/gfs2/ops_super.c28
-rw-r--r--fs/gfs2/rgrp.c12
-rw-r--r--fs/hfs/btree.c3
-rw-r--r--fs/hfs/super.c2
-rw-r--r--fs/hfsplus/btree.c3
-rw-r--r--fs/hfsplus/super.c2
-rw-r--r--fs/hostfs/hostfs.h15
-rw-r--r--fs/hostfs/hostfs_kern.c192
-rw-r--r--fs/hostfs/hostfs_user.c229
-rw-r--r--fs/hpfs/super.c3
-rw-r--r--fs/hugetlbfs/inode.c20
-rw-r--r--fs/inode.c47
-rw-r--r--fs/inotify.c2
-rw-r--r--fs/internal.h10
-rw-r--r--fs/ioctl.c2
-rw-r--r--fs/isofs/inode.c3
-rw-r--r--fs/jbd/commit.c1
-rw-r--r--fs/jbd/journal.c14
-rw-r--r--fs/jbd/revoke.c1
-rw-r--r--fs/jbd/transaction.c1
-rw-r--r--fs/jbd2/commit.c1
-rw-r--r--fs/jbd2/journal.c14
-rw-r--r--fs/jbd2/revoke.c1
-rw-r--r--fs/jbd2/transaction.c1
-rw-r--r--fs/jffs2/super.c3
-rw-r--r--fs/jfs/inode.c1
-rw-r--r--fs/jfs/ioctl.c2
-rw-r--r--fs/jfs/jfs_imap.c2
-rw-r--r--fs/jfs/jfs_inode.c18
-rw-r--r--fs/jfs/jfs_inode.h1
-rw-r--r--fs/jfs/jfs_lock.h2
-rw-r--r--fs/jfs/jfs_logmgr.c8
-rw-r--r--fs/jfs/jfs_metapage.c3
-rw-r--r--fs/jfs/jfs_txnmgr.c7
-rw-r--r--fs/jfs/super.c3
-rw-r--r--fs/libfs.c23
-rw-r--r--fs/lockd/clntproc.c1
-rw-r--r--fs/lockd/svc4proc.c6
-rw-r--r--fs/lockd/svclock.c275
-rw-r--r--fs/lockd/svcproc.c7
-rw-r--r--fs/lockd/svcsubs.c2
-rw-r--r--fs/locks.c267
-rw-r--r--fs/minix/dir.c1
-rw-r--r--fs/minix/inode.c3
-rw-r--r--fs/mpage.c16
-rw-r--r--fs/namei.c24
-rw-r--r--fs/namespace.c41
-rw-r--r--fs/ncpfs/file.c1
-rw-r--r--fs/ncpfs/inode.c3
-rw-r--r--fs/nfs/client.c1
-rw-r--r--fs/nfs/dir.c5
-rw-r--r--fs/nfs/direct.c1
-rw-r--r--fs/nfs/file.c7
-rw-r--r--fs/nfs/getroot.c1
-rw-r--r--fs/nfs/inode.c3
-rw-r--r--fs/nfs/nfs3proc.c1
-rw-r--r--fs/nfs/nfs4proc.c1
-rw-r--r--fs/nfs/nfs4renewd.c1
-rw-r--r--fs/nfs/proc.c1
-rw-r--r--fs/nfs/symlink.c7
-rw-r--r--fs/nfs/write.c5
-rw-r--r--fs/nfsd/nfs4idmap.c1
-rw-r--r--fs/nfsd/nfs4state.c30
-rw-r--r--fs/nfsd/nfs4xdr.c1
-rw-r--r--fs/nfsd/nfsfh.c1
-rw-r--r--fs/ntfs/aops.h3
-rw-r--r--fs/ntfs/attrib.c18
-rw-r--r--fs/ntfs/dir.c1
-rw-r--r--fs/ntfs/file.c24
-rw-r--r--fs/ntfs/inode.c1
-rw-r--r--fs/ntfs/super.c33
-rw-r--r--fs/ocfs2/dlm/dlmfs.c4
-rw-r--r--fs/ocfs2/dlmglue.c1
-rw-r--r--fs/ocfs2/inode.c1
-rw-r--r--fs/ocfs2/slot_map.c1
-rw-r--r--fs/ocfs2/super.c3
-rw-r--r--fs/ocfs2/symlink.c7
-rw-r--r--fs/ocfs2/vote.c1
-rw-r--r--fs/open.c4
-rw-r--r--fs/openpromfs/inode.c3
-rw-r--r--fs/partitions/Kconfig9
-rw-r--r--fs/partitions/Makefile1
-rw-r--r--fs/partitions/acorn.c2
-rw-r--r--fs/partitions/check.c7
-rw-r--r--fs/partitions/sysv68.c92
-rw-r--r--fs/partitions/sysv68.h1
-rw-r--r--fs/pipe.c18
-rw-r--r--fs/pnode.c2
-rw-r--r--fs/proc/array.c4
-rw-r--r--fs/proc/base.c302
-rw-r--r--fs/proc/generic.c13
-rw-r--r--fs/proc/inode.c17
-rw-r--r--fs/proc/internal.h2
-rw-r--r--fs/proc/proc_misc.c12
-rw-r--r--fs/proc/proc_sysctl.c7
-rw-r--r--fs/proc/proc_tty.c3
-rw-r--r--fs/proc/task_mmu.c151
-rw-r--r--fs/proc/task_nommu.c7
-rw-r--r--fs/qnx4/inode.c3
-rw-r--r--fs/quota.c1
-rw-r--r--fs/ramfs/file-nommu.c1
-rw-r--r--fs/ramfs/inode.c1
-rw-r--r--fs/read_write.c16
-rw-r--r--fs/readdir.c9
-rw-r--r--fs/reiserfs/dir.c1
-rw-r--r--fs/reiserfs/file.c1
-rw-r--r--fs/reiserfs/journal.c2
-rw-r--r--fs/reiserfs/namei.c1
-rw-r--r--fs/reiserfs/procfs.c3
-rw-r--r--fs/reiserfs/resize.c4
-rw-r--r--fs/reiserfs/stree.c1
-rw-r--r--fs/reiserfs/super.c10
-rw-r--r--fs/reiserfs/xattr.c4
-rw-r--r--fs/romfs/inode.c3
-rw-r--r--fs/select.c9
-rw-r--r--fs/smbfs/inode.c3
-rw-r--r--fs/smbfs/request.c7
-rw-r--r--fs/smbfs/smbiod.c3
-rw-r--r--fs/smbfs/sock.c1
-rw-r--r--fs/smbfs/symlink.c1
-rw-r--r--fs/splice.c17
-rw-r--r--fs/stat.c1
-rw-r--r--fs/super.c27
-rw-r--r--fs/sync.c2
-rw-r--r--fs/sysv/dir.c10
-rw-r--r--fs/sysv/inode.c3
-rw-r--r--fs/sysv/namei.c1
-rw-r--r--fs/udf/balloc.c177
-rw-r--r--fs/udf/dir.c39
-rw-r--r--fs/udf/directory.c30
-rw-r--r--fs/udf/fsync.c1
-rw-r--r--fs/udf/inode.c581
-rw-r--r--fs/udf/misc.c6
-rw-r--r--fs/udf/namei.c226
-rw-r--r--fs/udf/partition.c2
-rw-r--r--fs/udf/super.c79
-rw-r--r--fs/udf/symlink.c2
-rw-r--r--fs/udf/truncate.c206
-rw-r--r--fs/udf/udf_sb.h2
-rw-r--r--fs/udf/udfdecl.h25
-rw-r--r--fs/ufs/dir.c7
-rw-r--r--fs/ufs/super.c3
-rw-r--r--fs/ufs/util.c6
-rw-r--r--fs/utimes.c162
-rw-r--r--fs/xattr.c1
-rw-r--r--fs/xfs/linux-2.6/mrlock.h12
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c89
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c10
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h3
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.c21
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c185
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c3
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h2
-rw-r--r--fs/xfs/quota/xfs_dquot.c3
-rw-r--r--fs/xfs/quota/xfs_qm.c16
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c19
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c4
-rw-r--r--fs/xfs/support/debug.c17
-rw-r--r--fs/xfs/support/debug.h2
-rw-r--r--fs/xfs/xfs_alloc.c2
-rw-r--r--fs/xfs/xfs_attr.c12
-rw-r--r--fs/xfs/xfs_attr_leaf.c2
-rw-r--r--fs/xfs/xfs_bmap.c28
-rw-r--r--fs/xfs/xfs_dfrag.c6
-rw-r--r--fs/xfs/xfs_dir2_block.c14
-rw-r--r--fs/xfs/xfs_dir2_data.c7
-rw-r--r--fs/xfs/xfs_dir2_data.h2
-rw-r--r--fs/xfs/xfs_dir2_leaf.c7
-rw-r--r--fs/xfs/xfs_dir2_node.c4
-rw-r--r--fs/xfs/xfs_error.c2
-rw-r--r--fs/xfs/xfs_fsops.c4
-rw-r--r--fs/xfs/xfs_iget.c15
-rw-r--r--fs/xfs/xfs_inode.c58
-rw-r--r--fs/xfs/xfs_inode.h65
-rw-r--r--fs/xfs/xfs_iocore.c2
-rw-r--r--fs/xfs/xfs_iomap.c15
-rw-r--r--fs/xfs/xfs_iomap.h1
-rw-r--r--fs/xfs/xfs_log_recover.c15
-rw-r--r--fs/xfs/xfs_mount.c2
-rw-r--r--fs/xfs/xfs_qmops.c2
-rw-r--r--fs/xfs/xfs_quota.h3
-rw-r--r--fs/xfs/xfs_rename.c2
-rw-r--r--fs/xfs/xfs_rtalloc.c6
-rw-r--r--fs/xfs/xfs_rw.c4
-rw-r--r--fs/xfs/xfs_trans.c6
-rw-r--r--fs/xfs/xfs_trans.h4
-rw-r--r--fs/xfs/xfs_utils.c11
-rw-r--r--fs/xfs/xfs_vfsops.c6
-rw-r--r--fs/xfs/xfs_vnodeops.c125
-rw-r--r--include/acpi/acpi_bus.h3
-rw-r--r--include/asm-alpha/atomic.h64
-rw-r--r--include/asm-alpha/kdebug.h1
-rw-r--r--include/asm-alpha/local.h126
-rw-r--r--include/asm-alpha/pgtable.h4
-rw-r--r--include/asm-alpha/system.h226
-rw-r--r--include/asm-alpha/thread_info.h22
-rw-r--r--include/asm-arm/arch-at91/at91_adc.h61
-rw-r--r--include/asm-arm/arch-at91/board.h12
-rw-r--r--include/asm-arm/arch-ebsa110/io.h8
-rw-r--r--include/asm-arm/arch-imx/imx-regs.h118
-rw-r--r--include/asm-arm/arch-iop13xx/io.h1
-rw-r--r--include/asm-arm/arch-iop13xx/iop13xx.h24
-rw-r--r--include/asm-arm/arch-iop13xx/time.h56
-rw-r--r--include/asm-arm/arch-iop32x/io.h1
-rw-r--r--include/asm-arm/arch-iop32x/iop32x.h9
-rw-r--r--include/asm-arm/arch-iop32x/memory.h4
-rw-r--r--include/asm-arm/arch-iop33x/io.h1
-rw-r--r--include/asm-arm/arch-iop33x/iop33x.h10
-rw-r--r--include/asm-arm/arch-iop33x/memory.h4
-rw-r--r--include/asm-arm/arch-ixp23xx/io.h4
-rw-r--r--include/asm-arm/arch-ixp4xx/cpu.h31
-rw-r--r--include/asm-arm/arch-ixp4xx/dsmg600.h57
-rw-r--r--include/asm-arm/arch-ixp4xx/entry-macro.S4
-rw-r--r--include/asm-arm/arch-ixp4xx/gpio.h73
-rw-r--r--include/asm-arm/arch-ixp4xx/hardware.h12
-rw-r--r--include/asm-arm/arch-ixp4xx/io.h6
-rw-r--r--include/asm-arm/arch-ixp4xx/irqs.h16
-rw-r--r--include/asm-arm/arch-ixp4xx/ixp4xx-regs.h15
-rw-r--r--include/asm-arm/arch-netx/netx-regs.h4
-rw-r--r--include/asm-arm/arch-ns9xxx/board.h2
-rw-r--r--include/asm-arm/arch-ns9xxx/clock.h34
-rw-r--r--include/asm-arm/arch-ns9xxx/hardware.h5
-rw-r--r--include/asm-arm/arch-ns9xxx/processor.h3
-rw-r--r--include/asm-arm/arch-ns9xxx/regs-sys.h6
-rw-r--r--include/asm-arm/arch-pxa/i2c.h1
-rw-r--r--include/asm-arm/arch-pxa/pxa-regs.h58
-rw-r--r--include/asm-arm/arch-s3c2410/regs-ac97.h56
-rw-r--r--include/asm-arm/arch-s3c2410/regs-udc.h6
-rw-r--r--include/asm-arm/atomic.h1
-rw-r--r--include/asm-arm/ecard.h52
-rw-r--r--include/asm-arm/hardware/iop3xx.h24
-rw-r--r--include/asm-arm/io.h33
-rw-r--r--include/asm-arm/kdebug.h1
-rw-r--r--include/asm-arm/kexec.h2
-rw-r--r--include/asm-arm/mach/map.h21
-rw-r--r--include/asm-arm/pgtable-nommu.h4
-rw-r--r--include/asm-arm/pgtable.h4
-rw-r--r--include/asm-arm/plat-s3c24xx/clock.h1
-rw-r--r--include/asm-arm/plat-s3c24xx/cpu.h16
-rw-r--r--include/asm-arm/ptrace.h10
-rw-r--r--include/asm-arm/system.h6
-rw-r--r--include/asm-arm/thread_info.h1
-rw-r--r--include/asm-arm26/atomic.h1
-rw-r--r--include/asm-arm26/kdebug.h1
-rw-r--r--include/asm-arm26/pgtable.h4
-rw-r--r--include/asm-arm26/system.h2
-rw-r--r--include/asm-avr32/kdebug.h25
-rw-r--r--include/asm-avr32/pgtable.h4
-rw-r--r--include/asm-blackfin/Kbuild1
-rw-r--r--include/asm-blackfin/a.out.h25
-rw-r--r--include/asm-blackfin/atomic.h144
-rw-r--r--include/asm-blackfin/auxvec.h4
-rw-r--r--include/asm-blackfin/bf5xx_timers.h209
-rw-r--r--include/asm-blackfin/bfin-global.h120
-rw-r--r--include/asm-blackfin/bfin5xx_spi.h170
-rw-r--r--include/asm-blackfin/bfin_simple_timer.h13
-rw-r--r--include/asm-blackfin/bfin_sport.h175
-rw-r--r--include/asm-blackfin/bitops.h213
-rw-r--r--include/asm-blackfin/blackfin.h81
-rw-r--r--include/asm-blackfin/bug.h4
-rw-r--r--include/asm-blackfin/bugs.h16
-rw-r--r--include/asm-blackfin/byteorder.h48
-rw-r--r--include/asm-blackfin/cache.h29
-rw-r--r--include/asm-blackfin/cacheflush.h90
-rw-r--r--include/asm-blackfin/checksum.h101
-rw-r--r--include/asm-blackfin/cplb.h51
-rw-r--r--include/asm-blackfin/cplbinit.h203
-rw-r--r--include/asm-blackfin/cpumask.h6
-rw-r--r--include/asm-blackfin/cputime.h6
-rw-r--r--include/asm-blackfin/current.h23
-rw-r--r--include/asm-blackfin/delay.h44
-rw-r--r--include/asm-blackfin/device.h7
-rw-r--r--include/asm-blackfin/div64.h1
-rw-r--r--include/asm-blackfin/dma-mapping.h66
-rw-r--r--include/asm-blackfin/dma.h188
-rw-r--r--include/asm-blackfin/dpmc.h70
-rw-r--r--include/asm-blackfin/elf.h127
-rw-r--r--include/asm-blackfin/emergency-restart.h6
-rw-r--r--include/asm-blackfin/entry.h56
-rw-r--r--include/asm-blackfin/errno.h6
-rw-r--r--include/asm-blackfin/fcntl.h13
-rw-r--r--include/asm-blackfin/flat.h58
-rw-r--r--include/asm-blackfin/futex.h6
-rw-r--r--include/asm-blackfin/gpio.h367
-rw-r--r--include/asm-blackfin/hardirq.h41
-rw-r--r--include/asm-blackfin/hw_irq.h6
-rw-r--r--include/asm-blackfin/ide.h32
-rw-r--r--include/asm-blackfin/io.h207
-rw-r--r--include/asm-blackfin/ioctl.h1
-rw-r--r--include/asm-blackfin/ioctls.h82
-rw-r--r--include/asm-blackfin/ipc.h1
-rw-r--r--include/asm-blackfin/ipcbuf.h30
-rw-r--r--include/asm-blackfin/irq.h70
-rw-r--r--include/asm-blackfin/irq_handler.h22
-rw-r--r--include/asm-blackfin/irq_regs.h1
-rw-r--r--include/asm-blackfin/kdebug.h1
-rw-r--r--include/asm-blackfin/kmap_types.h21
-rw-r--r--include/asm-blackfin/l1layout.h31
-rw-r--r--include/asm-blackfin/linkage.h7
-rw-r--r--include/asm-blackfin/local.h6
-rw-r--r--include/asm-blackfin/mach-bf533/anomaly.h175
-rw-r--r--include/asm-blackfin/mach-bf533/bf533.h306
-rw-r--r--include/asm-blackfin/mach-bf533/bfin_serial_5xx.h108
-rw-r--r--include/asm-blackfin/mach-bf533/blackfin.h45
-rw-r--r--include/asm-blackfin/mach-bf533/cdefBF532.h706
-rw-r--r--include/asm-blackfin/mach-bf533/defBF532.h1175
-rw-r--r--include/asm-blackfin/mach-bf533/dma.h54
-rw-r--r--include/asm-blackfin/mach-bf533/irq.h177
-rw-r--r--include/asm-blackfin/mach-bf533/mem_init.h316
-rw-r--r--include/asm-blackfin/mach-bf533/mem_map.h168
-rw-r--r--include/asm-blackfin/mach-bf537/anomaly.h120
-rw-r--r--include/asm-blackfin/mach-bf537/bf537.h287
-rw-r--r--include/asm-blackfin/mach-bf537/bfin_serial_5xx.h147
-rw-r--r--include/asm-blackfin/mach-bf537/blackfin.h430
-rw-r--r--include/asm-blackfin/mach-bf537/cdefBF534.h1823
-rw-r--r--include/asm-blackfin/mach-bf537/cdefBF537.h209
-rw-r--r--include/asm-blackfin/mach-bf537/defBF534.h2501
-rw-r--r--include/asm-blackfin/mach-bf537/defBF537.h404
-rw-r--r--include/asm-blackfin/mach-bf537/dma.h55
-rw-r--r--include/asm-blackfin/mach-bf537/irq.h219
-rw-r--r--include/asm-blackfin/mach-bf537/mem_init.h330
-rw-r--r--include/asm-blackfin/mach-bf537/mem_map.h175
-rw-r--r--include/asm-blackfin/mach-bf561/anomaly.h184
-rw-r--r--include/asm-blackfin/mach-bf561/bf561.h408
-rw-r--r--include/asm-blackfin/mach-bf561/bfin_serial_5xx.h108
-rw-r--r--include/asm-blackfin/mach-bf561/blackfin.h52
-rw-r--r--include/asm-blackfin/mach-bf561/cdefBF561.h1543
-rw-r--r--include/asm-blackfin/mach-bf561/defBF561.h1717
-rw-r--r--include/asm-blackfin/mach-bf561/dma.h35
-rw-r--r--include/asm-blackfin/mach-bf561/irq.h450
-rw-r--r--include/asm-blackfin/mach-bf561/mem_init.h322
-rw-r--r--include/asm-blackfin/mach-bf561/mem_map.h75
-rw-r--r--include/asm-blackfin/mach-common/cdef_LPBlackfin.h471
-rw-r--r--include/asm-blackfin/mach-common/context.S350
-rw-r--r--include/asm-blackfin/mach-common/def_LPBlackfin.h691
-rw-r--r--include/asm-blackfin/macros.h95
-rw-r--r--include/asm-blackfin/mem_map.h12
-rw-r--r--include/asm-blackfin/mman.h45
-rw-r--r--include/asm-blackfin/mmu.h30
-rw-r--r--include/asm-blackfin/mmu_context.h129
-rw-r--r--include/asm-blackfin/module.h19
-rw-r--r--include/asm-blackfin/msgbuf.h31
-rw-r--r--include/asm-blackfin/mutex.h9
-rw-r--r--include/asm-blackfin/namei.h19
-rw-r--r--include/asm-blackfin/page.h89
-rw-r--r--include/asm-blackfin/page_offset.h6
-rw-r--r--include/asm-blackfin/param.h22
-rw-r--r--include/asm-blackfin/pci.h148
-rw-r--r--include/asm-blackfin/percpu.h6
-rw-r--r--include/asm-blackfin/pgalloc.h8
-rw-r--r--include/asm-blackfin/pgtable.h96
-rw-r--r--include/asm-blackfin/poll.h24
-rw-r--r--include/asm-blackfin/posix_types.h65
-rw-r--r--include/asm-blackfin/processor.h130
-rw-r--r--include/asm-blackfin/ptrace.h166
-rw-r--r--include/asm-blackfin/resource.h6
-rw-r--r--include/asm-blackfin/scatterlist.h26
-rw-r--r--include/asm-blackfin/sections.h7
-rw-r--r--include/asm-blackfin/segment.h7
-rw-r--r--include/asm-blackfin/semaphore-helper.h82
-rw-r--r--include/asm-blackfin/semaphore.h106
-rw-r--r--include/asm-blackfin/sembuf.h25
-rw-r--r--include/asm-blackfin/setup.h17
-rw-r--r--include/asm-blackfin/shmbuf.h42
-rw-r--r--include/asm-blackfin/shmparam.h6
-rw-r--r--include/asm-blackfin/sigcontext.h55
-rw-r--r--include/asm-blackfin/siginfo.h35
-rw-r--r--include/asm-blackfin/signal.h160
-rw-r--r--include/asm-blackfin/socket.h53
-rw-r--r--include/asm-blackfin/sockios.h13
-rw-r--r--include/asm-blackfin/spinlock.h6
-rw-r--r--include/asm-blackfin/stat.h63
-rw-r--r--include/asm-blackfin/statfs.h6
-rw-r--r--include/asm-blackfin/string.h104
-rw-r--r--include/asm-blackfin/system.h249
-rw-r--r--include/asm-blackfin/termbits.h184
-rw-r--r--include/asm-blackfin/termios.h106
-rw-r--r--include/asm-blackfin/thread_info.h143
-rw-r--r--include/asm-blackfin/timex.h18
-rw-r--r--include/asm-blackfin/tlb.h16
-rw-r--r--include/asm-blackfin/tlbflush.h62
-rw-r--r--include/asm-blackfin/topology.h6
-rw-r--r--include/asm-blackfin/traps.h75
-rw-r--r--include/asm-blackfin/types.h66
-rw-r--r--include/asm-blackfin/uaccess.h271
-rw-r--r--include/asm-blackfin/ucontext.h17
-rw-r--r--include/asm-blackfin/unaligned.h6
-rw-r--r--include/asm-blackfin/unistd.h382
-rw-r--r--include/asm-blackfin/user.h89
-rw-r--r--include/asm-cris/kdebug.h1
-rw-r--r--include/asm-frv/atomic.h91
-rw-r--r--include/asm-frv/kdebug.h1
-rw-r--r--include/asm-frv/pgtable.h4
-rw-r--r--include/asm-frv/semaphore.h14
-rw-r--r--include/asm-frv/system.h70
-rw-r--r--include/asm-generic/atomic.h140
-rw-r--r--include/asm-generic/kdebug.h8
-rw-r--r--include/asm-generic/local.h33
-rw-r--r--include/asm-h8300/irq.h1
-rw-r--r--include/asm-h8300/irq_regs.h1
-rw-r--r--include/asm-h8300/kdebug.h1
-rw-r--r--include/asm-h8300/pgtable.h5
-rw-r--r--include/asm-h8300/system.h1
-rw-r--r--include/asm-i386/atomic.h45
-rw-r--r--include/asm-i386/cmpxchg.h293
-rw-r--r--include/asm-i386/elf.h2
-rw-r--r--include/asm-i386/ioctls.h4
-rw-r--r--include/asm-i386/kdebug.h25
-rw-r--r--include/asm-i386/kexec.h2
-rw-r--r--include/asm-i386/local.h205
-rw-r--r--include/asm-i386/msr.h12
-rw-r--r--include/asm-i386/pgtable.h41
-rw-r--r--include/asm-i386/serial.h16
-rw-r--r--include/asm-i386/system.h234
-rw-r--r--include/asm-i386/termbits.h14
-rw-r--r--include/asm-i386/termios.h6
-rw-r--r--include/asm-i386/thread_info.h8
-rw-r--r--include/asm-i386/unistd.h3
-rw-r--r--include/asm-ia64/asmmacro.h10
-rw-r--r--include/asm-ia64/atomic.h53
-rw-r--r--include/asm-ia64/io.h6
-rw-r--r--include/asm-ia64/kdebug.h27
-rw-r--r--include/asm-ia64/kexec.h2
-rw-r--r--include/asm-ia64/kregs.h3
-rw-r--r--include/asm-ia64/local.h51
-rw-r--r--include/asm-ia64/pal.h33
-rw-r--r--include/asm-ia64/patch.h1
-rw-r--r--include/asm-ia64/pgtable.h4
-rw-r--r--include/asm-ia64/processor.h1
-rw-r--r--include/asm-ia64/sections.h1
-rw-r--r--include/asm-m32r/atomic.h23
-rw-r--r--include/asm-m32r/kdebug.h1
-rw-r--r--include/asm-m32r/pgtable.h4
-rw-r--r--include/asm-m32r/system.h2
-rw-r--r--include/asm-m68k/atomic.h31
-rw-r--r--include/asm-m68k/kdebug.h1
-rw-r--r--include/asm-m68k/pgtable.h4
-rw-r--r--include/asm-m68k/system.h1
-rw-r--r--include/asm-m68knommu/atomic.h25
-rw-r--r--include/asm-m68knommu/kdebug.h1
-rw-r--r--include/asm-m68knommu/pgtable.h4
-rw-r--r--include/asm-m68knommu/system.h1
-rw-r--r--include/asm-mips/atomic.h57
-rw-r--r--include/asm-mips/kdebug.h1
-rw-r--r--include/asm-mips/kexec.h2
-rw-r--r--include/asm-mips/local.h304
-rw-r--r--include/asm-mips/mach-au1x00/au1550_spi.h16
-rw-r--r--include/asm-mips/pgtable.h4
-rw-r--r--include/asm-mips/system.h126
-rw-r--r--include/asm-parisc/atomic.h56
-rw-r--r--include/asm-parisc/kdebug.h1
-rw-r--r--include/asm-parisc/local.h41
-rw-r--r--include/asm-parisc/pgtable.h4
-rw-r--r--include/asm-powerpc/atomic.h7
-rw-r--r--include/asm-powerpc/bitops.h1
-rw-r--r--include/asm-powerpc/iommu.h14
-rw-r--r--include/asm-powerpc/kdebug.h34
-rw-r--r--include/asm-powerpc/kexec.h2
-rw-r--r--include/asm-powerpc/kprobes.h7
-rw-r--r--include/asm-powerpc/local.h201
-rw-r--r--include/asm-powerpc/machdep.h19
-rw-r--r--include/asm-powerpc/mmu-44x.h78
-rw-r--r--include/asm-powerpc/mmu.h7
-rw-r--r--include/asm-powerpc/mpc52xx.h11
-rw-r--r--include/asm-powerpc/mpic.h20
-rw-r--r--include/asm-powerpc/of_device.h2
-rw-r--r--include/asm-powerpc/page.h10
-rw-r--r--include/asm-powerpc/page_32.h2
-rw-r--r--include/asm-powerpc/parport.h5
-rw-r--r--include/asm-powerpc/pgalloc-32.h41
-rw-r--r--include/asm-powerpc/pgalloc-64.h152
-rw-r--r--include/asm-powerpc/pgalloc.h154
-rw-r--r--include/asm-powerpc/pgtable-4k.h3
-rw-r--r--include/asm-powerpc/pgtable-64k.h5
-rw-r--r--include/asm-powerpc/pgtable-ppc32.h813
-rw-r--r--include/asm-powerpc/pgtable-ppc64.h492
-rw-r--r--include/asm-powerpc/pgtable.h493
-rw-r--r--include/asm-powerpc/pmac_feature.h2
-rw-r--r--include/asm-powerpc/prom.h34
-rw-r--r--include/asm-powerpc/ps3.h33
-rw-r--r--include/asm-powerpc/suspend.h9
-rw-r--r--include/asm-powerpc/system.h130
-rw-r--r--include/asm-powerpc/tsi108.h12
-rw-r--r--include/asm-powerpc/tsi108_pci.h45
-rw-r--r--include/asm-powerpc/udbg.h1
-rw-r--r--include/asm-ppc/kdebug.h1
-rw-r--r--include/asm-ppc/pgtable.h4
-rw-r--r--include/asm-ppc/system.h2
-rw-r--r--include/asm-s390/dma-mapping.h2
-rw-r--r--include/asm-s390/kdebug.h30
-rw-r--r--include/asm-s390/kexec.h2
-rw-r--r--include/asm-s390/qdio.h1
-rw-r--r--include/asm-sh/bug.h92
-rw-r--r--include/asm-sh/clock.h32
-rw-r--r--include/asm-sh/cpu-sh3/mmu_context.h1
-rw-r--r--include/asm-sh/cpu-sh4/freq.h8
-rw-r--r--include/asm-sh/irq.h91
-rw-r--r--include/asm-sh/kdebug.h36
-rw-r--r--include/asm-sh/kexec.h44
-rw-r--r--include/asm-sh/kgdb.h51
-rw-r--r--include/asm-sh/lboxre2.h27
-rw-r--r--include/asm-sh/mmu_context.h6
-rw-r--r--include/asm-sh/page.h10
-rw-r--r--include/asm-sh/param.h2
-rw-r--r--include/asm-sh/pci.h2
-rw-r--r--include/asm-sh/pgtable.h4
-rw-r--r--include/asm-sh/processor.h2
-rw-r--r--include/asm-sh/r7780rp.h76
-rw-r--r--include/asm-sh/se.h4
-rw-r--r--include/asm-sh/se7722.h118
-rw-r--r--include/asm-sh/se7751.h2
-rw-r--r--include/asm-sh/se7780.h108
-rw-r--r--include/asm-sh/stat.h19
-rw-r--r--include/asm-sh/system.h13
-rw-r--r--include/asm-sh64/kdebug.h1
-rw-r--r--include/asm-sh64/pgtable.h4
-rw-r--r--include/asm-sh64/system.h2
-rw-r--r--include/asm-sparc/kdebug.h4
-rw-r--r--include/asm-sparc/system.h1
-rw-r--r--include/asm-sparc64/Kbuild1
-rw-r--r--include/asm-sparc64/atomic.h53
-rw-r--r--include/asm-sparc64/const.h19
-rw-r--r--include/asm-sparc64/iommu.h1
-rw-r--r--include/asm-sparc64/kdebug.h23
-rw-r--r--include/asm-sparc64/local.h41
-rw-r--r--include/asm-sparc64/lsu.h2
-rw-r--r--include/asm-sparc64/mmu.h2
-rw-r--r--include/asm-sparc64/page.h2
-rw-r--r--include/asm-sparc64/pgalloc.h26
-rw-r--r--include/asm-sparc64/pgtable.h2
-rw-r--r--include/asm-sparc64/pstate.h2
-rw-r--r--include/asm-sparc64/sfafsr.h2
-rw-r--r--include/asm-sparc64/system.h1
-rw-r--r--include/asm-um/cmpxchg.h6
-rw-r--r--include/asm-um/kdebug.h1
-rw-r--r--include/asm-um/page.h3
-rw-r--r--include/asm-um/tlbflush.h24
-rw-r--r--include/asm-v850/kdebug.h1
-rw-r--r--include/asm-v850/system.h1
-rw-r--r--include/asm-x86_64/Kbuild1
-rw-r--r--include/asm-x86_64/atomic.h65
-rw-r--r--include/asm-x86_64/cmpxchg.h134
-rw-r--r--include/asm-x86_64/kdebug.h25
-rw-r--r--include/asm-x86_64/kexec.h2
-rw-r--r--include/asm-x86_64/local.h196
-rw-r--r--include/asm-x86_64/msr.h11
-rw-r--r--include/asm-x86_64/page.h27
-rw-r--r--include/asm-x86_64/pgtable.h21
-rw-r--r--include/asm-x86_64/serial.h16
-rw-r--r--include/asm-x86_64/system.h96
-rw-r--r--include/asm-x86_64/termbits.h2
-rw-r--r--include/asm-x86_64/unistd.h2
-rw-r--r--include/asm-xtensa/atomic.h23
-rw-r--r--include/asm-xtensa/kdebug.h1
-rw-r--r--include/asm-xtensa/system.h2
-rw-r--r--include/linux/Kbuild8
-rw-r--r--include/linux/awe_voice.h525
-rw-r--r--include/linux/buffer_head.h5
-rw-r--r--include/linux/byteorder/generic.h25
-rw-r--r--include/linux/byteorder/swab.h108
-rw-r--r--include/linux/clockchips.h10
-rw-r--r--include/linux/clocksource.h15
-rw-r--r--include/linux/compat_ioctl.h830
-rw-r--r--include/linux/compiler-gcc.h3
-rw-r--r--include/linux/compiler-gcc3.h6
-rw-r--r--include/linux/compiler-gcc4.h6
-rw-r--r--include/linux/compiler-intel.h5
-rw-r--r--include/linux/console.h7
-rw-r--r--include/linux/console_struct.h3
-rw-r--r--include/linux/const.h (renamed from include/asm-x86_64/const.h)9
-rw-r--r--include/linux/cpu.h3
-rw-r--r--include/linux/cyclades.h229
-rw-r--r--include/linux/dcache.h6
-rw-r--r--include/linux/device.h4
-rw-r--r--include/linux/display.h61
-rw-r--r--include/linux/dlm_device.h9
-rw-r--r--include/linux/ds1wm.h11
-rw-r--r--include/linux/efi.h1
-rw-r--r--include/linux/elf-em.h1
-rw-r--r--include/linux/etherdevice.h12
-rw-r--r--include/linux/ext3_fs.h1
-rw-r--r--include/linux/fb.h57
-rw-r--r--include/linux/fcntl.h4
-rw-r--r--include/linux/font.h3
-rw-r--r--include/linux/fs.h27
-rw-r--r--include/linux/futex.h29
-rw-r--r--include/linux/gfp.h3
-rw-r--r--include/linux/hugetlb.h6
-rw-r--r--include/linux/init.h5
-rw-r--r--include/linux/init_task.h2
-rw-r--r--include/linux/input.h4
-rw-r--r--include/linux/interrupt.h38
-rw-r--r--include/linux/ioctl32.h17
-rw-r--r--include/linux/ipc.h11
-rw-r--r--include/linux/irq.h4
-rw-r--r--include/linux/isdn/capiutil.h1
-rw-r--r--include/linux/isdn_divertif.h5
-rw-r--r--include/linux/kallsyms.h13
-rw-r--r--include/linux/kdebug.h20
-rw-r--r--include/linux/kernel.h3
-rw-r--r--include/linux/kexec.h17
-rw-r--r--include/linux/kprobes.h22
-rw-r--r--include/linux/kvm.h133
-rw-r--r--include/linux/libata.h40
-rw-r--r--include/linux/list.h11
-rw-r--r--include/linux/lockd/lockd.h14
-rw-r--r--include/linux/loop.h2
-rw-r--r--include/linux/mc146818rtc.h7
-rw-r--r--include/linux/migrate.h15
-rw-r--r--include/linux/miscdevice.h1
-rw-r--r--include/linux/mm.h55
-rw-r--r--include/linux/mm_types.h17
-rw-r--r--include/linux/mmzone.h12
-rw-r--r--include/linux/mnt_namespace.h5
-rw-r--r--include/linux/mod_devicetable.h1
-rw-r--r--include/linux/module.h30
-rw-r--r--include/linux/msdos_fs.h3
-rw-r--r--include/linux/nfs_fs_sb.h2
-rw-r--r--include/linux/nsproxy.h3
-rw-r--r--include/linux/page-flags.h41
-rw-r--r--include/linux/pagemap.h22
-rw-r--r--include/linux/parport.h8
-rw-r--r--include/linux/parport_pc.h3
-rw-r--r--include/linux/phantom.h42
-rw-r--r--include/linux/pid_namespace.h2
-rw-r--r--include/linux/pmu.h8
-rw-r--r--include/linux/pnp.h3
-rw-r--r--include/linux/poison.h7
-rw-r--r--include/linux/proc_fs.h4
-rw-r--r--include/linux/quicklist.h94
-rw-r--r--include/linux/quota.h4
-rw-r--r--include/linux/quotaops.h3
-rw-r--r--include/linux/reiserfs_fs_sb.h3
-rw-r--r--include/linux/rfkill.h89
-rw-r--r--include/linux/rtc.h39
-rw-r--r--include/linux/sched.h35
-rw-r--r--include/linux/serial_core.h10
-rw-r--r--include/linux/serial_reg.h2
-rw-r--r--include/linux/slab.h36
-rw-r--r--include/linux/slub_def.h206
-rw-r--r--include/linux/spi/Kbuild1
-rw-r--r--include/linux/spi/ad7877.h24
-rw-r--r--include/linux/spi/spi.h82
-rw-r--r--include/linux/spi/spidev.h124
-rw-r--r--include/linux/spinlock_types.h6
-rw-r--r--include/linux/stacktrace.h6
-rw-r--r--include/linux/stat.h3
-rw-r--r--include/linux/suspend.h37
-rw-r--r--include/linux/svga.h1
-rw-r--r--include/linux/sysdev.h1
-rw-r--r--include/linux/tifm.h1
-rw-r--r--include/linux/time.h3
-rw-r--r--include/linux/timer.h1
-rw-r--r--include/linux/tty.h2
-rw-r--r--include/linux/uinput.h2
-rw-r--r--include/linux/usb_sl811.h26
-rw-r--r--include/linux/utsname.h19
-rw-r--r--include/linux/vmalloc.h1
-rw-r--r--include/linux/vt_kern.h3
-rw-r--r--include/linux/workqueue.h6
-rw-r--r--include/math-emu/extended.h396
-rw-r--r--include/net/sock.h9
-rw-r--r--include/pcmcia/ds.h6
-rw-r--r--include/rdma/ib_verbs.h47
-rw-r--r--include/video/mach64.h1
-rw-r--r--include/video/permedia2.h4
-rw-r--r--include/video/tgafb.h47
-rw-r--r--init/Kconfig88
-rw-r--r--init/do_mounts.c1
-rw-r--r--init/do_mounts_initrd.c5
-rw-r--r--init/main.c29
-rw-r--r--ipc/compat.c4
-rw-r--r--ipc/mqueue.c3
-rw-r--r--ipc/sem.c1
-rw-r--r--ipc/util.c54
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/audit.c8
-rw-r--r--kernel/cpuset.c67
-rw-r--r--kernel/delayacct.c6
-rw-r--r--kernel/die_notifier.c38
-rw-r--r--kernel/exit.c18
-rw-r--r--kernel/fork.c89
-rw-r--r--kernel/futex.c106
-rw-r--r--kernel/hrtimer.c1
-rw-r--r--kernel/irq/handle.c4
-rw-r--r--kernel/irq/manage.c10
-rw-r--r--kernel/irq/proc.c15
-rw-r--r--kernel/irq/spurious.c4
-rw-r--r--kernel/itimer.c60
-rw-r--r--kernel/kallsyms.c81
-rw-r--r--kernel/kexec.c4
-rw-r--r--kernel/kmod.c7
-rw-r--r--kernel/kprobes.c293
-rw-r--r--kernel/lockdep.c51
-rw-r--r--kernel/module.c79
-rw-r--r--kernel/nsproxy.c139
-rw-r--r--kernel/params.c2
-rw-r--r--kernel/pid.c15
-rw-r--r--kernel/posix-cpu-timers.c14
-rw-r--r--kernel/posix-timers.c1
-rw-r--r--kernel/power/Kconfig15
-rw-r--r--kernel/power/disk.c63
-rw-r--r--kernel/power/main.c19
-rw-r--r--kernel/power/power.h42
-rw-r--r--kernel/power/process.c12
-rw-r--r--kernel/power/snapshot.c299
-rw-r--r--kernel/power/swap.c19
-rw-r--r--kernel/power/swsusp.c139
-rw-r--r--kernel/power/user.c39
-rw-r--r--kernel/printk.c27
-rw-r--r--kernel/rcutorture.c45
-rw-r--r--kernel/rwsem.c2
-rw-r--r--kernel/sched.c373
-rw-r--r--kernel/signal.c7
-rw-r--r--kernel/softlockup.c48
-rw-r--r--kernel/stop_machine.c8
-rw-r--r--kernel/sys.c21
-rw-r--r--kernel/sysctl.c11
-rw-r--r--kernel/taskstats.c4
-rw-r--r--kernel/time.c61
-rw-r--r--kernel/time/Makefile2
-rw-r--r--kernel/time/tick-common.c8
-rw-r--r--kernel/time/tick-internal.h1
-rw-r--r--kernel/time/tick-sched.c51
-rw-r--r--kernel/time/timekeeping.c476
-rw-r--r--kernel/time/timer_list.c15
-rw-r--r--kernel/time/timer_stats.c14
-rw-r--r--kernel/timer.c528
-rw-r--r--kernel/uid16.c1
-rw-r--r--kernel/utsname.c41
-rw-r--r--lib/Kconfig5
-rw-r--r--lib/Kconfig.debug34
-rw-r--r--lib/cpumask.c3
-rw-r--r--lib/fault-inject.c3
-rw-r--r--lib/swiotlb.c1
-rw-r--r--lib/vsprintf.c11
-rw-r--r--lib/zlib_inflate/inflate.c8
-rw-r--r--mm/Kconfig5
-rw-r--r--mm/Makefile3
-rw-r--r--mm/filemap.c175
-rw-r--r--mm/internal.h2
-rw-r--r--mm/madvise.c33
-rw-r--r--mm/memory.c106
-rw-r--r--mm/mmap.c44
-rw-r--r--mm/nommu.c8
-rw-r--r--mm/oom_kill.c17
-rw-r--r--mm/page-writeback.c57
-rw-r--r--mm/page_alloc.c78
-rw-r--r--mm/quicklist.c88
-rw-r--r--mm/readahead.c29
-rw-r--r--mm/rmap.c4
-rw-r--r--mm/shmem.c3
-rw-r--r--mm/slab.c245
-rw-r--r--mm/slob.c57
-rw-r--r--mm/slub.c3520
-rw-r--r--mm/sparse.c14
-rw-r--r--mm/swap.c2
-rw-r--r--mm/swapfile.c3
-rw-r--r--mm/vmalloc.c7
-rw-r--r--mm/vmscan.c21
-rw-r--r--net/Kconfig2
-rw-r--r--net/Makefile1
-rw-r--r--net/appletalk/ddp.c1
-rw-r--r--net/ax25/af_ax25.c1
-rw-r--r--net/bluetooth/bnep/core.c1
-rw-r--r--net/bluetooth/hci_sock.c9
-rw-r--r--net/bluetooth/hci_sysfs.c9
-rw-r--r--net/bluetooth/l2cap.c6
-rw-r--r--net/bluetooth/rfcomm/core.c29
-rw-r--r--net/bluetooth/rfcomm/tty.c11
-rw-r--r--net/bridge/br_stp.c1
-rw-r--r--net/bridge/br_stp_if.c1
-rw-r--r--net/bridge/br_stp_timer.c1
-rw-r--r--net/core/dev.c4
-rw-r--r--net/core/netpoll.c1
-rw-r--r--net/core/pktgen.c1
-rw-r--r--net/ipv4/af_inet.c1
-rw-r--r--net/ipv4/tcp.c1
-rw-r--r--net/ipv4/tcp_output.c1
-rw-r--r--net/ipv6/af_inet6.c1
-rw-r--r--net/ipv6/netfilter/Kconfig2
-rw-r--r--net/ipx/af_ipx.c1
-rw-r--r--net/irda/af_irda.c1
-rw-r--r--net/netfilter/Kconfig24
-rw-r--r--net/netlink/af_netlink.c1
-rw-r--r--net/rfkill/Kconfig24
-rw-r--r--net/rfkill/Makefile6
-rw-r--r--net/rfkill/rfkill-input.c174
-rw-r--r--net/rfkill/rfkill.c407
-rw-r--r--net/socket.c23
-rw-r--r--net/sunrpc/rpc_pipe.c3
-rw-r--r--net/sunrpc/sched.c8
-rw-r--r--net/tipc/Kconfig2
-rw-r--r--net/unix/af_unix.c1
-rw-r--r--net/x25/af_x25.c1
-rw-r--r--scripts/Makefile.build19
-rw-r--r--scripts/Makefile.host14
-rw-r--r--scripts/Makefile.modpost8
-rw-r--r--scripts/basic/fixdep.c2
-rwxr-xr-xscripts/checksyscalls.sh118
-rwxr-xr-xscripts/cleanfile126
-rwxr-xr-xscripts/cleanpatch206
-rw-r--r--scripts/gen_initramfs_list.sh12
-rw-r--r--scripts/genksyms/genksyms.c3
-rw-r--r--scripts/kconfig/Makefile5
-rw-r--r--scripts/kconfig/conf.c1
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped2
-rw-r--r--scripts/kconfig/lkc.h1
-rw-r--r--scripts/kconfig/lxdialog/dialog.h1
-rw-r--r--scripts/kconfig/lxdialog/util.c9
-rw-r--r--scripts/kconfig/mconf.c43
-rw-r--r--scripts/kconfig/menu.c2
-rw-r--r--scripts/kconfig/qconf.cc5
-rw-r--r--scripts/kconfig/qconf.h2
-rw-r--r--scripts/kconfig/symbol.c13
-rw-r--r--scripts/kconfig/zconf.l2
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped6
-rw-r--r--scripts/kconfig/zconf.y6
-rwxr-xr-xscripts/kernel-doc140
-rwxr-xr-xscripts/mkcompile_h27
-rwxr-xr-xscripts/mkuboot.sh2
-rw-r--r--scripts/mod/file2alias.c21
-rw-r--r--scripts/mod/mk_elfconfig.c3
-rw-r--r--scripts/mod/modpost.c166
-rw-r--r--scripts/mod/modpost.h1
-rw-r--r--scripts/mod/sumversion.c5
-rw-r--r--security/capability.c1
-rw-r--r--security/commoncap.c1
-rw-r--r--security/selinux/hooks.c8
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-onyx.c4
-rw-r--r--sound/aoa/codecs/snd-aoa-codec-tas.c2
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus-core.c4
-rw-r--r--sound/arm/pxa2xx-ac97.c12
-rw-r--r--sound/core/control.c1
-rw-r--r--sound/core/hwdep.c1
-rw-r--r--sound/core/oss/mixer_oss.c1
-rw-r--r--sound/core/oss/pcm_oss.c1
-rw-r--r--sound/core/pcm_native.c1
-rw-r--r--sound/core/rawmidi.c1
-rw-r--r--sound/core/seq/oss/seq_oss.c1
-rw-r--r--sound/core/seq/seq_clientmgr.c1
-rw-r--r--sound/core/timer.c1
-rw-r--r--sound/oss/Kconfig30
-rw-r--r--sound/oss/btaudio.c2
-rw-r--r--sound/oss/dmasound/Kconfig14
-rw-r--r--sound/oss/dmasound/dmasound_awacs.c16
-rw-r--r--sound/oss/sh_dac_audio.c2
-rw-r--r--sound/oss/swarm_cs4297a.c1
-rw-r--r--sound/oss/trident.c1
-rw-r--r--sound/oss/via82cxxx_audio.c1
-rw-r--r--sound/ppc/pmac.c14
-rw-r--r--sound/ppc/tumbler.c2
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c12
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c4
-rw-r--r--usr/Kconfig2
2539 files changed, 124341 insertions, 30771 deletions
diff --git a/CREDITS b/CREDITS
index c5f819b..80e2413 100644
--- a/CREDITS
+++ b/CREDITS
@@ -661,7 +661,7 @@ N: Kees Cook
E: kees@outflux.net
W: http://outflux.net/
P: 1024D/17063E6D 9FA3 C49C 23C9 D1BC 2E30 1975 1FFF 4BA9 1706 3E6D
-D: Minor updates to SCSI code for the Communications type
+D: Minor updates to SCSI types, added /proc/pid/maps protection
S: (ask for current address)
S: USA
@@ -2580,10 +2580,9 @@ S: Australia
N: Miguel Ojeda Sandonis
E: maxextreme@gmail.com
-D: Author: Auxiliary LCD Controller driver (ks0108)
-D: Author: Auxiliary LCD driver (cfag12864b)
-D: Author: Auxiliary LCD framebuffer driver (cfag12864bfb)
-D: Maintainer: Auxiliary display drivers tree (drivers/auxdisplay/*)
+W: http://maxextreme.googlepages.com/
+D: Author of the ks0108, cfag12864b and cfag12864bfb auxiliary display drivers.
+D: Maintainer of the auxiliary display drivers tree (drivers/auxdisplay/*)
S: C/ Mieses 20, 9-B
S: Valladolid 47009
S: Spain
diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle
index 9069189..afc2867 100644
--- a/Documentation/CodingStyle
+++ b/Documentation/CodingStyle
@@ -160,6 +160,21 @@ supply of new-lines on your screen is not a renewable resource (think
25-line terminal screens here), you have more empty lines to put
comments on.
+Do not unnecessarily use braces where a single statement will do.
+
+if (condition)
+ action();
+
+This does not apply if one branch of a conditional statement is a single
+statement. Use braces in both branches.
+
+if (condition) {
+ do_this();
+ do_that();
+} else {
+ otherwise();
+}
+
3.1: Spaces
Linux kernel style for use of spaces depends (mostly) on
@@ -625,7 +640,7 @@ language.
There appears to be a common misperception that gcc has a magic "make me
faster" speedup option called "inline". While the use of inlines can be
-appropriate (for example as a means of replacing macros, see Chapter 11), it
+appropriate (for example as a means of replacing macros, see Chapter 12), it
very often is not. Abundant use of the inline keyword leads to a much bigger
kernel, which in turn slows the system as a whole down, due to a bigger
icache footprint for the CPU and simply because there is less memory
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 867608a..6fd1646 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -41,8 +41,9 @@ psdocs: $(PS)
PDF := $(patsubst %.xml, %.pdf, $(BOOKS))
pdfdocs: $(PDF)
-HTML := $(patsubst %.xml, %.html, $(BOOKS))
+HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS)))
htmldocs: $(HTML)
+ $(call build_main_index)
MAN := $(patsubst %.xml, %.9, $(BOOKS))
mandocs: $(MAN)
@@ -132,10 +133,17 @@ quiet_cmd_db2pdf = PDF $@
%.pdf : %.xml
$(call cmd,db2pdf)
+
+main_idx = Documentation/DocBook/index.html
+build_main_index = rm -rf $(main_idx) && \
+ echo '<h1>Linux Kernel HTML Documentation</h1>' >> $(main_idx) && \
+ echo '<h2>Kernel Version: $(KERNELVERSION)</h2>' >> $(main_idx) && \
+ cat $(HTML) >> $(main_idx)
+
quiet_cmd_db2html = HTML $@
cmd_db2html = xmlto xhtml $(XMLTOFLAGS) -o $(patsubst %.html,%,$@) $< && \
echo '<a HREF="$(patsubst %.html,%,$(notdir $@))/index.html"> \
- Goto $(patsubst %.html,%,$(notdir $@))</a><p>' > $@
+ $(patsubst %.html,%,$(notdir $@))</a><p>' > $@
%.html: %.xml
@(which xmlto > /dev/null 2>&1) || \
@@ -152,6 +160,7 @@ quiet_cmd_db2man = MAN $@
@(which xmlto > /dev/null 2>&1) || \
(echo "*** You need to install xmlto ***"; \
exit 1)
+ $(Q)mkdir -p $(obj)/man
$(call cmd,db2man)
@touch $@
@@ -212,11 +221,7 @@ clean-files := $(DOCBOOKS) \
$(patsubst %.xml, %.9, $(DOCBOOKS)) \
$(C-procfs-example)
-clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS))
-
-#man put files in man subdir - traverse down
-subdir- := man/
-
+clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) man
# Declare the contents of the .PHONY variable as phony. We keep that
# information in a variable se we can use it in if_changed and friends.
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index b61dfc7..a2b2b4d 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -576,4 +576,67 @@ X!Idrivers/video/console/fonts.c
!Edrivers/input/ff-core.c
!Edrivers/input/ff-memless.c
</chapter>
+
+ <chapter id="spi">
+ <title>Serial Peripheral Interface (SPI)</title>
+ <para>
+ SPI is the "Serial Peripheral Interface", widely used with
+ embedded systems because it is a simple and efficient
+ interface: basically a multiplexed shift register.
+ Its three signal wires hold a clock (SCK, often in the range
+ of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and
+ a "Master In, Slave Out" (MISO) data line.
+ SPI is a full duplex protocol; for each bit shifted out the
+ MOSI line (one per clock) another is shifted in on the MISO line.
+ Those bits are assembled into words of various sizes on the
+ way to and from system memory.
+ An additional chipselect line is usually active-low (nCS);
+ four signals are normally used for each peripheral, plus
+ sometimes an interrupt.
+ </para>
+ <para>
+ The SPI bus facilities listed here provide a generalized
+ interface to declare SPI busses and devices, manage them
+ according to the standard Linux driver model, and perform
+ input/output operations.
+ At this time, only "master" side interfaces are supported,
+ where Linux talks to SPI peripherals and does not implement
+ such a peripheral itself.
+ (Interfaces to support implementing SPI slaves would
+ necessarily look different.)
+ </para>
+ <para>
+ The programming interface is structured around two kinds of driver,
+ and two kinds of device.
+ A "Controller Driver" abstracts the controller hardware, which may
+ be as simple as a set of GPIO pins or as complex as a pair of FIFOs
+ connected to dual DMA engines on the other side of the SPI shift
+ register (maximizing throughput). Such drivers bridge between
+ whatever bus they sit on (often the platform bus) and SPI, and
+ expose the SPI side of their device as a
+ <structname>struct spi_master</structname>.
+ SPI devices are children of that master, represented as a
+ <structname>struct spi_device</structname> and manufactured from
+ <structname>struct spi_board_info</structname> descriptors which
+ are usually provided by board-specific initialization code.
+ A <structname>struct spi_driver</structname> is called a
+ "Protocol Driver", and is bound to a spi_device using normal
+ driver model calls.
+ </para>
+ <para>
+ The I/O model is a set of queued messages. Protocol drivers
+ submit one or more <structname>struct spi_message</structname>
+ objects, which are processed and completed asynchronously.
+ (There are synchronous wrappers, however.) Messages are
+ built from one or more <structname>struct spi_transfer</structname>
+ objects, each of which wraps a full duplex SPI transfer.
+ A variety of protocol tweaking options are needed, because
+ different chips adopt very different policies for how they
+ use the bits transferred with SPI.
+ </para>
+!Iinclude/linux/spi/spi.h
+!Fdrivers/spi/spi.c spi_register_board_info
+!Edrivers/spi/spi.c
+ </chapter>
+
</book>
diff --git a/Documentation/DocBook/librs.tmpl b/Documentation/DocBook/librs.tmpl
index 3ff39ba..94f2136 100644
--- a/Documentation/DocBook/librs.tmpl
+++ b/Documentation/DocBook/librs.tmpl
@@ -79,12 +79,12 @@
<chapter id="usage">
<title>Usage</title>
<para>
- This chapter provides examples how to use the library.
+ This chapter provides examples of how to use the library.
</para>
<sect1>
<title>Initializing</title>
<para>
- The init function init_rs returns a pointer to a
+ The init function init_rs returns a pointer to an
rs decoder structure, which holds the necessary
information for encoding, decoding and error correction
with the given polynomial. It either uses an existing
@@ -98,10 +98,10 @@
static struct rs_control *rs_decoder;
/* Symbolsize is 10 (bits)
- * Primitve polynomial is x^10+x^3+1
+ * Primitive polynomial is x^10+x^3+1
* first consecutive root is 0
- * primitve element to generate roots = 1
- * generator polinomial degree (number of roots) = 6
+ * primitive element to generate roots = 1
+ * generator polynomial degree (number of roots) = 6
*/
rs_decoder = init_rs (10, 0x409, 0, 1, 6);
</programlisting>
@@ -116,12 +116,12 @@ rs_decoder = init_rs (10, 0x409, 0, 1, 6);
</para>
<para>
The expanded data can be inverted on the fly by
- providing a non zero inversion mask. The expanded data is
+ providing a non-zero inversion mask. The expanded data is
XOR'ed with the mask. This is used e.g. for FLASH
ECC, where the all 0xFF is inverted to an all 0x00.
The Reed-Solomon code for all 0x00 is all 0x00. The
code is inverted before storing to FLASH so it is 0xFF
- too. This prevent's that reading from an erased FLASH
+ too. This prevents that reading from an erased FLASH
results in ECC errors.
</para>
<para>
@@ -273,7 +273,7 @@ free_rs(rs_decoder);
May be used under the terms of the GNU General Public License (GPL)
</programlisting>
<para>
- The wrapper functions and interfaces are written by Thomas Gleixner
+ The wrapper functions and interfaces are written by Thomas Gleixner.
</para>
<para>
Many users have provided bugfixes, improvements and helping hands for testing.
diff --git a/Documentation/DocBook/man/Makefile b/Documentation/DocBook/man/Makefile
deleted file mode 100644
index 4fb7ea0..0000000
--- a/Documentation/DocBook/man/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-# Rules are put in Documentation/DocBook
-
-clean-files := *.9.gz *.sgml manpage.links manpage.refs
diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers
index 58bead0..d7e2642 100644
--- a/Documentation/SubmittingDrivers
+++ b/Documentation/SubmittingDrivers
@@ -87,6 +87,21 @@ Clarity: It helps if anyone can see how to fix the driver. It helps
driver that intentionally obfuscates how the hardware works
it will go in the bitbucket.
+PM support: Since Linux is used on many portable and desktop systems, your
+ driver is likely to be used on such a system and therefore it
+ should support basic power management by implementing, if
+ necessary, the .suspend and .resume methods used during the
+ system-wide suspend and resume transitions. You should verify
+ that your driver correctly handles the suspend and resume, but
+ if you are unable to ensure that, please at least define the
+ .suspend method returning the -ENOSYS ("Function not
+ implemented") error. You should also try to make sure that your
+ driver uses as little power as possible when it's not doing
+ anything. For the driver testing instructions see
+ Documentation/power/drivers-testing.txt and for a relatively
+ complete overview of the power management issues related to
+ drivers see Documentation/power/devices.txt .
+
Control: In general if there is active maintainance of a driver by
the author then patches will be redirected to them unless
they are totally obvious and without need of checking.
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
index e9126e7..71acc28 100644
--- a/Documentation/accounting/getdelays.c
+++ b/Documentation/accounting/getdelays.c
@@ -61,8 +61,6 @@ __u64 stime, utime;
#define MAX_MSG_SIZE 1024
/* Maximum number of cpus expected to be specified in a cpumask */
#define MAX_CPUS 32
-/* Maximum length of pathname to log file */
-#define MAX_FILENAME 256
struct msgtemplate {
struct nlmsghdr n;
@@ -72,6 +70,16 @@ struct msgtemplate {
char cpumask[100+6*MAX_CPUS];
+static void usage(void)
+{
+ fprintf(stderr, "getdelays [-dilv] [-w logfile] [-r bufsize] "
+ "[-m cpumask] [-t tgid] [-p pid]\n");
+ fprintf(stderr, " -d: print delayacct stats\n");
+ fprintf(stderr, " -i: print IO accounting (works only with -p)\n");
+ fprintf(stderr, " -l: listen forever\n");
+ fprintf(stderr, " -v: debug on\n");
+}
+
/*
* Create a raw netlink socket and bind
*/
@@ -221,13 +229,13 @@ int main(int argc, char *argv[])
int count = 0;
int write_file = 0;
int maskset = 0;
- char logfile[128];
+ char *logfile = NULL;
int loop = 0;
struct msgtemplate msg;
while (1) {
- c = getopt(argc, argv, "diw:r:m:t:p:v:l");
+ c = getopt(argc, argv, "diw:r:m:t:p:vl");
if (c < 0)
break;
@@ -241,7 +249,7 @@ int main(int argc, char *argv[])
print_io_accounting = 1;
break;
case 'w':
- strncpy(logfile, optarg, MAX_FILENAME);
+ logfile = strdup(optarg);
printf("write to file %s\n", logfile);
write_file = 1;
break;
@@ -277,7 +285,7 @@ int main(int argc, char *argv[])
loop = 1;
break;
default:
- printf("Unknown option %d\n", c);
+ usage();
exit(-1);
}
}
diff --git a/Documentation/blackfin/00-INDEX b/Documentation/blackfin/00-INDEX
new file mode 100644
index 0000000..7cb3b35
--- /dev/null
+++ b/Documentation/blackfin/00-INDEX
@@ -0,0 +1,11 @@
+00-INDEX
+ - This file
+
+cache-lock.txt
+ - HOWTO for blackfin cache locking.
+
+cachefeatures.txt
+ - Supported cache features.
+
+Filesystems
+ - Requirements for mounting the root file system.
diff --git a/Documentation/blackfin/Filesystems b/Documentation/blackfin/Filesystems
new file mode 100644
index 0000000..51260a1
--- /dev/null
+++ b/Documentation/blackfin/Filesystems
@@ -0,0 +1,169 @@
+/*
+ * File: Documentation/blackfin/Filesystems
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: This file contains the simple DMA Implementation for Blackfin
+ *
+ * Rev: $Id: Filesystems 2384 2006-11-01 04:12:43Z magicyang $
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ */
+
+ How to mount the root file system in uClinux/Blackfin
+ -----------------------------------------------------
+
+1 Mounting EXT3 File system.
+ ------------------------
+
+ Creating an EXT3 File system for uClinux/Blackfin:
+
+
+Please follow the steps to form the EXT3 File system and mount the same as root
+file system.
+
+a Make an ext3 file system as large as you want the final root file
+ system.
+
+ mkfs.ext3 /dev/ram0 <your-rootfs-size-in-1k-blocks>
+
+b Mount this Empty file system on a free directory as:
+
+ mount -t ext3 /dev/ram0 ./test
+ where ./test is the empty directory.
+
+c Copy your root fs directory that you have so carefully made over.
+
+ cp -af /tmp/my_final_rootfs_files/* ./test
+
+ (For ex: cp -af uClinux-dist/romfs/* ./test)
+
+d If you have done everything right till now you should be able to see
+ the required "root" dir's (that's etc, root, bin, lib, sbin...)
+
+e Now unmount the file system
+
+ umount ./test
+
+f Create the root file system image.
+
+ dd if=/dev/ram0 bs=1k count=<your-rootfs-size-in-1k-blocks> \
+ > ext3fs.img
+
+
+Now you have to tell the kernel that will be mounting this file system as
+rootfs.
+So do a make menuconfig under kernel and select the Ext3 journaling file system
+support under File system --> submenu.
+
+
+2. Mounting EXT2 File system.
+ -------------------------
+
+By default the ext2 file system image will be created if you invoke make from
+the top uClinux-dist directory.
+
+
+3. Mounting CRAMFS File System
+ ----------------------------
+
+To create a CRAMFS file system image execute the command
+
+ mkfs.cramfs ./test cramfs.img
+
+ where ./test is the target directory.
+
+
+4. Mounting ROMFS File System
+ --------------------------
+
+To create a ROMFS file system image execute the command
+
+ genromfs -v -V "ROMdisk" -f romfs.img -d ./test
+
+ where ./test is the target directory
+
+
+5. Mounting the JFFS2 Filesystem
+ -----------------------------
+
+To create a compressed JFFS filesystem (JFFS2), please execute the command
+
+ mkfs.jffs2 -d ./test -o jffs2.img
+
+ where ./test is the target directory.
+
+However, please make sure the following is in your kernel config.
+
+/*
+ * RAM/ROM/Flash chip drivers
+ */
+#define CONFIG_MTD_CFI 1
+#define CONFIG_MTD_ROM 1
+/*
+ * Mapping drivers for chip access
+ */
+#define CONFIG_MTD_COMPLEX_MAPPINGS 1
+#define CONFIG_MTD_BF533 1
+#undef CONFIG_MTD_UCLINUX
+
+Through the u-boot boot loader, use the jffs2.img in the corresponding
+partition made in linux-2.6.x/drivers/mtd/maps/bf533_flash.c.
+
+NOTE - Currently the Flash driver is available only for EZKIT. Watch out for a
+ STAMP driver soon.
+
+
+6. Mounting the NFS File system
+ -----------------------------
+
+ For mounting the NFS please do the following in the kernel config.
+
+ In Networking Support --> Networking options --> TCP/IP networking -->
+ IP: kernel level autoconfiguration
+
+ Enable BOOTP Support.
+
+ In Kernel hacking --> Compiled-in kernel boot parameter add the following
+
+ root=/dev/nfs rw ip=bootp
+
+ In File system --> Network File system, Enable
+
+ NFS file system support --> NFSv3 client support
+ Root File system on NFS
+
+ in uClibc menuconfig, do the following
+ In Networking Support
+ enable Remote Procedure Call (RPC) support
+ Full RPC Support
+
+ On the Host side, ensure that /etc/dhcpd.conf looks something like this
+
+ ddns-update-style ad-hoc;
+ allow bootp;
+ subnet 10.100.4.0 netmask 255.255.255.0 {
+ default-lease-time 122209600;
+ max-lease-time 31557600;
+ group {
+ host bf533 {
+ hardware ethernet 00:CF:52:49:C3:01;
+ fixed-address 10.100.4.50;
+ option root-path "/home/nfsmount";
+ }
+ }
+
+ ensure that /etc/exports looks something like this
+ /home/nfsmount *(rw,no_root_squash,no_all_squash)
+
+ run the following commands as root (may differ depending on your
+ distribution) :
+ - service nfs start
+ - service portmap start
+ - service dhcpd start
+ - /usr/sbin/exportfs
diff --git a/Documentation/blackfin/cache-lock.txt b/Documentation/blackfin/cache-lock.txt
new file mode 100644
index 0000000..88ba1e6
--- /dev/null
+++ b/Documentation/blackfin/cache-lock.txt
@@ -0,0 +1,48 @@
+/*
+ * File: Documentation/blackfin/cache-lock.txt
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: This file contains the simple DMA Implementation for Blackfin
+ *
+ * Rev: $Id: cache-lock.txt 2384 2006-11-01 04:12:43Z magicyang $
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ */
+
+How to lock your code in cache in uClinux/blackfin
+--------------------------------------------------
+
+There are only a few steps required to lock your code into the cache.
+Currently you can lock the code by Way.
+
+Below are the interface provided for locking the cache.
+
+
+1. cache_grab_lock(int Ways);
+
+This function grab the lock for locking your code into the cache specified
+by Ways.
+
+
+2. cache_lock(int Ways);
+
+This function should be called after your critical code has been executed.
+Once the critical code exits, the code is now loaded into the cache. This
+function locks the code into the cache.
+
+
+So, the example sequence will be:
+
+ cache_grab_lock(WAY0_L); /* Grab the lock */
+
+ critical_code(); /* Execute the code of interest */
+
+ cache_lock(WAY0_L); /* Lock the cache */
+
+Where WAY0_L signifies WAY0 locking.
diff --git a/Documentation/blackfin/cachefeatures.txt b/Documentation/blackfin/cachefeatures.txt
new file mode 100644
index 0000000..0fbec23
--- /dev/null
+++ b/Documentation/blackfin/cachefeatures.txt
@@ -0,0 +1,65 @@
+/*
+ * File: Documentation/blackfin/cachefeatures.txt
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: This file contains the simple DMA Implementation for Blackfin
+ *
+ * Rev: $Id: cachefeatures.txt 2384 2006-11-01 04:12:43Z magicyang $
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ */
+
+ - Instruction and Data cache initialization.
+ icache_init();
+ dcache_init();
+
+ - Instruction and Data cache Invalidation Routines, when flushing the
+ same is not required.
+ _icache_invalidate();
+ _dcache_invalidate();
+
+ Also, for invalidating the entire instruction and data cache, the below
+ routines are provided (another method for invalidation, refer page no 267 and 287 of
+ ADSP-BF533 Hardware Reference manual)
+
+ invalidate_entire_dcache();
+ invalidate_entire_icache();
+
+ -External Flushing of Instruction and data cache routines.
+
+ flush_instruction_cache();
+ flush_data_cache();
+
+ - Internal Flushing of Instruction and Data Cache.
+
+ icplb_flush();
+ dcplb_flush();
+
+ - Locking the cache.
+
+ cache_grab_lock();
+ cache_lock();
+
+ Please refer linux-2.6.x/Documentation/blackfin/cache-lock.txt for how to
+ lock the cache.
+
+ Locking the cache is optional feature.
+
+ - Miscellaneous cache functions.
+
+ flush_cache_all();
+ flush_cache_mm();
+ invalidate_dcache_range();
+ flush_dcache_range();
+ flush_dcache_page();
+ flush_cache_range();
+ flush_cache_page();
+ invalidate_dcache_range();
+ flush_page_to_ram();
+
diff --git a/Documentation/cciss.txt b/Documentation/cciss.txt
index f74affe..e65736c 100644
--- a/Documentation/cciss.txt
+++ b/Documentation/cciss.txt
@@ -22,14 +22,21 @@ This driver is known to work with the following cards:
* SA E200i
* SA E500
-If nodes are not already created in the /dev/cciss directory, run as root:
+Detecting drive failures:
+-------------------------
-# cd /dev
-# ./MAKEDEV cciss
+To get the status of logical volumes and to detect physical drive
+failures, you can use the cciss_vol_status program found here:
+http://cciss.sourceforge.net/#cciss_utils
Device Naming:
--------------
+If nodes are not already created in the /dev/cciss directory, run as root:
+
+# cd /dev
+# ./MAKEDEV cciss
+
You need some entries in /dev for the cciss device. The MAKEDEV script
can make device nodes for you automatically. Currently the device setup
is as follows:
diff --git a/Documentation/fb/deferred_io.txt b/Documentation/fb/deferred_io.txt
new file mode 100644
index 0000000..73cf9fb
--- /dev/null
+++ b/Documentation/fb/deferred_io.txt
@@ -0,0 +1,75 @@
+Deferred IO
+-----------
+
+Deferred IO is a way to delay and repurpose IO. It uses host memory as a
+buffer and the MMU pagefault as a pretrigger for when to perform the device
+IO. The following example may be a useful explaination of how one such setup
+works:
+
+- userspace app like Xfbdev mmaps framebuffer
+- deferred IO and driver sets up nopage and page_mkwrite handlers
+- userspace app tries to write to mmaped vaddress
+- we get pagefault and reach nopage handler
+- nopage handler finds and returns physical page
+- we get page_mkwrite where we add this page to a list
+- schedule a workqueue task to be run after a delay
+- app continues writing to that page with no additional cost. this is
+ the key benefit.
+- the workqueue task comes in and mkcleans the pages on the list, then
+ completes the work associated with updating the framebuffer. this is
+ the real work talking to the device.
+- app tries to write to the address (that has now been mkcleaned)
+- get pagefault and the above sequence occurs again
+
+As can be seen from above, one benefit is roughly to allow bursty framebuffer
+writes to occur at minimum cost. Then after some time when hopefully things
+have gone quiet, we go and really update the framebuffer which would be
+a relatively more expensive operation.
+
+For some types of nonvolatile high latency displays, the desired image is
+the final image rather than the intermediate stages which is why it's okay
+to not update for each write that is occuring.
+
+It may be the case that this is useful in other scenarios as well. Paul Mundt
+has mentioned a case where it is beneficial to use the page count to decide
+whether to coalesce and issue SG DMA or to do memory bursts.
+
+Another one may be if one has a device framebuffer that is in an usual format,
+say diagonally shifting RGB, this may then be a mechanism for you to allow
+apps to pretend to have a normal framebuffer but reswizzle for the device
+framebuffer at vsync time based on the touched pagelist.
+
+How to use it: (for applications)
+---------------------------------
+No changes needed. mmap the framebuffer like normal and just use it.
+
+How to use it: (for fbdev drivers)
+----------------------------------
+The following example may be helpful.
+
+1. Setup your structure. Eg:
+
+static struct fb_deferred_io hecubafb_defio = {
+ .delay = HZ,
+ .deferred_io = hecubafb_dpy_deferred_io,
+};
+
+The delay is the minimum delay between when the page_mkwrite trigger occurs
+and when the deferred_io callback is called. The deferred_io callback is
+explained below.
+
+2. Setup your deferred IO callback. Eg:
+static void hecubafb_dpy_deferred_io(struct fb_info *info,
+ struct list_head *pagelist)
+
+The deferred_io callback is where you would perform all your IO to the display
+device. You receive the pagelist which is the list of pages that were written
+to during the delay. You must not modify this list. This callback is called
+from a workqueue.
+
+3. Call init
+ info->fbdefio = &hecubafb_defio;
+ fb_deferred_io_init(info);
+
+4. Call cleanup
+ fb_deferred_io_cleanup(info);
diff --git a/Documentation/fb/s3fb.txt b/Documentation/fb/s3fb.txt
index 8a04c0d..2c97770 100644
--- a/Documentation/fb/s3fb.txt
+++ b/Documentation/fb/s3fb.txt
@@ -35,10 +35,12 @@ Supported Features
* suspend/resume support
* DPMS support
-Text mode is supported even in higher resolutions, but there is limitation
-to lower pixclocks (maximum between 50-60 MHz, depending on specific hardware).
-This limitation is not enforced by driver. Text mode supports 8bit wide fonts
-only (hardware limitation) and 16bit tall fonts (driver limitation).
+Text mode is supported even in higher resolutions, but there is limitation to
+lower pixclocks (maximum usually between 50-60 MHz, depending on specific
+hardware, i get best results from plain S3 Trio32 card - about 75 MHz). This
+limitation is not enforced by driver. Text mode supports 8bit wide fonts only
+(hardware limitation) and 16bit tall fonts (driver limitation). Text mode
+support is broken on S3 Trio64 V2/DX.
There are two 4 bpp modes. First mode (selected if nonstd == 0) is mode with
packed pixels, high nibble first. Second mode (selected if nonstd == 1) is mode
@@ -73,6 +75,8 @@ Known bugs
==========
* cursor disable in text mode doesn't work
+ * text mode broken on S3 Trio64 V2/DX
+
--
Ondrej Zajicek <santiago@crfreenet.org>
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 94fd03f..676b798 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -6,6 +6,14 @@ be removed from this file.
---------------------------
+What: MXSER
+When: December 2007
+Why: Old mxser driver is obsoleted by the mxser_new. Give it some time yet
+ and remove it.
+Who: Jiri Slaby <jirislaby@gmail.com>
+
+---------------------------
+
What: V4L2 VIDIOC_G_MPEGCOMP and VIDIOC_S_MPEGCOMP
When: October 2007
Why: Broken attempt to set MPEG compression parameters. These ioctls are
@@ -126,18 +134,6 @@ Who: Adrian Bunk <bunk@stusta.de>
---------------------------
-What: Usage of invalid timevals in setitimer
-When: March 2007
-Why: POSIX requires to validate timevals in the setitimer call. This
- was never done by Linux. The invalid (e.g. negative timevals) were
- silently converted to more or less random timeouts and intervals.
- Until the removal a per boot limited number of warnings is printed
- and the timevals are sanitized.
-
-Who: Thomas Gleixner <tglx@linutronix.de>
-
----------------------------
-
What: Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports
(temporary transition config option provided until then)
The transition config option will also be removed at the same time.
@@ -165,7 +161,7 @@ Who: Greg Kroah-Hartman <gregkh@suse.de>
---------------------------
What: Interrupt only SA_* flags
-When: Januar 2007
+When: September 2007
Why: The interrupt related SA_* flags are replaced by IRQF_* to move them
out of the signal namespace.
@@ -332,3 +328,11 @@ Why: Obsolete. The new i2c-gpio driver replaces all hardware-specific
Who: Jean Delvare <khali@linux-fr.org>
---------------------------
+
+What: drivers depending on OSS_OBSOLETE
+When: options in 2.6.23, code in 2.6.25
+Why: obsolete OSS drivers
+Who: Adrian Bunk <bunk@stusta.de>
+
+---------------------------
+
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 28bfea7..59c1415 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -15,6 +15,7 @@ prototypes:
int (*d_delete)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
+ char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
locking rules:
none have BKL
@@ -25,6 +26,7 @@ d_compare: no yes no no
d_delete: yes no yes no
d_release: no no no yes
d_iput: no no no yes
+d_dname: no no no no
--------------------------- inode_operations ---------------------------
prototypes:
diff --git a/Documentation/filesystems/jfs.txt b/Documentation/filesystems/jfs.txt
index bae1286..26ebde7 100644
--- a/Documentation/filesystems/jfs.txt
+++ b/Documentation/filesystems/jfs.txt
@@ -29,7 +29,13 @@ errors=continue Keep going on a filesystem error.
errors=remount-ro Default. Remount the filesystem read-only on an error.
errors=panic Panic and halt the machine if an error occurs.
-Please send bugs, comments, cards and letters to shaggy@austin.ibm.com.
+uid=value Override on-disk uid with specified value
+gid=value Override on-disk gid with specified value
+umask=value Override on-disk umask with specified octal value. For
+ directories, the execute bit will be set if the corresponding
+ read bit is set.
+
+Please send bugs, comments, cards and letters to shaggy@linux.vnet.ibm.com.
The JFS mailing list can be subscribed to by using the link labeled
"Mail list Subscribe" at our web page http://jfs.sourceforge.net/
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 7aaf09b..4f3e84c 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -122,21 +122,22 @@ subdirectory has the entries listed in Table 1-1.
Table 1-1: Process specific entries in /proc
..............................................................................
- File Content
- cmdline Command line arguments
- cpu Current and last cpu in which it was executed (2.4)(smp)
- cwd Link to the current working directory
- environ Values of environment variables
- exe Link to the executable of this process
- fd Directory, which contains all file descriptors
- maps Memory maps to executables and library files (2.4)
- mem Memory held by this process
- root Link to the root directory of this process
- stat Process status
- statm Process memory status information
- status Process status in human readable form
- wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan
- smaps Extension based on maps, presenting the rss size for each mapped file
+ File Content
+ clear_refs Clears page referenced bits shown in smaps output
+ cmdline Command line arguments
+ cpu Current and last cpu in which it was executed (2.4)(smp)
+ cwd Link to the current working directory
+ environ Values of environment variables
+ exe Link to the executable of this process
+ fd Directory, which contains all file descriptors
+ maps Memory maps to executables and library files (2.4)
+ mem Memory held by this process
+ root Link to the root directory of this process
+ stat Process status
+ statm Process memory status information
+ status Process status in human readable form
+ wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan
+ smaps Extension based on maps, the rss size for each mapped file
..............................................................................
For example, to get the status information of a process, all you have to do is
@@ -1137,6 +1138,13 @@ determine whether or not they are still functioning properly.
Because the NMI watchdog shares registers with oprofile, by disabling the NMI
watchdog, oprofile may have more registers to utilize.
+maps_protect
+------------
+
+Enables/Disables the protection of the per-process proc entries "maps" and
+"smaps". When enabled, the contents of these files are visible only to
+readers that are allowed to ptrace() the given process.
+
2.4 /proc/sys/vm - The virtual memory subsystem
-----------------------------------------------
diff --git a/Documentation/filesystems/vfat.txt b/Documentation/filesystems/vfat.txt
index 069cb10..fcc123f 100644
--- a/Documentation/filesystems/vfat.txt
+++ b/Documentation/filesystems/vfat.txt
@@ -57,6 +57,13 @@ nonumtail=<bool> -- When creating 8.3 aliases, normally the alias will
currently exist in the directory, 'longfile.txt' will
be the short alias instead of 'longfi~1.txt'.
+usefree -- Use the "free clusters" value stored on FSINFO. It'll
+ be used to determine number of free clusters without
+ scanning disk. But it's not used by default, because
+ recent Windows don't update it correctly in some
+ case. If you are sure the "free clusters" on FSINFO is
+ correct, by this option you can avoid scanning disk.
+
quiet -- Stops printing certain warning messages.
check=s|r|n -- Case sensitivity checking setting.
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index ea271f2..a47cc81 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -827,7 +827,7 @@ This describes how a filesystem can overload the standard dentry
operations. Dentries and the dcache are the domain of the VFS and the
individual filesystem implementations. Device drivers have no business
here. These methods may be set to NULL, as they are either optional or
-the VFS uses a default. As of kernel 2.6.13, the following members are
+the VFS uses a default. As of kernel 2.6.22, the following members are
defined:
struct dentry_operations {
@@ -837,6 +837,7 @@ struct dentry_operations {
int (*d_delete)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
+ char *(*d_dname)(struct dentry *, char *, int);
};
d_revalidate: called when the VFS needs to revalidate a dentry. This
@@ -859,6 +860,26 @@ struct dentry_operations {
VFS calls iput(). If you define this method, you must call
iput() yourself
+ d_dname: called when the pathname of a dentry should be generated.
+ Usefull for some pseudo filesystems (sockfs, pipefs, ...) to delay
+ pathname generation. (Instead of doing it when dentry is created,
+ its done only when the path is needed.). Real filesystems probably
+ dont want to use it, because their dentries are present in global
+ dcache hash, so their hash should be an invariant. As no lock is
+ held, d_dname() should not try to modify the dentry itself, unless
+ appropriate SMP safety is used. CAUTION : d_path() logic is quite
+ tricky. The correct way to return for example "Hello" is to put it
+ at the end of the buffer, and returns a pointer to the first char.
+ dynamic_dname() helper function is provided to take care of this.
+
+Example :
+
+static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen)
+{
+ return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
+ dentry->d_inode->i_ino);
+}
+
Each dentry has a pointer to its parent dentry, as well as a hash list
of child dentries. Child dentries are basically like files in a
directory.
diff --git a/Documentation/hwmon/coretemp b/Documentation/hwmon/coretemp
new file mode 100644
index 0000000..870cda9
--- /dev/null
+++ b/Documentation/hwmon/coretemp
@@ -0,0 +1,36 @@
+Kernel driver coretemp
+======================
+
+Supported chips:
+ * All Intel Core family
+ Prefix: 'coretemp'
+ CPUID: family 0x6, models 0xe, 0xf
+ Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual
+ Volume 3A: System Programming Guide
+
+Author: Rudolf Marek
+
+Description
+-----------
+
+This driver permits reading temperature sensor embedded inside Intel Core CPU.
+Temperature is measured in degrees Celsius and measurement resolution is
+1 degree C. Valid temperatures are from 0 to TjMax degrees C, because
+the actual value of temperature register is in fact a delta from TjMax.
+
+Temperature known as TjMax is the maximum junction temperature of processor.
+Intel defines this temperature as 85C or 100C. At this temperature, protection
+mechanism will perform actions to forcibly cool down the processor. Alarm
+may be raised, if the temperature grows enough (more than TjMax) to trigger
+the Out-Of-Spec bit. Following table summarizes the exported sysfs files:
+
+temp1_input - Core temperature (in millidegrees Celsius).
+temp1_crit - Maximum junction temperature (in millidegrees Celsius).
+temp1_crit_alarm - Set when Out-of-spec bit is set, never clears.
+ Correct CPU operation is no longer guaranteed.
+temp1_label - Contains string "Core X", where X is processor
+ number.
+
+The TjMax temperature is set to 85 degrees C if undocumented model specific
+register (UMSR) 0xee has bit 30 set. If not the TjMax is 100 degrees C as
+(sometimes) documented in processor datasheet.
diff --git a/Documentation/hwmon/max6650 b/Documentation/hwmon/max6650
new file mode 100644
index 0000000..8be7beb
--- /dev/null
+++ b/Documentation/hwmon/max6650
@@ -0,0 +1,53 @@
+Kernel driver max6650
+=====================
+
+Supported chips:
+ * Maxim 6650 / 6651
+ Prefix: 'max6650'
+ Addresses scanned: I2C 0x1b, 0x1f, 0x48, 0x4b
+ Datasheet: http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf
+
+Authors:
+ Hans J. Koch <hjk@linutronix.de>
+ John Morris <john.morris@spirentcom.com>
+ Claus Gindhart <claus.gindhart@kontron.com>
+
+Description
+-----------
+
+This driver implements support for the Maxim 6650/6651
+
+The 2 devices are very similar, but the Maxim 6550 has a reduced feature
+set, e.g. only one fan-input, instead of 4 for the 6651.
+
+The driver is not able to distinguish between the 2 devices.
+
+The driver provides the following sensor accesses in sysfs:
+
+fan1_input ro fan tachometer speed in RPM
+fan2_input ro "
+fan3_input ro "
+fan4_input ro "
+fan1_target rw desired fan speed in RPM (closed loop mode only)
+pwm1_enable rw regulator mode, 0=full on, 1=open loop, 2=closed loop
+pwm1 rw relative speed (0-255), 255=max. speed.
+ Used in open loop mode only.
+fan1_div rw sets the speed range the inputs can handle. Legal
+ values are 1, 2, 4, and 8. Use lower values for
+ faster fans.
+
+Module parameters
+-----------------
+
+If your board has a BIOS that initializes the MAX6650/6651 correctly, you can
+simply load your module without parameters. It won't touch the configuration
+registers then. If your board BIOS doesn't initialize the chip, or you want
+different settings, you can set the following parameters:
+
+voltage_12V: 5=5V fan, 12=12V fan, 0=don't change
+prescaler: Possible values are 1,2,4,8,16, or 0 for don't change
+clock: The clock frequency in Hz of the chip the driver should assume [254000]
+
+Please have a look at the MAX6650/6651 data sheet and make sure that you fully
+understand the meaning of these parameters before you attempt to change them.
+
diff --git a/Documentation/hwmon/smsc47m1 b/Documentation/hwmon/smsc47m1
index 04a1112..42c8431 100644
--- a/Documentation/hwmon/smsc47m1
+++ b/Documentation/hwmon/smsc47m1
@@ -14,6 +14,10 @@ Supported chips:
http://www.smsc.com/main/datasheets/47m14x.pdf
http://www.smsc.com/main/tools/discontinued/47m15x.pdf
http://www.smsc.com/main/datasheets/47m192.pdf
+ * SMSC LPC47M292
+ Addresses scanned: none, address read from Super I/O config space
+ Prefix: 'smsc47m2'
+ Datasheet: Not public
* SMSC LPC47M997
Addresses scanned: none, address read from Super I/O config space
Prefix: 'smsc47m1'
@@ -32,9 +36,10 @@ Description
The Standard Microsystems Corporation (SMSC) 47M1xx Super I/O chips
contain monitoring and PWM control circuitry for two fans.
-The 47M15x and 47M192 chips contain a full 'hardware monitoring block'
-in addition to the fan monitoring and control. The hardware monitoring
-block is not supported by the driver.
+The LPC47M15x, LPC47M192 and LPC47M292 chips contain a full 'hardware
+monitoring block' in addition to the fan monitoring and control. The
+hardware monitoring block is not supported by this driver, use the
+smsc47m192 driver for that.
No documentation is available for the 47M997, but it has the same device
ID as the 47M15x and 47M192 chips and seems to be compatible.
diff --git a/Documentation/hwmon/smsc47m192 b/Documentation/hwmon/smsc47m192
index 45d6453..6d54ecb 100644
--- a/Documentation/hwmon/smsc47m192
+++ b/Documentation/hwmon/smsc47m192
@@ -2,12 +2,13 @@ Kernel driver smsc47m192
========================
Supported chips:
- * SMSC LPC47M192 and LPC47M997
+ * SMSC LPC47M192, LPC47M15x, LPC47M292 and LPC47M997
Prefix: 'smsc47m192'
Addresses scanned: I2C 0x2c - 0x2d
Datasheet: The datasheet for LPC47M192 is publicly available from
http://www.smsc.com/
- The LPC47M997 is compatible for hardware monitoring.
+ The LPC47M15x, LPC47M292 and LPC47M997 are compatible for
+ hardware monitoring.
Author: Hartmut Rick <linux@rick.claranet.de>
Special thanks to Jean Delvare for careful checking
@@ -18,7 +19,7 @@ Description
-----------
This driver implements support for the hardware sensor capabilities
-of the SMSC LPC47M192 and LPC47M997 Super-I/O chips.
+of the SMSC LPC47M192 and compatible Super-I/O chips.
These chips support 3 temperature channels and 8 voltage inputs
as well as CPU voltage VID input.
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
index d73d2e8..a9a18ad 100644
--- a/Documentation/hwmon/sysfs-interface
+++ b/Documentation/hwmon/sysfs-interface
@@ -152,6 +152,13 @@ fan[1-*]_div Fan divisor.
Note that this is actually an internal clock divisor, which
affects the measurable speed range, not the read value.
+fan[1-*]_target
+ Desired fan speed
+ Unit: revolution/min (RPM)
+ RW
+ Only makes sense if the chip supports closed-loop fan speed
+ control based on the measured fan speed.
+
Also see the Alarms section for status flags associated with fans.
diff --git a/Documentation/ia64/aliasing-test.c b/Documentation/ia64/aliasing-test.c
new file mode 100644
index 0000000..3153167
--- /dev/null
+++ b/Documentation/ia64/aliasing-test.c
@@ -0,0 +1,247 @@
+/*
+ * Exercise /dev/mem mmap cases that have been troublesome in the past
+ *
+ * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+int sum;
+
+int map_mem(char *path, off_t offset, size_t length, int touch)
+{
+ int fd, rc;
+ void *addr;
+ int *c;
+
+ fd = open(path, O_RDWR);
+ if (fd == -1) {
+ perror(path);
+ return -1;
+ }
+
+ addr = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset);
+ if (addr == MAP_FAILED)
+ return 1;
+
+ if (touch) {
+ c = (int *) addr;
+ while (c < (int *) (offset + length))
+ sum += *c++;
+ }
+
+ rc = munmap(addr, length);
+ if (rc == -1) {
+ perror("munmap");
+ return -1;
+ }
+
+ close(fd);
+ return 0;
+}
+
+int scan_sysfs(char *path, char *file, off_t offset, size_t length, int touch)
+{
+ struct dirent **namelist;
+ char *name, *path2;
+ int i, n, r, rc, result = 0;
+ struct stat buf;
+
+ n = scandir(path, &namelist, 0, alphasort);
+ if (n < 0) {
+ perror("scandir");
+ return -1;
+ }
+
+ for (i = 0; i < n; i++) {
+ name = namelist[i]->d_name;
+
+ if (fnmatch(".", name, 0) == 0)
+ goto skip;
+ if (fnmatch("..", name, 0) == 0)
+ goto skip;
+
+ path2 = malloc(strlen(path) + strlen(name) + 3);
+ strcpy(path2, path);
+ strcat(path2, "/");
+ strcat(path2, name);
+
+ if (fnmatch(file, name, 0) == 0) {
+ rc = map_mem(path2, offset, length, touch);
+ if (rc == 0)
+ fprintf(stderr, "PASS: %s 0x%lx-0x%lx is %s\n", path2, offset, offset + length, touch ? "readable" : "mappable");
+ else if (rc > 0)
+ fprintf(stderr, "PASS: %s 0x%lx-0x%lx not mappable\n", path2, offset, offset + length);
+ else {
+ fprintf(stderr, "FAIL: %s 0x%lx-0x%lx not accessible\n", path2, offset, offset + length);
+ return rc;
+ }
+ } else {
+ r = lstat(path2, &buf);
+ if (r == 0 && S_ISDIR(buf.st_mode)) {
+ rc = scan_sysfs(path2, file, offset, length, touch);
+ if (rc < 0)
+ return rc;
+ }
+ }
+
+ result |= rc;
+ free(path2);
+
+skip:
+ free(namelist[i]);
+ }
+ free(namelist);
+ return rc;
+}
+
+char buf[1024];
+
+int read_rom(char *path)
+{
+ int fd, rc;
+ size_t size = 0;
+
+ fd = open(path, O_RDWR);
+ if (fd == -1) {
+ perror(path);
+ return -1;
+ }
+
+ rc = write(fd, "1", 2);
+ if (rc <= 0) {
+ perror("write");
+ return -1;
+ }
+
+ do {
+ rc = read(fd, buf, sizeof(buf));
+ if (rc > 0)
+ size += rc;
+ } while (rc > 0);
+
+ close(fd);
+ return size;
+}
+
+int scan_rom(char *path, char *file)
+{
+ struct dirent **namelist;
+ char *name, *path2;
+ int i, n, r, rc, result = 0;
+ struct stat buf;
+
+ n = scandir(path, &namelist, 0, alphasort);
+ if (n < 0) {
+ perror("scandir");
+ return -1;
+ }
+
+ for (i = 0; i < n; i++) {
+ name = namelist[i]->d_name;
+
+ if (fnmatch(".", name, 0) == 0)
+ goto skip;
+ if (fnmatch("..", name, 0) == 0)
+ goto skip;
+
+ path2 = malloc(strlen(path) + strlen(name) + 3);
+ strcpy(path2, path);
+ strcat(path2, "/");
+ strcat(path2, name);
+
+ if (fnmatch(file, name, 0) == 0) {
+ rc = read_rom(path2);
+
+ /*
+ * It's OK if the ROM is unreadable. Maybe there
+ * is no ROM, or some other error ocurred. The
+ * important thing is that no MCA happened.
+ */
+ if (rc > 0)
+ fprintf(stderr, "PASS: %s read %ld bytes\n", path2, rc);
+ else {
+ fprintf(stderr, "PASS: %s not readable\n", path2);
+ return rc;
+ }
+ } else {
+ r = lstat(path2, &buf);
+ if (r == 0 && S_ISDIR(buf.st_mode)) {
+ rc = scan_rom(path2, file);
+ if (rc < 0)
+ return rc;
+ }
+ }
+
+ result |= rc;
+ free(path2);
+
+skip:
+ free(namelist[i]);
+ }
+ free(namelist);
+ return rc;
+}
+
+main()
+{
+ int rc;
+
+ if (map_mem("/dev/mem", 0, 0xA0000, 1) == 0)
+ fprintf(stderr, "PASS: /dev/mem 0x0-0xa0000 is readable\n");
+ else
+ fprintf(stderr, "FAIL: /dev/mem 0x0-0xa0000 not accessible\n");
+
+ /*
+ * It's not safe to blindly read the VGA frame buffer. If you know
+ * how to poke the card the right way, it should respond, but it's
+ * not safe in general. Many machines, e.g., Intel chipsets, cover
+ * up a non-responding card by just returning -1, but others will
+ * report the failure as a machine check.
+ */
+ if (map_mem("/dev/mem", 0xA0000, 0x20000, 0) == 0)
+ fprintf(stderr, "PASS: /dev/mem 0xa0000-0xc0000 is mappable\n");
+ else
+ fprintf(stderr, "FAIL: /dev/mem 0xa0000-0xc0000 not accessible\n");
+
+ if (map_mem("/dev/mem", 0xC0000, 0x40000, 1) == 0)
+ fprintf(stderr, "PASS: /dev/mem 0xc0000-0x100000 is readable\n");
+ else
+ fprintf(stderr, "FAIL: /dev/mem 0xc0000-0x100000 not accessible\n");
+
+ /*
+ * Often you can map all the individual pieces above (0-0xA0000,
+ * 0xA0000-0xC0000, and 0xC0000-0x100000), but can't map the whole
+ * thing at once. This is because the individual pieces use different
+ * attributes, and there's no single attribute supported over the
+ * whole region.
+ */
+ rc = map_mem("/dev/mem", 0, 1024*1024, 0);
+ if (rc == 0)
+ fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 is mappable\n");
+ else if (rc > 0)
+ fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 not mappable\n");
+ else
+ fprintf(stderr, "FAIL: /dev/mem 0x0-0x100000 not accessible\n");
+
+ scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1);
+ scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0);
+ scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1);
+ scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0);
+
+ scan_rom("/sys/devices", "rom");
+}
diff --git a/Documentation/ia64/aliasing.txt b/Documentation/ia64/aliasing.txt
index 38f9a52..9a431a7 100644
--- a/Documentation/ia64/aliasing.txt
+++ b/Documentation/ia64/aliasing.txt
@@ -112,16 +112,6 @@ POTENTIAL ATTRIBUTE ALIASING CASES
The /dev/mem mmap constraints apply.
- However, since this is for mapping legacy MMIO space, WB access
- does not make sense. This matters on machines without legacy
- VGA support: these machines may have WB memory for the entire
- first megabyte (or even the entire first granule).
-
- On these machines, we could mmap legacy_mem as WB, which would
- be safe in terms of attribute aliasing, but X has no way of
- knowing that it is accessing regular memory, not a frame buffer,
- so the kernel should fail the mmap rather than doing it with WB.
-
read/write of /dev/mem
This uses copy_from_user(), which implicitly uses a kernel
@@ -138,14 +128,20 @@ POTENTIAL ATTRIBUTE ALIASING CASES
ioremap()
- This returns a kernel identity mapping for use inside the
- kernel.
+ This returns a mapping for use inside the kernel.
If the region is in kern_memmap, we should use the attribute
- specified there. Otherwise, if the EFI memory map reports that
- the entire granule supports WB, we should use that (granules
- that are partially reserved or occupied by firmware do not appear
- in kern_memmap). Otherwise, we should use a UC mapping.
+ specified there.
+
+ If the EFI memory map reports that the entire granule supports
+ WB, we should use that (granules that are partially reserved
+ or occupied by firmware do not appear in kern_memmap).
+
+ If the granule contains non-WB memory, but we can cover the
+ region safely with kernel page table mappings, we can use
+ ioremap_page_range() as most other architectures do.
+
+ Failing all of the above, we have to fall back to a UC mapping.
PAST PROBLEM CASES
@@ -158,7 +154,7 @@ PAST PROBLEM CASES
succeed. It may create either WB or UC user mappings, depending
on whether the region is in kern_memmap or the EFI memory map.
- mmap of 0x0-0xA0000 /dev/mem by "hwinfo" on HP sx1000 with VGA enabled
+ mmap of 0x0-0x9FFFF /dev/mem by "hwinfo" on HP sx1000 with VGA enabled
See https://bugzilla.novell.com/show_bug.cgi?id=140858.
@@ -171,28 +167,25 @@ PAST PROBLEM CASES
so it is safe to use WB mappings.
The kernel VGA driver may ioremap the VGA frame buffer at 0xA0000,
- which will use a granule-sized UC mapping covering 0-0xFFFFF. This
- granule covers some WB-only memory, but since UC is non-speculative,
- the processor will never generate an uncacheable reference to the
- WB-only areas unless the driver explicitly touches them.
+ which uses a granule-sized UC mapping. This granule will cover some
+ WB-only memory, but since UC is non-speculative, the processor will
+ never generate an uncacheable reference to the WB-only areas unless
+ the driver explicitly touches them.
mmap of 0x0-0xFFFFF legacy_mem by "X"
- If the EFI memory map reports this entire range as WB, there
- is no VGA MMIO hole, and the mmap should fail or be done with
- a WB mapping.
+ If the EFI memory map reports that the entire range supports the
+ same attributes, we can allow the mmap (and we will prefer WB if
+ supported, as is the case with HP sx[12]000 machines with VGA
+ disabled).
- There's no easy way for X to determine whether the 0xA0000-0xBFFFF
- region is a frame buffer or just memory, so I think it's best to
- just fail this mmap request rather than using a WB mapping. As
- far as I know, there's no need to map legacy_mem with WB
- mappings.
+ If EFI reports the range as partly WB and partly UC (as on sx[12]000
+ machines with VGA enabled), we must fail the mmap because there's no
+ safe attribute to use.
- Otherwise, a UC mapping of the entire region is probably safe.
- The VGA hole means the region will not be in kern_memmap. The
- HP sx1000 chipset doesn't support UC access to the memory surrounding
- the VGA hole, but X doesn't need that area anyway and should not
- reference it.
+ If EFI reports some of the range but not all (as on Intel firmware
+ that doesn't report the VGA frame buffer at all), we should fail the
+ mmap and force the user to map just the specific region of interest.
mmap of 0xA0000-0xBFFFF legacy_mem by "X" on HP sx1000 with VGA disabled
@@ -202,6 +195,16 @@ PAST PROBLEM CASES
This is a special case of the previous case, and the mmap should
fail for the same reason as above.
+ read of /sys/devices/.../rom
+
+ For VGA devices, this may cause an ioremap() of 0xC0000. This
+ used to be done with a UC mapping, because the VGA frame buffer
+ at 0xA0000 prevents use of a WB granule. The UC mapping causes
+ an MCA on HP sx[12]000 chipsets.
+
+ We should use WB page table mappings to avoid covering the VGA
+ frame buffer.
+
NOTES
[1] SDM rev 2.2, vol 2, sec 4.4.1.
diff --git a/Documentation/ia64/err_inject.txt b/Documentation/ia64/err_inject.txt
new file mode 100644
index 0000000..6449a70
--- /dev/null
+++ b/Documentation/ia64/err_inject.txt
@@ -0,0 +1,1068 @@
+
+IPF Machine Check (MC) error inject tool
+========================================
+
+IPF Machine Check (MC) error inject tool is used to inject MC
+errors from Linux. The tool is a test bed for IPF MC work flow including
+hardware correctable error handling, OS recoverable error handling, MC
+event logging, etc.
+
+The tool includes two parts: a kernel driver and a user application
+sample. The driver provides interface to PAL to inject error
+and query error injection capabilities. The driver code is in
+arch/ia64/kernel/err_inject.c. The application sample (shown below)
+provides a combination of various errors and calls the driver's interface
+(sysfs interface) to inject errors or query error injection capabilities.
+
+The tool can be used to test Intel IPF machine MC handling capabilities.
+It's especially useful for people who can not access hardware MC injection
+tool to inject error. It's also very useful to integrate with other
+software test suits to do stressful testing on IPF.
+
+Below is a sample application as part of the whole tool. The sample
+can be used as a working test tool. Or it can be expanded to include
+more features. It also can be a integrated into a libary or other user
+application to have more thorough test.
+
+The sample application takes err.conf as error configuation input. Gcc
+compiles the code. After you install err_inject driver, you can run
+this sample application to inject errors.
+
+Errata: Itanium 2 Processors Specification Update lists some errata against
+the pal_mc_error_inject PAL procedure. The following err.conf has been tested
+on latest Montecito PAL.
+
+err.conf:
+
+#This is configuration file for err_inject_tool.
+#The format of the each line is:
+#cpu, loop, interval, err_type_info, err_struct_info, err_data_buffer
+#where
+# cpu: logical cpu number the error will be inject in.
+# loop: times the error will be injected.
+# interval: In second. every so often one error is injected.
+# err_type_info, err_struct_info: PAL parameters.
+#
+#Note: All values are hex w/o or w/ 0x prefix.
+
+
+#On cpu2, inject only total 0x10 errors, interval 5 seconds
+#corrected, data cache, hier-2, physical addr(assigned by tool code).
+#working on Montecito latest PAL.
+2, 10, 5, 4101, 95
+
+#On cpu4, inject and consume total 0x10 errors, interval 5 seconds
+#corrected, data cache, hier-2, physical addr(assigned by tool code).
+#working on Montecito latest PAL.
+4, 10, 5, 4109, 95
+
+#On cpu15, inject and consume total 0x10 errors, interval 5 seconds
+#recoverable, DTR0, hier-2.
+#working on Montecito latest PAL.
+0xf, 0x10, 5, 4249, 15
+
+The sample application source code:
+
+err_injection_tool.c:
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Copyright (C) 2006 Intel Co
+ * Fenghua Yu <fenghua.yu@intel.com>
+ *
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sched.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <sys/shm.h>
+
+#define MAX_FN_SIZE 256
+#define MAX_BUF_SIZE 256
+#define DATA_BUF_SIZE 256
+#define NR_CPUS 512
+#define MAX_TASK_NUM 2048
+#define MIN_INTERVAL 5 // seconds
+#define ERR_DATA_BUFFER_SIZE 3 // Three 8-byte.
+#define PARA_FIELD_NUM 5
+#define MASK_SIZE (NR_CPUS/64)
+#define PATH_FORMAT "/sys/devices/system/cpu/cpu%d/err_inject/"
+
+int sched_setaffinity(pid_t pid, unsigned int len, unsigned long *mask);
+
+int verbose;
+#define vbprintf if (verbose) printf
+
+int log_info(int cpu, const char *fmt, ...)
+{
+ FILE *log;
+ char fn[MAX_FN_SIZE];
+ char buf[MAX_BUF_SIZE];
+ va_list args;
+
+ sprintf(fn, "%d.log", cpu);
+ log=fopen(fn, "a+");
+ if (log==NULL) {
+ perror("Error open:");
+ return -1;
+ }
+
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ memset(buf, 0, MAX_BUF_SIZE);
+ vsprintf(buf, fmt, args);
+ va_end(args);
+
+ fwrite(buf, sizeof(buf), 1, log);
+ fclose(log);
+
+ return 0;
+}
+
+typedef unsigned long u64;
+typedef unsigned int u32;
+
+typedef union err_type_info_u {
+ struct {
+ u64 mode : 3, /* 0-2 */
+ err_inj : 3, /* 3-5 */
+ err_sev : 2, /* 6-7 */
+ err_struct : 5, /* 8-12 */
+ struct_hier : 3, /* 13-15 */
+ reserved : 48; /* 16-63 */
+ } err_type_info_u;
+ u64 err_type_info;
+} err_type_info_t;
+
+typedef union err_struct_info_u {
+ struct {
+ u64 siv : 1, /* 0 */
+ c_t : 2, /* 1-2 */
+ cl_p : 3, /* 3-5 */
+ cl_id : 3, /* 6-8 */
+ cl_dp : 1, /* 9 */
+ reserved1 : 22, /* 10-31 */
+ tiv : 1, /* 32 */
+ trigger : 4, /* 33-36 */
+ trigger_pl : 3, /* 37-39 */
+ reserved2 : 24; /* 40-63 */
+ } err_struct_info_cache;
+ struct {
+ u64 siv : 1, /* 0 */
+ tt : 2, /* 1-2 */
+ tc_tr : 2, /* 3-4 */
+ tr_slot : 8, /* 5-12 */
+ reserved1 : 19, /* 13-31 */
+ tiv : 1, /* 32 */
+ trigger : 4, /* 33-36 */
+ trigger_pl : 3, /* 37-39 */
+ reserved2 : 24; /* 40-63 */
+ } err_struct_info_tlb;
+ struct {
+ u64 siv : 1, /* 0 */
+ regfile_id : 4, /* 1-4 */
+ reg_num : 7, /* 5-11 */
+ reserved1 : 20, /* 12-31 */
+ tiv : 1, /* 32 */
+ trigger : 4, /* 33-36 */
+ trigger_pl : 3, /* 37-39 */
+ reserved2 : 24; /* 40-63 */
+ } err_struct_info_register;
+ struct {
+ u64 reserved;
+ } err_struct_info_bus_processor_interconnect;
+ u64 err_struct_info;
+} err_struct_info_t;
+
+typedef union err_data_buffer_u {
+ struct {
+ u64 trigger_addr; /* 0-63 */
+ u64 inj_addr; /* 64-127 */
+ u64 way : 5, /* 128-132 */
+ index : 20, /* 133-152 */
+ : 39; /* 153-191 */
+ } err_data_buffer_cache;
+ struct {
+ u64 trigger_addr; /* 0-63 */
+ u64 inj_addr; /* 64-127 */
+ u64 way : 5, /* 128-132 */
+ index : 20, /* 133-152 */
+ reserved : 39; /* 153-191 */
+ } err_data_buffer_tlb;
+ struct {
+ u64 trigger_addr; /* 0-63 */
+ } err_data_buffer_register;
+ struct {
+ u64 reserved; /* 0-63 */
+ } err_data_buffer_bus_processor_interconnect;
+ u64 err_data_buffer[ERR_DATA_BUFFER_SIZE];
+} err_data_buffer_t;
+
+typedef union capabilities_u {
+ struct {
+ u64 i : 1,
+ d : 1,
+ rv : 1,
+ tag : 1,
+ data : 1,
+ mesi : 1,
+ dp : 1,
+ reserved1 : 3,
+ pa : 1,
+ va : 1,
+ wi : 1,
+ reserved2 : 20,
+ trigger : 1,
+ trigger_pl : 1,
+ reserved3 : 30;
+ } capabilities_cache;
+ struct {
+ u64 d : 1,
+ i : 1,
+ rv : 1,
+ tc : 1,
+ tr : 1,
+ reserved1 : 27,
+ trigger : 1,
+ trigger_pl : 1,
+ reserved2 : 30;
+ } capabilities_tlb;
+ struct {
+ u64 gr_b0 : 1,
+ gr_b1 : 1,
+ fr : 1,
+ br : 1,
+ pr : 1,
+ ar : 1,
+ cr : 1,
+ rr : 1,
+ pkr : 1,
+ dbr : 1,
+ ibr : 1,
+ pmc : 1,
+ pmd : 1,
+ reserved1 : 3,
+ regnum : 1,
+ reserved2 : 15,
+ trigger : 1,
+ trigger_pl : 1,
+ reserved3 : 30;
+ } capabilities_register;
+ struct {
+ u64 reserved;
+ } capabilities_bus_processor_interconnect;
+} capabilities_t;
+
+typedef struct resources_s {
+ u64 ibr0 : 1,
+ ibr2 : 1,
+ ibr4 : 1,
+ ibr6 : 1,
+ dbr0 : 1,
+ dbr2 : 1,
+ dbr4 : 1,
+ dbr6 : 1,
+ reserved : 48;
+} resources_t;
+
+
+long get_page_size(void)
+{
+ long page_size=sysconf(_SC_PAGESIZE);
+ return page_size;
+}
+
+#define PAGE_SIZE (get_page_size()==-1?0x4000:get_page_size())
+#define SHM_SIZE (2*PAGE_SIZE*NR_CPUS)
+#define SHM_VA 0x2000000100000000
+
+int shmid;
+void *shmaddr;
+
+int create_shm(void)
+{
+ key_t key;
+ char fn[MAX_FN_SIZE];
+
+ /* cpu0 is always existing */
+ sprintf(fn, PATH_FORMAT, 0);
+ if ((key = ftok(fn, 's')) == -1) {
+ perror("ftok");
+ return -1;
+ }
+
+ shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT);
+ if (shmid == -1) {
+ if (errno==EEXIST) {
+ shmid = shmget(key, SHM_SIZE, 0);
+ if (shmid == -1) {
+ perror("shmget");
+ return -1;
+ }
+ }
+ else {
+ perror("shmget");
+ return -1;
+ }
+ }
+ vbprintf("shmid=%d", shmid);
+
+ /* connect to the segment: */
+ shmaddr = shmat(shmid, (void *)SHM_VA, 0);
+ if (shmaddr == (void*)-1) {
+ perror("shmat");
+ return -1;
+ }
+
+ memset(shmaddr, 0, SHM_SIZE);
+ mlock(shmaddr, SHM_SIZE);
+
+ return 0;
+}
+
+int free_shm()
+{
+ munlock(shmaddr, SHM_SIZE);
+ shmdt(shmaddr);
+ semctl(shmid, 0, IPC_RMID);
+
+ return 0;
+}
+
+#ifdef _SEM_SEMUN_UNDEFINED
+union semun
+{
+ int val;
+ struct semid_ds *buf;
+ unsigned short int *array;
+ struct seminfo *__buf;
+};
+#endif
+
+u32 mode=1; /* 1: physical mode; 2: virtual mode. */
+int one_lock=1;
+key_t key[NR_CPUS];
+int semid[NR_CPUS];
+
+int create_sem(int cpu)
+{
+ union semun arg;
+ char fn[MAX_FN_SIZE];
+ int sid;
+
+ sprintf(fn, PATH_FORMAT, cpu);
+ sprintf(fn, "%s/%s", fn, "err_type_info");
+ if ((key[cpu] = ftok(fn, 'e')) == -1) {
+ perror("ftok");
+ return -1;
+ }
+
+ if (semid[cpu]!=0)
+ return 0;
+
+ /* clear old semaphore */
+ if ((sid = semget(key[cpu], 1, 0)) != -1)
+ semctl(sid, 0, IPC_RMID);
+
+ /* get one semaphore */
+ if ((semid[cpu] = semget(key[cpu], 1, IPC_CREAT | IPC_EXCL)) == -1) {
+ perror("semget");
+ printf("Please remove semaphore with key=0x%lx, then run the tool.\n",
+ (u64)key[cpu]);
+ return -1;
+ }
+
+ vbprintf("semid[%d]=0x%lx, key[%d]=%lx\n",cpu,(u64)semid[cpu],cpu,
+ (u64)key[cpu]);
+ /* initialize the semaphore to 1: */
+ arg.val = 1;
+ if (semctl(semid[cpu], 0, SETVAL, arg) == -1) {
+ perror("semctl");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int lock(int cpu)
+{
+ struct sembuf lock;
+
+ lock.sem_num = cpu;
+ lock.sem_op = 1;
+ semop(semid[cpu], &lock, 1);
+
+ return 0;
+}
+
+static int unlock(int cpu)
+{
+ struct sembuf unlock;
+
+ unlock.sem_num = cpu;
+ unlock.sem_op = -1;
+ semop(semid[cpu], &unlock, 1);
+
+ return 0;
+}
+
+void free_sem(int cpu)
+{
+ semctl(semid[cpu], 0, IPC_RMID);
+}
+
+int wr_multi(char *fn, unsigned long *data, int size)
+{
+ int fd;
+ char buf[MAX_BUF_SIZE];
+ int ret;
+
+ if (size==1)
+ sprintf(buf, "%lx", *data);
+ else if (size==3)
+ sprintf(buf, "%lx,%lx,%lx", data[0], data[1], data[2]);
+ else {
+ fprintf(stderr,"write to file with wrong size!\n");
+ return -1;
+ }
+
+ fd=open(fn, O_RDWR);
+ if (!fd) {
+ perror("Error:");
+ return -1;
+ }
+ ret=write(fd, buf, sizeof(buf));
+ close(fd);
+ return ret;
+}
+
+int wr(char *fn, unsigned long data)
+{
+ return wr_multi(fn, &data, 1);
+}
+
+int rd(char *fn, unsigned long *data)
+{
+ int fd;
+ char buf[MAX_BUF_SIZE];
+
+ fd=open(fn, O_RDONLY);
+ if (fd<0) {
+ perror("Error:");
+ return -1;
+ }
+ read(fd, buf, MAX_BUF_SIZE);
+ *data=strtoul(buf, NULL, 16);
+ close(fd);
+ return 0;
+}
+
+int rd_status(char *path, int *status)
+{
+ char fn[MAX_FN_SIZE];
+ sprintf(fn, "%s/status", path);
+ if (rd(fn, (u64*)status)<0) {
+ perror("status reading error.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int rd_capabilities(char *path, u64 *capabilities)
+{
+ char fn[MAX_FN_SIZE];
+ sprintf(fn, "%s/capabilities", path);
+ if (rd(fn, capabilities)<0) {
+ perror("capabilities reading error.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int rd_all(char *path)
+{
+ unsigned long err_type_info, err_struct_info, err_data_buffer;
+ int status;
+ unsigned long capabilities, resources;
+ char fn[MAX_FN_SIZE];
+
+ sprintf(fn, "%s/err_type_info", path);
+ if (rd(fn, &err_type_info)<0) {
+ perror("err_type_info reading error.\n");
+ return -1;
+ }
+ printf("err_type_info=%lx\n", err_type_info);
+
+ sprintf(fn, "%s/err_struct_info", path);
+ if (rd(fn, &err_struct_info)<0) {
+ perror("err_struct_info reading error.\n");
+ return -1;
+ }
+ printf("err_struct_info=%lx\n", err_struct_info);
+
+ sprintf(fn, "%s/err_data_buffer", path);
+ if (rd(fn, &err_data_buffer)<0) {
+ perror("err_data_buffer reading error.\n");
+ return -1;
+ }
+ printf("err_data_buffer=%lx\n", err_data_buffer);
+
+ sprintf(fn, "%s/status", path);
+ if (rd("status", (u64*)&status)<0) {
+ perror("status reading error.\n");
+ return -1;
+ }
+ printf("status=%d\n", status);
+
+ sprintf(fn, "%s/capabilities", path);
+ if (rd(fn,&capabilities)<0) {
+ perror("capabilities reading error.\n");
+ return -1;
+ }
+ printf("capabilities=%lx\n", capabilities);
+
+ sprintf(fn, "%s/resources", path);
+ if (rd(fn, &resources)<0) {
+ perror("resources reading error.\n");
+ return -1;
+ }
+ printf("resources=%lx\n", resources);
+
+ return 0;
+}
+
+int query_capabilities(char *path, err_type_info_t err_type_info,
+ u64 *capabilities)
+{
+ char fn[MAX_FN_SIZE];
+ err_struct_info_t err_struct_info;
+ err_data_buffer_t err_data_buffer;
+
+ err_struct_info.err_struct_info=0;
+ memset(err_data_buffer.err_data_buffer, -1, ERR_DATA_BUFFER_SIZE*8);
+
+ sprintf(fn, "%s/err_type_info", path);
+ wr(fn, err_type_info.err_type_info);
+ sprintf(fn, "%s/err_struct_info", path);
+ wr(fn, 0x0);
+ sprintf(fn, "%s/err_data_buffer", path);
+ wr_multi(fn, err_data_buffer.err_data_buffer, ERR_DATA_BUFFER_SIZE);
+
+ // Fire pal_mc_error_inject procedure.
+ sprintf(fn, "%s/call_start", path);
+ wr(fn, mode);
+
+ if (rd_capabilities(path, capabilities)<0)
+ return -1;
+
+ return 0;
+}
+
+int query_all_capabilities()
+{
+ int status;
+ err_type_info_t err_type_info;
+ int err_sev, err_struct, struct_hier;
+ int cap=0;
+ u64 capabilities;
+ char path[MAX_FN_SIZE];
+
+ err_type_info.err_type_info=0; // Initial
+ err_type_info.err_type_info_u.mode=0; // Query mode;
+ err_type_info.err_type_info_u.err_inj=0;
+
+ printf("All capabilities implemented in pal_mc_error_inject:\n");
+ sprintf(path, PATH_FORMAT ,0);
+ for (err_sev=0;err_sev<3;err_sev++)
+ for (err_struct=0;err_struct<5;err_struct++)
+ for (struct_hier=0;struct_hier<5;struct_hier++)
+ {
+ status=-1;
+ capabilities=0;
+ err_type_info.err_type_info_u.err_sev=err_sev;
+ err_type_info.err_type_info_u.err_struct=err_struct;
+ err_type_info.err_type_info_u.struct_hier=struct_hier;
+
+ if (query_capabilities(path, err_type_info, &capabilities)<0)
+ continue;
+
+ if (rd_status(path, &status)<0)
+ continue;
+
+ if (status==0) {
+ cap=1;
+ printf("For err_sev=%d, err_struct=%d, struct_hier=%d: ",
+ err_sev, err_struct, struct_hier);
+ printf("capabilities 0x%lx\n", capabilities);
+ }
+ }
+ if (!cap) {
+ printf("No capabilities supported.\n");
+ return 0;
+ }
+
+ return 0;
+}
+
+int err_inject(int cpu, char *path, err_type_info_t err_type_info,
+ err_struct_info_t err_struct_info,
+ err_data_buffer_t err_data_buffer)
+{
+ int status;
+ char fn[MAX_FN_SIZE];
+
+ log_info(cpu, "err_type_info=%lx, err_struct_info=%lx, ",
+ err_type_info.err_type_info,
+ err_struct_info.err_struct_info);
+ log_info(cpu,"err_data_buffer=[%lx,%lx,%lx]\n",
+ err_data_buffer.err_data_buffer[0],
+ err_data_buffer.err_data_buffer[1],
+ err_data_buffer.err_data_buffer[2]);
+ sprintf(fn, "%s/err_type_info", path);
+ wr(fn, err_type_info.err_type_info);
+ sprintf(fn, "%s/err_struct_info", path);
+ wr(fn, err_struct_info.err_struct_info);
+ sprintf(fn, "%s/err_data_buffer", path);
+ wr_multi(fn, err_data_buffer.err_data_buffer, ERR_DATA_BUFFER_SIZE);
+
+ // Fire pal_mc_error_inject procedure.
+ sprintf(fn, "%s/call_start", path);
+ wr(fn,mode);
+
+ if (rd_status(path, &status)<0) {
+ vbprintf("fail: read status\n");
+ return -100;
+ }
+
+ if (status!=0) {
+ log_info(cpu, "fail: status=%d\n", status);
+ return status;
+ }
+
+ return status;
+}
+
+static int construct_data_buf(char *path, err_type_info_t err_type_info,
+ err_struct_info_t err_struct_info,
+ err_data_buffer_t *err_data_buffer,
+ void *va1)
+{
+ char fn[MAX_FN_SIZE];
+ u64 virt_addr=0, phys_addr=0;
+
+ vbprintf("va1=%lx\n", (u64)va1);
+ memset(&err_data_buffer->err_data_buffer_cache, 0, ERR_DATA_BUFFER_SIZE*8);
+
+ switch (err_type_info.err_type_info_u.err_struct) {
+ case 1: // Cache
+ switch (err_struct_info.err_struct_info_cache.cl_id) {
+ case 1: //Virtual addr
+ err_data_buffer->err_data_buffer_cache.inj_addr=(u64)va1;
+ break;
+ case 2: //Phys addr
+ sprintf(fn, "%s/virtual_to_phys", path);
+ virt_addr=(u64)va1;
+ if (wr(fn,virt_addr)<0)
+ return -1;
+ rd(fn, &phys_addr);
+ err_data_buffer->err_data_buffer_cache.inj_addr=phys_addr;
+ break;
+ default:
+ printf("Not supported cl_id\n");
+ break;
+ }
+ break;
+ case 2: // TLB
+ break;
+ case 3: // Register file
+ break;
+ case 4: // Bus/system interconnect
+ default:
+ printf("Not supported err_struct\n");
+ break;
+ }
+
+ return 0;
+}
+
+typedef struct {
+ u64 cpu;
+ u64 loop;
+ u64 interval;
+ u64 err_type_info;
+ u64 err_struct_info;
+ u64 err_data_buffer[ERR_DATA_BUFFER_SIZE];
+} parameters_t;
+
+parameters_t line_para;
+int para;
+
+static int empty_data_buffer(u64 *err_data_buffer)
+{
+ int empty=1;
+ int i;
+
+ for (i=0;i<ERR_DATA_BUFFER_SIZE; i++)
+ if (err_data_buffer[i]!=-1)
+ empty=0;
+
+ return empty;
+}
+
+int err_inj()
+{
+ err_type_info_t err_type_info;
+ err_struct_info_t err_struct_info;
+ err_data_buffer_t err_data_buffer;
+ int count;
+ FILE *fp;
+ unsigned long cpu, loop, interval, err_type_info_conf, err_struct_info_conf;
+ u64 err_data_buffer_conf[ERR_DATA_BUFFER_SIZE];
+ int num;
+ int i;
+ char path[MAX_FN_SIZE];
+ parameters_t parameters[MAX_TASK_NUM]={};
+ pid_t child_pid[MAX_TASK_NUM];
+ time_t current_time;
+ int status;
+
+ if (!para) {
+ fp=fopen("err.conf", "r");
+ if (fp==NULL) {
+ perror("Error open err.conf");
+ return -1;
+ }
+
+ num=0;
+ while (!feof(fp)) {
+ char buf[256];
+ memset(buf,0,256);
+ fgets(buf, 256, fp);
+ count=sscanf(buf, "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx\n",
+ &cpu, &loop, &interval,&err_type_info_conf,
+ &err_struct_info_conf,
+ &err_data_buffer_conf[0],
+ &err_data_buffer_conf[1],
+ &err_data_buffer_conf[2]);
+ if (count!=PARA_FIELD_NUM+3) {
+ err_data_buffer_conf[0]=-1;
+ err_data_buffer_conf[1]=-1;
+ err_data_buffer_conf[2]=-1;
+ count=sscanf(buf, "%lx, %lx, %lx, %lx, %lx\n",
+ &cpu, &loop, &interval,&err_type_info_conf,
+ &err_struct_info_conf);
+ if (count!=PARA_FIELD_NUM)
+ continue;
+ }
+
+ parameters[num].cpu=cpu;
+ parameters[num].loop=loop;
+ parameters[num].interval= interval>MIN_INTERVAL
+ ?interval:MIN_INTERVAL;
+ parameters[num].err_type_info=err_type_info_conf;
+ parameters[num].err_struct_info=err_struct_info_conf;
+ memcpy(parameters[num++].err_data_buffer,
+ err_data_buffer_conf,ERR_DATA_BUFFER_SIZE*8) ;
+
+ if (num>=MAX_TASK_NUM)
+ break;
+ }
+ }
+ else {
+ parameters[0].cpu=line_para.cpu;
+ parameters[0].loop=line_para.loop;
+ parameters[0].interval= line_para.interval>MIN_INTERVAL
+ ?line_para.interval:MIN_INTERVAL;
+ parameters[0].err_type_info=line_para.err_type_info;
+ parameters[0].err_struct_info=line_para.err_struct_info;
+ memcpy(parameters[0].err_data_buffer,
+ line_para.err_data_buffer,ERR_DATA_BUFFER_SIZE*8) ;
+
+ num=1;
+ }
+
+ /* Create semaphore: If one_lock, one semaphore for all processors.
+ Otherwise, one sempaphore for each processor. */
+ if (one_lock) {
+ if (create_sem(0)) {
+ printf("Can not create semaphore...exit\n");
+ free_sem(0);
+ return -1;
+ }
+ }
+ else {
+ for (i=0;i<num;i++) {
+ if (create_sem(parameters[i].cpu)) {
+ printf("Can not create semaphore for cpu%d...exit\n",i);
+ free_sem(parameters[num].cpu);
+ return -1;
+ }
+ }
+ }
+
+ /* Create a shm segment which will be used to inject/consume errors on.*/
+ if (create_shm()==-1) {
+ printf("Error to create shm...exit\n");
+ return -1;
+ }
+
+ for (i=0;i<num;i++) {
+ pid_t pid;
+
+ current_time=time(NULL);
+ log_info(parameters[i].cpu, "\nBegine at %s", ctime(&current_time));
+ log_info(parameters[i].cpu, "Configurations:\n");
+ log_info(parameters[i].cpu,"On cpu%ld: loop=%lx, interval=%lx(s)",
+ parameters[i].cpu,
+ parameters[i].loop,
+ parameters[i].interval);
+ log_info(parameters[i].cpu," err_type_info=%lx,err_struct_info=%lx\n",
+ parameters[i].err_type_info,
+ parameters[i].err_struct_info);
+
+ sprintf(path, PATH_FORMAT, (int)parameters[i].cpu);
+ err_type_info.err_type_info=parameters[i].err_type_info;
+ err_struct_info.err_struct_info=parameters[i].err_struct_info;
+ memcpy(err_data_buffer.err_data_buffer,
+ parameters[i].err_data_buffer,
+ ERR_DATA_BUFFER_SIZE*8);
+
+ pid=fork();
+ if (pid==0) {
+ unsigned long mask[MASK_SIZE];
+ int j, k;
+
+ void *va1, *va2;
+
+ /* Allocate two memory areas va1 and va2 in shm */
+ va1=shmaddr+parameters[i].cpu*PAGE_SIZE;
+ va2=shmaddr+parameters[i].cpu*PAGE_SIZE+PAGE_SIZE;
+
+ vbprintf("va1=%lx, va2=%lx\n", (u64)va1, (u64)va2);
+ memset(va1, 0x1, PAGE_SIZE);
+ memset(va2, 0x2, PAGE_SIZE);
+
+ if (empty_data_buffer(err_data_buffer.err_data_buffer))
+ /* If not specified yet, construct data buffer
+ * with va1
+ */
+ construct_data_buf(path, err_type_info,
+ err_struct_info, &err_data_buffer,va1);
+
+ for (j=0;j<MASK_SIZE;j++)
+ mask[j]=0;
+
+ cpu=parameters[i].cpu;
+ k = cpu%64;
+ j = cpu/64;
+ mask[j]=1<<k;
+
+ if (sched_setaffinity(0, MASK_SIZE*8, mask)==-1) {
+ perror("Error sched_setaffinity:");
+ return -1;
+ }
+
+ for (j=0; j<parameters[i].loop; j++) {
+ log_info(parameters[i].cpu,"Injection ");
+ log_info(parameters[i].cpu,"on cpu%ld: #%d/%ld ",
+
+ parameters[i].cpu,j+1, parameters[i].loop);
+
+ /* Hold the lock */
+ if (one_lock)
+ lock(0);
+ else
+ /* Hold lock on this cpu */
+ lock(parameters[i].cpu);
+
+ if ((status=err_inject(parameters[i].cpu,
+ path, err_type_info,
+ err_struct_info, err_data_buffer))
+ ==0) {
+ /* consume the error for "inject only"*/
+ memcpy(va2, va1, PAGE_SIZE);
+ memcpy(va1, va2, PAGE_SIZE);
+ log_info(parameters[i].cpu,
+ "successful\n");
+ }
+ else {
+ log_info(parameters[i].cpu,"fail:");
+ log_info(parameters[i].cpu,
+ "status=%d\n", status);
+ unlock(parameters[i].cpu);
+ break;
+ }
+ if (one_lock)
+ /* Release the lock */
+ unlock(0);
+ /* Release lock on this cpu */
+ else
+ unlock(parameters[i].cpu);
+
+ if (j < parameters[i].loop-1)
+ sleep(parameters[i].interval);
+ }
+ current_time=time(NULL);
+ log_info(parameters[i].cpu, "Done at %s", ctime(&current_time));
+ return 0;
+ }
+ else if (pid<0) {
+ perror("Error fork:");
+ continue;
+ }
+ child_pid[i]=pid;
+ }
+ for (i=0;i<num;i++)
+ waitpid(child_pid[i], NULL, 0);
+
+ if (one_lock)
+ free_sem(0);
+ else
+ for (i=0;i<num;i++)
+ free_sem(parameters[i].cpu);
+
+ printf("All done.\n");
+
+ return 0;
+}
+
+void help()
+{
+ printf("err_inject_tool:\n");
+ printf("\t-q: query all capabilities. default: off\n");
+ printf("\t-m: procedure mode. 1: physical 2: virtual. default: 1\n");
+ printf("\t-i: inject errors. default: off\n");
+ printf("\t-l: one lock per cpu. default: one lock for all\n");
+ printf("\t-e: error parameters:\n");
+ printf("\t\tcpu,loop,interval,err_type_info,err_struct_info[,err_data_buffer[0],err_data_buffer[1],err_data_buffer[2]]\n");
+ printf("\t\t cpu: logical cpu number the error will be inject in.\n");
+ printf("\t\t loop: times the error will be injected.\n");
+ printf("\t\t interval: In second. every so often one error is injected.\n");
+ printf("\t\t err_type_info, err_struct_info: PAL parameters.\n");
+ printf("\t\t err_data_buffer: PAL parameter. Optional. If not present,\n");
+ printf("\t\t it's constructed by tool automatically. Be\n");
+ printf("\t\t careful to provide err_data_buffer and make\n");
+ printf("\t\t sure it's working with the environment.\n");
+ printf("\t Note:no space between error parameters.\n");
+ printf("\t default: Take error parameters from err.conf instead of command line.\n");
+ printf("\t-v: verbose. default: off\n");
+ printf("\t-h: help\n\n");
+ printf("The tool will take err.conf file as ");
+ printf("input to inject single or multiple errors ");
+ printf("on one or multiple cpus in parallel.\n");
+}
+
+int main(int argc, char **argv)
+{
+ char c;
+ int do_err_inj=0;
+ int do_query_all=0;
+ int count;
+ u32 m;
+
+ /* Default one lock for all cpu's */
+ one_lock=1;
+ while ((c = getopt(argc, argv, "m:iqvhle:")) != EOF)
+ switch (c) {
+ case 'm': /* Procedure mode. 1: phys 2: virt */
+ count=sscanf(optarg, "%x", &m);
+ if (count!=1 || (m!=1 && m!=2)) {
+ printf("Wrong mode number.\n");
+ help();
+ return -1;
+ }
+ mode=m;
+ break;
+ case 'i': /* Inject errors */
+ do_err_inj=1;
+ break;
+ case 'q': /* Query */
+ do_query_all=1;
+ break;
+ case 'v': /* Verbose */
+ verbose=1;
+ break;
+ case 'l': /* One lock per cpu */
+ one_lock=0;
+ break;
+ case 'e': /* error arguments */
+ /* Take parameters:
+ * #cpu, loop, interval, err_type_info, err_struct_info[, err_data_buffer]
+ * err_data_buffer is optional. Recommend not to specify
+ * err_data_buffer. Better to use tool to generate it.
+ */
+ count=sscanf(optarg,
+ "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx\n",
+ &line_para.cpu,
+ &line_para.loop,
+ &line_para.interval,
+ &line_para.err_type_info,
+ &line_para.err_struct_info,
+ &line_para.err_data_buffer[0],
+ &line_para.err_data_buffer[1],
+ &line_para.err_data_buffer[2]);
+ if (count!=PARA_FIELD_NUM+3) {
+ line_para.err_data_buffer[0]=-1,
+ line_para.err_data_buffer[1]=-1,
+ line_para.err_data_buffer[2]=-1;
+ count=sscanf(optarg, "%lx, %lx, %lx, %lx, %lx\n",
+ &line_para.cpu,
+ &line_para.loop,
+ &line_para.interval,
+ &line_para.err_type_info,
+ &line_para.err_struct_info);
+ if (count!=PARA_FIELD_NUM) {
+ printf("Wrong error arguments.\n");
+ help();
+ return -1;
+ }
+ }
+ para=1;
+ break;
+ continue;
+ break;
+ case 'h':
+ help();
+ return 0;
+ default:
+ break;
+ }
+
+ if (do_query_all)
+ query_all_capabilities();
+ if (do_err_inj)
+ err_inj();
+
+ if (!do_query_all && !do_err_inj)
+ help();
+
+ return 0;
+}
+
diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt
index 8f750c0..3de7d37 100644
--- a/Documentation/ioctl-number.txt
+++ b/Documentation/ioctl-number.txt
@@ -138,7 +138,8 @@ Code Seq# Include File Comments
'm' 00-1F net/irda/irmod.h conflict!
'n' 00-7F linux/ncp_fs.h
'n' E0-FF video/matrox.h matroxfb
-'p' 00-3F linux/mc146818rtc.h
+'p' 00-0F linux/phantom.h conflict! (OpenHaptics needs this)
+'p' 00-3F linux/mc146818rtc.h conflict!
'p' 40-7F linux/nvram.h
'p' 80-9F user-space parport
<mailto:tim@cyberelk.net>
diff --git a/Documentation/kbuild/modules.txt b/Documentation/kbuild/modules.txt
index 769ee05..1d247d5 100644
--- a/Documentation/kbuild/modules.txt
+++ b/Documentation/kbuild/modules.txt
@@ -249,7 +249,7 @@ following files:
--> filename: Makefile
KERNELDIR := /lib/modules/`uname -r`/build
all::
- $(MAKE) -C $KERNELDIR M=`pwd` $@
+ $(MAKE) -C $(KERNELDIR) M=`pwd` $@
# Module specific targets
genbin:
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 38d7db3..6b8ad06 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -496,6 +496,30 @@ and is between 256 and 4096 characters. It is defined in the file
Format: <area>[,<node>]
See also Documentation/networking/decnet.txt.
+ default_blu= [VT]
+ Format: <blue0>,<blue1>,<blue2>,...,<blue15>
+ Change the default blue palette of the console.
+ This is a 16-member array composed of values
+ ranging from 0-255.
+
+ default_grn= [VT]
+ Format: <green0>,<green1>,<green2>,...,<green15>
+ Change the default green palette of the console.
+ This is a 16-member array composed of values
+ ranging from 0-255.
+
+ default_red= [VT]
+ Format: <red0>,<red1>,<red2>,...,<red15>
+ Change the default red palette of the console.
+ This is a 16-member array composed of values
+ ranging from 0-255.
+
+ default_utf8= [VT]
+ Format=<0|1>
+ Set system-wide default UTF-8 mode for all tty's.
+ Default is 0 and by setting to 1, it enables UTF-8
+ mode for all newly opened or allocated terminals.
+
dhash_entries= [KNL]
Set number of hash buckets for dentry cache.
@@ -816,6 +840,11 @@ and is between 256 and 4096 characters. It is defined in the file
lasi= [HW,SCSI] PARISC LASI driver for the 53c700 chip
Format: addr:<io>,irq:<irq>
+ legacy_serial.force [HW,IA-32,X86-64]
+ Probe for COM ports at legacy addresses even
+ if PNPBIOS or ACPI should describe them. This
+ is for working around firmware defects.
+
llsc*= [IA64] See function print_params() in
arch/ia64/sn/kernel/llsc4.c.
@@ -1578,6 +1607,17 @@ and is between 256 and 4096 characters. It is defined in the file
smp-alt-once [IA-32,SMP] On a hotplug CPU system, only
attempt to substitute SMP alternatives once at boot.
+ smsc-ircc2.nopnp [HW] Don't use PNP to discover SMC devices
+ smsc-ircc2.ircc_cfg= [HW] Device configuration I/O port
+ smsc-ircc2.ircc_sir= [HW] SIR base I/O port
+ smsc-ircc2.ircc_fir= [HW] FIR base I/O port
+ smsc-ircc2.ircc_irq= [HW] IRQ line
+ smsc-ircc2.ircc_dma= [HW] DMA channel
+ smsc-ircc2.ircc_transceiver= [HW] Transceiver type:
+ 0: Toshiba Satellite 1800 (GP data pin select)
+ 1: Fast pin select (default)
+ 2: ATC IRMode
+
snd-ad1816a= [HW,ALSA]
snd-ad1848= [HW,ALSA]
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index d71faff..da5404ab 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -14,6 +14,7 @@ CONTENTS
8. Kprobes Example
9. Jprobes Example
10. Kretprobes Example
+Appendix A: The kprobes debugfs interface
1. Concepts: Kprobes, Jprobes, Return Probes
@@ -349,9 +350,12 @@ for instrumentation and error reporting.)
If the number of times a function is called does not match the number
of times it returns, registering a return probe on that function may
-produce undesirable results. We have the do_exit() case covered.
-do_execve() and do_fork() are not an issue. We're unaware of other
-specific cases where this could be a problem.
+produce undesirable results. In such a case, a line:
+kretprobe BUG!: Processing kretprobe d000000000041aa8 @ c00000000004f48c
+gets printed. With this information, one will be able to correlate the
+exact instance of the kretprobe that caused the problem. We have the
+do_exit() case covered. do_execve() and do_fork() are not an issue.
+We're unaware of other specific cases where this could be a problem.
If, upon entry to or exit from a function, the CPU is running on
a stack other than that of the current task, registering a return
@@ -614,3 +618,27 @@ http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe
http://www.redhat.com/magazine/005mar05/features/kprobes/
http://www-users.cs.umn.edu/~boutcher/kprobes/
http://www.linuxsymposium.org/2006/linuxsymposium_procv2.pdf (pages 101-115)
+
+
+Appendix A: The kprobes debugfs interface
+
+With recent kernels (> 2.6.20) the list of registered kprobes is visible
+under the /debug/kprobes/ directory (assuming debugfs is mounted at /debug).
+
+/debug/kprobes/list: Lists all registered probes on the system
+
+c015d71a k vfs_read+0x0
+c011a316 j do_fork+0x0
+c03dedc5 r tcp_v4_rcv+0x0
+
+The first column provides the kernel address where the probe is inserted.
+The second column identifies the type of probe (k - kprobe, r - kretprobe
+and j - jprobe), while the third column specifies the symbol+offset of
+the probe. If the probed function belongs to a module, the module name
+is also specified.
+
+/debug/kprobes/enabled: Turn kprobes ON/OFF
+
+Provides a knob to globally turn registered kprobes ON or OFF. By default,
+all kprobes are enabled. By echoing "0" to this file, all registered probes
+will be disarmed, till such time a "1" is echoed to this file.
diff --git a/Documentation/laptop-mode.txt b/Documentation/laptop-mode.txt
index 6f639e3..eeedee1 100644
--- a/Documentation/laptop-mode.txt
+++ b/Documentation/laptop-mode.txt
@@ -33,7 +33,7 @@ or anything. Simply install all the files included in this document, and
laptop mode will automatically be started when you're on battery. For
your convenience, a tarball containing an installer can be downloaded at:
-http://www.xs4all.nl/~bsamwel/laptop_mode/tools/
+http://www.samwel.tk/laptop_mode/laptop_mode/
To configure laptop mode, you need to edit the configuration file, which is
located in /etc/default/laptop-mode on Debian-based systems, or in
diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt
index ea55ea8..7d5b60d 100644
--- a/Documentation/oops-tracing.txt
+++ b/Documentation/oops-tracing.txt
@@ -234,9 +234,6 @@ characters, each representing a particular tainted value.
6: 'B' if a page-release function has found a bad page reference or
some unexpected page flags.
- 7: 'U' if a user specifically requested that the Tainted flag be set,
- ' ' otherwise.
-
7: 'U' if a user or user application specifically requested that the
Tainted flag be set, ' ' otherwise.
diff --git a/Documentation/pcmcia/driver.txt b/Documentation/pcmcia/driver.txt
new file mode 100644
index 0000000..0ac1679
--- /dev/null
+++ b/Documentation/pcmcia/driver.txt
@@ -0,0 +1,30 @@
+PCMCIA Driver
+-------------
+
+
+sysfs
+-----
+
+New PCMCIA IDs may be added to a device driver pcmcia_device_id table at
+runtime as shown below:
+
+echo "match_flags manf_id card_id func_id function device_no \
+prod_id_hash[0] prod_id_hash[1] prod_id_hash[2] prod_id_hash[3]" > \
+/sys/bus/pcmcia/drivers/{driver}/new_id
+
+All fields are passed in as hexadecimal values (no leading 0x).
+The meaning is described in the PCMCIA specification, the match_flags is
+a bitwise or-ed combination from PCMCIA_DEV_ID_MATCH_* constants
+defined in include/linux/mod_devicetable.h.
+
+Once added, the driver probe routine will be invoked for any unclaimed
+PCMCIA device listed in its (newly updated) pcmcia_device_id list.
+
+A common use-case is to add a new device according to the manufacturer ID
+and the card ID (form the manf_id and card_id file in the device tree).
+For this, just use:
+
+echo "0x3 manf_id card_id 0 0 0 0 0 0 0" > \
+ /sys/bus/pcmcia/drivers/{driver}/new_id
+
+after loading the driver.
diff --git a/Documentation/power/basic-pm-debugging.txt b/Documentation/power/basic-pm-debugging.txt
new file mode 100644
index 0000000..1a85e2b
--- /dev/null
+++ b/Documentation/power/basic-pm-debugging.txt
@@ -0,0 +1,106 @@
+Debugging suspend and resume
+ (C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL
+
+1. Testing suspend to disk (STD)
+
+To verify that the STD works, you can try to suspend in the "reboot" mode:
+
+# echo reboot > /sys/power/disk
+# echo disk > /sys/power/state
+
+and the system should suspend, reboot, resume and get back to the command prompt
+where you have started the transition. If that happens, the STD is most likely
+to work correctly, but you need to repeat the test at least a couple of times in
+a row for confidence. This is necessary, because some problems only show up on
+a second attempt at suspending and resuming the system. You should also test
+the "platform" and "shutdown" modes of suspend:
+
+# echo platform > /sys/power/disk
+# echo disk > /sys/power/state
+
+or
+
+# echo shutdown > /sys/power/disk
+# echo disk > /sys/power/state
+
+in which cases you will have to press the power button to make the system
+resume. If that does not work, you will need to identify what goes wrong.
+
+a) Test mode of STD
+
+To verify if there are any drivers that cause problems you can run the STD
+in the test mode:
+
+# echo test > /sys/power/disk
+# echo disk > /sys/power/state
+
+in which case the system should freeze tasks, suspend devices, disable nonboot
+CPUs (if any), wait for 5 seconds, enable nonboot CPUs, resume devices, thaw
+tasks and return to your command prompt. If that fails, most likely there is
+a driver that fails to either suspend or resume (in the latter case the system
+may hang or be unstable after the test, so please take that into consideration).
+To find this driver, you can carry out a binary search according to the rules:
+- if the test fails, unload a half of the drivers currently loaded and repeat
+(that would probably involve rebooting the system, so always note what drivers
+have been loaded before the test),
+- if the test succeeds, load a half of the drivers you have unloaded most
+recently and repeat.
+
+Once you have found the failing driver (there can be more than just one of
+them), you have to unload it every time before the STD transition. In that case
+please make sure to report the problem with the driver.
+
+It is also possible that a cycle can still fail after you have unloaded
+all modules. In that case, you would want to look in your kernel configuration
+for the drivers that can be compiled as modules (testing again with them as
+modules), and possibly also try boot time options such as "noapic" or "noacpi".
+
+b) Testing minimal configuration
+
+If the test mode of STD works, you can boot the system with "init=/bin/bash"
+and attempt to suspend in the "reboot", "shutdown" and "platform" modes. If
+that does not work, there probably is a problem with a driver statically
+compiled into the kernel and you can try to compile more drivers as modules,
+so that they can be tested individually. Otherwise, there is a problem with a
+modular driver and you can find it by loading a half of the modules you normally
+use and binary searching in accordance with the algorithm:
+- if there are n modules loaded and the attempt to suspend and resume fails,
+unload n/2 of the modules and try again (that would probably involve rebooting
+the system),
+- if there are n modules loaded and the attempt to suspend and resume succeeds,
+load n/2 modules more and try again.
+
+Again, if you find the offending module(s), it(they) must be unloaded every time
+before the STD transition, and please report the problem with it(them).
+
+c) Advanced debugging
+
+In case the STD does not work on your system even in the minimal configuration
+and compiling more drivers as modules is not practical or some modules cannot
+be unloaded, you can use one of the more advanced debugging techniques to find
+the problem. First, if there is a serial port in your box, you can set the
+CONFIG_DISABLE_CONSOLE_SUSPEND kernel configuration option and try to log kernel
+messages using the serial console. This may provide you with some information
+about the reasons of the suspend (resume) failure. Alternatively, it may be
+possible to use a FireWire port for debugging with firescope
+(ftp://ftp.firstfloor.org/pub/ak/firescope/). On i386 it is also possible to
+use the PM_TRACE mechanism documented in Documentation/s2ram.txt .
+
+2. Testing suspend to RAM (STR)
+
+To verify that the STR works, it is generally more convenient to use the s2ram
+tool available from http://suspend.sf.net and documented at
+http://en.opensuse.org/s2ram . However, before doing that it is recommended to
+carry out the procedure described in section 1.
+
+Assume you have resolved the problems with the STD and you have found some
+failing drivers. These drivers are also likely to fail during the STR or
+during the resume, so it is better to unload them every time before the STR
+transition. Now, you can follow the instructions at
+http://en.opensuse.org/s2ram to test the system, but if it does not work
+"out of the box", you may need to boot it with "init=/bin/bash" and test
+s2ram in the minimal configuration. In that case, you may be able to search
+for failing drivers by following the procedure analogous to the one described in
+1b). If you find some failing drivers, you will have to unload them every time
+before the STR transition (ie. before you run s2ram), and please report the
+problems with them.
diff --git a/Documentation/power/drivers-testing.txt b/Documentation/power/drivers-testing.txt
new file mode 100644
index 0000000..33016c2
--- /dev/null
+++ b/Documentation/power/drivers-testing.txt
@@ -0,0 +1,42 @@
+Testing suspend and resume support in device drivers
+ (C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL
+
+1. Preparing the test system
+
+Unfortunately, to effectively test the support for the system-wide suspend and
+resume transitions in a driver, it is necessary to suspend and resume a fully
+functional system with this driver loaded. Moreover, that should be done
+several times, preferably several times in a row, and separately for the suspend
+to disk (STD) and the suspend to RAM (STR) transitions, because each of these
+cases involves different ordering of operations and different interactions with
+the machine's BIOS.
+
+Of course, for this purpose the test system has to be known to suspend and
+resume without the driver being tested. Thus, if possible, you should first
+resolve all suspend/resume-related problems in the test system before you start
+testing the new driver. Please see Documents/power/basic-pm-debugging.txt for
+more information about the debugging of suspend/resume functionality.
+
+2. Testing the driver
+
+Once you have resolved the suspend/resume-related problems with your test system
+without the new driver, you are ready to test it:
+
+a) Build the driver as a module, load it and try the STD in the test mode (see:
+Documents/power/basic-pm-debugging.txt, 1a)).
+
+b) Load the driver and attempt to suspend to disk in the "reboot", "shutdown"
+and "platform" modes (see: Documents/power/basic-pm-debugging.txt, 1).
+
+c) Compile the driver directly into the kernel and try the STD in the test mode.
+
+d) Attempt to suspend to disk with the driver compiled directly into the kernel
+in the "reboot", "shutdown" and "platform" modes.
+
+e) Attempt to suspend to RAM using the s2ram tool with the driver loaded (see:
+Documents/power/basic-pm-debugging.txt, 2). As far as the STR tests are
+concerned, it should not matter whether or not the driver is built as a module.
+
+Each of the above tests should be repeated several times and the STD tests
+should be mixed with the STR tests. If any of them fails, the driver cannot be
+regarded as suspend/resume-safe.
diff --git a/Documentation/power/interface.txt b/Documentation/power/interface.txt
index 8c5b41b..fd5192a 100644
--- a/Documentation/power/interface.txt
+++ b/Documentation/power/interface.txt
@@ -34,8 +34,12 @@ for 5 seconds, resume devices, unfreeze tasks and enable nonboot CPUs. Then,
we are able to look in the log messages and work out, for example, which code
is being slow and which device drivers are misbehaving.
-Reading from this file will display what the mode is currently set
-to. Writing to this file will accept one of
+Reading from this file will display all supported modes and the currently
+selected one in brackets, for example
+
+ [shutdown] reboot test testproc
+
+Writing to this file will accept one of
'platform' (only if the platform supports it)
'shutdown'
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index 033a3f3..d4bfae7 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -1560,6 +1560,9 @@ platforms are moved over to use the flattened-device-tree model.
network device. This is used by the bootwrapper to interpret
MAC addresses passed by the firmware when no information other
than indices is available to associate an address with a device.
+ - phy-connection-type : a string naming the controller/PHY interface type,
+ i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id", "tbi",
+ or "rtbi".
Example:
ucc@2000 {
@@ -1574,6 +1577,7 @@ platforms are moved over to use the flattened-device-tree model.
rx-clock = "none";
tx-clock = "clk9";
phy-handle = <212000>;
+ phy-connection-type = "gmii";
pio-handle = <140001>;
};
diff --git a/Documentation/rtc.txt b/Documentation/rtc.txt
index 1ef6bb8..7c701b8 100644
--- a/Documentation/rtc.txt
+++ b/Documentation/rtc.txt
@@ -147,7 +147,7 @@ RTC class framework, but can't be supported by the older driver.
* RTC_AIE_ON, RTC_AIE_OFF, RTC_ALM_SET, RTC_ALM_READ ... when the RTC
is connected to an IRQ line, it can often issue an alarm IRQ up to
- 24 hours in the future.
+ 24 hours in the future. (Use RTC_WKALM_* by preference.)
* RTC_WKALM_SET, RTC_WKALM_RD ... RTCs that can issue alarms beyond
the next 24 hours use a slightly more powerful API, which supports
@@ -175,10 +175,7 @@ driver returns ENOIOCTLCMD. Some common examples:
called with appropriate values.
* RTC_ALM_SET, RTC_ALM_READ, RTC_WKALM_SET, RTC_WKALM_RD: the
- set_alarm/read_alarm functions will be called. To differentiate
- between the ALM and WKALM, check the larger fields of the rtc_wkalrm
- struct (like tm_year). These will be set to -1 when using ALM and
- will be set to proper values when using WKALM.
+ set_alarm/read_alarm functions will be called.
* RTC_IRQP_SET, RTC_IRQP_READ: the irq_set_freq function will be called
to set the frequency while the framework will handle the read for you
diff --git a/Documentation/sh/clk.txt b/Documentation/sh/clk.txt
new file mode 100644
index 0000000..9aef710
--- /dev/null
+++ b/Documentation/sh/clk.txt
@@ -0,0 +1,32 @@
+Clock framework on SuperH architecture
+
+The framework on SH extends existing API by the function clk_set_rate_ex,
+which prototype is as follows:
+
+ clk_set_rate_ex (struct clk *clk, unsigned long rate, int algo_id)
+
+The algo_id parameter is used to specify algorithm used to recalculate clocks,
+adjanced to clock, specified as first argument. It is assumed that algo_id==0
+means no changes to adjanced clock
+
+Internally, the clk_set_rate_ex forwards request to clk->ops->set_rate method,
+if it is present in ops structure. The method should set the clock rate and adjust
+all needed clocks according to the passed algo_id.
+Exact values for algo_id are machine-dependend. For the sh7722, the following
+values are defined:
+
+ NO_CHANGE = 0,
+ IUS_N1_N1, /* I:U = N:1, U:Sh = N:1 */
+ IUS_322, /* I:U:Sh = 3:2:2 */
+ IUS_522, /* I:U:Sh = 5:2:2 */
+ IUS_N11, /* I:U:Sh = N:1:1 */
+ SB_N1, /* Sh:B = N:1 */
+ SB3_N1, /* Sh:B3 = N:1 */
+ SB3_32, /* Sh:B3 = 3:2 */
+ SB3_43, /* Sh:B3 = 4:3 */
+ SB3_54, /* Sh:B3 = 5:4 */
+ BP_N1, /* B:P = N:1 */
+ IP_N1 /* I:P = N:1 */
+
+Each of these constants means relation between clocks that can be set via the FRQCR
+register
diff --git a/Documentation/spi/pxa2xx b/Documentation/spi/pxa2xx
index f9717fe..215e3b8 100644
--- a/Documentation/spi/pxa2xx
+++ b/Documentation/spi/pxa2xx
@@ -62,7 +62,7 @@ static struct resource pxa_spi_nssp_resources[] = {
static struct pxa2xx_spi_master pxa_nssp_master_info = {
.ssp_type = PXA25x_NSSP, /* Type of SSP */
- .clock_enable = CKEN9_NSSP, /* NSSP Peripheral clock */
+ .clock_enable = CKEN_NSSP, /* NSSP Peripheral clock */
.num_chipselect = 1, /* Matches the number of chips attached to NSSP */
.enable_dma = 1, /* Enables NSSP DMA */
};
diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary
index ecc7c9e..795fbb4 100644
--- a/Documentation/spi/spi-summary
+++ b/Documentation/spi/spi-summary
@@ -8,7 +8,7 @@ What is SPI?
The "Serial Peripheral Interface" (SPI) is a synchronous four wire serial
link used to connect microcontrollers to sensors, memory, and peripherals.
-The three signal wires hold a clock (SCLK, often on the order of 10 MHz),
+The three signal wires hold a clock (SCK, often on the order of 10 MHz),
and parallel data lines with "Master Out, Slave In" (MOSI) or "Master In,
Slave Out" (MISO) signals. (Other names are also used.) There are four
clocking modes through which data is exchanged; mode-0 and mode-3 are most
@@ -22,7 +22,7 @@ other signals, often including an interrupt to the master.
Unlike serial busses like USB or SMBUS, even low level protocols for
SPI slave functions are usually not interoperable between vendors
-(except for cases like SPI memory chips).
+(except for commodities like SPI memory chips).
- SPI may be used for request/response style device protocols, as with
touchscreen sensors and memory chips.
@@ -77,8 +77,9 @@ cards without needing a special purpose MMC/SD/SDIO controller.
How do these driver programming interfaces work?
------------------------------------------------
The <linux/spi/spi.h> header file includes kerneldoc, as does the
-main source code, and you should certainly read that. This is just
-an overview, so you get the big picture before the details.
+main source code, and you should certainly read that chapter of the
+kernel API document. This is just an overview, so you get the big
+picture before those details.
SPI requests always go into I/O queues. Requests for a given SPI device
are always executed in FIFO order, and complete asynchronously through
@@ -88,7 +89,7 @@ a command and then reading its response.
There are two types of SPI driver, here called:
- Controller drivers ... these are often built in to System-On-Chip
+ Controller drivers ... controllers may be built in to System-On-Chip
processors, and often support both Master and Slave roles.
These drivers touch hardware registers and may use DMA.
Or they can be PIO bitbangers, needing just GPIO pins.
@@ -108,18 +109,18 @@ those two types of driver. At this writing, Linux has no slave side
programming interface.
There is a minimal core of SPI programming interfaces, focussing on
-using driver model to connect controller and protocol drivers using
+using the driver model to connect controller and protocol drivers using
device tables provided by board specific initialization code. SPI
shows up in sysfs in several locations:
- /sys/devices/.../CTLR/spiB.C ... spi_device for on bus "B",
+ /sys/devices/.../CTLR/spiB.C ... spi_device on bus "B",
chipselect C, accessed through CTLR.
/sys/devices/.../CTLR/spiB.C/modalias ... identifies the driver
that should be used with this device (for hotplug/coldplug)
/sys/bus/spi/devices/spiB.C ... symlink to the physical
- spiB-C device
+ spiB.C device
/sys/bus/spi/drivers/D ... driver for one or more spi*.* devices
@@ -240,7 +241,7 @@ The board_info should provide enough information to let the system work
without the chip's driver being loaded. The most troublesome aspect of
that is likely the SPI_CS_HIGH bit in the spi_device.mode field, since
sharing a bus with a device that interprets chipselect "backwards" is
-not possible.
+not possible until the infrastructure knows how to deselect it.
Then your board initialization code would register that table with the SPI
infrastructure, so that it's available later when the SPI master controller
@@ -268,16 +269,14 @@ board info based on the board that was hotplugged. Of course, you'd later
call at least spi_unregister_device() when that board is removed.
When Linux includes support for MMC/SD/SDIO/DataFlash cards through SPI, those
-configurations will also be dynamic. Fortunately, those devices all support
-basic device identification probes, so that support should hotplug normally.
+configurations will also be dynamic. Fortunately, such devices all support
+basic device identification probes, so they should hotplug normally.
How do I write an "SPI Protocol Driver"?
----------------------------------------
-All SPI drivers are currently kernel drivers. A userspace driver API
-would just be another kernel driver, probably offering some lowlevel
-access through aio_read(), aio_write(), and ioctl() calls and using the
-standard userspace sysfs mechanisms to bind to a given SPI device.
+Most SPI drivers are currently kernel drivers, but there's also support
+for userspace drivers. Here we talk only about kernel drivers.
SPI protocol drivers somewhat resemble platform device drivers:
@@ -319,7 +318,8 @@ might look like this unless you're creating a class_device:
As soon as it enters probe(), the driver may issue I/O requests to
the SPI device using "struct spi_message". When remove() returns,
-the driver guarantees that it won't submit any more such messages.
+or after probe() fails, the driver guarantees that it won't submit
+any more such messages.
- An spi_message is a sequence of protocol operations, executed
as one atomic sequence. SPI driver controls include:
@@ -368,7 +368,8 @@ the driver guarantees that it won't submit any more such messages.
Some drivers may need to modify spi_device characteristics like the
transfer mode, wordsize, or clock rate. This is done with spi_setup(),
which would normally be called from probe() before the first I/O is
-done to the device.
+done to the device. However, that can also be called at any time
+that no message is pending for that device.
While "spi_device" would be the bottom boundary of the driver, the
upper boundaries might include sysfs (especially for sensor readings),
@@ -445,11 +446,15 @@ SPI MASTER METHODS
This sets up the device clock rate, SPI mode, and word sizes.
Drivers may change the defaults provided by board_info, and then
call spi_setup(spi) to invoke this routine. It may sleep.
+ Unless each SPI slave has its own configuration registers, don't
+ change them right away ... otherwise drivers could corrupt I/O
+ that's in progress for other SPI devices.
master->transfer(struct spi_device *spi, struct spi_message *message)
This must not sleep. Its responsibility is arrange that the
- transfer happens and its complete() callback is issued; the two
- will normally happen later, after other transfers complete.
+ transfer happens and its complete() callback is issued. The two
+ will normally happen later, after other transfers complete, and
+ if the controller is idle it will need to be kickstarted.
master->cleanup(struct spi_device *spi)
Your controller driver may use spi_device.controller_state to hold
diff --git a/Documentation/spi/spidev b/Documentation/spi/spidev
new file mode 100644
index 0000000..5c8e1b98
--- /dev/null
+++ b/Documentation/spi/spidev
@@ -0,0 +1,307 @@
+SPI devices have a limited userspace API, supporting basic half-duplex
+read() and write() access to SPI slave devices. Using ioctl() requests,
+full duplex transfers and device I/O configuration are also available.
+
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <sys/ioctl.h>
+ #include <linux/types.h>
+ #include <linux/spi/spidev.h>
+
+Some reasons you might want to use this programming interface include:
+
+ * Prototyping in an environment that's not crash-prone; stray pointers
+ in userspace won't normally bring down any Linux system.
+
+ * Developing simple protocols used to talk to microcontrollers acting
+ as SPI slaves, which you may need to change quite often.
+
+Of course there are drivers that can never be written in userspace, because
+they need to access kernel interfaces (such as IRQ handlers or other layers
+of the driver stack) that are not accessible to userspace.
+
+
+DEVICE CREATION, DRIVER BINDING
+===============================
+The simplest way to arrange to use this driver is to just list it in the
+spi_board_info for a device as the driver it should use: the "modalias"
+entry is "spidev", matching the name of the driver exposing this API.
+Set up the other device characteristics (bits per word, SPI clocking,
+chipselect polarity, etc) as usual, so you won't always need to override
+them later.
+
+(Sysfs also supports userspace driven binding/unbinding of drivers to
+devices. That mechanism might be supported here in the future.)
+
+When you do that, the sysfs node for the SPI device will include a child
+device node with a "dev" attribute that will be understood by udev or mdev.
+(Larger systems will have "udev". Smaller ones may configure "mdev" into
+busybox; it's less featureful, but often enough.) For a SPI device with
+chipselect C on bus B, you should see:
+
+ /dev/spidevB.C ... character special device, major number 153 with
+ a dynamically chosen minor device number. This is the node
+ that userspace programs will open, created by "udev" or "mdev".
+
+ /sys/devices/.../spiB.C ... as usual, the SPI device node will
+ be a child of its SPI master controller.
+
+ /sys/class/spidev/spidevB.C ... created when the "spidev" driver
+ binds to that device. (Directory or symlink, based on whether
+ or not you enabled the "deprecated sysfs files" Kconfig option.)
+
+Do not try to manage the /dev character device special file nodes by hand.
+That's error prone, and you'd need to pay careful attention to system
+security issues; udev/mdev should already be configured securely.
+
+If you unbind the "spidev" driver from that device, those two "spidev" nodes
+(in sysfs and in /dev) should automatically be removed (respectively by the
+kernel and by udev/mdev). You can unbind by removing the "spidev" driver
+module, which will affect all devices using this driver. You can also unbind
+by having kernel code remove the SPI device, probably by removing the driver
+for its SPI controller (so its spi_master vanishes).
+
+Since this is a standard Linux device driver -- even though it just happens
+to expose a low level API to userspace -- it can be associated with any number
+of devices at a time. Just provide one spi_board_info record for each such
+SPI device, and you'll get a /dev device node for each device.
+
+
+BASIC CHARACTER DEVICE API
+==========================
+Normal open() and close() operations on /dev/spidevB.D files work as you
+would expect.
+
+Standard read() and write() operations are obviously only half-duplex, and
+the chipselect is deactivated between those operations. Full-duplex access,
+and composite operation without chipselect de-activation, is available using
+the SPI_IOC_MESSAGE(N) request.
+
+Several ioctl() requests let your driver read or override the device's current
+settings for data transfer parameters:
+
+ SPI_IOC_RD_MODE, SPI_IOC_WR_MODE ... pass a pointer to a byte which will
+ return (RD) or assign (WR) the SPI transfer mode. Use the constants
+ SPI_MODE_0..SPI_MODE_3; or if you prefer you can combine SPI_CPOL
+ (clock polarity, idle high iff this is set) or SPI_CPHA (clock phase,
+ sample on trailing edge iff this is set) flags.
+
+ SPI_IOC_RD_LSB_FIRST, SPI_IOC_WR_LSB_FIRST ... pass a pointer to a byte
+ which will return (RD) or assign (WR) the bit justification used to
+ transfer SPI words. Zero indicates MSB-first; other values indicate
+ the less common LSB-first encoding. In both cases the specified value
+ is right-justified in each word, so that unused (TX) or undefined (RX)
+ bits are in the MSBs.
+
+ SPI_IOC_RD_BITS_PER_WORD, SPI_IOC_WR_BITS_PER_WORD ... pass a pointer to
+ a byte which will return (RD) or assign (WR) the number of bits in
+ each SPI transfer word. The value zero signifies eight bits.
+
+ SPI_IOC_RD_MAX_SPEED_HZ, SPI_IOC_WR_MAX_SPEED_HZ ... pass a pointer to a
+ u32 which will return (RD) or assign (WR) the maximum SPI transfer
+ speed, in Hz. The controller can't necessarily assign that specific
+ clock speed.
+
+NOTES:
+
+ - At this time there is no async I/O support; everything is purely
+ synchronous.
+
+ - There's currently no way to report the actual bit rate used to
+ shift data to/from a given device.
+
+ - From userspace, you can't currently change the chip select polarity;
+ that could corrupt transfers to other devices sharing the SPI bus.
+ Each SPI device is deselected when it's not in active use, allowing
+ other drivers to talk to other devices.
+
+ - There's a limit on the number of bytes each I/O request can transfer
+ to the SPI device. It defaults to one page, but that can be changed
+ using a module parameter.
+
+ - Because SPI has no low-level transfer acknowledgement, you usually
+ won't see any I/O errors when talking to a non-existent device.
+
+
+FULL DUPLEX CHARACTER DEVICE API
+================================
+
+See the sample program below for one example showing the use of the full
+duplex programming interface. (Although it doesn't perform a full duplex
+transfer.) The model is the same as that used in the kernel spi_sync()
+request; the individual transfers offer the same capabilities as are
+available to kernel drivers (except that it's not asynchronous).
+
+The example shows one half-duplex RPC-style request and response message.
+These requests commonly require that the chip not be deselected between
+the request and response. Several such requests could be chained into
+a single kernel request, even allowing the chip to be deselected after
+each response. (Other protocol options include changing the word size
+and bitrate for each transfer segment.)
+
+To make a full duplex request, provide both rx_buf and tx_buf for the
+same transfer. It's even OK if those are the same buffer.
+
+
+SAMPLE PROGRAM
+==============
+
+-------------------------------- CUT HERE
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <linux/types.h>
+#include <linux/spi/spidev.h>
+
+
+static int verbose;
+
+static void do_read(int fd, int len)
+{
+ unsigned char buf[32], *bp;
+ int status;
+
+ /* read at least 2 bytes, no more than 32 */
+ if (len < 2)
+ len = 2;
+ else if (len > sizeof(buf))
+ len = sizeof(buf);
+ memset(buf, 0, sizeof buf);
+
+ status = read(fd, buf, len);
+ if (status < 0) {
+ perror("read");
+ return;
+ }
+ if (status != len) {
+ fprintf(stderr, "short read\n");
+ return;
+ }
+
+ printf("read(%2d, %2d): %02x %02x,", len, status,
+ buf[0], buf[1]);
+ status -= 2;
+ bp = buf + 2;
+ while (status-- > 0)
+ printf(" %02x", *bp++);
+ printf("\n");
+}
+
+static void do_msg(int fd, int len)
+{
+ struct spi_ioc_transfer xfer[2];
+ unsigned char buf[32], *bp;
+ int status;
+
+ memset(xfer, 0, sizeof xfer);
+ memset(buf, 0, sizeof buf);
+
+ if (len > sizeof buf)
+ len = sizeof buf;
+
+ buf[0] = 0xaa;
+ xfer[0].tx_buf = (__u64) buf;
+ xfer[0].len = 1;
+
+ xfer[1].rx_buf = (__u64) buf;
+ xfer[1].len = len;
+
+ status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer);
+ if (status < 0) {
+ perror("SPI_IOC_MESSAGE");
+ return;
+ }
+
+ printf("response(%2d, %2d): ", len, status);
+ for (bp = buf; len; len--)
+ printf(" %02x", *bp++);
+ printf("\n");
+}
+
+static void dumpstat(const char *name, int fd)
+{
+ __u8 mode, lsb, bits;
+ __u32 speed;
+
+ if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0) {
+ perror("SPI rd_mode");
+ return;
+ }
+ if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) {
+ perror("SPI rd_lsb_fist");
+ return;
+ }
+ if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) {
+ perror("SPI bits_per_word");
+ return;
+ }
+ if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) {
+ perror("SPI max_speed_hz");
+ return;
+ }
+
+ printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n",
+ name, mode, bits, lsb ? "(lsb first) " : "", speed);
+}
+
+int main(int argc, char **argv)
+{
+ int c;
+ int readcount = 0;
+ int msglen = 0;
+ int fd;
+ const char *name;
+
+ while ((c = getopt(argc, argv, "hm:r:v")) != EOF) {
+ switch (c) {
+ case 'm':
+ msglen = atoi(optarg);
+ if (msglen < 0)
+ goto usage;
+ continue;
+ case 'r':
+ readcount = atoi(optarg);
+ if (readcount < 0)
+ goto usage;
+ continue;
+ case 'v':
+ verbose++;
+ continue;
+ case 'h':
+ case '?':
+usage:
+ fprintf(stderr,
+ "usage: %s [-h] [-m N] [-r N] /dev/spidevB.D\n",
+ argv[0]);
+ return 1;
+ }
+ }
+
+ if ((optind + 1) != argc)
+ goto usage;
+ name = argv[optind];
+
+ fd = open(name, O_RDWR);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
+
+ dumpstat(name, fd);
+
+ if (msglen)
+ do_msg(fd, msglen);
+
+ if (readcount)
+ do_read(fd, readcount);
+
+ close(fd);
+ return 0;
+}
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
index e96a341..1d19256 100644
--- a/Documentation/sysctl/vm.txt
+++ b/Documentation/sysctl/vm.txt
@@ -197,11 +197,22 @@ and may not be fast.
panic_on_oom
-This enables or disables panic on out-of-memory feature. If this is set to 1,
-the kernel panics when out-of-memory happens. If this is set to 0, the kernel
-will kill some rogue process, called oom_killer. Usually, oom_killer can kill
-rogue processes and system will survive. If you want to panic the system
-rather than killing rogue processes, set this to 1.
+This enables or disables panic on out-of-memory feature.
-The default value is 0.
+If this is set to 0, the kernel will kill some rogue process,
+called oom_killer. Usually, oom_killer can kill rogue processes and
+system will survive.
+
+If this is set to 1, the kernel panics when out-of-memory happens.
+However, if a process limits using nodes by mempolicy/cpusets,
+and those nodes become memory exhaustion status, one process
+may be killed by oom-killer. No panic occurs in this case.
+Because other nodes' memory may be free. This means system total status
+may be not fatal yet.
+If this is set to 2, the kernel panics compulsorily even on the
+above-mentioned.
+
+The default value is 0.
+1 and 2 are for failover of clustering. Please select either
+according to your policy of failover.
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt
index d43aa9d..ba328f2 100644
--- a/Documentation/sysrq.txt
+++ b/Documentation/sysrq.txt
@@ -1,6 +1,6 @@
Linux Magic System Request Key Hacks
Documentation for sysrq.c
-Last update: 2007-JAN-06
+Last update: 2007-MAR-14
* What is the magic SysRq key?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -75,7 +75,7 @@ On all - write a character to /proc/sysrq-trigger. e.g.:
'f' - Will call oom_kill to kill a memory hog process.
-'g' - Used by kgdb on ppc platforms.
+'g' - Used by kgdb on ppc and sh platforms.
'h' - Will display help (actually any other key than those listed
above will display help. but 'h' is easy to remember :-)
diff --git a/Documentation/tty.txt b/Documentation/tty.txt
index 5f799e6..048a876 100644
--- a/Documentation/tty.txt
+++ b/Documentation/tty.txt
@@ -108,7 +108,9 @@ hardware driver through the function pointers within the tty->driver
structure:
write() Write a block of characters to the tty device.
- Returns the number of characters accepted.
+ Returns the number of characters accepted. The
+ character buffer passed to this method is already
+ in kernel space.
put_char() Queues a character for writing to the tty device.
If there is no room in the queue, the character is
diff --git a/Documentation/vm/slabinfo.c b/Documentation/vm/slabinfo.c
new file mode 100644
index 0000000..41710cc
--- /dev/null
+++ b/Documentation/vm/slabinfo.c
@@ -0,0 +1,943 @@
+/*
+ * Slabinfo: Tool to get reports about slabs
+ *
+ * (C) 2007 sgi, Christoph Lameter <clameter@sgi.com>
+ *
+ * Compile by:
+ *
+ * gcc -o slabinfo slabinfo.c
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <getopt.h>
+#include <regex.h>
+
+#define MAX_SLABS 500
+#define MAX_ALIASES 500
+#define MAX_NODES 1024
+
+struct slabinfo {
+ char *name;
+ int alias;
+ int refs;
+ int aliases, align, cache_dma, cpu_slabs, destroy_by_rcu;
+ int hwcache_align, object_size, objs_per_slab;
+ int sanity_checks, slab_size, store_user, trace;
+ int order, poison, reclaim_account, red_zone;
+ unsigned long partial, objects, slabs;
+ int numa[MAX_NODES];
+ int numa_partial[MAX_NODES];
+} slabinfo[MAX_SLABS];
+
+struct aliasinfo {
+ char *name;
+ char *ref;
+ struct slabinfo *slab;
+} aliasinfo[MAX_ALIASES];
+
+int slabs = 0;
+int aliases = 0;
+int alias_targets = 0;
+int highest_node = 0;
+
+char buffer[4096];
+
+int show_alias = 0;
+int show_slab = 0;
+int skip_zero = 1;
+int show_numa = 0;
+int show_track = 0;
+int show_first_alias = 0;
+int validate = 0;
+int shrink = 0;
+int show_inverted = 0;
+int show_single_ref = 0;
+int show_totals = 0;
+int sort_size = 0;
+
+int page_size;
+
+regex_t pattern;
+
+void fatal(const char *x, ...)
+{
+ va_list ap;
+
+ va_start(ap, x);
+ vfprintf(stderr, x, ap);
+ va_end(ap);
+ exit(1);
+}
+
+void usage(void)
+{
+ printf("slabinfo [-ahnpvtsz] [slab-regexp]\n"
+ "-a|--aliases Show aliases\n"
+ "-h|--help Show usage information\n"
+ "-n|--numa Show NUMA information\n"
+ "-s|--shrink Shrink slabs\n"
+ "-v|--validate Validate slabs\n"
+ "-t|--tracking Show alloc/free information\n"
+ "-T|--Totals Show summary information\n"
+ "-l|--slabs Show slabs\n"
+ "-S|--Size Sort by size\n"
+ "-z|--zero Include empty slabs\n"
+ "-f|--first-alias Show first alias\n"
+ "-i|--inverted Inverted list\n"
+ "-1|--1ref Single reference\n"
+ );
+}
+
+unsigned long read_obj(char *name)
+{
+ FILE *f = fopen(name, "r");
+
+ if (!f)
+ buffer[0] = 0;
+ else {
+ if (!fgets(buffer,sizeof(buffer), f))
+ buffer[0] = 0;
+ fclose(f);
+ if (buffer[strlen(buffer)] == '\n')
+ buffer[strlen(buffer)] = 0;
+ }
+ return strlen(buffer);
+}
+
+
+/*
+ * Get the contents of an attribute
+ */
+unsigned long get_obj(char *name)
+{
+ if (!read_obj(name))
+ return 0;
+
+ return atol(buffer);
+}
+
+unsigned long get_obj_and_str(char *name, char **x)
+{
+ unsigned long result = 0;
+ char *p;
+
+ *x = NULL;
+
+ if (!read_obj(name)) {
+ x = NULL;
+ return 0;
+ }
+ result = strtoul(buffer, &p, 10);
+ while (*p == ' ')
+ p++;
+ if (*p)
+ *x = strdup(p);
+ return result;
+}
+
+void set_obj(struct slabinfo *s, char *name, int n)
+{
+ char x[100];
+
+ sprintf(x, "%s/%s", s->name, name);
+
+ FILE *f = fopen(x, "w");
+
+ if (!f)
+ fatal("Cannot write to %s\n", x);
+
+ fprintf(f, "%d\n", n);
+ fclose(f);
+}
+
+/*
+ * Put a size string together
+ */
+int store_size(char *buffer, unsigned long value)
+{
+ unsigned long divisor = 1;
+ char trailer = 0;
+ int n;
+
+ if (value > 1000000000UL) {
+ divisor = 100000000UL;
+ trailer = 'G';
+ } else if (value > 1000000UL) {
+ divisor = 100000UL;
+ trailer = 'M';
+ } else if (value > 1000UL) {
+ divisor = 100;
+ trailer = 'K';
+ }
+
+ value /= divisor;
+ n = sprintf(buffer, "%ld",value);
+ if (trailer) {
+ buffer[n] = trailer;
+ n++;
+ buffer[n] = 0;
+ }
+ if (divisor != 1) {
+ memmove(buffer + n - 2, buffer + n - 3, 4);
+ buffer[n-2] = '.';
+ n++;
+ }
+ return n;
+}
+
+void decode_numa_list(int *numa, char *t)
+{
+ int node;
+ int nr;
+
+ memset(numa, 0, MAX_NODES * sizeof(int));
+
+ while (*t == 'N') {
+ t++;
+ node = strtoul(t, &t, 10);
+ if (*t == '=') {
+ t++;
+ nr = strtoul(t, &t, 10);
+ numa[node] = nr;
+ if (node > highest_node)
+ highest_node = node;
+ }
+ while (*t == ' ')
+ t++;
+ }
+}
+
+void slab_validate(struct slabinfo *s)
+{
+ set_obj(s, "validate", 1);
+}
+
+void slab_shrink(struct slabinfo *s)
+{
+ set_obj(s, "shrink", 1);
+}
+
+int line = 0;
+
+void first_line(void)
+{
+ printf("Name Objects Objsize Space "
+ "Slabs/Part/Cpu O/S O %%Fr %%Ef Flg\n");
+}
+
+/*
+ * Find the shortest alias of a slab
+ */
+struct aliasinfo *find_one_alias(struct slabinfo *find)
+{
+ struct aliasinfo *a;
+ struct aliasinfo *best = NULL;
+
+ for(a = aliasinfo;a < aliasinfo + aliases; a++) {
+ if (a->slab == find &&
+ (!best || strlen(best->name) < strlen(a->name))) {
+ best = a;
+ if (strncmp(a->name,"kmall", 5) == 0)
+ return best;
+ }
+ }
+ if (best)
+ return best;
+ fatal("Cannot find alias for %s\n", find->name);
+ return NULL;
+}
+
+unsigned long slab_size(struct slabinfo *s)
+{
+ return s->slabs * (page_size << s->order);
+}
+
+
+void slabcache(struct slabinfo *s)
+{
+ char size_str[20];
+ char dist_str[40];
+ char flags[20];
+ char *p = flags;
+
+ if (skip_zero && !s->slabs)
+ return;
+
+ store_size(size_str, slab_size(s));
+ sprintf(dist_str,"%lu/%lu/%d", s->slabs, s->partial, s->cpu_slabs);
+
+ if (!line++)
+ first_line();
+
+ if (s->aliases)
+ *p++ = '*';
+ if (s->cache_dma)
+ *p++ = 'd';
+ if (s->hwcache_align)
+ *p++ = 'A';
+ if (s->poison)
+ *p++ = 'P';
+ if (s->reclaim_account)
+ *p++ = 'a';
+ if (s->red_zone)
+ *p++ = 'Z';
+ if (s->sanity_checks)
+ *p++ = 'F';
+ if (s->store_user)
+ *p++ = 'U';
+ if (s->trace)
+ *p++ = 'T';
+
+ *p = 0;
+ printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n",
+ s->name, s->objects, s->object_size, size_str, dist_str,
+ s->objs_per_slab, s->order,
+ s->slabs ? (s->partial * 100) / s->slabs : 100,
+ s->slabs ? (s->objects * s->object_size * 100) /
+ (s->slabs * (page_size << s->order)) : 100,
+ flags);
+}
+
+void slab_numa(struct slabinfo *s)
+{
+ int node;
+
+ if (!highest_node)
+ fatal("No NUMA information available.\n");
+
+ if (skip_zero && !s->slabs)
+ return;
+
+ if (!line) {
+ printf("\nSlab Node ");
+ for(node = 0; node <= highest_node; node++)
+ printf(" %4d", node);
+ printf("\n----------------------");
+ for(node = 0; node <= highest_node; node++)
+ printf("-----");
+ printf("\n");
+ }
+ printf("%-21s ", s->name);
+ for(node = 0; node <= highest_node; node++) {
+ char b[20];
+
+ store_size(b, s->numa[node]);
+ printf(" %4s", b);
+ }
+ printf("\n");
+ line++;
+}
+
+void show_tracking(struct slabinfo *s)
+{
+ printf("\n%s: Calls to allocate a slab object\n", s->name);
+ printf("---------------------------------------------------\n");
+ if (read_obj("alloc_calls"))
+ printf(buffer);
+
+ printf("%s: Calls to free a slab object\n", s->name);
+ printf("-----------------------------------------------\n");
+ if (read_obj("free_calls"))
+ printf(buffer);
+
+}
+
+void totals(void)
+{
+ struct slabinfo *s;
+
+ int used_slabs = 0;
+ char b1[20], b2[20], b3[20], b4[20];
+ unsigned long long max = 1ULL << 63;
+
+ /* Object size */
+ unsigned long long min_objsize = max, max_objsize = 0, avg_objsize;
+
+ /* Number of partial slabs in a slabcache */
+ unsigned long long min_partial = max, max_partial = 0,
+ avg_partial, total_partial = 0;
+
+ /* Number of slabs in a slab cache */
+ unsigned long long min_slabs = max, max_slabs = 0,
+ avg_slabs, total_slabs = 0;
+
+ /* Size of the whole slab */
+ unsigned long long min_size = max, max_size = 0,
+ avg_size, total_size = 0;
+
+ /* Bytes used for object storage in a slab */
+ unsigned long long min_used = max, max_used = 0,
+ avg_used, total_used = 0;
+
+ /* Waste: Bytes used for alignment and padding */
+ unsigned long long min_waste = max, max_waste = 0,
+ avg_waste, total_waste = 0;
+ /* Number of objects in a slab */
+ unsigned long long min_objects = max, max_objects = 0,
+ avg_objects, total_objects = 0;
+ /* Waste per object */
+ unsigned long long min_objwaste = max,
+ max_objwaste = 0, avg_objwaste,
+ total_objwaste = 0;
+
+ /* Memory per object */
+ unsigned long long min_memobj = max,
+ max_memobj = 0, avg_memobj,
+ total_objsize = 0;
+
+ /* Percentage of partial slabs per slab */
+ unsigned long min_ppart = 100, max_ppart = 0,
+ avg_ppart, total_ppart = 0;
+
+ /* Number of objects in partial slabs */
+ unsigned long min_partobj = max, max_partobj = 0,
+ avg_partobj, total_partobj = 0;
+
+ /* Percentage of partial objects of all objects in a slab */
+ unsigned long min_ppartobj = 100, max_ppartobj = 0,
+ avg_ppartobj, total_ppartobj = 0;
+
+
+ for (s = slabinfo; s < slabinfo + slabs; s++) {
+ unsigned long long size;
+ unsigned long used;
+ unsigned long long wasted;
+ unsigned long long objwaste;
+ long long objects_in_partial_slabs;
+ unsigned long percentage_partial_slabs;
+ unsigned long percentage_partial_objs;
+
+ if (!s->slabs || !s->objects)
+ continue;
+
+ used_slabs++;
+
+ size = slab_size(s);
+ used = s->objects * s->object_size;
+ wasted = size - used;
+ objwaste = s->slab_size - s->object_size;
+
+ objects_in_partial_slabs = s->objects -
+ (s->slabs - s->partial - s ->cpu_slabs) *
+ s->objs_per_slab;
+
+ if (objects_in_partial_slabs < 0)
+ objects_in_partial_slabs = 0;
+
+ percentage_partial_slabs = s->partial * 100 / s->slabs;
+ if (percentage_partial_slabs > 100)
+ percentage_partial_slabs = 100;
+
+ percentage_partial_objs = objects_in_partial_slabs * 100
+ / s->objects;
+
+ if (percentage_partial_objs > 100)
+ percentage_partial_objs = 100;
+
+ if (s->object_size < min_objsize)
+ min_objsize = s->object_size;
+ if (s->partial < min_partial)
+ min_partial = s->partial;
+ if (s->slabs < min_slabs)
+ min_slabs = s->slabs;
+ if (size < min_size)
+ min_size = size;
+ if (wasted < min_waste)
+ min_waste = wasted;
+ if (objwaste < min_objwaste)
+ min_objwaste = objwaste;
+ if (s->objects < min_objects)
+ min_objects = s->objects;
+ if (used < min_used)
+ min_used = used;
+ if (objects_in_partial_slabs < min_partobj)
+ min_partobj = objects_in_partial_slabs;
+ if (percentage_partial_slabs < min_ppart)
+ min_ppart = percentage_partial_slabs;
+ if (percentage_partial_objs < min_ppartobj)
+ min_ppartobj = percentage_partial_objs;
+ if (s->slab_size < min_memobj)
+ min_memobj = s->slab_size;
+
+ if (s->object_size > max_objsize)
+ max_objsize = s->object_size;
+ if (s->partial > max_partial)
+ max_partial = s->partial;
+ if (s->slabs > max_slabs)
+ max_slabs = s->slabs;
+ if (size > max_size)
+ max_size = size;
+ if (wasted > max_waste)
+ max_waste = wasted;
+ if (objwaste > max_objwaste)
+ max_objwaste = objwaste;
+ if (s->objects > max_objects)
+ max_objects = s->objects;
+ if (used > max_used)
+ max_used = used;
+ if (objects_in_partial_slabs > max_partobj)
+ max_partobj = objects_in_partial_slabs;
+ if (percentage_partial_slabs > max_ppart)
+ max_ppart = percentage_partial_slabs;
+ if (percentage_partial_objs > max_ppartobj)
+ max_ppartobj = percentage_partial_objs;
+ if (s->slab_size > max_memobj)
+ max_memobj = s->slab_size;
+
+ total_partial += s->partial;
+ total_slabs += s->slabs;
+ total_size += size;
+ total_waste += wasted;
+
+ total_objects += s->objects;
+ total_used += used;
+ total_partobj += objects_in_partial_slabs;
+ total_ppart += percentage_partial_slabs;
+ total_ppartobj += percentage_partial_objs;
+
+ total_objwaste += s->objects * objwaste;
+ total_objsize += s->objects * s->slab_size;
+ }
+
+ if (!total_objects) {
+ printf("No objects\n");
+ return;
+ }
+ if (!used_slabs) {
+ printf("No slabs\n");
+ return;
+ }
+
+ /* Per slab averages */
+ avg_partial = total_partial / used_slabs;
+ avg_slabs = total_slabs / used_slabs;
+ avg_size = total_size / used_slabs;
+ avg_waste = total_waste / used_slabs;
+
+ avg_objects = total_objects / used_slabs;
+ avg_used = total_used / used_slabs;
+ avg_partobj = total_partobj / used_slabs;
+ avg_ppart = total_ppart / used_slabs;
+ avg_ppartobj = total_ppartobj / used_slabs;
+
+ /* Per object object sizes */
+ avg_objsize = total_used / total_objects;
+ avg_objwaste = total_objwaste / total_objects;
+ avg_partobj = total_partobj * 100 / total_objects;
+ avg_memobj = total_objsize / total_objects;
+
+ printf("Slabcache Totals\n");
+ printf("----------------\n");
+ printf("Slabcaches : %3d Aliases : %3d->%-3d Active: %3d\n",
+ slabs, aliases, alias_targets, used_slabs);
+
+ store_size(b1, total_size);store_size(b2, total_waste);
+ store_size(b3, total_waste * 100 / total_used);
+ printf("Memory used: %6s # Loss : %6s MRatio: %6s%%\n", b1, b2, b3);
+
+ store_size(b1, total_objects);store_size(b2, total_partobj);
+ store_size(b3, total_partobj * 100 / total_objects);
+ printf("# Objects : %6s # PartObj: %6s ORatio: %6s%%\n", b1, b2, b3);
+
+ printf("\n");
+ printf("Per Cache Average Min Max Total\n");
+ printf("---------------------------------------------------------\n");
+
+ store_size(b1, avg_objects);store_size(b2, min_objects);
+ store_size(b3, max_objects);store_size(b4, total_objects);
+ printf("#Objects %10s %10s %10s %10s\n",
+ b1, b2, b3, b4);
+
+ store_size(b1, avg_slabs);store_size(b2, min_slabs);
+ store_size(b3, max_slabs);store_size(b4, total_slabs);
+ printf("#Slabs %10s %10s %10s %10s\n",
+ b1, b2, b3, b4);
+
+ store_size(b1, avg_partial);store_size(b2, min_partial);
+ store_size(b3, max_partial);store_size(b4, total_partial);
+ printf("#PartSlab %10s %10s %10s %10s\n",
+ b1, b2, b3, b4);
+ store_size(b1, avg_ppart);store_size(b2, min_ppart);
+ store_size(b3, max_ppart);
+ store_size(b4, total_partial * 100 / total_slabs);
+ printf("%%PartSlab %10s%% %10s%% %10s%% %10s%%\n",
+ b1, b2, b3, b4);
+
+ store_size(b1, avg_partobj);store_size(b2, min_partobj);
+ store_size(b3, max_partobj);
+ store_size(b4, total_partobj);
+ printf("PartObjs %10s %10s %10s %10s\n",
+ b1, b2, b3, b4);
+
+ store_size(b1, avg_ppartobj);store_size(b2, min_ppartobj);
+ store_size(b3, max_ppartobj);
+ store_size(b4, total_partobj * 100 / total_objects);
+ printf("%% PartObj %10s%% %10s%% %10s%% %10s%%\n",
+ b1, b2, b3, b4);
+
+ store_size(b1, avg_size);store_size(b2, min_size);
+ store_size(b3, max_size);store_size(b4, total_size);
+ printf("Memory %10s %10s %10s %10s\n",
+ b1, b2, b3, b4);
+
+ store_size(b1, avg_used);store_size(b2, min_used);
+ store_size(b3, max_used);store_size(b4, total_used);
+ printf("Used %10s %10s %10s %10s\n",
+ b1, b2, b3, b4);
+
+ store_size(b1, avg_waste);store_size(b2, min_waste);
+ store_size(b3, max_waste);store_size(b4, total_waste);
+ printf("Loss %10s %10s %10s %10s\n",
+ b1, b2, b3, b4);
+
+ printf("\n");
+ printf("Per Object Average Min Max\n");
+ printf("---------------------------------------------\n");
+
+ store_size(b1, avg_memobj);store_size(b2, min_memobj);
+ store_size(b3, max_memobj);
+ printf("Memory %10s %10s %10s\n",
+ b1, b2, b3);
+ store_size(b1, avg_objsize);store_size(b2, min_objsize);
+ store_size(b3, max_objsize);
+ printf("User %10s %10s %10s\n",
+ b1, b2, b3);
+
+ store_size(b1, avg_objwaste);store_size(b2, min_objwaste);
+ store_size(b3, max_objwaste);
+ printf("Loss %10s %10s %10s\n",
+ b1, b2, b3);
+}
+
+void sort_slabs(void)
+{
+ struct slabinfo *s1,*s2;
+
+ for (s1 = slabinfo; s1 < slabinfo + slabs; s1++) {
+ for (s2 = s1 + 1; s2 < slabinfo + slabs; s2++) {
+ int result;
+
+ if (sort_size)
+ result = slab_size(s1) < slab_size(s2);
+ else
+ result = strcasecmp(s1->name, s2->name);
+
+ if (show_inverted)
+ result = -result;
+
+ if (result > 0) {
+ struct slabinfo t;
+
+ memcpy(&t, s1, sizeof(struct slabinfo));
+ memcpy(s1, s2, sizeof(struct slabinfo));
+ memcpy(s2, &t, sizeof(struct slabinfo));
+ }
+ }
+ }
+}
+
+void sort_aliases(void)
+{
+ struct aliasinfo *a1,*a2;
+
+ for (a1 = aliasinfo; a1 < aliasinfo + aliases; a1++) {
+ for (a2 = a1 + 1; a2 < aliasinfo + aliases; a2++) {
+ char *n1, *n2;
+
+ n1 = a1->name;
+ n2 = a2->name;
+ if (show_alias && !show_inverted) {
+ n1 = a1->ref;
+ n2 = a2->ref;
+ }
+ if (strcasecmp(n1, n2) > 0) {
+ struct aliasinfo t;
+
+ memcpy(&t, a1, sizeof(struct aliasinfo));
+ memcpy(a1, a2, sizeof(struct aliasinfo));
+ memcpy(a2, &t, sizeof(struct aliasinfo));
+ }
+ }
+ }
+}
+
+void link_slabs(void)
+{
+ struct aliasinfo *a;
+ struct slabinfo *s;
+
+ for (a = aliasinfo; a < aliasinfo + aliases; a++) {
+
+ for(s = slabinfo; s < slabinfo + slabs; s++)
+ if (strcmp(a->ref, s->name) == 0) {
+ a->slab = s;
+ s->refs++;
+ break;
+ }
+ if (s == slabinfo + slabs)
+ fatal("Unresolved alias %s\n", a->ref);
+ }
+}
+
+void alias(void)
+{
+ struct aliasinfo *a;
+ char *active = NULL;
+
+ sort_aliases();
+ link_slabs();
+
+ for(a = aliasinfo; a < aliasinfo + aliases; a++) {
+
+ if (!show_single_ref && a->slab->refs == 1)
+ continue;
+
+ if (!show_inverted) {
+ if (active) {
+ if (strcmp(a->slab->name, active) == 0) {
+ printf(" %s", a->name);
+ continue;
+ }
+ }
+ printf("\n%-20s <- %s", a->slab->name, a->name);
+ active = a->slab->name;
+ }
+ else
+ printf("%-20s -> %s\n", a->name, a->slab->name);
+ }
+ if (active)
+ printf("\n");
+}
+
+
+void rename_slabs(void)
+{
+ struct slabinfo *s;
+ struct aliasinfo *a;
+
+ for (s = slabinfo; s < slabinfo + slabs; s++) {
+ if (*s->name != ':')
+ continue;
+
+ if (s->refs > 1 && !show_first_alias)
+ continue;
+
+ a = find_one_alias(s);
+
+ s->name = a->name;
+ }
+}
+
+int slab_mismatch(char *slab)
+{
+ return regexec(&pattern, slab, 0, NULL, 0);
+}
+
+void read_slab_dir(void)
+{
+ DIR *dir;
+ struct dirent *de;
+ struct slabinfo *slab = slabinfo;
+ struct aliasinfo *alias = aliasinfo;
+ char *p;
+ char *t;
+ int count;
+
+ dir = opendir(".");
+ while ((de = readdir(dir))) {
+ if (de->d_name[0] == '.' ||
+ slab_mismatch(de->d_name))
+ continue;
+ switch (de->d_type) {
+ case DT_LNK:
+ alias->name = strdup(de->d_name);
+ count = readlink(de->d_name, buffer, sizeof(buffer));
+
+ if (count < 0)
+ fatal("Cannot read symlink %s\n", de->d_name);
+
+ buffer[count] = 0;
+ p = buffer + count;
+ while (p > buffer && p[-1] != '/')
+ p--;
+ alias->ref = strdup(p);
+ alias++;
+ break;
+ case DT_DIR:
+ if (chdir(de->d_name))
+ fatal("Unable to access slab %s\n", slab->name);
+ slab->name = strdup(de->d_name);
+ slab->alias = 0;
+ slab->refs = 0;
+ slab->aliases = get_obj("aliases");
+ slab->align = get_obj("align");
+ slab->cache_dma = get_obj("cache_dma");
+ slab->cpu_slabs = get_obj("cpu_slabs");
+ slab->destroy_by_rcu = get_obj("destroy_by_rcu");
+ slab->hwcache_align = get_obj("hwcache_align");
+ slab->object_size = get_obj("object_size");
+ slab->objects = get_obj("objects");
+ slab->objs_per_slab = get_obj("objs_per_slab");
+ slab->order = get_obj("order");
+ slab->partial = get_obj("partial");
+ slab->partial = get_obj_and_str("partial", &t);
+ decode_numa_list(slab->numa_partial, t);
+ slab->poison = get_obj("poison");
+ slab->reclaim_account = get_obj("reclaim_account");
+ slab->red_zone = get_obj("red_zone");
+ slab->sanity_checks = get_obj("sanity_checks");
+ slab->slab_size = get_obj("slab_size");
+ slab->slabs = get_obj_and_str("slabs", &t);
+ decode_numa_list(slab->numa, t);
+ slab->store_user = get_obj("store_user");
+ slab->trace = get_obj("trace");
+ chdir("..");
+ if (slab->name[0] == ':')
+ alias_targets++;
+ slab++;
+ break;
+ default :
+ fatal("Unknown file type %lx\n", de->d_type);
+ }
+ }
+ closedir(dir);
+ slabs = slab - slabinfo;
+ aliases = alias - aliasinfo;
+ if (slabs > MAX_SLABS)
+ fatal("Too many slabs\n");
+ if (aliases > MAX_ALIASES)
+ fatal("Too many aliases\n");
+}
+
+void output_slabs(void)
+{
+ struct slabinfo *slab;
+
+ for (slab = slabinfo; slab < slabinfo + slabs; slab++) {
+
+ if (slab->alias)
+ continue;
+
+
+ if (show_numa)
+ slab_numa(slab);
+ else
+ if (show_track)
+ show_tracking(slab);
+ else
+ if (validate)
+ slab_validate(slab);
+ else
+ if (shrink)
+ slab_shrink(slab);
+ else {
+ if (show_slab)
+ slabcache(slab);
+ }
+ }
+}
+
+struct option opts[] = {
+ { "aliases", 0, NULL, 'a' },
+ { "slabs", 0, NULL, 'l' },
+ { "numa", 0, NULL, 'n' },
+ { "zero", 0, NULL, 'z' },
+ { "help", 0, NULL, 'h' },
+ { "validate", 0, NULL, 'v' },
+ { "first-alias", 0, NULL, 'f' },
+ { "shrink", 0, NULL, 's' },
+ { "track", 0, NULL, 't'},
+ { "inverted", 0, NULL, 'i'},
+ { "1ref", 0, NULL, '1'},
+ { NULL, 0, NULL, 0 }
+};
+
+int main(int argc, char *argv[])
+{
+ int c;
+ int err;
+ char *pattern_source;
+
+ page_size = getpagesize();
+ if (chdir("/sys/slab"))
+ fatal("This kernel does not have SLUB support.\n");
+
+ while ((c = getopt_long(argc, argv, "afhil1npstvzTS", opts, NULL)) != -1)
+ switch(c) {
+ case '1':
+ show_single_ref = 1;
+ break;
+ case 'a':
+ show_alias = 1;
+ break;
+ case 'f':
+ show_first_alias = 1;
+ break;
+ case 'h':
+ usage();
+ return 0;
+ case 'i':
+ show_inverted = 1;
+ break;
+ case 'n':
+ show_numa = 1;
+ break;
+ case 's':
+ shrink = 1;
+ break;
+ case 'l':
+ show_slab = 1;
+ break;
+ case 't':
+ show_track = 1;
+ break;
+ case 'v':
+ validate = 1;
+ break;
+ case 'z':
+ skip_zero = 0;
+ break;
+ case 'T':
+ show_totals = 1;
+ break;
+ case 'S':
+ sort_size = 1;
+ break;
+
+ default:
+ fatal("%s: Invalid option '%c'\n", argv[0], optopt);
+
+ }
+
+ if (!show_slab && !show_alias && !show_track
+ && !validate && !shrink)
+ show_slab = 1;
+
+ if (argc > optind)
+ pattern_source = argv[optind];
+ else
+ pattern_source = ".*";
+
+ err = regcomp(&pattern, pattern_source, REG_ICASE|REG_NOSUB);
+ if (err)
+ fatal("%s: Invalid pattern '%s' code %d\n",
+ argv[0], pattern_source, err);
+ read_slab_dir();
+ if (show_alias)
+ alias();
+ else
+ if (show_totals)
+ totals();
+ else {
+ link_slabs();
+ rename_slabs();
+ sort_slabs();
+ output_slabs();
+ }
+ return 0;
+}
diff --git a/Documentation/vm/slub.txt b/Documentation/vm/slub.txt
new file mode 100644
index 0000000..727c8d8
--- /dev/null
+++ b/Documentation/vm/slub.txt
@@ -0,0 +1,113 @@
+Short users guide for SLUB
+--------------------------
+
+First of all slub should transparently replace SLAB. If you enable
+SLUB then everything should work the same (Note the word "should".
+There is likely not much value in that word at this point).
+
+The basic philosophy of SLUB is very different from SLAB. SLAB
+requires rebuilding the kernel to activate debug options for all
+SLABS. SLUB always includes full debugging but its off by default.
+SLUB can enable debugging only for selected slabs in order to avoid
+an impact on overall system performance which may make a bug more
+difficult to find.
+
+In order to switch debugging on one can add a option "slub_debug"
+to the kernel command line. That will enable full debugging for
+all slabs.
+
+Typically one would then use the "slabinfo" command to get statistical
+data and perform operation on the slabs. By default slabinfo only lists
+slabs that have data in them. See "slabinfo -h" for more options when
+running the command. slabinfo can be compiled with
+
+gcc -o slabinfo Documentation/vm/slabinfo.c
+
+Some of the modes of operation of slabinfo require that slub debugging
+be enabled on the command line. F.e. no tracking information will be
+available without debugging on and validation can only partially
+be performed if debugging was not switched on.
+
+Some more sophisticated uses of slub_debug:
+-------------------------------------------
+
+Parameters may be given to slub_debug. If none is specified then full
+debugging is enabled. Format:
+
+slub_debug=<Debug-Options> Enable options for all slabs
+slub_debug=<Debug-Options>,<slab name>
+ Enable options only for select slabs
+
+Possible debug options are
+ F Sanity checks on (enables SLAB_DEBUG_FREE. Sorry
+ SLAB legacy issues)
+ Z Red zoning
+ P Poisoning (object and padding)
+ U User tracking (free and alloc)
+ T Trace (please only use on single slabs)
+
+F.e. in order to boot just with sanity checks and red zoning one would specify:
+
+ slub_debug=FZ
+
+Trying to find an issue in the dentry cache? Try
+
+ slub_debug=,dentry_cache
+
+to only enable debugging on the dentry cache.
+
+Red zoning and tracking may realign the slab. We can just apply sanity checks
+to the dentry cache with
+
+ slub_debug=F,dentry_cache
+
+In case you forgot to enable debugging on the kernel command line: It is
+possible to enable debugging manually when the kernel is up. Look at the
+contents of:
+
+/sys/slab/<slab name>/
+
+Look at the writable files. Writing 1 to them will enable the
+corresponding debug option. All options can be set on a slab that does
+not contain objects. If the slab already contains objects then sanity checks
+and tracing may only be enabled. The other options may cause the realignment
+of objects.
+
+Careful with tracing: It may spew out lots of information and never stop if
+used on the wrong slab.
+
+SLAB Merging
+------------
+
+If no debugging is specified then SLUB may merge similar slabs together
+in order to reduce overhead and increase cache hotness of objects.
+slabinfo -a displays which slabs were merged together.
+
+Getting more performance
+------------------------
+
+To some degree SLUB's performance is limited by the need to take the
+list_lock once in a while to deal with partial slabs. That overhead is
+governed by the order of the allocation for each slab. The allocations
+can be influenced by kernel parameters:
+
+slub_min_objects=x (default 8)
+slub_min_order=x (default 0)
+slub_max_order=x (default 4)
+
+slub_min_objects allows to specify how many objects must at least fit
+into one slab in order for the allocation order to be acceptable.
+In general slub will be able to perform this number of allocations
+on a slab without consulting centralized resources (list_lock) where
+contention may occur.
+
+slub_min_order specifies a minim order of slabs. A similar effect like
+slub_min_objects.
+
+slub_max_order specified the order at which slub_min_objects should no
+longer be checked. This is useful to avoid SLUB trying to generate
+super large order pages to fit slub_min_objects of a slab cache with
+large object sizes into one high order page.
+
+
+Christoph Lameter, <clameter@sgi.com>, April 10, 2007
diff --git a/Kbuild b/Kbuild
index 0451f69..163f8cb 100644
--- a/Kbuild
+++ b/Kbuild
@@ -2,6 +2,7 @@
# Kbuild for top-level directory of the kernel
# This file takes care of the following:
# 1) Generate asm-offsets.h
+# 2) Check for missing system calls
#####
# 1) Generate asm-offsets.h
@@ -46,3 +47,13 @@ $(obj)/$(offsets-file): arch/$(ARCH)/kernel/asm-offsets.s Kbuild
$(Q)mkdir -p $(dir $@)
$(call cmd,offsets)
+#####
+# 2) Check for missing system calls
+#
+
+quiet_cmd_syscalls = CALL $<
+ cmd_syscalls = $(CONFIG_SHELL) $< $(CC) $(c_flags)
+
+PHONY += missing-syscalls
+missing-syscalls: scripts/checksyscalls.sh FORCE
+ $(call cmd,syscalls)
diff --git a/MAINTAINERS b/MAINTAINERS
index 0492dd8..41a4b47 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -382,6 +382,12 @@ L: linux-laptop@vger.kernel.org
W: http://www.canb.auug.org.au/~sfr/
S: Supported
+APPLE SMC DRIVER
+P: Nicolas Boichat
+M: nicolas@boichat.ch
+L: mactel-linux-devel@lists.sourceforge.net
+S: Maintained
+
APPLETALK NETWORK LAYER
P: Arnaldo Carvalho de Melo
M: acme@ghostprotocols.net
@@ -673,6 +679,7 @@ AUXILIARY DISPLAY DRIVERS
P: Miguel Ojeda Sandonis
M: maxextreme@gmail.com
L: linux-kernel@vger.kernel.org
+W: http://auxdisplay.googlepages.com/
S: Maintained
AVR32 ARCHITECTURE
@@ -700,6 +707,44 @@ P: Richard Purdie
M: rpurdie@rpsys.net
S: Maintained
+BLACKFIN ARCHITECTURE
+P: Aubrey Li
+M: aubrey.li@analog.com
+P: Bernd Schmidt
+M: bernd.schmidt@analog.com
+P: Bryan Wu
+M: bryan.wu@analog.com
+P: Grace Pan
+M: grace.pan@analog.com
+P: Michael Hennerich
+M: michael.hennerich@analog.com
+P: Mike Frysinger
+M: michael.frysinger@analog.com
+P: Jane Lv
+M: jane.lv@analog.com
+P: Jerry Zeng
+M: jerry.zeng@analog.com
+P: Jie Zhang
+M: jie.zhang@analog.com
+P: Robin Getz
+M: robin.getz@analog.com
+P: Roy Huang
+M: roy.huang@analog.com
+P: Sonic Zhang
+M: sonic.zhang@analog.com
+P: Yi Li
+M: yi.li@analog.com
+L: uclinux-dist-devel@blackfin.uclinux.org
+W: http://blackfin.uclinux.org
+S: Supported
+
+BLACKFIN SERIAL DRIVER
+P: Aubrey Li
+M: aubrey.li@analog.com
+L: uclinux-dist-devel@blackfin.uclinux.org
+W: http://blackfin.uclinux.org
+S: Supported
+
BAYCOM/HDLCDRV DRIVERS FOR AX.25
P: Thomas Sailer
M: t.sailer@alumni.ethz.ch
@@ -899,12 +944,14 @@ CFAG12864B LCD DRIVER
P: Miguel Ojeda Sandonis
M: maxextreme@gmail.com
L: linux-kernel@vger.kernel.org
+W: http://auxdisplay.googlepages.com/
S: Maintained
CFAG12864BFB LCD FRAMEBUFFER DRIVER
P: Miguel Ojeda Sandonis
M: maxextreme@gmail.com
L: linux-kernel@vger.kernel.org
+W: http://auxdisplay.googlepages.com/
S: Maintained
CFG80211 and NL80211
@@ -993,6 +1040,12 @@ P: Simon Arlott
M: cxacru@fire.lp0.eu
S: Maintained
+CORETEMP HARDWARE MONITORING DRIVER
+P: Rudolf Marek
+M: r.marek@assembler.cz
+L: lm-sensors@lm-sensors.org
+S: Maintained
+
COSA/SRP SYNC SERIAL DRIVER
P: Jan "Yenya" Kasprzak
M: kas@fi.muni.cz
@@ -1983,7 +2036,7 @@ P: Vivek Goyal
M: vgoyal@in.ibm.com
P: Haren Myneni
M: hbabu@us.ibm.com
-L: fastboot@lists.linux-foundation.org
+L: kexec@lists.infradead.org
L: linux-kernel@vger.kernel.org
W: http://lse.sourceforge.net/kdump/
S: Maintained
@@ -2033,7 +2086,7 @@ P: Eric Biederman
M: ebiederm@xmission.com
W: http://www.xmission.com/~ebiederm/files/kexec/
L: linux-kernel@vger.kernel.org
-L: fastboot@lists.linux-foundation.org
+L: kexec@lists.infradead.org
S: Maintained
KPROBES
@@ -2052,6 +2105,7 @@ KS0108 LCD CONTROLLER DRIVER
P: Miguel Ojeda Sandonis
M: maxextreme@gmail.com
L: linux-kernel@vger.kernel.org
+W: http://auxdisplay.googlepages.com/
S: Maintained
LAPB module
@@ -2266,6 +2320,12 @@ M: vandrove@vc.cvut.cz
L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
S: Maintained
+MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
+P: Hans J. Koch
+M: hjk@linutronix.de
+L: lm-sensors@lm-sensors.org
+S: Maintained
+
MEGARAID SCSI DRIVERS
P: Neela Syam Kolli
M: Neela.Kolli@engenio.com
@@ -3060,6 +3120,11 @@ L: selinux@tycho.nsa.gov (subscribers-only, general discussion)
W: http://www.nsa.gov/selinux
S: Supported
+SENSABLE PHANTOM
+P: Jiri Slaby
+M: jirislaby@gmail.com
+S: Maintained
+
SERIAL ATA (SATA) SUBSYSTEM:
P: Jeff Garzik
M: jgarzik@pobox.com
diff --git a/Makefile b/Makefile
index 387526b..dfe559c 100644
--- a/Makefile
+++ b/Makefile
@@ -576,7 +576,7 @@ libs-y := $(libs-y1) $(libs-y2)
# ---------------------------------------------------------------------------
# vmlinux is built from the objects selected by $(vmlinux-init) and
# $(vmlinux-main). Most are built-in.o files from top-level directories
-# in the kernel tree, others are specified in arch/$(ARCH)Makefile.
+# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
# Ordering when linking is important, and $(vmlinux-init) must be first.
#
# vmlinux
@@ -603,6 +603,7 @@ vmlinux-init := $(head-y) $(init-y)
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
vmlinux-all := $(vmlinux-init) $(vmlinux-main)
vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.lds
+export KBUILD_VMLINUX_OBJS := $(vmlinux-all)
# Rule to link vmlinux - also used during CONFIG_KALLSYMS
# May be overridden by arch/$(ARCH)/Makefile
@@ -855,6 +856,7 @@ archprepare: prepare1 scripts_basic
prepare0: archprepare FORCE
$(Q)$(MAKE) $(build)=.
+ $(Q)$(MAKE) $(build)=. missing-syscalls
# All the preparing..
prepare: prepare0
@@ -1277,10 +1279,7 @@ endif
ALLSOURCE_ARCHS := $(ARCH)
define find-sources
- ( find $(__srctree) $(RCS_FIND_IGNORE) \
- \( -name include -o -name arch \) -prune -o \
- -name $1 -print; \
- for ARCH in $(ALLSOURCE_ARCHS) ; do \
+ ( for ARCH in $(ALLSOURCE_ARCHS) ; do \
find $(__srctree)arch/$${ARCH} $(RCS_FIND_IGNORE) \
-name $1 -print; \
done ; \
@@ -1294,7 +1293,11 @@ define find-sources
-name $1 -print; \
done ; \
find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \
- -name $1 -print )
+ -name $1 -print; \
+ find $(__srctree) $(RCS_FIND_IGNORE) \
+ \( -name include -o -name arch \) -prune -o \
+ -name $1 -print; \
+ )
endef
define all-sources
diff --git a/arch/alpha/Kconfig.debug b/arch/alpha/Kconfig.debug
index 36d0106..f45f28c 100644
--- a/arch/alpha/Kconfig.debug
+++ b/arch/alpha/Kconfig.debug
@@ -16,14 +16,6 @@ config DEBUG_RWLOCK
too many attempts. If you suspect a rwlock problem or a kernel
hacker asks for this option then say Y. Otherwise say N.
-config DEBUG_SEMAPHORE
- bool "Semaphore debugging"
- depends on DEBUG_KERNEL
- help
- If you say Y here then semaphore processing will issue lots of
- verbose debugging messages. If you suspect a semaphore problem or a
- kernel hacker asks for this option then say Y. Otherwise say N.
-
config ALPHA_LEGACY_START_ADDRESS
bool "Legacy kernel start address"
depends on ALPHA_GENERIC
diff --git a/arch/alpha/boot/bootpz.c b/arch/alpha/boot/bootpz.c
index 4307bde..1036b51 100644
--- a/arch/alpha/boot/bootpz.c
+++ b/arch/alpha/boot/bootpz.c
@@ -467,3 +467,9 @@ start_kernel(void)
#endif
runkernel();
}
+
+ /* dummy function, should never be called. */
+void *__kmalloc(size_t size, gfp_t flags)
+{
+ return (void *)NULL;
+}
diff --git a/arch/alpha/boot/tools/objstrip.c b/arch/alpha/boot/tools/objstrip.c
index 67beb1b..96154e7 100644
--- a/arch/alpha/boot/tools/objstrip.c
+++ b/arch/alpha/boot/tools/objstrip.c
@@ -25,7 +25,6 @@
#include <linux/a.out.h>
#include <linux/coff.h>
#include <linux/param.h>
-#include <linux/string.h>
#ifdef __ELF__
# include <linux/elf.h>
#endif
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index be133f1..ce85715 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -93,7 +93,6 @@ osf_set_program_attributes(unsigned long text_start, unsigned long text_len,
* offset differences aren't the same as "d_reclen").
*/
#define NAME_OFFSET offsetof (struct osf_dirent, d_name)
-#define ROUND_UP(x) (((x)+3) & ~3)
struct osf_dirent {
unsigned int d_ino;
@@ -115,7 +114,7 @@ osf_filldir(void *__buf, const char *name, int namlen, loff_t offset,
{
struct osf_dirent __user *dirent;
struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf;
- unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1);
+ unsigned int reclen = ALIGN(NAME_OFFSET + namlen + 1, sizeof(u32));
unsigned int d_ino;
buf->error = -EINVAL; /* only used if we fail */
@@ -174,7 +173,6 @@ osf_getdirentries(unsigned int fd, struct osf_dirent __user *dirent,
return error;
}
-#undef ROUND_UP
#undef NAME_OFFSET
asmlinkage unsigned long
@@ -955,15 +953,25 @@ osf_setitimer(int which, struct itimerval32 __user *in, struct itimerval32 __use
asmlinkage int
osf_utimes(char __user *filename, struct timeval32 __user *tvs)
{
- struct timeval ktvs[2];
+ struct timespec tv[2];
if (tvs) {
+ struct timeval ktvs[2];
if (get_tv32(&ktvs[0], &tvs[0]) ||
get_tv32(&ktvs[1], &tvs[1]))
return -EFAULT;
+
+ if (ktvs[0].tv_usec < 0 || ktvs[0].tv_usec >= 1000000 ||
+ ktvs[1].tv_usec < 0 || ktvs[1].tv_usec >= 1000000)
+ return -EINVAL;
+
+ tv[0].tv_sec = ktvs[0].tv_sec;
+ tv[0].tv_nsec = 1000 * ktvs[0].tv_usec;
+ tv[1].tv_sec = ktvs[1].tv_sec;
+ tv[1].tv_nsec = 1000 * ktvs[1].tv_usec;
}
- return do_utimes(AT_FDCWD, filename, tvs ? ktvs : NULL);
+ return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL, 0);
}
#define MAX_SELECT_SECONDS \
@@ -1267,6 +1275,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
if (len > limit)
return -ENOMEM;
+ if (flags & MAP_FIXED)
+ return addr;
+
/* First, see if the given suggestion fits.
The OSF/1 loader (/sbin/loader) relies on us returning an
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index c151863..92b6162 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index d352c2b..915f263 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -744,15 +744,6 @@ setup_arch(char **cmdline_p)
paging_init();
}
-void __init
-disable_early_printk(void)
-{
- if (alpha_using_srm && srmcons_output) {
- unregister_srm_console();
- srmcons_output = 0;
- }
-}
-
static char sys_unknown[] = "Unknown";
static char systype_names[][16] = {
"0",
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index 741da09..7f64aa7 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -15,7 +15,6 @@
#include <linux/unistd.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index d1ec4f5..80cfb75 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -18,7 +18,6 @@
#include <linux/mm.h>
#include <linux/threads.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c
index 7569232..930cedc 100644
--- a/arch/alpha/kernel/srmcons.c
+++ b/arch/alpha/kernel/srmcons.c
@@ -164,9 +164,9 @@ srmcons_get_private_struct(struct srmcons_private **ps)
int retval = 0;
if (srmconsp == NULL) {
+ srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL);
spin_lock_irqsave(&srmconsp_lock, flags);
- srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL);
if (srmconsp == NULL)
retval = -ENOMEM;
else {
@@ -300,7 +300,7 @@ static struct console srmcons = {
.write = srm_console_write,
.device = srm_console_device,
.setup = srm_console_setup,
- .flags = CON_PRINTBUFFER,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
.index = -1,
};
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index 8aa9db8..f586279 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -21,7 +21,6 @@
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/module.h>
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index db00376..0d8fac3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -29,6 +29,10 @@ config GENERIC_TIME
bool
default n
+config GENERIC_CLOCKEVENTS
+ bool
+ default n
+
config MMU
bool
default y
@@ -67,6 +71,14 @@ config GENERIC_HARDIRQS
bool
default y
+config STACKTRACE_SUPPORT
+ bool
+ default y
+
+config LOCKDEP_SUPPORT
+ bool
+ default y
+
config TRACE_IRQFLAGS_SUPPORT
bool
default y
@@ -162,6 +174,8 @@ config ARCH_VERSATILE
select ARM_AMBA
select ARM_VIC
select ICST307
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
help
This enables support for ARM Ltd Versatile board.
@@ -263,6 +277,7 @@ config ARCH_IXP4XX
bool "IXP4xx-based"
depends on MMU
select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
help
Support for Intel's IXP4XX (XScale) family of processors.
@@ -364,6 +379,7 @@ config ARCH_LH7A40X
config ARCH_OMAP
bool "TI OMAP"
select GENERIC_GPIO
+ select GENERIC_TIME
help
Support for TI's OMAP platform (OMAP1 and OMAP2).
@@ -514,6 +530,8 @@ endmenu
menu "Kernel Features"
+source "kernel/time/Kconfig"
+
config SMP
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
depends on EXPERIMENTAL && REALVIEW_MPCORE
@@ -573,6 +591,7 @@ config PREEMPT
config NO_IDLE_HZ
bool "Dynamic tick timer"
+ depends on !GENERIC_CLOCKEVENTS
help
Select this option if you want to disable continuous timer ticks
and have them programmed to occur as required. This option saves
@@ -670,6 +689,7 @@ config LEDS_TIMER
bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \
MACH_OMAP_H2 || MACH_OMAP_PERSEUS2
depends on LEDS
+ depends on !GENERIC_CLOCKEVENTS
default y if ARCH_EBSA110
help
If you say Y here, one of the system LEDs (the green one on the
diff --git a/arch/arm/boot/compressed/head-at91rm9200.S b/arch/arm/boot/compressed/head-at91rm9200.S
index d68b9ac..11782cc 100644
--- a/arch/arm/boot/compressed/head-at91rm9200.S
+++ b/arch/arm/boot/compressed/head-at91rm9200.S
@@ -61,6 +61,12 @@
cmp r7, r3
beq 99f
+ @ picotux 200 : 963
+ mov r3, #(MACH_TYPE_PICOTUX2XX & 0xff)
+ orr r3, r3, #(MACH_TYPE_PICOTUX2XX & 0xff00)
+ cmp r7, r3
+ beq 99f
+
@ Ajeco 1ARM : 1075
mov r3, #(MACH_TYPE_ONEARM & 0xff)
orr r3, r3, #(MACH_TYPE_ONEARM & 0xff00)
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index fe3f059..798bbfc 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -18,7 +18,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
-#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
diff --git a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c
index ba2e629..79a8206 100644
--- a/arch/arm/common/via82c505.c
+++ b/arch/arm/common/via82c505.c
@@ -1,6 +1,5 @@
#include <linux/kernel.h>
#include <linux/pci.h>
-#include <linux/ptrace.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/init.h>
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index fabf74c..db850a5 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -117,11 +117,13 @@ CONFIG_ARCH_ADI_COYOTE=y
CONFIG_ARCH_IXDP425=y
CONFIG_MACH_IXDPG425=y
CONFIG_MACH_IXDP465=y
+CONFIG_MACH_KIXRP435=y
CONFIG_ARCH_IXCDP1100=y
CONFIG_ARCH_PRPMC1100=y
CONFIG_MACH_NAS100D=y
CONFIG_ARCH_IXDP4XX=y
CONFIG_CPU_IXP46X=y
+CONFIG_CPU_IXP43X=y
# CONFIG_MACH_GTWX5715 is not set
#
diff --git a/arch/arm/configs/picotux200_defconfig b/arch/arm/configs/picotux200_defconfig
new file mode 100644
index 0000000..339c489
--- /dev/null
+++ b/arch/arm/configs/picotux200_defconfig
@@ -0,0 +1,1386 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-rc4
+# Wed Mar 28 16:19:50 2007
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=m
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Atmel AT91 System-on-Chip
+#
+CONFIG_ARCH_AT91RM9200=y
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+
+#
+# AT91RM9200 Board Type
+#
+# CONFIG_MACH_ONEARM is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+# CONFIG_MACH_AT91RM9200EK is not set
+# CONFIG_MACH_CSB337 is not set
+# CONFIG_MACH_CSB637 is not set
+# CONFIG_MACH_CARMEVA is not set
+# CONFIG_MACH_ATEB9200 is not set
+# CONFIG_MACH_KB9200 is not set
+CONFIG_MACH_PICOTUX2XX=y
+# CONFIG_MACH_KAFA is not set
+
+#
+# AT91 Board Options
+#
+
+#
+# AT91 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4T=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+CONFIG_NO_IDLE_HZ=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=m
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=y
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_ARM_AT91_ETHER=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT91RM9200_WATCHDOG=m
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_NVRAM is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_AT91=m
+CONFIG_I2C_ISA=m
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+# CONFIG_SENSORS_ABITUGURU is not set
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1029=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+CONFIG_SENSORS_DS1621=m
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+CONFIG_SENSORS_SMSC47B397=m
+# CONFIG_SENSORS_VT1211 is not set
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83793=m
+CONFIG_SENSORS_W83L785TS=m
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=m
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_TOUCHSCREEN is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET_MII=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+CONFIG_USB_NET_ZAURUS=m
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_AT91=m
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_AT91RM9200=m
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="utf-8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index bb28087..593b565 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -7,8 +7,8 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
# Object file lists.
obj-y := compat.o entry-armv.o entry-common.o irq.o \
- process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
- time.o traps.o
+ process.o ptrace.o semaphore.o setup.o signal.o \
+ sys_arm.o stacktrace.o time.o traps.o
obj-$(CONFIG_ISA_DMA_API) += dma.o
obj-$(CONFIG_ARCH_ACORN) += ecard.o
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index f1c0fb9..bdbd7da 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -40,6 +40,7 @@
#include <linux/device.h>
#include <linux/init.h>
#include <linux/mutex.h>
+#include <linux/kthread.h>
#include <asm/dma.h>
#include <asm/ecard.h>
@@ -50,6 +51,8 @@
#include <asm/mach/irq.h>
#include <asm/tlbflush.h>
+#include "ecard.h"
+
#ifndef CONFIG_ARCH_RPC
#define HAVE_EXPMASK
#endif
@@ -123,7 +126,7 @@ static void ecard_task_reset(struct ecard_request *req)
res = ec->slot_no == 8
? &ec->resource[ECARD_RES_MEMC]
- : ec->type == ECARD_EASI
+ : ec->easi
? &ec->resource[ECARD_RES_EASI]
: &ec->resource[ECARD_RES_IOCSYNC];
@@ -178,7 +181,7 @@ static void ecard_task_readbytes(struct ecard_request *req)
index += 1;
}
} else {
- unsigned long base = (ec->type == ECARD_EASI
+ unsigned long base = (ec->easi
? &ec->resource[ECARD_RES_EASI]
: &ec->resource[ECARD_RES_IOCSYNC])->start;
void __iomem *pbase = (void __iomem *)base;
@@ -263,8 +266,6 @@ static int ecard_init_mm(void)
static int
ecard_task(void * unused)
{
- daemonize("kecardd");
-
/*
* Allocate a mm. We're not a lazy-TLB kernel task since we need
* to set page table entries where the user space would be. Note
@@ -727,7 +728,7 @@ static int ecard_prints(char *buffer, ecard_t *ec)
char *start = buffer;
buffer += sprintf(buffer, " %d: %s ", ec->slot_no,
- ec->type == ECARD_EASI ? "EASI" : " ");
+ ec->easi ? "EASI" : " ");
if (ec->cid.id == 0) {
struct in_chunk_dir incd;
@@ -814,7 +815,7 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot)
}
ec->slot_no = slot;
- ec->type = type;
+ ec->easi = type == ECARD_EASI;
ec->irq = NO_IRQ;
ec->fiq = NO_IRQ;
ec->dma = NO_DMA;
@@ -825,6 +826,7 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot)
ec->dev.bus = &ecard_bus_type;
ec->dev.dma_mask = &ec->dma_mask;
ec->dma_mask = (u64)0xffffffff;
+ ec->dev.coherent_dma_mask = ec->dma_mask;
if (slot < 4) {
ec_set_resource(ec, ECARD_RES_MEMC,
@@ -907,7 +909,7 @@ static ssize_t ecard_show_device(struct device *dev, struct device_attribute *at
static ssize_t ecard_show_type(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
- return sprintf(buf, "%s\n", ec->type == ECARD_EASI ? "EASI" : "IOC");
+ return sprintf(buf, "%s\n", ec->easi ? "EASI" : "IOC");
}
static struct device_attribute ecard_dev_attrs[] = {
@@ -1058,13 +1060,14 @@ ecard_probe(int slot, card_type_t type)
*/
static int __init ecard_init(void)
{
- int slot, irqhw, ret;
-
- ret = kernel_thread(ecard_task, NULL, CLONE_KERNEL);
- if (ret < 0) {
- printk(KERN_ERR "Ecard: unable to create kernel thread: %d\n",
- ret);
- return ret;
+ struct task_struct *task;
+ int slot, irqhw;
+
+ task = kthread_run(ecard_task, NULL, "kecardd");
+ if (IS_ERR(task)) {
+ printk(KERN_ERR "Ecard: unable to create kernel thread: %ld\n",
+ PTR_ERR(task));
+ return PTR_ERR(task);
}
printk("Probing expansion cards\n");
diff --git a/arch/arm/kernel/ecard.h b/arch/arm/kernel/ecard.h
new file mode 100644
index 0000000..d7c2dac
--- /dev/null
+++ b/arch/arm/kernel/ecard.h
@@ -0,0 +1,56 @@
+/*
+ * ecard.h
+ *
+ * Copyright 2007 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Definitions internal to ecard.c - for it's use only!!
+ *
+ * External expansion card header as read from the card
+ */
+struct ex_ecid {
+ unsigned char r_irq:1;
+ unsigned char r_zero:1;
+ unsigned char r_fiq:1;
+ unsigned char r_id:4;
+ unsigned char r_a:1;
+
+ unsigned char r_cd:1;
+ unsigned char r_is:1;
+ unsigned char r_w:2;
+ unsigned char r_r1:4;
+
+ unsigned char r_r2:8;
+
+ unsigned char r_prod[2];
+
+ unsigned char r_manu[2];
+
+ unsigned char r_country;
+
+ unsigned char r_fiqmask;
+ unsigned char r_fiqoff[3];
+
+ unsigned char r_irqmask;
+ unsigned char r_irqoff[3];
+};
+
+/*
+ * Chunk directory entry as read from the card
+ */
+struct ex_chunk_dir {
+ unsigned char r_id;
+ unsigned char r_len[3];
+ unsigned long r_start;
+ union {
+ char string[256];
+ char data[1];
+ } d;
+#define c_id(x) ((x)->r_id)
+#define c_len(x) ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16))
+#define c_start(x) ((x)->r_start)
+};
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 66db0a9..1d35eda 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -257,7 +257,9 @@ __create_page_tables:
* Map some ram to cover our .data and .bss areas.
*/
orr r3, r7, #(KERNEL_RAM_PADDR & 0xff000000)
+ .if (KERNEL_RAM_PADDR & 0x00f00000)
orr r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000)
+ .endif
add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18
str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
ldr r6, =(_end - 1)
@@ -274,7 +276,9 @@ __create_page_tables:
*/
add r0, r4, #PAGE_OFFSET >> 18
orr r6, r7, #(PHYS_OFFSET & 0xff000000)
- orr r6, r6, #(PHYS_OFFSET & 0x00e00000)
+ .if (PHYS_OFFSET & 0x00f00000)
+ orr r6, r6, #(PHYS_OFFSET & 0x00f00000)
+ .endif
str r6, [r0]
#ifdef CONFIG_DEBUG_LL
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index e101846..11dcd52 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -27,7 +27,6 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
-#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/smp.h>
@@ -109,7 +108,7 @@ static struct irq_desc bad_irq_desc = {
* come via this function. Instead, they should provide their
* own 'handler'
*/
-asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
+asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
struct irq_desc *desc = irq_desc + irq;
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 782af3c..5d6e652 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -16,7 +16,6 @@
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
-#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/a.out.h>
@@ -28,6 +27,7 @@
#include <linux/cpu.h>
#include <linux/elfcore.h>
#include <linux/pm.h>
+#include <linux/tick.h>
#include <asm/leds.h>
#include <asm/processor.h>
@@ -160,9 +160,11 @@ void cpu_idle(void)
if (!idle)
idle = default_idle;
leds_event(led_idle_start);
+ tick_nohz_stop_sched_tick();
while (!need_resched())
idle();
leds_event(led_idle_end);
+ tick_nohz_restart_sched_tick();
preempt_enable_no_resched();
schedule();
preempt_disable();
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 9254ba2..6f2f46c 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -13,7 +13,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/security.h>
@@ -457,13 +456,10 @@ void ptrace_cancel_bpt(struct task_struct *child)
/*
* Called by kernel/ptrace.c when detaching..
- *
- * Make sure the single step bit is not set.
*/
void ptrace_disable(struct task_struct *child)
{
- child->ptrace &= ~PT_SINGLESTEP;
- ptrace_cancel_bpt(child);
+ single_step_disable(child);
}
/*
@@ -712,9 +708,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
else
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data;
- /* make sure single-step breakpoint is gone. */
- child->ptrace &= ~PT_SINGLESTEP;
- ptrace_cancel_bpt(child);
+ single_step_disable(child);
wake_up_process(child);
ret = 0;
break;
@@ -725,9 +719,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
* exit.
*/
case PTRACE_KILL:
- /* make sure single-step breakpoint is gone. */
- child->ptrace &= ~PT_SINGLESTEP;
- ptrace_cancel_bpt(child);
+ single_step_disable(child);
if (child->exit_state != EXIT_ZOMBIE) {
child->exit_code = SIGKILL;
wake_up_process(child);
@@ -742,7 +734,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = -EIO;
if (!valid_signal(data))
break;
- child->ptrace |= PT_SINGLESTEP;
+ single_step_enable(child);
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data;
/* give it a chance to run. */
@@ -786,8 +778,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
case PTRACE_SET_SYSCALL:
+ task_thread_info(child)->syscall = data;
ret = 0;
- child->ptrace_message = data;
break;
#ifdef CONFIG_CRUNCH
@@ -824,7 +816,7 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
ip = regs->ARM_ip;
regs->ARM_ip = why;
- current->ptrace_message = scno;
+ current_thread_info()->syscall = scno;
/* the 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
@@ -841,5 +833,5 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
}
regs->ARM_ip = ip;
- return current->ptrace_message;
+ return current_thread_info()->syscall;
}
diff --git a/arch/arm/kernel/ptrace.h b/arch/arm/kernel/ptrace.h
index f7cad13..def3b61 100644
--- a/arch/arm/kernel/ptrace.h
+++ b/arch/arm/kernel/ptrace.h
@@ -7,6 +7,45 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/ptrace.h>
+
extern void ptrace_cancel_bpt(struct task_struct *);
extern void ptrace_set_bpt(struct task_struct *);
extern void ptrace_break(struct task_struct *, struct pt_regs *);
+
+/*
+ * make sure single-step breakpoint is gone.
+ */
+static inline void single_step_disable(struct task_struct *task)
+{
+ task->ptrace &= ~PT_SINGLESTEP;
+ ptrace_cancel_bpt(task);
+}
+
+static inline void single_step_enable(struct task_struct *task)
+{
+ task->ptrace |= PT_SINGLESTEP;
+}
+
+/*
+ * Send SIGTRAP if we're single-stepping
+ */
+static inline void single_step_trap(struct task_struct *task)
+{
+ if (task->ptrace & PT_SINGLESTEP) {
+ ptrace_cancel_bpt(task);
+ send_sig(SIGTRAP, task, 1);
+ }
+}
+
+static inline void single_step_clear(struct task_struct *task)
+{
+ if (task->ptrace & PT_SINGLESTEP)
+ ptrace_cancel_bpt(task);
+}
+
+static inline void single_step_set(struct task_struct *task)
+{
+ if (task->ptrace & PT_SINGLESTEP)
+ ptrace_set_bpt(task);
+}
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 3843d3b..54cdf1ae 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -9,7 +9,6 @@
*/
#include <linux/errno.h>
#include <linux/signal.h>
-#include <linux/ptrace.h>
#include <linux/personality.h>
#include <linux/freezer.h>
@@ -285,11 +284,7 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
if (restore_sigframe(regs, frame))
goto badframe;
- /* Send SIGTRAP if we're single-stepping */
- if (current->ptrace & PT_SINGLESTEP) {
- ptrace_cancel_bpt(current);
- send_sig(SIGTRAP, current, 1);
- }
+ single_step_trap(current);
return regs->ARM_r0;
@@ -324,11 +319,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT)
goto badframe;
- /* Send SIGTRAP if we're single-stepping */
- if (current->ptrace & PT_SINGLESTEP) {
- ptrace_cancel_bpt(current);
- send_sig(SIGTRAP, current, 1);
- }
+ single_step_trap(current);
return regs->ARM_r0;
@@ -644,14 +635,12 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
if (try_to_freeze())
goto no_signal;
- if (current->ptrace & PT_SINGLESTEP)
- ptrace_cancel_bpt(current);
+ single_step_clear(current);
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
handle_signal(signr, &ka, &info, oldset, regs, syscall);
- if (current->ptrace & PT_SINGLESTEP)
- ptrace_set_bpt(current);
+ single_step_set(current);
return 1;
}
@@ -705,8 +694,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
restart_syscall(regs);
}
}
- if (current->ptrace & PT_SINGLESTEP)
- ptrace_set_bpt(current);
+ single_step_set(current);
return 0;
}
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
new file mode 100644
index 0000000..77ef35e
--- /dev/null
+++ b/arch/arm/kernel/stacktrace.c
@@ -0,0 +1,73 @@
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+
+#include "stacktrace.h"
+
+int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high,
+ int (*fn)(struct stackframe *, void *), void *data)
+{
+ struct stackframe *frame;
+
+ do {
+ /*
+ * Check current frame pointer is within bounds
+ */
+ if ((fp - 12) < low || fp + 4 >= high)
+ break;
+
+ frame = (struct stackframe *)(fp - 12);
+
+ if (fn(frame, data))
+ break;
+
+ /*
+ * Update the low bound - the next frame must always
+ * be at a higher address than the current frame.
+ */
+ low = fp + 4;
+ fp = frame->fp;
+ } while (fp);
+
+ return 0;
+}
+
+#ifdef CONFIG_STACKTRACE
+struct stack_trace_data {
+ struct stack_trace *trace;
+ unsigned int skip;
+};
+
+static int save_trace(struct stackframe *frame, void *d)
+{
+ struct stack_trace_data *data = d;
+ struct stack_trace *trace = data->trace;
+
+ if (data->skip) {
+ data->skip--;
+ return 0;
+ }
+
+ trace->entries[trace->nr_entries++] = frame->lr;
+
+ return trace->nr_entries >= trace->max_entries;
+}
+
+void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+{
+ struct stack_trace_data data;
+ unsigned long fp, base;
+
+ data.trace = trace;
+ data.skip = trace->skip;
+
+ if (task) {
+ base = (unsigned long)task_stack_page(task);
+ fp = 0; /* FIXME */
+ } else {
+ base = (unsigned long)task_stack_page(current);
+ asm("mov %0, fp" : "=r" (fp));
+ }
+
+ walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data);
+}
+#endif
diff --git a/arch/arm/kernel/stacktrace.h b/arch/arm/kernel/stacktrace.h
new file mode 100644
index 0000000..e9fd20c
--- /dev/null
+++ b/arch/arm/kernel/stacktrace.h
@@ -0,0 +1,9 @@
+struct stackframe {
+ unsigned long fp;
+ unsigned long sp;
+ unsigned long lr;
+ unsigned long pc;
+};
+
+int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high,
+ int (*fn)(struct stackframe *, void *), void *data);
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index f61decb..d0540e4 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -327,6 +327,7 @@ void restore_time_delta(struct timespec *delta, struct timespec *rtc)
}
EXPORT_SYMBOL(restore_time_delta);
+#ifndef CONFIG_GENERIC_CLOCKEVENTS
/*
* Kernel system timer support.
*/
@@ -340,8 +341,9 @@ void timer_tick(void)
update_process_times(user_mode(get_irq_regs()));
#endif
}
+#endif
-#ifdef CONFIG_PM
+#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS)
static int timer_suspend(struct sys_device *dev, pm_message_t state)
{
struct sys_timer *timer = container_of(dev, struct sys_timer, dev);
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 2409560..10ff36e 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -16,7 +16,6 @@
#include <linux/signal.h>
#include <linux/spinlock.h>
#include <linux/personality.h>
-#include <linux/ptrace.h>
#include <linux/kallsyms.h>
#include <linux/delay.h>
#include <linux/init.h>
@@ -45,7 +44,18 @@ static int __init user_debug_setup(char *str)
__setup("user_debug=", user_debug_setup);
#endif
-void dump_backtrace_entry(unsigned long where, unsigned long from)
+static void dump_mem(const char *str, unsigned long bottom, unsigned long top);
+
+static inline int in_exception_text(unsigned long ptr)
+{
+ extern char __exception_text_start[];
+ extern char __exception_text_end[];
+
+ return ptr >= (unsigned long)&__exception_text_start &&
+ ptr < (unsigned long)&__exception_text_end;
+}
+
+void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
{
#ifdef CONFIG_KALLSYMS
printk("[<%08lx>] ", where);
@@ -55,6 +65,9 @@ void dump_backtrace_entry(unsigned long where, unsigned long from)
#else
printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
#endif
+
+ if (in_exception_text(where))
+ dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
}
/*
@@ -232,8 +245,8 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
do_exit(SIGSEGV);
}
-void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
- unsigned long err, unsigned long trap)
+void arm_notify_die(const char *str, struct pt_regs *regs,
+ struct siginfo *info, unsigned long err, unsigned long trap)
{
if (user_mode(regs)) {
current->thread.error_code = err;
@@ -266,13 +279,14 @@ void unregister_undef_hook(struct undef_hook *hook)
spin_unlock_irqrestore(&undef_lock, flags);
}
-asmlinkage void do_undefinstr(struct pt_regs *regs)
+asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
{
unsigned int correction = thumb_mode(regs) ? 2 : 4;
unsigned int instr;
struct undef_hook *hook;
siginfo_t info;
void __user *pc;
+ unsigned long flags;
/*
* According to the ARM ARM, PC is 2 or 4 bytes ahead,
@@ -291,7 +305,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs)
get_user(instr, (u32 __user *)pc);
}
- spin_lock_irq(&undef_lock);
+ spin_lock_irqsave(&undef_lock, flags);
list_for_each_entry(hook, &undef_hook, node) {
if ((instr & hook->instr_mask) == hook->instr_val &&
(regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) {
@@ -301,7 +315,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs)
}
}
}
- spin_unlock_irq(&undef_lock);
+ spin_unlock_irqrestore(&undef_lock, flags);
#ifdef CONFIG_DEBUG_USER
if (user_debug & UDBG_UNDEFINED) {
@@ -316,7 +330,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs)
info.si_code = ILL_ILLOPC;
info.si_addr = pc;
- notify_die("Oops - undefined instruction", regs, &info, 0, 6);
+ arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6);
}
asmlinkage void do_unexp_fiq (struct pt_regs *regs)
@@ -370,7 +384,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
info.si_addr = (void __user *)instruction_pointer(regs) -
(thumb_mode(regs) ? 2 : 4);
- notify_die("Oops - bad syscall", regs, &info, n, 0);
+ arm_notify_die("Oops - bad syscall", regs, &info, n, 0);
return regs->ARM_r0;
}
@@ -414,7 +428,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
info.si_code = SEGV_MAPERR;
info.si_addr = NULL;
- notify_die("branch through zero", regs, &info, 0, 0);
+ arm_notify_die("branch through zero", regs, &info, 0, 0);
return 0;
case NR(breakpoint): /* SWI BREAK_POINT */
@@ -550,7 +564,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
info.si_addr = (void __user *)instruction_pointer(regs) -
(thumb_mode(regs) ? 2 : 4);
- notify_die("Oops - bad syscall(2)", regs, &info, no, 0);
+ arm_notify_die("Oops - bad syscall(2)", regs, &info, no, 0);
return 0;
}
@@ -624,7 +638,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
info.si_code = ILL_ILLOPC;
info.si_addr = (void __user *)addr;
- notify_die("unknown data abort code", regs, &info, instr, 0);
+ arm_notify_die("unknown data abort code", regs, &info, instr, 0);
}
void __attribute__((noreturn)) __bug(const char *file, int line)
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index d1a6a59..6be6729 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -83,6 +83,9 @@ SECTIONS
.text : { /* Real text segment */
_text = .; /* Text and read-only data */
+ __exception_text_start = .;
+ *(.exception.text)
+ __exception_text_end = .;
*(.text)
SCHED_TEXT
LOCK_TEXT
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
index 7423008..84dc890 100644
--- a/arch/arm/lib/backtrace.S
+++ b/arch/arm/lib/backtrace.S
@@ -17,8 +17,8 @@
@ fp is 0 or stack frame
#define frame r4
-#define next r5
-#define save r6
+#define sv_fp r5
+#define sv_pc r6
#define mask r7
#define offset r8
@@ -31,108 +31,106 @@ ENTRY(c_backtrace)
#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
mov pc, lr
#else
-
stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location...
- tst r1, #0x10 @ 26 or 32-bit?
- moveq mask, #0xfc000003
- movne mask, #0
- tst mask, r0
- movne r0, #0
- movs frame, r0
-1: moveq r0, #-2
- ldmeqfd sp!, {r4 - r8, pc}
-
-2: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction
- ldr r0, [sp], #4
- adr r1, 2b - 4
+ movs frame, r0 @ if frame pointer is zero
+ beq no_frame @ we have no stack frames
+
+ tst r1, #0x10 @ 26 or 32-bit mode?
+ moveq mask, #0xfc000003 @ mask for 26-bit
+ movne mask, #0 @ mask for 32-bit
+
+1: stmfd sp!, {pc} @ calculate offset of PC stored
+ ldr r0, [sp], #4 @ by stmfd for this CPU
+ adr r1, 1b
sub offset, r0, r1
-3: tst frame, mask @ Check for address exceptions...
- bne 1b
+/*
+ * Stack frame layout:
+ * optionally saved caller registers (r4 - r10)
+ * saved fp
+ * saved sp
+ * saved lr
+ * frame => saved pc
+ * optionally saved arguments (r0 - r3)
+ * saved sp => <next word>
+ *
+ * Functions start with the following code sequence:
+ * mov ip, sp
+ * stmfd sp!, {r0 - r3} (optional)
+ * corrected pc => stmfd sp!, {..., fp, ip, lr, pc}
+ */
+for_each_frame: tst frame, mask @ Check for address exceptions
+ bne no_frame
+
+1001: ldr sv_pc, [frame, #0] @ get saved pc
+1002: ldr sv_fp, [frame, #-12] @ get saved fp
-1001: ldr next, [frame, #-12] @ get fp
-1002: ldr r2, [frame, #-4] @ get lr
-1003: ldr r3, [frame, #0] @ get pc
- sub save, r3, offset @ Correct PC for prefetching
- bic save, save, mask
-1004: ldr r1, [save, #0] @ get instruction at function
- mov r1, r1, lsr #10
- ldr r3, .Ldsi+4
- teq r1, r3
- subeq save, save, #4
- mov r0, save
- bic r1, r2, mask
+ sub sv_pc, sv_pc, offset @ Correct PC for prefetching
+ bic sv_pc, sv_pc, mask @ mask PC/LR for the mode
+
+1003: ldr r2, [sv_pc, #-4] @ if stmfd sp!, {args} exists,
+ ldr r3, .Ldsi+4 @ adjust saved 'pc' back one
+ teq r3, r2, lsr #10 @ instruction
+ subne r0, sv_pc, #4 @ allow for mov
+ subeq r0, sv_pc, #8 @ allow for mov + stmia
+
+ ldr r1, [frame, #-4] @ get saved lr
+ mov r2, frame
+ bic r1, r1, mask @ mask PC/LR for the mode
bl dump_backtrace_entry
- ldr r0, [frame, #-8] @ get sp
- sub r0, r0, #4
-1005: ldr r1, [save, #4] @ get instruction at function+4
- mov r3, r1, lsr #10
- ldr r2, .Ldsi+4
- teq r3, r2 @ Check for stmia sp!, {args}
- addeq save, save, #4 @ next instruction
- bleq .Ldumpstm
-
- sub r0, frame, #16
-1006: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction
- mov r3, r1, lsr #10
- ldr r2, .Ldsi
- teq r3, r2
- bleq .Ldumpstm
-
- /*
- * A zero next framepointer means we're done.
- */
- teq next, #0
- ldmeqfd sp!, {r4 - r8, pc}
-
- /*
- * The next framepointer must be above the
- * current framepointer.
- */
- cmp next, frame
- mov frame, next
- bhi 3b
- b 1007f
+ ldr r1, [sv_pc, #-4] @ if stmfd sp!, {args} exists,
+ ldr r3, .Ldsi+4
+ teq r3, r1, lsr #10
+ ldreq r0, [frame, #-8] @ get sp
+ subeq r0, r0, #4 @ point at the last arg
+ bleq .Ldumpstm @ dump saved registers
-/*
- * Fixup for LDMDB. Note that this must not be in the fixup section.
- */
-1007: ldr r0, =.Lbad
+1004: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, ip, lr, pc}
+ ldr r3, .Ldsi @ instruction exists,
+ teq r3, r1, lsr #10
+ subeq r0, frame, #16
+ bleq .Ldumpstm @ dump saved registers
+
+ teq sv_fp, #0 @ zero saved fp means
+ beq no_frame @ no further frames
+
+ cmp sv_fp, frame @ next frame must be
+ mov frame, sv_fp @ above the current frame
+ bhi for_each_frame
+
+1006: adr r0, .Lbad
mov r1, frame
bl printk
- ldmfd sp!, {r4 - r8, pc}
- .ltorg
+no_frame: ldmfd sp!, {r4 - r8, pc}
.section __ex_table,"a"
.align 3
- .long 1001b, 1007b
- .long 1002b, 1007b
- .long 1003b, 1007b
- .long 1004b, 1007b
- .long 1005b, 1007b
- .long 1006b, 1007b
+ .long 1001b, 1006b
+ .long 1002b, 1006b
+ .long 1003b, 1006b
+ .long 1004b, 1006b
.previous
#define instr r4
#define reg r5
#define stack r6
-.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, r8, lr}
+.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr}
mov stack, r0
mov instr, r1
- mov reg, #9
+ mov reg, #10
mov r7, #0
1: mov r3, #1
tst instr, r3, lsl reg
beq 2f
add r7, r7, #1
- teq r7, #4
- moveq r7, #0
- moveq r3, #'\n'
- movne r3, #' '
- ldr r2, [stack], #-4
- mov r1, reg
+ teq r7, #6
+ moveq r7, #1
+ moveq r1, #'\n'
+ movne r1, #' '
+ ldr r3, [stack], #-4
+ mov r2, reg
adr r0, .Lfp
bl printk
2: subs reg, reg, #1
@@ -140,14 +138,13 @@ ENTRY(c_backtrace)
teq r7, #0
adrne r0, .Lcr
blne printk
- mov r0, stack
- ldmfd sp!, {instr, reg, stack, r7, r8, pc}
+ ldmfd sp!, {instr, reg, stack, r7, pc}
-.Lfp: .asciz " r%d = %08X%c"
+.Lfp: .asciz "%cr%d:%08x"
.Lcr: .asciz "\n"
.Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n"
.align
-.Ldsi: .word 0x00e92dd8 >> 2
- .word 0x00e92d00 >> 2
+.Ldsi: .word 0xe92dd800 >> 10 @ stmfd sp!, {... fp, ip, lr, pc}
+ .word 0xe92d0000 >> 10 @ stmfd sp!, {}
#endif
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index c03ea8e..1dd8ea4f 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -26,8 +26,6 @@
* Note that ADDR_LIMIT is either 0 or 0xc0000000.
* Note also that it is intended that __get_user_bad is not global.
*/
-#include <asm/asm-offsets.h>
-#include <asm/thread_info.h>
#include <asm/errno.h>
.global __get_user_1
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
index 4593e9c..8620afe 100644
--- a/arch/arm/lib/putuser.S
+++ b/arch/arm/lib/putuser.S
@@ -26,8 +26,6 @@
* Note that ADDR_LIMIT is either 0 or 0xc0000000
* Note also that it is intended that __put_user_bad is not global.
*/
-#include <asm/asm-offsets.h>
-#include <asm/thread_info.h>
#include <asm/errno.h>
.global __put_user_1
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
index a950160..0446ef2 100644
--- a/arch/arm/mach-aaec2000/core.c
+++ b/arch/arm/mach-aaec2000/core.c
@@ -142,7 +142,7 @@ aaec2000_timer_interrupt(int irq, void *dev_id)
static struct irqaction aaec2000_timer_irq = {
.name = "AAEC-2000 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = aaec2000_timer_interrupt,
};
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index bf0d962..e238ad8 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -81,6 +81,13 @@ config MACH_KB9200
Select this if you are using KwikByte's KB920x board.
<http://kwikbyte.com/KB9202_description_new.htm>
+config MACH_PICOTUX2XX
+ bool "picotux 200"
+ depends on ARCH_AT91RM9200
+ help
+ Select this if you are using a picotux 200.
+ <http://www.picotux.com/>
+
config MACH_KAFA
bool "Sperry-Sun KAFA board"
depends on ARCH_AT91RM9200
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 05de6cd..a412ae1 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_MACH_CARMEVA) += board-carmeva.o
obj-$(CONFIG_MACH_KB9200) += board-kb9202.o
obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o
obj-$(CONFIG_MACH_KAFA) += board-kafa.o
+obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o
# AT91SAM9260 board-specific support
obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 2ddcdd6..2cad2bf 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -117,6 +117,21 @@ static struct clk pioD_clk = {
.pmc_mask = 1 << AT91RM9200_ID_PIOD,
.type = CLK_TYPE_PERIPHERAL,
};
+static struct clk ssc0_clk = {
+ .name = "ssc0_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_SSC0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+ .name = "ssc1_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_SSC1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc2_clk = {
+ .name = "ssc2_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_SSC2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
static struct clk tc0_clk = {
.name = "tc0_clk",
.pmc_mask = 1 << AT91RM9200_ID_TC0,
@@ -161,7 +176,9 @@ static struct clk *periph_clocks[] __initdata = {
&udc_clk,
&twi_clk,
&spi_clk,
- // ssc 0 .. ssc2
+ &ssc0_clk,
+ &ssc1_clk,
+ &ssc2_clk,
&tc0_clk,
&tc1_clk,
&tc2_clk,
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
index 949199a..a634035 100644
--- a/arch/arm/mach-at91/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -87,7 +87,7 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
static struct irqaction at91rm9200_timer_irq = {
.name = "at91_tick",
- .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = at91rm9200_timer_interrupt
};
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index 6ea41d8..e47381e 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -119,6 +119,11 @@ static struct clk spi1_clk = {
.pmc_mask = 1 << AT91SAM9260_ID_SPI1,
.type = CLK_TYPE_PERIPHERAL,
};
+static struct clk ssc_clk = {
+ .name = "ssc_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_SSC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
static struct clk tc0_clk = {
.name = "tc0_clk",
.pmc_mask = 1 << AT91SAM9260_ID_TC0,
@@ -193,7 +198,7 @@ static struct clk *periph_clocks[] __initdata = {
&twi_clk,
&spi0_clk,
&spi1_clk,
- // ssc
+ &ssc_clk,
&tc0_clk,
&tc1_clk,
&tc2_clk,
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 784d1e6..dfe8c39 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -97,6 +97,21 @@ static struct clk spi1_clk = {
.pmc_mask = 1 << AT91SAM9261_ID_SPI1,
.type = CLK_TYPE_PERIPHERAL,
};
+static struct clk ssc0_clk = {
+ .name = "ssc0_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_SSC0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+ .name = "ssc1_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_SSC1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc2_clk = {
+ .name = "ssc2_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_SSC2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
static struct clk tc0_clk = {
.name = "tc0_clk",
.pmc_mask = 1 << AT91SAM9261_ID_TC0,
@@ -135,7 +150,9 @@ static struct clk *periph_clocks[] __initdata = {
&twi_clk,
&spi0_clk,
&spi1_clk,
- // ssc 0 .. ssc2
+ &ssc0_clk,
+ &ssc1_clk,
+ &ssc2_clk,
&tc0_clk,
&tc1_clk,
&tc2_clk,
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index e150476..8e78199 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -430,9 +430,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
* LCD Controller
* -------------------------------------------------------------------- */
-#if defined(CONFIG_FB_AT91) || defined(CONFIG_FB_AT91_MODULE)
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
static u64 lcdc_dmamask = 0xffffffffUL;
-static struct at91fb_info lcdc_data;
+static struct atmel_lcdfb_info lcdc_data;
static struct resource lcdc_resources[] = {
[0] = {
@@ -455,7 +455,7 @@ static struct resource lcdc_resources[] = {
};
static struct platform_device at91_lcdc_device = {
- .name = "at91-fb",
+ .name = "atmel_lcdfb",
.id = 0,
.dev = {
.dma_mask = &lcdc_dmamask,
@@ -466,7 +466,7 @@ static struct platform_device at91_lcdc_device = {
.num_resources = ARRAY_SIZE(lcdc_resources),
};
-void __init at91_add_device_lcdc(struct at91fb_info *data)
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
{
if (!data) {
return;
@@ -499,7 +499,7 @@ void __init at91_add_device_lcdc(struct at91fb_info *data)
platform_device_register(&at91_lcdc_device);
}
#else
-void __init at91_add_device_lcdc(struct at91fb_info *data) {}
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
#endif
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 0e89a7f..00e27b1 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -87,6 +87,11 @@ static struct clk mmc1_clk = {
.pmc_mask = 1 << AT91SAM9263_ID_MCI1,
.type = CLK_TYPE_PERIPHERAL,
};
+static struct clk can_clk = {
+ .name = "can_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_CAN,
+ .type = CLK_TYPE_PERIPHERAL,
+};
static struct clk twi_clk = {
.name = "twi_clk",
.pmc_mask = 1 << AT91SAM9263_ID_TWI,
@@ -102,16 +107,46 @@ static struct clk spi1_clk = {
.pmc_mask = 1 << AT91SAM9263_ID_SPI1,
.type = CLK_TYPE_PERIPHERAL,
};
+static struct clk ssc0_clk = {
+ .name = "ssc0_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_SSC0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+ .name = "ssc1_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_SSC1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ac97_clk = {
+ .name = "ac97_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_AC97C,
+ .type = CLK_TYPE_PERIPHERAL,
+};
static struct clk tcb_clk = {
.name = "tcb_clk",
.pmc_mask = 1 << AT91SAM9263_ID_TCB,
.type = CLK_TYPE_PERIPHERAL,
};
+static struct clk pwmc_clk = {
+ .name = "pwmc_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_PWMC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
static struct clk macb_clk = {
.name = "macb_clk",
.pmc_mask = 1 << AT91SAM9263_ID_EMAC,
.type = CLK_TYPE_PERIPHERAL,
};
+static struct clk dma_clk = {
+ .name = "dma_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_DMA,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twodge_clk = {
+ .name = "2dge_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_2DGE,
+ .type = CLK_TYPE_PERIPHERAL,
+};
static struct clk udc_clk = {
.name = "udc_clk",
.pmc_mask = 1 << AT91SAM9263_ID_UDP,
@@ -142,20 +177,21 @@ static struct clk *periph_clocks[] __initdata = {
&usart2_clk,
&mmc0_clk,
&mmc1_clk,
- // can
+ &can_clk,
&twi_clk,
&spi0_clk,
&spi1_clk,
- // ssc0 .. ssc1
- // ac97
+ &ssc0_clk,
+ &ssc1_clk,
+ &ac97_clk,
&tcb_clk,
- // pwmc
+ &pwmc_clk,
&macb_clk,
- // 2dge
+ &twodge_clk,
&udc_clk,
&isi_clk,
&lcdc_clk,
- // dma
+ &dma_clk,
&ohci_clk,
// irq0 .. irq1
};
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index b77121f..2b2e18a 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -573,6 +573,130 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
/* --------------------------------------------------------------------
+ * AC97
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE)
+static u64 ac97_dmamask = 0xffffffffUL;
+static struct atmel_ac97_data ac97_data;
+
+static struct resource ac97_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_AC97C,
+ .end = AT91SAM9263_BASE_AC97C + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_AC97C,
+ .end = AT91SAM9263_ID_AC97C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_ac97_device = {
+ .name = "ac97c",
+ .id = 1,
+ .dev = {
+ .dma_mask = &ac97_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &ac97_data,
+ },
+ .resource = ac97_resources,
+ .num_resources = ARRAY_SIZE(ac97_resources),
+};
+
+void __init at91_add_device_ac97(struct atmel_ac97_data *data)
+{
+ if (!data)
+ return;
+
+ at91_set_A_periph(AT91_PIN_PB0, 0); /* AC97FS */
+ at91_set_A_periph(AT91_PIN_PB1, 0); /* AC97CK */
+ at91_set_A_periph(AT91_PIN_PB2, 0); /* AC97TX */
+ at91_set_A_periph(AT91_PIN_PB3, 0); /* AC97RX */
+
+ /* reset */
+ if (data->reset_pin)
+ at91_set_gpio_output(data->reset_pin, 0);
+
+ ac97_data = *ek_data;
+ platform_device_register(&at91sam9263_ac97_device);
+}
+#else
+void __init at91_add_device_ac97(struct atmel_ac97_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * LCD Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static u64 lcdc_dmamask = 0xffffffffUL;
+static struct atmel_lcdfb_info lcdc_data;
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_LCDC_BASE,
+ .end = AT91SAM9263_LCDC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_LCDC,
+ .end = AT91SAM9263_ID_LCDC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91_lcdc_device = {
+ .name = "atmel_lcdfb",
+ .id = 0,
+ .dev = {
+ .dma_mask = &lcdc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &lcdc_data,
+ },
+ .resource = lcdc_resources,
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+};
+
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
+{
+ if (!data)
+ return;
+
+ at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */
+ at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */
+ at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */
+ at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */
+ at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */
+ at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */
+ at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */
+ at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */
+ at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */
+ at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */
+ at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */
+ at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */
+ at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */
+ at91_set_B_periph(AT91_PIN_PC12, 0); /* LCDD13 */
+ at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */
+ at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */
+ at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */
+ at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */
+ at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */
+ at91_set_B_periph(AT91_PIN_PC17, 0); /* LCDD21 */
+ at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */
+ at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */
+
+ lcdc_data = *data;
+ platform_device_register(&at91_lcdc_device);
+}
+#else
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
* LEDs
* -------------------------------------------------------------------- */
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
index a4dded2..5c090c9 100644
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -66,7 +66,7 @@ static irqreturn_t at91sam926x_timer_interrupt(int irq, void *dev_id)
static struct irqaction at91sam926x_timer_irq = {
.name = "at91_tick",
- .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = at91sam926x_timer_interrupt
};
diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c
new file mode 100644
index 0000000..49cfe7a
--- /dev/null
+++ b/arch/arm/mach-at91/board-picotux200.c
@@ -0,0 +1,166 @@
+/*
+ * linux/arch/arm/mach-at91/board-picotux200.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2007 Kleinhenz Elektronik GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/at91rm9200_mc.h>
+
+#include "generic.h"
+
+
+/*
+ * Serial port configuration.
+ * 0 .. 3 = USART0 .. USART3
+ * 4 = DBGU
+ */
+static struct at91_uart_config __initdata picotux200_uart_config = {
+ .console_tty = 0, /* ttyS0 */
+ .nr_tty = 2,
+ .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
+};
+
+static void __init picotux200_map_io(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91rm9200_initialize(18432000, AT91RM9200_BGA);
+
+ /* Setup the serial ports and console */
+ at91_init_serial(&picotux200_uart_config);
+}
+
+static void __init picotux200_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata picotux200_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC4,
+ .is_rmii = 1,
+};
+
+static struct at91_usbh_data __initdata picotux200_usbh_data = {
+ .ports = 1,
+};
+
+// static struct at91_udc_data __initdata picotux200_udc_data = {
+// .vbus_pin = AT91_PIN_PD4,
+// .pullup_pin = AT91_PIN_PD5,
+// };
+
+static struct at91_mmc_data __initdata picotux200_mmc_data = {
+ .det_pin = AT91_PIN_PB27,
+ .slot_b = 0,
+ .wire4 = 1,
+ .wp_pin = AT91_PIN_PA17,
+};
+
+// static struct spi_board_info picotux200_spi_devices[] = {
+// { /* DataFlash chip */
+// .modalias = "mtd_dataflash",
+// .chip_select = 0,
+// .max_speed_hz = 15 * 1000 * 1000,
+// },
+// #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+// { /* DataFlash card */
+// .modalias = "mtd_dataflash",
+// .chip_select = 3,
+// .max_speed_hz = 15 * 1000 * 1000,
+// },
+// #endif
+// };
+
+#define PICOTUX200_FLASH_BASE AT91_CHIPSELECT_0
+#define PICOTUX200_FLASH_SIZE 0x400000
+
+static struct physmap_flash_data picotux200_flash_data = {
+ .width = 2,
+};
+
+static struct resource picotux200_flash_resource = {
+ .start = PICOTUX200_FLASH_BASE,
+ .end = PICOTUX200_FLASH_BASE + PICOTUX200_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device picotux200_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &picotux200_flash_data,
+ },
+ .resource = &picotux200_flash_resource,
+ .num_resources = 1,
+};
+
+static void __init picotux200_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* Ethernet */
+ at91_add_device_eth(&picotux200_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&picotux200_usbh_data);
+ /* USB Device */
+ // at91_add_device_udc(&picotux200_udc_data);
+ // at91_set_multi_drive(picotux200_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */
+ /* I2C */
+ at91_add_device_i2c();
+ /* SPI */
+ // at91_add_device_spi(picotux200_spi_devices, ARRAY_SIZE(picotux200_spi_devices));
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+ /* DataFlash card */
+ at91_set_gpio_output(AT91_PIN_PB22, 0);
+#else
+ /* MMC */
+ at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
+ at91_add_device_mmc(0, &picotux200_mmc_data);
+#endif
+ /* NOR Flash */
+ platform_device_register(&picotux200_flash);
+}
+
+MACHINE_START(PICOTUX2XX, "picotux 200")
+ /* Maintainer: Kleinhenz Elektronik GmbH */
+ .phys_io = AT91_BASE_SYS,
+ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+ .boot_params = AT91_SDRAM_BASE + 0x100,
+ .timer = &at91rm9200_timer,
+ .map_io = picotux200_map_io,
+ .init_irq = picotux200_init_irq,
+ .init_machine = picotux200_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c
index 57fb449..65fa532 100644
--- a/arch/arm/mach-at91/board-sam9260ek.c
+++ b/arch/arm/mach-at91/board-sam9260ek.c
@@ -104,9 +104,9 @@ static struct spi_board_info ek_spi_devices[] = {
},
#endif
#endif
-#if defined(CONFIG_SND_AT73C213)
+#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
{ /* AT73C213 DAC */
- .modalias = "snd_at73c213",
+ .modalias = "at73c213",
.chip_select = 0,
.max_speed_hz = 10 * 1000 * 1000,
.bus_num = 1,
@@ -118,7 +118,7 @@ static struct spi_board_info ek_spi_devices[] = {
/*
* MACB Ethernet device
*/
-static struct __initdata at91_eth_data ek_macb_data = {
+static struct at91_eth_data __initdata ek_macb_data = {
.phy_irq_pin = AT91_PIN_PA7,
.is_rmii = 1,
};
@@ -140,7 +140,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
},
};
-static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(ek_nand_partition);
return ek_nand_partition;
@@ -188,6 +188,8 @@ static void __init ek_board_init(void)
at91_add_device_eth(&ek_macb_data);
/* MMC */
at91_add_device_mmc(0, &ek_mmc_data);
+ /* I2C */
+ at91_add_device_i2c();
}
MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index b7e7724..bcf7153 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
#include <linux/dm9000.h>
#include <asm/hardware.h>
@@ -195,6 +196,41 @@ static struct at91_nand_data __initdata ek_nand_data = {
};
/*
+ * ADS7846 Touchscreen
+ */
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+
+static int ads7843_pendown_state(void)
+{
+ return !at91_get_gpio_value(AT91_PIN_PC2); /* Touchscreen PENIRQ */
+}
+
+static struct ads7846_platform_data ads_info = {
+ .model = 7843,
+ .x_min = 150,
+ .x_max = 3830,
+ .y_min = 190,
+ .y_max = 3830,
+ .vref_delay_usecs = 100,
+ .x_plate_ohms = 450,
+ .y_plate_ohms = 250,
+ .pressure_max = 15000,
+ .debounce_max = 1,
+ .debounce_rep = 0,
+ .debounce_tol = (~0),
+ .get_pendown_state = ads7843_pendown_state,
+};
+
+static void __init ek_add_device_ts(void)
+{
+ at91_set_B_periph(AT91_PIN_PC2, 1); /* External IRQ0, with pullup */
+ at91_set_gpio_input(AT91_PIN_PA11, 1); /* Touchscreen BUSY signal */
+}
+#else
+static void __init ek_add_device_ts(void) {}
+#endif
+
+/*
* SPI devices
*/
static struct spi_board_info ek_spi_devices[] = {
@@ -204,6 +240,16 @@ static struct spi_board_info ek_spi_devices[] = {
.max_speed_hz = 15 * 1000 * 1000,
.bus_num = 0,
},
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+ {
+ .modalias = "ads7846",
+ .chip_select = 2,
+ .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */
+ .bus_num = 0,
+ .platform_data = &ads_info,
+ .irq = AT91SAM9261_ID_IRQ0,
+ },
+#endif
#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
{ /* DataFlash card - jumper (J12) configurable to CS3 or CS0 */
.modalias = "mtd_dataflash",
@@ -211,9 +257,9 @@ static struct spi_board_info ek_spi_devices[] = {
.max_speed_hz = 15 * 1000 * 1000,
.bus_num = 0,
},
-#elif defined(CONFIG_SND_AT73C213)
+#elif defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
{ /* AT73C213 DAC */
- .modalias = "snd_at73c213",
+ .modalias = "at73c213",
.chip_select = 3,
.max_speed_hz = 10 * 1000 * 1000,
.bus_num = 0,
@@ -241,6 +287,8 @@ static void __init ek_board_init(void)
#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
/* SPI */
at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+ /* Touchscreen */
+ ek_add_device_ts();
#else
/* MMC */
at91_add_device_mmc(0, &ek_mmc_data);
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index 8fdce11..f574585 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
#include <asm/hardware.h>
#include <asm/setup.h>
@@ -86,6 +87,40 @@ static struct at91_udc_data __initdata ek_udc_data = {
/*
+ * ADS7846 Touchscreen
+ */
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+static int ads7843_pendown_state(void)
+{
+ return !at91_get_gpio_value(AT91_PIN_PA15); /* Touchscreen PENIRQ */
+}
+
+static struct ads7846_platform_data ads_info = {
+ .model = 7843,
+ .x_min = 150,
+ .x_max = 3830,
+ .y_min = 190,
+ .y_max = 3830,
+ .vref_delay_usecs = 100,
+ .x_plate_ohms = 450,
+ .y_plate_ohms = 250,
+ .pressure_max = 15000,
+ .debounce_max = 1,
+ .debounce_rep = 0,
+ .debounce_tol = (~0),
+ .get_pendown_state = ads7843_pendown_state,
+};
+
+static void __init ek_add_device_ts(void)
+{
+ at91_set_B_periph(AT91_PIN_PA15, 1); /* External IRQ1, with pullup */
+ at91_set_gpio_input(AT91_PIN_PA31, 1); /* Touchscreen BUSY signal */
+}
+#else
+static void __init ek_add_device_ts(void) {}
+#endif
+
+/*
* SPI devices.
*/
static struct spi_board_info ek_spi_devices[] = {
@@ -97,6 +132,16 @@ static struct spi_board_info ek_spi_devices[] = {
.bus_num = 0,
},
#endif
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+ {
+ .modalias = "ads7846",
+ .chip_select = 3,
+ .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */
+ .bus_num = 0,
+ .platform_data = &ads_info,
+ .irq = AT91SAM9263_ID_IRQ1,
+ },
+#endif
};
@@ -112,6 +157,14 @@ static struct at91_mmc_data __initdata ek_mmc_data = {
/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+ .is_rmii = 1,
+};
+
+
+/*
* NAND flash
*/
static struct mtd_partition __initdata ek_nand_partition[] = {
@@ -148,6 +201,14 @@ static struct at91_nand_data __initdata ek_nand_data = {
};
+/*
+ * AC97
+ */
+static struct atmel_ac97_data ek_ac97_data = {
+ .reset_pin = AT91_PIN_PA13,
+};
+
+
static void __init ek_board_init(void)
{
/* Serial */
@@ -157,11 +218,20 @@ static void __init ek_board_init(void)
/* USB Device */
at91_add_device_udc(&ek_udc_data);
/* SPI */
+ at91_set_gpio_output(AT91_PIN_PE20, 1); /* select spi0 clock */
at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+ /* Touchscreen */
+ ek_add_device_ts();
/* MMC */
at91_add_device_mmc(1, &ek_mmc_data);
+ /* Ethernet */
+ at91_add_device_eth(&ek_macb_data);
/* NAND */
at91_add_device_nand(&ek_nand_data);
+ /* I2C */
+ at91_add_device_i2c();
+ /* AC97 */
+ at91_add_device_ac97(&ek_ac97_data);
}
MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c
index 428493d..f428af7 100644
--- a/arch/arm/mach-clps711x/time.c
+++ b/arch/arm/mach-clps711x/time.c
@@ -58,7 +58,7 @@ p720t_timer_interrupt(int irq, void *dev_id)
static struct irqaction clps711x_timer_irq = {
.name = "CLPS711x Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = p720t_timer_interrupt,
};
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index 231b900..4dde34f 100644
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -316,7 +316,7 @@ clps7500_timer_interrupt(int irq, void *dev_id)
static struct irqaction clps7500_timer_irq = {
.name = "CLPS7500 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = clps7500_timer_interrupt,
};
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 8459431..8c1b569 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -199,7 +199,7 @@ ebsa110_timer_interrupt(int irq, void *dev_id)
static struct irqaction ebsa110_timer_irq = {
.name = "EBSA110 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = ebsa110_timer_interrupt,
};
diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c
index db38afb..bbf0d33 100644
--- a/arch/arm/mach-ebsa110/io.c
+++ b/arch/arm/mach-ebsa110/io.c
@@ -102,6 +102,26 @@ EXPORT_SYMBOL(__readb);
EXPORT_SYMBOL(__readw);
EXPORT_SYMBOL(__readl);
+void readsw(void __iomem *addr, void *data, int len)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+
+ BUG_ON((unsigned long)addr & 1);
+
+ __raw_readsw(a, data, len);
+}
+EXPORT_SYMBOL(readsw);
+
+void readsl(void __iomem *addr, void *data, int len)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+
+ BUG_ON((unsigned long)addr & 3);
+
+ __raw_readsl(a, data, len);
+}
+EXPORT_SYMBOL(readsl);
+
void __writeb(u8 val, void __iomem *addr)
{
void __iomem *a = __isamem_convert_addr(addr);
@@ -137,6 +157,26 @@ EXPORT_SYMBOL(__writeb);
EXPORT_SYMBOL(__writew);
EXPORT_SYMBOL(__writel);
+void writesw(void __iomem *addr, void *data, int len)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+
+ BUG_ON((unsigned long)addr & 1);
+
+ __raw_writesw(a, data, len);
+}
+EXPORT_SYMBOL(writesw);
+
+void writesl(void __iomem *addr, void *data, int len)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+
+ BUG_ON((unsigned long)addr & 3);
+
+ __raw_writesl(a, data, len);
+}
+EXPORT_SYMBOL(writesl);
+
#define SUPERIO_PORT(p) \
(((p) >> 3) == (0x3f8 >> 3) || \
((p) >> 3) == (0x2f8 >> 3) || \
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index f174d1a..9d7515c 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -27,6 +27,10 @@ struct clk {
u32 enable_mask;
};
+static struct clk clk_uart = {
+ .name = "UARTCLK",
+ .rate = 14745600,
+};
static struct clk clk_pll1 = {
.name = "pll1",
};
@@ -50,6 +54,7 @@ static struct clk clk_usb_host = {
static struct clk *clocks[] = {
+ &clk_uart,
&clk_pll1,
&clk_f,
&clk_h,
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 829aed6..851cc71 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -116,7 +116,7 @@ static int ep93xx_timer_interrupt(int irq, void *dev_id)
static struct irqaction ep93xx_timer_irq = {
.name = "ep93xx timer",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = ep93xx_timer_interrupt,
};
diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c
index fa6be87..3a63941 100644
--- a/arch/arm/mach-footbridge/dc21285-timer.c
+++ b/arch/arm/mach-footbridge/dc21285-timer.c
@@ -44,7 +44,7 @@ timer1_interrupt(int irq, void *dev_id)
static struct irqaction footbridge_timer_irq = {
.name = "Timer1 timer tick",
.handler = timer1_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
};
/*
diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c
index 1463330..d0dc51e 100644
--- a/arch/arm/mach-footbridge/dc21285.c
+++ b/arch/arm/mach-footbridge/dc21285.c
@@ -10,7 +10,6 @@
*/
#include <linux/kernel.h>
#include <linux/pci.h>
-#include <linux/ptrace.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/slab.h>
diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c
index d884a39..d08d641 100644
--- a/arch/arm/mach-footbridge/isa-timer.c
+++ b/arch/arm/mach-footbridge/isa-timer.c
@@ -73,7 +73,7 @@ isa_timer_interrupt(int irq, void *dev_id)
static struct irqaction isa_timer_irq = {
.name = "ISA timer tick",
.handler = isa_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
};
static void __init isa_timer_init(void)
diff --git a/arch/arm/mach-h720x/cpu-h7201.c b/arch/arm/mach-h720x/cpu-h7201.c
index 13f76bd..9107b8e 100644
--- a/arch/arm/mach-h720x/cpu-h7201.c
+++ b/arch/arm/mach-h720x/cpu-h7201.c
@@ -41,7 +41,7 @@ h7201_timer_interrupt(int irq, void *dev_id)
static struct irqaction h7201_timer_irq = {
.name = "h7201 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = h7201_timer_interrupt,
};
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
index 703870f..82e420d 100644
--- a/arch/arm/mach-h720x/cpu-h7202.c
+++ b/arch/arm/mach-h720x/cpu-h7202.c
@@ -170,7 +170,7 @@ static struct irq_chip h7202_timerx_chip = {
static struct irqaction h7202_timer_irq = {
.name = "h7202 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = h7202_timer_interrupt,
};
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 2703a73..6960a9d 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -56,7 +56,7 @@ imx_timer_interrupt(int irq, void *dev_id)
static struct irqaction imx_timer_irq = {
.name = "i.MX Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = imx_timer_interrupt,
};
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 8d880cb..897c21c 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -282,7 +282,7 @@ integrator_timer_interrupt(int irq, void *dev_id)
static struct irqaction integrator_timer_irq = {
.name = "Integrator Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = integrator_timer_interrupt,
};
diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c
index 394ec92..af7d3ff 100644
--- a/arch/arm/mach-integrator/pci.c
+++ b/arch/arm/mach-integrator/pci.c
@@ -23,7 +23,6 @@
*/
#include <linux/kernel.h>
#include <linux/pci.h>
-#include <linux/ptrace.h>
#include <linux/interrupt.h>
#include <linux/init.h>
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index fb8c6d9..af9ebcc 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -22,7 +22,6 @@
*/
#include <linux/kernel.h>
#include <linux/pci.h>
-#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
diff --git a/arch/arm/mach-iop13xx/Makefile b/arch/arm/mach-iop13xx/Makefile
index 4185e05..da1609d 100644
--- a/arch/arm/mach-iop13xx/Makefile
+++ b/arch/arm/mach-iop13xx/Makefile
@@ -7,5 +7,6 @@ obj-$(CONFIG_ARCH_IOP13XX) += setup.o
obj-$(CONFIG_ARCH_IOP13XX) += irq.o
obj-$(CONFIG_ARCH_IOP13XX) += pci.o
obj-$(CONFIG_ARCH_IOP13XX) += io.o
+obj-$(CONFIG_ARCH_IOP13XX) += tpmi.o
obj-$(CONFIG_MACH_IQ81340SC) += iq81340sc.o
obj-$(CONFIG_MACH_IQ81340MC) += iq81340mc.o
diff --git a/arch/arm/mach-iop13xx/io.c b/arch/arm/mach-iop13xx/io.c
index e79a1b6..5b22fde 100644
--- a/arch/arm/mach-iop13xx/io.c
+++ b/arch/arm/mach-iop13xx/io.c
@@ -41,7 +41,7 @@ void * __iomem __iop13xx_io(unsigned long io_addr)
EXPORT_SYMBOL(__iop13xx_io);
void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
- unsigned long flags)
+ unsigned int mtype)
{
void __iomem * retval;
@@ -61,9 +61,9 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
(cookie - IOP13XX_PCIE_LOWER_MEM_RA));
break;
case IOP13XX_PBI_LOWER_MEM_RA ... IOP13XX_PBI_UPPER_MEM_RA:
- retval = __ioremap(IOP13XX_PBI_LOWER_MEM_PA +
- (cookie - IOP13XX_PBI_LOWER_MEM_RA),
- size, flags);
+ retval = __arm_ioremap(IOP13XX_PBI_LOWER_MEM_PA +
+ (cookie - IOP13XX_PBI_LOWER_MEM_RA),
+ size, mtype);
break;
case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA:
retval = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(cookie);
@@ -75,7 +75,7 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie);
break;
default:
- retval = __ioremap(cookie, size, flags);
+ retval = __arm_ioremap(cookie, size, mtype);
}
return retval;
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c
index a519d707..268a8d8 100644
--- a/arch/arm/mach-iop13xx/iq81340mc.c
+++ b/arch/arm/mach-iop13xx/iq81340mc.c
@@ -75,11 +75,14 @@ static void __init iq81340mc_init(void)
{
iop13xx_platform_init();
iq81340mc_pci_init();
+ iop13xx_add_tpmi_devices();
}
static void __init iq81340mc_timer_init(void)
{
- iop_init_time(400000000);
+ unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio();
+ printk(KERN_DEBUG "%s: bus frequency: %lu\n", __FUNCTION__, bus_freq);
+ iop_init_time(bus_freq);
}
static struct sys_timer iq81340mc_timer = {
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c
index 0e71fbc..a51ffd2 100644
--- a/arch/arm/mach-iop13xx/iq81340sc.c
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -77,11 +77,14 @@ static void __init iq81340sc_init(void)
{
iop13xx_platform_init();
iq81340sc_pci_init();
+ iop13xx_add_tpmi_devices();
}
static void __init iq81340sc_timer_init(void)
{
- iop_init_time(400000000);
+ unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio();
+ printk(KERN_DEBUG "%s: bus frequency: %lu\n", __FUNCTION__, bus_freq);
+ iop_init_time(bus_freq);
}
static struct sys_timer iq81340sc_timer = {
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
index 89ec70e..d1d0d32 100644
--- a/arch/arm/mach-iop13xx/pci.c
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -88,9 +88,9 @@ void iop13xx_map_pci_memory(void)
if (end) {
iop13xx_atux_mem_base =
- (u32) __ioremap_pfn(
+ (u32) __arm_ioremap_pfn(
__phys_to_pfn(IOP13XX_PCIX_LOWER_MEM_PA)
- , 0, iop13xx_atux_mem_size, 0);
+ , 0, iop13xx_atux_mem_size, MT_DEVICE);
if (!iop13xx_atux_mem_base) {
printk("%s: atux allocation "
"failed\n", __FUNCTION__);
@@ -114,9 +114,9 @@ void iop13xx_map_pci_memory(void)
if (end) {
iop13xx_atue_mem_base =
- (u32) __ioremap_pfn(
+ (u32) __arm_ioremap_pfn(
__phys_to_pfn(IOP13XX_PCIE_LOWER_MEM_PA)
- , 0, iop13xx_atue_mem_size, 0);
+ , 0, iop13xx_atue_mem_size, MT_DEVICE);
if (!iop13xx_atue_mem_base) {
printk("%s: atue allocation "
"failed\n", __FUNCTION__);
@@ -1023,7 +1023,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
<< IOP13XX_ATUX_PCIXSR_FUNC_NUM;
__raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR);
- res[0].start = IOP13XX_PCIX_LOWER_IO_PA;
+ res[0].start = IOP13XX_PCIX_LOWER_IO_PA + IOP13XX_PCIX_IO_BUS_OFFSET;
res[0].end = IOP13XX_PCIX_UPPER_IO_PA;
res[0].name = "IQ81340 ATUX PCI I/O Space";
res[0].flags = IORESOURCE_IO;
@@ -1033,7 +1033,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
res[1].name = "IQ81340 ATUX PCI Memory Space";
res[1].flags = IORESOURCE_MEM;
sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET;
- sys->io_offset = IOP13XX_PCIX_IO_OFFSET;
+ sys->io_offset = IOP13XX_PCIX_LOWER_IO_PA;
break;
case IOP13XX_INIT_ATU_ATUE:
/* Note: the function number field in the PCSR is ro */
@@ -1044,7 +1044,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
__raw_writel(pcsr, IOP13XX_ATUE_PCSR);
- res[0].start = IOP13XX_PCIE_LOWER_IO_PA;
+ res[0].start = IOP13XX_PCIE_LOWER_IO_PA + IOP13XX_PCIE_IO_BUS_OFFSET;
res[0].end = IOP13XX_PCIE_UPPER_IO_PA;
res[0].name = "IQ81340 ATUE PCI I/O Space";
res[0].flags = IORESOURCE_IO;
@@ -1054,7 +1054,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
res[1].name = "IQ81340 ATUE PCI Memory Space";
res[1].flags = IORESOURCE_MEM;
sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET;
- sys->io_offset = IOP13XX_PCIE_IO_OFFSET;
+ sys->io_offset = IOP13XX_PCIE_LOWER_IO_PA;
sys->map_irq = iop13xx_pcie_map_irq;
break;
default:
diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c
index 9a46bcd..bc48715 100644
--- a/arch/arm/mach-iop13xx/setup.c
+++ b/arch/arm/mach-iop13xx/setup.c
@@ -258,15 +258,11 @@ void __init iop13xx_platform_init(void)
if (init_uart == IOP13XX_INIT_UART_DEFAULT) {
switch (iop13xx_dev_id()) {
- /* enable both uarts on iop341 and iop342 */
+ /* enable both uarts on iop341 */
case 0x3380:
case 0x3384:
case 0x3388:
case 0x338c:
- case 0x3382:
- case 0x3386:
- case 0x338a:
- case 0x338e:
init_uart |= IOP13XX_INIT_UART_0;
init_uart |= IOP13XX_INIT_UART_1;
break;
diff --git a/arch/arm/mach-iop13xx/tpmi.c b/arch/arm/mach-iop13xx/tpmi.c
new file mode 100644
index 0000000..d3dc278
--- /dev/null
+++ b/arch/arm/mach-iop13xx/tpmi.c
@@ -0,0 +1,234 @@
+/*
+ * iop13xx tpmi device resources
+ * Copyright (c) 2005-2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+
+/* assumes CONTROLLER_ONLY# is never asserted in the ESSR register */
+#define IOP13XX_TPMI_MMR(dev) IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12))
+#define IOP13XX_TPMI_MEM(dev) IOP13XX_REG_ADDR32_PHYS(0x60000 + (dev << 13))
+#define IOP13XX_TPMI_CTRL(dev) IOP13XX_REG_ADDR32_PHYS(0x50000 + (dev << 10))
+#define IOP13XX_TPMI_MMR_SIZE (SZ_4K - 1)
+#define IOP13XX_TPMI_MEM_SIZE (255)
+#define IOP13XX_TPMI_MEM_CTRL (SZ_1K - 1)
+#define IOP13XX_TPMI_RESOURCE_MMR 0
+#define IOP13XX_TPMI_RESOURCE_MEM 1
+#define IOP13XX_TPMI_RESOURCE_CTRL 2
+#define IOP13XX_TPMI_RESOURCE_IRQ 3
+
+static struct resource iop13xx_tpmi_0_resources[] = {
+ [IOP13XX_TPMI_RESOURCE_MMR] = {
+ .start = IOP13XX_TPMI_MMR(4), /* tpmi0 starts at dev == 4 */
+ .end = IOP13XX_TPMI_MMR(4) + IOP13XX_TPMI_MMR_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_MEM] = {
+ .start = IOP13XX_TPMI_MEM(0),
+ .end = IOP13XX_TPMI_MEM(0) + IOP13XX_TPMI_MEM_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_CTRL] = {
+ .start = IOP13XX_TPMI_CTRL(0),
+ .end = IOP13XX_TPMI_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_IRQ] = {
+ .start = IRQ_IOP13XX_TPMI0_OUT,
+ .end = IRQ_IOP13XX_TPMI0_OUT,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource iop13xx_tpmi_1_resources[] = {
+ [IOP13XX_TPMI_RESOURCE_MMR] = {
+ .start = IOP13XX_TPMI_MMR(1),
+ .end = IOP13XX_TPMI_MMR(1) + IOP13XX_TPMI_MMR_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_MEM] = {
+ .start = IOP13XX_TPMI_MEM(1),
+ .end = IOP13XX_TPMI_MEM(1) + IOP13XX_TPMI_MEM_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_CTRL] = {
+ .start = IOP13XX_TPMI_CTRL(1),
+ .end = IOP13XX_TPMI_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_IRQ] = {
+ .start = IRQ_IOP13XX_TPMI1_OUT,
+ .end = IRQ_IOP13XX_TPMI1_OUT,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource iop13xx_tpmi_2_resources[] = {
+ [IOP13XX_TPMI_RESOURCE_MMR] = {
+ .start = IOP13XX_TPMI_MMR(2),
+ .end = IOP13XX_TPMI_MMR(2) + IOP13XX_TPMI_MMR_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_MEM] = {
+ .start = IOP13XX_TPMI_MEM(2),
+ .end = IOP13XX_TPMI_MEM(2) + IOP13XX_TPMI_MEM_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_CTRL] = {
+ .start = IOP13XX_TPMI_CTRL(2),
+ .end = IOP13XX_TPMI_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_IRQ] = {
+ .start = IRQ_IOP13XX_TPMI2_OUT,
+ .end = IRQ_IOP13XX_TPMI2_OUT,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource iop13xx_tpmi_3_resources[] = {
+ [IOP13XX_TPMI_RESOURCE_MMR] = {
+ .start = IOP13XX_TPMI_MMR(3),
+ .end = IOP13XX_TPMI_MMR(3) + IOP13XX_TPMI_MMR_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_MEM] = {
+ .start = IOP13XX_TPMI_MEM(3),
+ .end = IOP13XX_TPMI_MEM(3) + IOP13XX_TPMI_MEM_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_CTRL] = {
+ .start = IOP13XX_TPMI_CTRL(3),
+ .end = IOP13XX_TPMI_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_IRQ] = {
+ .start = IRQ_IOP13XX_TPMI3_OUT,
+ .end = IRQ_IOP13XX_TPMI3_OUT,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+u64 iop13xx_tpmi_mask = DMA_64BIT_MASK;
+static struct platform_device iop13xx_tpmi_0_device = {
+ .name = "iop-tpmi",
+ .id = 0,
+ .num_resources = 4,
+ .resource = iop13xx_tpmi_0_resources,
+ .dev = {
+ .dma_mask = &iop13xx_tpmi_mask,
+ .coherent_dma_mask = DMA_64BIT_MASK,
+ },
+};
+
+static struct platform_device iop13xx_tpmi_1_device = {
+ .name = "iop-tpmi",
+ .id = 1,
+ .num_resources = 4,
+ .resource = iop13xx_tpmi_1_resources,
+ .dev = {
+ .dma_mask = &iop13xx_tpmi_mask,
+ .coherent_dma_mask = DMA_64BIT_MASK,
+ },
+};
+
+static struct platform_device iop13xx_tpmi_2_device = {
+ .name = "iop-tpmi",
+ .id = 2,
+ .num_resources = 4,
+ .resource = iop13xx_tpmi_2_resources,
+ .dev = {
+ .dma_mask = &iop13xx_tpmi_mask,
+ .coherent_dma_mask = DMA_64BIT_MASK,
+ },
+};
+
+static struct platform_device iop13xx_tpmi_3_device = {
+ .name = "iop-tpmi",
+ .id = 3,
+ .num_resources = 4,
+ .resource = iop13xx_tpmi_3_resources,
+ .dev = {
+ .dma_mask = &iop13xx_tpmi_mask,
+ .coherent_dma_mask = DMA_64BIT_MASK,
+ },
+};
+
+__init void iop13xx_add_tpmi_devices(void)
+{
+ unsigned short device_id;
+
+ /* tpmi's not present on iop341 or iop342 */
+ if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX)
+ /* ATUE must be present */
+ device_id = __raw_readw(IOP13XX_ATUE_DID);
+ else
+ /* ATUX must be present */
+ device_id = __raw_readw(IOP13XX_ATUX_DID);
+
+ switch (device_id) {
+ /* iop34[1|2] 0-tpmi */
+ case 0x3380:
+ case 0x3384:
+ case 0x3388:
+ case 0x338c:
+ case 0x3382:
+ case 0x3386:
+ case 0x338a:
+ case 0x338e:
+ return;
+ /* iop348 1-tpmi */
+ case 0x3310:
+ case 0x3312:
+ case 0x3314:
+ case 0x3318:
+ case 0x331a:
+ case 0x331c:
+ case 0x33c0:
+ case 0x33c2:
+ case 0x33c4:
+ case 0x33c8:
+ case 0x33ca:
+ case 0x33cc:
+ case 0x33b0:
+ case 0x33b2:
+ case 0x33b4:
+ case 0x33b8:
+ case 0x33ba:
+ case 0x33bc:
+ case 0x3320:
+ case 0x3322:
+ case 0x3324:
+ case 0x3328:
+ case 0x332a:
+ case 0x332c:
+ platform_device_register(&iop13xx_tpmi_0_device);
+ return;
+ default:
+ platform_device_register(&iop13xx_tpmi_0_device);
+ platform_device_register(&iop13xx_tpmi_1_device);
+ platform_device_register(&iop13xx_tpmi_2_device);
+ platform_device_register(&iop13xx_tpmi_3_device);
+ return;
+ }
+}
diff --git a/arch/arm/mach-iop32x/Kconfig b/arch/arm/mach-iop32x/Kconfig
index 9dd49cf..9bb02b6 100644
--- a/arch/arm/mach-iop32x/Kconfig
+++ b/arch/arm/mach-iop32x/Kconfig
@@ -34,6 +34,14 @@ config MACH_N2100
Say Y here if you want to run your kernel on the Thecus n2100
NAS appliance.
+config IOP3XX_ATU
+ bool "Enable the PCI Controller"
+ default y
+ help
+ Say Y here if you want the IOP to initialize its PCI Controller.
+ Say N if the IOP is an add in card, the host system owns the PCI
+ bus in this case.
+
endmenu
endif
diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c
index 60e7430..7b21c6e 100644
--- a/arch/arm/mach-iop32x/iq31244.c
+++ b/arch/arm/mach-iop32x/iq31244.c
@@ -178,9 +178,10 @@ static struct hw_pci iq31244_pci __initdata = {
static int __init iq31244_pci_init(void)
{
- if (is_ep80219())
- pci_common_init(&ep80219_pci);
- else if (machine_is_iq31244()) {
+ if (is_ep80219()) {
+ if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE)
+ pci_common_init(&ep80219_pci);
+ } else if (machine_is_iq31244()) {
if (is_80219()) {
printk("note: iq31244 board type has been selected\n");
printk("note: to select ep80219 operation:\n");
@@ -189,7 +190,9 @@ static int __init iq31244_pci_init(void)
printk("\t2/ update boot loader to pass"
" the ep80219 id: %d\n", MACH_TYPE_EP80219);
}
- pci_common_init(&iq31244_pci);
+
+ if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE)
+ pci_common_init(&iq31244_pci);
}
return 0;
diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c
index 361c70c..bc25fb9 100644
--- a/arch/arm/mach-iop32x/iq80321.c
+++ b/arch/arm/mach-iop32x/iq80321.c
@@ -113,7 +113,8 @@ static struct hw_pci iq80321_pci __initdata = {
static int __init iq80321_pci_init(void)
{
- if (machine_is_iq80321())
+ if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) &&
+ machine_is_iq80321())
pci_common_init(&iq80321_pci);
return 0;
diff --git a/arch/arm/mach-iop33x/Kconfig b/arch/arm/mach-iop33x/Kconfig
index 9aa016b..45598e0 100644
--- a/arch/arm/mach-iop33x/Kconfig
+++ b/arch/arm/mach-iop33x/Kconfig
@@ -16,6 +16,14 @@ config MACH_IQ80332
Say Y here if you want to run your kernel on the Intel IQ80332
evaluation kit for the IOP332 chipset.
+config IOP3XX_ATU
+ bool "Enable the PCI Controller"
+ default y
+ help
+ Say Y here if you want the IOP to initialize its PCI Controller.
+ Say N if the IOP is an add in card, the host system owns the PCI
+ bus in this case.
+
endmenu
endif
diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c
index 1a9e361..376c932 100644
--- a/arch/arm/mach-iop33x/iq80331.c
+++ b/arch/arm/mach-iop33x/iq80331.c
@@ -96,7 +96,8 @@ static struct hw_pci iq80331_pci __initdata = {
static int __init iq80331_pci_init(void)
{
- if (machine_is_iq80331())
+ if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) &&
+ machine_is_iq80331())
pci_common_init(&iq80331_pci);
return 0;
diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c
index 96d6f0f..58c8149 100644
--- a/arch/arm/mach-iop33x/iq80332.c
+++ b/arch/arm/mach-iop33x/iq80332.c
@@ -96,7 +96,8 @@ static struct hw_pci iq80332_pci __initdata = {
static int __init iq80332_pci_init(void)
{
- if (machine_is_iq80332())
+ if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) &&
+ machine_is_iq80332())
pci_common_init(&iq80332_pci);
return 0;
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index 27b7480..cb6ad21 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -84,59 +84,59 @@ static struct map_desc ixp2000_io_desc[] __initdata = {
.virtual = IXP2000_CAP_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE),
.length = IXP2000_CAP_SIZE,
- .type = MT_IXP2000_DEVICE,
+ .type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_INTCTL_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE),
.length = IXP2000_INTCTL_SIZE,
- .type = MT_IXP2000_DEVICE,
+ .type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_PCI_CREG_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE),
.length = IXP2000_PCI_CREG_SIZE,
- .type = MT_IXP2000_DEVICE,
+ .type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_PCI_CSR_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE),
.length = IXP2000_PCI_CSR_SIZE,
- .type = MT_IXP2000_DEVICE,
+ .type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_MSF_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE),
.length = IXP2000_MSF_SIZE,
- .type = MT_IXP2000_DEVICE,
+ .type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_SCRATCH_RING_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_SCRATCH_RING_PHYS_BASE),
.length = IXP2000_SCRATCH_RING_SIZE,
- .type = MT_IXP2000_DEVICE,
+ .type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_SRAM0_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_SRAM0_PHYS_BASE),
.length = IXP2000_SRAM0_SIZE,
- .type = MT_IXP2000_DEVICE,
+ .type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_PCI_IO_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE),
.length = IXP2000_PCI_IO_SIZE,
- .type = MT_IXP2000_DEVICE,
+ .type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_PCI_CFG0_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE),
.length = IXP2000_PCI_CFG0_SIZE,
- .type = MT_IXP2000_DEVICE,
+ .type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_PCI_CFG1_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE),
.length = IXP2000_PCI_CFG1_SIZE,
- .type = MT_IXP2000_DEVICE,
+ .type = MT_DEVICE_IXP2000,
}
};
void __init ixp2000_map_io(void)
{
/*
- * On IXP2400 CPUs we need to use MT_IXP2000_DEVICE so that
+ * On IXP2400 CPUs we need to use MT_DEVICE_IXP2000 so that
* XCB=101 (to avoid triggering erratum #66), and given that
* this mode speeds up I/O accesses and we have write buffer
* flushes in the right places anyway, it doesn't hurt to use
@@ -224,7 +224,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id)
static struct irqaction ixp2000_timer_irq = {
.name = "IXP2000 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = ixp2000_timer_interrupt,
};
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
index ac29298..500e997 100644
--- a/arch/arm/mach-ixp2000/enp2611.c
+++ b/arch/arm/mach-ixp2000/enp2611.c
@@ -70,17 +70,17 @@ static struct map_desc enp2611_io_desc[] __initdata = {
.virtual = ENP2611_CALEB_VIRT_BASE,
.pfn = __phys_to_pfn(ENP2611_CALEB_PHYS_BASE),
.length = ENP2611_CALEB_SIZE,
- .type = MT_IXP2000_DEVICE,
+ .type = MT_DEVICE_IXP2000,
}, {
.virtual = ENP2611_PM3386_0_VIRT_BASE,
.pfn = __phys_to_pfn(ENP2611_PM3386_0_PHYS_BASE),
.length = ENP2611_PM3386_0_SIZE,
- .type = MT_IXP2000_DEVICE,
+ .type = MT_DEVICE_IXP2000,
}, {
.virtual = ENP2611_PM3386_1_VIRT_BASE,
.pfn = __phys_to_pfn(ENP2611_PM3386_1_PHYS_BASE),
.length = ENP2611_PM3386_1_SIZE,
- .type = MT_IXP2000_DEVICE,
+ .type = MT_DEVICE_IXP2000,
}
};
diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c
index ce6ad63..b644bba 100644
--- a/arch/arm/mach-ixp23xx/core.c
+++ b/arch/arm/mach-ixp23xx/core.c
@@ -363,7 +363,7 @@ ixp23xx_timer_interrupt(int irq, void *dev_id)
static struct irqaction ixp23xx_timer_irq = {
.name = "IXP23xx Timer Tick",
.handler = ixp23xx_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
};
void __init ixp23xx_init_timer(void)
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 8a339cd..9715ef5 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -62,6 +62,12 @@ config MACH_IXDP465
IXDP465 Development Platform (Also known as BMP).
For more information on this platform, see <file:Documentation/arm/IXP4xx>.
+config MACH_KIXRP435
+ bool "KIXRP435"
+ help
+ Say 'Y' here if you want your kernel to support Intel's
+ KIXRP435 Reference Platform.
+ For more information on this platform, see <file:Documentation/arm/IXP4xx>.
#
# IXCDP1100 is the exact same HW as IXDP425, but with a different machine
@@ -89,12 +95,21 @@ config MACH_NAS100D
NAS 100d device. For more information on this platform,
see http://www.nslu2-linux.org/wiki/NAS100d/HomePage
+config MACH_DSMG600
+ bool
+ prompt "D-Link DSM-G600 RevA"
+ select PCI
+ help
+ Say 'Y' here if you want your kernel to support D-Link's
+ DSM-G600 RevA device. For more information on this platform,
+ see http://www.nslu2-linux.org/wiki/DSMG600/HomePage
+
#
# Avila and IXDP share the same source for now. Will change in future
#
config ARCH_IXDP4XX
bool
- depends on ARCH_IXDP425 || MACH_IXDP465
+ depends on ARCH_IXDP425 || MACH_IXDP465 || MACH_KIXRP435
default y
#
@@ -105,6 +120,11 @@ config CPU_IXP46X
depends on MACH_IXDP465
default y
+config CPU_IXP43X
+ bool
+ depends on MACH_KIXRP435
+ default y
+
config MACH_GTWX5715
bool "Gemtek WX5715 (Linksys WRV54G)"
depends on ARCH_IXP4XX
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index 746e297..3b87c47 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -12,6 +12,7 @@ obj-pci-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o
obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o
obj-pci-$(CONFIG_MACH_NSLU2) += nslu2-pci.o
obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o
+obj-pci-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o
obj-y += common.o
@@ -22,5 +23,6 @@ obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o
obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o
obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o nslu2-power.o
obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o nas100d-power.o
+obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o dsmg600-power.o
obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index 9562177..bf04121 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -374,7 +374,7 @@ void __init ixp4xx_pci_preinit(void)
* Determine which PCI read method to use.
* Rev 0 IXP425 requires workaround.
*/
- if (!(processor_id & 0xf) && !cpu_is_ixp46x()) {
+ if (!(processor_id & 0xf) && cpu_is_ixp42x()) {
printk("PCI: IXP42x A0 silicon detected - "
"PCI Non-Prefetch Workaround Enabled\n");
ixp4xx_pci_read = ixp4xx_pci_read_errata;
@@ -480,7 +480,7 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys)
res[0].flags = IORESOURCE_IO;
res[1].name = "PCI Memory Space";
- res[1].start = 0x48000000;
+ res[1].start = PCIBIOS_MIN_MEM;
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
res[1].end = 0x4bffffff;
#else
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 45068c3..64685da 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -27,6 +27,7 @@
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/clocksource.h>
+#include <linux/clockchips.h>
#include <asm/arch/udc.h>
#include <asm/hardware.h>
@@ -41,6 +42,8 @@
#include <asm/mach/time.h>
static int __init ixp4xx_clocksource_init(void);
+static int __init ixp4xx_clockevent_init(void);
+static struct clock_event_device clockevent_ixp4xx;
/*************************************************************************
* IXP4xx chipset I/O mapping
@@ -102,6 +105,29 @@ static signed char irq2gpio[32] = {
7, 8, 9, 10, 11, 12, -1, -1,
};
+int gpio_to_irq(int gpio)
+{
+ int irq;
+
+ for (irq = 0; irq < 32; irq++) {
+ if (irq2gpio[irq] == gpio)
+ return irq;
+ }
+ return -EINVAL;
+}
+EXPORT_SYMBOL(gpio_to_irq);
+
+int irq_to_gpio(int irq)
+{
+ int gpio = (irq < 32) ? irq2gpio[irq] : -EINVAL;
+
+ if (gpio == -1)
+ return -EINVAL;
+
+ return gpio;
+}
+EXPORT_SYMBOL(irq_to_gpio);
+
static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
{
int line = irq2gpio[irq];
@@ -169,7 +195,7 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
static void ixp4xx_irq_mask(unsigned int irq)
{
- if (cpu_is_ixp46x() && irq >= 32)
+ if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32)
*IXP4XX_ICMR2 &= ~(1 << (irq - 32));
else
*IXP4XX_ICMR &= ~(1 << irq);
@@ -192,7 +218,7 @@ static void ixp4xx_irq_unmask(unsigned int irq)
if (!(ixp4xx_irq_edge & (1 << irq)))
ixp4xx_irq_ack(irq);
- if (cpu_is_ixp46x() && irq >= 32)
+ if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32)
*IXP4XX_ICMR2 |= (1 << (irq - 32));
else
*IXP4XX_ICMR |= (1 << irq);
@@ -216,7 +242,7 @@ void __init ixp4xx_init_irq(void)
/* Disable all interrupt */
*IXP4XX_ICMR = 0x0;
- if (cpu_is_ixp46x()) {
+ if (cpu_is_ixp46x() || cpu_is_ixp43x()) {
/* Route upper 32 sources to IRQ instead of FIQ */
*IXP4XX_ICLR2 = 0x00;
@@ -239,52 +265,40 @@ void __init ixp4xx_init_irq(void)
* counter as a source of real clock ticks to account for missed jiffies.
*************************************************************************/
-static unsigned volatile last_jiffy_time;
-
-#define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC)
-
static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
{
- write_seqlock(&xtime_lock);
+ struct clock_event_device *evt = &clockevent_ixp4xx;
/* Clear Pending Interrupt by writing '1' to it */
*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
- /*
- * Catch up with the real idea of time
- */
- while ((signed long)(*IXP4XX_OSTS - last_jiffy_time) >= LATCH) {
- timer_tick();
- last_jiffy_time += LATCH;
- }
-
- write_sequnlock(&xtime_lock);
+ evt->event_handler(evt);
return IRQ_HANDLED;
}
static struct irqaction ixp4xx_timer_irq = {
- .name = "IXP4xx Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .name = "timer1",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = ixp4xx_timer_interrupt,
};
static void __init ixp4xx_timer_init(void)
{
+ /* Reset/disable counter */
+ *IXP4XX_OSRT1 = 0;
+
/* Clear Pending Interrupt by writing '1' to it */
*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
- /* Setup the Timer counter value */
- *IXP4XX_OSRT1 = (LATCH & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE;
-
/* Reset time-stamp counter */
*IXP4XX_OSTS = 0;
- last_jiffy_time = 0;
/* Connect the interrupt handler and enable the interrupt */
setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq);
ixp4xx_clocksource_init();
+ ixp4xx_clockevent_init();
}
struct sys_timer ixp4xx_timer = {
@@ -384,6 +398,9 @@ void __init ixp4xx_sys_init(void)
ixp4xx_exp_bus_size >> 20);
}
+/*
+ * clocksource
+ */
cycle_t ixp4xx_get_cycles(void)
{
return *IXP4XX_OSTS;
@@ -408,3 +425,64 @@ static int __init ixp4xx_clocksource_init(void)
return 0;
}
+
+/*
+ * clockevents
+ */
+static int ixp4xx_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
+
+ *IXP4XX_OSRT1 = (evt & ~IXP4XX_OST_RELOAD_MASK) | opts;
+
+ return 0;
+}
+
+static void ixp4xx_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long opts, osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ osrt = LATCH & ~IXP4XX_OST_RELOAD_MASK;
+ opts = IXP4XX_OST_ENABLE;
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* period set by 'set next_event' */
+ osrt = 0;
+ opts = IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT;
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ default:
+ osrt = opts = 0;
+ break;
+ }
+
+ *IXP4XX_OSRT1 = osrt | opts;
+}
+
+static struct clock_event_device clockevent_ixp4xx = {
+ .name = "ixp4xx timer1",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 200,
+ .shift = 24,
+ .set_mode = ixp4xx_set_mode,
+ .set_next_event = ixp4xx_set_next_event,
+};
+
+static int __init ixp4xx_clockevent_init(void)
+{
+ clockevent_ixp4xx.mult = div_sc(FREQ, NSEC_PER_SEC,
+ clockevent_ixp4xx.shift);
+ clockevent_ixp4xx.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_ixp4xx);
+ clockevent_ixp4xx.min_delta_ns =
+ clockevent_delta2ns(0xf, &clockevent_ixp4xx);
+ clockevent_ixp4xx.cpumask = cpumask_of_cpu(0);
+
+ clockevents_register_device(&clockevent_ixp4xx);
+ return 0;
+}
diff --git a/arch/arm/mach-ixp4xx/dsmg600-pci.c b/arch/arm/mach-ixp4xx/dsmg600-pci.c
new file mode 100644
index 0000000..9db7e1f
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/dsmg600-pci.c
@@ -0,0 +1,74 @@
+/*
+ * DSM-G600 board-level PCI initialization
+ *
+ * Copyright (C) 2006 Tower Technologies
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ *
+ * based on ixdp425-pci.c:
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Maintainer: http://www.nslu2-linux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+void __init dsmg600_pci_preinit(void)
+{
+ set_irq_type(IRQ_DSMG600_PCI_INTA, IRQT_LOW);
+ set_irq_type(IRQ_DSMG600_PCI_INTB, IRQT_LOW);
+ set_irq_type(IRQ_DSMG600_PCI_INTC, IRQT_LOW);
+ set_irq_type(IRQ_DSMG600_PCI_INTD, IRQT_LOW);
+ set_irq_type(IRQ_DSMG600_PCI_INTE, IRQT_LOW);
+ set_irq_type(IRQ_DSMG600_PCI_INTF, IRQT_LOW);
+
+ ixp4xx_pci_preinit();
+}
+
+static int __init dsmg600_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ static int pci_irq_table[DSMG600_PCI_MAX_DEV][DSMG600_PCI_IRQ_LINES] =
+ {
+ { IRQ_DSMG600_PCI_INTE, -1, -1 },
+ { IRQ_DSMG600_PCI_INTA, -1, -1 },
+ { IRQ_DSMG600_PCI_INTB, IRQ_DSMG600_PCI_INTC, IRQ_DSMG600_PCI_INTD },
+ { IRQ_DSMG600_PCI_INTF, -1, -1 },
+ };
+
+ int irq = -1;
+
+ if (slot >= 1 && slot <= DSMG600_PCI_MAX_DEV &&
+ pin >= 1 && pin <= DSMG600_PCI_IRQ_LINES)
+ irq = pci_irq_table[slot-1][pin-1];
+
+ return irq;
+}
+
+struct hw_pci __initdata dsmg600_pci = {
+ .nr_controllers = 1,
+ .preinit = dsmg600_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = dsmg600_map_irq,
+};
+
+int __init dsmg600_pci_init(void)
+{
+ if (machine_is_dsmg600())
+ pci_common_init(&dsmg600_pci);
+
+ return 0;
+}
+
+subsys_initcall(dsmg600_pci_init);
diff --git a/arch/arm/mach-ixp4xx/dsmg600-power.c b/arch/arm/mach-ixp4xx/dsmg600-power.c
new file mode 100644
index 0000000..3471787
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/dsmg600-power.c
@@ -0,0 +1,125 @@
+/*
+ * arch/arm/mach-ixp4xx/dsmg600-power.c
+ *
+ * DSM-G600 Power/Reset driver
+ * Author: Michael Westerhof <mwester@dls.net>
+ *
+ * Based on nslu2-power.c
+ * Copyright (C) 2005 Tower Technologies
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ *
+ * which was based on nslu2-io.c
+ * Copyright (C) 2004 Karen Spearel
+ *
+ * Maintainers: http://www.nslu2-linux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+
+#include <asm/mach-types.h>
+
+extern void ctrl_alt_del(void);
+
+/* This is used to make sure the power-button pusher is serious. The button
+ * must be held until the value of this counter reaches zero.
+ */
+static volatile int power_button_countdown;
+
+/* Must hold the button down for at least this many counts to be processed */
+#define PBUTTON_HOLDDOWN_COUNT 4 /* 2 secs */
+
+static void dsmg600_power_handler(unsigned long data);
+static DEFINE_TIMER(dsmg600_power_timer, dsmg600_power_handler, 0, 0);
+
+static void dsmg600_power_handler(unsigned long data)
+{
+ /* This routine is called twice per second to check the
+ * state of the power button.
+ */
+
+ if (*IXP4XX_GPIO_GPINR & DSMG600_PB_BM) {
+
+ /* IO Pin is 1 (button pushed) */
+ if (power_button_countdown == 0) {
+ /* Signal init to do the ctrlaltdel action, this will bypass
+ * init if it hasn't started and do a kernel_restart.
+ */
+ ctrl_alt_del();
+
+ /* Change the state of the power LED to "blink" */
+ gpio_line_set(DSMG600_LED_PWR_GPIO, IXP4XX_GPIO_LOW);
+ }
+ power_button_countdown--;
+
+ } else {
+ power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
+ }
+
+ mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500));
+}
+
+static irqreturn_t dsmg600_reset_handler(int irq, void *dev_id)
+{
+ /* This is the paper-clip reset, it shuts the machine down directly. */
+ machine_power_off();
+
+ return IRQ_HANDLED;
+}
+
+static int __init dsmg600_power_init(void)
+{
+ if (!(machine_is_dsmg600()))
+ return 0;
+
+ if (request_irq(DSMG600_RB_IRQ, &dsmg600_reset_handler,
+ IRQF_DISABLED | IRQF_TRIGGER_LOW, "DSM-G600 reset button",
+ NULL) < 0) {
+
+ printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
+ DSMG600_RB_IRQ);
+
+ return -EIO;
+ }
+
+ /* The power button on the D-Link DSM-G600 is on GPIO 15, but
+ * it cannot handle interrupts on that GPIO line. So we'll
+ * have to poll it with a kernel timer.
+ */
+
+ /* Make sure that the power button GPIO is set up as an input */
+ gpio_line_config(DSMG600_PB_GPIO, IXP4XX_GPIO_IN);
+
+ /* Set the initial value for the power button IRQ handler */
+ power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
+
+ mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500));
+
+ return 0;
+}
+
+static void __exit dsmg600_power_exit(void)
+{
+ if (!(machine_is_dsmg600()))
+ return;
+
+ del_timer_sync(&dsmg600_power_timer);
+
+ free_irq(DSMG600_RB_IRQ, NULL);
+}
+
+module_init(dsmg600_power_init);
+module_exit(dsmg600_power_exit);
+
+MODULE_AUTHOR("Michael Westerhof <mwester@dls.net>");
+MODULE_DESCRIPTION("DSM-G600 Power/Reset driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c
new file mode 100644
index 0000000..1caff65
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -0,0 +1,175 @@
+/*
+ * DSM-G600 board-setup
+ *
+ * Copyright (C) 2006 Tower Technologies
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ *
+ * based ixdp425-setup.c:
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ * Maintainers: http://www.nslu2-linux.org/
+ */
+
+#include <linux/kernel.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+static struct flash_platform_data dsmg600_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource dsmg600_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device dsmg600_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev.platform_data = &dsmg600_flash_data,
+ .num_resources = 1,
+ .resource = &dsmg600_flash_resource,
+};
+
+static struct ixp4xx_i2c_pins dsmg600_i2c_gpio_pins = {
+ .sda_pin = DSMG600_SDA_PIN,
+ .scl_pin = DSMG600_SCL_PIN,
+};
+
+static struct platform_device dsmg600_i2c_controller = {
+ .name = "IXP4XX-I2C",
+ .id = 0,
+ .dev.platform_data = &dsmg600_i2c_gpio_pins,
+};
+
+#ifdef CONFIG_LEDS_CLASS
+static struct resource dsmg600_led_resources[] = {
+ {
+ .name = "power",
+ .start = DSMG600_LED_PWR_GPIO,
+ .end = DSMG600_LED_PWR_GPIO,
+ .flags = IXP4XX_GPIO_HIGH,
+ },
+ {
+ .name = "wlan",
+ .start = DSMG600_LED_WLAN_GPIO,
+ .end = DSMG600_LED_WLAN_GPIO,
+ .flags = IXP4XX_GPIO_LOW,
+ },
+};
+
+static struct platform_device dsmg600_leds = {
+ .name = "IXP4XX-GPIO-LED",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dsmg600_led_resources),
+ .resource = dsmg600_led_resources,
+};
+#endif
+
+static struct resource dsmg600_uart_resources[] = {
+ {
+ .start = IXP4XX_UART1_BASE_PHYS,
+ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct plat_serial8250_port dsmg600_uart_data[] = {
+ {
+ .mapbase = IXP4XX_UART1_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART1,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ { }
+};
+
+static struct platform_device dsmg600_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev.platform_data = dsmg600_uart_data,
+ .num_resources = ARRAY_SIZE(dsmg600_uart_resources),
+ .resource = dsmg600_uart_resources,
+};
+
+static struct platform_device *dsmg600_devices[] __initdata = {
+ &dsmg600_i2c_controller,
+ &dsmg600_flash,
+};
+
+static void dsmg600_power_off(void)
+{
+ /* enable the pwr cntl gpio */
+ gpio_line_config(DSMG600_PO_GPIO, IXP4XX_GPIO_OUT);
+
+ /* poweroff */
+ gpio_line_set(DSMG600_PO_GPIO, IXP4XX_GPIO_HIGH);
+}
+
+static void __init dsmg600_init(void)
+{
+ ixp4xx_sys_init();
+
+ /* Make sure that GPIO14 and GPIO15 are not used as clocks */
+ *IXP4XX_GPIO_GPCLKR = 0;
+
+ dsmg600_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+ dsmg600_flash_resource.end =
+ IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
+
+ pm_power_off = dsmg600_power_off;
+
+ /* The UART is required on the DSM-G600 (Redboot cannot use the
+ * NIC) -- do it here so that it does *not* get removed if
+ * platform_add_devices fails!
+ */
+ (void)platform_device_register(&dsmg600_uart);
+
+ platform_add_devices(dsmg600_devices, ARRAY_SIZE(dsmg600_devices));
+
+#ifdef CONFIG_LEDS_CLASS
+ /* We don't care whether or not this works. */
+ (void)platform_device_register(&dsmg600_leds);
+#endif
+}
+
+static void __init dsmg600_fixup(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+ /* The xtal on this machine is non-standard. */
+ ixp4xx_timer_freq = DSMG600_FREQ;
+}
+
+MACHINE_START(DSMG600, "D-Link DSM-G600 RevA")
+ /* Maintainer: www.nslu2-linux.org */
+ .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
+ .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .fixup = dsmg600_fixup,
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .init_machine = dsmg600_init,
+MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c
index 99c1dc8..4087960 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 = {
int __init ixdp425_pci_init(void)
{
if (machine_is_ixdp425() || machine_is_ixcdp1100() ||
- machine_is_ixdp465())
+ machine_is_ixdp465() || machine_is_kixrp435())
pci_common_init(&ixdp425_pci);
return 0;
}
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index 04b1d56..ec4f079 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -115,6 +115,11 @@ static void __init ixdp425_init(void)
ixdp425_flash_resource.end =
IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
+ if (cpu_is_ixp43x()) {
+ ixdp425_uart.num_resources = 1;
+ ixdp425_uart_data[1].flags = 0;
+ }
+
platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
}
@@ -156,3 +161,16 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
.init_machine = ixdp425_init,
MACHINE_END
#endif
+
+#ifdef CONFIG_MACH_KIXRP435
+MACHINE_START(KIXRP435, "Intel KIXRP435 Reference Platform")
+ /* Maintainer: MontaVista Software, Inc. */
+ .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
+ .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = ixdp425_init,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-lh7a40x/irq-lh7a400.c b/arch/arm/mach-lh7a40x/irq-lh7a400.c
index 0b938e8..9472bbe 100644
--- a/arch/arm/mach-lh7a40x/irq-lh7a400.c
+++ b/arch/arm/mach-lh7a40x/irq-lh7a400.c
@@ -11,7 +11,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
-#include <linux/ptrace.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-lh7a40x/irq-lh7a404.c b/arch/arm/mach-lh7a40x/irq-lh7a404.c
index 5760f8c..9b28389 100644
--- a/arch/arm/mach-lh7a40x/irq-lh7a404.c
+++ b/arch/arm/mach-lh7a40x/irq-lh7a404.c
@@ -11,7 +11,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
-#include <linux/ptrace.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
index 15b9577..66e1ed3 100644
--- a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c
@@ -12,7 +12,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
-#include <linux/ptrace.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c
index bef3c4b..c25316d 100644
--- a/arch/arm/mach-lh7a40x/time.c
+++ b/arch/arm/mach-lh7a40x/time.c
@@ -53,7 +53,7 @@ lh7a40x_timer_interrupt(int irq, void *dev_id)
static struct irqaction lh7a40x_timer_irq = {
.name = "LHA740x Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = lh7a40x_timer_interrupt,
};
diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c
index 7e132fc..4762e20 100644
--- a/arch/arm/mach-netx/time.c
+++ b/arch/arm/mach-netx/time.c
@@ -47,7 +47,7 @@ netx_timer_interrupt(int irq, void *dev_id)
static struct irqaction netx_timer_irq = {
.name = "NetX Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = netx_timer_interrupt,
};
diff --git a/arch/arm/mach-ns9xxx/Kconfig b/arch/arm/mach-ns9xxx/Kconfig
index 8175ba9..8584ed1 100644
--- a/arch/arm/mach-ns9xxx/Kconfig
+++ b/arch/arm/mach-ns9xxx/Kconfig
@@ -3,19 +3,30 @@ if ARCH_NS9XXX
menu "NS9xxx Implementations"
config MACH_CC9P9360DEV
- bool "Connect Core 9P 9360 on an A9M9750 Devboard"
+ bool "ConnectCore 9P 9360 on an A9M9750 Devboard"
select PROCESSOR_NS9360
select BOARD_A9M9750DEV
help
- Say Y here if you are using the Digi Connect Core 9P 9360
+ Say Y here if you are using the Digi ConnectCore 9P 9360
on an A9M9750 Development Board.
+config MACH_CC9P9360JS
+ bool "ConnectCore 9P 9360 on a JSCC9P9360 Devboard"
+ select PROCESSOR_NS9360
+ select BOARD_JSCC9P9360
+ help
+ Say Y here if you are using the Digi ConnectCore 9P 9360
+ on an JSCC9P9360 Development Board.
+
config PROCESSOR_NS9360
bool
config BOARD_A9M9750DEV
bool
+config BOARD_JSCC9P9360
+ bool
+
endmenu
endif
diff --git a/arch/arm/mach-ns9xxx/Makefile b/arch/arm/mach-ns9xxx/Makefile
index 91e945f..53213a6 100644
--- a/arch/arm/mach-ns9xxx/Makefile
+++ b/arch/arm/mach-ns9xxx/Makefile
@@ -3,3 +3,4 @@ obj-y := irq.o time.o generic.o
obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o
obj-$(CONFIG_BOARD_A9M9750DEV) += board-a9m9750dev.o
+obj-$(CONFIG_BOARD_JSCC9P9360) += board-jscc9p9360.o
diff --git a/arch/arm/mach-ns9xxx/board-jscc9p9360.c b/arch/arm/mach-ns9xxx/board-jscc9p9360.c
new file mode 100644
index 0000000..4bd3eec
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/board-jscc9p9360.c
@@ -0,0 +1,17 @@
+/*
+ * arch/arm/mach-ns9xxx/board-jscc9p9360.c
+ *
+ * Copyright (C) 2006,2007 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include "board-jscc9p9360.h"
+
+void __init board_jscc9p9360_init_machine(void)
+{
+ /* TODO: reserve GPIOs for push buttons, etc pp */
+}
+
diff --git a/arch/arm/mach-ns9xxx/board-jscc9p9360.h b/arch/arm/mach-ns9xxx/board-jscc9p9360.h
new file mode 100644
index 0000000..1a81a07
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/board-jscc9p9360.h
@@ -0,0 +1,13 @@
+/*
+ * arch/arm/mach-ns9xxx/board-jscc9p9360.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/init.h>
+
+void __init board_jscc9p9360_init_machine(void);
diff --git a/arch/arm/mach-ns9xxx/mach-cc9p9360js.c b/arch/arm/mach-ns9xxx/mach-cc9p9360js.c
new file mode 100644
index 0000000..d09d5fa
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/mach-cc9p9360js.c
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-ns9xxx/mach-cc9p9360js.c
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include "board-jscc9p9360.h"
+#include "generic.h"
+
+static void __init mach_cc9p9360js_init_machine(void)
+{
+ ns9xxx_init_machine();
+ board_jscc9p9360_init_machine();
+}
+
+MACHINE_START(CC9P9360DEV, "Digi ConnectCore 9P 9360 on an JSCC9P9360 Devboard")
+ .map_io = ns9xxx_map_io,
+ .init_irq = ns9xxx_init_irq,
+ .init_machine = mach_cc9p9360js_init_machine,
+ .timer = &ns9xxx_timer,
+ .boot_params = 0x100,
+MACHINE_END
diff --git a/arch/arm/mach-ns9xxx/time.c b/arch/arm/mach-ns9xxx/time.c
index eec05f1..dd25708 100644
--- a/arch/arm/mach-ns9xxx/time.c
+++ b/arch/arm/mach-ns9xxx/time.c
@@ -53,7 +53,7 @@ static unsigned long ns9xxx_timer_gettimeoffset(void)
static struct irqaction ns9xxx_timer_irq = {
.name = "NS9xxx Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = ns9xxx_timer_interrupt,
};
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index 410d3e7..0733078 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -40,7 +40,6 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include <linux/ptrace.h>
#include <asm/hardware.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index 1b7e4a5..3705d20 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -39,6 +39,10 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
#include <asm/system.h>
#include <asm/hardware.h>
@@ -48,13 +52,7 @@
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
-struct sys_timer omap_timer;
-/*
- * ---------------------------------------------------------------------------
- * MPU timer
- * ---------------------------------------------------------------------------
- */
#define OMAP_MPU_TIMER_BASE OMAP_MPU_TIMER1_BASE
#define OMAP_MPU_TIMER_OFFSET 0x100
@@ -88,21 +86,6 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
}
-/*
- * MPU_TICKS_PER_SEC must be an even number, otherwise machinecycles_to_usecs
- * will break. On P2, the timer count rate is 6.5 MHz after programming PTV
- * with 0. This divides the 13MHz input by 2, and is undocumented.
- */
-#if defined(CONFIG_MACH_OMAP_PERSEUS2) || defined(CONFIG_MACH_OMAP_FSAMPLE)
-/* REVISIT: This ifdef construct should be replaced by a query to clock
- * framework to see if timer base frequency is 12.0, 13.0 or 19.2 MHz.
- */
-#define MPU_TICKS_PER_SEC (13000000 / 2)
-#else
-#define MPU_TICKS_PER_SEC (12000000 / 2)
-#endif
-
-#define MPU_TIMER_TICK_PERIOD ((MPU_TICKS_PER_SEC / HZ) - 1)
typedef struct {
u32 cntl; /* CNTL_TIMER, R/W */
@@ -120,98 +103,164 @@ static inline unsigned long omap_mpu_timer_read(int nr)
return timer->read_tim;
}
-static inline void omap_mpu_timer_start(int nr, unsigned long load_val)
+static inline void omap_mpu_set_autoreset(int nr)
+{
+ volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
+
+ timer->cntl = timer->cntl | MPU_TIMER_AR;
+}
+
+static inline void omap_mpu_remove_autoreset(int nr)
+{
+ volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
+
+ timer->cntl = timer->cntl & ~MPU_TIMER_AR;
+}
+
+static inline void omap_mpu_timer_start(int nr, unsigned long load_val,
+ int autoreset)
{
volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
+ unsigned int timerflags = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_ST);
+
+ if (autoreset) timerflags |= MPU_TIMER_AR;
timer->cntl = MPU_TIMER_CLOCK_ENABLE;
udelay(1);
timer->load_tim = load_val;
udelay(1);
- timer->cntl = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_AR | MPU_TIMER_ST);
+ timer->cntl = timerflags;
}
-unsigned long omap_mpu_timer_ticks_to_usecs(unsigned long nr_ticks)
+/*
+ * ---------------------------------------------------------------------------
+ * MPU timer 1 ... count down to zero, interrupt, reload
+ * ---------------------------------------------------------------------------
+ */
+static int omap_mpu_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
{
- unsigned long long nsec;
+ omap_mpu_timer_start(0, cycles, 0);
+ return 0;
+}
- nsec = cycles_2_ns((unsigned long long)nr_ticks);
- return (unsigned long)nsec / 1000;
+static void omap_mpu_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ omap_mpu_set_autoreset(0);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ omap_mpu_remove_autoreset(0);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ break;
+ }
}
-/*
- * Last processed system timer interrupt
- */
-static unsigned long omap_mpu_timer_last = 0;
+static struct clock_event_device clockevent_mpu_timer1 = {
+ .name = "mpu_timer1",
+ .features = CLOCK_EVT_FEAT_PERIODIC, CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_next_event = omap_mpu_set_next_event,
+ .set_mode = omap_mpu_set_mode,
+};
-/*
- * Returns elapsed usecs since last system timer interrupt
- */
-static unsigned long omap_mpu_timer_gettimeoffset(void)
+static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_mpu_timer1;
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction omap_mpu_timer1_irq = {
+ .name = "mpu_timer1",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = omap_mpu_timer1_interrupt,
+};
+
+static __init void omap_init_mpu_timer(unsigned long rate)
{
- unsigned long now = 0 - omap_mpu_timer_read(0);
- unsigned long elapsed = now - omap_mpu_timer_last;
+ set_cyc2ns_scale(rate / 1000);
+
+ setup_irq(INT_TIMER1, &omap_mpu_timer1_irq);
+ omap_mpu_timer_start(0, (rate / HZ) - 1, 1);
+
+ clockevent_mpu_timer1.mult = div_sc(rate, NSEC_PER_SEC,
+ clockevent_mpu_timer1.shift);
+ clockevent_mpu_timer1.max_delta_ns =
+ clockevent_delta2ns(-1, &clockevent_mpu_timer1);
+ clockevent_mpu_timer1.min_delta_ns =
+ clockevent_delta2ns(1, &clockevent_mpu_timer1);
- return omap_mpu_timer_ticks_to_usecs(elapsed);
+ clockevent_mpu_timer1.cpumask = cpumask_of_cpu(0);
+ clockevents_register_device(&clockevent_mpu_timer1);
}
+
/*
- * Elapsed time between interrupts is calculated using timer0.
- * Latency during the interrupt is calculated using timer1.
- * Both timer0 and timer1 are counting at 6MHz (P2 6.5MHz).
+ * ---------------------------------------------------------------------------
+ * MPU timer 2 ... free running 32-bit clock source and scheduler clock
+ * ---------------------------------------------------------------------------
*/
-static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id)
-{
- unsigned long now, latency;
- write_seqlock(&xtime_lock);
- now = 0 - omap_mpu_timer_read(0);
- latency = MPU_TICKS_PER_SEC / HZ - omap_mpu_timer_read(1);
- omap_mpu_timer_last = now - latency;
- timer_tick();
- write_sequnlock(&xtime_lock);
+static unsigned long omap_mpu_timer2_overflows;
+static irqreturn_t omap_mpu_timer2_interrupt(int irq, void *dev_id)
+{
+ omap_mpu_timer2_overflows++;
return IRQ_HANDLED;
}
-static struct irqaction omap_mpu_timer_irq = {
- .name = "mpu timer",
- .flags = IRQF_DISABLED | IRQF_TIMER,
- .handler = omap_mpu_timer_interrupt,
+static struct irqaction omap_mpu_timer2_irq = {
+ .name = "mpu_timer2",
+ .flags = IRQF_DISABLED,
+ .handler = omap_mpu_timer2_interrupt,
};
-static unsigned long omap_mpu_timer1_overflows;
-static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id)
+static cycle_t mpu_read(void)
{
- omap_mpu_timer1_overflows++;
- return IRQ_HANDLED;
+ return ~omap_mpu_timer_read(1);
}
-static struct irqaction omap_mpu_timer1_irq = {
- .name = "mpu timer1 overflow",
- .flags = IRQF_DISABLED,
- .handler = omap_mpu_timer1_interrupt,
+static struct clocksource clocksource_mpu = {
+ .name = "mpu_timer2",
+ .rating = 300,
+ .read = mpu_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 24,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-static __init void omap_init_mpu_timer(void)
+static void __init omap_init_clocksource(unsigned long rate)
{
- set_cyc2ns_scale(MPU_TICKS_PER_SEC / 1000);
- omap_timer.offset = omap_mpu_timer_gettimeoffset;
- setup_irq(INT_TIMER1, &omap_mpu_timer1_irq);
- setup_irq(INT_TIMER2, &omap_mpu_timer_irq);
- omap_mpu_timer_start(0, 0xffffffff);
- omap_mpu_timer_start(1, MPU_TIMER_TICK_PERIOD);
+ static char err[] __initdata = KERN_ERR
+ "%s: can't register clocksource!\n";
+
+ clocksource_mpu.mult
+ = clocksource_khz2mult(rate/1000, clocksource_mpu.shift);
+
+ setup_irq(INT_TIMER2, &omap_mpu_timer2_irq);
+ omap_mpu_timer_start(1, ~0, 1);
+
+ if (clocksource_register(&clocksource_mpu))
+ printk(err, clocksource_mpu.name);
}
+
/*
* Scheduler clock - returns current time in nanosec units.
*/
unsigned long long sched_clock(void)
{
- unsigned long ticks = 0 - omap_mpu_timer_read(0);
+ unsigned long ticks = 0 - omap_mpu_timer_read(1);
unsigned long long ticks64;
- ticks64 = omap_mpu_timer1_overflows;
+ ticks64 = omap_mpu_timer2_overflows;
ticks64 <<= 32;
ticks64 |= ticks;
@@ -225,10 +274,21 @@ unsigned long long sched_clock(void)
*/
static void __init omap_timer_init(void)
{
- omap_init_mpu_timer();
+ struct clk *ck_ref = clk_get(NULL, "ck_ref");
+ unsigned long rate;
+
+ BUG_ON(IS_ERR(ck_ref));
+
+ rate = clk_get_rate(ck_ref);
+ clk_put(ck_ref);
+
+ /* PTV = 0 */
+ rate /= 2;
+
+ omap_init_mpu_timer(rate);
+ omap_init_clocksource(rate);
}
struct sys_timer omap_timer = {
.init = omap_timer_init,
- .offset = NULL, /* Initialized later */
};
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 45d1aaa..62e801e 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -52,7 +52,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
static struct irqaction omap2_gp_timer_irq = {
.name = "gp timer",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = omap2_gp_timer_interrupt,
};
diff --git a/arch/arm/mach-pnx4008/time.c b/arch/arm/mach-pnx4008/time.c
index 8621c20..67e05f0 100644
--- a/arch/arm/mach-pnx4008/time.c
+++ b/arch/arm/mach-pnx4008/time.c
@@ -82,7 +82,7 @@ static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id)
static struct irqaction pnx4008_timer_irq = {
.name = "PNX4008 Tick Timer",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = pnx4008_timer_interrupt
};
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index b8cb79f..64b08b7 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -164,9 +164,9 @@ void pxa_set_cken(int clock, int enable)
local_irq_save(flags);
if (enable)
- CKEN |= clock;
+ CKEN |= (1 << clock);
else
- CKEN &= ~clock;
+ CKEN &= ~(1 << clock);
local_irq_restore(flags);
}
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index f815678..4619d5f 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -15,7 +15,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
-#include <linux/ptrace.h>
#include <asm/hardware.h>
#include <asm/irq.h>
@@ -39,11 +38,33 @@ static void pxa_unmask_low_irq(unsigned int irq)
ICMR |= (1 << (irq + PXA_IRQ_SKIP));
}
+static int pxa_set_wake(unsigned int irq, unsigned int on)
+{
+ u32 mask;
+
+ switch (irq) {
+ case IRQ_RTCAlrm:
+ mask = PWER_RTC;
+ break;
+#ifdef CONFIG_PXA27x
+ /* REVISIT can handle USBH1, USBH2, USB, MSL, USIM, ... */
+#endif
+ default:
+ return -EINVAL;
+ }
+ if (on)
+ PWER |= mask;
+ else
+ PWER &= ~mask;
+ return 0;
+}
+
static struct irq_chip pxa_internal_chip_low = {
.name = "SC",
.ack = pxa_mask_low_irq,
.mask = pxa_mask_low_irq,
.unmask = pxa_unmask_low_irq,
+ .set_wake = pxa_set_wake,
};
#if PXA_INTERNAL_IRQS > 32
@@ -71,6 +92,26 @@ static struct irq_chip pxa_internal_chip_high = {
#endif
+/* Note that if an input/irq line ever gets changed to an output during
+ * suspend, the relevant PWER, PRER, and PFER bits should be cleared.
+ */
+#ifdef CONFIG_PXA27x
+
+/* PXA27x: Various gpios can issue wakeup events. This logic only
+ * handles the simple cases, not the WEMUX2 and WEMUX3 options
+ */
+#define PXA27x_GPIO_NOWAKE_MASK \
+ ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2))
+#define WAKEMASK(gpio) \
+ (((gpio) <= 15) \
+ ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \
+ : ((gpio == 35) ? (1 << 24) : 0))
+#else
+
+/* pxa 210, 250, 255, 26x: gpios 0..15 can issue wakeups */
+#define WAKEMASK(gpio) (((gpio) <= 15) ? (1 << (gpio)) : 0)
+#endif
+
/*
* PXA GPIO edge detection for IRQs:
* IRQs are generated on Falling-Edge, Rising-Edge, or both.
@@ -84,9 +125,11 @@ static long GPIO_IRQ_mask[4];
static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
{
int gpio, idx;
+ u32 mask;
gpio = IRQ_TO_GPIO(irq);
idx = gpio >> 5;
+ mask = WAKEMASK(gpio);
if (type == IRQT_PROBE) {
/* Don't mess with enabled GPIOs using preconfigured edges or
@@ -106,14 +149,20 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
if (type & __IRQT_RISEDGE) {
/* printk("rising "); */
__set_bit (gpio, GPIO_IRQ_rising_edge);
- } else
+ PRER |= mask;
+ } else {
__clear_bit (gpio, GPIO_IRQ_rising_edge);
+ PRER &= ~mask;
+ }
if (type & __IRQT_FALEDGE) {
/* printk("falling "); */
__set_bit (gpio, GPIO_IRQ_falling_edge);
- } else
+ PFER |= mask;
+ } else {
__clear_bit (gpio, GPIO_IRQ_falling_edge);
+ PFER &= ~mask;
+ }
/* printk("edges\n"); */
@@ -131,12 +180,29 @@ static void pxa_ack_low_gpio(unsigned int irq)
GEDR0 = (1 << (irq - IRQ_GPIO0));
}
+static int pxa_set_gpio_wake(unsigned int irq, unsigned int on)
+{
+ int gpio = IRQ_TO_GPIO(irq);
+ u32 mask = WAKEMASK(gpio);
+
+ if (!mask)
+ return -EINVAL;
+
+ if (on)
+ PWER |= mask;
+ else
+ PWER &= ~mask;
+ return 0;
+}
+
+
static struct irq_chip pxa_low_gpio_chip = {
.name = "GPIO-l",
.ack = pxa_ack_low_gpio,
.mask = pxa_mask_low_irq,
.unmask = pxa_unmask_low_irq,
.set_type = pxa_gpio_irq_type,
+ .set_wake = pxa_set_gpio_wake,
};
/*
@@ -245,6 +311,7 @@ static struct irq_chip pxa_muxed_gpio_chip = {
.mask = pxa_mask_muxed_gpio,
.unmask = pxa_unmask_muxed_gpio,
.set_type = pxa_gpio_irq_type,
+ .set_wake = pxa_set_gpio_wake,
};
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index 8e27a64..e309766 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -234,7 +234,7 @@ static void lpd270_backlight_power(int on)
{
if (on) {
pxa_gpio_mode(GPIO16_PWM0_MD);
- pxa_set_cken(CKEN0_PWM0, 1);
+ pxa_set_cken(CKEN_PWM0, 1);
PWM_CTRL0 = 0;
PWM_PWDUTY0 = 0x3ff;
PWM_PERVAL0 = 0x3ff;
@@ -242,7 +242,7 @@ static void lpd270_backlight_power(int on)
PWM_CTRL0 = 0;
PWM_PWDUTY0 = 0x0;
PWM_PERVAL0 = 0x3FF;
- pxa_set_cken(CKEN0_PWM0, 0);
+ pxa_set_cken(CKEN_PWM0, 0);
}
}
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 055de7f..6377b2e 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -220,7 +220,7 @@ static struct resource pxa_ssp_resources[] = {
static struct pxa2xx_spi_master pxa_ssp_master_info = {
.ssp_type = PXA25x_SSP,
- .clock_enable = CKEN3_SSP,
+ .clock_enable = CKEN_SSP,
.num_chipselect = 0,
};
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 56d94d8..ed99a81 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -266,7 +266,7 @@ static void mainstone_backlight_power(int on)
{
if (on) {
pxa_gpio_mode(GPIO16_PWM0_MD);
- pxa_set_cken(CKEN0_PWM0, 1);
+ pxa_set_cken(CKEN_PWM0, 1);
PWM_CTRL0 = 0;
PWM_PWDUTY0 = 0x3ff;
PWM_PERVAL0 = 0x3ff;
@@ -274,7 +274,7 @@ static void mainstone_backlight_power(int on)
PWM_CTRL0 = 0;
PWM_PWDUTY0 = 0x0;
PWM_PERVAL0 = 0x3FF;
- pxa_set_cken(CKEN0_PWM0, 0);
+ pxa_set_cken(CKEN_PWM0, 0);
}
}
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 74eeada..c64bab4 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -140,9 +140,9 @@ void pxa_cpu_pm_enter(suspend_state_t state)
extern void pxa_cpu_resume(void);
if (state == PM_SUSPEND_STANDBY)
- CKEN = CKEN22_MEMC | CKEN9_OSTIMER | CKEN16_LCD |CKEN0_PWM0;
+ CKEN = CKEN_MEMC | CKEN_OSTIMER | CKEN_LCD | CKEN_PWM0;
else
- CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
+ CKEN = CKEN_MEMC | CKEN_OSTIMER;
/* ensure voltage-change sequencer not initiated, which hangs */
PCFR &= ~PCFR_FVC;
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index 6cc2027..71766ac 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -52,13 +52,13 @@ struct ssp_info_ {
*/
static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = {
#if defined (CONFIG_PXA27x)
- {IRQ_SSP, CKEN23_SSP1},
- {IRQ_SSP2, CKEN3_SSP2},
- {IRQ_SSP3, CKEN4_SSP3},
+ {IRQ_SSP, CKEN_SSP1},
+ {IRQ_SSP2, CKEN_SSP2},
+ {IRQ_SSP3, CKEN_SSP3},
#else
- {IRQ_SSP, CKEN3_SSP},
- {IRQ_NSSP, CKEN9_NSSP},
- {IRQ_ASSP, CKEN10_ASSP},
+ {IRQ_SSP, CKEN_SSP},
+ {IRQ_NSSP, CKEN_NSSP},
+ {IRQ_ASSP, CKEN_ASSP},
#endif
};
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index fc3b82a..5248abe 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -97,7 +97,7 @@ pxa_timer_interrupt(int irq, void *dev_id)
static struct irqaction pxa_timer_irq = {
.name = "PXA Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = pxa_timer_interrupt,
};
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 84d3fe7..c7f1b44 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -549,7 +549,7 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id)
static struct irqaction realview_timer_irq = {
.name = "RealView Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = realview_timer_interrupt,
};
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
index 208a2b5..570cf93 100644
--- a/arch/arm/mach-rpc/riscpc.c
+++ b/arch/arm/mach-rpc/riscpc.c
@@ -17,6 +17,7 @@
#include <linux/sched.h>
#include <linux/device.h>
#include <linux/serial_8250.h>
+#include <linux/pata_platform.h>
#include <asm/elf.h>
#include <asm/io.h>
@@ -159,11 +160,45 @@ static struct platform_device serial_device = {
},
};
+static struct pata_platform_info pata_platform_data = {
+ .ioport_shift = 2,
+};
+
+static struct resource pata_resources[] = {
+ [0] = {
+ .start = 0x030107c0,
+ .end = 0x030107df,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0x03010fd8,
+ .end = 0x03010fdb,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_HARDDISK,
+ .end = IRQ_HARDDISK,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pata_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pata_resources),
+ .resource = pata_resources,
+ .dev = {
+ .platform_data = &pata_platform_data,
+ .coherent_dma_mask = ~0, /* grumble */
+ },
+};
+
static struct platform_device *devs[] __initdata = {
&iomd_device,
&kbd_device,
&serial_device,
&acornfb_device,
+ &pata_device,
};
static int __init rpc_init(void)
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
index daeba42..76a7cb1 100644
--- a/arch/arm/mach-s3c2410/bast-irq.c
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -24,7 +24,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ioport.h>
-#include <linux/ptrace.h>
#include <linux/sysdev.h>
#include <asm/mach-types.h>
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
index 53cbdaa..f5c5c53 100644
--- a/arch/arm/mach-s3c2410/irq.c
+++ b/arch/arm/mach-s3c2410/irq.c
@@ -23,7 +23,6 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/ptrace.h>
#include <linux/sysdev.h>
#include <asm/plat-s3c24xx/cpu.h>
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index 72f2cc4..bc308ce 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -160,17 +160,11 @@ static struct platform_device *amlm5900_devices[] __initdata = {
#endif
};
-static struct s3c24xx_board amlm5900_board __initdata = {
- .devices = amlm5900_devices,
- .devices_count = ARRAY_SIZE(amlm5900_devices)
-};
-
void __init amlm5900_map_io(void)
{
s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs));
- s3c24xx_set_board(&amlm5900_board);
}
#ifdef CONFIG_FB_S3C2410
@@ -247,6 +241,7 @@ static void __init amlm5900_init(void)
#ifdef CONFIG_FB_S3C2410
s3c24xx_fb_set_platdata(&amlm5900_lcd_info);
#endif
+ platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices));
}
MACHINE_START(AML_M5900, "AML_M5900")
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 7b81296..f01de80 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -464,13 +464,6 @@ static struct clk *bast_clocks[] = {
&s3c24xx_uclk,
};
-static struct s3c24xx_board bast_board __initdata = {
- .devices = bast_devices,
- .devices_count = ARRAY_SIZE(bast_devices),
- .clocks = bast_clocks,
- .clocks_count = ARRAY_SIZE(bast_clocks),
-};
-
static void __init bast_map_io(void)
{
/* initialise the clocks */
@@ -486,19 +479,22 @@ static void __init bast_map_io(void)
s3c24xx_uclk.parent = &s3c24xx_clkout1;
+ s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks));
+
s3c_device_nand.dev.platform_data = &bast_nand_info;
s3c_device_i2c.dev.platform_data = &bast_i2c_info;
s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
- s3c24xx_set_board(&bast_board);
+
usb_simtec_init();
}
static void __init bast_init(void)
{
s3c24xx_fb_set_platdata(&bast_lcd_info);
+ platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices));
}
MACHINE_START(BAST, "Simtec-BAST")
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index d052ab2..5d5f00e 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -129,7 +129,6 @@ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
};
-
/**
* Set lcd on or off
**/
@@ -188,17 +187,11 @@ static struct platform_device *h1940_devices[] __initdata = {
&s3c_device_leds,
};
-static struct s3c24xx_board h1940_board __initdata = {
- .devices = h1940_devices,
- .devices_count = ARRAY_SIZE(h1940_devices)
-};
-
static void __init h1940_map_io(void)
{
s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
- s3c24xx_set_board(&h1940_board);
/* setup PM */
@@ -232,6 +225,8 @@ static void __init h1940_init(void)
| (0x02 << S3C2410_PLLCON_PDIVSHIFT)
| (0x03 << S3C2410_PLLCON_SDIVSHIFT);
writel(tmp, S3C2410_UPLLCON);
+
+ platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
}
MACHINE_START(H1940, "IPAQ-H1940")
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 261aa4c..412e50c 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -90,17 +90,11 @@ static struct s3c2410_platform_i2c n30_i2ccfg = {
.max_freq = 10*1000,
};
-static struct s3c24xx_board n30_board __initdata = {
- .devices = n30_devices,
- .devices_count = ARRAY_SIZE(n30_devices)
-};
-
static void __init n30_map_io(void)
{
s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
- s3c24xx_set_board(&n30_board);
}
static void __init n30_init_irq(void)
@@ -120,6 +114,8 @@ static void __init n30_init(void)
s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
S3C2410_MISCCR_USBSUSPND0 |
S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+ platform_add_devices(n30_devices, ARRAY_SIZE(n30_devices));
}
MACHINE_START(N30, "Acer-N30")
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
index c78ab75..1f899fa 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -100,20 +100,17 @@ static struct platform_device *otom11_devices[] __initdata = {
&otom_device_nor,
};
-static struct s3c24xx_board otom11_board __initdata = {
- .devices = otom11_devices,
- .devices_count = ARRAY_SIZE(otom11_devices)
-};
-
-
static void __init otom11_map_io(void)
{
s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs));
- s3c24xx_set_board(&otom11_board);
}
+static void __init otom11_init(void)
+{
+ platform_add_devices(otom11_devices, ARRAY_SIZE(otom11_devices));
+}
MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
@@ -121,6 +118,7 @@ MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = otom11_map_io,
+ .init_machine = otom11_init,
.init_irq = s3c24xx_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
index c6a4159..9cc4253 100644
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -29,7 +29,6 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>
-#include <linux/mmc/protocol.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
@@ -331,11 +330,6 @@ static struct platform_device *qt2410_devices[] __initdata = {
&qt2410_led,
};
-static struct s3c24xx_board qt2410_board __initdata = {
- .devices = qt2410_devices,
- .devices_count = ARRAY_SIZE(qt2410_devices)
-};
-
static struct mtd_partition qt2410_nand_part[] = {
[0] = {
.name = "U-Boot",
@@ -405,7 +399,6 @@ static void __init qt2410_map_io(void)
s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
s3c24xx_init_clocks(12*1000*1000);
s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
- s3c24xx_set_board(&qt2410_board);
}
static void __init qt2410_machine_init(void)
@@ -432,6 +425,7 @@ static void __init qt2410_machine_init(void)
s3c2410_gpio_cfgpin(S3C2410_GPB5, S3C2410_GPIO_OUTPUT);
+ platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
s3c2410_pm_init();
}
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index 57b8a80..5852d30 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -94,17 +94,17 @@ static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_iis,
};
-static struct s3c24xx_board smdk2410_board __initdata = {
- .devices = smdk2410_devices,
- .devices_count = ARRAY_SIZE(smdk2410_devices)
-};
-
static void __init smdk2410_map_io(void)
{
s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
- s3c24xx_set_board(&smdk2410_board);
+}
+
+static void __init smdk2410_init(void)
+{
+ platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));
+ smdk_machine_init();
}
MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
@@ -115,7 +115,7 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = smdk2410_map_io,
.init_irq = s3c24xx_init_irq,
- .init_machine = smdk_machine_init,
+ .init_machine = smdk2410_init,
.timer = &s3c24xx_timer,
MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index c947c75..7b624bb 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -384,13 +384,6 @@ static struct clk *vr1000_clocks[] = {
&s3c24xx_uclk,
};
-static struct s3c24xx_board vr1000_board __initdata = {
- .devices = vr1000_devices,
- .devices_count = ARRAY_SIZE(vr1000_devices),
- .clocks = vr1000_clocks,
- .clocks_count = ARRAY_SIZE(vr1000_clocks),
-};
-
static void vr1000_power_off(void)
{
s3c2410_gpio_cfgpin(S3C2410_GPB9, S3C2410_GPB9_OUTP);
@@ -412,15 +405,19 @@ static void __init vr1000_map_io(void)
s3c24xx_uclk.parent = &s3c24xx_clkout1;
+ s3c24xx_register_clocks(vr1000_clocks, ARRAY_SIZE(vr1000_clocks));
+
pm_power_off = vr1000_power_off;
s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
- s3c24xx_set_board(&vr1000_board);
- usb_simtec_init();
}
+static void __init vr1000_init(void)
+{
+ platform_add_devices(vr1000_devices, ARRAY_SIZE(vr1000_devices));
+}
MACHINE_START(VR1000, "Thorcom-VR1000")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
@@ -428,6 +425,7 @@ MACHINE_START(VR1000, "Thorcom-VR1000")
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = vr1000_map_io,
+ .init_machine = vr1000_init,
.init_irq = s3c24xx_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index befc5fd..d5be5d0 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -47,6 +47,15 @@ config MACH_S3C2413
machine_is_s3c2413() will work when MACH_SMDK2413 is
selected
+config MACH_SMDK2412
+ bool "SMDK2412"
+ select MACH_SMDK2413
+ help
+ Say Y here if you are using an SMDK2412
+
+ Note, this shares support with SMDK2413, so will automatically
+ select MACH_SMDK2413.
+
config MACH_VSTMS
bool "VMSTMS"
select CPU_S3C2412
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index e89dbdc..f0d6682 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -23,7 +23,6 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/ptrace.h>
#include <linux/sysdev.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
index b5befce..063af09 100644
--- a/arch/arm/mach-s3c2412/mach-smdk2413.c
+++ b/arch/arm/mach-s3c2412/mach-smdk2413.c
@@ -110,11 +110,6 @@ static struct platform_device *smdk2413_devices[] __initdata = {
&s3c_device_usbgadget,
};
-static struct s3c24xx_board smdk2413_board __initdata = {
- .devices = smdk2413_devices,
- .devices_count = ARRAY_SIZE(smdk2413_devices)
-};
-
static void __init smdk2413_fixup(struct machine_desc *desc,
struct tag *tags, char **cmdline,
struct meminfo *mi)
@@ -132,7 +127,6 @@ static void __init smdk2413_map_io(void)
s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs));
- s3c24xx_set_board(&smdk2413_board);
}
static void __init smdk2413_machine_init(void)
@@ -149,6 +143,7 @@ static void __init smdk2413_machine_init(void)
s3c24xx_udc_set_platdata(&smdk2413_udc_cfg);
+ platform_add_devices(smdk2413_devices, ARRAY_SIZE(smdk2413_devices));
smdk_machine_init();
}
diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c
index 4231b54..f2fbd65 100644
--- a/arch/arm/mach-s3c2412/mach-vstms.c
+++ b/arch/arm/mach-s3c2412/mach-vstms.c
@@ -129,11 +129,6 @@ static struct platform_device *vstms_devices[] __initdata = {
&s3c_device_nand,
};
-static struct s3c24xx_board vstms_board __initdata = {
- .devices = vstms_devices,
- .devices_count = ARRAY_SIZE(vstms_devices)
-};
-
static void __init vstms_fixup(struct machine_desc *desc,
struct tag *tags, char **cmdline,
struct meminfo *mi)
@@ -153,7 +148,11 @@ static void __init vstms_map_io(void)
s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
- s3c24xx_set_board(&vstms_board);
+}
+
+static void __init vstms_init(void)
+{
+ platform_add_devices(vstms_devices, ARRAY_SIZE(vstms_devices));
}
MACHINE_START(VSTMS, "VSTMS")
@@ -163,6 +162,7 @@ MACHINE_START(VSTMS, "VSTMS")
.fixup = vstms_fixup,
.init_irq = s3c24xx_init_irq,
+ .init_machine = vstms_init,
.map_io = vstms_map_io,
.timer = &s3c24xx_timer,
MACHINE_END
diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c
index 1069d13..a87608b 100644
--- a/arch/arm/mach-s3c2440/irq.c
+++ b/arch/arm/mach-s3c2440/irq.c
@@ -23,7 +23,6 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/ptrace.h>
#include <linux/sysdev.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
index 3f0288e..b5d387e 100644
--- a/arch/arm/mach-s3c2440/mach-anubis.c
+++ b/arch/arm/mach-s3c2440/mach-anubis.c
@@ -281,13 +281,6 @@ static struct clk *anubis_clocks[] = {
&s3c24xx_uclk,
};
-static struct s3c24xx_board anubis_board __initdata = {
- .devices = anubis_devices,
- .devices_count = ARRAY_SIZE(anubis_devices),
- .clocks = anubis_clocks,
- .clocks_count = ARRAY_SIZE(anubis_clocks),
-};
-
static void __init anubis_map_io(void)
{
/* initialise the clocks */
@@ -303,23 +296,31 @@ static void __init anubis_map_io(void)
s3c24xx_uclk.parent = &s3c24xx_clkout1;
+ s3c24xx_register_clocks(anubis_clocks, ARRAY_SIZE(anubis_clocks));
+
s3c_device_nand.dev.platform_data = &anubis_nand_info;
s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
- s3c24xx_set_board(&anubis_board);
/* ensure that the GPIO is setup */
s3c2410_gpio_setpin(S3C2410_GPA0, 1);
}
+static void __init anubis_init(void)
+{
+ platform_add_devices(anubis_devices, ARRAY_SIZE(anubis_devices));
+}
+
+
MACHINE_START(ANUBIS, "Simtec-Anubis")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = anubis_map_io,
+ .init_machine = anubis_init,
.init_irq = s3c24xx_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c
index 6d551d8..5e61f21 100644
--- a/arch/arm/mach-s3c2440/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2440/mach-nexcoder.c
@@ -116,12 +116,6 @@ static struct platform_device *nexcoder_devices[] __initdata = {
&nexcoder_device_nor,
};
-static struct s3c24xx_board nexcoder_board __initdata = {
- .devices = nexcoder_devices,
- .devices_count = ARRAY_SIZE(nexcoder_devices),
-};
-
-
static void __init nexcoder_sensorboard_init(void)
{
// Initialize SCCB bus
@@ -142,10 +136,14 @@ static void __init nexcoder_map_io(void)
s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs));
- s3c24xx_set_board(&nexcoder_board);
+
nexcoder_sensorboard_init();
}
+static void __init nexcoder_init(void)
+{
+ platform_add_devices(nexcoder_devices, ARRAY_SIZE(nexcoder_devices));
+};
MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
@@ -153,6 +151,7 @@ MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = nexcoder_map_io,
+ .init_machine = nexcoder_init,
.init_irq = s3c24xx_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index 2ed8e51..324f5a2 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -251,13 +251,6 @@ static struct clk *osiris_clocks[] = {
&s3c24xx_uclk,
};
-static struct s3c24xx_board osiris_board __initdata = {
- .devices = osiris_devices,
- .devices_count = ARRAY_SIZE(osiris_devices),
- .clocks = osiris_clocks,
- .clocks_count = ARRAY_SIZE(osiris_clocks),
-};
-
static void __init osiris_map_io(void)
{
unsigned long flags;
@@ -275,12 +268,13 @@ static void __init osiris_map_io(void)
s3c24xx_uclk.parent = &s3c24xx_clkout1;
+ s3c24xx_register_clocks(osiris_clocks, ARRAY_SIZE(osiris_clocks));
+
s3c_device_nand.dev.platform_data = &osiris_nand_info;
s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
- s3c24xx_set_board(&osiris_board);
/* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */
@@ -292,12 +286,18 @@ static void __init osiris_map_io(void)
s3c2410_gpio_setpin(S3C2410_GPA0, 1);
}
+static void __init osiris_init(void)
+{
+ platform_add_devices(osiris_devices, ARRAY_SIZE(osiris_devices));
+};
+
MACHINE_START(OSIRIS, "Simtec-OSIRIS")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = osiris_map_io,
+ .init_machine = osiris_init,
.init_irq = s3c24xx_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index ae1d0a8..c3cc4bf 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -202,11 +202,6 @@ static struct platform_device *rx3715_devices[] __initdata = {
&s3c_device_nand,
};
-static struct s3c24xx_board rx3715_board __initdata = {
- .devices = rx3715_devices,
- .devices_count = ARRAY_SIZE(rx3715_devices)
-};
-
static void __init rx3715_map_io(void)
{
s3c_device_nand.dev.platform_data = &rx3715_nand_info;
@@ -214,7 +209,6 @@ static void __init rx3715_map_io(void)
s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
s3c24xx_init_clocks(16934000);
s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
- s3c24xx_set_board(&rx3715_board);
}
static void __init rx3715_init_irq(void)
@@ -230,9 +224,9 @@ static void __init rx3715_init_machine(void)
s3c2410_pm_init();
s3c24xx_fb_set_platdata(&rx3715_lcdcfg);
+ platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices));
}
-
MACHINE_START(RX3715, "IPAQ-RX3715")
/* Maintainer: Ben Dooks <ben@fluff.org> */
.phys_io = S3C2410_PA_UART,
diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c
index c17eb5b..e167254 100644
--- a/arch/arm/mach-s3c2440/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2440/mach-smdk2440.c
@@ -174,23 +174,18 @@ static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_iis,
};
-static struct s3c24xx_board smdk2440_board __initdata = {
- .devices = smdk2440_devices,
- .devices_count = ARRAY_SIZE(smdk2440_devices)
-};
-
static void __init smdk2440_map_io(void)
{
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
s3c24xx_init_clocks(16934400);
s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
- s3c24xx_set_board(&smdk2440_board);
}
static void __init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg);
+ platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
}
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
index 7565735..6cd4818 100644
--- a/arch/arm/mach-s3c2443/irq.c
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -23,7 +23,6 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/ptrace.h>
#include <linux/sysdev.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c
index e82aaff..b71ee53 100644
--- a/arch/arm/mach-s3c2443/mach-smdk2443.c
+++ b/arch/arm/mach-s3c2443/mach-smdk2443.c
@@ -106,21 +106,16 @@ static struct platform_device *smdk2443_devices[] __initdata = {
&s3c_device_i2c,
};
-static struct s3c24xx_board smdk2443_board __initdata = {
- .devices = smdk2443_devices,
- .devices_count = ARRAY_SIZE(smdk2443_devices)
-};
-
static void __init smdk2443_map_io(void)
{
s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
- s3c24xx_set_board(&smdk2443_board);
}
static void __init smdk2443_machine_init(void)
{
+ platform_add_devices(smdk2443_devices, ARRAY_SIZE(smdk2443_devices));
smdk_machine_init();
}
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index b1e8fd7..fc97fe5 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -9,14 +9,17 @@
#include <linux/string.h>
#include <linux/clk.h>
#include <linux/spinlock.h>
+#include <linux/mutex.h>
#include <asm/hardware.h>
-#include <asm/semaphore.h>
+/*
+ * Very simple clock implementation - we only have one clock to
+ * deal with at the moment, so we only match using the "name".
+ */
struct clk {
struct list_head node;
unsigned long rate;
- struct module *owner;
const char *name;
unsigned int enabled;
void (*enable)(void);
@@ -24,21 +27,21 @@ struct clk {
};
static LIST_HEAD(clocks);
-static DECLARE_MUTEX(clocks_sem);
+static DEFINE_MUTEX(clocks_mutex);
static DEFINE_SPINLOCK(clocks_lock);
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
- if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+ if (strcmp(id, p->name) == 0) {
clk = p;
break;
}
}
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return clk;
}
@@ -46,7 +49,6 @@ EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
{
- module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
@@ -109,18 +111,18 @@ static struct clk clk_gpio27 = {
int clk_register(struct clk *clk)
{
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_add(&clk->node, &clocks);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister(struct clk *clk)
{
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_del(&clk->node);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
}
EXPORT_SYMBOL(clk_unregister);
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index b034ad6..b72fee0 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -740,7 +740,7 @@ static void h3800_IRQ_demux(unsigned int irq, struct irq_desc *desc)
static struct irqaction h3800_irq = {
.name = "h3800_asic",
.handler = h3800_IRQ_demux,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
};
u32 kpio_int_shadow = 0;
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 5642aec..edf3347 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -14,7 +14,6 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/ioport.h>
-#include <linux/ptrace.h>
#include <linux/sysdev.h>
#include <asm/hardware.h>
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 075d4d1..d7c038a 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -4,7 +4,6 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/ptrace.h>
#include <linux/tty.h>
#include <linux/ioport.h>
#include <linux/serial_core.h>
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index 29c89f9..416e277 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -111,7 +111,7 @@ sa1100_timer_interrupt(int irq, void *dev_id)
static struct irqaction sa1100_timer_irq = {
.name = "SA11xx Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = sa1100_timer_interrupt,
};
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index 0e480fa..a0545db 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -90,7 +90,7 @@ shark_timer_interrupt(int irq, void *dev_id)
static struct irqaction shark_timer_irq = {
.name = "Shark Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = shark_timer_interrupt,
};
diff --git a/arch/arm/mach-shark/irq.c b/arch/arm/mach-shark/irq.c
index 00a6c14..5b0c6af 100644
--- a/arch/arm/mach-shark/irq.c
+++ b/arch/arm/mach-shark/irq.c
@@ -10,7 +10,6 @@
#include <linux/init.h>
#include <linux/fs.h>
-#include <linux/ptrace.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index bf71507..a7dd094 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -26,6 +26,8 @@
#include <linux/interrupt.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
#include <asm/cnt32_to_63.h>
#include <asm/system.h>
@@ -828,69 +830,101 @@ void __init versatile_init(void)
#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
#endif
-/*
- * Returns number of ms since last clock interrupt. Note that interrupts
- * will have been disabled by do_gettimeoffset()
- */
-static unsigned long versatile_gettimeoffset(void)
+static void timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *clk)
{
- unsigned long ticks1, ticks2, status;
+ unsigned long ctrl;
- /*
- * Get the current number of ticks. Note that there is a race
- * condition between us reading the timer and checking for
- * an interrupt. We get around this by ensuring that the
- * counter has not reloaded between our two reads.
- */
- ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
- do {
- ticks1 = ticks2;
- status = __raw_readl(VA_IC_BASE + VIC_RAW_STATUS);
- ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
- } while (ticks2 > ticks1);
+ switch(mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
- /*
- * Number of ticks since last interrupt.
- */
- ticks1 = TIMER_RELOAD - ticks2;
+ ctrl = TIMER_CTRL_PERIODIC;
+ ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE;
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* period set, and timer enabled in 'next_event' hook */
+ ctrl = TIMER_CTRL_ONESHOT;
+ ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE;
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ default:
+ ctrl = 0;
+ }
- /*
- * Interrupt pending? If so, we've reloaded once already.
- *
- * FIXME: Need to check this is effectively timer 0 that expires
- */
- if (status & IRQMASK_TIMERINT0_1)
- ticks1 += TIMER_RELOAD;
+ writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL);
+}
- /*
- * Convert the ticks to usecs
- */
- return TICKS2USECS(ticks1);
+static int timer_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL);
+
+ writel(evt, TIMER0_VA_BASE + TIMER_LOAD);
+ writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL);
+
+ return 0;
}
+static struct clock_event_device timer0_clockevent = {
+ .name = "timer0",
+ .shift = 32,
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = timer_set_mode,
+ .set_next_event = timer_set_next_event,
+};
+
/*
* IRQ handler for the timer
*/
static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id)
{
- write_seqlock(&xtime_lock);
+ struct clock_event_device *evt = &timer0_clockevent;
- // ...clear the interrupt
writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
- timer_tick();
-
- write_sequnlock(&xtime_lock);
+ evt->event_handler(evt);
return IRQ_HANDLED;
}
static struct irqaction versatile_timer_irq = {
.name = "Versatile Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = versatile_timer_interrupt,
};
+static cycle_t versatile_get_cycles(void)
+{
+ return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
+}
+
+static struct clocksource clocksource_versatile = {
+ .name = "timer3",
+ .rating = 200,
+ .read = versatile_get_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 20,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init versatile_clocksource_init(void)
+{
+ /* setup timer3 as free-running clocksource */
+ writel(0, TIMER3_VA_BASE + TIMER_CTRL);
+ writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD);
+ writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE);
+ writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
+ TIMER3_VA_BASE + TIMER_CTRL);
+
+ clocksource_versatile.mult =
+ clocksource_khz2mult(1000, clocksource_versatile.shift);
+ clocksource_register(&clocksource_versatile);
+
+ return 0;
+}
+
/*
* Set up timer interrupt, and return the current time in seconds.
*/
@@ -918,18 +952,25 @@ static void __init versatile_timer_init(void)
writel(0, TIMER2_VA_BASE + TIMER_CTRL);
writel(0, TIMER3_VA_BASE + TIMER_CTRL);
- writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
- writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE);
- writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC |
- TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL);
-
/*
* Make irqs happen for the system timer
*/
setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq);
+
+ versatile_clocksource_init();
+
+ timer0_clockevent.mult =
+ div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
+ timer0_clockevent.max_delta_ns =
+ clockevent_delta2ns(0xffffffff, &timer0_clockevent);
+ timer0_clockevent.min_delta_ns =
+ clockevent_delta2ns(0xf, &timer0_clockevent);
+
+ timer0_clockevent.cpumask = cpumask_of_cpu(0);
+ clockevents_register_device(&timer0_clockevent);
}
struct sys_timer versatile_timer = {
.init = versatile_timer_init,
- .offset = versatile_gettimeoffset,
};
+
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
index 5cd0b5d..ba58223 100644
--- a/arch/arm/mach-versatile/pci.c
+++ b/arch/arm/mach-versatile/pci.c
@@ -16,7 +16,6 @@
*/
#include <linux/kernel.h>
#include <linux/pci.h>
-#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index aa109f0..19ca333 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -15,7 +15,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
-#include <linux/ptrace.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 9fd6d2e..75d4914 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -10,7 +10,6 @@
*/
#include <linux/module.h>
#include <linux/signal.h>
-#include <linux/ptrace.h>
#include <linux/mm.h>
#include <linux/init.h>
@@ -438,7 +437,7 @@ hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *)
/*
* Dispatch a data abort to the relevant handler.
*/
-asmlinkage void
+asmlinkage void __exception
do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6);
@@ -454,10 +453,10 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
info.si_errno = 0;
info.si_code = inf->code;
info.si_addr = (void __user *)addr;
- notify_die("", regs, &info, fsr, 0);
+ arm_notify_die("", regs, &info, fsr, 0);
}
-asmlinkage void
+asmlinkage void __exception
do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
{
do_translation_fault(addr, 0, regs);
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 7760193..c0ad7c0 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -9,7 +9,6 @@
*/
#include <linux/kernel.h>
#include <linux/errno.h>
-#include <linux/ptrace.h>
#include <linux/swap.h>
#include <linux/init.h>
#include <linux/bootmem.h>
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 0ac615c..d6167ad 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -32,6 +32,9 @@
#include <asm/tlbflush.h>
#include <asm/sizes.h>
+#include <asm/mach/map.h>
+#include "mm.h"
+
/*
* Used by ioremap() and iounmap() code to mark (super)section-mapped
* I/O regions in vm_struct->flags field.
@@ -39,8 +42,9 @@
#define VM_ARM_SECTION_MAPPING 0x80000000
static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end,
- unsigned long phys_addr, pgprot_t prot)
+ unsigned long phys_addr, const struct mem_type *type)
{
+ pgprot_t prot = __pgprot(type->prot_pte);
pte_t *pte;
pte = pte_alloc_kernel(pmd, addr);
@@ -51,7 +55,8 @@ static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end,
if (!pte_none(*pte))
goto bad;
- set_pte_ext(pte, pfn_pte(phys_addr >> PAGE_SHIFT, prot), 0);
+ set_pte_ext(pte, pfn_pte(phys_addr >> PAGE_SHIFT, prot),
+ type->prot_pte_ext);
phys_addr += PAGE_SIZE;
} while (pte++, addr += PAGE_SIZE, addr != end);
return 0;
@@ -63,7 +68,7 @@ static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end,
static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr,
unsigned long end, unsigned long phys_addr,
- pgprot_t prot)
+ const struct mem_type *type)
{
unsigned long next;
pmd_t *pmd;
@@ -75,7 +80,7 @@ static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr,
do {
next = pmd_addr_end(addr, end);
- ret = remap_area_pte(pmd, addr, next, phys_addr, prot);
+ ret = remap_area_pte(pmd, addr, next, phys_addr, type);
if (ret)
return ret;
phys_addr += next - addr;
@@ -84,13 +89,11 @@ static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr,
}
static int remap_area_pages(unsigned long start, unsigned long pfn,
- unsigned long size, unsigned long flags)
+ size_t size, const struct mem_type *type)
{
unsigned long addr = start;
unsigned long next, end = start + size;
unsigned long phys_addr = __pfn_to_phys(pfn);
- pgprot_t prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
- L_PTE_DIRTY | L_PTE_WRITE | flags);
pgd_t *pgd;
int err = 0;
@@ -98,7 +101,7 @@ static int remap_area_pages(unsigned long start, unsigned long pfn,
pgd = pgd_offset_k(addr);
do {
next = pgd_addr_end(addr, end);
- err = remap_area_pmd(pgd, addr, next, phys_addr, prot);
+ err = remap_area_pmd(pgd, addr, next, phys_addr, type);
if (err)
break;
phys_addr += next - addr;
@@ -178,9 +181,9 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
static int
remap_area_sections(unsigned long virt, unsigned long pfn,
- unsigned long size, unsigned long flags)
+ size_t size, const struct mem_type *type)
{
- unsigned long prot, addr = virt, end = virt + size;
+ unsigned long addr = virt, end = virt + size;
pgd_t *pgd;
/*
@@ -189,23 +192,13 @@ remap_area_sections(unsigned long virt, unsigned long pfn,
*/
unmap_area_sections(virt, size);
- prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO) |
- (flags & (L_PTE_CACHEABLE | L_PTE_BUFFERABLE));
-
- /*
- * ARMv6 and above need XN set to prevent speculative prefetches
- * hitting IO.
- */
- if (cpu_architecture() >= CPU_ARCH_ARMv6)
- prot |= PMD_SECT_XN;
-
pgd = pgd_offset_k(addr);
do {
pmd_t *pmd = pmd_offset(pgd, addr);
- pmd[0] = __pmd(__pfn_to_phys(pfn) | prot);
+ pmd[0] = __pmd(__pfn_to_phys(pfn) | type->prot_sect);
pfn += SZ_1M >> PAGE_SHIFT;
- pmd[1] = __pmd(__pfn_to_phys(pfn) | prot);
+ pmd[1] = __pmd(__pfn_to_phys(pfn) | type->prot_sect);
pfn += SZ_1M >> PAGE_SHIFT;
flush_pmd_entry(pmd);
@@ -218,9 +211,9 @@ remap_area_sections(unsigned long virt, unsigned long pfn,
static int
remap_area_supersections(unsigned long virt, unsigned long pfn,
- unsigned long size, unsigned long flags)
+ size_t size, const struct mem_type *type)
{
- unsigned long prot, addr = virt, end = virt + size;
+ unsigned long addr = virt, end = virt + size;
pgd_t *pgd;
/*
@@ -229,22 +222,12 @@ remap_area_supersections(unsigned long virt, unsigned long pfn,
*/
unmap_area_sections(virt, size);
- prot = PMD_TYPE_SECT | PMD_SECT_SUPER | PMD_SECT_AP_WRITE |
- PMD_DOMAIN(DOMAIN_IO) |
- (flags & (L_PTE_CACHEABLE | L_PTE_BUFFERABLE));
-
- /*
- * ARMv6 and above need XN set to prevent speculative prefetches
- * hitting IO.
- */
- if (cpu_architecture() >= CPU_ARCH_ARMv6)
- prot |= PMD_SECT_XN;
-
pgd = pgd_offset_k(virt);
do {
unsigned long super_pmd_val, i;
- super_pmd_val = __pfn_to_phys(pfn) | prot;
+ super_pmd_val = __pfn_to_phys(pfn) | type->prot_sect |
+ PMD_SECT_SUPER;
super_pmd_val |= ((pfn >> (32 - PAGE_SHIFT)) & 0xf) << 20;
for (i = 0; i < 8; i++) {
@@ -279,9 +262,10 @@ remap_area_supersections(unsigned long virt, unsigned long pfn,
* mapping. See include/asm-arm/proc-armv/pgtable.h for more information.
*/
void __iomem *
-__ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
- unsigned long flags)
+__arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
+ unsigned int mtype)
{
+ const struct mem_type *type;
int err;
unsigned long addr;
struct vm_struct * area;
@@ -292,6 +276,10 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK))
return NULL;
+ type = get_mem_type(mtype);
+ if (!type)
+ return NULL;
+
size = PAGE_ALIGN(size);
area = get_vm_area(size, VM_IOREMAP);
@@ -302,16 +290,16 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
#ifndef CONFIG_SMP
if (DOMAIN_IO == 0 &&
(((cpu_architecture() >= CPU_ARCH_ARMv6) && (get_cr() & CR_XP)) ||
- cpu_is_xsc3()) &&
+ cpu_is_xsc3()) && pfn >= 0x100000 &&
!((__pfn_to_phys(pfn) | size | addr) & ~SUPERSECTION_MASK)) {
area->flags |= VM_ARM_SECTION_MAPPING;
- err = remap_area_supersections(addr, pfn, size, flags);
+ err = remap_area_supersections(addr, pfn, size, type);
} else if (!((__pfn_to_phys(pfn) | size | addr) & ~PMD_MASK)) {
area->flags |= VM_ARM_SECTION_MAPPING;
- err = remap_area_sections(addr, pfn, size, flags);
+ err = remap_area_sections(addr, pfn, size, type);
} else
#endif
- err = remap_area_pages(addr, pfn, size, flags);
+ err = remap_area_pages(addr, pfn, size, type);
if (err) {
vunmap((void *)addr);
@@ -321,10 +309,10 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
flush_cache_vmap(addr, addr + size);
return (void __iomem *) (offset + addr);
}
-EXPORT_SYMBOL(__ioremap_pfn);
+EXPORT_SYMBOL(__arm_ioremap_pfn);
void __iomem *
-__ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
+__arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
{
unsigned long last_addr;
unsigned long offset = phys_addr & ~PAGE_MASK;
@@ -342,9 +330,9 @@ __ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
*/
size = PAGE_ALIGN(last_addr + 1) - phys_addr;
- return __ioremap_pfn(pfn, offset, size, flags);
+ return __arm_ioremap_pfn(pfn, offset, size, mtype);
}
-EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(__arm_ioremap);
void __iounmap(volatile void __iomem *addr)
{
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index a44e309..7647c59 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -16,6 +16,16 @@ static inline pmd_t *pmd_off_k(unsigned long virt)
return pmd_off(pgd_offset_k(virt), virt);
}
+struct mem_type {
+ unsigned int prot_pte;
+ unsigned int prot_pte_ext;
+ unsigned int prot_l1;
+ unsigned int prot_sect;
+ unsigned int domain;
+};
+
+const struct mem_type *get_mem_type(unsigned int type);
+
#endif
struct map_desc;
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index b0b5f46..2c4c242 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -49,8 +49,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
#endif
/*
- * We should enforce the MAP_FIXED case. However, currently
- * the generic kernel code doesn't allow us to handle this.
+ * We enforce the MAP_FIXED case.
*/
if (flags & MAP_FIXED) {
if (aliasing && flags & MAP_SHARED && addr & (SHMLBA - 1))
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 94fd4bf..2ba1530 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -176,28 +176,42 @@ void adjust_cr(unsigned long mask, unsigned long set)
}
#endif
-struct mem_types {
- unsigned int prot_pte;
- unsigned int prot_l1;
- unsigned int prot_sect;
- unsigned int domain;
-};
-
-static struct mem_types mem_types[] __initdata = {
- [MT_DEVICE] = {
- .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
- L_PTE_WRITE,
- .prot_l1 = PMD_TYPE_TABLE,
- .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED |
- PMD_SECT_AP_WRITE,
- .domain = DOMAIN_IO,
+#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_WRITE
+#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_XN|PMD_SECT_AP_WRITE
+
+static struct mem_type mem_types[] = {
+ [MT_DEVICE] = { /* Strongly ordered / ARMv6 shared device */
+ .prot_pte = PROT_PTE_DEVICE,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PROT_SECT_DEVICE | PMD_SECT_UNCACHED,
+ .domain = DOMAIN_IO,
+ },
+ [MT_DEVICE_NONSHARED] = { /* ARMv6 non-shared device */
+ .prot_pte = PROT_PTE_DEVICE,
+ .prot_pte_ext = PTE_EXT_TEX(2),
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PROT_SECT_DEVICE | PMD_SECT_TEX(2),
+ .domain = DOMAIN_IO,
+ },
+ [MT_DEVICE_CACHED] = { /* ioremap_cached */
+ .prot_pte = PROT_PTE_DEVICE | L_PTE_CACHEABLE | L_PTE_BUFFERABLE,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PROT_SECT_DEVICE | PMD_SECT_WB,
+ .domain = DOMAIN_IO,
+ },
+ [MT_DEVICE_IXP2000] = { /* IXP2400 requires XCB=101 for on-chip I/O */
+ .prot_pte = PROT_PTE_DEVICE,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PROT_SECT_DEVICE | PMD_SECT_BUFFERABLE |
+ PMD_SECT_TEX(1),
+ .domain = DOMAIN_IO,
},
[MT_CACHECLEAN] = {
- .prot_sect = PMD_TYPE_SECT | PMD_BIT4,
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
.domain = DOMAIN_KERNEL,
},
[MT_MINICLEAN] = {
- .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_MINICACHE,
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_MINICACHE,
.domain = DOMAIN_KERNEL,
},
[MT_LOW_VECTORS] = {
@@ -213,30 +227,20 @@ static struct mem_types mem_types[] __initdata = {
.domain = DOMAIN_USER,
},
[MT_MEMORY] = {
- .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_AP_WRITE,
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
.domain = DOMAIN_KERNEL,
},
[MT_ROM] = {
- .prot_sect = PMD_TYPE_SECT | PMD_BIT4,
+ .prot_sect = PMD_TYPE_SECT,
.domain = DOMAIN_KERNEL,
},
- [MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */
- .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
- L_PTE_WRITE,
- .prot_l1 = PMD_TYPE_TABLE,
- .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED |
- PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE |
- PMD_SECT_TEX(1),
- .domain = DOMAIN_IO,
- },
- [MT_NONSHARED_DEVICE] = {
- .prot_l1 = PMD_TYPE_TABLE,
- .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_NONSHARED_DEV |
- PMD_SECT_AP_WRITE,
- .domain = DOMAIN_IO,
- }
};
+const struct mem_type *get_mem_type(unsigned int type)
+{
+ return type < ARRAY_SIZE(mem_types) ? &mem_types[type] : NULL;
+}
+
/*
* Adjust the PMD section entries according to the CPU in use.
*/
@@ -262,20 +266,23 @@ static void __init build_mem_type_table(void)
}
/*
- * Xscale must not have PMD bit 4 set for section mappings.
+ * ARMv5 and lower, bit 4 must be set for page tables.
+ * (was: cache "update-able on write" bit on ARM610)
+ * However, Xscale cores require this bit to be cleared.
*/
- if (cpu_is_xscale())
- for (i = 0; i < ARRAY_SIZE(mem_types); i++)
+ if (cpu_is_xscale()) {
+ for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
mem_types[i].prot_sect &= ~PMD_BIT4;
-
- /*
- * ARMv5 and lower, excluding Xscale, bit 4 must be set for
- * page tables.
- */
- if (cpu_arch < CPU_ARCH_ARMv6 && !cpu_is_xscale())
- for (i = 0; i < ARRAY_SIZE(mem_types); i++)
+ mem_types[i].prot_l1 &= ~PMD_BIT4;
+ }
+ } else if (cpu_arch < CPU_ARCH_ARMv6) {
+ for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
if (mem_types[i].prot_l1)
mem_types[i].prot_l1 |= PMD_BIT4;
+ if (mem_types[i].prot_sect)
+ mem_types[i].prot_sect |= PMD_BIT4;
+ }
+ }
cp = &cache_policies[cachepolicy];
kern_pgprot = user_pgprot = cp->pte;
@@ -296,13 +303,6 @@ static void __init build_mem_type_table(void)
*/
if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
/*
- * bit 4 becomes XN which we must clear for the
- * kernel memory mapping.
- */
- mem_types[MT_MEMORY].prot_sect &= ~PMD_SECT_XN;
- mem_types[MT_ROM].prot_sect &= ~PMD_SECT_XN;
-
- /*
* Mark cache clean areas and XIP ROM read only
* from SVC mode and no access from userspace.
*/
@@ -368,64 +368,126 @@ static void __init build_mem_type_table(void)
}
printk("Memory policy: ECC %sabled, Data cache %s\n",
ecc_mask ? "en" : "dis", cp->policy);
+
+ for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
+ struct mem_type *t = &mem_types[i];
+ if (t->prot_l1)
+ t->prot_l1 |= PMD_DOMAIN(t->domain);
+ if (t->prot_sect)
+ t->prot_sect |= PMD_DOMAIN(t->domain);
+ }
}
#define vectors_base() (vectors_high() ? 0xffff0000 : 0)
-/*
- * Create a SECTION PGD between VIRT and PHYS in domain
- * DOMAIN with protection PROT. This operates on half-
- * pgdir entry increments.
- */
-static inline void
-alloc_init_section(unsigned long virt, unsigned long phys, int prot)
+static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
+ unsigned long end, unsigned long pfn,
+ const struct mem_type *type)
{
- pmd_t *pmdp = pmd_off_k(virt);
+ pte_t *pte;
- if (virt & (1 << 20))
- pmdp++;
+ if (pmd_none(*pmd)) {
+ pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
+ __pmd_populate(pmd, __pa(pte) | type->prot_l1);
+ }
- *pmdp = __pmd(phys | prot);
- flush_pmd_entry(pmdp);
+ pte = pte_offset_kernel(pmd, addr);
+ do {
+ set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)),
+ type->prot_pte_ext);
+ pfn++;
+ } while (pte++, addr += PAGE_SIZE, addr != end);
}
-/*
- * Create a SUPER SECTION PGD between VIRT and PHYS with protection PROT
- */
-static inline void
-alloc_init_supersection(unsigned long virt, unsigned long phys, int prot)
+static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,
+ unsigned long end, unsigned long phys,
+ const struct mem_type *type)
{
- int i;
+ pmd_t *pmd = pmd_offset(pgd, addr);
+
+ /*
+ * Try a section mapping - end, addr and phys must all be aligned
+ * to a section boundary. Note that PMDs refer to the individual
+ * L1 entries, whereas PGDs refer to a group of L1 entries making
+ * up one logical pointer to an L2 table.
+ */
+ if (((addr | end | phys) & ~SECTION_MASK) == 0) {
+ pmd_t *p = pmd;
+
+ if (addr & SECTION_SIZE)
+ pmd++;
- for (i = 0; i < 16; i += 1) {
- alloc_init_section(virt, phys, prot | PMD_SECT_SUPER);
+ do {
+ *pmd = __pmd(phys | type->prot_sect);
+ phys += SECTION_SIZE;
+ } while (pmd++, addr += SECTION_SIZE, addr != end);
- virt += (PGDIR_SIZE / 2);
+ flush_pmd_entry(p);
+ } else {
+ /*
+ * No need to loop; pte's aren't interested in the
+ * individual L1 entries.
+ */
+ alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type);
}
}
-/*
- * Add a PAGE mapping between VIRT and PHYS in domain
- * DOMAIN with protection PROT. Note that due to the
- * way we map the PTEs, we must allocate two PTE_SIZE'd
- * blocks - one for the Linux pte table, and one for
- * the hardware pte table.
- */
-static inline void
-alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot)
+static void __init create_36bit_mapping(struct map_desc *md,
+ const struct mem_type *type)
{
- pmd_t *pmdp = pmd_off_k(virt);
- pte_t *ptep;
+ unsigned long phys, addr, length, end;
+ pgd_t *pgd;
+
+ addr = md->virtual;
+ phys = (unsigned long)__pfn_to_phys(md->pfn);
+ length = PAGE_ALIGN(md->length);
+
+ if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) {
+ printk(KERN_ERR "MM: CPU does not support supersection "
+ "mapping for 0x%08llx at 0x%08lx\n",
+ __pfn_to_phys((u64)md->pfn), addr);
+ return;
+ }
- if (pmd_none(*pmdp)) {
- ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
- sizeof(pte_t));
+ /* N.B. ARMv6 supersections are only defined to work with domain 0.
+ * Since domain assignments can in fact be arbitrary, the
+ * 'domain == 0' check below is required to insure that ARMv6
+ * supersections are only allocated for domain 0 regardless
+ * of the actual domain assignments in use.
+ */
+ if (type->domain) {
+ printk(KERN_ERR "MM: invalid domain in supersection "
+ "mapping for 0x%08llx at 0x%08lx\n",
+ __pfn_to_phys((u64)md->pfn), addr);
+ return;
+ }
- __pmd_populate(pmdp, __pa(ptep) | prot_l1);
+ if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) {
+ printk(KERN_ERR "MM: cannot create mapping for "
+ "0x%08llx at 0x%08lx invalid alignment\n",
+ __pfn_to_phys((u64)md->pfn), addr);
+ return;
}
- ptep = pte_offset_kernel(pmdp, virt);
- set_pte_ext(ptep, pfn_pte(phys >> PAGE_SHIFT, prot), 0);
+ /*
+ * Shift bits [35:32] of address into bits [23:20] of PMD
+ * (See ARMv6 spec).
+ */
+ phys |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20);
+
+ pgd = pgd_offset_k(addr);
+ end = addr + length;
+ do {
+ pmd_t *pmd = pmd_offset(pgd, addr);
+ int i;
+
+ for (i = 0; i < 16; i++)
+ *pmd++ = __pmd(phys | type->prot_sect | PMD_SECT_SUPER);
+
+ addr += SUPERSECTION_SIZE;
+ phys += SUPERSECTION_SIZE;
+ pgd += SUPERSECTION_SIZE >> PGDIR_SHIFT;
+ } while (addr != end);
}
/*
@@ -437,10 +499,9 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg
*/
void __init create_mapping(struct map_desc *md)
{
- unsigned long virt, length;
- int prot_sect, prot_l1, domain;
- pgprot_t prot_pte;
- unsigned long off = (u32)__pfn_to_phys(md->pfn);
+ unsigned long phys, addr, length, end;
+ const struct mem_type *type;
+ pgd_t *pgd;
if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
printk(KERN_WARNING "BUG: not creating mapping for "
@@ -456,105 +517,37 @@ void __init create_mapping(struct map_desc *md)
__pfn_to_phys((u64)md->pfn), md->virtual);
}
- domain = mem_types[md->type].domain;
- prot_pte = __pgprot(mem_types[md->type].prot_pte);
- prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain);
- prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain);
+ type = &mem_types[md->type];
/*
* Catch 36-bit addresses
*/
- if(md->pfn >= 0x100000) {
- if(domain) {
- printk(KERN_ERR "MM: invalid domain in supersection "
- "mapping for 0x%08llx at 0x%08lx\n",
- __pfn_to_phys((u64)md->pfn), md->virtual);
- return;
- }
- if((md->virtual | md->length | __pfn_to_phys(md->pfn))
- & ~SUPERSECTION_MASK) {
- printk(KERN_ERR "MM: cannot create mapping for "
- "0x%08llx at 0x%08lx invalid alignment\n",
- __pfn_to_phys((u64)md->pfn), md->virtual);
- return;
- }
-
- /*
- * Shift bits [35:32] of address into bits [23:20] of PMD
- * (See ARMv6 spec).
- */
- off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20);
+ if (md->pfn >= 0x100000) {
+ create_36bit_mapping(md, type);
+ return;
}
- virt = md->virtual;
- off -= virt;
- length = md->length;
+ addr = md->virtual;
+ phys = (unsigned long)__pfn_to_phys(md->pfn);
+ length = PAGE_ALIGN(md->length);
- if (mem_types[md->type].prot_l1 == 0 &&
- (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) {
+ if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) {
printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not "
"be mapped using pages, ignoring.\n",
- __pfn_to_phys(md->pfn), md->virtual);
+ __pfn_to_phys(md->pfn), addr);
return;
}
- while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) {
- alloc_init_page(virt, virt + off, prot_l1, prot_pte);
+ pgd = pgd_offset_k(addr);
+ end = addr + length;
+ do {
+ unsigned long next = pgd_addr_end(addr, end);
- virt += PAGE_SIZE;
- length -= PAGE_SIZE;
- }
-
- /* N.B. ARMv6 supersections are only defined to work with domain 0.
- * Since domain assignments can in fact be arbitrary, the
- * 'domain == 0' check below is required to insure that ARMv6
- * supersections are only allocated for domain 0 regardless
- * of the actual domain assignments in use.
- */
- if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())
- && domain == 0) {
- /*
- * Align to supersection boundary if !high pages.
- * High pages have already been checked for proper
- * alignment above and they will fail the SUPSERSECTION_MASK
- * check because of the way the address is encoded into
- * offset.
- */
- if (md->pfn <= 0x100000) {
- while ((virt & ~SUPERSECTION_MASK ||
- (virt + off) & ~SUPERSECTION_MASK) &&
- length >= (PGDIR_SIZE / 2)) {
- alloc_init_section(virt, virt + off, prot_sect);
-
- virt += (PGDIR_SIZE / 2);
- length -= (PGDIR_SIZE / 2);
- }
- }
+ alloc_init_section(pgd, addr, next, phys, type);
- while (length >= SUPERSECTION_SIZE) {
- alloc_init_supersection(virt, virt + off, prot_sect);
-
- virt += SUPERSECTION_SIZE;
- length -= SUPERSECTION_SIZE;
- }
- }
-
- /*
- * A section mapping covers half a "pgdir" entry.
- */
- while (length >= (PGDIR_SIZE / 2)) {
- alloc_init_section(virt, virt + off, prot_sect);
-
- virt += (PGDIR_SIZE / 2);
- length -= (PGDIR_SIZE / 2);
- }
-
- while (length >= PAGE_SIZE) {
- alloc_init_page(virt, virt + off, prot_l1, prot_pte);
-
- virt += PAGE_SIZE;
- length -= PAGE_SIZE;
- }
+ phys += next - addr;
+ addr = next;
+ } while (pgd++, addr != end);
}
/*
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 05818fc..8cd3a60 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -62,21 +62,21 @@ void flush_dcache_page(struct page *page)
}
EXPORT_SYMBOL(flush_dcache_page);
-void __iomem *__ioremap_pfn(unsigned long pfn, unsigned long offset,
- size_t size, unsigned long flags)
+void __iomem *__arm_ioremap_pfn(unsigned long pfn, unsigned long offset,
+ size_t size, unsigned int mtype)
{
if (pfn >= (0x100000000ULL >> PAGE_SHIFT))
return NULL;
return (void __iomem *) (offset + (pfn << PAGE_SHIFT));
}
-EXPORT_SYMBOL(__ioremap_pfn);
+EXPORT_SYMBOL(__arm_ioremap_pfn);
-void __iomem *__ioremap(unsigned long phys_addr, size_t size,
- unsigned long flags)
+void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size,
+ unsigned int mtype)
{
return (void __iomem *)phys_addr;
}
-EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(__arm_ioremap);
void __iounmap(volatile void __iomem *addr)
{
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index d29fe92..c156dda 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -584,6 +584,11 @@ cpu_ixp42x_name:
.asciz "XScale-IXP42x Family"
.size cpu_ixp42x_name, . - cpu_ixp42x_name
+ .type cpu_ixp43x_name, #object
+cpu_ixp43x_name:
+ .asciz "XScale-IXP43x Family"
+ .size cpu_ixp43x_name, . - cpu_ixp43x_name
+
.type cpu_ixp46x_name, #object
cpu_ixp46x_name:
.asciz "XScale-IXP46x Family"
@@ -843,6 +848,29 @@ __ixp42x_proc_info:
.long xscale_cache_fns
.size __ixp42x_proc_info, . - __ixp42x_proc_info
+ .type __ixp43x_proc_info, #object
+__ixp43x_proc_info:
+ .long 0x69054040
+ .long 0xfffffff0
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ b __xscale_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+ .long cpu_ixp43x_name
+ .long xscale_processor_functions
+ .long v4wbi_tlb_fns
+ .long xscale_mc_user_fns
+ .long xscale_cache_fns
+ .size __ixp43x_proc_info, . - __ixp43x_proc_info
+
.type __ixp46x_proc_info, #object
__ixp46x_proc_info:
.long 0x69054200
diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c
index 7c22c1261..f5ebf30 100644
--- a/arch/arm/oprofile/backtrace.c
+++ b/arch/arm/oprofile/backtrace.c
@@ -19,6 +19,19 @@
#include <asm/ptrace.h>
#include <asm/uaccess.h>
+#include "../kernel/stacktrace.h"
+
+static int report_trace(struct stackframe *frame, void *d)
+{
+ unsigned int *depth = d;
+
+ if (*depth) {
+ oprofile_add_trace(frame->lr);
+ (*depth)--;
+ }
+
+ return *depth == 0;
+}
/*
* The registers we're interested in are at the end of the variable
@@ -32,21 +45,6 @@ struct frame_tail {
unsigned long lr;
} __attribute__((packed));
-
-#ifdef CONFIG_FRAME_POINTER
-static struct frame_tail* kernel_backtrace(struct frame_tail *tail)
-{
- oprofile_add_trace(tail->lr);
-
- /* frame pointers should strictly progress back up the stack
- * (towards higher addresses) */
- if (tail >= tail->fp)
- return NULL;
-
- return tail->fp-1;
-}
-#endif
-
static struct frame_tail* user_backtrace(struct frame_tail *tail)
{
struct frame_tail buftail[2];
@@ -67,47 +65,14 @@ static struct frame_tail* user_backtrace(struct frame_tail *tail)
return buftail[0].fp-1;
}
-/*
- * | | /\ Higher addresses
- * | |
- * --------------- stack base (address of current_thread_info)
- * | thread info |
- * . .
- * | stack |
- * --------------- saved regs->ARM_fp value if valid (frame_tail address)
- * . .
- * --------------- struct pt_regs stored on stack (struct pt_regs *)
- * | |
- * . .
- * | |
- * --------------- %esp
- * | |
- * | | \/ Lower addresses
- *
- * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values
- */
-static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs)
-{
- unsigned long tailaddr = (unsigned long)tail;
- unsigned long stack = (unsigned long)regs;
- unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
-
- return (tailaddr > stack) && (tailaddr < stack_base);
-}
-
void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
{
- struct frame_tail *tail;
-
- tail = ((struct frame_tail *) regs->ARM_fp) - 1;
+ struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1;
if (!user_mode(regs)) {
-
-#ifdef CONFIG_FRAME_POINTER
- while (depth-- && tail && valid_kernel_stack(tail, regs)) {
- tail = kernel_backtrace(tail);
- }
-#endif
+ unsigned long base = ((unsigned long)regs) & ~(THREAD_SIZE - 1);
+ walk_stackframe(regs->ARM_fp, base, base + THREAD_SIZE,
+ report_trace, &depth);
return;
}
diff --git a/arch/arm/plat-iop/io.c b/arch/arm/plat-iop/io.c
index f7eccec..498675d 100644
--- a/arch/arm/plat-iop/io.c
+++ b/arch/arm/plat-iop/io.c
@@ -22,7 +22,7 @@
#include <asm/io.h>
void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size,
- unsigned long flags)
+ unsigned int mtype)
{
void __iomem * retval;
@@ -34,7 +34,7 @@ void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size,
retval = (void *) IOP3XX_PMMR_PHYS_TO_VIRT(cookie);
break;
default:
- retval = __ioremap(cookie, size, flags);
+ retval = __arm_ioremap(cookie, size, mtype);
}
return retval;
diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c
index b5f6ec3..e2744b7 100644
--- a/arch/arm/plat-iop/pci.c
+++ b/arch/arm/plat-iop/pci.c
@@ -55,7 +55,7 @@ static u32 iop3xx_cfg_address(struct pci_bus *bus, int devfn, int where)
* This routine checks the status of the last configuration cycle. If an error
* was detected it returns a 1, else it returns a 0. The errors being checked
* are parity, master abort, target abort (master and target). These types of
- * errors occure during a config cycle where there is no device, like during
+ * errors occur during a config cycle where there is no device, like during
* the discovery stage.
*/
static int iop3xx_pci_status(void)
@@ -223,8 +223,111 @@ struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys)
return pci_scan_bus(sys->busnr, &iop3xx_ops, sys);
}
+void __init iop3xx_atu_setup(void)
+{
+ /* BAR 0 ( Disabled ) */
+ *IOP3XX_IAUBAR0 = 0x0;
+ *IOP3XX_IABAR0 = 0x0;
+ *IOP3XX_IATVR0 = 0x0;
+ *IOP3XX_IALR0 = 0x0;
+
+ /* BAR 1 ( Disabled ) */
+ *IOP3XX_IAUBAR1 = 0x0;
+ *IOP3XX_IABAR1 = 0x0;
+ *IOP3XX_IALR1 = 0x0;
+
+ /* BAR 2 (1:1 mapping with Physical RAM) */
+ /* Set limit and enable */
+ *IOP3XX_IALR2 = ~((u32)IOP3XX_MAX_RAM_SIZE - 1) & ~0x1;
+ *IOP3XX_IAUBAR2 = 0x0;
+
+ /* Align the inbound bar with the base of memory */
+ *IOP3XX_IABAR2 = PHYS_OFFSET |
+ PCI_BASE_ADDRESS_MEM_TYPE_64 |
+ PCI_BASE_ADDRESS_MEM_PREFETCH;
+
+ *IOP3XX_IATVR2 = PHYS_OFFSET;
+
+ /* Outbound window 0 */
+ *IOP3XX_OMWTVR0 = IOP3XX_PCI_LOWER_MEM_PA;
+ *IOP3XX_OUMWTVR0 = 0;
+
+ /* Outbound window 1 */
+ *IOP3XX_OMWTVR1 = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE;
+ *IOP3XX_OUMWTVR1 = 0;
+
+ /* BAR 3 ( Disabled ) */
+ *IOP3XX_IAUBAR3 = 0x0;
+ *IOP3XX_IABAR3 = 0x0;
+ *IOP3XX_IATVR3 = 0x0;
+ *IOP3XX_IALR3 = 0x0;
+
+ /* Setup the I/O Bar
+ */
+ *IOP3XX_OIOWTVR = IOP3XX_PCI_LOWER_IO_PA;;
+
+ /* Enable inbound and outbound cycles
+ */
+ *IOP3XX_ATUCMD |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+ PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+ *IOP3XX_ATUCR |= IOP3XX_ATUCR_OUT_EN;
+}
+
+void __init iop3xx_atu_disable(void)
+{
+ *IOP3XX_ATUCMD = 0;
+ *IOP3XX_ATUCR = 0;
+
+ /* wait for cycles to quiesce */
+ while (*IOP3XX_PCSR & (IOP3XX_PCSR_OUT_Q_BUSY |
+ IOP3XX_PCSR_IN_Q_BUSY))
+ cpu_relax();
+
+ /* BAR 0 ( Disabled ) */
+ *IOP3XX_IAUBAR0 = 0x0;
+ *IOP3XX_IABAR0 = 0x0;
+ *IOP3XX_IATVR0 = 0x0;
+ *IOP3XX_IALR0 = 0x0;
+
+ /* BAR 1 ( Disabled ) */
+ *IOP3XX_IAUBAR1 = 0x0;
+ *IOP3XX_IABAR1 = 0x0;
+ *IOP3XX_IALR1 = 0x0;
+
+ /* BAR 2 ( Disabled ) */
+ *IOP3XX_IAUBAR2 = 0x0;
+ *IOP3XX_IABAR2 = 0x0;
+ *IOP3XX_IATVR2 = 0x0;
+ *IOP3XX_IALR2 = 0x0;
+
+ /* BAR 3 ( Disabled ) */
+ *IOP3XX_IAUBAR3 = 0x0;
+ *IOP3XX_IABAR3 = 0x0;
+ *IOP3XX_IATVR3 = 0x0;
+ *IOP3XX_IALR3 = 0x0;
+
+ /* Clear the outbound windows */
+ *IOP3XX_OIOWTVR = 0;
+
+ /* Outbound window 0 */
+ *IOP3XX_OMWTVR0 = 0;
+ *IOP3XX_OUMWTVR0 = 0;
+
+ /* Outbound window 1 */
+ *IOP3XX_OMWTVR1 = 0;
+ *IOP3XX_OUMWTVR1 = 0;
+}
+
+/* Flag to determine whether the ATU is initialized and the PCI bus scanned */
+int init_atu;
+
void iop3xx_pci_preinit(void)
{
+ if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) {
+ iop3xx_atu_disable();
+ iop3xx_atu_setup();
+ }
+
DBG("PCI: Intel 803xx PCI init code.\n");
DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD);
DBG("ATU: IOP3XX_OMWTVR0=0x%04x, IOP3XX_OIOWTVR=0x%04x\n",
@@ -245,3 +348,38 @@ void iop3xx_pci_preinit(void)
hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, "imprecise external abort");
}
+
+/* allow init_atu to be user overridden */
+static int __init iop3xx_init_atu_setup(char *str)
+{
+ init_atu = IOP3XX_INIT_ATU_DEFAULT;
+ if (str) {
+ while (*str != '\0') {
+ switch (*str) {
+ case 'y':
+ case 'Y':
+ init_atu = IOP3XX_INIT_ATU_ENABLE;
+ break;
+ case 'n':
+ case 'N':
+ init_atu = IOP3XX_INIT_ATU_DISABLE;
+ break;
+ case ',':
+ case '=':
+ break;
+ default:
+ printk(KERN_DEBUG "\"%s\" malformed at "
+ "character: \'%c\'",
+ __FUNCTION__,
+ *str);
+ *(str + 1) = '\0';
+ }
+ str++;
+ }
+ }
+
+ return 1;
+}
+
+__setup("iop3xx_init_atu", iop3xx_init_atu_setup);
+
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
index 16300ad..100d57a 100644
--- a/arch/arm/plat-iop/time.c
+++ b/arch/arm/plat-iop/time.c
@@ -32,22 +32,22 @@ static unsigned long next_jiffy_time;
unsigned long iop_gettimeoffset(void)
{
- unsigned long offset, temp1, temp2;
+ unsigned long offset, temp;
/* enable cp6, if necessary, to avoid taking the overhead of an
* undefined instruction trap
*/
asm volatile (
"mrc p15, 0, %0, c15, c1, 0\n\t"
- "ands %1, %0, #(1 << 6)\n\t"
+ "tst %0, #(1 << 6)\n\t"
"orreq %0, %0, #(1 << 6)\n\t"
"mcreq p15, 0, %0, c15, c1, 0\n\t"
-#ifdef CONFIG_XSCALE
+#ifdef CONFIG_CPU_XSCALE
"mrceq p15, 0, %0, c15, c1, 0\n\t"
"moveq %0, %0\n\t"
"subeq pc, pc, #4\n\t"
#endif
- : "=r"(temp1), "=r"(temp2) : : "cc");
+ : "=r"(temp) : : "cc");
offset = next_jiffy_time - read_tcr1();
@@ -75,7 +75,7 @@ iop_timer_interrupt(int irq, void *dev_id)
static struct irqaction iop_timer_irq = {
.name = "IOP Timer Tick",
.handler = iop_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
};
void __init iop_init_time(unsigned long tick_rate)
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index f2dc363..9e8d21e 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -11,6 +11,7 @@ choice
config ARCH_OMAP1
bool "TI OMAP1"
+ select GENERIC_CLOCKEVENTS
config ARCH_OMAP2
bool "TI OMAP2"
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 57b7b93..fecd3d6 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -156,3 +156,53 @@ static int __init omap_add_serial_console(void)
return add_preferred_console("ttyS", line, opt);
}
console_initcall(omap_add_serial_console);
+
+
+/*
+ * 32KHz clocksource ... always available, on pretty most chips except
+ * OMAP 730 and 1510. Other timers could be used as clocksources, with
+ * higher resolution in free-running counter modes (e.g. 12 MHz xtal),
+ * but systems won't necessarily want to spend resources that way.
+ */
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+#define TIMER_32K_SYNCHRONIZED 0xfffbc410
+#elif defined(CONFIG_ARCH_OMAP24XX)
+#define TIMER_32K_SYNCHRONIZED 0x48004010
+#endif
+
+#ifdef TIMER_32K_SYNCHRONIZED
+
+#include <linux/clocksource.h>
+
+static cycle_t omap_32k_read(void)
+{
+ return omap_readl(TIMER_32K_SYNCHRONIZED);
+}
+
+static struct clocksource clocksource_32k = {
+ .name = "32k_counter",
+ .rating = 250,
+ .read = omap_32k_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 10,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init omap_init_clocksource_32k(void)
+{
+ static char err[] __initdata = KERN_ERR
+ "%s: can't register clocksource!\n";
+
+ if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
+ clocksource_32k.mult = clocksource_hz2mult(32768,
+ clocksource_32k.shift);
+
+ if (clocksource_register(&clocksource_32k))
+ printk(err, clocksource_32k.name);
+ }
+ return 0;
+}
+arch_initcall(omap_init_clocksource_32k);
+
+#endif /* TIMER_32K_SYNCHRONIZED */
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index dbc3f44..eeb33fe 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -429,6 +429,10 @@ static inline void omap_init_rng(void) {}
*/
static int __init omap_init_devices(void)
{
+/*
+ * Need to enable relevant once for 2430 SDP
+ */
+#ifndef CONFIG_MACH_OMAP_2430SDP
/* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
@@ -438,7 +442,7 @@ static int __init omap_init_devices(void)
omap_init_uwire();
omap_init_wdt();
omap_init_rng();
-
+#endif
return 0;
}
arch_initcall(omap_init_devices);
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 45f0439..659619f 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -506,6 +506,8 @@ int omap_dm_timer_init(void)
BUG_ON(dm_source_clocks[i] == NULL);
}
#endif
+ if (cpu_is_omap243x())
+ dm_timers[0].phys_base = 0x49018000;
for (i = 0; i < dm_timer_count; i++) {
#ifdef CONFIG_ARCH_OMAP2
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index b8c01de..9dc6d36 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -15,7 +15,6 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include <linux/ptrace.h>
#include <linux/sysdev.h>
#include <linux/err.h>
#include <linux/clk.h>
@@ -86,10 +85,17 @@
/*
* omap24xx specific GPIO registers
*/
-#define OMAP24XX_GPIO1_BASE (void __iomem *)0x48018000
-#define OMAP24XX_GPIO2_BASE (void __iomem *)0x4801a000
-#define OMAP24XX_GPIO3_BASE (void __iomem *)0x4801c000
-#define OMAP24XX_GPIO4_BASE (void __iomem *)0x4801e000
+#define OMAP242X_GPIO1_BASE (void __iomem *)0x48018000
+#define OMAP242X_GPIO2_BASE (void __iomem *)0x4801a000
+#define OMAP242X_GPIO3_BASE (void __iomem *)0x4801c000
+#define OMAP242X_GPIO4_BASE (void __iomem *)0x4801e000
+
+#define OMAP243X_GPIO1_BASE (void __iomem *)0x4900C000
+#define OMAP243X_GPIO2_BASE (void __iomem *)0x4900E000
+#define OMAP243X_GPIO3_BASE (void __iomem *)0x49010000
+#define OMAP243X_GPIO4_BASE (void __iomem *)0x49012000
+#define OMAP243X_GPIO5_BASE (void __iomem *)0x480B6000
+
#define OMAP24XX_GPIO_REVISION 0x0000
#define OMAP24XX_GPIO_SYSCONFIG 0x0010
#define OMAP24XX_GPIO_SYSSTATUS 0x0014
@@ -118,8 +124,18 @@ struct gpio_bank {
u16 virtual_irq_start;
int method;
u32 reserved_map;
+#if defined (CONFIG_ARCH_OMAP16XX) || defined (CONFIG_ARCH_OMAP24XX)
u32 suspend_wakeup;
u32 saved_wakeup;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
+ u32 non_wakeup_gpios;
+ u32 enabled_non_wakeup_gpios;
+
+ u32 saved_datain;
+ u32 saved_fallingdetect;
+ u32 saved_risingdetect;
+#endif
spinlock_t lock;
};
@@ -159,12 +175,22 @@ static struct gpio_bank gpio_bank_730[7] = {
#endif
#ifdef CONFIG_ARCH_OMAP24XX
-static struct gpio_bank gpio_bank_24xx[4] = {
- { OMAP24XX_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_24XX },
- { OMAP24XX_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_24XX },
- { OMAP24XX_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_24XX },
- { OMAP24XX_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_24XX },
+
+static struct gpio_bank gpio_bank_242x[4] = {
+ { OMAP242X_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_24XX },
+ { OMAP242X_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_24XX },
+ { OMAP242X_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_24XX },
+ { OMAP242X_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_24XX },
+};
+
+static struct gpio_bank gpio_bank_243x[5] = {
+ { OMAP243X_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_24XX },
+ { OMAP243X_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_24XX },
+ { OMAP243X_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_24XX },
+ { OMAP243X_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_24XX },
+ { OMAP243X_GPIO5_BASE, INT_24XX_GPIO_BANK5, IH_GPIO_BASE + 128, METHOD_GPIO_24XX },
};
+
#endif
static struct gpio_bank *gpio_bank;
@@ -258,21 +284,34 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
u32 l;
switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
reg += OMAP_MPUIO_IO_CNTL;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_DIR_CONTROL;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
case METHOD_GPIO_1610:
reg += OMAP1610_GPIO_DIRECTION;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
case METHOD_GPIO_730:
reg += OMAP730_GPIO_DIR_CONTROL;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_OE;
break;
+#endif
+ default:
+ WARN_ON(1);
+ return;
}
l = __raw_readl(reg);
if (is_input)
@@ -300,6 +339,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
u32 l = 0;
switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
reg += OMAP_MPUIO_OUTPUT;
l = __raw_readl(reg);
@@ -308,6 +348,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
else
l &= ~(1 << gpio);
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_DATA_OUTPUT;
l = __raw_readl(reg);
@@ -316,6 +358,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
else
l &= ~(1 << gpio);
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
case METHOD_GPIO_1610:
if (enable)
reg += OMAP1610_GPIO_SET_DATAOUT;
@@ -323,6 +367,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
reg += OMAP1610_GPIO_CLEAR_DATAOUT;
l = 1 << gpio;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
case METHOD_GPIO_730:
reg += OMAP730_GPIO_DATA_OUTPUT;
l = __raw_readl(reg);
@@ -331,6 +377,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
else
l &= ~(1 << gpio);
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
case METHOD_GPIO_24XX:
if (enable)
reg += OMAP24XX_GPIO_SETDATAOUT;
@@ -338,8 +386,9 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
reg += OMAP24XX_GPIO_CLEARDATAOUT;
l = 1 << gpio;
break;
+#endif
default:
- BUG();
+ WARN_ON(1);
return;
}
__raw_writel(l, reg);
@@ -363,28 +412,37 @@ int omap_get_gpio_datain(int gpio)
void __iomem *reg;
if (check_gpio(gpio) < 0)
- return -1;
+ return -EINVAL;
bank = get_gpio_bank(gpio);
reg = bank->base;
switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
reg += OMAP_MPUIO_INPUT_LATCH;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_DATA_INPUT;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
case METHOD_GPIO_1610:
reg += OMAP1610_GPIO_DATAIN;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
case METHOD_GPIO_730:
reg += OMAP730_GPIO_DATA_INPUT;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_DATAIN;
break;
+#endif
default:
- BUG();
- return -1;
+ return -EINVAL;
}
return (__raw_readl(reg)
& (1 << get_gpio_index(gpio))) != 0;
@@ -398,8 +456,10 @@ do { \
__raw_writel(l, base + reg); \
} while(0)
-static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int trigger)
+#ifdef CONFIG_ARCH_OMAP24XX
+static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
{
+ void __iomem *base = bank->base;
u32 gpio_bit = 1 << gpio;
MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
@@ -410,9 +470,21 @@ static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int tr
trigger & __IRQT_RISEDGE);
MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
trigger & __IRQT_FALEDGE);
+ if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
+ if (trigger != 0)
+ __raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_SETWKUENA);
+ else
+ __raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_CLEARWKUENA);
+ } else {
+ if (trigger != 0)
+ bank->enabled_non_wakeup_gpios |= gpio_bit;
+ else
+ bank->enabled_non_wakeup_gpios &= ~gpio_bit;
+ }
/* FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only level
* triggering requested. */
}
+#endif
static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
{
@@ -420,6 +492,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
u32 l = 0;
switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
reg += OMAP_MPUIO_GPIO_INT_EDGE;
l = __raw_readl(reg);
@@ -430,6 +503,8 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
else
goto bad;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_INT_CONTROL;
l = __raw_readl(reg);
@@ -440,22 +515,28 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
else
goto bad;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
case METHOD_GPIO_1610:
if (gpio & 0x08)
reg += OMAP1610_GPIO_EDGE_CTRL2;
else
reg += OMAP1610_GPIO_EDGE_CTRL1;
gpio &= 0x07;
- /* We allow only edge triggering, i.e. two lowest bits */
- if (trigger & (__IRQT_LOWLVL | __IRQT_HIGHLVL))
- BUG();
l = __raw_readl(reg);
l &= ~(3 << (gpio << 1));
if (trigger & __IRQT_RISEDGE)
l |= 2 << (gpio << 1);
if (trigger & __IRQT_FALEDGE)
l |= 1 << (gpio << 1);
+ if (trigger)
+ /* Enable wake-up during idle for dynamic tick */
+ __raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_SET_WAKEUPENA);
+ else
+ __raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA);
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
case METHOD_GPIO_730:
reg += OMAP730_GPIO_INT_CONTROL;
l = __raw_readl(reg);
@@ -466,11 +547,13 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
else
goto bad;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
case METHOD_GPIO_24XX:
- set_24xx_gpio_triggering(reg, gpio, trigger);
+ set_24xx_gpio_triggering(bank, gpio, trigger);
break;
+#endif
default:
- BUG();
goto bad;
}
__raw_writel(l, reg);
@@ -485,7 +568,7 @@ static int gpio_irq_type(unsigned irq, unsigned type)
unsigned gpio;
int retval;
- if (irq > IH_MPUIO_BASE)
+ if (!cpu_is_omap24xx() && irq > IH_MPUIO_BASE)
gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
else
gpio = irq - IH_GPIO_BASE;
@@ -493,14 +576,21 @@ static int gpio_irq_type(unsigned irq, unsigned type)
if (check_gpio(gpio) < 0)
return -EINVAL;
- if (type & IRQT_PROBE)
+ if (type & ~IRQ_TYPE_SENSE_MASK)
return -EINVAL;
- if (!cpu_is_omap24xx() && (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL)))
+
+ /* OMAP1 allows only only edge triggering */
+ if (!cpu_is_omap24xx()
+ && (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
return -EINVAL;
- bank = get_gpio_bank(gpio);
+ bank = get_irq_chip_data(irq);
spin_lock(&bank->lock);
retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
+ if (retval == 0) {
+ irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
+ irq_desc[irq].status |= type;
+ }
spin_unlock(&bank->lock);
return retval;
}
@@ -510,24 +600,34 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
void __iomem *reg = bank->base;
switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
/* MPUIO irqstatus is reset by reading the status register,
* so do nothing here */
return;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_INT_STATUS;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
case METHOD_GPIO_1610:
reg += OMAP1610_GPIO_IRQSTATUS1;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
case METHOD_GPIO_730:
reg += OMAP730_GPIO_INT_STATUS;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_IRQSTATUS1;
break;
+#endif
default:
- BUG();
+ WARN_ON(1);
return;
}
__raw_writel(gpio_mask, reg);
@@ -550,31 +650,41 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
u32 mask;
switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
reg += OMAP_MPUIO_GPIO_MASKIT;
mask = 0xffff;
inv = 1;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_INT_MASK;
mask = 0xffff;
inv = 1;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
case METHOD_GPIO_1610:
reg += OMAP1610_GPIO_IRQENABLE1;
mask = 0xffff;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
case METHOD_GPIO_730:
reg += OMAP730_GPIO_INT_MASK;
mask = 0xffffffff;
inv = 1;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_IRQENABLE1;
mask = 0xffffffff;
break;
+#endif
default:
- BUG();
+ WARN_ON(1);
return 0;
}
@@ -591,6 +701,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
u32 l;
switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
case METHOD_MPUIO:
reg += OMAP_MPUIO_GPIO_MASKIT;
l = __raw_readl(reg);
@@ -599,6 +710,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
else
l |= gpio_mask;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
case METHOD_GPIO_1510:
reg += OMAP1510_GPIO_INT_MASK;
l = __raw_readl(reg);
@@ -607,6 +720,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
else
l |= gpio_mask;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
case METHOD_GPIO_1610:
if (enable)
reg += OMAP1610_GPIO_SET_IRQENABLE1;
@@ -614,6 +729,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
reg += OMAP1610_GPIO_CLEAR_IRQENABLE1;
l = gpio_mask;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
case METHOD_GPIO_730:
reg += OMAP730_GPIO_INT_MASK;
l = __raw_readl(reg);
@@ -622,6 +739,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
else
l |= gpio_mask;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
case METHOD_GPIO_24XX:
if (enable)
reg += OMAP24XX_GPIO_SETIRQENABLE1;
@@ -629,8 +748,9 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
reg += OMAP24XX_GPIO_CLEARIRQENABLE1;
l = gpio_mask;
break;
+#endif
default:
- BUG();
+ WARN_ON(1);
return;
}
__raw_writel(l, reg);
@@ -652,15 +772,39 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena
static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
{
switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP16XX
+ case METHOD_MPUIO:
case METHOD_GPIO_1610:
+ spin_lock(&bank->lock);
+ if (enable) {
+ bank->suspend_wakeup |= (1 << gpio);
+ enable_irq_wake(bank->irq);
+ } else {
+ disable_irq_wake(bank->irq);
+ bank->suspend_wakeup &= ~(1 << gpio);
+ }
+ spin_unlock(&bank->lock);
+ return 0;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
case METHOD_GPIO_24XX:
+ if (bank->non_wakeup_gpios & (1 << gpio)) {
+ printk(KERN_ERR "Unable to modify wakeup on "
+ "non-wakeup GPIO%d\n",
+ (bank - gpio_bank) * 32 + gpio);
+ return -EINVAL;
+ }
spin_lock(&bank->lock);
- if (enable)
+ if (enable) {
bank->suspend_wakeup |= (1 << gpio);
- else
+ enable_irq_wake(bank->irq);
+ } else {
+ disable_irq_wake(bank->irq);
bank->suspend_wakeup &= ~(1 << gpio);
+ }
spin_unlock(&bank->lock);
return 0;
+#endif
default:
printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n",
bank->method);
@@ -685,7 +829,7 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable)
if (check_gpio(gpio) < 0)
return -ENODEV;
- bank = get_gpio_bank(gpio);
+ bank = get_irq_chip_data(irq);
retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
return retval;
@@ -722,20 +866,6 @@ int omap_request_gpio(int gpio)
__raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg);
}
#endif
-#ifdef CONFIG_ARCH_OMAP16XX
- if (bank->method == METHOD_GPIO_1610) {
- /* Enable wake-up during idle for dynamic tick */
- void __iomem *reg = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
- __raw_writel(1 << get_gpio_index(gpio), reg);
- }
-#endif
-#ifdef CONFIG_ARCH_OMAP24XX
- if (bank->method == METHOD_GPIO_24XX) {
- /* Enable wake-up during idle for dynamic tick */
- void __iomem *reg = bank->base + OMAP24XX_GPIO_SETWKUENA;
- __raw_writel(1 << get_gpio_index(gpio), reg);
- }
-#endif
spin_unlock(&bank->lock);
return 0;
@@ -795,8 +925,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
desc->chip->ack(irq);
bank = get_irq_data(irq);
+#ifdef CONFIG_ARCH_OMAP1
if (bank->method == METHOD_MPUIO)
isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
+#endif
#ifdef CONFIG_ARCH_OMAP15XX
if (bank->method == METHOD_GPIO_1510)
isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
@@ -912,7 +1044,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
static void gpio_irq_shutdown(unsigned int irq)
{
unsigned int gpio = irq - IH_GPIO_BASE;
- struct gpio_bank *bank = get_gpio_bank(gpio);
+ struct gpio_bank *bank = get_irq_chip_data(irq);
_reset_gpio(bank, gpio);
}
@@ -920,7 +1052,7 @@ static void gpio_irq_shutdown(unsigned int irq)
static void gpio_ack_irq(unsigned int irq)
{
unsigned int gpio = irq - IH_GPIO_BASE;
- struct gpio_bank *bank = get_gpio_bank(gpio);
+ struct gpio_bank *bank = get_irq_chip_data(irq);
_clear_gpio_irqstatus(bank, gpio);
}
@@ -928,7 +1060,7 @@ static void gpio_ack_irq(unsigned int irq)
static void gpio_mask_irq(unsigned int irq)
{
unsigned int gpio = irq - IH_GPIO_BASE;
- struct gpio_bank *bank = get_gpio_bank(gpio);
+ struct gpio_bank *bank = get_irq_chip_data(irq);
_set_gpio_irqenable(bank, gpio, 0);
}
@@ -937,11 +1069,27 @@ static void gpio_unmask_irq(unsigned int irq)
{
unsigned int gpio = irq - IH_GPIO_BASE;
unsigned int gpio_idx = get_gpio_index(gpio);
- struct gpio_bank *bank = get_gpio_bank(gpio);
+ struct gpio_bank *bank = get_irq_chip_data(irq);
_set_gpio_irqenable(bank, gpio_idx, 1);
}
+static struct irq_chip gpio_irq_chip = {
+ .name = "GPIO",
+ .shutdown = gpio_irq_shutdown,
+ .ack = gpio_ack_irq,
+ .mask = gpio_mask_irq,
+ .unmask = gpio_unmask_irq,
+ .set_type = gpio_irq_type,
+ .set_wake = gpio_wake_enable,
+};
+
+/*---------------------------------------------------------------------*/
+
+#ifdef CONFIG_ARCH_OMAP1
+
+/* MPUIO uses the always-on 32k clock */
+
static void mpuio_ack_irq(unsigned int irq)
{
/* The ISR is reset automatically, so do nothing here. */
@@ -950,7 +1098,7 @@ static void mpuio_ack_irq(unsigned int irq)
static void mpuio_mask_irq(unsigned int irq)
{
unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
- struct gpio_bank *bank = get_gpio_bank(gpio);
+ struct gpio_bank *bank = get_irq_chip_data(irq);
_set_gpio_irqenable(bank, gpio, 0);
}
@@ -958,33 +1106,108 @@ static void mpuio_mask_irq(unsigned int irq)
static void mpuio_unmask_irq(unsigned int irq)
{
unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
- struct gpio_bank *bank = get_gpio_bank(gpio);
+ struct gpio_bank *bank = get_irq_chip_data(irq);
_set_gpio_irqenable(bank, gpio, 1);
}
-static struct irq_chip gpio_irq_chip = {
- .name = "GPIO",
- .shutdown = gpio_irq_shutdown,
- .ack = gpio_ack_irq,
- .mask = gpio_mask_irq,
- .unmask = gpio_unmask_irq,
+static struct irq_chip mpuio_irq_chip = {
+ .name = "MPUIO",
+ .ack = mpuio_ack_irq,
+ .mask = mpuio_mask_irq,
+ .unmask = mpuio_unmask_irq,
.set_type = gpio_irq_type,
+#ifdef CONFIG_ARCH_OMAP16XX
+ /* REVISIT: assuming only 16xx supports MPUIO wake events */
.set_wake = gpio_wake_enable,
+#endif
};
-static struct irq_chip mpuio_irq_chip = {
- .name = "MPUIO",
- .ack = mpuio_ack_irq,
- .mask = mpuio_mask_irq,
- .unmask = mpuio_unmask_irq,
- .set_type = gpio_irq_type,
+
+#define bank_is_mpuio(bank) ((bank)->method == METHOD_MPUIO)
+
+
+#ifdef CONFIG_ARCH_OMAP16XX
+
+#include <linux/platform_device.h>
+
+static int omap_mpuio_suspend_late(struct platform_device *pdev, pm_message_t mesg)
+{
+ struct gpio_bank *bank = platform_get_drvdata(pdev);
+ void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT;
+
+ spin_lock(&bank->lock);
+ bank->saved_wakeup = __raw_readl(mask_reg);
+ __raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg);
+ spin_unlock(&bank->lock);
+
+ return 0;
+}
+
+static int omap_mpuio_resume_early(struct platform_device *pdev)
+{
+ struct gpio_bank *bank = platform_get_drvdata(pdev);
+ void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT;
+
+ spin_lock(&bank->lock);
+ __raw_writel(bank->saved_wakeup, mask_reg);
+ spin_unlock(&bank->lock);
+
+ return 0;
+}
+
+/* use platform_driver for this, now that there's no longer any
+ * point to sys_device (other than not disturbing old code).
+ */
+static struct platform_driver omap_mpuio_driver = {
+ .suspend_late = omap_mpuio_suspend_late,
+ .resume_early = omap_mpuio_resume_early,
+ .driver = {
+ .name = "mpuio",
+ },
+};
+
+static struct platform_device omap_mpuio_device = {
+ .name = "mpuio",
+ .id = -1,
+ .dev = {
+ .driver = &omap_mpuio_driver.driver,
+ }
+ /* could list the /proc/iomem resources */
};
+static inline void mpuio_init(void)
+{
+ platform_set_drvdata(&omap_mpuio_device, &gpio_bank_1610[0]);
+
+ if (platform_driver_register(&omap_mpuio_driver) == 0)
+ (void) platform_device_register(&omap_mpuio_device);
+}
+
+#else
+static inline void mpuio_init(void) {}
+#endif /* 16xx */
+
+#else
+
+extern struct irq_chip mpuio_irq_chip;
+
+#define bank_is_mpuio(bank) 0
+static inline void mpuio_init(void) {}
+
+#endif
+
+/*---------------------------------------------------------------------*/
+
static int initialized;
static struct clk * gpio_ick;
static struct clk * gpio_fck;
+#ifdef CONFIG_ARCH_OMAP2430
+static struct clk * gpio5_ick;
+static struct clk * gpio5_fck;
+#endif
+
static int __init _omap_gpio_init(void)
{
int i;
@@ -1010,7 +1233,25 @@ static int __init _omap_gpio_init(void)
printk("Could not get gpios_fck\n");
else
clk_enable(gpio_fck);
- }
+
+ /*
+ * On 2430 GPIO 5 uses CORE L4 ICLK
+ */
+#ifdef CONFIG_ARCH_OMAP2430
+ if (cpu_is_omap2430()) {
+ gpio5_ick = clk_get(NULL, "gpio5_ick");
+ if (IS_ERR(gpio5_ick))
+ printk("Could not get gpio5_ick\n");
+ else
+ clk_enable(gpio5_ick);
+ gpio5_fck = clk_get(NULL, "gpio5_fck");
+ if (IS_ERR(gpio5_fck))
+ printk("Could not get gpio5_fck\n");
+ else
+ clk_enable(gpio5_fck);
+ }
+#endif
+}
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap15xx()) {
@@ -1037,14 +1278,24 @@ static int __init _omap_gpio_init(void)
gpio_bank = gpio_bank_730;
}
#endif
+
#ifdef CONFIG_ARCH_OMAP24XX
- if (cpu_is_omap24xx()) {
+ if (cpu_is_omap242x()) {
int rev;
gpio_bank_count = 4;
- gpio_bank = gpio_bank_24xx;
+ gpio_bank = gpio_bank_242x;
+ rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
+ printk(KERN_INFO "OMAP242x GPIO hardware version %d.%d\n",
+ (rev >> 4) & 0x0f, rev & 0x0f);
+ }
+ if (cpu_is_omap243x()) {
+ int rev;
+
+ gpio_bank_count = 5;
+ gpio_bank = gpio_bank_243x;
rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
- printk(KERN_INFO "OMAP24xx GPIO hardware version %d.%d\n",
+ printk(KERN_INFO "OMAP243x GPIO hardware version %d.%d\n",
(rev >> 4) & 0x0f, rev & 0x0f);
}
#endif
@@ -1055,9 +1306,8 @@ static int __init _omap_gpio_init(void)
bank->reserved_map = 0;
bank->base = IO_ADDRESS(bank->base);
spin_lock_init(&bank->lock);
- if (bank->method == METHOD_MPUIO) {
+ if (bank_is_mpuio(bank))
omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
- }
#ifdef CONFIG_ARCH_OMAP15XX
if (bank->method == METHOD_GPIO_1510) {
__raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
@@ -1081,15 +1331,25 @@ static int __init _omap_gpio_init(void)
#endif
#ifdef CONFIG_ARCH_OMAP24XX
if (bank->method == METHOD_GPIO_24XX) {
+ static const u32 non_wakeup_gpios[] = {
+ 0xe203ffc0, 0x08700040
+ };
+
__raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1);
__raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1);
+ __raw_writew(0x0015, bank->base + OMAP24XX_GPIO_SYSCONFIG);
+ /* Initialize interface clock ungated, module enabled */
+ __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
+ if (i < ARRAY_SIZE(non_wakeup_gpios))
+ bank->non_wakeup_gpios = non_wakeup_gpios[i];
gpio_count = 32;
}
#endif
for (j = bank->virtual_irq_start;
j < bank->virtual_irq_start + gpio_count; j++) {
- if (bank->method == METHOD_MPUIO)
+ set_irq_chip_data(j, bank);
+ if (bank_is_mpuio(bank))
set_irq_chip(j, &mpuio_irq_chip);
else
set_irq_chip(j, &gpio_irq_chip);
@@ -1105,6 +1365,12 @@ static int __init _omap_gpio_init(void)
if (cpu_is_omap16xx())
omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
+#ifdef CONFIG_ARCH_OMAP24XX
+ /* Enable autoidle for the OCP interface */
+ if (cpu_is_omap24xx())
+ omap_writel(1 << 0, 0x48019010);
+#endif
+
return 0;
}
@@ -1123,16 +1389,20 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
void __iomem *wake_set;
switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP16XX
case METHOD_GPIO_1610:
wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE;
wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
case METHOD_GPIO_24XX:
wake_status = bank->base + OMAP24XX_GPIO_SETWKUENA;
wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
break;
+#endif
default:
continue;
}
@@ -1160,14 +1430,18 @@ static int omap_gpio_resume(struct sys_device *dev)
void __iomem *wake_set;
switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP16XX
case METHOD_GPIO_1610:
wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
case METHOD_GPIO_24XX:
wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
break;
+#endif
default:
continue;
}
@@ -1191,6 +1465,80 @@ static struct sys_device omap_gpio_device = {
.id = 0,
.cls = &omap_gpio_sysclass,
};
+
+#endif
+
+#ifdef CONFIG_ARCH_OMAP24XX
+
+static int workaround_enabled;
+
+void omap2_gpio_prepare_for_retention(void)
+{
+ int i, c = 0;
+
+ /* Remove triggering for all non-wakeup GPIOs. Otherwise spurious
+ * IRQs will be generated. See OMAP2420 Errata item 1.101. */
+ for (i = 0; i < gpio_bank_count; i++) {
+ struct gpio_bank *bank = &gpio_bank[i];
+ u32 l1, l2;
+
+ if (!(bank->enabled_non_wakeup_gpios))
+ continue;
+ bank->saved_datain = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
+ l1 = __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+ l2 = __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
+ bank->saved_fallingdetect = l1;
+ bank->saved_risingdetect = l2;
+ l1 &= ~bank->enabled_non_wakeup_gpios;
+ l2 &= ~bank->enabled_non_wakeup_gpios;
+ __raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+ __raw_writel(l2, bank->base + OMAP24XX_GPIO_RISINGDETECT);
+ c++;
+ }
+ if (!c) {
+ workaround_enabled = 0;
+ return;
+ }
+ workaround_enabled = 1;
+}
+
+void omap2_gpio_resume_after_retention(void)
+{
+ int i;
+
+ if (!workaround_enabled)
+ return;
+ for (i = 0; i < gpio_bank_count; i++) {
+ struct gpio_bank *bank = &gpio_bank[i];
+ u32 l;
+
+ if (!(bank->enabled_non_wakeup_gpios))
+ continue;
+ __raw_writel(bank->saved_fallingdetect,
+ bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+ __raw_writel(bank->saved_risingdetect,
+ bank->base + OMAP24XX_GPIO_RISINGDETECT);
+ /* Check if any of the non-wakeup interrupt GPIOs have changed
+ * state. If so, generate an IRQ by software. This is
+ * horribly racy, but it's the best we can do to work around
+ * this silicon bug. */
+ l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
+ l ^= bank->saved_datain;
+ l &= bank->non_wakeup_gpios;
+ if (l) {
+ u32 old0, old1;
+
+ old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
+ old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+ __raw_writel(old0 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT0);
+ __raw_writel(old1 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+ __raw_writel(old0, bank->base + OMAP24XX_GPIO_LEVELDETECT0);
+ __raw_writel(old1, bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+ }
+ }
+
+}
+
#endif
/*
@@ -1212,6 +1560,8 @@ static int __init omap_gpio_sysinit(void)
if (!initialized)
ret = _omap_gpio_init();
+ mpuio_init();
+
#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX)
if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
if (ret == 0) {
@@ -1232,3 +1582,128 @@ EXPORT_SYMBOL(omap_set_gpio_dataout);
EXPORT_SYMBOL(omap_get_gpio_datain);
arch_initcall(omap_gpio_sysinit);
+
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static int gpio_is_input(struct gpio_bank *bank, int mask)
+{
+ void __iomem *reg = bank->base;
+
+ switch (bank->method) {
+ case METHOD_MPUIO:
+ reg += OMAP_MPUIO_IO_CNTL;
+ break;
+ case METHOD_GPIO_1510:
+ reg += OMAP1510_GPIO_DIR_CONTROL;
+ break;
+ case METHOD_GPIO_1610:
+ reg += OMAP1610_GPIO_DIRECTION;
+ break;
+ case METHOD_GPIO_730:
+ reg += OMAP730_GPIO_DIR_CONTROL;
+ break;
+ case METHOD_GPIO_24XX:
+ reg += OMAP24XX_GPIO_OE;
+ break;
+ }
+ return __raw_readl(reg) & mask;
+}
+
+
+static int dbg_gpio_show(struct seq_file *s, void *unused)
+{
+ unsigned i, j, gpio;
+
+ for (i = 0, gpio = 0; i < gpio_bank_count; i++) {
+ struct gpio_bank *bank = gpio_bank + i;
+ unsigned bankwidth = 16;
+ u32 mask = 1;
+
+ if (bank_is_mpuio(bank))
+ gpio = OMAP_MPUIO(0);
+ else if (cpu_is_omap24xx() || cpu_is_omap730())
+ bankwidth = 32;
+
+ for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) {
+ unsigned irq, value, is_in, irqstat;
+
+ if (!(bank->reserved_map & mask))
+ continue;
+
+ irq = bank->virtual_irq_start + j;
+ value = omap_get_gpio_datain(gpio);
+ is_in = gpio_is_input(bank, mask);
+
+ if (bank_is_mpuio(bank))
+ seq_printf(s, "MPUIO %2d: ", j);
+ else
+ seq_printf(s, "GPIO %3d: ", gpio);
+ seq_printf(s, "%s %s",
+ is_in ? "in " : "out",
+ value ? "hi" : "lo");
+
+ irqstat = irq_desc[irq].status;
+ if (is_in && ((bank->suspend_wakeup & mask)
+ || irqstat & IRQ_TYPE_SENSE_MASK)) {
+ char *trigger = NULL;
+
+ switch (irqstat & IRQ_TYPE_SENSE_MASK) {
+ case IRQ_TYPE_EDGE_FALLING:
+ trigger = "falling";
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ trigger = "rising";
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ trigger = "bothedge";
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ trigger = "low";
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ trigger = "high";
+ break;
+ case IRQ_TYPE_NONE:
+ trigger = "(unspecified)";
+ break;
+ }
+ seq_printf(s, ", irq-%d %s%s",
+ irq, trigger,
+ (bank->suspend_wakeup & mask)
+ ? " wakeup" : "");
+ }
+ seq_printf(s, "\n");
+ }
+
+ if (bank_is_mpuio(bank)) {
+ seq_printf(s, "\n");
+ gpio = 0;
+ }
+ }
+ return 0;
+}
+
+static int dbg_gpio_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dbg_gpio_show, &inode->i_private);
+}
+
+static const struct file_operations debug_fops = {
+ .open = dbg_gpio_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init omap_gpio_debuginit(void)
+{
+ (void) debugfs_create_file("omap_gpio", S_IRUGO,
+ NULL, NULL, &debug_fops);
+ return 0;
+}
+late_initcall(omap_gpio_debuginit);
+#endif
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index b8d6f17..f7b9ccd 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -225,11 +225,16 @@ static void omap_mcbsp_dsp_free(void)
#ifdef CONFIG_ARCH_OMAP2
static void omap2_mcbsp2_mux_setup(void)
{
- omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
- omap_cfg_reg(R14_24XX_MCBSP2_FSX);
- omap_cfg_reg(W15_24XX_MCBSP2_DR);
- omap_cfg_reg(V15_24XX_MCBSP2_DX);
- omap_cfg_reg(V14_24XX_GPIO117);
+ if (cpu_is_omap2420()) {
+ omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
+ omap_cfg_reg(R14_24XX_MCBSP2_FSX);
+ omap_cfg_reg(W15_24XX_MCBSP2_DR);
+ omap_cfg_reg(V15_24XX_MCBSP2_DX);
+ omap_cfg_reg(V14_24XX_GPIO117);
+ }
+ /*
+ * Need to add MUX settings for OMAP 2430 SDP
+ */
}
#endif
diff --git a/arch/arm/plat-omap/timer32k.c b/arch/arm/plat-omap/timer32k.c
index 2653106..2feceec 100644
--- a/arch/arm/plat-omap/timer32k.c
+++ b/arch/arm/plat-omap/timer32k.c
@@ -42,6 +42,8 @@
#include <linux/spinlock.h>
#include <linux/err.h>
#include <linux/clk.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
#include <asm/system.h>
#include <asm/hardware.h>
@@ -80,13 +82,13 @@ struct sys_timer omap_timer;
#define OMAP1_32K_TIMER_TVR 0x00
#define OMAP1_32K_TIMER_TCR 0x04
-#define OMAP_32K_TICKS_PER_HZ (32768 / HZ)
+#define OMAP_32K_TICKS_PER_SEC (32768)
/*
* TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
* so with HZ = 128, TVR = 255.
*/
-#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1)
+#define OMAP_32K_TIMER_TICK_PERIOD ((OMAP_32K_TICKS_PER_SEC / HZ) - 1)
#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \
(((nr_jiffies) * (clock_rate)) / HZ)
@@ -142,6 +144,28 @@ static inline void omap_32k_timer_ack_irq(void)
#endif
+static void omap_32k_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_PERIODIC:
+ omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ omap_32k_timer_stop();
+ break;
+ }
+}
+
+static struct clock_event_device clockevent_32k_timer = {
+ .name = "32k-timer",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .shift = 32,
+ .set_mode = omap_32k_timer_set_mode,
+};
+
/*
* The 32KHz synchronized timer is an additional timer on 16xx.
* It is always running.
@@ -171,15 +195,6 @@ omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
static unsigned long omap_32k_last_tick = 0;
/*
- * Returns elapsed usecs since last 32k timer interrupt
- */
-static unsigned long omap_32k_timer_gettimeoffset(void)
-{
- unsigned long now = omap_32k_sync_timer_read();
- return omap_32k_ticks_to_usecs(now - omap_32k_last_tick);
-}
-
-/*
* Returns current time from boot in nsecs. It's OK for this to wrap
* around for now, as it's just a relative time stamp.
*/
@@ -188,110 +203,26 @@ unsigned long long sched_clock(void)
return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
}
-/*
- * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
- * function is also called from other interrupts to remove latency
- * issues with dynamic tick. In the dynamic tick case, we need to lock
- * with irqsave.
- */
-static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id)
-{
- unsigned long now;
-
- omap_32k_timer_ack_irq();
- now = omap_32k_sync_timer_read();
-
- while ((signed long)(now - omap_32k_last_tick)
- >= OMAP_32K_TICKS_PER_HZ) {
- omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
- timer_tick();
- }
-
- /* Restart timer so we don't drift off due to modulo or dynamic tick.
- * By default we program the next timer to be continuous to avoid
- * latencies during high system load. During dynamic tick operation the
- * continuous timer can be overridden from pm_idle to be longer.
- */
- omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id)
-{
- return _omap_32k_timer_interrupt(irq, dev_id);
-}
-
static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
{
- unsigned long flags;
+ struct clock_event_device *evt = &clockevent_32k_timer;
+ omap_32k_timer_ack_irq();
- write_seqlock_irqsave(&xtime_lock, flags);
- _omap_32k_timer_interrupt(irq, dev_id);
- write_sequnlock_irqrestore(&xtime_lock, flags);
+ evt->event_handler(evt);
return IRQ_HANDLED;
}
-#ifdef CONFIG_NO_IDLE_HZ
-/*
- * Programs the next timer interrupt needed. Called when dynamic tick is
- * enabled, and to reprogram the ticks to skip from pm_idle. Note that
- * we can keep the timer continuous, and don't need to set it to run in
- * one-shot mode. This is because the timer will get reprogrammed again
- * after next interrupt.
- */
-void omap_32k_timer_reprogram(unsigned long next_tick)
-{
- unsigned long ticks = JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1;
- unsigned long now = omap_32k_sync_timer_read();
- unsigned long idled = now - omap_32k_last_tick;
-
- if (idled + 1 < ticks)
- ticks -= idled;
- else
- ticks = 1;
- omap_32k_timer_start(ticks);
-}
-
-static struct irqaction omap_32k_timer_irq;
-extern struct timer_update_handler timer_update;
-
-static int omap_32k_timer_enable_dyn_tick(void)
-{
- /* No need to reprogram timer, just use the next interrupt */
- return 0;
-}
-
-static int omap_32k_timer_disable_dyn_tick(void)
-{
- omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
- return 0;
-}
-
-static struct dyn_tick_timer omap_dyn_tick_timer = {
- .enable = omap_32k_timer_enable_dyn_tick,
- .disable = omap_32k_timer_disable_dyn_tick,
- .reprogram = omap_32k_timer_reprogram,
- .handler = omap_32k_timer_handler,
-};
-#endif /* CONFIG_NO_IDLE_HZ */
-
static struct irqaction omap_32k_timer_irq = {
.name = "32KHz timer",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = omap_32k_timer_interrupt,
};
static __init void omap_init_32k_timer(void)
{
-#ifdef CONFIG_NO_IDLE_HZ
- omap_timer.dyn_tick = &omap_dyn_tick_timer;
-#endif
-
if (cpu_class_is_omap1())
setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
- omap_timer.offset = omap_32k_timer_gettimeoffset;
omap_32k_last_tick = omap_32k_sync_timer_read();
#ifdef CONFIG_ARCH_OMAP2
@@ -308,7 +239,16 @@ static __init void omap_init_32k_timer(void)
}
#endif
- omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
+ clockevent_32k_timer.mult = div_sc(OMAP_32K_TICKS_PER_SEC,
+ NSEC_PER_SEC,
+ clockevent_32k_timer.shift);
+ clockevent_32k_timer.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_32k_timer);
+ clockevent_32k_timer.min_delta_ns =
+ clockevent_delta2ns(1, &clockevent_32k_timer);
+
+ clockevent_32k_timer.cpumask = cpumask_of_cpu(0);
+ clockevents_register_device(&clockevent_32k_timer);
}
/*
@@ -326,5 +266,4 @@ static void __init omap_timer_init(void)
struct sys_timer omap_timer = {
.init = omap_timer_init,
- .offset = NULL, /* Initialized later */
};
diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c
index d3dc03a..79cda0f 100644
--- a/arch/arm/plat-s3c24xx/clock.c
+++ b/arch/arm/plat-s3c24xx/clock.c
@@ -404,6 +404,18 @@ int s3c24xx_register_clock(struct clk *clk)
return 0;
}
+int s3c24xx_register_clocks(struct clk **clks, int nr_clks)
+{
+ int fails = 0;
+
+ for (; nr_clks > 0; nr_clks--, clks++) {
+ if (s3c24xx_register_clock(*clks) < 0)
+ fails++;
+ }
+
+ return fails;
+}
+
/* initalise all the clocks */
int __init s3c24xx_setup_clocks(unsigned long xtal,
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 6a2d107..8ce4904 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -181,24 +181,6 @@ s3c_lookup_cpu(unsigned long idcode)
return NULL;
}
-/* board information */
-
-static struct s3c24xx_board *board;
-
-void s3c24xx_set_board(struct s3c24xx_board *b)
-{
- int i;
-
- board = b;
-
- if (b->clocks_count != 0) {
- struct clk **ptr = b->clocks;
-
- for (i = b->clocks_count; i > 0; i--, ptr++)
- s3c24xx_register_clock(*ptr);
- }
-}
-
/* cpu information */
static struct cpu_table *cpu;
@@ -342,26 +324,6 @@ static int __init s3c_arch_init(void)
return ret;
ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
- if (ret != 0)
- return ret;
-
- if (board != NULL) {
- struct platform_device **ptr = board->devices;
- int i;
-
- for (i = 0; i < board->devices_count; i++, ptr++) {
- ret = platform_device_register(*ptr);
-
- if (ret) {
- printk(KERN_ERR "s3c24xx: failed to add board device %s (%d) @%p\n", (*ptr)->name, ret, *ptr);
- }
- }
-
- /* mask any error, we may not need all these board
- * devices */
- ret = 0;
- }
-
return ret;
}
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index 4540a80..6f03c93 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -44,7 +44,7 @@ static struct kmem_cache *dma_kmem;
static int dma_channels;
-struct s3c24xx_dma_selection dma_sel;
+static struct s3c24xx_dma_selection dma_sel;
/* dma channel state information */
struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
@@ -880,7 +880,7 @@ static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
return 0;
}
-void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
+static void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
{
unsigned long tmp;
unsigned int timeout = 0x10000;
@@ -957,8 +957,7 @@ static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
return 0;
}
-int
-s3c2410_dma_started(struct s3c2410_dma_chan *chan)
+static int s3c2410_dma_started(struct s3c2410_dma_chan *chan)
{
unsigned long flags;
@@ -1280,7 +1279,7 @@ static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long
/* initialisation code */
-int __init s3c24xx_dma_sysclass_init(void)
+static int __init s3c24xx_dma_sysclass_init(void)
{
int ret = sysdev_class_register(&dma_sysclass);
@@ -1292,7 +1291,7 @@ int __init s3c24xx_dma_sysclass_init(void)
core_initcall(s3c24xx_dma_sysclass_init);
-int __init s3c24xx_dma_sysdev_register(void)
+static int __init s3c24xx_dma_sysdev_register(void)
{
struct s3c2410_dma_chan *cp = s3c2410_chans;
int channel, ret;
@@ -1396,7 +1395,7 @@ static struct s3c24xx_dma_order *dma_order;
* channel
*/
-struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
+static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
{
struct s3c24xx_dma_order_ch *ord = NULL;
struct s3c24xx_dma_map *ch_map;
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index ce18639..8fbc884 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -54,7 +54,6 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/ptrace.h>
#include <linux/sysdev.h>
#include <asm/hardware.h>
diff --git a/arch/arm/plat-s3c24xx/s3c244x-irq.c b/arch/arm/plat-s3c24xx/s3c244x-irq.c
index a0e39d8..2dbb260 100644
--- a/arch/arm/plat-s3c24xx/s3c244x-irq.c
+++ b/arch/arm/plat-s3c24xx/s3c244x-irq.c
@@ -23,7 +23,6 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/ptrace.h>
#include <linux/sysdev.h>
#include <asm/hardware.h>
diff --git a/arch/arm/plat-s3c24xx/time.c b/arch/arm/plat-s3c24xx/time.c
index c523d1c..b766737 100644
--- a/arch/arm/plat-s3c24xx/time.c
+++ b/arch/arm/plat-s3c24xx/time.c
@@ -138,7 +138,7 @@ s3c2410_timer_interrupt(int irq, void *dev_id)
static struct irqaction s3c2410_timer_irq = {
.name = "S3C2410 Timer Tick",
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = s3c2410_timer_interrupt,
};
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c
index e44b9ed..74e89f8 100644
--- a/arch/arm/vfp/vfpdouble.c
+++ b/arch/arm/vfp/vfpdouble.c
@@ -34,7 +34,6 @@
#include <linux/bitops.h>
#include <asm/div64.h>
-#include <asm/ptrace.h>
#include <asm/vfp.h>
#include "vfpinstr.h"
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c
index 0221ba3..b252631 100644
--- a/arch/arm/vfp/vfpsingle.c
+++ b/arch/arm/vfp/vfpsingle.c
@@ -34,7 +34,6 @@
#include <linux/bitops.h>
#include <asm/div64.h>
-#include <asm/ptrace.h>
#include <asm/vfp.h>
#include "vfpinstr.h"
diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig
index 989113d..20688bc 100644
--- a/arch/arm26/Kconfig
+++ b/arch/arm26/Kconfig
@@ -57,9 +57,6 @@ config GENERIC_CALIBRATE_DELAY
bool
default y
-config GENERIC_BUST_SPINLOCK
- bool
-
config ZONE_DMA
bool
default y
diff --git a/arch/arm26/kernel/armksyms.c b/arch/arm26/kernel/armksyms.c
index 93293d0..f735d7e 100644
--- a/arch/arm26/kernel/armksyms.c
+++ b/arch/arm26/kernel/armksyms.c
@@ -20,7 +20,6 @@
#include <linux/pm.h>
#include <linux/tty.h>
#include <linux/vt_kern.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <asm/byteorder.h>
diff --git a/arch/arm26/kernel/ptrace.c b/arch/arm26/kernel/ptrace.c
index 9343889..4169279 100644
--- a/arch/arm26/kernel/ptrace.c
+++ b/arch/arm26/kernel/ptrace.c
@@ -13,7 +13,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/security.h>
diff --git a/arch/arm26/kernel/signal.c b/arch/arm26/kernel/signal.c
index 6a8ef8d..379b82d 100644
--- a/arch/arm26/kernel/signal.c
+++ b/arch/arm26/kernel/signal.c
@@ -13,7 +13,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/signal.h>
diff --git a/arch/arm26/mm/memc.c b/arch/arm26/mm/memc.c
index f290158..4250554 100644
--- a/arch/arm26/mm/memc.c
+++ b/arch/arm26/mm/memc.c
@@ -176,13 +176,9 @@ void __init pgtable_cache_init(void)
{
pte_cache = kmem_cache_create("pte-cache",
sizeof(pte_t) * PTRS_PER_PTE,
- 0, 0, pte_cache_ctor, NULL);
- if (!pte_cache)
- BUG();
+ 0, SLAB_PANIC, pte_cache_ctor, NULL);
pgd_cache = kmem_cache_create("pgd-cache", MEMC_TABLE_SIZE +
sizeof(pgd_t) * PTRS_PER_PGD,
- 0, 0, pgd_cache_ctor, NULL);
- if (!pgd_cache)
- BUG();
+ 0, SLAB_PANIC, pgd_cache_ctor, NULL);
}
diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c
index d0abbca..004c94b 100644
--- a/arch/avr32/kernel/kprobes.c
+++ b/arch/avr32/kernel/kprobes.c
@@ -15,7 +15,7 @@
#include <linux/ptrace.h>
#include <asm/cacheflush.h>
-#include <asm/kdebug.h>
+#include <linux/kdebug.h>
#include <asm/ocd.h>
DEFINE_PER_CPU(struct kprobe *, current_kprobe);
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
index 6f4388f..8ac74dd 100644
--- a/arch/avr32/kernel/ptrace.c
+++ b/arch/avr32/kernel/ptrace.c
@@ -9,7 +9,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/user.h>
@@ -21,7 +20,7 @@
#include <asm/uaccess.h>
#include <asm/ocd.h>
#include <asm/mmu_context.h>
-#include <asm/kdebug.h>
+#include <linux/kdebug.h>
static struct pt_regs *get_user_regs(struct task_struct *tsk)
{
@@ -300,7 +299,7 @@ asmlinkage void do_debug_priv(struct pt_regs *regs)
else
die_val = DIE_BREAKPOINT;
- if (notify_die(die_val, regs, 0, SIGTRAP) == NOTIFY_STOP)
+ if (notify_die(die_val, "ptrace", regs, 0, 0, SIGTRAP) == NOTIFY_STOP)
return;
if (likely(ds & DS_SSS)) {
diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c
index 4f0382d..4de9edf 100644
--- a/arch/avr32/kernel/traps.c
+++ b/arch/avr32/kernel/traps.c
@@ -20,20 +20,6 @@
#include <asm/sysreg.h>
#include <asm/traps.h>
-ATOMIC_NOTIFIER_HEAD(avr32_die_chain);
-
-int register_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_register(&avr32_die_chain, nb);
-}
-EXPORT_SYMBOL(register_die_notifier);
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&avr32_die_chain, nb);
-}
-EXPORT_SYMBOL(unregister_die_notifier);
-
static DEFINE_SPINLOCK(die_lock);
void NORET_TYPE die(const char *str, struct pt_regs *regs, long err)
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index 146ebdb..88b00b1 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -13,7 +13,7 @@
#include <linux/module.h>
#include <linux/pagemap.h>
-#include <asm/kdebug.h>
+#include <linux/kdebug.h>
#include <asm/mmu_context.h>
#include <asm/sysreg.h>
#include <asm/tlb.h>
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
new file mode 100644
index 0000000..1a49305
--- /dev/null
+++ b/arch/blackfin/Kconfig
@@ -0,0 +1,989 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+mainmenu "uClinux/Blackfin (w/o MMU) Kernel Configuration"
+
+config MMU
+ bool
+ default n
+
+config FPU
+ bool
+ default n
+
+config RWSEM_GENERIC_SPINLOCK
+ bool
+ default y
+
+config RWSEM_XCHGADD_ALGORITHM
+ bool
+ default n
+
+config BLACKFIN
+ bool
+ default y
+
+config BFIN
+ bool
+ default y
+
+config SEMAPHORE_SLEEPERS
+ bool
+ default y
+
+config GENERIC_FIND_NEXT_BIT
+ bool
+ default y
+
+config GENERIC_HWEIGHT
+ bool
+ default y
+
+config GENERIC_HARDIRQS
+ bool
+ default y
+
+config GENERIC_IRQ_PROBE
+ bool
+ default y
+
+config GENERIC_TIME
+ bool
+ default n
+
+config GENERIC_CALIBRATE_DELAY
+ bool
+ default y
+
+config FORCE_MAX_ZONEORDER
+ int
+ default "14"
+
+config GENERIC_CALIBRATE_DELAY
+ bool
+ default y
+
+config IRQCHIP_DEMUX_GPIO
+ bool
+ default y
+
+source "init/Kconfig"
+source "kernel/Kconfig.preempt"
+
+menu "Blackfin Processor Options"
+
+comment "Processor and Board Settings"
+
+choice
+ prompt "CPU"
+ default BF533
+
+config BF531
+ bool "BF531"
+ help
+ BF531 Processor Support.
+
+config BF532
+ bool "BF532"
+ help
+ BF532 Processor Support.
+
+config BF533
+ bool "BF533"
+ help
+ BF533 Processor Support.
+
+config BF534
+ bool "BF534"
+ help
+ BF534 Processor Support.
+
+config BF536
+ bool "BF536"
+ help
+ BF536 Processor Support.
+
+config BF537
+ bool "BF537"
+ help
+ BF537 Processor Support.
+
+config BF561
+ bool "BF561"
+ help
+ Not Supported Yet - Work in progress - BF561 Processor Support.
+
+endchoice
+
+choice
+ prompt "Silicon Rev"
+ default BF_REV_0_2 if BF537
+ default BF_REV_0_3 if BF533
+
+config BF_REV_0_2
+ bool "0.2"
+ depends on (BF537 || BF536 || BF534)
+
+config BF_REV_0_3
+ bool "0.3"
+ depends on (BF561 || BF537 || BF536 || BF534 || BF533 || BF532 || BF531)
+
+config BF_REV_0_4
+ bool "0.4"
+ depends on (BF561 || BF533 || BF532 || BF531)
+
+config BF_REV_0_5
+ bool "0.5"
+ depends on (BF561 || BF533 || BF532 || BF531)
+
+endchoice
+
+config BFIN_DUAL_CORE
+ bool
+ depends on (BF561)
+ default y
+
+config BFIN_SINGLE_CORE
+ bool
+ depends on !BFIN_DUAL_CORE
+ default y
+
+choice
+ prompt "System type"
+ default BFIN533_STAMP
+ help
+ Do NOT change the board here. Please use the top level
+ configuration to ensure that all the other settings are
+ correct.
+
+config BFIN533_EZKIT
+ bool "BF533-EZKIT"
+ depends on (BF533 || BF532 || BF531)
+ help
+ BF533-EZKIT-LITE board Support.
+
+config BFIN533_STAMP
+ bool "BF533-STAMP"
+ depends on (BF533 || BF532 || BF531)
+ help
+ BF533-STAMP board Support.
+
+config BFIN537_STAMP
+ bool "BF537-STAMP"
+ depends on (BF537 || BF536 || BF534)
+ help
+ BF537-STAMP board Support.
+
+config BFIN533_BLUETECHNIX_CM
+ bool "Bluetechnix CM-BF533"
+ depends on (BF533)
+ help
+ CM-BF533 support for EVAL- and DEV-Board.
+
+config BFIN537_BLUETECHNIX_CM
+ bool "Bluetechnix CM-BF537"
+ depends on (BF537)
+ help
+ CM-BF537 support for EVAL- and DEV-Board.
+
+config BFIN561_BLUETECHNIX_CM
+ bool "BF561-CM"
+ depends on (BF561)
+ help
+ CM-BF561 support for EVAL- and DEV-Board.
+
+config BFIN561_EZKIT
+ bool "BF561-EZKIT"
+ depends on (BF561)
+ help
+ BF561-EZKIT-LITE board Support.
+
+config PNAV10
+ bool "PNAV 1.0 board"
+ depends on (BF537)
+ help
+ PNAV 1.0 board Support.
+
+config GENERIC_BOARD
+ bool "Custom"
+ depends on (BF537 || BF536 \
+ || BF534 || BF561 || BF535 || BF533 || BF532 || BF531)
+ help
+ GENERIC or Custom board Support.
+
+endchoice
+
+config MEM_GENERIC_BOARD
+ bool
+ depends on GENERIC_BOARD
+ default y
+
+config MEM_MT48LC64M4A2FB_7E
+ bool
+ depends on (BFIN533_STAMP)
+ default y
+
+config MEM_MT48LC16M16A2TG_75
+ bool
+ depends on (BFIN533_EZKIT || BFIN561_EZKIT \
+ || BFIN533_BLUETECHNIX_CM || BFIN537_BLUETECHNIX_CM)
+ default y
+
+config MEM_MT48LC32M8A2_75
+ bool
+ depends on (BFIN537_STAMP || PNAV10)
+ default y
+
+config MEM_MT48LC8M32B2B5_7
+ bool
+ depends on (BFIN561_BLUETECHNIX_CM)
+ default y
+
+config BFIN_SHARED_FLASH_ENET
+ bool
+ depends on (BFIN533_STAMP)
+ default y
+
+source "arch/blackfin/mach-bf533/Kconfig"
+source "arch/blackfin/mach-bf561/Kconfig"
+source "arch/blackfin/mach-bf537/Kconfig"
+
+menu "Board customizations"
+
+config CMDLINE_BOOL
+ bool "Default bootloader kernel arguments"
+
+config CMDLINE
+ string "Initial kernel command string"
+ depends on CMDLINE_BOOL
+ default "console=ttyBF0,57600"
+ help
+ If you don't have a boot loader capable of passing a command line string
+ to the kernel, you may specify one here. As a minimum, you should specify
+ the memory size and the root device (e.g., mem=8M, root=/dev/nfs).
+
+comment "Board Setup"
+
+config CLKIN_HZ
+ int "Crystal Frequency in Hz"
+ default "11059200" if BFIN533_STAMP
+ default "27000000" if BFIN533_EZKIT
+ default "25000000" if BFIN537_STAMP
+ default "30000000" if BFIN561_EZKIT
+ default "24576000" if PNAV10
+ help
+ The frequency of CLKIN crystal oscillator on the board in Hz.
+
+config MEM_SIZE
+ int "SDRAM Memory Size in MBytes"
+ default 32 if BFIN533_EZKIT
+ default 64 if BFIN537_STAMP
+ default 64 if BFIN561_EZKIT
+ default 128 if BFIN533_STAMP
+ default 64 if PNAV10
+
+config MEM_ADD_WIDTH
+ int "SDRAM Memory Address Width"
+ default 9 if BFIN533_EZKIT
+ default 9 if BFIN561_EZKIT
+ default 10 if BFIN537_STAMP
+ default 11 if BFIN533_STAMP
+ default 10 if PNAV10
+
+config ENET_FLASH_PIN
+ int "PF port/pin used for flash and ethernet sharing"
+ depends on (BFIN533_STAMP)
+ default 0
+ help
+ PF port/pin used for flash and ethernet sharing to allow other PF
+ pins to be used on other platforms without having to touch common
+ code.
+ For example: PF0 --> 0,PF1 --> 1,PF2 --> 2, etc.
+
+config BOOT_LOAD
+ hex "Kernel load address for booting"
+ default "0x1000"
+ help
+ This option allows you to set the load address of the kernel.
+ This can be useful if you are on a board which has a small amount
+ of memory or you wish to reserve some memory at the beginning of
+ the address space.
+
+ Note that you generally want to keep this value at or above 4k
+ (0x1000) as this will allow the kernel to capture NULL pointer
+ references.
+
+comment "LED Status Indicators"
+ depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM)
+
+config BFIN_ALIVE_LED
+ bool "Enable Board Alive"
+ depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM)
+ default n
+ help
+ Blink the LEDs you select when the kernel is running. Helps detect
+ a hung kernel.
+
+config BFIN_ALIVE_LED_NUM
+ int "LED"
+ depends on BFIN_ALIVE_LED
+ range 1 3 if BFIN533_STAMP
+ default "3" if BFIN533_STAMP
+ help
+ Select the LED (marked on the board) for you to blink.
+
+config BFIN_IDLE_LED
+ bool "Enable System Load/Idle LED"
+ depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM)
+ default n
+ help
+ Blinks the LED you select when to determine kernel load.
+
+config BFIN_IDLE_LED_NUM
+ int "LED"
+ depends on BFIN_IDLE_LED
+ range 1 3 if BFIN533_STAMP
+ default "2" if BFIN533_STAMP
+ help
+ Select the LED (marked on the board) for you to blink.
+
+#
+# Sorry - but you need to put the hex address here -
+#
+
+# Flag Data register
+config BFIN_ALIVE_LED_PORT
+ hex
+ default 0xFFC00700 if (BFIN533_STAMP)
+
+# Peripheral Flag Direction Register
+config BFIN_ALIVE_LED_DPORT
+ hex
+ default 0xFFC00730 if (BFIN533_STAMP)
+
+config BFIN_ALIVE_LED_PIN
+ hex
+ default 0x04 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 1)
+ default 0x08 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 2)
+ default 0x10 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 3)
+
+config BFIN_IDLE_LED_PORT
+ hex
+ default 0xFFC00700 if (BFIN533_STAMP)
+
+# Peripheral Flag Direction Register
+config BFIN_IDLE_LED_DPORT
+ hex
+ default 0xFFC00730 if (BFIN533_STAMP)
+
+config BFIN_IDLE_LED_PIN
+ hex
+ default 0x04 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 1)
+ default 0x08 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 2)
+ default 0x10 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 3)
+
+comment "Console UART Setup"
+
+choice
+ prompt "Baud Rate"
+ default BAUD_57600
+config BAUD_9600
+ bool "9600"
+config BAUD_19200
+ bool "19200"
+config BAUD_38400
+ bool "38400"
+config BAUD_57600
+ bool "57600"
+config BAUD_115200
+ bool "115200"
+endchoice
+
+choice
+ prompt "Parity"
+ default BAUD_NO_PARITY
+config BAUD_NO_PARITY
+ bool "No Parity"
+config BAUD_PARITY
+ bool "Parity"
+endchoice
+
+choice
+ prompt "Stop Bits"
+ default BAUD_1_STOPBIT
+config BAUD_1_STOPBIT
+ bool "1"
+config BAUD_2_STOPBIT
+ bool "2"
+endchoice
+
+endmenu
+
+
+menu "Blackfin Kernel Optimizations"
+
+comment "Timer Tick"
+
+source kernel/Kconfig.hz
+
+comment "Memory Optimizations"
+
+config I_ENTRY_L1
+ bool "Locate interrupt entry code in L1 Memory"
+ default y
+ help
+ If enabled interrupt entry code (STORE/RESTORE CONTEXT) is linked
+ into L1 instruction memory.(less latency)
+
+config EXCPT_IRQ_SYSC_L1
+ bool "Locate entire ASM lowlevel excepetion / interrupt - Syscall and CPLB handler code in L1 Memory"
+ default y
+ help
+ If enabled entire ASM lowlevel exception and interrupt entry code (STORE/RESTORE CONTEXT) is linked
+ into L1 instruction memory.(less latency)
+
+config DO_IRQ_L1
+ bool "Locate frequently called do_irq dispatcher function in L1 Memory"
+ default y
+ help
+ If enabled frequently called do_irq dispatcher function is linked
+ into L1 instruction memory.(less latency)
+
+config CORE_TIMER_IRQ_L1
+ bool "Locate frequently called timer_interrupt() function in L1 Memory"
+ default y
+ help
+ If enabled frequently called timer_interrupt() function is linked
+ into L1 instruction memory.(less latency)
+
+config IDLE_L1
+ bool "Locate frequently idle function in L1 Memory"
+ default y
+ help
+ If enabled frequently called idle function is linked
+ into L1 instruction memory.(less latency)
+
+config SCHEDULE_L1
+ bool "Locate kernel schedule function in L1 Memory"
+ default y
+ help
+ If enabled frequently called kernel schedule is linked
+ into L1 instruction memory.(less latency)
+
+config ARITHMETIC_OPS_L1
+ bool "Locate kernel owned arithmetic functions in L1 Memory"
+ default y
+ help
+ If enabled arithmetic functions are linked
+ into L1 instruction memory.(less latency)
+
+config ACCESS_OK_L1
+ bool "Locate access_ok function in L1 Memory"
+ default y
+ help
+ If enabled access_ok function is linked
+ into L1 instruction memory.(less latency)
+
+config MEMSET_L1
+ bool "Locate memset function in L1 Memory"
+ default y
+ help
+ If enabled memset function is linked
+ into L1 instruction memory.(less latency)
+
+config MEMCPY_L1
+ bool "Locate memcpy function in L1 Memory"
+ default y
+ help
+ If enabled memcpy function is linked
+ into L1 instruction memory.(less latency)
+
+config SYS_BFIN_SPINLOCK_L1
+ bool "Locate sys_bfin_spinlock function in L1 Memory"
+ default y
+ help
+ If enabled sys_bfin_spinlock function is linked
+ into L1 instruction memory.(less latency)
+
+config IP_CHECKSUM_L1
+ bool "Locate IP Checksum function in L1 Memory"
+ default n
+ help
+ If enabled IP Checksum function is linked
+ into L1 instruction memory.(less latency)
+
+config CACHELINE_ALIGNED_L1
+ bool "Locate cacheline_aligned data to L1 Data Memory"
+ default y
+ depends on !BF531
+ help
+ If enabled cacheline_anligned data is linked
+ into L1 data memory.(less latency)
+
+config SYSCALL_TAB_L1
+ bool "Locate Syscall Table L1 Data Memory"
+ default n
+ depends on !BF531
+ help
+ If enabled the Syscall LUT is linked
+ into L1 data memory.(less latency)
+
+config CPLB_SWITCH_TAB_L1
+ bool "Locate CPLB Switch Tables L1 Data Memory"
+ default n
+ depends on !BF531
+ help
+ If enabled the CPLB Switch Tables are linked
+ into L1 data memory.(less latency)
+
+endmenu
+
+
+choice
+ prompt "Kernel executes from"
+ help
+ Choose the memory type that the kernel will be running in.
+
+config RAMKERNEL
+ bool "RAM"
+ help
+ The kernel will be resident in RAM when running.
+
+config ROMKERNEL
+ bool "ROM"
+ help
+ The kernel will be resident in FLASH/ROM when running.
+
+endchoice
+
+source "mm/Kconfig"
+
+config LARGE_ALLOCS
+ bool "Allow allocating large blocks (> 1MB) of memory"
+ help
+ Allow the slab memory allocator to keep chains for very large
+ memory sizes - upto 32MB. You may need this if your system has
+ a lot of RAM, and you need to able to allocate very large
+ contiguous chunks. If unsure, say N.
+
+config BFIN_DMA_5XX
+ bool "Enable DMA Support"
+ depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561)
+ default y
+ help
+ DMA driver for BF5xx.
+
+choice
+ prompt "Uncached SDRAM region"
+ default DMA_UNCACHED_1M
+ depends BFIN_DMA_5XX
+config DMA_UNCACHED_2M
+ bool "Enable 2M DMA region"
+config DMA_UNCACHED_1M
+ bool "Enable 1M DMA region"
+config DMA_UNCACHED_NONE
+ bool "Disable DMA region"
+endchoice
+
+
+comment "Cache Support"
+config BLKFIN_CACHE
+ bool "Enable ICACHE"
+config BLKFIN_DCACHE
+ bool "Enable DCACHE"
+config BLKFIN_DCACHE_BANKA
+ bool "Enable only 16k BankA DCACHE - BankB is SRAM"
+ depends on BLKFIN_DCACHE && !BF531
+ default n
+config BLKFIN_CACHE_LOCK
+ bool "Enable Cache Locking"
+
+choice
+ prompt "Policy"
+ depends on BLKFIN_DCACHE
+ default BLKFIN_WB
+config BLKFIN_WB
+ bool "Write back"
+ help
+ Write Back Policy:
+ Cached data will be written back to SDRAM only when needed.
+ This can give a nice increase in performance, but beware of
+ broken drivers that do not properly invalidate/flush their
+ cache.
+
+ Write Through Policy:
+ Cached data will always be written back to SDRAM when the
+ cache is updated. This is a completely safe setting, but
+ performance is worse than Write Back.
+
+ If you are unsure of the options and you want to be safe,
+ then go with Write Through.
+
+config BLKFIN_WT
+ bool "Write through"
+ help
+ Write Back Policy:
+ Cached data will be written back to SDRAM only when needed.
+ This can give a nice increase in performance, but beware of
+ broken drivers that do not properly invalidate/flush their
+ cache.
+
+ Write Through Policy:
+ Cached data will always be written back to SDRAM when the
+ cache is updated. This is a completely safe setting, but
+ performance is worse than Write Back.
+
+ If you are unsure of the options and you want to be safe,
+ then go with Write Through.
+
+endchoice
+
+config L1_MAX_PIECE
+ int "Set the max L1 SRAM pieces"
+ default 16
+ help
+ Set the max memory pieces for the L1 SRAM allocation algorithm.
+ Min value is 16. Max value is 1024.
+
+menu "Clock Settings"
+
+
+config BFIN_KERNEL_CLOCK
+ bool "Re-program Clocks while Kernel boots?"
+ default n
+ help
+ This option decides if kernel clocks are re-programed from the
+ bootloader settings. If the clocks are not set, the SDRAM settings
+ are also not changed, and the Bootloader does 100% of the hardware
+ configuration.
+
+config VCO_MULT
+ int "VCO Multiplier"
+ depends on BFIN_KERNEL_CLOCK
+ default "22" if BFIN533_EZKIT
+ default "45" if BFIN533_STAMP
+ default "20" if BFIN537_STAMP
+ default "22" if BFIN533_BLUETECHNIX_CM
+ default "20" if BFIN537_BLUETECHNIX_CM
+ default "20" if BFIN561_BLUETECHNIX_CM
+ default "20" if BFIN561_EZKIT
+
+config CCLK_DIV
+ int "Core Clock Divider"
+ depends on BFIN_KERNEL_CLOCK
+ default 1 if BFIN533_EZKIT
+ default 1 if BFIN533_STAMP
+ default 1 if BFIN537_STAMP
+ default 1 if BFIN533_BLUETECHNIX_CM
+ default 1 if BFIN537_BLUETECHNIX_CM
+ default 1 if BFIN561_BLUETECHNIX_CM
+ default 1 if BFIN561_EZKIT
+
+config SCLK_DIV
+ int "System Clock Divider"
+ depends on BFIN_KERNEL_CLOCK
+ default 5 if BFIN533_EZKIT
+ default 5 if BFIN533_STAMP
+ default 4 if BFIN537_STAMP
+ default 5 if BFIN533_BLUETECHNIX_CM
+ default 4 if BFIN537_BLUETECHNIX_CM
+ default 4 if BFIN561_BLUETECHNIX_CM
+ default 5 if BFIN561_EZKIT
+
+config CLKIN_HALF
+ bool "Half ClockIn"
+ depends on BFIN_KERNEL_CLOCK
+ default n
+
+config PLL_BYPASS
+ bool "Bypass PLL"
+ depends on BFIN_KERNEL_CLOCK
+ default n
+
+endmenu
+
+comment "Asynchonous Memory Configuration"
+
+menu "EBIU_AMBCTL Global Control"
+config C_AMCKEN
+ bool "Enable CLKOUT"
+ default y
+
+config C_CDPRIO
+ bool "DMA has priority over core for ext. accesses"
+ default n
+
+config C_B0PEN
+ depends on BF561
+ bool "Bank 0 16 bit packing enable"
+ default y
+
+config C_B1PEN
+ depends on BF561
+ bool "Bank 1 16 bit packing enable"
+ default y
+
+config C_B2PEN
+ depends on BF561
+ bool "Bank 2 16 bit packing enable"
+ default y
+
+config C_B3PEN
+ depends on BF561
+ bool "Bank 3 16 bit packing enable"
+ default n
+
+choice
+ prompt"Enable Asynchonous Memory Banks"
+ default C_AMBEN_ALL
+
+config C_AMBEN
+ bool "Disable All Banks"
+
+config C_AMBEN_B0
+ bool "Enable Bank 0"
+
+config C_AMBEN_B0_B1
+ bool "Enable Bank 0 & 1"
+
+config C_AMBEN_B0_B1_B2
+ bool "Enable Bank 0 & 1 & 2"
+
+config C_AMBEN_ALL
+ bool "Enable All Banks"
+endchoice
+endmenu
+
+menu "EBIU_AMBCTL Control"
+config BANK_0
+ hex "Bank 0"
+ default 0x7BB0
+
+config BANK_1
+ hex "Bank 1"
+ default 0x7BB0
+
+config BANK_2
+ hex "Bank 2"
+ default 0x7BB0
+
+config BANK_3
+ hex "Bank 3"
+ default 0x99B3
+endmenu
+
+endmenu
+
+#############################################################################
+menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
+
+config PCI
+ bool "PCI support"
+ help
+ Support for PCI bus.
+
+source "drivers/pci/Kconfig"
+
+config HOTPLUG
+ bool "Support for hot-pluggable device"
+ help
+ Say Y here if you want to plug devices into your computer while
+ the system is running, and be able to use them quickly. In many
+ cases, the devices can likewise be unplugged at any time too.
+
+ One well known example of this is PCMCIA- or PC-cards, credit-card
+ size devices such as network cards, modems or hard drives which are
+ plugged into slots found on all modern laptop computers. Another
+ example, used on modern desktops as well as laptops, is USB.
+
+ Enable HOTPLUG and KMOD, and build a modular kernel. Get agent
+ software (at <http://linux-hotplug.sourceforge.net/>) and install it.
+ Then your kernel will automatically call out to a user mode "policy
+ agent" (/sbin/hotplug) to load modules and set up software needed
+ to use devices as you hotplug them.
+
+source "drivers/pcmcia/Kconfig"
+
+source "drivers/pci/hotplug/Kconfig"
+
+endmenu
+
+menu "Executable file formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+menu "Power management options"
+source "kernel/power/Kconfig"
+
+choice
+ prompt "Select PM Wakeup Event Source"
+ default PM_WAKEUP_GPIO_BY_SIC_IWR
+ depends on PM
+ help
+ If you have a GPIO already configured as input with the corresponding PORTx_MASK
+ bit set - "Specify Wakeup Event by SIC_IWR value"
+
+config PM_WAKEUP_GPIO_BY_SIC_IWR
+ bool "Specify Wakeup Event by SIC_IWR value"
+config PM_WAKEUP_BY_GPIO
+ bool "Cause Wakeup Event by GPIO"
+config PM_WAKEUP_GPIO_API
+ bool "Configure Wakeup Event by PM GPIO API"
+
+endchoice
+
+config PM_WAKEUP_SIC_IWR
+ hex "Wakeup Events (SIC_IWR)"
+ depends on PM_WAKEUP_GPIO_BY_SIC_IWR
+ default 0x80000000 if (BF537 || BF536 || BF534)
+ default 0x100000 if (BF533 || BF532 || BF531)
+
+config PM_WAKEUP_GPIO_NUMBER
+ int "Wakeup GPIO number"
+ range 0 47
+ depends on PM_WAKEUP_BY_GPIO
+ default 2 if BFIN537_STAMP
+
+choice
+ prompt "GPIO Polarity"
+ depends on PM_WAKEUP_BY_GPIO
+ default PM_WAKEUP_GPIO_POLAR_H
+config PM_WAKEUP_GPIO_POLAR_H
+ bool "Active High"
+config PM_WAKEUP_GPIO_POLAR_L
+ bool "Active Low"
+config PM_WAKEUP_GPIO_POLAR_EDGE_F
+ bool "Falling EDGE"
+config PM_WAKEUP_GPIO_POLAR_EDGE_R
+ bool "Rising EDGE"
+config PM_WAKEUP_GPIO_POLAR_EDGE_B
+ bool "Both EDGE"
+endchoice
+
+endmenu
+
+if (BF537 || BF533)
+
+menu "CPU Frequency scaling"
+
+source "drivers/cpufreq/Kconfig"
+
+config CPU_FREQ
+ bool
+ default n
+ help
+ If you want to enable this option, you should select the
+ DPMC driver from Character Devices.
+endmenu
+
+endif
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/blackfin/oprofile/Kconfig"
+
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config DEBUG_HWERR
+ bool "Hardware error interrupt debugging"
+ depends on DEBUG_KERNEL
+ help
+ When enabled, the hardware error interrupt is never disabled, and
+ will happen immediately when an error condition occurs. This comes
+ at a slight cost in code size, but is necessary if you are getting
+ hardware error interrupts and need to know where they are coming
+ from.
+
+config DEBUG_ICACHE_CHECK
+ bool "Check Instruction cache coherancy"
+ depends on DEBUG_KERNEL
+ depends on DEBUG_HWERR
+ help
+ Say Y here if you are getting wierd unexplained errors. This will
+ ensure that icache is what SDRAM says it should be, by doing a
+ byte wise comparision between SDRAM and instruction cache. This
+ also relocates the irq_panic() function to L1 memory, (which is
+ un-cached).
+
+config DEBUG_KERNEL_START
+ bool "Debug Kernel Startup"
+ depends on DEBUG_KERNEL
+ help
+ Say Y here to put in an mini-execption handler before the kernel
+ replaces the bootloader exception handler. This will stop kernels
+ from dieing at startup with no visible error messages.
+
+config DEBUG_SERIAL_EARLY_INIT
+ bool "Initialize serial driver early"
+ default n
+ depends on SERIAL_BFIN
+ help
+ Say Y here if you want to get kernel output early when kernel
+ crashes before the normal console initialization. If this option
+ is enable, console output will always go to the ttyBF0, no matter
+ what kernel boot paramters you set.
+
+config DEBUG_HUNT_FOR_ZERO
+ bool "Catch NULL pointer reads/writes"
+ default y
+ help
+ Say Y here to catch reads/writes to anywhere in the memory range
+ from 0x0000 - 0x0FFF (the first 4k) of memory. This is useful in
+ catching common programming errors such as NULL pointer dereferences.
+
+ Misbehaving applications will be killed (generate a SEGV) while the
+ kernel will trigger a panic.
+
+ Enabling this option will take up an extra entry in CPLB table.
+ Otherwise, there is no extra overhead.
+
+config DEBUG_BFIN_NO_KERN_HWTRACE
+ bool "Trace user apps (turn off hwtrace in kernel)"
+ default n
+ help
+ Some pieces of the kernel contain a lot of flow changes which can
+ quickly fill up the hardware trace buffer. When debugging crashes,
+ the hardware trace may indicate that the problem lies in kernel
+ space when in reality an application is buggy.
+
+ Say Y here to disable hardware tracing in some known "jumpy" pieces
+ of code so that the trace buffer will extend further back.
+
+config DUAL_CORE_TEST_MODULE
+ tristate "Dual Core Test Module"
+ depends on (BF561)
+ default n
+ help
+ Say Y here to build-in dual core test module for dual core test.
+
+config CPLB_INFO
+ bool "Display the CPLB information"
+ help
+ Display the CPLB information.
+
+config ACCESS_CHECK
+ bool "Check the user pointer address"
+ default y
+ help
+ Usually the pointer transfer from user space is checked to see if its
+ address is in the kernel space.
+
+ Say N here to disable that check to improve the performance.
+
+endmenu
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
new file mode 100644
index 0000000..52d4dbd
--- /dev/null
+++ b/arch/blackfin/Makefile
@@ -0,0 +1,80 @@
+#
+# arch/blackfin/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+
+
+CROSS_COMPILE ?= bfin-uclinux-
+LDFLAGS_vmlinux := -X
+OBJCOPYFLAGS := -O binary -R .note -R .comment -S
+GZFLAGS := -9
+
+CFLAGS_MODULE += -mlong-calls
+KALLSYMS += --symbol-prefix=_
+
+
+# setup the machine name and the machine dependent settings
+machine-$(CONFIG_BF531) := bf533
+machine-$(CONFIG_BF532) := bf533
+machine-$(CONFIG_BF533) := bf533
+machine-$(CONFIG_BF534) := bf537
+machine-$(CONFIG_BF536) := bf537
+machine-$(CONFIG_BF537) := bf537
+machine-$(CONFIG_BF561) := bf561
+MACHINE := $(machine-y)
+export MACHINE
+
+
+head-y := arch/$(ARCH)/mach-$(MACHINE)/head.o arch/$(ARCH)/kernel/init_task.o
+
+core-y += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/ arch/$(ARCH)/mach-common/
+
+# If we have a machine-specific directory, then include it in the build.
+ifneq ($(machine-y),)
+core-y += arch/$(ARCH)/mach-$(MACHINE)/
+core-y += arch/$(ARCH)/mach-$(MACHINE)/boards/
+endif
+
+libs-y += arch/$(ARCH)/lib/
+
+drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/
+
+
+
+# Update machine arch symlinks if something which affects
+# them changed. We use .mach to indicate when they were updated
+# last, otherwise make uses the target directory mtime.
+
+include/asm-blackfin/.mach: $(wildcard include/config/arch/*.h) include/config/auto.conf
+ @echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach'
+ifneq ($(KBUILD_SRC),)
+ $(Q)mkdir -p include/asm-$(ARCH)
+ $(Q)ln -fsn $(srctree)/include/asm-$(ARCH)/mach-$(MACHINE) include/asm-$(ARCH)/mach
+else
+ $(Q)ln -fsn mach-$(MACHINE) include/asm-$(ARCH)/mach
+endif
+ @touch $@
+
+CLEAN_FILES += \
+ include/asm-$(ARCH)/asm-offsets.h \
+ arch/$(ARCH)/kernel/asm-offsets.s \
+ include/asm-$(ARCH)/mach \
+ include/asm-$(ARCH)/.mach
+
+archprepare: include/asm-blackfin/.mach
+archclean:
+ $(Q)$(MAKE) $(clean)=$(boot)
+
+
+all: vmImage
+boot := arch/$(ARCH)/boot
+BOOT_TARGETS = vmImage
+.PHONY: $(BOOT_TARGETS)
+$(BOOT_TARGETS): vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+define archhelp
+ echo '* vmImage - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage)'
+endef
diff --git a/arch/blackfin/boot/Makefile b/arch/blackfin/boot/Makefile
new file mode 100644
index 0000000..49e8098
--- /dev/null
+++ b/arch/blackfin/boot/Makefile
@@ -0,0 +1,27 @@
+#
+# arch/blackfin/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+
+MKIMAGE := $(srctree)/scripts/mkuboot.sh
+
+targets := vmImage
+extra-y += vmlinux.bin vmlinux.gz
+
+quiet_cmd_uimage = UIMAGE $@
+ cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \
+ -C gzip -a $(CONFIG_BOOT_LOAD) -e $(CONFIG_BOOT_LOAD) -n 'Linux-$(KERNELRELEASE)' \
+ -d $< $@
+
+$(obj)/vmlinux.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,gzip)
+
+$(obj)/vmImage: $(obj)/vmlinux.gz
+ $(call if_changed,uimage)
+ @echo 'Kernel: $@ is ready'
diff --git a/arch/blackfin/defconfig b/arch/blackfin/defconfig
new file mode 100644
index 0000000..d5904ca
--- /dev/null
+++ b/arch/blackfin/defconfig
@@ -0,0 +1,1314 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.20
+#
+# CONFIG_MMU is not set
+# CONFIG_FPU is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BFIN=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_UCLINUX=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_IRQCHIP_DEMUX_GPIO=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_LIMIT_PAGECACHE is not set
+CONFIG_BUDDY=y
+# CONFIG_NP2 is not set
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Blackfin Processor Options
+#
+
+#
+# Processor and Board Settings
+#
+# CONFIG_BF531 is not set
+# CONFIG_BF532 is not set
+# CONFIG_BF533 is not set
+# CONFIG_BF534 is not set
+# CONFIG_BF535 is not set
+# CONFIG_BF536 is not set
+CONFIG_BF537=y
+# CONFIG_BF561 is not set
+CONFIG_BF_REV_0_2=y
+# CONFIG_BF_REV_0_3 is not set
+# CONFIG_BF_REV_0_4 is not set
+# CONFIG_BF_REV_0_5 is not set
+CONFIG_BLACKFIN=y
+CONFIG_BFIN_SINGLE_CORE=y
+# CONFIG_BFIN533_EZKIT is not set
+# CONFIG_BFIN533_STAMP is not set
+CONFIG_BFIN537_STAMP=y
+# CONFIG_BFIN533_BLUETECHNIX_CM is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM is not set
+# CONFIG_BFIN561_BLUETECHNIX_CM is not set
+# CONFIG_BFIN561_EZKIT is not set
+# CONFIG_PNAV10 is not set
+# CONFIG_GENERIC_BOARD is not set
+CONFIG_MEM_MT48LC32M8A2_75=y
+CONFIG_IRQ_PLL_WAKEUP=7
+
+#
+# BF537 Specific Configuration
+#
+
+#
+# PORT F/G Selection
+#
+CONFIG_BF537_PORT_F=y
+# CONFIG_BF537_PORT_G is not set
+# CONFIG_BF537_PORT_H is not set
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_DMA_ERROR=7
+CONFIG_IRQ_ERROR=7
+CONFIG_IRQ_RTC=8
+CONFIG_IRQ_PPI=8
+CONFIG_IRQ_SPORT0_RX=9
+CONFIG_IRQ_SPORT0_TX=9
+CONFIG_IRQ_SPORT1_RX=9
+CONFIG_IRQ_SPORT1_TX=9
+CONFIG_IRQ_TWI=10
+CONFIG_IRQ_SPI=10
+CONFIG_IRQ_UART0_RX=10
+CONFIG_IRQ_UART0_TX=10
+CONFIG_IRQ_UART1_RX=10
+CONFIG_IRQ_UART1_TX=10
+CONFIG_IRQ_CAN_RX=11
+CONFIG_IRQ_CAN_TX=11
+CONFIG_IRQ_MAC_RX=11
+CONFIG_IRQ_MAC_TX=11
+CONFIG_IRQ_TMR0=12
+CONFIG_IRQ_TMR1=12
+CONFIG_IRQ_TMR2=12
+CONFIG_IRQ_TMR3=12
+CONFIG_IRQ_TMR4=12
+CONFIG_IRQ_TMR5=12
+CONFIG_IRQ_TMR6=12
+CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_PROG_INTA=12
+CONFIG_IRQ_PORTG_INTB=12
+CONFIG_IRQ_MEM_DMA0=13
+CONFIG_IRQ_MEM_DMA1=13
+CONFIG_IRQ_WATCH=13
+
+#
+# Board customizations
+#
+
+#
+# Board Setup
+#
+CONFIG_CLKIN_HZ=25000000
+CONFIG_MEM_SIZE=64
+CONFIG_MEM_ADD_WIDTH=10
+CONFIG_BOOT_LOAD=0x1000
+
+#
+# Console UART Setup
+#
+# CONFIG_BAUD_9600 is not set
+# CONFIG_BAUD_19200 is not set
+# CONFIG_BAUD_38400 is not set
+CONFIG_BAUD_57600=y
+# CONFIG_BAUD_115200 is not set
+CONFIG_BAUD_NO_PARITY=y
+# CONFIG_BAUD_PARITY is not set
+CONFIG_BAUD_1_STOPBIT=y
+# CONFIG_BAUD_2_STOPBIT is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
+#
+# Timer Tick
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+
+#
+# Memory Optimizations
+#
+CONFIG_I_ENTRY_L1=y
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_LARGE_ALLOCS=y
+CONFIG_BFIN_DMA_5XX=y
+# CONFIG_DMA_UNCACHED_2M is not set
+CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_NONE is not set
+
+#
+# Cache Support
+#
+CONFIG_BLKFIN_CACHE=y
+CONFIG_BLKFIN_DCACHE=y
+# CONFIG_BLKFIN_CACHE_LOCK is not set
+# CONFIG_BLKFIN_WB is not set
+CONFIG_BLKFIN_WT=y
+CONFIG_L1_MAX_PIECE=16
+
+#
+# Clock Settings
+#
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+
+#
+# Asynchonous Memory Configuration
+#
+
+#
+# EBIU_AMBCTL Global Control
+#
+CONFIG_C_AMCKEN=y
+CONFIG_C_CDPRIO=y
+# CONFIG_C_AMBEN is not set
+# CONFIG_C_AMBEN_B0 is not set
+# CONFIG_C_AMBEN_B0_B1 is not set
+# CONFIG_C_AMBEN_B0_B1_B2 is not set
+CONFIG_C_AMBEN_ALL=y
+
+#
+# EBIU_AMBCTL Control
+#
+CONFIG_BANK_0=0x7BB0
+CONFIG_BANK_1=0x7BB0
+CONFIG_BANK_2=0x7BB0
+CONFIG_BANK_3=0x99B3
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
+# CONFIG_PM_WAKEUP_BY_GPIO is not set
+# CONFIG_PM_WAKEUP_GPIO_API is not set
+CONFIG_PM_WAKEUP_SIC_IWR=0x80000000
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# Old SIR device drivers
+#
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_MW320D=m
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=m
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_BF5xx=m
+CONFIG_BFIN_FLASH_SIZE=0x400000
+CONFIG_EBIU_FLASH_BASE=0x20000000
+
+#
+# FLASH_EBIU_AMBCTL Control
+#
+CONFIG_BFIN_FLASH_BANK_0=0x7BB0
+CONFIG_BFIN_FLASH_BANK_1=0x7BB0
+CONFIG_BFIN_FLASH_BANK_2=0x7BB0
+CONFIG_BFIN_FLASH_BANK_3=0x7BB0
+CONFIG_MTD_UCLINUX=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_BFIN=m
+CONFIG_BFIN_NAND_BASE=0x20212000
+CONFIG_BFIN_NAND_CLE=2
+CONFIG_BFIN_NAND_ALE=1
+CONFIG_BFIN_NAND_READY=3
+CONFIG_MTD_NAND_IDS=m
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_TIFM_CORE is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_SMC91X is not set
+CONFIG_BFIN_MAC=y
+CONFIG_BFIN_MAC_USE_L1=y
+CONFIG_BFIN_TX_DESC_NUM=10
+CONFIG_BFIN_RX_DESC_NUM=20
+# CONFIG_BFIN_MAC_RMII is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_BF53X_PFBUTTONS is not set
+CONFIG_TWI_KEYPAD=m
+CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=72
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_AD9960 is not set
+# CONFIG_SPI_ADC_BF533 is not set
+# CONFIG_BF533_PFLAGS is not set
+# CONFIG_BF5xx_PPIFCD is not set
+# CONFIG_BF5xx_TIMERS is not set
+# CONFIG_BF5xx_PPI is not set
+CONFIG_BFIN_SPORT=y
+# CONFIG_BFIN_TIMER_LATENCY is not set
+CONFIG_TWI_LCD=m
+CONFIG_TWI_LCD_SLAVE_ADDR=34
+# CONFIG_AD5304 is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+CONFIG_SERIAL_BFIN_DMA=y
+# CONFIG_SERIAL_BFIN_PIO is not set
+CONFIG_SERIAL_BFIN_UART0=y
+# CONFIG_BFIN_UART0_CTSRTS is not set
+# CONFIG_SERIAL_BFIN_UART1 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_BFIN_SPORT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# CAN, the car bus and industrial fieldbus
+#
+CONFIG_CAN4LINUX=y
+
+#
+# linux embedded drivers
+#
+# CONFIG_CAN_MCF5282 is not set
+# CONFIG_CAN_UNCTWINCAN is not set
+CONFIG_CAN_BLACKFIN=m
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+CONFIG_BLACKFIN_DPMC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_BFIN_GPIO is not set
+CONFIG_I2C_BFIN_TWI=m
+CONFIG_TWICLK_KHZ=50
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+CONFIG_SENSORS_AD5252=m
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+CONFIG_SPI_BFIN=y
+
+#
+# SPI Protocol Masters
+#
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB=m
+CONFIG_FB_CFB_FILLRECT=m
+CONFIG_FB_CFB_COPYAREA=m
+CONFIG_FB_CFB_IMAGEBLIT=m
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_BFIN_7171=m
+CONFIG_FB_BFIN_7393=m
+CONFIG_NTSC=y
+# CONFIG_PAL is not set
+# CONFIG_NTSC_640x480 is not set
+# CONFIG_PAL_640x480 is not set
+# CONFIG_NTSC_YCBCR is not set
+# CONFIG_PAL_YCBCR is not set
+CONFIG_ADV7393_1XMEM=y
+# CONFIG_ADV7393_2XMEM is not set
+CONFIG_FB_BF537_LQ035=m
+CONFIG_LQ035_SLAVE_ADDR=0x58
+# CONFIG_FB_BFIN_LANDSCAPE is not set
+# CONFIG_FB_BFIN_BGR is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
+CONFIG_LCD_DEVICE=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_SPI_MMC is not set
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+CONFIG_RTC_DRV_BFIN=y
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Virtualization
+#
+
+#
+# PBX support
+#
+# CONFIG_PBX is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_YAFFS_FS=m
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_HUNT_FOR_ZERO=y
+# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+# CONFIG_BOOTPARAM is not set
+# CONFIG_NO_KERNEL_MSG is not set
+CONFIG_CPLB_INFO=y
+# CONFIG_NO_ACCESS_CHECK is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITY_NETWORK is not set
+CONFIG_SECURITY_CAPABILITIES=y
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
new file mode 100644
index 0000000..f3b7d2f
--- /dev/null
+++ b/arch/blackfin/kernel/Makefile
@@ -0,0 +1,14 @@
+#
+# arch/blackfin/kernel/Makefile
+#
+
+extra-y := init_task.o vmlinux.lds
+
+obj-y := \
+ entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \
+ sys_bfin.o time.o traps.o irqchip.o dma-mapping.o bfin_gpio.o \
+ flat.o
+
+obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o
+obj-$(CONFIG_DUAL_CORE_TEST_MODULE) += dualcore_test.o
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c
new file mode 100644
index 0000000..41d9a9f
--- /dev/null
+++ b/arch/blackfin/kernel/asm-offsets.c
@@ -0,0 +1,136 @@
+/*
+ * File: arch/blackfin/kernel/asm-offsets.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: generate definitions needed by assembly language modules.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/ptrace.h>
+#include <linux/hardirq.h>
+#include <asm/irq.h>
+#include <asm/thread_info.h>
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+int main(void)
+{
+ /* offsets into the task struct */
+ DEFINE(TASK_STATE, offsetof(struct task_struct, state));
+ DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+ DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
+ DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
+ DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+ DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info));
+ DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+ DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+ DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, pending));
+
+ /* offsets into the irq_cpustat_t struct */
+ DEFINE(CPUSTAT_SOFTIRQ_PENDING,
+ offsetof(irq_cpustat_t, __softirq_pending));
+
+ /* offsets into the thread struct */
+ DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
+ DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
+ DEFINE(THREAD_SR, offsetof(struct thread_struct, seqstat));
+ DEFINE(PT_SR, offsetof(struct thread_struct, seqstat));
+ DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
+ DEFINE(THREAD_PC, offsetof(struct thread_struct, pc));
+ DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE);
+
+ /* offsets into the pt_regs */
+ DEFINE(PT_ORIG_P0, offsetof(struct pt_regs, orig_p0));
+ DEFINE(PT_ORIG_PC, offsetof(struct pt_regs, orig_pc));
+ DEFINE(PT_R0, offsetof(struct pt_regs, r0));
+ DEFINE(PT_R1, offsetof(struct pt_regs, r1));
+ DEFINE(PT_R2, offsetof(struct pt_regs, r2));
+ DEFINE(PT_R3, offsetof(struct pt_regs, r3));
+ DEFINE(PT_R4, offsetof(struct pt_regs, r4));
+ DEFINE(PT_R5, offsetof(struct pt_regs, r5));
+ DEFINE(PT_R6, offsetof(struct pt_regs, r6));
+ DEFINE(PT_R7, offsetof(struct pt_regs, r7));
+
+ DEFINE(PT_P0, offsetof(struct pt_regs, p0));
+ DEFINE(PT_P1, offsetof(struct pt_regs, p1));
+ DEFINE(PT_P2, offsetof(struct pt_regs, p2));
+ DEFINE(PT_P3, offsetof(struct pt_regs, p3));
+ DEFINE(PT_P4, offsetof(struct pt_regs, p4));
+ DEFINE(PT_P5, offsetof(struct pt_regs, p5));
+
+ DEFINE(PT_FP, offsetof(struct pt_regs, fp));
+ DEFINE(PT_USP, offsetof(struct pt_regs, usp));
+ DEFINE(PT_I0, offsetof(struct pt_regs, i0));
+ DEFINE(PT_I1, offsetof(struct pt_regs, i1));
+ DEFINE(PT_I2, offsetof(struct pt_regs, i2));
+ DEFINE(PT_I3, offsetof(struct pt_regs, i3));
+ DEFINE(PT_M0, offsetof(struct pt_regs, m0));
+ DEFINE(PT_M1, offsetof(struct pt_regs, m1));
+ DEFINE(PT_M2, offsetof(struct pt_regs, m2));
+ DEFINE(PT_M3, offsetof(struct pt_regs, m3));
+ DEFINE(PT_L0, offsetof(struct pt_regs, l0));
+ DEFINE(PT_L1, offsetof(struct pt_regs, l1));
+ DEFINE(PT_L2, offsetof(struct pt_regs, l2));
+ DEFINE(PT_L3, offsetof(struct pt_regs, l3));
+ DEFINE(PT_B0, offsetof(struct pt_regs, b0));
+ DEFINE(PT_B1, offsetof(struct pt_regs, b1));
+ DEFINE(PT_B2, offsetof(struct pt_regs, b2));
+ DEFINE(PT_B3, offsetof(struct pt_regs, b3));
+ DEFINE(PT_A0X, offsetof(struct pt_regs, a0x));
+ DEFINE(PT_A0W, offsetof(struct pt_regs, a0w));
+ DEFINE(PT_A1X, offsetof(struct pt_regs, a1x));
+ DEFINE(PT_A1W, offsetof(struct pt_regs, a1w));
+ DEFINE(PT_LC0, offsetof(struct pt_regs, lc0));
+ DEFINE(PT_LC1, offsetof(struct pt_regs, lc1));
+ DEFINE(PT_LT0, offsetof(struct pt_regs, lt0));
+ DEFINE(PT_LT1, offsetof(struct pt_regs, lt1));
+ DEFINE(PT_LB0, offsetof(struct pt_regs, lb0));
+ DEFINE(PT_LB1, offsetof(struct pt_regs, lb1));
+ DEFINE(PT_ASTAT, offsetof(struct pt_regs, astat));
+ DEFINE(PT_RESERVED, offsetof(struct pt_regs, reserved));
+ DEFINE(PT_RETS, offsetof(struct pt_regs, rets));
+ DEFINE(PT_PC, offsetof(struct pt_regs, pc));
+ DEFINE(PT_RETX, offsetof(struct pt_regs, retx));
+ DEFINE(PT_RETN, offsetof(struct pt_regs, retn));
+ DEFINE(PT_RETE, offsetof(struct pt_regs, rete));
+ DEFINE(PT_SEQSTAT, offsetof(struct pt_regs, seqstat));
+ DEFINE(PT_SYSCFG, offsetof(struct pt_regs, syscfg));
+ DEFINE(PT_IPEND, offsetof(struct pt_regs, ipend));
+ DEFINE(SIZEOF_PTREGS, sizeof(struct pt_regs));
+ DEFINE(PT_TEXT_ADDR, sizeof(struct pt_regs)); /* Needed by gdb */
+ DEFINE(PT_TEXT_END_ADDR, 4 + sizeof(struct pt_regs));/* Needed by gdb */
+ DEFINE(PT_DATA_ADDR, 8 + sizeof(struct pt_regs)); /* Needed by gdb */
+ DEFINE(PT_FDPIC_EXEC, 12 + sizeof(struct pt_regs)); /* Needed by gdb */
+ DEFINE(PT_FDPIC_INTERP, 16 + sizeof(struct pt_regs));/* Needed by gdb */
+
+ /* signal defines */
+ DEFINE(SIGSEGV, SIGSEGV);
+ DEFINE(SIGTRAP, SIGTRAP);
+
+ return 0;
+}
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
new file mode 100644
index 0000000..8ea079e
--- /dev/null
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -0,0 +1,742 @@
+/*
+ * File: arch/blackfin/kernel/bfin_dma_5xx.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+
+#include <asm/dma.h>
+#include <asm/cacheflush.h>
+
+/* Remove unused code not exported by symbol or internally called */
+#define REMOVE_DEAD_CODE
+
+/**************************************************************************
+ * Global Variables
+***************************************************************************/
+
+static struct dma_channel dma_ch[MAX_BLACKFIN_DMA_CHANNEL];
+#if defined (CONFIG_BF561)
+static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
+ (struct dma_register *) DMA1_0_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_1_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_2_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_3_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_4_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_5_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_6_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_7_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_8_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_9_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_10_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_11_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_0_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_1_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_2_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_3_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_4_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_5_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_6_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_7_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_8_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_9_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_10_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_11_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA1_D0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA1_S0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA1_D1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA1_S1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA2_D0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA2_S0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA2_D1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA2_S1_NEXT_DESC_PTR,
+ (struct dma_register *) IMDMA_D0_NEXT_DESC_PTR,
+ (struct dma_register *) IMDMA_S0_NEXT_DESC_PTR,
+ (struct dma_register *) IMDMA_D1_NEXT_DESC_PTR,
+ (struct dma_register *) IMDMA_S1_NEXT_DESC_PTR,
+};
+#else
+static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
+ (struct dma_register *) DMA0_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_NEXT_DESC_PTR,
+ (struct dma_register *) DMA3_NEXT_DESC_PTR,
+ (struct dma_register *) DMA4_NEXT_DESC_PTR,
+ (struct dma_register *) DMA5_NEXT_DESC_PTR,
+ (struct dma_register *) DMA6_NEXT_DESC_PTR,
+ (struct dma_register *) DMA7_NEXT_DESC_PTR,
+#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536))
+ (struct dma_register *) DMA8_NEXT_DESC_PTR,
+ (struct dma_register *) DMA9_NEXT_DESC_PTR,
+ (struct dma_register *) DMA10_NEXT_DESC_PTR,
+ (struct dma_register *) DMA11_NEXT_DESC_PTR,
+#endif
+ (struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
+};
+#endif
+
+/*------------------------------------------------------------------------------
+ * Set the Buffer Clear bit in the Configuration register of specific DMA
+ * channel. This will stop the descriptor based DMA operation.
+ *-----------------------------------------------------------------------------*/
+static void clear_dma_buffer(unsigned int channel)
+{
+ dma_ch[channel].regs->cfg |= RESTART;
+ SSYNC();
+ dma_ch[channel].regs->cfg &= ~RESTART;
+ SSYNC();
+}
+
+int __init blackfin_dma_init(void)
+{
+ int i;
+
+ printk(KERN_INFO "Blackfin DMA Controller\n");
+
+ for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) {
+ dma_ch[i].chan_status = DMA_CHANNEL_FREE;
+ dma_ch[i].regs = base_addr[i];
+ mutex_init(&(dma_ch[i].dmalock));
+ }
+
+ return 0;
+}
+
+arch_initcall(blackfin_dma_init);
+
+/*
+ * Form the channel find the irq number for that channel.
+ */
+#if !defined(CONFIG_BF561)
+
+static int bf533_channel2irq(unsigned int channel)
+{
+ int ret_irq = -1;
+
+ switch (channel) {
+ case CH_PPI:
+ ret_irq = IRQ_PPI;
+ break;
+
+#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536))
+ case CH_EMAC_RX:
+ ret_irq = IRQ_MAC_RX;
+ break;
+
+ case CH_EMAC_TX:
+ ret_irq = IRQ_MAC_TX;
+ break;
+
+ case CH_UART1_RX:
+ ret_irq = IRQ_UART1_RX;
+ break;
+
+ case CH_UART1_TX:
+ ret_irq = IRQ_UART1_TX;
+ break;
+#endif
+
+ case CH_SPORT0_RX:
+ ret_irq = IRQ_SPORT0_RX;
+ break;
+
+ case CH_SPORT0_TX:
+ ret_irq = IRQ_SPORT0_TX;
+ break;
+
+ case CH_SPORT1_RX:
+ ret_irq = IRQ_SPORT1_RX;
+ break;
+
+ case CH_SPORT1_TX:
+ ret_irq = IRQ_SPORT1_TX;
+ break;
+
+ case CH_SPI:
+ ret_irq = IRQ_SPI;
+ break;
+
+ case CH_UART_RX:
+ ret_irq = IRQ_UART_RX;
+ break;
+
+ case CH_UART_TX:
+ ret_irq = IRQ_UART_TX;
+ break;
+
+ case CH_MEM_STREAM0_SRC:
+ case CH_MEM_STREAM0_DEST:
+ ret_irq = IRQ_MEM_DMA0;
+ break;
+
+ case CH_MEM_STREAM1_SRC:
+ case CH_MEM_STREAM1_DEST:
+ ret_irq = IRQ_MEM_DMA1;
+ break;
+ }
+ return ret_irq;
+}
+
+# define channel2irq(channel) bf533_channel2irq(channel)
+
+#else
+
+static int bf561_channel2irq(unsigned int channel)
+{
+ int ret_irq = -1;
+
+ switch (channel) {
+ case CH_PPI0:
+ ret_irq = IRQ_PPI0;
+ break;
+ case CH_PPI1:
+ ret_irq = IRQ_PPI1;
+ break;
+ case CH_SPORT0_RX:
+ ret_irq = IRQ_SPORT0_RX;
+ break;
+ case CH_SPORT0_TX:
+ ret_irq = IRQ_SPORT0_TX;
+ break;
+ case CH_SPORT1_RX:
+ ret_irq = IRQ_SPORT1_RX;
+ break;
+ case CH_SPORT1_TX:
+ ret_irq = IRQ_SPORT1_TX;
+ break;
+ case CH_SPI:
+ ret_irq = IRQ_SPI;
+ break;
+ case CH_UART_RX:
+ ret_irq = IRQ_UART_RX;
+ break;
+ case CH_UART_TX:
+ ret_irq = IRQ_UART_TX;
+ break;
+
+ case CH_MEM_STREAM0_SRC:
+ case CH_MEM_STREAM0_DEST:
+ ret_irq = IRQ_MEM_DMA0;
+ break;
+ case CH_MEM_STREAM1_SRC:
+ case CH_MEM_STREAM1_DEST:
+ ret_irq = IRQ_MEM_DMA1;
+ break;
+ case CH_MEM_STREAM2_SRC:
+ case CH_MEM_STREAM2_DEST:
+ ret_irq = IRQ_MEM_DMA2;
+ break;
+ case CH_MEM_STREAM3_SRC:
+ case CH_MEM_STREAM3_DEST:
+ ret_irq = IRQ_MEM_DMA3;
+ break;
+
+ case CH_IMEM_STREAM0_SRC:
+ case CH_IMEM_STREAM0_DEST:
+ ret_irq = IRQ_IMEM_DMA0;
+ break;
+ case CH_IMEM_STREAM1_SRC:
+ case CH_IMEM_STREAM1_DEST:
+ ret_irq = IRQ_IMEM_DMA1;
+ break;
+ }
+ return ret_irq;
+}
+
+# define channel2irq(channel) bf561_channel2irq(channel)
+
+#endif
+
+/*------------------------------------------------------------------------------
+ * Request the specific DMA channel from the system.
+ *-----------------------------------------------------------------------------*/
+int request_dma(unsigned int channel, char *device_id)
+{
+
+ pr_debug("request_dma() : BEGIN \n");
+ mutex_lock(&(dma_ch[channel].dmalock));
+
+ if ((dma_ch[channel].chan_status == DMA_CHANNEL_REQUESTED)
+ || (dma_ch[channel].chan_status == DMA_CHANNEL_ENABLED)) {
+ mutex_unlock(&(dma_ch[channel].dmalock));
+ pr_debug("DMA CHANNEL IN USE \n");
+ return -EBUSY;
+ } else {
+ dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED;
+ pr_debug("DMA CHANNEL IS ALLOCATED \n");
+ }
+
+ mutex_unlock(&(dma_ch[channel].dmalock));
+
+ dma_ch[channel].device_id = device_id;
+ dma_ch[channel].irq_callback = NULL;
+
+ /* This is to be enabled by putting a restriction -
+ * you have to request DMA, before doing any operations on
+ * descriptor/channel
+ */
+ pr_debug("request_dma() : END \n");
+ return channel;
+}
+EXPORT_SYMBOL(request_dma);
+
+int set_dma_callback(unsigned int channel, dma_interrupt_t callback, void *data)
+{
+ int ret_irq = 0;
+
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ if (callback != NULL) {
+ int ret_val;
+ ret_irq = channel2irq(channel);
+
+ dma_ch[channel].data = data;
+
+ ret_val =
+ request_irq(ret_irq, (void *)callback, IRQF_DISABLED,
+ dma_ch[channel].device_id, data);
+ if (ret_val) {
+ printk(KERN_NOTICE
+ "Request irq in DMA engine failed.\n");
+ return -EPERM;
+ }
+ dma_ch[channel].irq_callback = callback;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(set_dma_callback);
+
+void free_dma(unsigned int channel)
+{
+ int ret_irq;
+
+ pr_debug("freedma() : BEGIN \n");
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ /* Halt the DMA */
+ disable_dma(channel);
+ clear_dma_buffer(channel);
+
+ if (dma_ch[channel].irq_callback != NULL) {
+ ret_irq = channel2irq(channel);
+ free_irq(ret_irq, dma_ch[channel].data);
+ }
+
+ /* Clear the DMA Variable in the Channel */
+ mutex_lock(&(dma_ch[channel].dmalock));
+ dma_ch[channel].chan_status = DMA_CHANNEL_FREE;
+ mutex_unlock(&(dma_ch[channel].dmalock));
+
+ pr_debug("freedma() : END \n");
+}
+EXPORT_SYMBOL(free_dma);
+
+void dma_enable_irq(unsigned int channel)
+{
+ int ret_irq;
+
+ pr_debug("dma_enable_irq() : BEGIN \n");
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ ret_irq = channel2irq(channel);
+ enable_irq(ret_irq);
+}
+EXPORT_SYMBOL(dma_enable_irq);
+
+void dma_disable_irq(unsigned int channel)
+{
+ int ret_irq;
+
+ pr_debug("dma_disable_irq() : BEGIN \n");
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ ret_irq = channel2irq(channel);
+ disable_irq(ret_irq);
+}
+EXPORT_SYMBOL(dma_disable_irq);
+
+int dma_channel_active(unsigned int channel)
+{
+ if (dma_ch[channel].chan_status == DMA_CHANNEL_FREE) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+EXPORT_SYMBOL(dma_channel_active);
+
+/*------------------------------------------------------------------------------
+* stop the specific DMA channel.
+*-----------------------------------------------------------------------------*/
+void disable_dma(unsigned int channel)
+{
+ pr_debug("stop_dma() : BEGIN \n");
+
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->cfg &= ~DMAEN; /* Clean the enable bit */
+ SSYNC();
+ dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED;
+ /* Needs to be enabled Later */
+ pr_debug("stop_dma() : END \n");
+ return;
+}
+EXPORT_SYMBOL(disable_dma);
+
+void enable_dma(unsigned int channel)
+{
+ pr_debug("enable_dma() : BEGIN \n");
+
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].chan_status = DMA_CHANNEL_ENABLED;
+ dma_ch[channel].regs->curr_x_count = 0;
+ dma_ch[channel].regs->curr_y_count = 0;
+
+ dma_ch[channel].regs->cfg |= DMAEN; /* Set the enable bit */
+ SSYNC();
+ pr_debug("enable_dma() : END \n");
+ return;
+}
+EXPORT_SYMBOL(enable_dma);
+
+/*------------------------------------------------------------------------------
+* Set the Start Address register for the specific DMA channel
+* This function can be used for register based DMA,
+* to setup the start address
+* addr: Starting address of the DMA Data to be transferred.
+*-----------------------------------------------------------------------------*/
+void set_dma_start_addr(unsigned int channel, unsigned long addr)
+{
+ pr_debug("set_dma_start_addr() : BEGIN \n");
+
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->start_addr = addr;
+ SSYNC();
+ pr_debug("set_dma_start_addr() : END\n");
+}
+EXPORT_SYMBOL(set_dma_start_addr);
+
+void set_dma_next_desc_addr(unsigned int channel, unsigned long addr)
+{
+ pr_debug("set_dma_next_desc_addr() : BEGIN \n");
+
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->next_desc_ptr = addr;
+ SSYNC();
+ pr_debug("set_dma_start_addr() : END\n");
+}
+EXPORT_SYMBOL(set_dma_next_desc_addr);
+
+void set_dma_x_count(unsigned int channel, unsigned short x_count)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->x_count = x_count;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_dma_x_count);
+
+void set_dma_y_count(unsigned int channel, unsigned short y_count)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->y_count = y_count;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_dma_y_count);
+
+void set_dma_x_modify(unsigned int channel, short x_modify)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->x_modify = x_modify;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_dma_x_modify);
+
+void set_dma_y_modify(unsigned int channel, short y_modify)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->y_modify = y_modify;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_dma_y_modify);
+
+void set_dma_config(unsigned int channel, unsigned short config)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->cfg = config;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_dma_config);
+
+unsigned short
+set_bfin_dma_config(char direction, char flow_mode,
+ char intr_mode, char dma_mode, char width)
+{
+ unsigned short config;
+
+ config =
+ ((direction << 1) | (width << 2) | (dma_mode << 4) |
+ (intr_mode << 6) | (flow_mode << 12) | RESTART);
+ return config;
+}
+EXPORT_SYMBOL(set_bfin_dma_config);
+
+void set_dma_sg(unsigned int channel, struct dmasg * sg, int nr_sg)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ dma_ch[channel].regs->cfg |= ((nr_sg & 0x0F) << 8);
+
+ dma_ch[channel].regs->next_desc_ptr = (unsigned int)sg;
+
+ SSYNC();
+}
+EXPORT_SYMBOL(set_dma_sg);
+
+/*------------------------------------------------------------------------------
+ * Get the DMA status of a specific DMA channel from the system.
+ *-----------------------------------------------------------------------------*/
+unsigned short get_dma_curr_irqstat(unsigned int channel)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ return dma_ch[channel].regs->irq_status;
+}
+EXPORT_SYMBOL(get_dma_curr_irqstat);
+
+/*------------------------------------------------------------------------------
+ * Clear the DMA_DONE bit in DMA status. Stop the DMA completion interrupt.
+ *-----------------------------------------------------------------------------*/
+void clear_dma_irqstat(unsigned int channel)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+ dma_ch[channel].regs->irq_status |= 3;
+}
+EXPORT_SYMBOL(clear_dma_irqstat);
+
+/*------------------------------------------------------------------------------
+ * Get current DMA xcount of a specific DMA channel from the system.
+ *-----------------------------------------------------------------------------*/
+unsigned short get_dma_curr_xcount(unsigned int channel)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ return dma_ch[channel].regs->curr_x_count;
+}
+EXPORT_SYMBOL(get_dma_curr_xcount);
+
+/*------------------------------------------------------------------------------
+ * Get current DMA ycount of a specific DMA channel from the system.
+ *-----------------------------------------------------------------------------*/
+unsigned short get_dma_curr_ycount(unsigned int channel)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ return dma_ch[channel].regs->curr_y_count;
+}
+EXPORT_SYMBOL(get_dma_curr_ycount);
+
+void *dma_memcpy(void *dest, const void *src, size_t size)
+{
+ int direction; /* 1 - address decrease, 0 - address increase */
+ int flag_align; /* 1 - address aligned, 0 - address unaligned */
+ int flag_2D; /* 1 - 2D DMA needed, 0 - 1D DMA needed */
+
+ if (size <= 0)
+ return NULL;
+
+ if ((unsigned long)src < memory_end)
+ blackfin_dcache_flush_range((unsigned int)src,
+ (unsigned int)(src + size));
+
+ bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
+
+ if ((unsigned long)src < (unsigned long)dest)
+ direction = 1;
+ else
+ direction = 0;
+
+ if ((((unsigned long)dest % 2) == 0) && (((unsigned long)src % 2) == 0)
+ && ((size % 2) == 0))
+ flag_align = 1;
+ else
+ flag_align = 0;
+
+ if (size > 0x10000) /* size > 64K */
+ flag_2D = 1;
+ else
+ flag_2D = 0;
+
+ /* Setup destination and source start address */
+ if (direction) {
+ if (flag_align) {
+ bfin_write_MDMA_D0_START_ADDR(dest + size - 2);
+ bfin_write_MDMA_S0_START_ADDR(src + size - 2);
+ } else {
+ bfin_write_MDMA_D0_START_ADDR(dest + size - 1);
+ bfin_write_MDMA_S0_START_ADDR(src + size - 1);
+ }
+ } else {
+ bfin_write_MDMA_D0_START_ADDR(dest);
+ bfin_write_MDMA_S0_START_ADDR(src);
+ }
+
+ /* Setup destination and source xcount */
+ if (flag_2D) {
+ if (flag_align) {
+ bfin_write_MDMA_D0_X_COUNT(1024 / 2);
+ bfin_write_MDMA_S0_X_COUNT(1024 / 2);
+ } else {
+ bfin_write_MDMA_D0_X_COUNT(1024);
+ bfin_write_MDMA_S0_X_COUNT(1024);
+ }
+ bfin_write_MDMA_D0_Y_COUNT(size >> 10);
+ bfin_write_MDMA_S0_Y_COUNT(size >> 10);
+ } else {
+ if (flag_align) {
+ bfin_write_MDMA_D0_X_COUNT(size / 2);
+ bfin_write_MDMA_S0_X_COUNT(size / 2);
+ } else {
+ bfin_write_MDMA_D0_X_COUNT(size);
+ bfin_write_MDMA_S0_X_COUNT(size);
+ }
+ }
+
+ /* Setup destination and source xmodify and ymodify */
+ if (direction) {
+ if (flag_align) {
+ bfin_write_MDMA_D0_X_MODIFY(-2);
+ bfin_write_MDMA_S0_X_MODIFY(-2);
+ if (flag_2D) {
+ bfin_write_MDMA_D0_Y_MODIFY(-2);
+ bfin_write_MDMA_S0_Y_MODIFY(-2);
+ }
+ } else {
+ bfin_write_MDMA_D0_X_MODIFY(-1);
+ bfin_write_MDMA_S0_X_MODIFY(-1);
+ if (flag_2D) {
+ bfin_write_MDMA_D0_Y_MODIFY(-1);
+ bfin_write_MDMA_S0_Y_MODIFY(-1);
+ }
+ }
+ } else {
+ if (flag_align) {
+ bfin_write_MDMA_D0_X_MODIFY(2);
+ bfin_write_MDMA_S0_X_MODIFY(2);
+ if (flag_2D) {
+ bfin_write_MDMA_D0_Y_MODIFY(2);
+ bfin_write_MDMA_S0_Y_MODIFY(2);
+ }
+ } else {
+ bfin_write_MDMA_D0_X_MODIFY(1);
+ bfin_write_MDMA_S0_X_MODIFY(1);
+ if (flag_2D) {
+ bfin_write_MDMA_D0_Y_MODIFY(1);
+ bfin_write_MDMA_S0_Y_MODIFY(1);
+ }
+ }
+ }
+
+ /* Enable source DMA */
+ if (flag_2D) {
+ if (flag_align) {
+ bfin_write_MDMA_S0_CONFIG(DMAEN | DMA2D | WDSIZE_16);
+ bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | DMA2D | WDSIZE_16);
+ } else {
+ bfin_write_MDMA_S0_CONFIG(DMAEN | DMA2D);
+ bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | DMA2D);
+ }
+ } else {
+ if (flag_align) {
+ bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16);
+ bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16);
+ } else {
+ bfin_write_MDMA_S0_CONFIG(DMAEN);
+ bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN);
+ }
+ }
+
+ while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE))
+ ;
+
+ bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() |
+ (DMA_DONE | DMA_ERR));
+
+ bfin_write_MDMA_S0_CONFIG(0);
+ bfin_write_MDMA_D0_CONFIG(0);
+
+ if ((unsigned long)dest < memory_end)
+ blackfin_dcache_invalidate_range((unsigned int)dest,
+ (unsigned int)(dest + size));
+
+ return dest;
+}
+EXPORT_SYMBOL(dma_memcpy);
+
+void *safe_dma_memcpy(void *dest, const void *src, size_t size)
+{
+ int flags = 0;
+ void *addr;
+ local_irq_save(flags);
+ addr = dma_memcpy(dest, src, size);
+ local_irq_restore(flags);
+ return addr;
+}
+EXPORT_SYMBOL(safe_dma_memcpy);
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
new file mode 100644
index 0000000..e9f24a9
--- /dev/null
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -0,0 +1,637 @@
+/*
+ * File: arch/blackfin/kernel/bfin_gpio.c
+ * Based on:
+ * Author: Michael Hennerich (hennerich@blackfin.uclinux.org)
+ *
+ * Created:
+ * Description: GPIO Abstraction Layer
+ *
+ * Modified:
+ * Copyright 2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+* Number BF537/6/4 BF561 BF533/2/1
+*
+* GPIO_0 PF0 PF0 PF0
+* GPIO_1 PF1 PF1 PF1
+* GPIO_2 PF2 PF2 PF2
+* GPIO_3 PF3 PF3 PF3
+* GPIO_4 PF4 PF4 PF4
+* GPIO_5 PF5 PF5 PF5
+* GPIO_6 PF6 PF6 PF6
+* GPIO_7 PF7 PF7 PF7
+* GPIO_8 PF8 PF8 PF8
+* GPIO_9 PF9 PF9 PF9
+* GPIO_10 PF10 PF10 PF10
+* GPIO_11 PF11 PF11 PF11
+* GPIO_12 PF12 PF12 PF12
+* GPIO_13 PF13 PF13 PF13
+* GPIO_14 PF14 PF14 PF14
+* GPIO_15 PF15 PF15 PF15
+* GPIO_16 PG0 PF16
+* GPIO_17 PG1 PF17
+* GPIO_18 PG2 PF18
+* GPIO_19 PG3 PF19
+* GPIO_20 PG4 PF20
+* GPIO_21 PG5 PF21
+* GPIO_22 PG6 PF22
+* GPIO_23 PG7 PF23
+* GPIO_24 PG8 PF24
+* GPIO_25 PG9 PF25
+* GPIO_26 PG10 PF26
+* GPIO_27 PG11 PF27
+* GPIO_28 PG12 PF28
+* GPIO_29 PG13 PF29
+* GPIO_30 PG14 PF30
+* GPIO_31 PG15 PF31
+* GPIO_32 PH0 PF32
+* GPIO_33 PH1 PF33
+* GPIO_34 PH2 PF34
+* GPIO_35 PH3 PF35
+* GPIO_36 PH4 PF36
+* GPIO_37 PH5 PF37
+* GPIO_38 PH6 PF38
+* GPIO_39 PH7 PF39
+* GPIO_40 PH8 PF40
+* GPIO_41 PH9 PF41
+* GPIO_42 PH10 PF42
+* GPIO_43 PH11 PF43
+* GPIO_44 PH12 PF44
+* GPIO_45 PH13 PF45
+* GPIO_46 PH14 PF46
+* GPIO_47 PH15 PF47
+*/
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <asm/blackfin.h>
+#include <asm/gpio.h>
+#include <linux/irq.h>
+
+#ifdef BF533_FAMILY
+static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+ (struct gpio_port_t *) FIO_FLAG_D,
+};
+#endif
+
+#ifdef BF537_FAMILY
+static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+ (struct gpio_port_t *) PORTFIO,
+ (struct gpio_port_t *) PORTGIO,
+ (struct gpio_port_t *) PORTHIO,
+};
+
+static unsigned short *port_fer[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+ (unsigned short *) PORTF_FER,
+ (unsigned short *) PORTG_FER,
+ (unsigned short *) PORTH_FER,
+};
+
+#endif
+
+#ifdef BF561_FAMILY
+static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+ (struct gpio_port_t *) FIO0_FLAG_D,
+ (struct gpio_port_t *) FIO1_FLAG_D,
+ (struct gpio_port_t *) FIO2_FLAG_D,
+};
+#endif
+
+static unsigned short reserved_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
+
+#ifdef CONFIG_PM
+static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
+static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS];
+static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)];
+
+#ifdef BF533_FAMILY
+static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB};
+#endif
+
+#ifdef BF537_FAMILY
+static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX};
+#endif
+
+#ifdef BF561_FAMILY
+static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB};
+#endif
+
+#endif /* CONFIG_PM */
+
+inline int check_gpio(unsigned short gpio)
+{
+ if (gpio > MAX_BLACKFIN_GPIOS)
+ return -EINVAL;
+ return 0;
+}
+
+#ifdef BF537_FAMILY
+void port_setup(unsigned short gpio, unsigned short usage)
+{
+ if (usage == GPIO_USAGE) {
+ if (*port_fer[gpio_bank(gpio)] & gpio_bit(gpio))
+ printk(KERN_WARNING "bfin-gpio: Possible Conflict with Peripheral "
+ "usage and GPIO %d detected!\n", gpio);
+ *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+ } else
+ *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
+ SSYNC();
+}
+#else
+# define port_setup(...) do { } while (0)
+#endif
+
+
+void default_gpio(unsigned short gpio)
+{
+ unsigned short bank,bitmask;
+
+ bank = gpio_bank(gpio);
+ bitmask = gpio_bit(gpio);
+
+ gpio_bankb[bank]->maska_clear = bitmask;
+ gpio_bankb[bank]->maskb_clear = bitmask;
+ SSYNC();
+ gpio_bankb[bank]->inen &= ~bitmask;
+ gpio_bankb[bank]->dir &= ~bitmask;
+ gpio_bankb[bank]->polar &= ~bitmask;
+ gpio_bankb[bank]->both &= ~bitmask;
+ gpio_bankb[bank]->edge &= ~bitmask;
+}
+
+
+int __init bfin_gpio_init(void)
+{
+ int i;
+
+ printk(KERN_INFO "Blackfin GPIO Controller\n");
+
+ for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE)
+ reserved_map[gpio_bank(i)] = 0;
+
+#if defined(BF537_FAMILY) && (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
+# if defined(CONFIG_BFIN_MAC_RMII)
+ reserved_map[PORT_H] = 0xC373;
+# else
+ reserved_map[PORT_H] = 0xFFFF;
+# endif
+#endif
+
+ return 0;
+}
+
+arch_initcall(bfin_gpio_init);
+
+
+/***********************************************************
+*
+* FUNCTIONS: Blackfin General Purpose Ports Access Functions
+*
+* INPUTS/OUTPUTS:
+* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
+*
+*
+* DESCRIPTION: These functions abstract direct register access
+* to Blackfin processor General Purpose
+* Ports Regsiters
+*
+* CAUTION: These functions do not belong to the GPIO Driver API
+*************************************************************
+* MODIFICATION HISTORY :
+**************************************************************/
+
+/* Set a specific bit */
+
+#define SET_GPIO(name) \
+void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
+{ \
+ unsigned long flags; \
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
+ local_irq_save(flags); \
+ if (arg) \
+ gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
+ else \
+ gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \
+ local_irq_restore(flags); \
+} \
+EXPORT_SYMBOL(set_gpio_ ## name);
+
+SET_GPIO(dir)
+SET_GPIO(inen)
+SET_GPIO(polar)
+SET_GPIO(edge)
+SET_GPIO(both)
+
+
+#define SET_GPIO_SC(name) \
+void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
+{ \
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
+ if (arg) \
+ gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
+ else \
+ gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
+} \
+EXPORT_SYMBOL(set_gpio_ ## name);
+
+SET_GPIO_SC(maska)
+SET_GPIO_SC(maskb)
+
+#if defined(ANOMALY_05000311)
+void set_gpio_data(unsigned short gpio, unsigned short arg)
+{
+ unsigned long flags;
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+ local_irq_save(flags);
+ if (arg)
+ gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
+ else
+ gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
+ bfin_read_CHIPID();
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(set_gpio_data);
+#else
+SET_GPIO_SC(data)
+#endif
+
+
+#if defined(ANOMALY_05000311)
+void set_gpio_toggle(unsigned short gpio)
+{
+ unsigned long flags;
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+ local_irq_save(flags);
+ gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
+ bfin_read_CHIPID();
+ local_irq_restore(flags);
+}
+#else
+void set_gpio_toggle(unsigned short gpio)
+{
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+ gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
+}
+#endif
+EXPORT_SYMBOL(set_gpio_toggle);
+
+
+/*Set current PORT date (16-bit word)*/
+
+#define SET_GPIO_P(name) \
+void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \
+{ \
+ gpio_bankb[gpio_bank(gpio)]->name = arg; \
+} \
+EXPORT_SYMBOL(set_gpiop_ ## name);
+
+SET_GPIO_P(dir)
+SET_GPIO_P(inen)
+SET_GPIO_P(polar)
+SET_GPIO_P(edge)
+SET_GPIO_P(both)
+SET_GPIO_P(maska)
+SET_GPIO_P(maskb)
+
+
+#if defined(ANOMALY_05000311)
+void set_gpiop_data(unsigned short gpio, unsigned short arg)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ gpio_bankb[gpio_bank(gpio)]->data = arg;
+ bfin_read_CHIPID();
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(set_gpiop_data);
+#else
+SET_GPIO_P(data)
+#endif
+
+
+
+/* Get a specific bit */
+
+#define GET_GPIO(name) \
+unsigned short get_gpio_ ## name(unsigned short gpio) \
+{ \
+ return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \
+} \
+EXPORT_SYMBOL(get_gpio_ ## name);
+
+GET_GPIO(dir)
+GET_GPIO(inen)
+GET_GPIO(polar)
+GET_GPIO(edge)
+GET_GPIO(both)
+GET_GPIO(maska)
+GET_GPIO(maskb)
+
+
+#if defined(ANOMALY_05000311)
+unsigned short get_gpio_data(unsigned short gpio)
+{
+ unsigned long flags;
+ unsigned short ret;
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+ local_irq_save(flags);
+ ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->data >> gpio_sub_n(gpio));
+ bfin_read_CHIPID();
+ local_irq_restore(flags);
+ return ret;
+}
+EXPORT_SYMBOL(get_gpio_data);
+#else
+GET_GPIO(data)
+#endif
+
+/*Get current PORT date (16-bit word)*/
+
+#define GET_GPIO_P(name) \
+unsigned short get_gpiop_ ## name(unsigned short gpio) \
+{ \
+ return (gpio_bankb[gpio_bank(gpio)]->name);\
+} \
+EXPORT_SYMBOL(get_gpiop_ ## name);
+
+GET_GPIO_P(dir)
+GET_GPIO_P(inen)
+GET_GPIO_P(polar)
+GET_GPIO_P(edge)
+GET_GPIO_P(both)
+GET_GPIO_P(maska)
+GET_GPIO_P(maskb)
+
+#if defined(ANOMALY_05000311)
+unsigned short get_gpiop_data(unsigned short gpio)
+{
+ unsigned long flags;
+ unsigned short ret;
+ local_irq_save(flags);
+ ret = gpio_bankb[gpio_bank(gpio)]->data;
+ bfin_read_CHIPID();
+ local_irq_restore(flags);
+ return ret;
+}
+EXPORT_SYMBOL(get_gpiop_data);
+#else
+GET_GPIO_P(data)
+#endif
+
+#ifdef CONFIG_PM
+/***********************************************************
+*
+* FUNCTIONS: Blackfin PM Setup API
+*
+* INPUTS/OUTPUTS:
+* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
+* type -
+* PM_WAKE_RISING
+* PM_WAKE_FALLING
+* PM_WAKE_HIGH
+* PM_WAKE_LOW
+* PM_WAKE_BOTH_EDGES
+*
+* DESCRIPTION: Blackfin PM Driver API
+*
+* CAUTION:
+*************************************************************
+* MODIFICATION HISTORY :
+**************************************************************/
+int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type)
+{
+ unsigned long flags;
+
+ if ((check_gpio(gpio) < 0) || !type)
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio);
+ wakeup_flags_map[gpio] = type;
+ local_irq_restore(flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(gpio_pm_wakeup_request);
+
+void gpio_pm_wakeup_free(unsigned short gpio)
+{
+ unsigned long flags;
+
+ if (check_gpio(gpio) < 0)
+ return;
+
+ local_irq_save(flags);
+
+ wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_pm_wakeup_free);
+
+static int bfin_gpio_wakeup_type(unsigned short gpio, unsigned char type)
+{
+ port_setup(gpio, GPIO_USAGE);
+ set_gpio_dir(gpio, 0);
+ set_gpio_inen(gpio, 1);
+
+ if (type & (PM_WAKE_RISING | PM_WAKE_FALLING))
+ set_gpio_edge(gpio, 1);
+ else
+ set_gpio_edge(gpio, 0);
+
+ if ((type & (PM_WAKE_BOTH_EDGES)) == (PM_WAKE_BOTH_EDGES))
+ set_gpio_both(gpio, 1);
+ else
+ set_gpio_both(gpio, 0);
+
+ if ((type & (PM_WAKE_FALLING | PM_WAKE_LOW)))
+ set_gpio_polar(gpio, 1);
+ else
+ set_gpio_polar(gpio, 0);
+
+ SSYNC();
+
+ return 0;
+}
+
+u32 gpio_pm_setup(void)
+{
+ u32 sic_iwr = 0;
+ u16 bank, mask, i, gpio;
+
+ for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) {
+ mask = wakeup_map[gpio_bank(i)];
+ bank = gpio_bank(i);
+
+ gpio_bank_saved[bank].maskb = gpio_bankb[bank]->maskb;
+ gpio_bankb[bank]->maskb = 0;
+
+ if (mask) {
+#ifdef BF537_FAMILY
+ gpio_bank_saved[bank].fer = *port_fer[bank];
+#endif
+ gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen;
+ gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar;
+ gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir;
+ gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge;
+ gpio_bank_saved[bank].both = gpio_bankb[bank]->both;
+
+ gpio = i;
+
+ while (mask) {
+ if (mask & 1) {
+ bfin_gpio_wakeup_type(gpio, wakeup_flags_map[gpio]);
+ set_gpio_data(gpio, 0); /*Clear*/
+ }
+ gpio++;
+ mask >>= 1;
+ }
+
+ sic_iwr |= 1 << (sic_iwr_irqs[bank] - (IRQ_CORETMR + 1));
+ gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)];
+ }
+ }
+
+ if (sic_iwr)
+ return sic_iwr;
+ else
+ return IWR_ENABLE_ALL;
+}
+
+
+void gpio_pm_restore(void)
+{
+ u16 bank, mask, i;
+
+ for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) {
+ mask = wakeup_map[gpio_bank(i)];
+ bank = gpio_bank(i);
+
+ if (mask) {
+#ifdef BF537_FAMILY
+ *port_fer[bank] = gpio_bank_saved[bank].fer;
+#endif
+ gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen;
+ gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir;
+ gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar;
+ gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge;
+ gpio_bankb[bank]->both = gpio_bank_saved[bank].both;
+ }
+
+ gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb;
+ }
+}
+
+#endif
+
+/***********************************************************
+*
+* FUNCTIONS: Blackfin GPIO Driver
+*
+* INPUTS/OUTPUTS:
+* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
+*
+*
+* DESCRIPTION: Blackfin GPIO Driver API
+*
+* CAUTION:
+*************************************************************
+* MODIFICATION HISTORY :
+**************************************************************/
+
+int gpio_request(unsigned short gpio, const char *label)
+{
+ unsigned long flags;
+
+ if (check_gpio(gpio) < 0)
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ if (unlikely(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
+ printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio);
+ dump_stack();
+ local_irq_restore(flags);
+ return -EBUSY;
+ }
+ reserved_map[gpio_bank(gpio)] |= gpio_bit(gpio);
+
+ local_irq_restore(flags);
+
+ port_setup(gpio, GPIO_USAGE);
+
+ return 0;
+}
+EXPORT_SYMBOL(gpio_request);
+
+
+void gpio_free(unsigned short gpio)
+{
+ unsigned long flags;
+
+ if (check_gpio(gpio) < 0)
+ return;
+
+ local_irq_save(flags);
+
+ if (unlikely(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
+ printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio);
+ dump_stack();
+ local_irq_restore(flags);
+ return;
+ }
+
+ default_gpio(gpio);
+
+ reserved_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
+
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_free);
+
+
+void gpio_direction_input(unsigned short gpio)
+{
+ unsigned long flags;
+
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+
+ local_irq_save(flags);
+ gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
+ gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+void gpio_direction_output(unsigned short gpio)
+{
+ unsigned long flags;
+
+ BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+
+ local_irq_save(flags);
+ gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
+ gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_direction_output);
diff --git a/arch/blackfin/kernel/bfin_ksyms.c b/arch/blackfin/kernel/bfin_ksyms.c
new file mode 100644
index 0000000..f64ecb6
--- /dev/null
+++ b/arch/blackfin/kernel/bfin_ksyms.c
@@ -0,0 +1,119 @@
+/*
+ * File: arch/blackfin/kernel/bfin_ksyms.c
+ * Based on: none - original work
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <asm/irq.h>
+#include <asm/checksum.h>
+#include <asm/cacheflush.h>
+#include <asm/uaccess.h>
+
+/* platform dependent support */
+
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strncmp);
+EXPORT_SYMBOL(dump_thread);
+
+EXPORT_SYMBOL(ip_fast_csum);
+
+EXPORT_SYMBOL(kernel_thread);
+
+EXPORT_SYMBOL(__up);
+EXPORT_SYMBOL(__down);
+EXPORT_SYMBOL(__down_trylock);
+EXPORT_SYMBOL(__down_interruptible);
+
+EXPORT_SYMBOL(is_in_rom);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial_copy);
+
+/* The following are special because they're not called
+ * explicitly (the C compiler generates them). Fortunately,
+ * their interface isn't gonna change any time soon now, so
+ * it's OK to leave it out of version control.
+ */
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memcmp);
+EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(memchr);
+EXPORT_SYMBOL(get_wchan);
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler... (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __ashldi3(void);
+extern void __ashrdi3(void);
+extern void __smulsi3_highpart(void);
+extern void __umulsi3_highpart(void);
+extern void __divsi3(void);
+extern void __lshrdi3(void);
+extern void __modsi3(void);
+extern void __muldi3(void);
+extern void __udivsi3(void);
+extern void __umodsi3(void);
+
+/* gcc lib functions */
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__umulsi3_highpart);
+EXPORT_SYMBOL(__smulsi3_highpart);
+EXPORT_SYMBOL(__divsi3);
+EXPORT_SYMBOL(__lshrdi3);
+EXPORT_SYMBOL(__modsi3);
+EXPORT_SYMBOL(__muldi3);
+EXPORT_SYMBOL(__udivsi3);
+EXPORT_SYMBOL(__umodsi3);
+
+EXPORT_SYMBOL(outsb);
+EXPORT_SYMBOL(insb);
+EXPORT_SYMBOL(outsw);
+EXPORT_SYMBOL(insw);
+EXPORT_SYMBOL(outsl);
+EXPORT_SYMBOL(insl);
+EXPORT_SYMBOL(irq_flags);
+EXPORT_SYMBOL(iounmap);
+EXPORT_SYMBOL(blackfin_dcache_invalidate_range);
+EXPORT_SYMBOL(blackfin_icache_dcache_flush_range);
+EXPORT_SYMBOL(blackfin_icache_flush_range);
+EXPORT_SYMBOL(blackfin_dcache_flush_range);
+EXPORT_SYMBOL(blackfin_dflush_page);
+
+EXPORT_SYMBOL(csum_partial);
+EXPORT_SYMBOL(__init_begin);
+EXPORT_SYMBOL(__init_end);
+EXPORT_SYMBOL(_ebss_l1);
+EXPORT_SYMBOL(_stext_l1);
+EXPORT_SYMBOL(_etext_l1);
+EXPORT_SYMBOL(_sdata_l1);
+EXPORT_SYMBOL(_ebss_b_l1);
+EXPORT_SYMBOL(_sdata_b_l1);
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
new file mode 100644
index 0000000..539eb24
--- /dev/null
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -0,0 +1,183 @@
+/*
+ * File: arch/blackfin/kernel/dma-mapping.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: Dynamic DMA mapping support.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/bootmem.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/bfin-global.h>
+
+static spinlock_t dma_page_lock;
+static unsigned int *dma_page;
+static unsigned int dma_pages;
+static unsigned long dma_base;
+static unsigned long dma_size;
+static unsigned int dma_initialized;
+
+void dma_alloc_init(unsigned long start, unsigned long end)
+{
+ spin_lock_init(&dma_page_lock);
+ dma_initialized = 0;
+
+ dma_page = (unsigned int *)__get_free_page(GFP_KERNEL);
+ memset(dma_page, 0, PAGE_SIZE);
+ dma_base = PAGE_ALIGN(start);
+ dma_size = PAGE_ALIGN(end) - PAGE_ALIGN(start);
+ dma_pages = dma_size >> PAGE_SHIFT;
+ memset((void *)dma_base, 0, DMA_UNCACHED_REGION);
+ dma_initialized = 1;
+
+ printk(KERN_INFO "%s: dma_page @ 0x%p - %d pages at 0x%08lx\n", __FUNCTION__,
+ dma_page, dma_pages, dma_base);
+}
+
+static inline unsigned int get_pages(size_t size)
+{
+ return ((size - 1) >> PAGE_SHIFT) + 1;
+}
+
+static unsigned long __alloc_dma_pages(unsigned int pages)
+{
+ unsigned long ret = 0, flags;
+ int i, count = 0;
+
+ if (dma_initialized == 0)
+ dma_alloc_init(_ramend - DMA_UNCACHED_REGION, _ramend);
+
+ spin_lock_irqsave(&dma_page_lock, flags);
+
+ for (i = 0; i < dma_pages;) {
+ if (dma_page[i++] == 0) {
+ if (++count == pages) {
+ while (count--)
+ dma_page[--i] = 1;
+ ret = dma_base + (i << PAGE_SHIFT);
+ break;
+ }
+ } else
+ count = 0;
+ }
+ spin_unlock_irqrestore(&dma_page_lock, flags);
+ return ret;
+}
+
+static void __free_dma_pages(unsigned long addr, unsigned int pages)
+{
+ unsigned long page = (addr - dma_base) >> PAGE_SHIFT;
+ unsigned long flags;
+ int i;
+
+ if ((page + pages) > dma_pages) {
+ printk(KERN_ERR "%s: freeing outside range.\n", __FUNCTION__);
+ BUG();
+ }
+
+ spin_lock_irqsave(&dma_page_lock, flags);
+ for (i = page; i < page + pages; i++) {
+ dma_page[i] = 0;
+ }
+ spin_unlock_irqrestore(&dma_page_lock, flags);
+}
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t * dma_handle, gfp_t gfp)
+{
+ void *ret;
+
+ ret = (void *)__alloc_dma_pages(get_pages(size));
+
+ if (ret) {
+ memset(ret, 0, size);
+ *dma_handle = virt_to_phys(ret);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+void
+dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle)
+{
+ __free_dma_pages((unsigned long)vaddr, get_pages(size));
+}
+EXPORT_SYMBOL(dma_free_coherent);
+
+/*
+ * Dummy functions defined for some existing drivers
+ */
+
+dma_addr_t
+dma_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+
+ invalidate_dcache_range((unsigned long)ptr,
+ (unsigned long)ptr + size);
+
+ return (dma_addr_t) ptr;
+}
+EXPORT_SYMBOL(dma_map_single);
+
+int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction)
+{
+ int i;
+
+ BUG_ON(direction == DMA_NONE);
+
+ for (i = 0; i < nents; i++)
+ invalidate_dcache_range(sg_dma_address(&sg[i]),
+ sg_dma_address(&sg[i]) +
+ sg_dma_len(&sg[i]));
+
+ return nents;
+}
+EXPORT_SYMBOL(dma_map_sg);
+
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+}
+EXPORT_SYMBOL(dma_unmap_single);
+
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nhwentries, enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+}
+EXPORT_SYMBOL(dma_unmap_sg);
diff --git a/arch/blackfin/kernel/dualcore_test.c b/arch/blackfin/kernel/dualcore_test.c
new file mode 100644
index 0000000..8b89c99
--- /dev/null
+++ b/arch/blackfin/kernel/dualcore_test.c
@@ -0,0 +1,49 @@
+/*
+ * File: arch/blackfin/kernel/dualcore_test.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: Small test code for CoreB on a BF561
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+static int *testarg = (int*)0xfeb00000;
+
+static int test_init(void)
+{
+ *testarg = 1;
+ printk("Dual core test module inserted: set testarg = [%d]\n @ [%p]\n",
+ *testarg, testarg);
+ return 0;
+}
+
+static void test_exit(void)
+{
+ printk("Dual core test module removed: testarg = [%d]\n", *testarg);
+}
+
+module_init(test_init);
+module_exit(test_exit);
diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S
new file mode 100644
index 0000000..5880b27
--- /dev/null
+++ b/arch/blackfin/kernel/entry.S
@@ -0,0 +1,94 @@
+/*
+ * File: arch/blackfin/kernel/entry.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+#include <asm/asm-offsets.h>
+
+#include <asm/mach-common/context.S>
+
+#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
+.section .l1.text
+#else
+.text
+#endif
+
+ENTRY(_ret_from_fork)
+ SP += -12;
+ call _schedule_tail;
+ SP += 12;
+ r0 = [sp + PT_IPEND];
+ cc = bittst(r0,1);
+ if cc jump .Lin_kernel;
+ RESTORE_CONTEXT
+ rti;
+.Lin_kernel:
+ bitclr(r0,1);
+ [sp + PT_IPEND] = r0;
+ /* do a 'fake' RTI by jumping to [RETI]
+ * to avoid clearing supervisor mode in child
+ */
+ RESTORE_ALL_SYS
+ p0 = reti;
+ jump (p0);
+
+ENTRY(_sys_fork)
+ r0 = -EINVAL;
+ rts;
+
+ENTRY(_sys_vfork)
+ r0 = sp;
+ r0 += 24;
+ [--sp] = rets;
+ SP += -12;
+ call _bfin_vfork;
+ SP += 12;
+ rets = [sp++];
+ rts;
+
+ENTRY(_sys_clone)
+ r0 = sp;
+ r0 += 24;
+ [--sp] = rets;
+ SP += -12;
+ call _bfin_clone;
+ SP += 12;
+ rets = [sp++];
+ rts;
+
+ENTRY(_sys_rt_sigreturn)
+ r0 = sp;
+ r0 += 24;
+ [--sp] = rets;
+ SP += -12;
+ call _do_rt_sigreturn;
+ SP += 12;
+ rets = [sp++];
+ rts;
diff --git a/arch/blackfin/kernel/flat.c b/arch/blackfin/kernel/flat.c
new file mode 100644
index 0000000..a92587b
--- /dev/null
+++ b/arch/blackfin/kernel/flat.c
@@ -0,0 +1,101 @@
+/*
+ * arch/blackfin/kernel/flat.c
+ *
+ * Copyright (C) 2007 Analog Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/flat.h>
+
+#define FLAT_BFIN_RELOC_TYPE_16_BIT 0
+#define FLAT_BFIN_RELOC_TYPE_16H_BIT 1
+#define FLAT_BFIN_RELOC_TYPE_32_BIT 2
+
+unsigned long bfin_get_addr_from_rp(unsigned long *ptr,
+ unsigned long relval,
+ unsigned long flags,
+ unsigned long *persistent)
+{
+ unsigned short *usptr = (unsigned short *)ptr;
+ int type = (relval >> 26) & 7;
+ unsigned long val;
+
+ switch (type) {
+ case FLAT_BFIN_RELOC_TYPE_16_BIT:
+ case FLAT_BFIN_RELOC_TYPE_16H_BIT:
+ usptr = (unsigned short *)ptr;
+ pr_debug("*usptr = %x", get_unaligned(usptr));
+ val = get_unaligned(usptr);
+ val += *persistent;
+ break;
+
+ case FLAT_BFIN_RELOC_TYPE_32_BIT:
+ pr_debug("*ptr = %lx", get_unaligned(ptr));
+ val = get_unaligned(ptr);
+ break;
+
+ default:
+ pr_debug("BINFMT_FLAT: Unknown relocation type %x\n",
+ type);
+
+ return 0;
+ }
+
+ /*
+ * Stack-relative relocs contain the offset into the stack, we
+ * have to add the stack's start address here and return 1 from
+ * flat_addr_absolute to prevent the normal address calculations
+ */
+ if (relval & (1 << 29))
+ return val + current->mm->context.end_brk;
+
+ if ((flags & FLAT_FLAG_GOTPIC) == 0)
+ val = htonl(val);
+ return val;
+}
+EXPORT_SYMBOL(bfin_get_addr_from_rp);
+
+/*
+ * Insert the address ADDR into the symbol reference at RP;
+ * RELVAL is the raw relocation-table entry from which RP is derived
+ */
+void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr,
+ unsigned long relval)
+{
+ unsigned short *usptr = (unsigned short *)ptr;
+ int type = (relval >> 26) & 7;
+
+ switch (type) {
+ case FLAT_BFIN_RELOC_TYPE_16_BIT:
+ put_unaligned(addr, usptr);
+ pr_debug("new value %x at %p", get_unaligned(usptr),
+ usptr);
+ break;
+
+ case FLAT_BFIN_RELOC_TYPE_16H_BIT:
+ put_unaligned(addr >> 16, usptr);
+ pr_debug("new value %x", get_unaligned(usptr));
+ break;
+
+ case FLAT_BFIN_RELOC_TYPE_32_BIT:
+ put_unaligned(addr, ptr);
+ pr_debug("new ptr =%lx", get_unaligned(ptr));
+ break;
+ }
+}
+EXPORT_SYMBOL(bfin_put_addr_at_rp);
diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c
new file mode 100644
index 0000000..b45188f
--- /dev/null
+++ b/arch/blackfin/kernel/init_task.c
@@ -0,0 +1,60 @@
+/*
+ * File: arch/blackfin/kernel/init_task.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/init_task.h>
+#include <linux/mqueue.h>
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+
+struct mm_struct init_mm = INIT_MM(init_mm);
+EXPORT_SYMBOL(init_mm);
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
+EXPORT_SYMBOL(init_task);
+
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by having a special
+ * "init_task" linker map entry.
+ */
+union thread_union init_thread_union
+ __attribute__ ((__section__(".data.init_task"))) = {
+INIT_THREAD_INFO(init_task)};
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
new file mode 100644
index 0000000..df5bf02
--- /dev/null
+++ b/arch/blackfin/kernel/irqchip.c
@@ -0,0 +1,147 @@
+/*
+ * File: arch/blackfin/kernel/irqchip.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/seq_file.h>
+#include <linux/kallsyms.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+static unsigned long irq_err_count;
+static spinlock_t irq_controller_lock;
+
+/*
+ * Dummy mask/unmask handler
+ */
+void dummy_mask_unmask_irq(unsigned int irq)
+{
+}
+
+void ack_bad_irq(unsigned int irq)
+{
+ irq_err_count += 1;
+ printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
+}
+EXPORT_SYMBOL(ack_bad_irq);
+
+static struct irq_chip bad_chip = {
+ .ack = dummy_mask_unmask_irq,
+ .mask = dummy_mask_unmask_irq,
+ .unmask = dummy_mask_unmask_irq,
+};
+
+static struct irq_desc bad_irq_desc = {
+ .chip = &bad_chip,
+ .handle_irq = handle_bad_irq,
+ .depth = 1,
+};
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+ int i = *(loff_t *) v;
+ struct irqaction *action;
+ unsigned long flags;
+
+ if (i < NR_IRQS) {
+ spin_lock_irqsave(&irq_desc[i].lock, flags);
+ action = irq_desc[i].action;
+ if (!action)
+ goto unlock;
+
+ seq_printf(p, "%3d: %10u ", i, kstat_irqs(i));
+ seq_printf(p, " %s", action->name);
+ for (action = action->next; action; action = action->next)
+ seq_printf(p, ", %s", action->name);
+
+ seq_putc(p, '\n');
+ unlock:
+ spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+ } else if (i == NR_IRQS) {
+ seq_printf(p, "Err: %10lu\n", irq_err_count);
+ }
+ return 0;
+}
+
+/*
+ * do_IRQ handles all hardware IRQ's. Decoded IRQs should not
+ * come via this function. Instead, they should provide their
+ * own 'handler'
+ */
+
+#ifdef CONFIG_DO_IRQ_L1
+asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)__attribute__((l1_text));
+#endif
+
+asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
+{
+ struct pt_regs *old_regs;
+ struct irq_desc *desc = irq_desc + irq;
+ unsigned short pending, other_ints;
+
+ old_regs = set_irq_regs(regs);
+
+ /*
+ * Some hardware gives randomly wrong interrupts. Rather
+ * than crashing, do something sensible.
+ */
+ if (irq >= NR_IRQS)
+ desc = &bad_irq_desc;
+
+ irq_enter();
+
+ generic_handle_irq(irq);
+
+ /* If we're the only interrupt running (ignoring IRQ15 which is for
+ syscalls), lower our priority to IRQ14 so that softirqs run at
+ that level. If there's another, lower-level interrupt, irq_exit
+ will defer softirqs to that. */
+ CSYNC();
+ pending = bfin_read_IPEND() & ~0x8000;
+ other_ints = pending & (pending - 1);
+ if (other_ints == 0)
+ lower_to_irq14();
+ irq_exit();
+
+ set_irq_regs(old_regs);
+}
+
+void __init init_IRQ(void)
+{
+ struct irq_desc *desc;
+ int irq;
+
+ spin_lock_init(&irq_controller_lock);
+ for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++) {
+ *desc = bad_irq_desc;
+ }
+
+ init_arch_irq();
+}
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c
new file mode 100644
index 0000000..372f756
--- /dev/null
+++ b/arch/blackfin/kernel/module.c
@@ -0,0 +1,429 @@
+/*
+ * File: arch/blackfin/kernel/module.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <asm/dma.h>
+#include <asm/cacheflush.h>
+
+/*
+ * handle arithmetic relocations.
+ * See binutils/bfd/elf32-bfin.c for more details
+ */
+#define RELOC_STACK_SIZE 100
+static uint32_t reloc_stack[RELOC_STACK_SIZE];
+static unsigned int reloc_stack_tos;
+
+#define is_reloc_stack_empty() ((reloc_stack_tos > 0)?0:1)
+
+static void reloc_stack_push(uint32_t value)
+{
+ reloc_stack[reloc_stack_tos++] = value;
+}
+
+static uint32_t reloc_stack_pop(void)
+{
+ return reloc_stack[--reloc_stack_tos];
+}
+
+static uint32_t reloc_stack_operate(unsigned int oper, struct module *mod)
+{
+ uint32_t value;
+
+ switch (oper) {
+ case R_add:
+ value = reloc_stack[reloc_stack_tos - 2] +
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_sub:
+ value = reloc_stack[reloc_stack_tos - 2] -
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_mult:
+ value = reloc_stack[reloc_stack_tos - 2] *
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_div:
+ value = reloc_stack[reloc_stack_tos - 2] /
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_mod:
+ value = reloc_stack[reloc_stack_tos - 2] %
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_lshift:
+ value = reloc_stack[reloc_stack_tos - 2] <<
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_rshift:
+ value = reloc_stack[reloc_stack_tos - 2] >>
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_and:
+ value = reloc_stack[reloc_stack_tos - 2] &
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_or:
+ value = reloc_stack[reloc_stack_tos - 2] |
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_xor:
+ value = reloc_stack[reloc_stack_tos - 2] ^
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_land:
+ value = reloc_stack[reloc_stack_tos - 2] &&
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_lor:
+ value = reloc_stack[reloc_stack_tos - 2] ||
+ reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 2;
+ break;
+ case R_neg:
+ value = -reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos--;
+ break;
+ case R_comp:
+ value = ~reloc_stack[reloc_stack_tos - 1];
+ reloc_stack_tos -= 1;
+ break;
+ default:
+ printk(KERN_WARNING "module %s: unhandled reloction\n",
+ mod->name);
+ return 0;
+ }
+
+ /* now push the new value back on stack */
+ reloc_stack_push(value);
+
+ return value;
+}
+
+void *module_alloc(unsigned long size)
+{
+ if (size == 0)
+ return NULL;
+ return vmalloc(size);
+}
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+ vfree(module_region);
+}
+
+/* Transfer the section to the L1 memory */
+int
+module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
+ char *secstrings, struct module *mod)
+{
+ Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
+ void *dest = NULL;
+
+ for (s = sechdrs; s < sechdrs_end; ++s) {
+ if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) ||
+ ((strcmp(".text", secstrings + s->sh_name)==0) &&
+ (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) {
+ mod->arch.text_l1 = s;
+ dest = l1_inst_sram_alloc(s->sh_size);
+ if (dest == NULL) {
+ printk(KERN_ERR
+ "module %s: L1 instruction memory allocation failed\n",
+ mod->name);
+ return -1;
+ }
+ dma_memcpy(dest, (void *)s->sh_addr, s->sh_size);
+ s->sh_flags &= ~SHF_ALLOC;
+ s->sh_addr = (unsigned long)dest;
+ }
+ if ((strcmp(".l1.data", secstrings + s->sh_name) == 0)||
+ ((strcmp(".data", secstrings + s->sh_name)==0) &&
+ (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
+ mod->arch.data_a_l1 = s;
+ dest = l1_data_sram_alloc(s->sh_size);
+ if (dest == NULL) {
+ printk(KERN_ERR
+ "module %s: L1 data memory allocation failed\n",
+ mod->name);
+ return -1;
+ }
+ memcpy(dest, (void *)s->sh_addr, s->sh_size);
+ s->sh_flags &= ~SHF_ALLOC;
+ s->sh_addr = (unsigned long)dest;
+ }
+ if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 ||
+ ((strcmp(".bss", secstrings + s->sh_name)==0) &&
+ (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
+ mod->arch.bss_a_l1 = s;
+ dest = l1_data_sram_alloc(s->sh_size);
+ if (dest == NULL) {
+ printk(KERN_ERR
+ "module %s: L1 data memory allocation failed\n",
+ mod->name);
+ return -1;
+ }
+ memset(dest, 0, s->sh_size);
+ s->sh_flags &= ~SHF_ALLOC;
+ s->sh_addr = (unsigned long)dest;
+ }
+ if (strcmp(".l1.data.B", secstrings + s->sh_name) == 0) {
+ mod->arch.data_b_l1 = s;
+ dest = l1_data_B_sram_alloc(s->sh_size);
+ if (dest == NULL) {
+ printk(KERN_ERR
+ "module %s: L1 data memory allocation failed\n",
+ mod->name);
+ return -1;
+ }
+ memcpy(dest, (void *)s->sh_addr, s->sh_size);
+ s->sh_flags &= ~SHF_ALLOC;
+ s->sh_addr = (unsigned long)dest;
+ }
+ if (strcmp(".l1.bss.B", secstrings + s->sh_name) == 0) {
+ mod->arch.bss_b_l1 = s;
+ dest = l1_data_B_sram_alloc(s->sh_size);
+ if (dest == NULL) {
+ printk(KERN_ERR
+ "module %s: L1 data memory allocation failed\n",
+ mod->name);
+ return -1;
+ }
+ memset(dest, 0, s->sh_size);
+ s->sh_flags &= ~SHF_ALLOC;
+ s->sh_addr = (unsigned long)dest;
+ }
+ }
+ return 0;
+}
+
+int
+apply_relocate(Elf_Shdr * sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec, struct module *me)
+{
+ printk(KERN_ERR "module %s: .rel unsupported\n", me->name);
+ return -ENOEXEC;
+}
+
+/*************************************************************************/
+/* FUNCTION : apply_relocate_add */
+/* ABSTRACT : Blackfin specific relocation handling for the loadable */
+/* modules. Modules are expected to be .o files. */
+/* Arithmetic relocations are handled. */
+/* We do not expect LSETUP to be split and hence is not */
+/* handled. */
+/* R_byte and R_byte2 are also not handled as the gas */
+/* does not generate it. */
+/*************************************************************************/
+int
+apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec,
+ struct module *mod)
+{
+ unsigned int i;
+ unsigned short tmp;
+ Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
+ Elf32_Sym *sym;
+ uint32_t *location32;
+ uint16_t *location16;
+ uint32_t value;
+
+ pr_debug("Applying relocate section %u to %u\n", relsec,
+ sechdrs[relsec].sh_info);
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ /* This is where to make the change */
+ location16 =
+ (uint16_t *) (sechdrs[sechdrs[relsec].sh_info].sh_addr +
+ rel[i].r_offset);
+ location32 = (uint32_t *) location16;
+ /* This is the symbol it is referring to. Note that all
+ undefined symbols have been resolved. */
+ sym = (Elf32_Sym *) sechdrs[symindex].sh_addr
+ + ELF32_R_SYM(rel[i].r_info);
+ if (is_reloc_stack_empty()) {
+ value = sym->st_value;
+ } else {
+ value = reloc_stack_pop();
+ }
+ value += rel[i].r_addend;
+ pr_debug("location is %x, value is %x type is %d \n",
+ (unsigned int) location32, value,
+ ELF32_R_TYPE(rel[i].r_info));
+
+ switch (ELF32_R_TYPE(rel[i].r_info)) {
+
+ case R_pcrel24:
+ case R_pcrel24_jump_l:
+ /* Add the value, subtract its postition */
+ location16 =
+ (uint16_t *) (sechdrs[sechdrs[relsec].sh_info].
+ sh_addr + rel[i].r_offset - 2);
+ location32 = (uint32_t *) location16;
+ value -= (uint32_t) location32;
+ value >>= 1;
+ pr_debug("value is %x, before %x-%x after %x-%x\n", value,
+ *location16, *(location16 + 1),
+ (*location16 & 0xff00) | (value >> 16 & 0x00ff),
+ value & 0xffff);
+ *location16 =
+ (*location16 & 0xff00) | (value >> 16 & 0x00ff);
+ *(location16 + 1) = value & 0xffff;
+ break;
+ case R_pcrel12_jump:
+ case R_pcrel12_jump_s:
+ value -= (uint32_t) location32;
+ value >>= 1;
+ *location16 = (value & 0xfff);
+ break;
+ case R_pcrel10:
+ value -= (uint32_t) location32;
+ value >>= 1;
+ *location16 = (value & 0x3ff);
+ break;
+ case R_luimm16:
+ pr_debug("before %x after %x\n", *location16,
+ (value & 0xffff));
+ tmp = (value & 0xffff);
+ if((unsigned long)location16 >= L1_CODE_START) {
+ dma_memcpy(location16, &tmp, 2);
+ } else
+ *location16 = tmp;
+ break;
+ case R_huimm16:
+ pr_debug("before %x after %x\n", *location16,
+ ((value >> 16) & 0xffff));
+ tmp = ((value >> 16) & 0xffff);
+ if((unsigned long)location16 >= L1_CODE_START) {
+ dma_memcpy(location16, &tmp, 2);
+ } else
+ *location16 = tmp;
+ break;
+ case R_rimm16:
+ *location16 = (value & 0xffff);
+ break;
+ case R_byte4_data:
+ pr_debug("before %x after %x\n", *location32, value);
+ *location32 = value;
+ break;
+ case R_push:
+ reloc_stack_push(value);
+ break;
+ case R_const:
+ reloc_stack_push(rel[i].r_addend);
+ break;
+ case R_add:
+ case R_sub:
+ case R_mult:
+ case R_div:
+ case R_mod:
+ case R_lshift:
+ case R_rshift:
+ case R_and:
+ case R_or:
+ case R_xor:
+ case R_land:
+ case R_lor:
+ case R_neg:
+ case R_comp:
+ reloc_stack_operate(ELF32_R_TYPE(rel[i].r_info), mod);
+ break;
+ default:
+ printk(KERN_ERR "module %s: Unknown relocation: %u\n",
+ mod->name, ELF32_R_TYPE(rel[i].r_info));
+ return -ENOEXEC;
+ }
+ }
+ return 0;
+}
+
+int
+module_finalize(const Elf_Ehdr * hdr,
+ const Elf_Shdr * sechdrs, struct module *mod)
+{
+ unsigned int i, strindex = 0, symindex = 0;
+ char *secstrings;
+
+ secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+ for (i = 1; i < hdr->e_shnum; i++) {
+ /* Internal symbols and strings. */
+ if (sechdrs[i].sh_type == SHT_SYMTAB) {
+ symindex = i;
+ strindex = sechdrs[i].sh_link;
+ }
+ }
+
+ for (i = 1; i < hdr->e_shnum; i++) {
+ const char *strtab = (char *)sechdrs[strindex].sh_addr;
+ unsigned int info = sechdrs[i].sh_info;
+
+ /* Not a valid relocation section? */
+ if (info >= hdr->e_shnum)
+ continue;
+
+ if ((sechdrs[i].sh_type == SHT_RELA) &&
+ ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0)||
+ ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) &&
+ (hdr->e_flags & FLG_CODE_IN_L1)))) {
+ apply_relocate_add((Elf_Shdr *) sechdrs, strtab,
+ symindex, i, mod);
+ }
+ }
+ return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+ if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr))
+ l1_inst_sram_free((void*)mod->arch.text_l1->sh_addr);
+ if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr))
+ l1_data_sram_free((void*)mod->arch.data_a_l1->sh_addr);
+ if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr))
+ l1_data_sram_free((void*)mod->arch.bss_a_l1->sh_addr);
+ if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr))
+ l1_data_B_sram_free((void*)mod->arch.data_b_l1->sh_addr);
+ if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr))
+ l1_data_B_sram_free((void*)mod->arch.bss_b_l1->sh_addr);
+}
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
new file mode 100644
index 0000000..3eff743
--- /dev/null
+++ b/arch/blackfin/kernel/process.c
@@ -0,0 +1,394 @@
+/*
+ * File: arch/blackfin/kernel/process.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: Blackfin architecture-dependent process handling.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/smp_lock.h>
+#include <linux/unistd.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+
+#include <asm/blackfin.h>
+#include <asm/uaccess.h>
+
+#define LED_ON 0
+#define LED_OFF 1
+
+asmlinkage void ret_from_fork(void);
+
+/* Points to the SDRAM backup memory for the stack that is currently in
+ * L1 scratchpad memory.
+ */
+void *current_l1_stack_save;
+
+/* The number of tasks currently using a L1 stack area. The SRAM is
+ * allocated/deallocated whenever this changes from/to zero.
+ */
+int nr_l1stack_tasks;
+
+/* Start and length of the area in L1 scratchpad memory which we've allocated
+ * for process stacks.
+ */
+void *l1_stack_base;
+unsigned long l1_stack_len;
+
+/*
+ * Powermanagement idle function, if any..
+ */
+void (*pm_idle)(void) = NULL;
+EXPORT_SYMBOL(pm_idle);
+
+void (*pm_power_off)(void) = NULL;
+EXPORT_SYMBOL(pm_power_off);
+
+/*
+ * We are using a different LED from the one used to indicate timer interrupt.
+ */
+#if defined(CONFIG_BFIN_IDLE_LED)
+static inline void leds_switch(int flag)
+{
+ unsigned short tmp = 0;
+
+ tmp = bfin_read_CONFIG_BFIN_IDLE_LED_PORT();
+ SSYNC();
+
+ if (flag == LED_ON)
+ tmp &= ~CONFIG_BFIN_IDLE_LED_PIN; /* light on */
+ else
+ tmp |= CONFIG_BFIN_IDLE_LED_PIN; /* light off */
+
+ bfin_write_CONFIG_BFIN_IDLE_LED_PORT(tmp);
+ SSYNC();
+
+}
+#else
+static inline void leds_switch(int flag)
+{
+}
+#endif
+
+/*
+ * The idle loop on BFIN
+ */
+#ifdef CONFIG_IDLE_L1
+void default_idle(void)__attribute__((l1_text));
+void cpu_idle(void)__attribute__((l1_text));
+#endif
+
+void default_idle(void)
+{
+ while (!need_resched()) {
+ leds_switch(LED_OFF);
+ local_irq_disable();
+ if (likely(!need_resched()))
+ idle_with_irq_disabled();
+ local_irq_enable();
+ leds_switch(LED_ON);
+ }
+}
+
+void (*idle)(void) = default_idle;
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle(void)
+{
+ /* endless idle loop with no priority at all */
+ while (1) {
+ idle();
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ }
+}
+
+void machine_restart(char *__unused)
+{
+#if defined(CONFIG_BLKFIN_CACHE)
+ bfin_write_IMEM_CONTROL(0x01);
+ SSYNC();
+#endif
+ bfin_reset();
+ /* Dont do anything till the reset occurs */
+ while (1) {
+ SSYNC();
+ }
+}
+
+void machine_halt(void)
+{
+ for (;;)
+ asm volatile ("idle");
+}
+
+void machine_power_off(void)
+{
+ for (;;)
+ asm volatile ("idle");
+}
+
+void show_regs(struct pt_regs *regs)
+{
+ printk(KERN_NOTICE "\n");
+ printk(KERN_NOTICE
+ "PC: %08lu Status: %04lu SysStatus: %04lu RETS: %08lu\n",
+ regs->pc, regs->astat, regs->seqstat, regs->rets);
+ printk(KERN_NOTICE
+ "A0.x: %08lx A0.w: %08lx A1.x: %08lx A1.w: %08lx\n",
+ regs->a0x, regs->a0w, regs->a1x, regs->a1w);
+ printk(KERN_NOTICE "P0: %08lx P1: %08lx P2: %08lx P3: %08lx\n",
+ regs->p0, regs->p1, regs->p2, regs->p3);
+ printk(KERN_NOTICE "P4: %08lx P5: %08lx\n", regs->p4, regs->p5);
+ printk(KERN_NOTICE "R0: %08lx R1: %08lx R2: %08lx R3: %08lx\n",
+ regs->r0, regs->r1, regs->r2, regs->r3);
+ printk(KERN_NOTICE "R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n",
+ regs->r4, regs->r5, regs->r6, regs->r7);
+
+ if (!(regs->ipend))
+ printk("USP: %08lx\n", rdusp());
+}
+
+/* Fill in the fpu structure for a core dump. */
+
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpregs)
+{
+ return 1;
+}
+
+/*
+ * This gets run with P1 containing the
+ * function to call, and R1 containing
+ * the "args". Note P0 is clobbered on the way here.
+ */
+void kernel_thread_helper(void);
+__asm__(".section .text\n"
+ ".align 4\n"
+ "_kernel_thread_helper:\n\t"
+ "\tsp += -12;\n\t"
+ "\tr0 = r1;\n\t" "\tcall (p1);\n\t" "\tcall _do_exit;\n" ".previous");
+
+/*
+ * Create a kernel thread.
+ */
+pid_t kernel_thread(int (*fn) (void *), void *arg, unsigned long flags)
+{
+ struct pt_regs regs;
+
+ memset(&regs, 0, sizeof(regs));
+
+ regs.r1 = (unsigned long)arg;
+ regs.p1 = (unsigned long)fn;
+ regs.pc = (unsigned long)kernel_thread_helper;
+ regs.orig_p0 = -1;
+ /* Set bit 2 to tell ret_from_fork we should be returning to kernel
+ mode. */
+ regs.ipend = 0x8002;
+ __asm__ __volatile__("%0 = syscfg;":"=da"(regs.syscfg):);
+ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL,
+ NULL);
+}
+
+void flush_thread(void)
+{
+}
+
+asmlinkage int bfin_vfork(struct pt_regs *regs)
+{
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL,
+ NULL);
+}
+
+asmlinkage int bfin_clone(struct pt_regs *regs)
+{
+ unsigned long clone_flags;
+ unsigned long newsp;
+
+ /* syscall2 puts clone_flags in r0 and usp in r1 */
+ clone_flags = regs->r0;
+ newsp = regs->r1;
+ if (!newsp)
+ newsp = rdusp();
+ else
+ newsp -= 12;
+ return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
+}
+
+int
+copy_thread(int nr, unsigned long clone_flags,
+ unsigned long usp, unsigned long topstk,
+ struct task_struct *p, struct pt_regs *regs)
+{
+ struct pt_regs *childregs;
+
+ childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
+ *childregs = *regs;
+ childregs->r0 = 0;
+
+ p->thread.usp = usp;
+ p->thread.ksp = (unsigned long)childregs;
+ p->thread.pc = (unsigned long)ret_from_fork;
+
+ return 0;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs *regs, struct user *dump)
+{
+ dump->magic = CMAGIC;
+ dump->start_code = 0;
+ dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
+ dump->u_tsize = ((unsigned long)current->mm->end_code) >> PAGE_SHIFT;
+ dump->u_dsize = ((unsigned long)(current->mm->brk +
+ (PAGE_SIZE - 1))) >> PAGE_SHIFT;
+ dump->u_dsize -= dump->u_tsize;
+ dump->u_ssize = 0;
+
+ if (dump->start_stack < TASK_SIZE)
+ dump->u_ssize =
+ ((unsigned long)(TASK_SIZE -
+ dump->start_stack)) >> PAGE_SHIFT;
+
+ dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump);
+
+ dump->regs.r0 = regs->r0;
+ dump->regs.r1 = regs->r1;
+ dump->regs.r2 = regs->r2;
+ dump->regs.r3 = regs->r3;
+ dump->regs.r4 = regs->r4;
+ dump->regs.r5 = regs->r5;
+ dump->regs.r6 = regs->r6;
+ dump->regs.r7 = regs->r7;
+ dump->regs.p0 = regs->p0;
+ dump->regs.p1 = regs->p1;
+ dump->regs.p2 = regs->p2;
+ dump->regs.p3 = regs->p3;
+ dump->regs.p4 = regs->p4;
+ dump->regs.p5 = regs->p5;
+ dump->regs.orig_p0 = regs->orig_p0;
+ dump->regs.a0w = regs->a0w;
+ dump->regs.a1w = regs->a1w;
+ dump->regs.a0x = regs->a0x;
+ dump->regs.a1x = regs->a1x;
+ dump->regs.rets = regs->rets;
+ dump->regs.astat = regs->astat;
+ dump->regs.pc = regs->pc;
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+
+asmlinkage int sys_execve(char *name, char **argv, char **envp)
+{
+ int error;
+ char *filename;
+ struct pt_regs *regs = (struct pt_regs *)((&name) + 6);
+
+ lock_kernel();
+ filename = getname(name);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
+ goto out;
+ error = do_execve(filename, argv, envp, regs);
+ putname(filename);
+ out:
+ unlock_kernel();
+ return error;
+}
+
+unsigned long get_wchan(struct task_struct *p)
+{
+ unsigned long fp, pc;
+ unsigned long stack_page;
+ int count = 0;
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+
+ stack_page = (unsigned long)p;
+ fp = p->thread.usp;
+ do {
+ if (fp < stack_page + sizeof(struct thread_info) ||
+ fp >= 8184 + stack_page)
+ return 0;
+ pc = ((unsigned long *)fp)[1];
+ if (!in_sched_functions(pc))
+ return pc;
+ fp = *(unsigned long *)fp;
+ }
+ while (count++ < 16);
+ return 0;
+}
+
+#if defined(CONFIG_ACCESS_CHECK)
+int _access_ok(unsigned long addr, unsigned long size)
+{
+
+ if (addr > (addr + size))
+ return 0;
+ if (segment_eq(get_fs(),KERNEL_DS))
+ return 1;
+#ifdef CONFIG_MTD_UCLINUX
+ if (addr >= memory_start && (addr + size) <= memory_end)
+ return 1;
+ if (addr >= memory_mtd_end && (addr + size) <= physical_mem_end)
+ return 1;
+#else
+ if (addr >= memory_start && (addr + size) <= physical_mem_end)
+ return 1;
+#endif
+ if (addr >= (unsigned long)__init_begin &&
+ addr + size <= (unsigned long)__init_end)
+ return 1;
+ if (addr >= L1_SCRATCH_START
+ && addr + size <= L1_SCRATCH_START + L1_SCRATCH_LENGTH)
+ return 1;
+#if L1_CODE_LENGTH != 0
+ if (addr >= L1_CODE_START + (_etext_l1 - _stext_l1)
+ && addr + size <= L1_CODE_START + L1_CODE_LENGTH)
+ return 1;
+#endif
+#if L1_DATA_A_LENGTH != 0
+ if (addr >= L1_DATA_A_START + (_ebss_l1 - _sdata_l1)
+ && addr + size <= L1_DATA_A_START + L1_DATA_A_LENGTH)
+ return 1;
+#endif
+#if L1_DATA_B_LENGTH != 0
+ if (addr >= L1_DATA_B_START
+ && addr + size <= L1_DATA_B_START + L1_DATA_B_LENGTH)
+ return 1;
+#endif
+ return 0;
+}
+EXPORT_SYMBOL(_access_ok);
+#endif /* CONFIG_ACCESS_CHECK */
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
new file mode 100644
index 0000000..d7c8e51
--- /dev/null
+++ b/arch/blackfin/kernel/ptrace.c
@@ -0,0 +1,430 @@
+/*
+ * File: arch/blackfin/kernel/ptrace.c
+ * Based on: Taken from linux/kernel/ptrace.c
+ * Author: linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+ *
+ * Created: 1/23/92
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/signal.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/asm-offsets.h>
+#include <asm/dma.h>
+
+#define MAX_SHARED_LIBS 3
+#define TEXT_OFFSET 0
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/* determines which bits in the SYSCFG reg the user has access to. */
+/* 1 = access 0 = no access */
+#define SYSCFG_MASK 0x0007 /* SYSCFG reg */
+/* sets the trace bits. */
+#define TRACE_BITS 0x0001
+
+/* Find the stack offset for a register, relative to thread.esp0. */
+#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
+
+/*
+ * Get the address of the live pt_regs for the specified task.
+ * These are saved onto the top kernel stack when the process
+ * is not running.
+ *
+ * Note: if a user thread is execve'd from kernel space, the
+ * kernel stack will not be empty on entry to the kernel, so
+ * ptracing these tasks will fail.
+ */
+static inline struct pt_regs *get_user_regs(struct task_struct *task)
+{
+ return (struct pt_regs *)
+ ((unsigned long)task->thread_info +
+ (THREAD_SIZE - sizeof(struct pt_regs)));
+}
+
+/*
+ * Get all user integer registers.
+ */
+static inline int ptrace_getregs(struct task_struct *tsk, void __user * uregs)
+{
+ struct pt_regs *regs = get_user_regs(tsk);
+ return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
+}
+
+/* Mapping from PT_xxx to the stack offset at which the register is
+ * saved. Notice that usp has no stack-slot and needs to be treated
+ * specially (see get_reg/put_reg below).
+ */
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline long get_reg(struct task_struct *task, int regno)
+{
+ unsigned char *reg_ptr;
+
+ struct pt_regs *regs =
+ (struct pt_regs *)((unsigned long)task->thread_info +
+ (THREAD_SIZE - sizeof(struct pt_regs)));
+ reg_ptr = (char *)regs;
+
+ switch (regno) {
+ case PT_USP:
+ return task->thread.usp;
+ default:
+ if (regno <= 216)
+ return *(long *)(reg_ptr + regno);
+ }
+ /* slight mystery ... never seems to come here but kernel misbehaves without this code! */
+
+ printk(KERN_WARNING "Request to get for unknown register %d\n", regno);
+ return 0;
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int
+put_reg(struct task_struct *task, int regno, unsigned long data)
+{
+ char * reg_ptr;
+
+ struct pt_regs *regs =
+ (struct pt_regs *)((unsigned long)task->thread_info +
+ (THREAD_SIZE - sizeof(struct pt_regs)));
+ reg_ptr = (char *)regs;
+
+ switch (regno) {
+ case PT_PC:
+ /*********************************************************************/
+ /* At this point the kernel is most likely in exception. */
+ /* The RETX register will be used to populate the pc of the process. */
+ /*********************************************************************/
+ regs->retx = data;
+ regs->pc = data;
+ break;
+ case PT_RETX:
+ break; /* regs->retx = data; break; */
+ case PT_USP:
+ regs->usp = data;
+ task->thread.usp = data;
+ break;
+ default:
+ if (regno <= 216)
+ *(long *)(reg_ptr + regno) = data;
+ }
+ return 0;
+}
+
+/*
+ * check that an address falls within the bounds of the target process's memory mappings
+ */
+static inline int is_user_addr_valid(struct task_struct *child,
+ unsigned long start, unsigned long len)
+{
+ struct vm_list_struct *vml;
+ struct sram_list_struct *sraml;
+
+ for (vml = child->mm->context.vmlist; vml; vml = vml->next)
+ if (start >= vml->vma->vm_start && start + len <= vml->vma->vm_end)
+ return 0;
+
+ for (sraml = child->mm->context.sram_list; sraml; sraml = sraml->next)
+ if (start >= (unsigned long)sraml->addr
+ && start + len <= (unsigned long)sraml->addr + sraml->length)
+ return 0;
+
+ return -EIO;
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure the single step bit is not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+ unsigned long tmp;
+ /* make sure the single step bit is not set. */
+ tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+ put_reg(child, PT_SR, tmp);
+}
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+{
+ int ret;
+ int add = 0;
+
+ switch (request) {
+ /* when I and D space are separate, these will need to be fixed. */
+ case PTRACE_PEEKDATA:
+ pr_debug("ptrace: PEEKDATA\n");
+ add = MAX_SHARED_LIBS * 4; /* space between text and data */
+ /* fall through */
+ case PTRACE_PEEKTEXT: /* read word at location addr. */
+ {
+ unsigned long tmp = 0;
+ int copied;
+
+ ret = -EIO;
+ pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + add %d %ld\n", addr, add,
+ sizeof(data));
+ if (is_user_addr_valid(child, addr + add, sizeof(tmp)) < 0)
+ break;
+ pr_debug("ptrace: user address is valid\n");
+
+#if L1_CODE_LENGTH != 0
+ if (addr + add >= L1_CODE_START
+ && addr + add + sizeof(tmp) <= L1_CODE_START + L1_CODE_LENGTH) {
+ safe_dma_memcpy (&tmp, (const void *)(addr + add), sizeof(tmp));
+ copied = sizeof(tmp);
+ } else
+#endif
+ copied =
+ access_process_vm(child, addr + add, &tmp,
+ sizeof(tmp), 0);
+ pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp);
+ if (copied != sizeof(tmp))
+ break;
+ ret = put_user(tmp, (unsigned long *)data);
+ break;
+ }
+
+ /* read the word at location addr in the USER area. */
+ case PTRACE_PEEKUSR:
+ {
+ unsigned long tmp;
+ ret = -EIO;
+ tmp = 0;
+ if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) {
+ printk(KERN_WARNING "ptrace error : PEEKUSR : temporarily returning "
+ "0 - %x sizeof(pt_regs) is %lx\n",
+ (int)addr, sizeof(struct pt_regs));
+ break;
+ }
+ if (addr == sizeof(struct pt_regs)) {
+ /* PT_TEXT_ADDR */
+ tmp = child->mm->start_code + TEXT_OFFSET;
+ } else if (addr == (sizeof(struct pt_regs) + 4)) {
+ /* PT_TEXT_END_ADDR */
+ tmp = child->mm->end_code;
+ } else if (addr == (sizeof(struct pt_regs) + 8)) {
+ /* PT_DATA_ADDR */
+ tmp = child->mm->start_data;
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+ } else if (addr == (sizeof(struct pt_regs) + 12)) {
+ tmp = child->mm->context.exec_fdpic_loadmap;
+ } else if (addr == (sizeof(struct pt_regs) + 16)) {
+ tmp = child->mm->context.interp_fdpic_loadmap;
+#endif
+ } else {
+ tmp = get_reg(child, addr);
+ }
+ ret = put_user(tmp, (unsigned long *)data);
+ break;
+ }
+
+ /* when I and D space are separate, this will have to be fixed. */
+ case PTRACE_POKEDATA:
+ printk(KERN_NOTICE "ptrace: PTRACE_PEEKDATA\n");
+ /* fall through */
+ case PTRACE_POKETEXT: /* write the word at location addr. */
+ {
+ int copied;
+
+ ret = -EIO;
+ pr_debug("ptrace: POKETEXT at addr 0x%08lx + add %d %ld bytes %lx\n",
+ addr, add, sizeof(data), data);
+ if (is_user_addr_valid(child, addr + add, sizeof(data)) < 0)
+ break;
+ pr_debug("ptrace: user address is valid\n");
+
+#if L1_CODE_LENGTH != 0
+ if (addr + add >= L1_CODE_START
+ && addr + add + sizeof(data) <= L1_CODE_START + L1_CODE_LENGTH) {
+ safe_dma_memcpy ((void *)(addr + add), &data, sizeof(data));
+ copied = sizeof(data);
+ } else
+#endif
+ copied =
+ access_process_vm(child, addr + add, &data,
+ sizeof(data), 1);
+ pr_debug("ptrace: copied size %d\n", copied);
+ if (copied != sizeof(data))
+ break;
+ ret = 0;
+ break;
+ }
+
+ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+ ret = -EIO;
+ if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) {
+ printk(KERN_WARNING "ptrace error : POKEUSR: temporarily returning 0\n");
+ break;
+ }
+
+ if (addr >= (sizeof(struct pt_regs))) {
+ ret = 0;
+ break;
+ }
+ if (addr == PT_SYSCFG) {
+ data &= SYSCFG_MASK;
+ data |= get_reg(child, PT_SYSCFG);
+ }
+ ret = put_reg(child, addr, data);
+ break;
+
+ case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+ case PTRACE_CONT:
+ { /* restart after signal. */
+ long tmp;
+
+ pr_debug("ptrace_cont\n");
+
+ ret = -EIO;
+ if (!valid_signal(data))
+ break;
+ if (request == PTRACE_SYSCALL)
+ set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ else
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+
+ child->exit_code = data;
+ /* make sure the single step bit is not set. */
+ tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS);
+ put_reg(child, PT_SYSCFG, tmp);
+ pr_debug("before wake_up_process\n");
+ wake_up_process(child);
+ ret = 0;
+ break;
+ }
+
+ /*
+ * make the child exit. Best I can do is send it a sigkill.
+ * perhaps it should be put in the status that it wants to
+ * exit.
+ */
+ case PTRACE_KILL:
+ {
+ long tmp;
+ ret = 0;
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
+ break;
+ child->exit_code = SIGKILL;
+ /* make sure the single step bit is not set. */
+ tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS);
+ put_reg(child, PT_SYSCFG, tmp);
+ wake_up_process(child);
+ break;
+ }
+
+ case PTRACE_SINGLESTEP:
+ { /* set the trap flag. */
+ long tmp;
+
+ pr_debug("single step\n");
+ ret = -EIO;
+ if (!valid_signal(data))
+ break;
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+
+ tmp = get_reg(child, PT_SYSCFG) | (TRACE_BITS);
+ put_reg(child, PT_SYSCFG, tmp);
+
+ child->exit_code = data;
+ /* give it a chance to run. */
+ wake_up_process(child);
+ ret = 0;
+ break;
+ }
+
+ case PTRACE_DETACH:
+ { /* detach a process that was attached. */
+ ret = ptrace_detach(child, data);
+ break;
+ }
+
+ case PTRACE_GETREGS:
+ {
+
+ /* Get all gp regs from the child. */
+ ret = ptrace_getregs(child, (void __user *)data);
+ break;
+ }
+
+ case PTRACE_SETREGS:
+ {
+ printk(KERN_NOTICE
+ "ptrace: SETREGS: **** NOT IMPLEMENTED ***\n");
+ /* Set all gp regs in the child. */
+ ret = 0;
+ break;
+ }
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+
+ return ret;
+}
+
+asmlinkage void syscall_trace(void)
+{
+
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
+ return;
+
+ if (!(current->ptrace & PT_PTRACED))
+ return;
+
+ /* the 0x80 provides a way for the tracing parent to distinguish
+ * between a syscall stop and SIGTRAP delivery
+ */
+ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+ ? 0x80 : 0));
+
+ /*
+ * this isn't the same as continuing with a signal, but it will do
+ * for normal use. strace only continues with a signal if the
+ * stopping signal is not SIGTRAP. -brl
+ */
+ if (current->exit_code) {
+ send_sig(current->exit_code, current, 1);
+ current->exit_code = 0;
+ }
+}
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
new file mode 100644
index 0000000..342bb8d
--- /dev/null
+++ b/arch/blackfin/kernel/setup.c
@@ -0,0 +1,902 @@
+/*
+ * File: arch/blackfin/kernel/setup.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/delay.h>
+#include <linux/console.h>
+#include <linux/bootmem.h>
+#include <linux/seq_file.h>
+#include <linux/cpu.h>
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+
+#include <linux/ext2_fs.h>
+#include <linux/cramfs_fs.h>
+#include <linux/romfs_fs.h>
+
+#include <asm/cacheflush.h>
+#include <asm/blackfin.h>
+#include <asm/cplbinit.h>
+
+unsigned long memory_start, memory_end, physical_mem_end;
+unsigned long reserved_mem_dcache_on;
+unsigned long reserved_mem_icache_on;
+EXPORT_SYMBOL(memory_start);
+EXPORT_SYMBOL(memory_end);
+EXPORT_SYMBOL(physical_mem_end);
+EXPORT_SYMBOL(_ramend);
+
+#ifdef CONFIG_MTD_UCLINUX
+unsigned long memory_mtd_end, memory_mtd_start, mtd_size;
+unsigned long _ebss;
+EXPORT_SYMBOL(memory_mtd_end);
+EXPORT_SYMBOL(memory_mtd_start);
+EXPORT_SYMBOL(mtd_size);
+#endif
+
+char command_line[COMMAND_LINE_SIZE];
+
+#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
+static void generate_cpl_tables(void);
+#endif
+
+void __init bf53x_cache_init(void)
+{
+#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
+ generate_cpl_tables();
+#endif
+
+#ifdef CONFIG_BLKFIN_CACHE
+ bfin_icache_init();
+ printk(KERN_INFO "Instruction Cache Enabled\n");
+#endif
+
+#ifdef CONFIG_BLKFIN_DCACHE
+ bfin_dcache_init();
+ printk(KERN_INFO "Data Cache Enabled"
+# if defined CONFIG_BLKFIN_WB
+ " (write-back)"
+# elif defined CONFIG_BLKFIN_WT
+ " (write-through)"
+# endif
+ "\n");
+#endif
+}
+
+void bf53x_relocate_l1_mem(void)
+{
+ unsigned long l1_code_length;
+ unsigned long l1_data_a_length;
+ unsigned long l1_data_b_length;
+
+ l1_code_length = _etext_l1 - _stext_l1;
+ if (l1_code_length > L1_CODE_LENGTH)
+ l1_code_length = L1_CODE_LENGTH;
+ /* cannot complain as printk is not available as yet.
+ * But we can continue booting and complain later!
+ */
+
+ /* Copy _stext_l1 to _etext_l1 to L1 instruction SRAM */
+ dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length);
+
+ l1_data_a_length = _ebss_l1 - _sdata_l1;
+ if (l1_data_a_length > L1_DATA_A_LENGTH)
+ l1_data_a_length = L1_DATA_A_LENGTH;
+
+ /* Copy _sdata_l1 to _ebss_l1 to L1 data bank A SRAM */
+ dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length);
+
+ l1_data_b_length = _ebss_b_l1 - _sdata_b_l1;
+ if (l1_data_b_length > L1_DATA_B_LENGTH)
+ l1_data_b_length = L1_DATA_B_LENGTH;
+
+ /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */
+ dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length +
+ l1_data_a_length, l1_data_b_length);
+
+}
+
+/*
+ * Initial parsing of the command line. Currently, we support:
+ * - Controlling the linux memory size: mem=xxx[KMG]
+ * - Controlling the physical memory size: max_mem=xxx[KMG][$][#]
+ * $ -> reserved memory is dcacheable
+ * # -> reserved memory is icacheable
+ */
+static __init void parse_cmdline_early(char *cmdline_p)
+{
+ char c = ' ', *to = cmdline_p;
+ unsigned int memsize;
+ for (;;) {
+ if (c == ' ') {
+
+ if (!memcmp(to, "mem=", 4)) {
+ to += 4;
+ memsize = memparse(to, &to);
+ if (memsize)
+ _ramend = memsize;
+
+ } else if (!memcmp(to, "max_mem=", 8)) {
+ to += 8;
+ memsize = memparse(to, &to);
+ if (memsize) {
+ physical_mem_end = memsize;
+ if (*to != ' ') {
+ if (*to == '$'
+ || *(to + 1) == '$')
+ reserved_mem_dcache_on =
+ 1;
+ if (*to == '#'
+ || *(to + 1) == '#')
+ reserved_mem_icache_on =
+ 1;
+ }
+ }
+ }
+
+ }
+ c = *(to++);
+ if (!c)
+ break;
+ }
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+ int bootmap_size;
+ unsigned long l1_length, sclk, cclk;
+#ifdef CONFIG_MTD_UCLINUX
+ unsigned long mtd_phys = 0;
+#endif
+
+ cclk = get_cclk();
+ sclk = get_sclk();
+
+#if !defined(CONFIG_BFIN_KERNEL_CLOCK) && defined(ANOMALY_05000273)
+ if (cclk == sclk)
+ panic("ANOMALY 05000273, SCLK can not be same as CCLK");
+#endif
+
+#if defined(ANOMALY_05000266)
+ bfin_read_IMDMA_D0_IRQ_STATUS();
+ bfin_read_IMDMA_D1_IRQ_STATUS();
+#endif
+
+#ifdef DEBUG_SERIAL_EARLY_INIT
+ bfin_console_init(); /* early console registration */
+ /* this give a chance to get printk() working before crash. */
+#endif
+
+#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
+ /* we need to initialize the Flashrom device here since we might
+ * do things with flash early on in the boot
+ */
+ flash_probe();
+#endif
+
+#if defined(CONFIG_CMDLINE_BOOL)
+ memset(command_line, 0, sizeof(command_line));
+ strncpy(&command_line[0], CONFIG_CMDLINE, sizeof(command_line));
+ command_line[sizeof(command_line) - 1] = 0;
+#endif
+
+ /* Keep a copy of command line */
+ *cmdline_p = &command_line[0];
+ memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
+ boot_command_line[COMMAND_LINE_SIZE - 1] = 0;
+
+ /* setup memory defaults from the user config */
+ physical_mem_end = 0;
+ _ramend = CONFIG_MEM_SIZE * 1024 * 1024;
+
+ parse_cmdline_early(&command_line[0]);
+
+ if (physical_mem_end == 0)
+ physical_mem_end = _ramend;
+
+ /* by now the stack is part of the init task */
+ memory_end = _ramend - DMA_UNCACHED_REGION;
+
+ _ramstart = (unsigned long)__bss_stop;
+ memory_start = PAGE_ALIGN(_ramstart);
+
+#if defined(CONFIG_MTD_UCLINUX)
+ /* generic memory mapped MTD driver */
+ memory_mtd_end = memory_end;
+
+ mtd_phys = _ramstart;
+ mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 8)));
+
+# if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS)
+ if (*((unsigned short *)(mtd_phys + 0x438)) == EXT2_SUPER_MAGIC)
+ mtd_size =
+ PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x404)) << 10);
+# endif
+
+# if defined(CONFIG_CRAMFS)
+ if (*((unsigned long *)(mtd_phys)) == CRAMFS_MAGIC)
+ mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x4)));
+# endif
+
+# if defined(CONFIG_ROMFS_FS)
+ if (((unsigned long *)mtd_phys)[0] == ROMSB_WORD0
+ && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1)
+ mtd_size =
+ PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2]));
+# if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
+ /* Due to a Hardware Anomaly we need to limit the size of usable
+ * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
+ * 05000263 - Hardware loop corrupted when taking an ICPLB exception
+ */
+# if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO))
+ if (memory_end >= 56 * 1024 * 1024)
+ memory_end = 56 * 1024 * 1024;
+# else
+ if (memory_end >= 60 * 1024 * 1024)
+ memory_end = 60 * 1024 * 1024;
+# endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */
+# endif /* ANOMALY_05000263 */
+# endif /* CONFIG_ROMFS_FS */
+
+ memory_end -= mtd_size;
+
+ if (mtd_size == 0) {
+ console_init();
+ panic("Don't boot kernel without rootfs attached.\n");
+ }
+
+ /* Relocate MTD image to the top of memory after the uncached memory area */
+ dma_memcpy((char *)memory_end, __bss_stop, mtd_size);
+
+ memory_mtd_start = memory_end;
+ _ebss = memory_mtd_start; /* define _ebss for compatible */
+#endif /* CONFIG_MTD_UCLINUX */
+
+#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
+ /* Due to a Hardware Anomaly we need to limit the size of usable
+ * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
+ * 05000263 - Hardware loop corrupted when taking an ICPLB exception
+ */
+#if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO))
+ if (memory_end >= 56 * 1024 * 1024)
+ memory_end = 56 * 1024 * 1024;
+#else
+ if (memory_end >= 60 * 1024 * 1024)
+ memory_end = 60 * 1024 * 1024;
+#endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */
+ printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20);
+#endif /* ANOMALY_05000263 */
+
+#if !defined(CONFIG_MTD_UCLINUX)
+ memory_end -= SIZE_4K; /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/
+#endif
+ init_mm.start_code = (unsigned long)_stext;
+ init_mm.end_code = (unsigned long)_etext;
+ init_mm.end_data = (unsigned long)_edata;
+ init_mm.brk = (unsigned long)0;
+
+ init_leds();
+
+ printk(KERN_INFO "Blackfin support (C) 2004-2007 Analog Devices, Inc.\n");
+ printk(KERN_INFO "Compiled for ADSP-%s Rev 0.%d\n", CPU, bfin_compiled_revid());
+ if (bfin_revid() != bfin_compiled_revid())
+ printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n",
+ bfin_compiled_revid(), bfin_revid());
+ if (bfin_revid() < SUPPORTED_REVID)
+ printk(KERN_ERR "Warning: Unsupported Chip Revision ADSP-%s Rev 0.%d detected\n",
+ CPU, bfin_revid());
+ printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n");
+
+ printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu Mhz System Clock\n",
+ cclk / 1000000, sclk / 1000000);
+
+#if defined(ANOMALY_05000273)
+ if ((cclk >> 1) <= sclk)
+ printk("\n\n\nANOMALY_05000273: CCLK must be >= 2*SCLK !!!\n\n\n");
+#endif
+
+ printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20);
+ printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20);
+
+ printk(KERN_INFO "Memory map:\n"
+ KERN_INFO " text = 0x%p-0x%p\n"
+ KERN_INFO " init = 0x%p-0x%p\n"
+ KERN_INFO " data = 0x%p-0x%p\n"
+ KERN_INFO " stack = 0x%p-0x%p\n"
+ KERN_INFO " bss = 0x%p-0x%p\n"
+ KERN_INFO " available = 0x%p-0x%p\n"
+#ifdef CONFIG_MTD_UCLINUX
+ KERN_INFO " rootfs = 0x%p-0x%p\n"
+#endif
+#if DMA_UNCACHED_REGION > 0
+ KERN_INFO " DMA Zone = 0x%p-0x%p\n"
+#endif
+ , _stext, _etext,
+ __init_begin, __init_end,
+ _sdata, _edata,
+ (void*)&init_thread_union, (void*)((int)(&init_thread_union) + 0x2000),
+ __bss_start, __bss_stop,
+ (void*)_ramstart, (void*)memory_end
+#ifdef CONFIG_MTD_UCLINUX
+ , (void*)memory_mtd_start, (void*)(memory_mtd_start + mtd_size)
+#endif
+#if DMA_UNCACHED_REGION > 0
+ , (void*)(_ramend - DMA_UNCACHED_REGION), (void*)(_ramend)
+#endif
+ );
+
+ /*
+ * give all the memory to the bootmap allocator, tell it to put the
+ * boot mem_map at the start of memory
+ */
+ bootmap_size = init_bootmem_node(NODE_DATA(0), memory_start >> PAGE_SHIFT, /* map goes here */
+ PAGE_OFFSET >> PAGE_SHIFT,
+ memory_end >> PAGE_SHIFT);
+ /*
+ * free the usable memory, we have to make sure we do not free
+ * the bootmem bitmap so we then reserve it after freeing it :-)
+ */
+ free_bootmem(memory_start, memory_end - memory_start);
+
+ reserve_bootmem(memory_start, bootmap_size);
+ /*
+ * get kmalloc into gear
+ */
+ paging_init();
+
+ /* check the size of the l1 area */
+ l1_length = _etext_l1 - _stext_l1;
+ if (l1_length > L1_CODE_LENGTH)
+ panic("L1 memory overflow\n");
+
+ l1_length = _ebss_l1 - _sdata_l1;
+ if (l1_length > L1_DATA_A_LENGTH)
+ panic("L1 memory overflow\n");
+
+ bf53x_cache_init();
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+# if defined(CONFIG_BFIN_SHARED_FLASH_ENET) && defined(CONFIG_BFIN533_STAMP)
+ /* setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC */
+ bfin_write_FIO_DIR(bfin_read_FIO_DIR() | (1 << CONFIG_ENET_FLASH_PIN));
+ bfin_write_FIO_FLAG_S(1 << CONFIG_ENET_FLASH_PIN);
+ SSYNC();
+# endif
+# if defined (CONFIG_BFIN561_EZKIT)
+ bfin_write_FIO0_DIR(bfin_read_FIO0_DIR() | (1 << 12));
+ SSYNC();
+# endif /* defined (CONFIG_BFIN561_EZKIT) */
+#endif
+
+ printk(KERN_INFO "Hardware Trace Enabled\n");
+ bfin_write_TBUFCTL(0x03);
+}
+
+#if defined(CONFIG_BF561)
+static struct cpu cpu[2];
+#else
+static struct cpu cpu[1];
+#endif
+static int __init topology_init(void)
+{
+#if defined (CONFIG_BF561)
+ register_cpu(&cpu[0], 0);
+ register_cpu(&cpu[1], 1);
+ return 0;
+#else
+ return register_cpu(cpu, 0);
+#endif
+}
+
+subsys_initcall(topology_init);
+
+#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
+u16 lock_kernel_check(u32 start, u32 end)
+{
+ if ((start <= (u32) _stext && end >= (u32) _end)
+ || (start >= (u32) _stext && end <= (u32) _end))
+ return IN_KERNEL;
+ return 0;
+}
+
+static unsigned short __init
+fill_cplbtab(struct cplb_tab *table,
+ unsigned long start, unsigned long end,
+ unsigned long block_size, unsigned long cplb_data)
+{
+ int i;
+
+ switch (block_size) {
+ case SIZE_4M:
+ i = 3;
+ break;
+ case SIZE_1M:
+ i = 2;
+ break;
+ case SIZE_4K:
+ i = 1;
+ break;
+ case SIZE_1K:
+ default:
+ i = 0;
+ break;
+ }
+
+ cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
+
+ while ((start < end) && (table->pos < table->size)) {
+
+ table->tab[table->pos++] = start;
+
+ if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
+ table->tab[table->pos++] =
+ cplb_data | CPLB_LOCK | CPLB_DIRTY;
+ else
+ table->tab[table->pos++] = cplb_data;
+
+ start += block_size;
+ }
+ return 0;
+}
+
+static unsigned short __init
+close_cplbtab(struct cplb_tab *table)
+{
+
+ while (table->pos < table->size) {
+
+ table->tab[table->pos++] = 0;
+ table->tab[table->pos++] = 0; /* !CPLB_VALID */
+ }
+ return 0;
+}
+
+static void __init generate_cpl_tables(void)
+{
+
+ u16 i, j, process;
+ u32 a_start, a_end, as, ae, as_1m;
+
+ struct cplb_tab *t_i = NULL;
+ struct cplb_tab *t_d = NULL;
+ struct s_cplb cplb;
+
+ cplb.init_i.size = MAX_CPLBS;
+ cplb.init_d.size = MAX_CPLBS;
+ cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
+ cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
+
+ cplb.init_i.pos = 0;
+ cplb.init_d.pos = 0;
+ cplb.switch_i.pos = 0;
+ cplb.switch_d.pos = 0;
+
+ cplb.init_i.tab = icplb_table;
+ cplb.init_d.tab = dcplb_table;
+ cplb.switch_i.tab = ipdt_table;
+ cplb.switch_d.tab = dpdt_table;
+
+ cplb_data[SDRAM_KERN].end = memory_end;
+
+#ifdef CONFIG_MTD_UCLINUX
+ cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
+ cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
+ cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
+# if defined(CONFIG_ROMFS_FS)
+ cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
+
+ /*
+ * The ROMFS_FS size is often not multiple of 1MB.
+ * This can cause multiple CPLB sets covering the same memory area.
+ * This will then cause multiple CPLB hit exceptions.
+ * Workaround: We ensure a contiguous memory area by extending the kernel
+ * memory section over the mtd section.
+ * For ROMFS_FS memory must be covered with ICPLBs anyways.
+ * So there is no difference between kernel and mtd memory setup.
+ */
+
+ cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
+ cplb_data[SDRAM_RAM_MTD].valid = 0;
+
+# endif
+#else
+ cplb_data[SDRAM_RAM_MTD].valid = 0;
+#endif
+
+ cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
+ cplb_data[SDRAM_DMAZ].end = _ramend;
+
+ cplb_data[RES_MEM].start = _ramend;
+ cplb_data[RES_MEM].end = physical_mem_end;
+
+ if (reserved_mem_dcache_on)
+ cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
+ else
+ cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
+
+ if (reserved_mem_icache_on)
+ cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
+ else
+ cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
+
+ for (i = ZERO_P; i <= L2_MEM; i++) {
+
+ if (cplb_data[i].valid) {
+
+ as_1m = cplb_data[i].start % SIZE_1M;
+
+ /* We need to make sure all sections are properly 1M aligned
+ * However between Kernel Memory and the Kernel mtd section, depending on the
+ * rootfs size, there can be overlapping memory areas.
+ */
+
+ if (as_1m && i!=L1I_MEM && i!=L1D_MEM) {
+#ifdef CONFIG_MTD_UCLINUX
+ if (i == SDRAM_RAM_MTD) {
+ if ((cplb_data[SDRAM_KERN].end + 1) > cplb_data[SDRAM_RAM_MTD].start)
+ cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M)) + SIZE_1M;
+ else
+ cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M));
+ } else
+#endif
+ printk(KERN_WARNING "Unaligned Start of %s at 0x%X\n",
+ cplb_data[i].name, cplb_data[i].start);
+ }
+
+ as = cplb_data[i].start % SIZE_4M;
+ ae = cplb_data[i].end % SIZE_4M;
+
+ if (as)
+ a_start = cplb_data[i].start + (SIZE_4M - (as));
+ else
+ a_start = cplb_data[i].start;
+
+ a_end = cplb_data[i].end - ae;
+
+ for (j = INITIAL_T; j <= SWITCH_T; j++) {
+
+ switch (j) {
+ case INITIAL_T:
+ if (cplb_data[i].attr & INITIAL_T) {
+ t_i = &cplb.init_i;
+ t_d = &cplb.init_d;
+ process = 1;
+ } else
+ process = 0;
+ break;
+ case SWITCH_T:
+ if (cplb_data[i].attr & SWITCH_T) {
+ t_i = &cplb.switch_i;
+ t_d = &cplb.switch_d;
+ process = 1;
+ } else
+ process = 0;
+ break;
+ default:
+ process = 0;
+ break;
+ }
+
+ if (process) {
+ if (cplb_data[i].attr & I_CPLB) {
+
+ if (cplb_data[i].psize) {
+ fill_cplbtab(t_i,
+ cplb_data[i].start,
+ cplb_data[i].end,
+ cplb_data[i].psize,
+ cplb_data[i].i_conf);
+ } else {
+ /*icplb_table */
+#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
+ if (i == SDRAM_KERN) {
+ fill_cplbtab(t_i,
+ cplb_data[i].start,
+ cplb_data[i].end,
+ SIZE_4M,
+ cplb_data[i].i_conf);
+ } else
+#endif
+ {
+ fill_cplbtab(t_i,
+ cplb_data[i].start,
+ a_start,
+ SIZE_1M,
+ cplb_data[i].i_conf);
+ fill_cplbtab(t_i,
+ a_start,
+ a_end,
+ SIZE_4M,
+ cplb_data[i].i_conf);
+ fill_cplbtab(t_i, a_end,
+ cplb_data[i].end,
+ SIZE_1M,
+ cplb_data[i].i_conf);
+ }
+ }
+
+ }
+ if (cplb_data[i].attr & D_CPLB) {
+
+ if (cplb_data[i].psize) {
+ fill_cplbtab(t_d,
+ cplb_data[i].start,
+ cplb_data[i].end,
+ cplb_data[i].psize,
+ cplb_data[i].d_conf);
+ } else {
+/*dcplb_table*/
+ fill_cplbtab(t_d,
+ cplb_data[i].start,
+ a_start, SIZE_1M,
+ cplb_data[i].d_conf);
+ fill_cplbtab(t_d, a_start,
+ a_end, SIZE_4M,
+ cplb_data[i].d_conf);
+ fill_cplbtab(t_d, a_end,
+ cplb_data[i].end,
+ SIZE_1M,
+ cplb_data[i].d_conf);
+
+ }
+
+ }
+ }
+ }
+
+ }
+ }
+
+/* close tables */
+
+ close_cplbtab(&cplb.init_i);
+ close_cplbtab(&cplb.init_d);
+
+ cplb.init_i.tab[cplb.init_i.pos] = -1;
+ cplb.init_d.tab[cplb.init_d.pos] = -1;
+ cplb.switch_i.tab[cplb.switch_i.pos] = -1;
+ cplb.switch_d.tab[cplb.switch_d.pos] = -1;
+
+}
+
+#endif
+
+static inline u_long get_vco(void)
+{
+ u_long msel;
+ u_long vco;
+
+ msel = (bfin_read_PLL_CTL() >> 9) & 0x3F;
+ if (0 == msel)
+ msel = 64;
+
+ vco = CONFIG_CLKIN_HZ;
+ vco >>= (1 & bfin_read_PLL_CTL()); /* DF bit */
+ vco = msel * vco;
+ return vco;
+}
+
+/*Get the Core clock*/
+u_long get_cclk(void)
+{
+ u_long csel, ssel;
+ if (bfin_read_PLL_STAT() & 0x1)
+ return CONFIG_CLKIN_HZ;
+
+ ssel = bfin_read_PLL_DIV();
+ csel = ((ssel >> 4) & 0x03);
+ ssel &= 0xf;
+ if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */
+ return get_vco() / ssel;
+ return get_vco() >> csel;
+}
+
+EXPORT_SYMBOL(get_cclk);
+
+/* Get the System clock */
+u_long get_sclk(void)
+{
+ u_long ssel;
+
+ if (bfin_read_PLL_STAT() & 0x1)
+ return CONFIG_CLKIN_HZ;
+
+ ssel = (bfin_read_PLL_DIV() & 0xf);
+ if (0 == ssel) {
+ printk(KERN_WARNING "Invalid System Clock\n");
+ ssel = 1;
+ }
+
+ return get_vco() / ssel;
+}
+
+EXPORT_SYMBOL(get_sclk);
+
+/*
+ * Get CPU information for use by the procfs.
+ */
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+ char *cpu, *mmu, *fpu, *name;
+ uint32_t revid;
+
+ u_long cclk = 0, sclk = 0;
+ u_int dcache_size = 0, dsup_banks = 0;
+
+ cpu = CPU;
+ mmu = "none";
+ fpu = "none";
+ revid = bfin_revid();
+ name = bfin_board_name;
+
+ cclk = get_cclk();
+ sclk = get_sclk();
+
+ seq_printf(m, "CPU:\t\tADSP-%s Rev. 0.%d\n"
+ "MMU:\t\t%s\n"
+ "FPU:\t\t%s\n"
+ "Core Clock:\t%9lu Hz\n"
+ "System Clock:\t%9lu Hz\n"
+ "BogoMips:\t%lu.%02lu\n"
+ "Calibration:\t%lu loops\n",
+ cpu, revid, mmu, fpu,
+ cclk,
+ sclk,
+ (loops_per_jiffy * HZ) / 500000,
+ ((loops_per_jiffy * HZ) / 5000) % 100,
+ (loops_per_jiffy * HZ));
+ seq_printf(m, "Board Name:\t%s\n", name);
+ seq_printf(m, "Board Memory:\t%ld MB\n", physical_mem_end >> 20);
+ seq_printf(m, "Kernel Memory:\t%ld MB\n", (unsigned long)_ramend >> 20);
+ if (bfin_read_IMEM_CONTROL() & (ENICPLB | IMC))
+ seq_printf(m, "I-CACHE:\tON\n");
+ else
+ seq_printf(m, "I-CACHE:\tOFF\n");
+ if ((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE))
+ seq_printf(m, "D-CACHE:\tON"
+#if defined CONFIG_BLKFIN_WB
+ " (write-back)"
+#elif defined CONFIG_BLKFIN_WT
+ " (write-through)"
+#endif
+ "\n");
+ else
+ seq_printf(m, "D-CACHE:\tOFF\n");
+
+
+ switch(bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) {
+ case ACACHE_BSRAM:
+ seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n");
+ dcache_size = 16;
+ dsup_banks = 1;
+ break;
+ case ACACHE_BCACHE:
+ seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n");
+ dcache_size = 32;
+ dsup_banks = 2;
+ break;
+ case ASRAM_BSRAM:
+ seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n");
+ dcache_size = 0;
+ dsup_banks = 0;
+ break;
+ default:
+ break;
+ }
+
+
+ seq_printf(m, "I-CACHE Size:\t%dKB\n", BLKFIN_ICACHESIZE / 1024);
+ seq_printf(m, "D-CACHE Size:\t%dKB\n", dcache_size);
+ seq_printf(m, "I-CACHE Setup:\t%d Sub-banks/%d Ways, %d Lines/Way\n",
+ BLKFIN_ISUBBANKS, BLKFIN_IWAYS, BLKFIN_ILINES);
+ seq_printf(m,
+ "D-CACHE Setup:\t%d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n",
+ dsup_banks, BLKFIN_DSUBBANKS, BLKFIN_DWAYS,
+ BLKFIN_DLINES);
+#ifdef CONFIG_BLKFIN_CACHE_LOCK
+ switch (read_iloc()) {
+ case WAY0_L:
+ seq_printf(m, "Way0 Locked-Down\n");
+ break;
+ case WAY1_L:
+ seq_printf(m, "Way1 Locked-Down\n");
+ break;
+ case WAY01_L:
+ seq_printf(m, "Way0,Way1 Locked-Down\n");
+ break;
+ case WAY2_L:
+ seq_printf(m, "Way2 Locked-Down\n");
+ break;
+ case WAY02_L:
+ seq_printf(m, "Way0,Way2 Locked-Down\n");
+ break;
+ case WAY12_L:
+ seq_printf(m, "Way1,Way2 Locked-Down\n");
+ break;
+ case WAY012_L:
+ seq_printf(m, "Way0,Way1 & Way2 Locked-Down\n");
+ break;
+ case WAY3_L:
+ seq_printf(m, "Way3 Locked-Down\n");
+ break;
+ case WAY03_L:
+ seq_printf(m, "Way0,Way3 Locked-Down\n");
+ break;
+ case WAY13_L:
+ seq_printf(m, "Way1,Way3 Locked-Down\n");
+ break;
+ case WAY013_L:
+ seq_printf(m, "Way 0,Way1,Way3 Locked-Down\n");
+ break;
+ case WAY32_L:
+ seq_printf(m, "Way3,Way2 Locked-Down\n");
+ break;
+ case WAY320_L:
+ seq_printf(m, "Way3,Way2,Way0 Locked-Down\n");
+ break;
+ case WAY321_L:
+ seq_printf(m, "Way3,Way2,Way1 Locked-Down\n");
+ break;
+ case WAYALL_L:
+ seq_printf(m, "All Ways are locked\n");
+ break;
+ default:
+ seq_printf(m, "No Ways are locked\n");
+ }
+#endif
+ return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ return *pos < NR_CPUS ? ((void *)0x12345678) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = show_cpuinfo,
+};
+
+void cmdline_init(unsigned long r0)
+{
+ if (r0)
+ strncpy(command_line, (char *)r0, COMMAND_LINE_SIZE);
+}
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
new file mode 100644
index 0000000..316e65c
--- /dev/null
+++ b/arch/blackfin/kernel/signal.c
@@ -0,0 +1,356 @@
+/*
+ * File: arch/blackfin/kernel/signal.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/signal.h>
+#include <linux/syscalls.h>
+#include <linux/ptrace.h>
+#include <linux/tty.h>
+#include <linux/personality.h>
+#include <linux/binfmts.h>
+#include <linux/freezer.h>
+
+#include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+#include <asm/ucontext.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+struct fdpic_func_descriptor {
+ unsigned long text;
+ unsigned long GOT;
+};
+
+struct rt_sigframe {
+ int sig;
+ struct siginfo *pinfo;
+ void *puc;
+ char retcode[8];
+ struct siginfo info;
+ struct ucontext uc;
+};
+
+asmlinkage int sys_sigaltstack(const stack_t * uss, stack_t * uoss)
+{
+ return do_sigaltstack(uss, uoss, rdusp());
+}
+
+static inline int
+rt_restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *pr0)
+{
+ unsigned long usp = 0;
+ int err = 0;
+
+#define RESTORE(x) err |= __get_user(regs->x, &sc->sc_##x)
+
+ /* restore passed registers */
+ RESTORE(r0); RESTORE(r1); RESTORE(r2); RESTORE(r3);
+ RESTORE(r4); RESTORE(r5); RESTORE(r6); RESTORE(r7);
+ RESTORE(p0); RESTORE(p1); RESTORE(p2); RESTORE(p3);
+ RESTORE(p4); RESTORE(p5);
+ err |= __get_user(usp, &sc->sc_usp);
+ wrusp(usp);
+ RESTORE(a0w); RESTORE(a1w);
+ RESTORE(a0x); RESTORE(a1x);
+ RESTORE(astat);
+ RESTORE(rets);
+ RESTORE(pc);
+ RESTORE(retx);
+ RESTORE(fp);
+ RESTORE(i0); RESTORE(i1); RESTORE(i2); RESTORE(i3);
+ RESTORE(m0); RESTORE(m1); RESTORE(m2); RESTORE(m3);
+ RESTORE(l0); RESTORE(l1); RESTORE(l2); RESTORE(l3);
+ RESTORE(b0); RESTORE(b1); RESTORE(b2); RESTORE(b3);
+ RESTORE(lc0); RESTORE(lc1);
+ RESTORE(lt0); RESTORE(lt1);
+ RESTORE(lb0); RESTORE(lb1);
+ RESTORE(seqstat);
+
+ regs->orig_p0 = -1; /* disable syscall checks */
+
+ *pr0 = regs->r0;
+ return err;
+}
+
+asmlinkage int do_rt_sigreturn(unsigned long __unused)
+{
+ struct pt_regs *regs = (struct pt_regs *)__unused;
+ unsigned long usp = rdusp();
+ struct rt_sigframe *frame = (struct rt_sigframe *)(usp);
+ sigset_t set;
+ int r0;
+
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+ goto badframe;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = set;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ if (rt_restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
+ goto badframe;
+
+ if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->usp) == -EFAULT)
+ goto badframe;
+
+ return r0;
+
+ badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+static inline int rt_setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs)
+{
+ int err = 0;
+
+#define SETUP(x) err |= __put_user(regs->x, &sc->sc_##x)
+
+ SETUP(r0); SETUP(r1); SETUP(r2); SETUP(r3);
+ SETUP(r4); SETUP(r5); SETUP(r6); SETUP(r7);
+ SETUP(p0); SETUP(p1); SETUP(p2); SETUP(p3);
+ SETUP(p4); SETUP(p5);
+ err |= __put_user(rdusp(), &sc->sc_usp);
+ SETUP(a0w); SETUP(a1w);
+ SETUP(a0x); SETUP(a1x);
+ SETUP(astat);
+ SETUP(rets);
+ SETUP(pc);
+ SETUP(retx);
+ SETUP(fp);
+ SETUP(i0); SETUP(i1); SETUP(i2); SETUP(i3);
+ SETUP(m0); SETUP(m1); SETUP(m2); SETUP(m3);
+ SETUP(l0); SETUP(l1); SETUP(l2); SETUP(l3);
+ SETUP(b0); SETUP(b1); SETUP(b2); SETUP(b3);
+ SETUP(lc0); SETUP(lc1);
+ SETUP(lt0); SETUP(lt1);
+ SETUP(lb0); SETUP(lb1);
+ SETUP(seqstat);
+
+ return err;
+}
+
+static inline void push_cache(unsigned long vaddr, unsigned int len)
+{
+ flush_icache_range(vaddr, vaddr + len);
+}
+
+static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+ size_t frame_size)
+{
+ unsigned long usp;
+
+ /* Default to using normal stack. */
+ usp = rdusp();
+
+ /* This is the X/Open sanctioned signal stack switching. */
+ if (ka->sa.sa_flags & SA_ONSTACK) {
+ if (!on_sig_stack(usp))
+ usp = current->sas_ss_sp + current->sas_ss_size;
+ }
+ return (void *)((usp - frame_size) & -8UL);
+}
+
+static int
+setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
+ sigset_t * set, struct pt_regs *regs)
+{
+ struct rt_sigframe *frame;
+ int err = 0;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+
+ err |= __put_user((current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->
+ signal_invmap[sig] : sig), &frame->sig);
+
+ err |= __put_user(&frame->info, &frame->pinfo);
+ err |= __put_user(&frame->uc, &frame->puc);
+ err |= copy_siginfo_to_user(&frame->info, info);
+
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->uc.uc_flags);
+ err |= __put_user(0, &frame->uc.uc_link);
+ err |=
+ __put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
+ err |= __put_user(sas_ss_flags(rdusp()), &frame->uc.uc_stack.ss_flags);
+ err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+ err |= rt_setup_sigcontext(&frame->uc.uc_mcontext, regs);
+ err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+ /* Set up to return from userspace. */
+ err |= __put_user(0x28, &(frame->retcode[0]));
+ err |= __put_user(0xe1, &(frame->retcode[1]));
+ err |= __put_user(0xad, &(frame->retcode[2]));
+ err |= __put_user(0x00, &(frame->retcode[3]));
+ err |= __put_user(0xa0, &(frame->retcode[4]));
+ err |= __put_user(0x00, &(frame->retcode[5]));
+
+ if (err)
+ goto give_sigsegv;
+
+ push_cache((unsigned long)&frame->retcode, sizeof(frame->retcode));
+
+ /* Set up registers for signal handler */
+ wrusp((unsigned long)frame);
+ if (get_personality & FDPIC_FUNCPTRS) {
+ struct fdpic_func_descriptor __user *funcptr =
+ (struct fdpic_func_descriptor *) ka->sa.sa_handler;
+ __get_user(regs->pc, &funcptr->text);
+ __get_user(regs->p3, &funcptr->GOT);
+ } else
+ regs->pc = (unsigned long)ka->sa.sa_handler;
+ regs->rets = (unsigned long)(frame->retcode);
+
+ regs->r0 = frame->sig;
+ regs->r1 = (unsigned long)(&frame->info);
+ regs->r2 = (unsigned long)(&frame->uc);
+
+ return 0;
+
+ give_sigsegv:
+ if (sig == SIGSEGV)
+ ka->sa.sa_handler = SIG_DFL;
+ force_sig(SIGSEGV, current);
+ return -EFAULT;
+}
+
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+ switch (regs->r0) {
+ case -ERESTARTNOHAND:
+ if (!has_handler)
+ goto do_restart;
+ regs->r0 = -EINTR;
+ break;
+
+ case -ERESTARTSYS:
+ if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+ regs->r0 = -EINTR;
+ break;
+ }
+ /* fallthrough */
+ case -ERESTARTNOINTR:
+ do_restart:
+ regs->p0 = regs->orig_p0;
+ regs->r0 = regs->orig_r0;
+ regs->pc -= 2;
+ break;
+ }
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static int
+handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
+ sigset_t *oldset, struct pt_regs *regs)
+{
+ int ret;
+
+ /* are we from a system call? to see pt_regs->orig_p0 */
+ if (regs->orig_p0 >= 0)
+ /* If so, check system call restarting.. */
+ handle_restart(regs, ka, 1);
+
+ /* set up the stack frame */
+ ret = setup_rt_frame(sig, ka, info, oldset, regs);
+
+ if (ret == 0) {
+ spin_lock_irq(&current->sighand->siglock);
+ sigorsets(&current->blocked, &current->blocked,
+ &ka->sa.sa_mask);
+ if (!(ka->sa.sa_flags & SA_NODEFER))
+ sigaddset(&current->blocked, sig);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+ }
+ return ret;
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals
+ * that the kernel can handle, and then we build all the user-level signal
+ * handling stack-frames in one go after that.
+ */
+asmlinkage void do_signal(struct pt_regs *regs)
+{
+ siginfo_t info;
+ int signr;
+ struct k_sigaction ka;
+ sigset_t *oldset;
+
+ current->thread.esp0 = (unsigned long)regs;
+
+ if (try_to_freeze())
+ goto no_signal;
+
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ oldset = &current->saved_sigmask;
+ else
+ oldset = &current->blocked;
+
+ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+ if (signr > 0) {
+ /* Whee! Actually deliver the signal. */
+ if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
+ /* a signal was successfully delivered; the saved
+ * sigmask will have been stored in the signal frame,
+ * and will be restored by sigreturn, so we can simply
+ * clear the TIF_RESTORE_SIGMASK flag */
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ }
+
+ return;
+ }
+
+no_signal:
+ /* Did we come from a system call? */
+ if (regs->orig_p0 >= 0)
+ /* Restart the system call - no handlers present */
+ handle_restart(regs, NULL, 0);
+
+ /* if there's no signal to deliver, we just put the saved sigmask
+ * back */
+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+ }
+}
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c
new file mode 100644
index 0000000..f436e67
--- /dev/null
+++ b/arch/blackfin/kernel/sys_bfin.c
@@ -0,0 +1,115 @@
+/*
+ * File: arch/blackfin/kernel/sys_bfin.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/bfin
+ * platform.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/syscalls.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+
+#include <asm/cacheflush.h>
+#include <asm/uaccess.h>
+#include <asm/ipc.h>
+#include <asm/dma.h>
+#include <asm/unistd.h>
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+asmlinkage int sys_pipe(unsigned long *fildes)
+{
+ int fd[2];
+ int error;
+
+ error = do_pipe(fd);
+ if (!error) {
+ if (copy_to_user(fildes, fd, 2 * sizeof(int)))
+ error = -EFAULT;
+ }
+ return error;
+}
+
+/* common code for old and new mmaps */
+static inline long
+do_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ int error = -EBADF;
+ struct file *file = NULL;
+
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ if (!(flags & MAP_ANONYMOUS)) {
+ file = fget(fd);
+ if (!file)
+ goto out;
+ }
+
+ down_write(&current->mm->mmap_sem);
+ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+ up_write(&current->mm->mmap_sem);
+
+ if (file)
+ fput(file);
+ out:
+ return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+asmlinkage int sys_getpagesize(void)
+{
+ return PAGE_SIZE;
+}
+
+asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags)
+{
+ return sram_alloc_with_lsl(size, flags);
+}
+
+asmlinkage int sys_sram_free(const void *addr)
+{
+ return sram_free_with_lsl(addr);
+}
+
+asmlinkage void *sys_dma_memcpy(void *dest, const void *src, size_t len)
+{
+ return safe_dma_memcpy(dest, src, len);
+}
diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c
new file mode 100644
index 0000000..f578176
--- /dev/null
+++ b/arch/blackfin/kernel/time.c
@@ -0,0 +1,326 @@
+/*
+ * File: arch/blackfin/kernel/time.c
+ * Based on: none - original work
+ * Author:
+ *
+ * Created:
+ * Description: This file contains the bfin-specific time handling details.
+ * Most of the stuff is located in the machine specific files.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/profile.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/irq.h>
+
+#include <asm/blackfin.h>
+
+/* This is an NTP setting */
+#define TICK_SIZE (tick_nsec / 1000)
+
+static void time_sched_init(irqreturn_t(*timer_routine)
+ (int, void *));
+static unsigned long gettimeoffset(void);
+static inline void do_leds(void);
+
+#if (defined(CONFIG_BFIN_ALIVE_LED) || defined(CONFIG_BFIN_IDLE_LED))
+void __init init_leds(void)
+{
+ unsigned int tmp = 0;
+
+#if defined(CONFIG_BFIN_ALIVE_LED)
+ /* config pins as output. */
+ tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_DPORT();
+ SSYNC();
+ bfin_write_CONFIG_BFIN_ALIVE_LED_DPORT(tmp | CONFIG_BFIN_ALIVE_LED_PIN);
+ SSYNC();
+
+ /* First set led be off */
+ tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_PORT();
+ SSYNC();
+ bfin_write_CONFIG_BFIN_ALIVE_LED_PORT(tmp | CONFIG_BFIN_ALIVE_LED_PIN); /* light off */
+ SSYNC();
+#endif
+
+#if defined(CONFIG_BFIN_IDLE_LED)
+ /* config pins as output. */
+ tmp = bfin_read_CONFIG_BFIN_IDLE_LED_DPORT();
+ SSYNC();
+ bfin_write_CONFIG_BFIN_IDLE_LED_DPORT(tmp | CONFIG_BFIN_IDLE_LED_PIN);
+ SSYNC();
+
+ /* First set led be off */
+ tmp = bfin_read_CONFIG_BFIN_IDLE_LED_PORT();
+ SSYNC();
+ bfin_write_CONFIG_BFIN_IDLE_LED_PORT(tmp | CONFIG_BFIN_IDLE_LED_PIN); /* light off */
+ SSYNC();
+#endif
+}
+#else
+void __init init_leds(void)
+{
+}
+#endif
+
+#if defined(CONFIG_BFIN_ALIVE_LED)
+static inline void do_leds(void)
+{
+ static unsigned int count = 50;
+ static int flag = 0;
+ unsigned short tmp = 0;
+
+ if (--count == 0) {
+ count = 50;
+ flag = ~flag;
+ }
+ tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_PORT();
+ SSYNC();
+
+ if (flag)
+ tmp &= ~CONFIG_BFIN_ALIVE_LED_PIN; /* light on */
+ else
+ tmp |= CONFIG_BFIN_ALIVE_LED_PIN; /* light off */
+
+ bfin_write_CONFIG_BFIN_ALIVE_LED_PORT(tmp);
+ SSYNC();
+
+}
+#else
+static inline void do_leds(void)
+{
+}
+#endif
+
+static struct irqaction bfin_timer_irq = {
+ .name = "BFIN Timer Tick",
+ .flags = IRQF_DISABLED
+};
+
+/*
+ * The way that the Blackfin core timer works is:
+ * - CCLK is divided by a programmable 8-bit pre-scaler (TSCALE)
+ * - Every time TSCALE ticks, a 32bit is counted down (TCOUNT)
+ *
+ * If you take the fastest clock (1ns, or 1GHz to make the math work easier)
+ * 10ms is 10,000,000 clock ticks, which fits easy into a 32-bit counter
+ * (32 bit counter is 4,294,967,296ns or 4.2 seconds) so, we don't need
+ * to use TSCALE, and program it to zero (which is pass CCLK through).
+ * If you feel like using it, try to keep HZ * TIMESCALE to some
+ * value that divides easy (like power of 2).
+ */
+
+#define TIME_SCALE 1
+
+static void
+time_sched_init(irqreturn_t(*timer_routine) (int, void *))
+{
+ u32 tcount;
+
+ /* power up the timer, but don't enable it just yet */
+ bfin_write_TCNTL(1);
+ CSYNC();
+
+ /*
+ * the TSCALE prescaler counter.
+ */
+ bfin_write_TSCALE((TIME_SCALE - 1));
+
+ tcount = ((get_cclk() / (HZ * TIME_SCALE)) - 1);
+ bfin_write_TPERIOD(tcount);
+ bfin_write_TCOUNT(tcount);
+
+ /* now enable the timer */
+ CSYNC();
+
+ bfin_write_TCNTL(7);
+
+ bfin_timer_irq.handler = (irq_handler_t)timer_routine;
+ /* call setup_irq instead of request_irq because request_irq calls
+ * kmalloc which has not been initialized yet
+ */
+ setup_irq(IRQ_CORETMR, &bfin_timer_irq);
+}
+
+/*
+ * Should return useconds since last timer tick
+ */
+static unsigned long gettimeoffset(void)
+{
+ unsigned long offset;
+ unsigned long clocks_per_jiffy;
+
+ clocks_per_jiffy = bfin_read_TPERIOD();
+ offset =
+ (clocks_per_jiffy -
+ bfin_read_TCOUNT()) / (((clocks_per_jiffy + 1) * HZ) /
+ USEC_PER_SEC);
+
+ /* Check if we just wrapped the counters and maybe missed a tick */
+ if ((bfin_read_ILAT() & (1 << IRQ_CORETMR))
+ && (offset < (100000 / HZ / 2)))
+ offset += (USEC_PER_SEC / HZ);
+
+ return offset;
+}
+
+static inline int set_rtc_mmss(unsigned long nowtime)
+{
+ return 0;
+}
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+#ifdef CONFIG_CORE_TIMER_IRQ_L1
+irqreturn_t timer_interrupt(int irq, void *dummy)__attribute__((l1_text));
+#endif
+
+irqreturn_t timer_interrupt(int irq, void *dummy)
+{
+ /* last time the cmos clock got updated */
+ static long last_rtc_update = 0;
+
+ write_seqlock(&xtime_lock);
+
+ do_timer(1);
+ do_leds();
+
+#ifndef CONFIG_SMP
+ update_process_times(user_mode(get_irq_regs()));
+#endif
+ profile_tick(CPU_PROFILING);
+
+ /*
+ * If we have an externally synchronized Linux clock, then update
+ * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+ * called as close as possible to 500 ms before the new second starts.
+ */
+
+ if (ntp_synced() &&
+ xtime.tv_sec > last_rtc_update + 660 &&
+ (xtime.tv_nsec / NSEC_PER_USEC) >=
+ 500000 - ((unsigned)TICK_SIZE) / 2
+ && (xtime.tv_nsec / NSEC_PER_USEC) <=
+ 500000 + ((unsigned)TICK_SIZE) / 2) {
+ if (set_rtc_mmss(xtime.tv_sec) == 0)
+ last_rtc_update = xtime.tv_sec;
+ else
+ /* Do it again in 60s. */
+ last_rtc_update = xtime.tv_sec - 600;
+ }
+ write_sequnlock(&xtime_lock);
+ return IRQ_HANDLED;
+}
+
+void __init time_init(void)
+{
+ time_t secs_since_1970 = (365 * 37 + 9) * 24 * 60 * 60; /* 1 Jan 2007 */
+
+#ifdef CONFIG_RTC_DRV_BFIN
+ /* [#2663] hack to filter junk RTC values that would cause
+ * userspace to have to deal with time values greater than
+ * 2^31 seconds (which uClibc cannot cope with yet)
+ */
+ if ((bfin_read_RTC_STAT() & 0xC0000000) == 0xC0000000) {
+ printk(KERN_NOTICE "bfin-rtc: invalid date; resetting\n");
+ bfin_write_RTC_STAT(0);
+ }
+#endif
+
+ /* Initialize xtime. From now on, xtime is updated with timer interrupts */
+ xtime.tv_sec = secs_since_1970;
+ xtime.tv_nsec = 0;
+
+ wall_to_monotonic.tv_sec = -xtime.tv_sec;
+
+ time_sched_init(timer_interrupt);
+}
+
+#ifndef CONFIG_GENERIC_TIME
+void do_gettimeofday(struct timeval *tv)
+{
+ unsigned long flags;
+ unsigned long seq;
+ unsigned long usec, sec;
+
+ do {
+ seq = read_seqbegin_irqsave(&xtime_lock, flags);
+ usec = gettimeoffset();
+ sec = xtime.tv_sec;
+ usec += (xtime.tv_nsec / NSEC_PER_USEC);
+ }
+ while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
+
+ while (usec >= USEC_PER_SEC) {
+ usec -= USEC_PER_SEC;
+ sec++;
+ }
+
+ tv->tv_sec = sec;
+ tv->tv_usec = usec;
+}
+EXPORT_SYMBOL(do_gettimeofday);
+
+int do_settimeofday(struct timespec *tv)
+{
+ time_t wtm_sec, sec = tv->tv_sec;
+ long wtm_nsec, nsec = tv->tv_nsec;
+
+ if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
+ return -EINVAL;
+
+ write_seqlock_irq(&xtime_lock);
+ /*
+ * This is revolting. We need to set the xtime.tv_usec
+ * correctly. However, the value in this location is
+ * is value at the last tick.
+ * Discover what correction gettimeofday
+ * would have done, and then undo it!
+ */
+ nsec -= (gettimeoffset() * NSEC_PER_USEC);
+
+ wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
+ wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
+
+ set_normalized_timespec(&xtime, sec, nsec);
+ set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+
+ ntp_clear();
+
+ write_sequnlock_irq(&xtime_lock);
+ clock_was_set();
+
+ return 0;
+}
+EXPORT_SYMBOL(do_settimeofday);
+#endif /* !CONFIG_GENERIC_TIME */
+
+/*
+ * Scheduler clock - returns current time in nanosec units.
+ */
+unsigned long long sched_clock(void)
+{
+ return (unsigned long long)jiffies *(NSEC_PER_SEC / HZ);
+}
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
new file mode 100644
index 0000000..9556b73
--- /dev/null
+++ b/arch/blackfin/kernel/traps.c
@@ -0,0 +1,649 @@
+/*
+ * File: arch/blackfin/kernel/traps.c
+ * Based on:
+ * Author: Hamish Macdonald
+ *
+ * Created:
+ * Description: uses S/W interrupt 15 for the system calls
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <asm/uaccess.h>
+#include <asm/traps.h>
+#include <asm/cacheflush.h>
+#include <asm/blackfin.h>
+#include <asm/uaccess.h>
+#include <asm/irq_handler.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+
+#ifdef CONFIG_KGDB
+# include <linux/debugger.h>
+# include <linux/kgdb.h>
+#endif
+
+/* Initiate the event table handler */
+void __init trap_init(void)
+{
+ CSYNC();
+ bfin_write_EVT3(trap);
+ CSYNC();
+}
+
+asmlinkage void trap_c(struct pt_regs *fp);
+
+int kstack_depth_to_print = 48;
+
+static int printk_address(unsigned long address)
+{
+ struct vm_list_struct *vml;
+ struct task_struct *p;
+ struct mm_struct *mm;
+
+#ifdef CONFIG_KALLSYMS
+ unsigned long offset = 0, symsize;
+ const char *symname;
+ char *modname;
+ char *delim = ":";
+ char namebuf[128];
+
+ /* look up the address and see if we are in kernel space */
+ symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf);
+
+ if (symname) {
+ /* yeah! kernel space! */
+ if (!modname)
+ modname = delim = "";
+ return printk("<0x%p> { %s%s%s%s + 0x%lx }",
+ (void*)address, delim, modname, delim, symname,
+ (unsigned long)offset);
+
+ }
+#endif
+
+ /* looks like we're off in user-land, so let's walk all the
+ * mappings of all our processes and see if we can't be a whee
+ * bit more specific
+ */
+ write_lock_irq(&tasklist_lock);
+ for_each_process(p) {
+ mm = get_task_mm(p);
+ if (!mm)
+ continue;
+
+ vml = mm->context.vmlist;
+ while (vml) {
+ struct vm_area_struct *vma = vml->vma;
+
+ if (address >= vma->vm_start && address < vma->vm_end) {
+ char *name = p->comm;
+ struct file *file = vma->vm_file;
+ if (file) {
+ char _tmpbuf[256];
+ name = d_path(file->f_dentry,
+ file->f_vfsmnt,
+ _tmpbuf,
+ sizeof(_tmpbuf));
+ }
+
+ write_unlock_irq(&tasklist_lock);
+ return printk("<0x%p> [ %s + 0x%lx ]",
+ (void*)address, name,
+ (unsigned long)
+ ((address - vma->vm_start) +
+ (vma->vm_pgoff << PAGE_SHIFT)));
+ }
+
+ vml = vml->next;
+ }
+ }
+ write_unlock_irq(&tasklist_lock);
+
+ /* we were unable to find this address anywhere */
+ return printk("[<0x%p>]", (void*)address);
+}
+
+#define trace_buffer_save(x) \
+ do { \
+ (x) = bfin_read_TBUFCTL(); \
+ bfin_write_TBUFCTL((x) & ~TBUFEN); \
+ } while (0)
+#define trace_buffer_restore(x) \
+ do { \
+ bfin_write_TBUFCTL((x)); \
+ } while (0)
+
+asmlinkage void trap_c(struct pt_regs *fp)
+{
+ int j, sig = 0;
+ siginfo_t info;
+ unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE;
+
+#ifdef CONFIG_KGDB
+# define CHK_DEBUGGER_TRAP() do { CHK_DEBUGGER(trapnr, sig, info.si_code, fp,); } while (0)
+# define CHK_DEBUGGER_TRAP_MAYBE() do { if (kgdb_connected) CHK_DEBUGGER_TRAP(); } while (0)
+#else
+# define CHK_DEBUGGER_TRAP() do { } while (0)
+# define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0)
+#endif
+
+ trace_buffer_save(j);
+
+ /* trap_c() will be called for exceptions. During exceptions
+ * processing, the pc value should be set with retx value.
+ * With this change we can cleanup some code in signal.c- TODO
+ */
+ fp->orig_pc = fp->retx;
+ /* printk("exception: 0x%x, ipend=%x, reti=%x, retx=%x\n",
+ trapnr, fp->ipend, fp->pc, fp->retx); */
+
+ /* send the appropriate signal to the user program */
+ switch (trapnr) {
+
+ /* This table works in conjuction with the one in ./mach-common/entry.S
+ * Some exceptions are handled there (in assembly, in exception space)
+ * Some are handled here, (in C, in interrupt space)
+ * Some, like CPLB, are handled in both, where the normal path is
+ * handled in assembly/exception space, and the error path is handled
+ * here
+ */
+
+ /* 0x00 - Linux Syscall, getting here is an error */
+ /* 0x01 - userspace gdb breakpoint, handled here */
+ case VEC_EXCPT01:
+ info.si_code = TRAP_ILLTRAP;
+ sig = SIGTRAP;
+ CHK_DEBUGGER_TRAP_MAYBE();
+ /* Check if this is a breakpoint in kernel space */
+ if (fp->ipend & 0xffc0)
+ return;
+ else
+ break;
+#ifdef CONFIG_KGDB
+ case VEC_EXCPT02 : /* gdb connection */
+ info.si_code = TRAP_ILLTRAP;
+ sig = SIGTRAP;
+ CHK_DEBUGGER_TRAP();
+ return;
+#else
+ /* 0x02 - User Defined, Caught by default */
+#endif
+ /* 0x03 - Atomic test and set */
+ case VEC_EXCPT03:
+ info.si_code = SEGV_STACKFLOW;
+ sig = SIGSEGV;
+ printk(KERN_EMERG EXC_0x03);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x04 - spinlock - handled by _ex_spinlock,
+ getting here is an error */
+ /* 0x05 - User Defined, Caught by default */
+ /* 0x06 - User Defined, Caught by default */
+ /* 0x07 - User Defined, Caught by default */
+ /* 0x08 - User Defined, Caught by default */
+ /* 0x09 - User Defined, Caught by default */
+ /* 0x0A - User Defined, Caught by default */
+ /* 0x0B - User Defined, Caught by default */
+ /* 0x0C - User Defined, Caught by default */
+ /* 0x0D - User Defined, Caught by default */
+ /* 0x0E - User Defined, Caught by default */
+ /* 0x0F - User Defined, Caught by default */
+ /* 0x10 HW Single step, handled here */
+ case VEC_STEP:
+ info.si_code = TRAP_STEP;
+ sig = SIGTRAP;
+ CHK_DEBUGGER_TRAP_MAYBE();
+ /* Check if this is a single step in kernel space */
+ if (fp->ipend & 0xffc0)
+ return;
+ else
+ break;
+ /* 0x11 - Trace Buffer Full, handled here */
+ case VEC_OVFLOW:
+ info.si_code = TRAP_TRACEFLOW;
+ sig = SIGTRAP;
+ printk(KERN_EMERG EXC_0x11);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x12 - Reserved, Caught by default */
+ /* 0x13 - Reserved, Caught by default */
+ /* 0x14 - Reserved, Caught by default */
+ /* 0x15 - Reserved, Caught by default */
+ /* 0x16 - Reserved, Caught by default */
+ /* 0x17 - Reserved, Caught by default */
+ /* 0x18 - Reserved, Caught by default */
+ /* 0x19 - Reserved, Caught by default */
+ /* 0x1A - Reserved, Caught by default */
+ /* 0x1B - Reserved, Caught by default */
+ /* 0x1C - Reserved, Caught by default */
+ /* 0x1D - Reserved, Caught by default */
+ /* 0x1E - Reserved, Caught by default */
+ /* 0x1F - Reserved, Caught by default */
+ /* 0x20 - Reserved, Caught by default */
+ /* 0x21 - Undefined Instruction, handled here */
+ case VEC_UNDEF_I:
+ info.si_code = ILL_ILLOPC;
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x21);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x22 - Illegal Instruction Combination, handled here */
+ case VEC_ILGAL_I:
+ info.si_code = ILL_ILLPARAOP;
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x22);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x23 - Data CPLB Protection Violation,
+ normal case is handled in _cplb_hdr */
+ case VEC_CPLB_VL:
+ info.si_code = ILL_CPLB_VI;
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x23);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x24 - Data access misaligned, handled here */
+ case VEC_MISALI_D:
+ info.si_code = BUS_ADRALN;
+ sig = SIGBUS;
+ printk(KERN_EMERG EXC_0x24);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x25 - Unrecoverable Event, handled here */
+ case VEC_UNCOV:
+ info.si_code = ILL_ILLEXCPT;
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x25);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr,
+ error case is handled here */
+ case VEC_CPLB_M:
+ info.si_code = BUS_ADRALN;
+ sig = SIGBUS;
+ printk(KERN_EMERG EXC_0x26);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */
+ case VEC_CPLB_MHIT:
+ info.si_code = ILL_CPLB_MULHIT;
+#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
+ sig = SIGSEGV;
+ printk(KERN_EMERG "\n\nNULL pointer access (probably)\n");
+#else
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x27);
+#endif
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x28 - Emulation Watchpoint, handled here */
+ case VEC_WATCH:
+ info.si_code = TRAP_WATCHPT;
+ sig = SIGTRAP;
+ pr_debug(EXC_0x28);
+ CHK_DEBUGGER_TRAP_MAYBE();
+ /* Check if this is a watchpoint in kernel space */
+ if (fp->ipend & 0xffc0)
+ return;
+ else
+ break;
+#ifdef CONFIG_BF535
+ /* 0x29 - Instruction fetch access error (535 only) */
+ case VEC_ISTRU_VL: /* ADSP-BF535 only (MH) */
+ info.si_code = BUS_OPFETCH;
+ sig = SIGBUS;
+ printk(KERN_EMERG "BF535: VEC_ISTRU_VL\n");
+ CHK_DEBUGGER_TRAP();
+ break;
+#else
+ /* 0x29 - Reserved, Caught by default */
+#endif
+ /* 0x2A - Instruction fetch misaligned, handled here */
+ case VEC_MISALI_I:
+ info.si_code = BUS_ADRALN;
+ sig = SIGBUS;
+ printk(KERN_EMERG EXC_0x2A);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x2B - Instruction CPLB protection Violation,
+ handled in _cplb_hdr */
+ case VEC_CPLB_I_VL:
+ info.si_code = ILL_CPLB_VI;
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x2B);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */
+ case VEC_CPLB_I_M:
+ info.si_code = ILL_CPLB_MISS;
+ sig = SIGBUS;
+ printk(KERN_EMERG EXC_0x2C);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x2D - Instruction CPLB Multiple Hits, handled here */
+ case VEC_CPLB_I_MHIT:
+ info.si_code = ILL_CPLB_MULHIT;
+#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
+ sig = SIGSEGV;
+ printk(KERN_EMERG "\n\nJump to address 0 - 0x0fff\n");
+#else
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x2D);
+#endif
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x2E - Illegal use of Supervisor Resource, handled here */
+ case VEC_ILL_RES:
+ info.si_code = ILL_PRVOPC;
+ sig = SIGILL;
+ printk(KERN_EMERG EXC_0x2E);
+ CHK_DEBUGGER_TRAP();
+ break;
+ /* 0x2F - Reserved, Caught by default */
+ /* 0x30 - Reserved, Caught by default */
+ /* 0x31 - Reserved, Caught by default */
+ /* 0x32 - Reserved, Caught by default */
+ /* 0x33 - Reserved, Caught by default */
+ /* 0x34 - Reserved, Caught by default */
+ /* 0x35 - Reserved, Caught by default */
+ /* 0x36 - Reserved, Caught by default */
+ /* 0x37 - Reserved, Caught by default */
+ /* 0x38 - Reserved, Caught by default */
+ /* 0x39 - Reserved, Caught by default */
+ /* 0x3A - Reserved, Caught by default */
+ /* 0x3B - Reserved, Caught by default */
+ /* 0x3C - Reserved, Caught by default */
+ /* 0x3D - Reserved, Caught by default */
+ /* 0x3E - Reserved, Caught by default */
+ /* 0x3F - Reserved, Caught by default */
+ default:
+ info.si_code = TRAP_ILLTRAP;
+ sig = SIGTRAP;
+ printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n",
+ (fp->seqstat & SEQSTAT_EXCAUSE));
+ CHK_DEBUGGER_TRAP();
+ break;
+ }
+
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_addr = (void *)fp->pc;
+ force_sig_info(sig, &info, current);
+ if (sig != 0 && sig != SIGTRAP) {
+ unsigned long stack;
+ dump_bfin_regs(fp, (void *)fp->retx);
+ dump_bfin_trace_buffer();
+ show_stack(current, &stack);
+ if (current->mm == NULL)
+ panic("Kernel exception");
+ }
+
+ /* if the address that we are about to return to is not valid, set it
+ * to a valid address, if we have a current application or panic
+ */
+ if (!(fp->pc <= physical_mem_end
+#if L1_CODE_LENGTH != 0
+ || (fp->pc >= L1_CODE_START &&
+ fp->pc <= (L1_CODE_START + L1_CODE_LENGTH))
+#endif
+ )) {
+ if (current->mm) {
+ fp->pc = current->mm->start_code;
+ } else {
+ printk(KERN_EMERG "I can't return to memory that doesn't exist - bad things happen\n");
+ panic("Help - I've fallen and can't get up\n");
+ }
+ }
+
+ trace_buffer_restore(j);
+ return;
+}
+
+/* Typical exception handling routines */
+
+void dump_bfin_trace_buffer(void)
+{
+ int tflags;
+ trace_buffer_save(tflags);
+
+ if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) {
+ int i;
+ printk(KERN_EMERG "Hardware Trace:\n");
+ for (i = 0; bfin_read_TBUFSTAT() & TBUFCNT; i++) {
+ printk(KERN_EMERG "%2i Target : ", i);
+ printk_address((unsigned long)bfin_read_TBUF());
+ printk("\n" KERN_EMERG " Source : ");
+ printk_address((unsigned long)bfin_read_TBUF());
+ printk("\n");
+ }
+ }
+
+ trace_buffer_restore(tflags);
+}
+EXPORT_SYMBOL(dump_bfin_trace_buffer);
+
+static void show_trace(struct task_struct *tsk, unsigned long *sp)
+{
+ unsigned long addr;
+
+ printk("\nCall Trace:");
+#ifdef CONFIG_KALLSYMS
+ printk("\n");
+#endif
+
+ while (!kstack_end(sp)) {
+ addr = *sp++;
+ /*
+ * If the address is either in the text segment of the
+ * kernel, or in the region which contains vmalloc'ed
+ * memory, it *may* be the address of a calling
+ * routine; if so, print it so that someone tracing
+ * down the cause of the crash will be able to figure
+ * out the call path that was taken.
+ */
+ if (kernel_text_address(addr))
+ print_ip_sym(addr);
+ }
+
+ printk("\n");
+}
+
+void show_stack(struct task_struct *task, unsigned long *stack)
+{
+ unsigned long *endstack, addr;
+ int i;
+
+ /* Cannot call dump_bfin_trace_buffer() here as show_stack() is
+ * called externally in some places in the kernel.
+ */
+
+ if (!stack) {
+ if (task)
+ stack = (unsigned long *)task->thread.ksp;
+ else
+ stack = (unsigned long *)&stack;
+ }
+
+ addr = (unsigned long)stack;
+ endstack = (unsigned long *)PAGE_ALIGN(addr);
+
+ printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack);
+ for (i = 0; i < kstack_depth_to_print; i++) {
+ if (stack + 1 > endstack)
+ break;
+ if (i % 8 == 0)
+ printk("\n" KERN_EMERG " ");
+ printk(" %08lx", *stack++);
+ }
+
+ show_trace(task, stack);
+}
+
+void dump_stack(void)
+{
+ unsigned long stack;
+ int tflags;
+ trace_buffer_save(tflags);
+ dump_bfin_trace_buffer();
+ show_stack(current, &stack);
+ trace_buffer_restore(tflags);
+}
+
+EXPORT_SYMBOL(dump_stack);
+
+void dump_bfin_regs(struct pt_regs *fp, void *retaddr)
+{
+ if (current->pid) {
+ printk("\nCURRENT PROCESS:\n\n");
+ printk("COMM=%s PID=%d\n", current->comm, current->pid);
+ } else {
+ printk
+ ("\nNo Valid pid - Either things are really messed up, or you are in the kernel\n");
+ }
+
+ if (current->mm) {
+ printk("TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n"
+ "BSS = 0x%p-0x%p USER-STACK = 0x%p\n\n",
+ (void*)current->mm->start_code,
+ (void*)current->mm->end_code,
+ (void*)current->mm->start_data,
+ (void*)current->mm->end_data,
+ (void*)current->mm->end_data,
+ (void*)current->mm->brk,
+ (void*)current->mm->start_stack);
+ }
+
+ printk("return address: 0x%p; contents of [PC-16...PC+8]:\n", retaddr);
+ if (retaddr != 0 && retaddr <= (void*)physical_mem_end
+#if L1_CODE_LENGTH != 0
+ /* FIXME: Copy the code out of L1 Instruction SRAM through dma
+ memcpy. */
+ && !(retaddr >= (void*)L1_CODE_START
+ && retaddr < (void*)(L1_CODE_START + L1_CODE_LENGTH))
+#endif
+ ) {
+ int i = 0;
+ unsigned short x = 0;
+ for (i = -16; i < 8; i++) {
+ if (get_user(x, (unsigned short *)retaddr + i))
+ break;
+#ifndef CONFIG_DEBUG_HWERR
+ /* If one of the last few instructions was a STI
+ * it is likily that the error occured awhile ago
+ * and we just noticed
+ */
+ if (x >= 0x0040 && x <= 0x0047 && i <= 0)
+ panic("\n\nWARNING : You should reconfigure the kernel to turn on\n"
+ " 'Hardware error interrupt debugging'\n"
+ " The rest of this error is meanless\n");
+#endif
+
+ if (i == -8)
+ printk("\n");
+ if (i == 0)
+ printk("X\n");
+ printk("%04x ", x);
+ }
+ } else
+ printk("Cannot look at the [PC] for it is in unreadable L1 SRAM - sorry\n");
+
+ printk("\n\n");
+
+ printk("RETE: %08lx RETN: %08lx RETX: %08lx RETS: %08lx\n",
+ fp->rete, fp->retn, fp->retx, fp->rets);
+ printk("IPEND: %04lx SYSCFG: %04lx\n", fp->ipend, fp->syscfg);
+ printk("SEQSTAT: %08lx SP: %08lx\n", (long)fp->seqstat, (long)fp);
+ printk("R0: %08lx R1: %08lx R2: %08lx R3: %08lx\n",
+ fp->r0, fp->r1, fp->r2, fp->r3);
+ printk("R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n",
+ fp->r4, fp->r5, fp->r6, fp->r7);
+ printk("P0: %08lx P1: %08lx P2: %08lx P3: %08lx\n",
+ fp->p0, fp->p1, fp->p2, fp->p3);
+ printk("P4: %08lx P5: %08lx FP: %08lx\n", fp->p4, fp->p5, fp->fp);
+ printk("A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n",
+ fp->a0w, fp->a0x, fp->a1w, fp->a1x);
+
+ printk("LB0: %08lx LT0: %08lx LC0: %08lx\n", fp->lb0, fp->lt0,
+ fp->lc0);
+ printk("LB1: %08lx LT1: %08lx LC1: %08lx\n", fp->lb1, fp->lt1,
+ fp->lc1);
+ printk("B0: %08lx L0: %08lx M0: %08lx I0: %08lx\n", fp->b0, fp->l0,
+ fp->m0, fp->i0);
+ printk("B1: %08lx L1: %08lx M1: %08lx I1: %08lx\n", fp->b1, fp->l1,
+ fp->m1, fp->i1);
+ printk("B2: %08lx L2: %08lx M2: %08lx I2: %08lx\n", fp->b2, fp->l2,
+ fp->m2, fp->i2);
+ printk("B3: %08lx L3: %08lx M3: %08lx I3: %08lx\n", fp->b3, fp->l3,
+ fp->m3, fp->i3);
+
+ printk("\nUSP: %08lx ASTAT: %08lx\n", rdusp(), fp->astat);
+ if ((long)fp->seqstat & SEQSTAT_EXCAUSE) {
+ printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void*)bfin_read_DCPLB_FAULT_ADDR());
+ printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void*)bfin_read_ICPLB_FAULT_ADDR());
+ }
+
+ printk("\n\n");
+}
+
+#ifdef CONFIG_SYS_BFIN_SPINLOCK_L1
+asmlinkage int sys_bfin_spinlock(int *spinlock)__attribute__((l1_text));
+#endif
+
+asmlinkage int sys_bfin_spinlock(int *spinlock)
+{
+ int ret = 0;
+ int tmp = 0;
+
+ local_irq_disable();
+ ret = get_user(tmp, spinlock);
+ if (ret == 0) {
+ if (tmp)
+ ret = 1;
+ tmp = 1;
+ put_user(tmp, spinlock);
+ }
+ local_irq_enable();
+ return ret;
+}
+
+void panic_cplb_error(int cplb_panic, struct pt_regs *fp)
+{
+ switch (cplb_panic) {
+ case CPLB_NO_UNLOCKED:
+ printk(KERN_EMERG "All CPLBs are locked\n");
+ break;
+ case CPLB_PROT_VIOL:
+ return;
+ case CPLB_NO_ADDR_MATCH:
+ return;
+ case CPLB_UNKNOWN_ERR:
+ printk(KERN_EMERG "Unknown CPLB Exception\n");
+ break;
+ }
+
+ printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void*)bfin_read_DCPLB_FAULT_ADDR());
+ printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void*)bfin_read_ICPLB_FAULT_ADDR());
+ dump_bfin_regs(fp, (void *)fp->retx);
+ dump_stack();
+ panic("Unrecoverable event\n");
+}
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
new file mode 100644
index 0000000..6ae9ebb
--- /dev/null
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -0,0 +1,228 @@
+/*
+ * File: arch/blackfin/kernel/vmlinux.lds.S
+ * Based on: none - original work
+ * Author:
+ *
+ * Created: Tue Sep 21 2004
+ * Description: Master linker script for blackfin architecture
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define VMLINUX_SYMBOL(_sym_) _##_sym_
+
+#include <asm-generic/vmlinux.lds.h>
+#include <asm/mem_map.h>
+
+
+OUTPUT_FORMAT("elf32-bfin")
+ENTRY(__start)
+_jiffies = _jiffies_64;
+
+MEMORY
+{
+ ram : ORIGIN = CONFIG_BOOT_LOAD, LENGTH = (CONFIG_MEM_SIZE * 1024 * 1024) - (CONFIG_BOOT_LOAD)
+ l1_data_a : ORIGIN = L1_DATA_A_START, LENGTH = L1_DATA_A_LENGTH
+ l1_data_b : ORIGIN = L1_DATA_B_START, LENGTH = L1_DATA_B_LENGTH
+ l1_code : ORIGIN = L1_CODE_START, LENGTH = L1_CODE_LENGTH
+ l1_scratch : ORIGIN = L1_SCRATCH_START, LENGTH = L1_SCRATCH_LENGTH
+}
+
+SECTIONS
+{
+ . = CONFIG_BOOT_LOAD;
+
+ .text :
+ {
+ _text = .;
+ __stext = .;
+ *(.text)
+ SCHED_TEXT
+ *(.text.lock)
+ . = ALIGN(16);
+ ___start___ex_table = .;
+ *(__ex_table)
+ ___stop___ex_table = .;
+
+ *($code)
+ *(.rodata)
+ *(.rodata.*)
+ *(__vermagic) /* Kernel version magic */
+ *(.rodata1)
+ *(.fixup)
+ *(.spinlock.text)
+
+ /* Kernel symbol table: Normal symbols */
+ . = ALIGN(4);
+ ___start___ksymtab = .;
+ *(__ksymtab)
+ ___stop___ksymtab = .;
+
+ /* Kernel symbol table: GPL-only symbols */
+ ___start___ksymtab_gpl = .;
+ *(__ksymtab_gpl)
+ ___stop___ksymtab_gpl = .;
+
+ /* Kernel symbol table: Normal unused symbols */ \
+ ___start___ksymtab_unused = .;
+ *(__ksymtab_unused)
+ ___stop___ksymtab_unused = .;
+
+ /* Kernel symbol table: GPL-only unused symbols */
+ ___start___ksymtab_unused_gpl = .;
+ *(__ksymtab_unused_gpl)
+ ___stop___ksymtab_unused_gpl = .;
+
+
+ /* Kernel symbol table: GPL-future symbols */
+ ___start___ksymtab_gpl_future = .;
+ *(__ksymtab_gpl_future)
+ ___stop___ksymtab_gpl_future = .;
+
+ /* Kernel symbol table: Normal symbols */
+ ___start___kcrctab = .;
+ *(__kcrctab)
+ ___stop___kcrctab = .;
+
+ /* Kernel symbol table: GPL-only symbols */
+ ___start___kcrctab_gpl = .;
+ *(__kcrctab_gpl)
+ ___stop___kcrctab_gpl = .;
+
+ /* Kernel symbol table: GPL-future symbols */
+ ___start___kcrctab_gpl_future = .;
+ *(__kcrctab_gpl_future)
+ ___stop___kcrctab_gpl_future = .;
+
+ /* Kernel symbol table: strings */
+ *(__ksymtab_strings)
+
+ . = ALIGN(4);
+ __etext = .;
+ } > ram
+
+ .init :
+ {
+ . = ALIGN(4096);
+ ___init_begin = .;
+ __sinittext = .;
+ *(.init.text)
+ __einittext = .;
+ *(.init.data)
+ . = ALIGN(16);
+ ___setup_start = .;
+ *(.init.setup)
+ ___setup_end = .;
+ ___start___param = .;
+ *(__param)
+ ___stop___param = .;
+ ___initcall_start = .;
+ INITCALLS
+ ___initcall_end = .;
+ ___con_initcall_start = .;
+ *(.con_initcall.init)
+ ___con_initcall_end = .;
+ ___security_initcall_start = .;
+ *(.security_initcall.init)
+ ___security_initcall_end = .;
+ . = ALIGN(4);
+ ___initramfs_start = .;
+ *(.init.ramfs)
+ ___initramfs_end = .;
+ . = ALIGN(4);
+ ___init_end = .;
+ } > ram
+
+ __l1_lma_start = .;
+
+ .text_l1 :
+ {
+ . = ALIGN(4);
+ __stext_l1 = .;
+ *(.l1.text)
+
+ . = ALIGN(4);
+ __etext_l1 = .;
+ } > l1_code AT > ram
+
+ .data_l1 :
+ {
+ . = ALIGN(4);
+ __sdata_l1 = .;
+ *(.l1.data)
+ __edata_l1 = .;
+
+ . = ALIGN(4);
+ __sbss_l1 = .;
+ *(.l1.bss)
+
+ . = ALIGN(32);
+ *(.data_l1.cacheline_aligned)
+
+ . = ALIGN(4);
+ __ebss_l1 = .;
+ } > l1_data_a AT > ram
+ .data_b_l1 :
+ {
+ . = ALIGN(4);
+ __sdata_b_l1 = .;
+ *(.l1.data.B)
+ __edata_b_l1 = .;
+
+ . = ALIGN(4);
+ __sbss_b_l1 = .;
+ *(.l1.bss.B)
+
+ . = ALIGN(4);
+ __ebss_b_l1 = .;
+ } > l1_data_b AT > ram
+
+ .data :
+ {
+ __sdata = .;
+ . = ALIGN(0x2000);
+ *(.data.init_task)
+ *(.data)
+
+ . = ALIGN(32);
+ *(.data.cacheline_aligned)
+
+ . = ALIGN(0x2000);
+ __edata = .;
+ } > ram
+
+ /DISCARD/ : { /* Exit code and data*/
+ *(.exit.text)
+ *(.exit.data)
+ *(.exitcall.exit)
+ } > ram
+
+ .bss :
+ {
+ . = ALIGN(4);
+ ___bss_start = .;
+ *(.bss)
+ *(COMMON)
+ . = ALIGN(4);
+ ___bss_stop = .;
+ __end = . ;
+ } > ram
+}
diff --git a/arch/blackfin/lib/Makefile b/arch/blackfin/lib/Makefile
new file mode 100644
index 0000000..635288f
--- /dev/null
+++ b/arch/blackfin/lib/Makefile
@@ -0,0 +1,11 @@
+#
+# arch/blackfin/lib/Makefile
+#
+
+lib-y := \
+ ashldi3.o ashrdi3.o lshrdi3.o \
+ muldi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \
+ checksum.o memcpy.o memset.o memcmp.o memchr.o memmove.o \
+ strcmp.o strcpy.o strncmp.o strncpy.o \
+ umulsi3_highpart.o smulsi3_highpart.o \
+ ins.o outs.o
diff --git a/arch/blackfin/lib/ashldi3.c b/arch/blackfin/lib/ashldi3.c
new file mode 100644
index 0000000..a8c279e
--- /dev/null
+++ b/arch/blackfin/lib/ashldi3.c
@@ -0,0 +1,58 @@
+/*
+ * File: arch/blackfin/lib/ashldi3.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "gcclib.h"
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+DItype __ashldi3(DItype u, word_type b)__attribute__((l1_text));
+#endif
+
+DItype __ashldi3(DItype u, word_type b)
+{
+ DIunion w;
+ word_type bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof(SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0) {
+ w.s.low = 0;
+ w.s.high = (USItype) uu.s.low << -bm;
+ } else {
+ USItype carries = (USItype) uu.s.low >> bm;
+ w.s.low = (USItype) uu.s.low << b;
+ w.s.high = ((USItype) uu.s.high << b) | carries;
+ }
+
+ return w.ll;
+}
diff --git a/arch/blackfin/lib/ashrdi3.c b/arch/blackfin/lib/ashrdi3.c
new file mode 100644
index 0000000..a0d3419
--- /dev/null
+++ b/arch/blackfin/lib/ashrdi3.c
@@ -0,0 +1,59 @@
+/*
+ * File: arch/blackfin/lib/ashrdi3.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "gcclib.h"
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+DItype __ashrdi3(DItype u, word_type b)__attribute__((l1_text));
+#endif
+
+DItype __ashrdi3(DItype u, word_type b)
+{
+ DIunion w;
+ word_type bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof(SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0) {
+ /* w.s.high = 1..1 or 0..0 */
+ w.s.high = uu.s.high >> (sizeof(SItype) * BITS_PER_UNIT - 1);
+ w.s.low = uu.s.high >> -bm;
+ } else {
+ USItype carries = (USItype) uu.s.high << bm;
+ w.s.high = uu.s.high >> b;
+ w.s.low = ((USItype) uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
diff --git a/arch/blackfin/lib/checksum.c b/arch/blackfin/lib/checksum.c
new file mode 100644
index 0000000..42768e0
--- /dev/null
+++ b/arch/blackfin/lib/checksum.c
@@ -0,0 +1,140 @@
+/*
+ * File: arch/blackfin/lib/checksum.c
+ * Based on: none - original work
+ * Author:
+ *
+ * Created:
+ * Description: An implementation of the TCP/IP protocol suite for the LINUX
+ * operating system. INET is implemented using the BSD Socket
+ * interface as the means of communication with the user level.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <net/checksum.h>
+#include <asm/checksum.h>
+
+#ifdef CONFIG_IP_CHECKSUM_L1
+static unsigned short do_csum(const unsigned char *buff, int len)__attribute__((l1_text));
+#endif
+
+static unsigned short do_csum(const unsigned char *buff, int len)
+{
+ register unsigned long sum = 0;
+ int swappem = 0;
+
+ if (1 & (unsigned long)buff) {
+ sum = *buff << 8;
+ buff++;
+ len--;
+ ++swappem;
+ }
+
+ while (len > 1) {
+ sum += *(unsigned short *)buff;
+ buff += 2;
+ len -= 2;
+ }
+
+ if (len > 0)
+ sum += *buff;
+
+ /* Fold 32-bit sum to 16 bits */
+ while (sum >> 16)
+ sum = (sum & 0xffff) + (sum >> 16);
+
+ if (swappem)
+ sum = ((sum & 0xff00) >> 8) + ((sum & 0x00ff) << 8);
+
+ return sum;
+
+}
+
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.
+ */
+unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl)
+{
+ return ~do_csum(iph, ihl * 4);
+}
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum)
+{
+ /*
+ * Just in case we get nasty checksum data...
+ * Like 0xffff6ec3 in the case of our IPv6 multicast header.
+ * We fold to begin with, as well as at the end.
+ */
+ sum = (sum & 0xffff) + (sum >> 16);
+
+ sum += do_csum(buff, len);
+
+ sum = (sum & 0xffff) + (sum >> 16);
+
+ return sum;
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+unsigned short ip_compute_csum(const unsigned char *buff, int len)
+{
+ return ~do_csum(buff, len);
+}
+
+/*
+ * copy from fs while checksumming, otherwise like csum_partial
+ */
+
+unsigned int
+csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
+ int len, int sum, int *csum_err)
+{
+ if (csum_err)
+ *csum_err = 0;
+ memcpy(dst, src, len);
+ return csum_partial(dst, len, sum);
+}
+
+/*
+ * copy from ds while checksumming, otherwise like csum_partial
+ */
+
+unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst,
+ int len, int sum)
+{
+ memcpy(dst, src, len);
+ return csum_partial(dst, len, sum);
+}
diff --git a/arch/blackfin/lib/divsi3.S b/arch/blackfin/lib/divsi3.S
new file mode 100644
index 0000000..3e29861
--- /dev/null
+++ b/arch/blackfin/lib/divsi3.S
@@ -0,0 +1,216 @@
+/*
+ * File: arch/blackfin/lib/divsi3.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: 16 / 32 bit signed division.
+ * Special cases :
+ * 1) If(numerator == 0)
+ * return 0
+ * 2) If(denominator ==0)
+ * return positive max = 0x7fffffff
+ * 3) If(numerator == denominator)
+ * return 1
+ * 4) If(denominator ==1)
+ * return numerator
+ * 5) If(denominator == -1)
+ * return -numerator
+ *
+ * Operand : R0 - Numerator (i)
+ * R1 - Denominator (i)
+ * R0 - Quotient (o)
+ * Registers Used : R2-R7,P0-P2
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+.global ___divsi3;
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+.align 2;
+___divsi3 :
+
+
+ R3 = R0 ^ R1;
+ R0 = ABS R0;
+
+ CC = V;
+
+ r3 = rot r3 by -1;
+ r1 = abs r1; /* now both positive, r3.30 means "negate result",
+ ** r3.31 means overflow, add one to result
+ */
+ cc = r0 < r1;
+ if cc jump .Lret_zero;
+ r2 = r1 >> 15;
+ cc = r2;
+ if cc jump .Lidents;
+ r2 = r1 << 16;
+ cc = r2 <= r0;
+ if cc jump .Lidents;
+
+ DIVS(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+ DIVQ(R0, R1);
+
+ R0 = R0.L (Z);
+ r1 = r3 >> 31; /* add overflow issue back in */
+ r0 = r0 + r1;
+ r1 = -r0;
+ cc = bittst(r3, 30);
+ if cc r0 = r1;
+ RTS;
+
+/* Can't use the primitives. Test common identities.
+** If the identity is true, return the value in R2.
+*/
+
+.Lidents:
+ CC = R1 == 0; /* check for divide by zero */
+ IF CC JUMP .Lident_return;
+
+ CC = R0 == 0; /* check for division of zero */
+ IF CC JUMP .Lzero_return;
+
+ CC = R0 == R1; /* check for identical operands */
+ IF CC JUMP .Lident_return;
+
+ CC = R1 == 1; /* check for divide by 1 */
+ IF CC JUMP .Lident_return;
+
+ R2.L = ONES R1;
+ R2 = R2.L (Z);
+ CC = R2 == 1;
+ IF CC JUMP .Lpower_of_two;
+
+ /* Identities haven't helped either.
+ ** Perform the full division process.
+ */
+
+ P1 = 31; /* Set loop counter */
+
+ [--SP] = (R7:5); /* Push registers R5-R7 */
+ R2 = -R1;
+ [--SP] = R2;
+ R2 = R0 << 1; /* R2 lsw of dividend */
+ R6 = R0 ^ R1; /* Get sign */
+ R5 = R6 >> 31; /* Shift sign to LSB */
+
+ R0 = 0 ; /* Clear msw partial remainder */
+ R2 = R2 | R5; /* Shift quotient bit */
+ R6 = R0 ^ R1; /* Get new quotient bit */
+
+ LSETUP(.Llst,.Llend) LC0 = P1; /* Setup loop */
+.Llst: R7 = R2 >> 31; /* record copy of carry from R2 */
+ R2 = R2 << 1; /* Shift 64 bit dividend up by 1 bit */
+ R0 = R0 << 1 || R5 = [SP];
+ R0 = R0 | R7; /* and add carry */
+ CC = R6 < 0; /* Check quotient(AQ) */
+ /* we might be subtracting divisor (AQ==0) */
+ IF CC R5 = R1; /* or we might be adding divisor (AQ==1)*/
+ R0 = R0 + R5; /* do add or subtract, as indicated by AQ */
+ R6 = R0 ^ R1; /* Generate next quotient bit */
+ R5 = R6 >> 31;
+ /* Assume AQ==1, shift in zero */
+ BITTGL(R5,0); /* tweak AQ to be what we want to shift in */
+.Llend: R2 = R2 + R5; /* and then set shifted-in value to
+ ** tweaked AQ.
+ */
+ r1 = r3 >> 31;
+ r2 = r2 + r1;
+ cc = bittst(r3,30);
+ r0 = -r2;
+ if !cc r0 = r2;
+ SP += 4;
+ (R7:5)= [SP++]; /* Pop registers R6-R7 */
+ RTS;
+
+.Lident_return:
+ CC = R1 == 0; /* check for divide by zero => 0x7fffffff */
+ R2 = -1 (X);
+ R2 >>= 1;
+ IF CC JUMP .Ltrue_ident_return;
+
+ CC = R0 == R1; /* check for identical operands => 1 */
+ R2 = 1 (Z);
+ IF CC JUMP .Ltrue_ident_return;
+
+ R2 = R0; /* assume divide by 1 => numerator */
+ /*FALLTHRU*/
+
+.Ltrue_ident_return:
+ R0 = R2; /* Return an identity value */
+ R2 = -R2;
+ CC = bittst(R3,30);
+ IF CC R0 = R2;
+.Lzero_return:
+ RTS; /* ...including zero */
+
+.Lpower_of_two:
+ /* Y has a single bit set, which means it's a power of two.
+ ** That means we can perform the division just by shifting
+ ** X to the right the appropriate number of bits
+ */
+
+ /* signbits returns the number of sign bits, minus one.
+ ** 1=>30, 2=>29, ..., 0x40000000=>0. Which means we need
+ ** to shift right n-signbits spaces. It also means 0x80000000
+ ** is a special case, because that *also* gives a signbits of 0
+ */
+
+ R2 = R0 >> 31;
+ CC = R1 < 0;
+ IF CC JUMP .Ltrue_ident_return;
+
+ R1.l = SIGNBITS R1;
+ R1 = R1.L (Z);
+ R1 += -30;
+ R0 = LSHIFT R0 by R1.L;
+ r1 = r3 >> 31;
+ r0 = r0 + r1;
+ R2 = -R0; // negate result if necessary
+ CC = bittst(R3,30);
+ IF CC R0 = R2;
+ RTS;
+
+.Lret_zero:
+ R0 = 0;
+ RTS;
diff --git a/arch/blackfin/lib/gcclib.h b/arch/blackfin/lib/gcclib.h
new file mode 100644
index 0000000..9ccd39a
--- /dev/null
+++ b/arch/blackfin/lib/gcclib.h
@@ -0,0 +1,47 @@
+/*
+ * File: arch/blackfin/lib/gcclib.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define BITS_PER_UNIT 8
+#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+
+typedef unsigned int UQItype __attribute__ ((mode(QI)));
+typedef int SItype __attribute__ ((mode(SI)));
+typedef unsigned int USItype __attribute__ ((mode(SI)));
+typedef int DItype __attribute__ ((mode(DI)));
+typedef int word_type __attribute__ ((mode(__word__)));
+typedef unsigned int UDItype __attribute__ ((mode(DI)));
+
+struct DIstruct {
+ SItype low, high;
+};
+
+typedef union {
+ struct DIstruct s;
+ DItype ll;
+} DIunion;
diff --git a/arch/blackfin/lib/ins.S b/arch/blackfin/lib/ins.S
new file mode 100644
index 0000000..730d2b4
--- /dev/null
+++ b/arch/blackfin/lib/ins.S
@@ -0,0 +1,69 @@
+/*
+ * File: arch/blackfin/lib/ins.S
+ * Based on:
+ * Author: Bas Vermeulen <bas@buyways.nl>
+ *
+ * Created: Tue Mar 22 15:27:24 CEST 2005
+ * Description: Implementation of ins{bwl} for BlackFin processors using zero overhead loops.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ * Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl>
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+.align 2
+
+ENTRY(_insl)
+ P0 = R0; /* P0 = port */
+ cli R3;
+ P1 = R1; /* P1 = address */
+ P2 = R2; /* P2 = count */
+ SSYNC;
+ LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2;
+.Llong_loop_s: R0 = [P0];
+.Llong_loop_e: [P1++] = R0;
+ sti R3;
+ RTS;
+
+ENTRY(_insw)
+ P0 = R0; /* P0 = port */
+ cli R3;
+ P1 = R1; /* P1 = address */
+ P2 = R2; /* P2 = count */
+ SSYNC;
+ LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2;
+.Lword_loop_s: R0 = W[P0];
+.Lword_loop_e: W[P1++] = R0;
+ sti R3;
+ RTS;
+
+ENTRY(_insb)
+ P0 = R0; /* P0 = port */
+ cli R3;
+ P1 = R1; /* P1 = address */
+ P2 = R2; /* P2 = count */
+ SSYNC;
+ LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2;
+.Lbyte_loop_s: R0 = B[P0];
+.Lbyte_loop_e: B[P1++] = R0;
+ sti R3;
+ RTS;
diff --git a/arch/blackfin/lib/lshrdi3.c b/arch/blackfin/lib/lshrdi3.c
new file mode 100644
index 0000000..84b9c55
--- /dev/null
+++ b/arch/blackfin/lib/lshrdi3.c
@@ -0,0 +1,72 @@
+/*
+ * File: arch/blackfin/lib/lshrdi3.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define BITS_PER_UNIT 8
+
+typedef int SItype __attribute__ ((mode(SI)));
+typedef unsigned int USItype __attribute__ ((mode(SI)));
+typedef int DItype __attribute__ ((mode(DI)));
+typedef int word_type __attribute__ ((mode(__word__)));
+
+struct DIstruct {
+ SItype high, low;
+};
+
+typedef union {
+ struct DIstruct s;
+ DItype ll;
+} DIunion;
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+DItype __lshrdi3(DItype u, word_type b)__attribute__((l1_text));
+#endif
+
+DItype __lshrdi3(DItype u, word_type b)
+{
+ DIunion w;
+ word_type bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof(SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0) {
+ w.s.high = 0;
+ w.s.low = (USItype) uu.s.high >> -bm;
+ } else {
+ USItype carries = (USItype) uu.s.high << bm;
+ w.s.high = (USItype) uu.s.high >> b;
+ w.s.low = ((USItype) uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
diff --git a/arch/blackfin/lib/memchr.S b/arch/blackfin/lib/memchr.S
new file mode 100644
index 0000000..4981222
--- /dev/null
+++ b/arch/blackfin/lib/memchr.S
@@ -0,0 +1,70 @@
+/*
+ * File: arch/blackfin/lib/memchr.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+/* void *memchr(const void *s, int c, size_t n);
+ * R0 = address (s)
+ * R1 = sought byte (c)
+ * R2 = count (n)
+ *
+ * Returns pointer to located character.
+ */
+
+.text
+
+.align 2
+
+ENTRY(_memchr)
+ P0 = R0; /* P0 = address */
+ P2 = R2; /* P2 = count */
+ R1 = R1.B(Z);
+ CC = R2 == 0;
+ IF CC JUMP .Lfailed;
+
+.Lbytes:
+ LSETUP (.Lbyte_loop_s, .Lbyte_loop_e) LC0=P2;
+
+.Lbyte_loop_s:
+ R3 = B[P0++](Z);
+ CC = R3 == R1;
+ IF CC JUMP .Lfound;
+.Lbyte_loop_e:
+ NOP;
+
+.Lfailed:
+ R0=0;
+ RTS;
+
+.Lfound:
+ R0 = P0;
+ R0 += -1;
+ RTS;
+
+.size _memchr,.-_memchr
diff --git a/arch/blackfin/lib/memcmp.S b/arch/blackfin/lib/memcmp.S
new file mode 100644
index 0000000..5b95023
--- /dev/null
+++ b/arch/blackfin/lib/memcmp.S
@@ -0,0 +1,110 @@
+/*
+ * File: arch/blackfin/lib/memcmp.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+/* int memcmp(const void *s1, const void *s2, size_t n);
+ * R0 = First Address (s1)
+ * R1 = Second Address (s2)
+ * R2 = count (n)
+ *
+ * Favours word aligned data.
+ */
+
+.text
+
+.align 2
+
+ENTRY(_memcmp)
+ I1 = P3;
+ P0 = R0; /* P0 = s1 address */
+ P3 = R1; /* P3 = s2 Address */
+ P2 = R2 ; /* P2 = count */
+ CC = R2 <= 7(IU);
+ IF CC JUMP .Ltoo_small;
+ I0 = R1; /* s2 */
+ R1 = R1 | R0; /* OR addresses together */
+ R1 <<= 30; /* check bottom two bits */
+ CC = AZ; /* AZ set if zero. */
+ IF !CC JUMP .Lbytes ; /* Jump if addrs not aligned. */
+
+ P1 = P2 >> 2; /* count = n/4 */
+ R3 = 3;
+ R2 = R2 & R3; /* remainder */
+ P2 = R2; /* set remainder */
+
+ LSETUP (.Lquad_loop_s, .Lquad_loop_e) LC0=P1;
+.Lquad_loop_s:
+ MNOP || R0 = [P0++] || R1 = [I0++];
+ CC = R0 == R1;
+ IF !CC JUMP .Lquad_different;
+.Lquad_loop_e:
+ NOP;
+
+ P3 = I0; /* s2 */
+.Ltoo_small:
+ CC = P2 == 0; /* Check zero count*/
+ IF CC JUMP .Lfinished; /* very unlikely*/
+
+.Lbytes:
+ LSETUP (.Lbyte_loop_s, .Lbyte_loop_e) LC0=P2;
+.Lbyte_loop_s:
+ R1 = B[P3++](Z); /* *s2 */
+ R0 = B[P0++](Z); /* *s1 */
+ CC = R0 == R1;
+ IF !CC JUMP .Ldifferent;
+.Lbyte_loop_e:
+ NOP;
+
+.Ldifferent:
+ R0 = R0 - R1;
+ P3 = I1;
+ RTS;
+
+.Lquad_different:
+ /* We've read two quads which don't match.
+ * Can't just compare them, because we're
+ * a little-endian machine, so the MSBs of
+ * the regs occur at later addresses in the
+ * string.
+ * Arrange to re-read those two quads again,
+ * byte-by-byte.
+ */
+ P0 += -4; /* back up to the start of the */
+ P3 = I0; /* quads, and increase the*/
+ P2 += 4; /* remainder count*/
+ P3 += -4;
+ JUMP .Lbytes;
+
+.Lfinished:
+ R0 = 0;
+ P3 = I1;
+ RTS;
+
+.size _memcmp,.-_memcmp
diff --git a/arch/blackfin/lib/memcpy.S b/arch/blackfin/lib/memcpy.S
new file mode 100644
index 0000000..c1e00ef
--- /dev/null
+++ b/arch/blackfin/lib/memcpy.S
@@ -0,0 +1,142 @@
+/*
+ * File: arch/blackfin/lib/memcpy.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: internal version of memcpy(), issued by the compiler
+ * to copy blocks of data around.
+ * This is really memmove() - it has to be able to deal with
+ * possible overlaps, because that ambiguity is when the compiler
+ * gives up and calls a function. We have our own, internal version
+ * so that we get something we trust, even if the user has redefined
+ * the normal symbol.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+/* void *memcpy(void *dest, const void *src, size_t n);
+ * R0 = To Address (dest) (leave unchanged to form result)
+ * R1 = From Address (src)
+ * R2 = count
+ *
+ * Note: Favours word alignment
+ */
+
+#ifdef CONFIG_MEMCPY_L1
+.section .l1.text
+#else
+.text
+#endif
+
+.align 2
+
+ENTRY(_memcpy)
+ CC = R2 <= 0; /* length not positive? */
+ IF CC JUMP .L_P1L2147483647; /* Nothing to do */
+
+ P0 = R0 ; /* dst*/
+ P1 = R1 ; /* src*/
+ P2 = R2 ; /* length */
+
+ /* check for overlapping data */
+ CC = R1 < R0; /* src < dst */
+ IF !CC JUMP .Lno_overlap;
+ R3 = R1 + R2;
+ CC = R0 < R3; /* and dst < src+len */
+ IF CC JUMP .Lhas_overlap;
+
+.Lno_overlap:
+ /* Check for aligned data.*/
+
+ R3 = R1 | R0;
+ R0 = 0x3;
+ R3 = R3 & R0;
+ CC = R3; /* low bits set on either address? */
+ IF CC JUMP .Lnot_aligned;
+
+ /* Both addresses are word-aligned, so we can copy
+ at least part of the data using word copies.*/
+ P2 = P2 >> 2;
+ CC = P2 <= 2;
+ IF !CC JUMP .Lmore_than_seven;
+ /* less than eight bytes... */
+ P2 = R2;
+ LSETUP(.Lthree_start, .Lthree_end) LC0=P2;
+ R0 = R1; /* setup src address for return */
+.Lthree_start:
+ R3 = B[P1++] (X);
+.Lthree_end:
+ B[P0++] = R3;
+
+ RTS;
+
+.Lmore_than_seven:
+ /* There's at least eight bytes to copy. */
+ P2 += -1; /* because we unroll one iteration */
+ LSETUP(.Lword_loop, .Lword_loop) LC0=P2;
+ R0 = R1;
+ I1 = P1;
+ R3 = [I1++];
+.Lword_loop:
+ MNOP || [P0++] = R3 || R3 = [I1++];
+
+ [P0++] = R3;
+ /* Any remaining bytes to copy? */
+ R3 = 0x3;
+ R3 = R2 & R3;
+ CC = R3 == 0;
+ P1 = I1; /* in case there's something left, */
+ IF !CC JUMP .Lbytes_left;
+ RTS;
+.Lbytes_left: P2 = R3;
+.Lnot_aligned:
+ /* From here, we're copying byte-by-byte. */
+ LSETUP (.Lbyte_start, .Lbyte_end) LC0=P2;
+ R0 = R1; /* Save src address for return */
+.Lbyte_start:
+ R1 = B[P1++] (X);
+.Lbyte_end:
+ B[P0++] = R1;
+
+.L_P1L2147483647:
+ RTS;
+
+.Lhas_overlap:
+ /* Need to reverse the copying, because the
+ * dst would clobber the src.
+ * Don't bother to work out alignment for
+ * the reverse case.
+ */
+ R0 = R1; /* save src for later. */
+ P0 = P0 + P2;
+ P0 += -1;
+ P1 = P1 + P2;
+ P1 += -1;
+ LSETUP(.Lover_start, .Lover_end) LC0=P2;
+.Lover_start:
+ R1 = B[P1--] (X);
+.Lover_end:
+ B[P0--] = R1;
+
+ RTS;
diff --git a/arch/blackfin/lib/memmove.S b/arch/blackfin/lib/memmove.S
new file mode 100644
index 0000000..2e5fb7f
--- /dev/null
+++ b/arch/blackfin/lib/memmove.S
@@ -0,0 +1,103 @@
+/*
+ * File: arch/blackfin/lib/memmove.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+.align 2
+
+/*
+ * C Library function MEMMOVE
+ * R0 = To Address (leave unchanged to form result)
+ * R1 = From Address
+ * R2 = count
+ * Data may overlap
+ */
+
+ENTRY(_memmove)
+ I1 = P3;
+ P0 = R0; /* P0 = To address */
+ P3 = R1; /* P3 = From Address */
+ P2 = R2; /* P2 = count */
+ CC = P2 == 0; /* Check zero count*/
+ IF CC JUMP .Lfinished; /* very unlikely */
+
+ CC = R1 < R0 (IU); /* From < To */
+ IF !CC JUMP .Lno_overlap;
+ R3 = R1 + R2;
+ CC = R0 <= R3 (IU); /* (From+len) >= To */
+ IF CC JUMP .Loverlap;
+.Lno_overlap:
+ R3 = 11;
+ CC = R2 <= R3;
+ IF CC JUMP .Lbytes;
+ R3 = R1 | R0; /* OR addresses together */
+ R3 <<= 30; /* check bottom two bits */
+ CC = AZ; /* AZ set if zero.*/
+ IF !CC JUMP .Lbytes; /* Jump if addrs not aligned.*/
+
+ I0 = P3;
+ P1 = P2 >> 2; /* count = n/4 */
+ P1 += -1;
+ R3 = 3;
+ R2 = R2 & R3; /* remainder */
+ P2 = R2; /* set remainder */
+ R1 = [I0++];
+
+ LSETUP (.Lquad_loop, .Lquad_loop) LC0=P1;
+.Lquad_loop: MNOP || [P0++] = R1 || R1 = [I0++];
+ [P0++] = R1;
+
+ CC = P2 == 0; /* any remaining bytes? */
+ P3 = I0; /* Ammend P3 to updated ptr. */
+ IF !CC JUMP .Lbytes;
+ P3 = I1;
+ RTS;
+
+.Lbytes: LSETUP (.Lbyte2_s, .Lbyte2_e) LC0=P2;
+.Lbyte2_s: R1 = B[P3++](Z);
+.Lbyte2_e: B[P0++] = R1;
+
+.Lfinished: P3 = I1;
+ RTS;
+
+.Loverlap:
+ P2 += -1;
+ P0 = P0 + P2;
+ P3 = P3 + P2;
+ R1 = B[P3--] (Z);
+ CC = P2 == 0;
+ IF CC JUMP .Lno_loop;
+ LSETUP (.Lol_s, .Lol_e) LC0 = P2;
+.Lol_s: B[P0--] = R1;
+.Lol_e: R1 = B[P3--] (Z);
+.Lno_loop: B[P0] = R1;
+ P3 = I1;
+ RTS;
+
+.size _memmove,.-_memmove
diff --git a/arch/blackfin/lib/memset.S b/arch/blackfin/lib/memset.S
new file mode 100644
index 0000000..ba6d047
--- /dev/null
+++ b/arch/blackfin/lib/memset.S
@@ -0,0 +1,109 @@
+/*
+ * File: arch/blackfin/lib/memset.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+.align 2
+
+#ifdef CONFIG_MEMSET_L1
+.section .l1.text
+#else
+.text
+#endif
+
+/*
+ * C Library function MEMSET
+ * R0 = address (leave unchanged to form result)
+ * R1 = filler byte
+ * R2 = count
+ * Favours word aligned data.
+ */
+
+ENTRY(_memset)
+ P0 = R0 ; /* P0 = address */
+ P2 = R2 ; /* P2 = count */
+ R3 = R0 + R2; /* end */
+ CC = R2 <= 7(IU);
+ IF CC JUMP .Ltoo_small;
+ R1 = R1.B (Z); /* R1 = fill char */
+ R2 = 3;
+ R2 = R0 & R2; /* addr bottom two bits */
+ CC = R2 == 0; /* AZ set if zero. */
+ IF !CC JUMP .Lforce_align ; /* Jump if addr not aligned. */
+
+.Laligned:
+ P1 = P2 >> 2; /* count = n/4 */
+ R2 = R1 << 8; /* create quad filler */
+ R2.L = R2.L + R1.L(NS);
+ R2.H = R2.L + R1.H(NS);
+ P2 = R3;
+
+ LSETUP (.Lquad_loop , .Lquad_loop) LC0=P1;
+.Lquad_loop:
+ [P0++] = R2;
+
+ CC = P0 == P2;
+ IF !CC JUMP .Lbytes_left;
+ RTS;
+
+.Lbytes_left:
+ R2 = R3; /* end point */
+ R3 = P0; /* current position */
+ R2 = R2 - R3; /* bytes left */
+ P2 = R2;
+
+.Ltoo_small:
+ CC = P2 == 0; /* Check zero count */
+ IF CC JUMP .Lfinished; /* Unusual */
+
+.Lbytes:
+ LSETUP (.Lbyte_loop , .Lbyte_loop) LC0=P2;
+.Lbyte_loop:
+ B[P0++] = R1;
+
+.Lfinished:
+ RTS;
+
+.Lforce_align:
+ CC = BITTST (R0, 0); /* odd byte */
+ R0 = 4;
+ R0 = R0 - R2;
+ P1 = R0;
+ R0 = P0; /* Recover return address */
+ IF !CC JUMP .Lskip1;
+ B[P0++] = R1;
+.Lskip1:
+ CC = R2 <= 2; /* 2 bytes */
+ P2 -= P1; /* reduce count */
+ IF !CC JUMP .Laligned;
+ B[P0++] = R1;
+ B[P0++] = R1;
+ JUMP .Laligned;
+
+.size _memset,.-_memset
diff --git a/arch/blackfin/lib/modsi3.S b/arch/blackfin/lib/modsi3.S
new file mode 100644
index 0000000..528b8b1
--- /dev/null
+++ b/arch/blackfin/lib/modsi3.S
@@ -0,0 +1,79 @@
+/*
+ * File: arch/blackfin/lib/modsi3.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: This program computes 32 bit signed remainder. It calls div32 function
+ * for quotient estimation.
+ *
+ * Registers used :
+ * Numerator/ Denominator in R0, R1
+ * R0 - returns remainder.
+ * R2-R7
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+.global ___modsi3;
+.type ___modsi3, STT_FUNC;
+.extern ___divsi3;
+.type ___divsi3, STT_FUNC;
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+___modsi3:
+
+ CC=R0==0;
+ IF CC JUMP .LRETURN_R0; /* Return 0, if numerator == 0 */
+ CC=R1==0;
+ IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == 0 */
+ CC=R0==R1;
+ IF CC JUMP .LRETURN_ZERO; /* Return 0, if numerator == denominator */
+ CC = R1 == 1;
+ IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == 1 */
+ CC = R1 == -1;
+ IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == -1 */
+
+ /* Valid input. Use __divsi3() to compute the quotient, and then
+ * derive the remainder from that. */
+
+ [--SP] = (R7:6); /* Push R7 and R6 */
+ [--SP] = RETS; /* and return address */
+ R7 = R0; /* Copy of R0 */
+ R6 = R1; /* Save for later */
+ SP += -12; /* Should always provide this space */
+ CALL ___divsi3; /* Compute signed quotient using ___divsi3()*/
+ SP += 12;
+ R0 *= R6; /* Quotient * divisor */
+ R0 = R7 - R0; /* Dividend - (quotient * divisor) */
+ RETS = [SP++]; /* Get back return address */
+ (R7:6) = [SP++]; /* Pop registers R7 and R4 */
+ RTS; /* Store remainder */
+
+.LRETURN_ZERO:
+ R0 = 0;
+.LRETURN_R0:
+ RTS;
diff --git a/arch/blackfin/lib/muldi3.c b/arch/blackfin/lib/muldi3.c
new file mode 100644
index 0000000..303d0c6
--- /dev/null
+++ b/arch/blackfin/lib/muldi3.c
@@ -0,0 +1,99 @@
+/*
+ * File: arch/blackfin/lib/muldi3.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef SI_TYPE_SIZE
+#define SI_TYPE_SIZE 32
+#endif
+#define __ll_b (1L << (SI_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((usitype) (t) % __ll_b)
+#define __ll_highpart(t) ((usitype) (t) / __ll_b)
+#define BITS_PER_UNIT 8
+
+#if !defined(umul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ usitype __x0, __x1, __x2, __x3; \
+ usitype __ul, __vl, __uh, __vh; \
+ \
+ __ul = __ll_lowpart (u); \
+ __uh = __ll_highpart (u); \
+ __vl = __ll_lowpart (v); \
+ __vh = __ll_highpart (v); \
+ \
+ __x0 = (usitype) __ul * __vl; \
+ __x1 = (usitype) __ul * __vh; \
+ __x2 = (usitype) __uh * __vl; \
+ __x3 = (usitype) __uh * __vh; \
+ \
+ __x1 += __ll_highpart (__x0);/* this can't give carry */ \
+ __x1 += __x2; /* but this indeed can */ \
+ if (__x1 < __x2) /* did we get it? */ \
+ __x3 += __ll_b; /* yes, add it in the proper pos. */ \
+ \
+ (w1) = __x3 + __ll_highpart (__x1); \
+ (w0) = __ll_lowpart (__x1) * __ll_b + __ll_lowpart (__x0); \
+ } while (0)
+#endif
+
+#if !defined(__umulsidi3)
+#define __umulsidi3(u, v) \
+ ({diunion __w; \
+ umul_ppmm (__w.s.high, __w.s.low, u, v); \
+ __w.ll; })
+#endif
+
+typedef unsigned int usitype __attribute__ ((mode(SI)));
+typedef int sitype __attribute__ ((mode(SI)));
+typedef int ditype __attribute__ ((mode(DI)));
+typedef int word_type __attribute__ ((mode(__word__)));
+
+struct distruct {
+ sitype low, high;
+};
+typedef union {
+ struct distruct s;
+ ditype ll;
+} diunion;
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+ditype __muldi3(ditype u, ditype v)__attribute__((l1_text));
+#endif
+
+ditype __muldi3(ditype u, ditype v)
+{
+ diunion w;
+ diunion uu, vv;
+
+ uu.ll = u, vv.ll = v;
+ w.ll = __umulsidi3(uu.s.low, vv.s.low);
+ w.s.high += ((usitype) uu.s.low * (usitype) vv.s.high
+ + (usitype) uu.s.high * (usitype) vv.s.low);
+
+ return w.ll;
+}
diff --git a/arch/blackfin/lib/outs.S b/arch/blackfin/lib/outs.S
new file mode 100644
index 0000000..f8c876f
--- /dev/null
+++ b/arch/blackfin/lib/outs.S
@@ -0,0 +1,62 @@
+/*
+ * File: arch/blackfin/lib/outs.S
+ * Based on:
+ * Author: Bas Vermeulen <bas@buyways.nl>
+ *
+ * Created: Tue Mar 22 15:27:24 CEST 2005
+ * Description: Implementation of outs{bwl} for BlackFin processors using zero overhead loops.
+ *
+ * Modified: Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl>
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+.align 2
+
+ENTRY(_outsl)
+ P0 = R0; /* P0 = port */
+ P1 = R1; /* P1 = address */
+ P2 = R2; /* P2 = count */
+
+ LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2;
+.Llong_loop_s: R0 = [P1++];
+.Llong_loop_e: [P0] = R0;
+ RTS;
+
+ENTRY(_outsw)
+ P0 = R0; /* P0 = port */
+ P1 = R1; /* P1 = address */
+ P2 = R2; /* P2 = count */
+
+ LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2;
+.Lword_loop_s: R0 = W[P1++];
+.Lword_loop_e: W[P0] = R0;
+ RTS;
+
+ENTRY(_outsb)
+ P0 = R0; /* P0 = port */
+ P1 = R1; /* P1 = address */
+ P2 = R2; /* P2 = count */
+
+ LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2;
+.Lbyte_loop_s: R0 = B[P1++];
+.Lbyte_loop_e: B[P0] = R0;
+ RTS;
diff --git a/arch/blackfin/lib/smulsi3_highpart.S b/arch/blackfin/lib/smulsi3_highpart.S
new file mode 100644
index 0000000..10b8f8d
--- /dev/null
+++ b/arch/blackfin/lib/smulsi3_highpart.S
@@ -0,0 +1,30 @@
+.align 2
+.global ___smulsi3_highpart;
+.type ___smulsi3_highpart, STT_FUNC;
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+___smulsi3_highpart:
+ R2 = R1.L * R0.L (FU);
+ R3 = R1.H * R0.L (IS,M);
+ R0 = R0.H * R1.H, R1 = R0.H * R1.L (IS,M);
+
+ R1.L = R2.H + R1.L;
+ cc = ac0;
+ R2 = cc;
+
+ R1.L = R1.L + R3.L;
+ cc = ac0;
+ R1 >>>= 16;
+ R3 >>>= 16;
+ R1 = R1 + R3;
+ R1 = R1 + R2;
+ R2 = cc;
+ R1 = R1 + R2;
+
+ R0 = R0 + R1;
+ RTS;
diff --git a/arch/blackfin/lib/strcmp.c b/arch/blackfin/lib/strcmp.c
new file mode 100644
index 0000000..2ad47c4
--- /dev/null
+++ b/arch/blackfin/lib/strcmp.c
@@ -0,0 +1,11 @@
+#include <linux/types.h>
+
+#define strcmp __inline_strcmp
+#include <asm/string.h>
+#undef strcmp
+
+int strcmp(const char *dest, const char *src)
+{
+ return __inline_strcmp(dest, src);
+}
+
diff --git a/arch/blackfin/lib/strcpy.c b/arch/blackfin/lib/strcpy.c
new file mode 100644
index 0000000..4dc835a
--- /dev/null
+++ b/arch/blackfin/lib/strcpy.c
@@ -0,0 +1,11 @@
+#include <linux/types.h>
+
+#define strcpy __inline_strcpy
+#include <asm/string.h>
+#undef strcpy
+
+char *strcpy(char *dest, const char *src)
+{
+ return __inline_strcpy(dest, src);
+}
+
diff --git a/arch/blackfin/lib/strncmp.c b/arch/blackfin/lib/strncmp.c
new file mode 100644
index 0000000..947bcfe
--- /dev/null
+++ b/arch/blackfin/lib/strncmp.c
@@ -0,0 +1,11 @@
+#include <linux/types.h>
+
+#define strncmp __inline_strncmp
+#include <asm/string.h>
+#undef strncmp
+
+int strncmp(const char *cs, const char *ct, size_t count)
+{
+ return __inline_strncmp(cs, ct, count);
+}
+
diff --git a/arch/blackfin/lib/strncpy.c b/arch/blackfin/lib/strncpy.c
new file mode 100644
index 0000000..77a9b2e
--- /dev/null
+++ b/arch/blackfin/lib/strncpy.c
@@ -0,0 +1,11 @@
+#include <linux/types.h>
+
+#define strncpy __inline_strncpy
+#include <asm/string.h>
+#undef strncpy
+
+char *strncpy(char *dest, const char *src, size_t n)
+{
+ return __inline_strncpy(dest, src, n);
+}
+
diff --git a/arch/blackfin/lib/udivsi3.S b/arch/blackfin/lib/udivsi3.S
new file mode 100644
index 0000000..d39a129
--- /dev/null
+++ b/arch/blackfin/lib/udivsi3.S
@@ -0,0 +1,298 @@
+/*
+ * File: arch/blackfin/lib/udivsi3.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+
+#define CARRY AC0
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+
+ENTRY(___udivsi3)
+
+ CC = R0 < R1 (IU); /* If X < Y, always return 0 */
+ IF CC JUMP .Lreturn_ident;
+
+ R2 = R1 << 16;
+ CC = R2 <= R0 (IU);
+ IF CC JUMP .Lidents;
+
+ R2 = R0 >> 31; /* if X is a 31-bit number */
+ R3 = R1 >> 15; /* and Y is a 15-bit number */
+ R2 = R2 | R3; /* then it's okay to use the DIVQ builtins (fallthrough to fast)*/
+ CC = R2;
+ IF CC JUMP .Ly_16bit;
+
+/* METHOD 1: FAST DIVQ
+ We know we have a 31-bit dividend, and 15-bit divisor so we can use the
+ simple divq approach (first setting AQ to 0 - implying unsigned division,
+ then 16 DIVQ's).
+*/
+
+ AQ = CC; /* Clear AQ (CC==0) */
+
+/* ISR States: When dividing two integers (32.0/16.0) using divide primitives,
+ we need to shift the dividend one bit to the left.
+ We have already checked that we have a 31-bit number so we are safe to do
+ that.
+*/
+ R0 <<= 1;
+ DIVQ(R0, R1); // 1
+ DIVQ(R0, R1); // 2
+ DIVQ(R0, R1); // 3
+ DIVQ(R0, R1); // 4
+ DIVQ(R0, R1); // 5
+ DIVQ(R0, R1); // 6
+ DIVQ(R0, R1); // 7
+ DIVQ(R0, R1); // 8
+ DIVQ(R0, R1); // 9
+ DIVQ(R0, R1); // 10
+ DIVQ(R0, R1); // 11
+ DIVQ(R0, R1); // 12
+ DIVQ(R0, R1); // 13
+ DIVQ(R0, R1); // 14
+ DIVQ(R0, R1); // 15
+ DIVQ(R0, R1); // 16
+ R0 = R0.L (Z);
+ RTS;
+
+.Ly_16bit:
+ /* We know that the upper 17 bits of Y might have bits set,
+ ** or that the sign bit of X might have a bit. If Y is a
+ ** 16-bit number, but not bigger, then we can use the builtins
+ ** with a post-divide correction.
+ ** R3 currently holds Y>>15, which means R3's LSB is the
+ ** bit we're interested in.
+ */
+
+ /* According to the ISR, to use the Divide primitives for
+ ** unsigned integer divide, the useable range is 31 bits
+ */
+ CC = ! BITTST(R0, 31);
+
+ /* IF condition is true we can scale our inputs and use the divide primitives,
+ ** with some post-adjustment
+ */
+ R3 += -1; /* if so, Y is 0x00008nnn */
+ CC &= AZ;
+
+ /* If condition is true we can scale our inputs and use the divide primitives,
+ ** with some post-adjustment
+ */
+ R3 = R1 >> 1; /* Pre-scaled divisor for primitive case */
+ R2 = R0 >> 16;
+
+ R2 = R3 - R2; /* shifted divisor < upper 16 bits of dividend */
+ CC &= CARRY;
+ IF CC JUMP .Lshift_and_correct;
+
+ /* Fall through to the identities */
+
+/* METHOD 2: identities and manual calculation
+ We are not able to use the divide primites, but may still catch some special
+ cases.
+*/
+.Lidents:
+ /* Test for common identities. Value to be returned is placed in R2. */
+ CC = R0 == 0; /* 0/Y => 0 */
+ IF CC JUMP .Lreturn_r0;
+ CC = R0 == R1; /* X==Y => 1 */
+ IF CC JUMP .Lreturn_ident;
+ CC = R1 == 1; /* X/1 => X */
+ IF CC JUMP .Lreturn_ident;
+
+ R2.L = ONES R1;
+ R2 = R2.L (Z);
+ CC = R2 == 1;
+ IF CC JUMP .Lpower_of_two;
+
+ [--SP] = (R7:5); /* Push registers R5-R7 */
+
+ /* Idents don't match. Go for the full operation. */
+
+
+ R6 = 2; /* assume we'll shift two */
+ R3 = 1;
+
+ P2 = R1;
+ /* If either R0 or R1 have sign set, */
+ /* divide them by two, and note it's */
+ /* been done. */
+ CC = R1 < 0;
+ R2 = R1 >> 1;
+ IF CC R1 = R2; /* Possibly-shifted R1 */
+ IF !CC R6 = R3; /* R1 doesn't, so at most 1 shifted */
+
+ P0 = 0;
+ R3 = -R1;
+ [--SP] = R3;
+ R2 = R0 >> 1;
+ R2 = R0 >> 1;
+ CC = R0 < 0;
+ IF CC P0 = R6; /* Number of values divided */
+ IF !CC R2 = R0; /* Shifted R0 */
+
+ /* P0 is 0, 1 (NR/=2) or 2 (NR/=2, DR/=2) */
+
+ /* r2 holds Copy dividend */
+ R3 = 0; /* Clear partial remainder */
+ R7 = 0; /* Initialise quotient bit */
+
+ P1 = 32; /* Set loop counter */
+ LSETUP(.Lulst, .Lulend) LC0 = P1; /* Set loop counter */
+.Lulst: R6 = R2 >> 31; /* R6 = sign bit of R2, for carry */
+ R2 = R2 << 1; /* Shift 64 bit dividend up by 1 bit */
+ R3 = R3 << 1 || R5 = [SP];
+ R3 = R3 | R6; /* Include any carry */
+ CC = R7 < 0; /* Check quotient(AQ) */
+ /* If AQ==0, we'll sub divisor */
+ IF CC R5 = R1; /* and if AQ==1, we'll add it. */
+ R3 = R3 + R5; /* Add/sub divsor to partial remainder */
+ R7 = R3 ^ R1; /* Generate next quotient bit */
+
+ R5 = R7 >> 31; /* Get AQ */
+ BITTGL(R5, 0); /* Invert it, to get what we'll shift */
+.Lulend: R2 = R2 + R5; /* and "shift" it in. */
+
+ CC = P0 == 0; /* Check how many inputs we shifted */
+ IF CC JUMP .Lno_mult; /* if none... */
+ R6 = R2 << 1;
+ CC = P0 == 1;
+ IF CC R2 = R6; /* if 1, Q = Q*2 */
+ IF !CC R1 = P2; /* if 2, restore stored divisor */
+
+ R3 = R2; /* Copy of R2 */
+ R3 *= R1; /* Q * divisor */
+ R5 = R0 - R3; /* Z = (dividend - Q * divisor) */
+ CC = R1 <= R5 (IU); /* Check if divisor <= Z? */
+ R6 = CC; /* if yes, R6 = 1 */
+ R2 = R2 + R6; /* if yes, add one to quotient(Q) */
+.Lno_mult:
+ SP += 4;
+ (R7:5) = [SP++]; /* Pop registers R5-R7 */
+ R0 = R2; /* Store quotient */
+ RTS;
+
+.Lreturn_ident:
+ CC = R0 < R1 (IU); /* If X < Y, always return 0 */
+ R2 = 0;
+ IF CC JUMP .Ltrue_return_ident;
+ R2 = -1 (X); /* X/0 => 0xFFFFFFFF */
+ CC = R1 == 0;
+ IF CC JUMP .Ltrue_return_ident;
+ R2 = -R2; /* R2 now 1 */
+ CC = R0 == R1; /* X==Y => 1 */
+ IF CC JUMP .Ltrue_return_ident;
+ R2 = R0; /* X/1 => X */
+ /*FALLTHRU*/
+
+.Ltrue_return_ident:
+ R0 = R2;
+.Lreturn_r0:
+ RTS;
+
+.Lpower_of_two:
+ /* Y has a single bit set, which means it's a power of two.
+ ** That means we can perform the division just by shifting
+ ** X to the right the appropriate number of bits
+ */
+
+ /* signbits returns the number of sign bits, minus one.
+ ** 1=>30, 2=>29, ..., 0x40000000=>0. Which means we need
+ ** to shift right n-signbits spaces. It also means 0x80000000
+ ** is a special case, because that *also* gives a signbits of 0
+ */
+
+ R2 = R0 >> 31;
+ CC = R1 < 0;
+ IF CC JUMP .Ltrue_return_ident;
+
+ R1.l = SIGNBITS R1;
+ R1 = R1.L (Z);
+ R1 += -30;
+ R0 = LSHIFT R0 by R1.L;
+ RTS;
+
+/* METHOD 3: PRESCALE AND USE THE DIVIDE PRIMITIVES WITH SOME POST-CORRECTION
+ Two scaling operations are required to use the divide primitives with a
+ divisor > 0x7FFFF.
+ Firstly (as in method 1) we need to shift the dividend 1 to the left for
+ integer division.
+ Secondly we need to shift both the divisor and dividend 1 to the right so
+ both are in range for the primitives.
+ The left/right shift of the dividend does nothing so we can skip it.
+*/
+.Lshift_and_correct:
+ R2 = R0;
+ // R3 is already R1 >> 1
+ CC=!CC;
+ AQ = CC; /* Clear AQ, got here with CC = 0 */
+ DIVQ(R2, R3); // 1
+ DIVQ(R2, R3); // 2
+ DIVQ(R2, R3); // 3
+ DIVQ(R2, R3); // 4
+ DIVQ(R2, R3); // 5
+ DIVQ(R2, R3); // 6
+ DIVQ(R2, R3); // 7
+ DIVQ(R2, R3); // 8
+ DIVQ(R2, R3); // 9
+ DIVQ(R2, R3); // 10
+ DIVQ(R2, R3); // 11
+ DIVQ(R2, R3); // 12
+ DIVQ(R2, R3); // 13
+ DIVQ(R2, R3); // 14
+ DIVQ(R2, R3); // 15
+ DIVQ(R2, R3); // 16
+
+ /* According to the Instruction Set Reference:
+ To divide by a divisor > 0x7FFF,
+ 1. prescale and perform divide to obtain quotient (Q) (done above),
+ 2. multiply quotient by unscaled divisor (result M)
+ 3. subtract the product from the divident to get an error (E = X - M)
+ 4. if E < divisor (Y) subtract 1, if E > divisor (Y) add 1, else return quotient (Q)
+ */
+ R3 = R2.L (Z); /* Q = X' / Y' */
+ R2 = R3; /* Preserve Q */
+ R2 *= R1; /* M = Q * Y */
+ R2 = R0 - R2; /* E = X - M */
+ R0 = R3; /* Copy Q into result reg */
+
+/* Correction: If result of the multiply is negative, we overflowed
+ and need to correct the result by subtracting 1 from the result.*/
+ R3 = 0xFFFF (Z);
+ R2 = R2 >> 16; /* E >> 16 */
+ CC = R2 == R3;
+ R3 = 1 ;
+ R1 = R0 - R3;
+ IF CC R0 = R1;
+ RTS;
diff --git a/arch/blackfin/lib/umodsi3.S b/arch/blackfin/lib/umodsi3.S
new file mode 100644
index 0000000..b55ce96
--- /dev/null
+++ b/arch/blackfin/lib/umodsi3.S
@@ -0,0 +1,66 @@
+/*
+ * File: arch/blackfin/lib/umodsi3.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: libgcc1 routines for Blackfin 5xx
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+.extern ___udivsi3;
+.globl ___umodsi3
+___umodsi3:
+
+ CC=R0==0;
+ IF CC JUMP .LRETURN_R0; /* Return 0, if NR == 0 */
+ CC= R1==0;
+ IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if DR == 0 */
+ CC=R0==R1;
+ IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if NR == DR */
+ CC = R1 == 1;
+ IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if DR == 1 */
+ CC = R0<R1 (IU);
+ IF CC JUMP .LRETURN_R0; /* Return dividend (R0),IF NR<DR */
+
+ [--SP] = (R7:6); /* Push registers and */
+ [--SP] = RETS; /* Return address */
+ R7 = R0; /* Copy of R0 */
+ R6 = R1;
+ SP += -12; /* Should always provide this space */
+ CALL ___udivsi3; /* Compute unsigned quotient using ___udiv32()*/
+ SP += 12;
+ R0 *= R6; /* Quotient * divisor */
+ R0 = R7 - R0; /* Dividend - (quotient * divisor) */
+ RETS = [SP++]; /* Pop return address */
+ ( R7:6) = [SP++]; /* And registers */
+ RTS; /* Return remainder */
+.LRETURN_ZERO_VAL:
+ R0 = 0;
+.LRETURN_R0:
+ RTS;
diff --git a/arch/blackfin/lib/umulsi3_highpart.S b/arch/blackfin/lib/umulsi3_highpart.S
new file mode 100644
index 0000000..aac8218
--- /dev/null
+++ b/arch/blackfin/lib/umulsi3_highpart.S
@@ -0,0 +1,23 @@
+.align 2
+.global ___umulsi3_highpart;
+.type ___umulsi3_highpart, STT_FUNC;
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+___umulsi3_highpart:
+ R2 = R1.H * R0.H, R3 = R1.L * R0.H (FU);
+ R0 = R1.L * R0.L, R1 = R1.H * R0.L (FU);
+ R0 >>= 16;
+ /* Unsigned multiplication has the nice property that we can
+ ignore carry on this first addition. */
+ R0 = R0 + R3;
+ R0 = R0 + R1;
+ cc = ac0;
+ R1 = cc;
+ R1 = PACK(R1.l,R0.h);
+ R0 = R1 + R2;
+ RTS;
diff --git a/arch/blackfin/mach-bf533/Kconfig b/arch/blackfin/mach-bf533/Kconfig
new file mode 100644
index 0000000..14297b3
--- /dev/null
+++ b/arch/blackfin/mach-bf533/Kconfig
@@ -0,0 +1,92 @@
+if (BF533 || BF532 || BF531)
+
+menu "BF533/2/1 Specific Configuration"
+
+comment "Interrupt Priority Assignment"
+menu "Priority"
+
+config UART_ERROR
+ int "UART ERROR"
+ default 7
+config SPORT0_ERROR
+ int "SPORT0 ERROR"
+ default 7
+config SPI_ERROR
+ int "SPI ERROR"
+ default 7
+config SPORT1_ERROR
+ int "SPORT1 ERROR"
+ default 7
+config PPI_ERROR
+ int "PPI ERROR"
+ default 7
+config DMA_ERROR
+ int "DMA ERROR"
+ default 7
+config PLLWAKE_ERROR
+ int "PLL WAKEUP ERROR"
+ default 7
+
+config RTC_ERROR
+ int "RTC ERROR"
+ default 8
+config DMA0_PPI
+ int "DMA0 PPI"
+ default 8
+
+config DMA1_SPORT0RX
+ int "DMA1 (SPORT0 RX)"
+ default 9
+config DMA2_SPORT0TX
+ int "DMA2 (SPORT0 TX)"
+ default 9
+config DMA3_SPORT1RX
+ int "DMA3 (SPORT1 RX)"
+ default 9
+config DMA4_SPORT1TX
+ int "DMA4 (SPORT1 TX)"
+ default 9
+config DMA5_SPI
+ int "DMA5 (SPI)"
+ default 10
+config DMA6_UARTRX
+ int "DMA6 (UART0 RX)"
+ default 10
+config DMA7_UARTTX
+ int "DMA7 (UART0 TX)"
+ default 10
+config TIMER0
+ int "TIMER0"
+ default 11
+config TIMER1
+ int "TIMER1"
+ default 11
+config TIMER2
+ int "TIMER2"
+ default 11
+config PFA
+ int "PF Interrupt A"
+ default 12
+config PFB
+ int "PF Interrupt B"
+ default 12
+config MEMDMA0
+ int "MEMORY DMA0"
+ default 13
+config MEMDMA1
+ int "MEMORY DMA1"
+ default 13
+config WDTIMER
+ int "WATCH DOG TIMER"
+ default 13
+
+ help
+ Enter the priority numbers between 7-13 ONLY. Others are Reserved.
+ This applies to all the above. It is not recommended to assign the
+ highest priority number 7 to UART or any other device.
+
+endmenu
+
+endmenu
+
+endif
diff --git a/arch/blackfin/mach-bf533/Makefile b/arch/blackfin/mach-bf533/Makefile
new file mode 100644
index 0000000..76d2c2b
--- /dev/null
+++ b/arch/blackfin/mach-bf533/Makefile
@@ -0,0 +1,9 @@
+#
+# arch/blackfin/mach-bf533/Makefile
+#
+
+extra-y := head.o
+
+obj-y := ints-priority.o
+
+obj-$(CONFIG_CPU_FREQ_BF533) += cpu.o
diff --git a/arch/blackfin/mach-bf533/boards/Makefile b/arch/blackfin/mach-bf533/boards/Makefile
new file mode 100644
index 0000000..12a631a
--- /dev/null
+++ b/arch/blackfin/mach-bf533/boards/Makefile
@@ -0,0 +1,8 @@
+#
+# arch/blackfin/mach-bf533/boards/Makefile
+#
+
+obj-$(CONFIG_GENERIC_BOARD) += generic_board.o
+obj-$(CONFIG_BFIN533_STAMP) += stamp.o
+obj-$(CONFIG_BFIN533_EZKIT) += ezkit.o
+obj-$(CONFIG_BFIN533_BLUETECHNIX_CM) += cm_bf533.o
diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c
new file mode 100644
index 0000000..23a7f60
--- /dev/null
+++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c
@@ -0,0 +1,267 @@
+/*
+ * File: arch/blackfin/mach-bf533/boards/cm_bf533.c
+ * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au> Copright 2005
+ *
+ * Created: 2005
+ * Description: Board description file
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/usb_isp1362.h>
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "Bluetechnix CM BF533";
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },{
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 2, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .start = 0x20200300,
+ .end = 0x20200300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF0,
+ .end = IRQ_PF0,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+ {
+ .start = 0x20308000,
+ .end = 0x20308000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20308004,
+ .end = 0x20308004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF4,
+ .end = IRQ_PF4,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+ .sel15Kres = 1,
+ .clknotstop = 0,
+ .oc_enable = 0,
+ .int_act_high = 0,
+ .int_edge_triggered = 0,
+ .remote_wakeup_connected = 0,
+ .no_power_switching = 1,
+ .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+ .name = "isp1362-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &isp1362_priv,
+ },
+ .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+ .resource = isp1362_hcd_resources,
+};
+#endif
+
+static struct platform_device *cm_bf533_devices[] __initdata = {
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+ &bfin_sport0_uart_device,
+ &bfin_sport1_uart_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+ &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+};
+
+static int __init cm_bf533_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(cm_bf533_devices, ARRAY_SIZE(cm_bf533_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(cm_bf533_init);
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
new file mode 100644
index 0000000..747298e
--- /dev/null
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -0,0 +1,224 @@
+/*
+ * File: arch/blackfin/mach-bf533/ezkit.c
+ * Based on: Orginal Work
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created: 2005
+ * Description:
+ *
+ * Modified: Robin Getz <rgetz@blackfin.uclinux.org> - Named the boards
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/usb_isp1362.h>
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "ADDS-BF533-EZKIT";
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+/*
+ * USB-LAN EzExtender board
+ * Driver needs to know address, irq and flag pin.
+ */
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x20310300,
+ .end = 0x20310300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF9,
+ .end = IRQ_PF9,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 2, /* Framework chip select. On STAMP537 it is SPISSEL2*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+static struct platform_device *ezkit_devices[] __initdata = {
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+};
+
+static int __init ezkit_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(ezkit_init);
diff --git a/arch/blackfin/mach-bf533/boards/generic_board.c b/arch/blackfin/mach-bf533/boards/generic_board.c
new file mode 100644
index 0000000..c0f43cc
--- /dev/null
+++ b/arch/blackfin/mach-bf533/boards/generic_board.c
@@ -0,0 +1,95 @@
+/*
+ * File: arch/blackfin/mach-bf533/generic_board.c
+ * Based on: arch/blackfin/mach-bf533/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created: 2005
+ * Description:
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <asm/irq.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "UNKNOWN BOARD";
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .start = 0x20300300,
+ .end = 0x20300300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PROG_INTB,
+ .end = IRQ_PROG_INTB,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },{
+ /*
+ * denotes the flag pin and is used directly if
+ * CONFIG_IRQCHIP_DEMUX_GPIO is defined.
+ */
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+static struct platform_device *generic_board_devices[] __initdata = {
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+};
+
+static int __init generic_board_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ return platform_add_devices(generic_board_devices, ARRAY_SIZE(generic_board_devices));
+}
+
+arch_initcall(generic_board_init);
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
new file mode 100644
index 0000000..d7b3a5d
--- /dev/null
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -0,0 +1,321 @@
+/*
+ * File: arch/blackfin/mach-bf533/stamp.c
+ * Based on: arch/blackfin/mach-bf533/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created: 2005
+ * Description: Board Info File for the BF533-STAMP
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+#include <linux/usb_isp1362.h>
+#endif
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "ADDS-BF533-STAMP";
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x20300300,
+ .end = 0x20300300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+ {
+ .start = 0x20300000,
+ .end = 0x20300000 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF10,
+ .end = IRQ_PF10,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device net2272_bfin_device = {
+ .name = "net2272",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+ .resource = net2272_bfin_resources,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_PBX)
+static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
+ .ctl_reg = 0x4, /* send zero */
+ .enable_dma = 0,
+ .bits_per_word = 8,
+ .cs_change_per_word = 1,
+};
+#endif
+
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+static struct bfin5xx_spi_chip ad5304_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 2, /* Framework chip select. On STAMP537 it is SPISSEL2*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 31250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_PBX)
+ {
+ .modalias = "fxs-spi",
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 3,
+ .controller_data= &spi_si3xxx_chip_info,
+ .mode = SPI_MODE_3,
+ },
+ {
+ .modalias = "fxo-spi",
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 2,
+ .controller_data= &spi_si3xxx_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+ {
+ .modalias = "ad5304_spi",
+ .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 2,
+ .platform_data = NULL,
+ .controller_data = &ad5304_chip_info,
+ .mode = SPI_MODE_2,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+static struct platform_device bfin_fb_device = {
+ .name = "bf537-fb",
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+};
+#endif
+
+static struct platform_device *stamp_devices[] __initdata = {
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+ &net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+ &bfin_sport0_uart_device,
+ &bfin_sport1_uart_device,
+#endif
+};
+
+static int __init stamp_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(stamp_init);
diff --git a/arch/blackfin/mach-bf533/cpu.c b/arch/blackfin/mach-bf533/cpu.c
new file mode 100644
index 0000000..99547c4
--- /dev/null
+++ b/arch/blackfin/mach-bf533/cpu.c
@@ -0,0 +1,161 @@
+/*
+ * File: arch/blackfin/mach-bf533/cpu.c
+ * Based on:
+ * Author: michael.kang@analog.com
+ *
+ * Created:
+ * Description: clock scaling for the bf533
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <asm/dpmc.h>
+#include <linux/fs.h>
+#include <asm/bfin-global.h>
+
+/* CONFIG_CLKIN_HZ=11059200 */
+#define VCO5 (CONFIG_CLKIN_HZ*45) /*497664000 */
+#define VCO4 (CONFIG_CLKIN_HZ*36) /*398131200 */
+#define VCO3 (CONFIG_CLKIN_HZ*27) /*298598400 */
+#define VCO2 (CONFIG_CLKIN_HZ*18) /*199065600 */
+#define VCO1 (CONFIG_CLKIN_HZ*9) /*99532800 */
+#define VCO(x) VCO##x
+
+#define FREQ(x) {VCO(x),VCO(x)/4},{VCO(x),VCO(x)/2},{VCO(x),VCO(x)}
+/* frequency */
+static struct cpufreq_frequency_table bf533_freq_table[] = {
+ FREQ(1),
+ FREQ(3),
+ {VCO4, VCO4 / 2}, {VCO4, VCO4},
+ FREQ(5),
+ {0, CPUFREQ_TABLE_END},
+};
+
+/*
+ * dpmc_fops->ioctl()
+ * static int dpmc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+ */
+static int bf533_getfreq(unsigned int cpu)
+{
+ unsigned long cclk_mhz, vco_mhz;
+
+ /* The driver only support single cpu */
+ if (cpu == 0)
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_GET_CORECLOCK, &cclk_mhz);
+ else
+ cclk_mhz = -1;
+ return cclk_mhz;
+}
+
+static int bf533_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ unsigned long cclk_mhz;
+ unsigned long vco_mhz;
+ unsigned long flags;
+ unsigned int index, vco_index;
+ int i;
+
+ struct cpufreq_freqs freqs;
+ if (cpufreq_frequency_table_target
+ (policy, bf533_freq_table, target_freq, relation, &index))
+ return -EINVAL;
+ cclk_mhz = bf533_freq_table[index].frequency;
+ vco_mhz = bf533_freq_table[index].index;
+
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_CHANGE_FREQUENCY, &vco_mhz);
+ freqs.old = bf533_getfreq(0);
+ freqs.new = cclk_mhz;
+ freqs.cpu = 0;
+
+ pr_debug("cclk begin change to cclk %d,vco=%d,index=%d,target=%d,oldfreq=%d\n",
+ cclk_mhz, vco_mhz, index, target_freq, freqs.old);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ local_irq_save(flags);
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_SET_CCLK, &cclk_mhz);
+ local_irq_restore(flags);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ vco_mhz = get_vco();
+ cclk_mhz = get_cclk();
+ return 0;
+}
+
+/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on
+ * this platform, anyway.
+ */
+static int bf533_verify_speed(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, &bf533_freq_table);
+}
+
+static int __init __bf533_cpu_init(struct cpufreq_policy *policy)
+{
+ int result;
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ /*Now ,only support one cpu */
+ policy->cur = bf533_getfreq(0);
+ cpufreq_frequency_table_get_attr(bf533_freq_table, policy->cpu);
+ return cpufreq_frequency_table_cpuinfo(policy, bf533_freq_table);
+}
+
+static struct freq_attr *bf533_freq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver bf533_driver = {
+ .verify = bf533_verify_speed,
+ .target = bf533_target,
+ .get = bf533_getfreq,
+ .init = __bf533_cpu_init,
+ .name = "bf533",
+ .owner = THIS_MODULE,
+ .attr = bf533_freq_attr,
+};
+
+static int __init bf533_cpu_init(void)
+{
+ return cpufreq_register_driver(&bf533_driver);
+}
+
+static void __exit bf533_cpu_exit(void)
+{
+ cpufreq_unregister_driver(&bf533_driver);
+}
+
+MODULE_AUTHOR("Mickael Kang");
+MODULE_DESCRIPTION("cpufreq driver for BF533 CPU");
+MODULE_LICENSE("GPL");
+
+module_init(bf533_cpu_init);
+module_exit(bf533_cpu_exit);
diff --git a/arch/blackfin/mach-bf533/head.S b/arch/blackfin/mach-bf533/head.S
new file mode 100644
index 0000000..4808edb
--- /dev/null
+++ b/arch/blackfin/mach-bf533/head.S
@@ -0,0 +1,774 @@
+/*
+ * File: arch/blackfin/mach-bf533/head.S
+ * Based on:
+ * Author: Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
+ *
+ * Created: 1998
+ * Description: bf533 startup file
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach/mem_init.h>
+#endif
+#if CONFIG_DEBUG_KERNEL_START
+#include <asm/mach-common/def_LPBlackfin.h>
+#endif
+
+.global __rambase
+.global __ramstart
+.global __ramend
+.extern ___bss_stop
+.extern ___bss_start
+.extern _bf53x_relocate_l1_mem
+
+#define INITIAL_STACK 0xFFB01000
+
+.text
+
+ENTRY(__start)
+ENTRY(__stext)
+ /* R0: argument of command line string, passed from uboot, save it */
+ R7 = R0;
+ /* Set the SYSCFG register */
+ R0 = 0x36;
+ /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
+ SYSCFG = R0;
+ R0 = 0;
+
+ /*Clear Out All the data and pointer Registers*/
+ R1 = R0;
+ R2 = R0;
+ R3 = R0;
+ R4 = R0;
+ R5 = R0;
+ R6 = R0;
+
+ P0 = R0;
+ P1 = R0;
+ P2 = R0;
+ P3 = R0;
+ P4 = R0;
+ P5 = R0;
+
+ LC0 = r0;
+ LC1 = r0;
+ L0 = r0;
+ L1 = r0;
+ L2 = r0;
+ L3 = r0;
+
+ /* Clear Out All the DAG Registers*/
+ B0 = r0;
+ B1 = r0;
+ B2 = r0;
+ B3 = r0;
+
+ I0 = r0;
+ I1 = r0;
+ I2 = r0;
+ I3 = r0;
+
+ M0 = r0;
+ M1 = r0;
+ M2 = r0;
+ M3 = r0;
+
+#if CONFIG_DEBUG_KERNEL_START
+
+/*
+ * Set up a temporary Event Vector Table, so if something bad happens before
+ * the kernel is fully started, it doesn't vector off into the bootloaders
+ * table
+ */
+ P0.l = lo(EVT2);
+ P0.h = hi(EVT2);
+ P1.l = lo(EVT15);
+ P1.h = hi(EVT15);
+ P2.l = debug_kernel_start_trap;
+ P2.h = debug_kernel_start_trap;
+
+ RTS = P2;
+ RTI = P2;
+ RTX = P2;
+ RTN = P2;
+ RTE = P2;
+
+.Lfill_temp_vector_table:
+ [P0++] = P2; /* Core Event Vector Table */
+ CC = P0 == P1;
+ if !CC JUMP .Lfill_temp_vector_table
+ P0 = r0;
+ P1 = r0;
+ P2 = r0;
+
+#endif
+
+ p0.h = hi(FIO_MASKA_C);
+ p0.l = lo(FIO_MASKA_C);
+ r0 = 0xFFFF(Z);
+ w[p0] = r0.L; /* Disable all interrupts */
+ ssync;
+
+ p0.h = hi(FIO_MASKB_C);
+ p0.l = lo(FIO_MASKB_C);
+ r0 = 0xFFFF(Z);
+ w[p0] = r0.L; /* Disable all interrupts */
+ ssync;
+
+ /* Turn off the icache */
+ p0.l = (IMEM_CONTROL & 0xFFFF);
+ p0.h = (IMEM_CONTROL >> 16);
+ R1 = [p0];
+ R0 = ~ENICPLB;
+ R0 = R0 & R1;
+
+ /* Anomaly 05000125 */
+#ifdef ANOMALY_05000125
+ CLI R2;
+ SSYNC;
+#endif
+ [p0] = R0;
+ SSYNC;
+#ifdef ANOMALY_05000125
+ STI R2;
+#endif
+
+ /* Turn off the dcache */
+ p0.l = (DMEM_CONTROL & 0xFFFF);
+ p0.h = (DMEM_CONTROL >> 16);
+ R1 = [p0];
+ R0 = ~ENDCPLB;
+ R0 = R0 & R1;
+
+ /* Anomaly 05000125 */
+#ifdef ANOMALY_05000125
+ CLI R2;
+ SSYNC;
+#endif
+ [p0] = R0;
+ SSYNC;
+#ifdef ANOMALY_05000125
+ STI R2;
+#endif
+
+ /* Initialise UART */
+ p0.h = hi(UART_LCR);
+ p0.l = lo(UART_LCR);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable DLL writes */
+ ssync;
+
+ p0.h = hi(UART_DLL);
+ p0.l = lo(UART_DLL);
+ r0 = 0x0(Z);
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART_DLH);
+ p0.l = lo(UART_DLH);
+ r0 = 0x00(Z);
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART_GCTL);
+ p0.l = lo(UART_GCTL);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable UART clock */
+ ssync;
+
+ /* Initialize stack pointer */
+ sp.l = lo(INITIAL_STACK);
+ sp.h = hi(INITIAL_STACK);
+ fp = sp;
+ usp = sp;
+
+ /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
+ call _bf53x_relocate_l1_mem;
+#if CONFIG_BFIN_KERNEL_CLOCK
+ call _start_dma_code;
+#endif
+
+ /* Code for initializing Async memory banks */
+
+ p2.h = hi(EBIU_AMBCTL1);
+ p2.l = lo(EBIU_AMBCTL1);
+ r0.h = hi(AMBCTL1VAL);
+ r0.l = lo(AMBCTL1VAL);
+ [p2] = r0;
+ ssync;
+
+ p2.h = hi(EBIU_AMBCTL0);
+ p2.l = lo(EBIU_AMBCTL0);
+ r0.h = hi(AMBCTL0VAL);
+ r0.l = lo(AMBCTL0VAL);
+ [p2] = r0;
+ ssync;
+
+ p2.h = hi(EBIU_AMGCTL);
+ p2.l = lo(EBIU_AMGCTL);
+ r0 = AMGCTLVAL;
+ w[p2] = r0;
+ ssync;
+
+ /* This section keeps the processor in supervisor mode
+ * during kernel boot. Switches to user mode at end of boot.
+ * See page 3-9 of Hardware Reference manual for documentation.
+ */
+
+ /* EVT15 = _real_start */
+
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _real_start;
+ p1.h = _real_start;
+ [p0] = p1;
+ csync;
+
+ p0.l = lo(IMASK);
+ p0.h = hi(IMASK);
+ p1.l = IMASK_IVG15;
+ p1.h = 0x0;
+ [p0] = p1;
+ csync;
+
+ raise 15;
+ p0.l = .LWAIT_HERE;
+ p0.h = .LWAIT_HERE;
+ reti = p0;
+#if defined(ANOMALY_05000281)
+ nop; nop; nop;
+#endif
+ rti;
+
+.LWAIT_HERE:
+ jump .LWAIT_HERE;
+
+ENTRY(_real_start)
+ [ -- sp ] = reti;
+ p0.l = lo(WDOG_CTL);
+ p0.h = hi(WDOG_CTL);
+ r0 = 0xAD6(z);
+ w[p0] = r0; /* watchdog off for now */
+ ssync;
+
+ /* Code update for BSS size == 0
+ * Zero out the bss region.
+ */
+
+ p1.l = ___bss_start;
+ p1.h = ___bss_start;
+ p2.l = ___bss_stop;
+ p2.h = ___bss_stop;
+ r0 = 0;
+ p2 -= p1;
+ lsetup (.L_clear_bss, .L_clear_bss) lc0 = p2;
+.L_clear_bss:
+ B[p1++] = r0;
+
+ /* In case there is a NULL pointer reference
+ * Zero out region before stext
+ */
+
+ p1.l = 0x0;
+ p1.h = 0x0;
+ r0.l = __stext;
+ r0.h = __stext;
+ r0 = r0 >> 1;
+ p2 = r0;
+ r0 = 0;
+ lsetup (.L_clear_zero, .L_clear_zero) lc0 = p2;
+.L_clear_zero:
+ W[p1++] = r0;
+
+/* pass the uboot arguments to the global value command line */
+ R0 = R7;
+ call _cmdline_init;
+
+ p1.l = __rambase;
+ p1.h = __rambase;
+ r0.l = __sdata;
+ r0.h = __sdata;
+ [p1] = r0;
+
+ p1.l = __ramstart;
+ p1.h = __ramstart;
+ p3.l = ___bss_stop;
+ p3.h = ___bss_stop;
+
+ r1 = p3;
+ [p1] = r1;
+
+ /*
+ * load the current thread pointer and stack
+ */
+ r1.l = _init_thread_union;
+ r1.h = _init_thread_union;
+
+ r2.l = 0x2000;
+ r2.h = 0x0000;
+ r1 = r1 + r2;
+ sp = r1;
+ usp = sp;
+ fp = sp;
+ call _start_kernel;
+.L_exit:
+ jump.s .L_exit;
+
+.section .l1.text
+#if CONFIG_BFIN_KERNEL_CLOCK
+ENTRY(_start_dma_code)
+ p0.h = hi(SIC_IWR);
+ p0.l = lo(SIC_IWR);
+ r0.l = 0x1;
+ r0.h = 0x0;
+ [p0] = r0;
+ SSYNC;
+
+ /*
+ * Set PLL_CTL
+ * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
+ * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK
+ * - [7] = output delay (add 200ps of delay to mem signals)
+ * - [6] = input delay (add 200ps of input delay to mem signals)
+ * - [5] = PDWN : 1=All Clocks off
+ * - [3] = STOPCK : 1=Core Clock off
+ * - [1] = PLL_OFF : 1=Disable Power to PLL
+ * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
+ * all other bits set to zero
+ */
+
+ p0.h = hi(PLL_LOCKCNT);
+ p0.l = lo(PLL_LOCKCNT);
+ r0 = 0x300(Z);
+ w[p0] = r0.l;
+ ssync;
+
+ P2.H = hi(EBIU_SDGCTL);
+ P2.L = lo(EBIU_SDGCTL);
+ R0 = [P2];
+ BITSET (R0, 24);
+ [P2] = R0;
+ SSYNC;
+
+ r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
+ r0 = r0 << 9; /* Shift it over, */
+ r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/
+ r0 = r1 | r0;
+ r1 = PLL_BYPASS; /* Bypass the PLL? */
+ r1 = r1 << 8; /* Shift it over */
+ r0 = r1 | r0; /* add them all together */
+
+ p0.h = hi(PLL_CTL);
+ p0.l = lo(PLL_CTL); /* Load the address */
+ cli r2; /* Disable interrupts */
+ ssync;
+ w[p0] = r0.l; /* Set the value */
+ idle; /* Wait for the PLL to stablize */
+ sti r2; /* Enable interrupts */
+
+.Lcheck_again:
+ p0.h = hi(PLL_STAT);
+ p0.l = lo(PLL_STAT);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,5);
+ if ! CC jump .Lcheck_again;
+
+ /* Configure SCLK & CCLK Dividers */
+ r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
+ p0.h = hi(PLL_DIV);
+ p0.l = lo(PLL_DIV);
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = lo(EBIU_SDRRC);
+ p0.h = hi(EBIU_SDRRC);
+ r0 = mem_SDRRC;
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = (EBIU_SDBCTL & 0xFFFF);
+ p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */
+ r0 = mem_SDBCTL;
+ w[p0] = r0.l;
+ ssync;
+
+ P2.H = hi(EBIU_SDGCTL);
+ P2.L = lo(EBIU_SDGCTL);
+ R0 = [P2];
+ BITCLR (R0, 24);
+ p0.h = hi(EBIU_SDSTAT);
+ p0.l = lo(EBIU_SDSTAT);
+ r2.l = w[p0];
+ cc = bittst(r2,3);
+ if !cc jump .Lskip;
+ NOP;
+ BITSET (R0, 23);
+.Lskip:
+ [P2] = R0;
+ SSYNC;
+
+ R0.L = lo(mem_SDGCTL);
+ R0.H = hi(mem_SDGCTL);
+ R1 = [p2];
+ R1 = R1 | R0;
+ [P2] = R1;
+ SSYNC;
+
+ p0.h = hi(SIC_IWR);
+ p0.l = lo(SIC_IWR);
+ r0.l = lo(IWR_ENABLE_ALL)
+ r0.h = hi(IWR_ENABLE_ALL)
+ [p0] = r0;
+ SSYNC;
+
+ RTS;
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+ENTRY(_bfin_reset)
+ /* No more interrupts to be handled*/
+ CLI R6;
+ SSYNC;
+
+#if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
+ p0.h = hi(FIO_INEN);
+ p0.l = lo(FIO_INEN);
+ r0.l = ~(1 << CONFIG_ENET_FLASH_PIN);
+ w[p0] = r0.l;
+
+ p0.h = hi(FIO_DIR);
+ p0.l = lo(FIO_DIR);
+ r0.l = (1 << CONFIG_ENET_FLASH_PIN);
+ w[p0] = r0.l;
+
+ p0.h = hi(FIO_FLAG_C);
+ p0.l = lo(FIO_FLAG_C);
+ r0.l = (1 << CONFIG_ENET_FLASH_PIN);
+ w[p0] = r0.l;
+#endif
+
+ /* Clear the bits 13-15 in SWRST if they werent cleared */
+ p0.h = hi(SWRST);
+ p0.l = lo(SWRST);
+ csync;
+ r0.l = w[p0];
+
+ /* Clear the IMASK register */
+ p0.h = hi(IMASK);
+ p0.l = lo(IMASK);
+ r0 = 0x0;
+ [p0] = r0;
+
+ /* Clear the ILAT register */
+ p0.h = hi(ILAT);
+ p0.l = lo(ILAT);
+ r0 = [p0];
+ [p0] = r0;
+ SSYNC;
+
+ /* Disable the WDOG TIMER */
+ p0.h = hi(WDOG_CTL);
+ p0.l = lo(WDOG_CTL);
+ r0.l = 0xAD6;
+ w[p0] = r0.l;
+ SSYNC;
+
+ /* Clear the sticky bit incase it is already set */
+ p0.h = hi(WDOG_CTL);
+ p0.l = lo(WDOG_CTL);
+ r0.l = 0x8AD6;
+ w[p0] = r0.l;
+ SSYNC;
+
+ /* Program the count value */
+ R0.l = 0x100;
+ R0.h = 0x0;
+ P0.h = hi(WDOG_CNT);
+ P0.l = lo(WDOG_CNT);
+ [P0] = R0;
+ SSYNC;
+
+ /* Program WDOG_STAT if necessary */
+ P0.h = hi(WDOG_CTL);
+ P0.l = lo(WDOG_CTL);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,1);
+ if !CC JUMP .LWRITESTAT;
+ CC = BITTST(R0,2);
+ if !CC JUMP .LWRITESTAT;
+ JUMP .LSKIP_WRITE;
+
+.LWRITESTAT:
+ /* When watch dog timer is enabled, a write to STAT will load the contents of CNT to STAT */
+ R0 = 0x0000(z);
+ P0.h = hi(WDOG_STAT);
+ P0.l = lo(WDOG_STAT)
+ [P0] = R0;
+ SSYNC;
+
+.LSKIP_WRITE:
+ /* Enable the reset event */
+ P0.h = hi(WDOG_CTL);
+ P0.l = lo(WDOG_CTL);
+ R0 = W[P0](Z);
+ BITCLR(R0,1);
+ BITCLR(R0,2);
+ W[P0] = R0.L;
+ SSYNC;
+ NOP;
+
+ /* Enable the wdog counter */
+ R0 = W[P0](Z);
+ BITCLR(R0,4);
+ W[P0] = R0.L;
+ SSYNC;
+
+ IDLE;
+
+ RTS;
+
+#if CONFIG_DEBUG_KERNEL_START
+debug_kernel_start_trap:
+ /* Set up a temp stack in L1 - SDRAM might not be working */
+ P0.L = lo(L1_DATA_A_START + 0x100);
+ P0.H = hi(L1_DATA_A_START + 0x100);
+ SP = P0;
+
+ /* Make sure the Clocks are the way I think they should be */
+ r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
+ r0 = r0 << 9; /* Shift it over, */
+ r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/
+ r0 = r1 | r0;
+ r1 = PLL_BYPASS; /* Bypass the PLL? */
+ r1 = r1 << 8; /* Shift it over */
+ r0 = r1 | r0; /* add them all together */
+
+ p0.h = hi(PLL_CTL);
+ p0.l = lo(PLL_CTL); /* Load the address */
+ cli r2; /* Disable interrupts */
+ ssync;
+ w[p0] = r0.l; /* Set the value */
+ idle; /* Wait for the PLL to stablize */
+ sti r2; /* Enable interrupts */
+
+.Lcheck_again1:
+ p0.h = hi(PLL_STAT);
+ p0.l = lo(PLL_STAT);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,5);
+ if ! CC jump .Lcheck_again1;
+
+ /* Configure SCLK & CCLK Dividers */
+ r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
+ p0.h = hi(PLL_DIV);
+ p0.l = lo(PLL_DIV);
+ w[p0] = r0.l;
+ ssync;
+
+ /* Make sure UART is enabled - you can never be sure */
+
+/*
+ * Setup for console. Argument comes from the menuconfig
+ */
+
+#ifdef CONFIG_BAUD_9600
+#define CONSOLE_BAUD_RATE 9600
+#elif CONFIG_BAUD_19200
+#define CONSOLE_BAUD_RATE 19200
+#elif CONFIG_BAUD_38400
+#define CONSOLE_BAUD_RATE 38400
+#elif CONFIG_BAUD_57600
+#define CONSOLE_BAUD_RATE 57600
+#elif CONFIG_BAUD_115200
+#define CONSOLE_BAUD_RATE 115200
+#endif
+
+ p0.h = hi(UART_GCTL);
+ p0.l = lo(UART_GCTL);
+ r0 = 0x00(Z);
+ w[p0] = r0.L; /* To Turn off UART clocks */
+ ssync;
+
+ p0.h = hi(UART_LCR);
+ p0.l = lo(UART_LCR);
+ r0 = 0x83(Z);
+ w[p0] = r0.L; /* To enable DLL writes */
+ ssync;
+
+ R1 = (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_SCLK_DIV) / (CONSOLE_BAUD_RATE * 16));
+
+ p0.h = hi(UART_DLL);
+ p0.l = lo(UART_DLL);
+ r0 = 0xFF(Z);
+ r0 = R1 & R0;
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART_DLH);
+ p0.l = lo(UART_DLH);
+ r1 >>= 8 ;
+ w[p0] = r1.L;
+ ssync;
+
+ p0.h = hi(UART_GCTL);
+ p0.l = lo(UART_GCTL);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable UART clock */
+ ssync;
+
+ p0.h = hi(UART_LCR);
+ p0.l = lo(UART_LCR);
+ r0 = 0x03(Z);
+ w[p0] = r0.L; /* To Turn on UART */
+ ssync;
+
+ p0.h = hi(UART_GCTL);
+ p0.l = lo(UART_GCTL);
+ r0 = 0x01(Z);
+ w[p0] = r0.L; /* To Turn on UART Clocks */
+ ssync;
+
+ P0.h = hi(UART_THR);
+ P0.l = lo(UART_THR);
+ P1.h = hi(UART_LSR);
+ P1.l = lo(UART_LSR);
+
+ R0.L = 'K';
+ call .Lwait_char;
+ R0.L='e';
+ call .Lwait_char;
+ R0.L='r';
+ call .Lwait_char;
+ R0.L='n'
+ call .Lwait_char;
+ R0.L='e'
+ call .Lwait_char;
+ R0.L='l';
+ call .Lwait_char;
+ R0.L=' ';
+ call .Lwait_char;
+ R0.L='c';
+ call .Lwait_char;
+ R0.L='r';
+ call .Lwait_char;
+ R0.L='a';
+ call .Lwait_char;
+ R0.L='s';
+ call .Lwait_char;
+ R0.L='h';
+ call .Lwait_char;
+ R0.L='\r';
+ call .Lwait_char;
+ R0.L='\n';
+ call .Lwait_char;
+
+ R0.L='S';
+ call .Lwait_char;
+ R0.L='E';
+ call .Lwait_char;
+ R0.L='Q'
+ call .Lwait_char;
+ R0.L='S'
+ call .Lwait_char;
+ R0.L='T';
+ call .Lwait_char;
+ R0.L='A';
+ call .Lwait_char;
+ R0.L='T';
+ call .Lwait_char;
+ R0.L='=';
+ call .Lwait_char;
+ R2 = SEQSTAT;
+ call .Ldump_reg;
+
+ R0.L=' ';
+ call .Lwait_char;
+ R0.L='R';
+ call .Lwait_char;
+ R0.L='E'
+ call .Lwait_char;
+ R0.L='T'
+ call .Lwait_char;
+ R0.L='X';
+ call .Lwait_char;
+ R0.L='=';
+ call .Lwait_char;
+ R2 = RETX;
+ call .Ldump_reg;
+
+ R0.L='\r';
+ call .Lwait_char;
+ R0.L='\n';
+ call .Lwait_char;
+
+.Ldebug_kernel_start_trap_done:
+ JUMP .Ldebug_kernel_start_trap_done;
+.Ldump_reg:
+ R3 = 32;
+ R4 = 0x0F;
+ R5 = ':'; /* one past 9 */
+
+.Ldump_reg2:
+ R0 = R2;
+ R3 += -4;
+ R0 >>>= R3;
+ R0 = R0 & R4;
+ R0 += 0x30;
+ CC = R0 <= R5;
+ if CC JUMP .Ldump_reg1;
+ R0 += 7;
+
+.Ldump_reg1:
+ R1.l = W[P1];
+ CC = BITTST(R1, 5);
+ if !CC JUMP .Ldump_reg1;
+ W[P0] = r0;
+
+ CC = R3 == 0;
+ if !CC JUMP .Ldump_reg2
+ RTS;
+
+.Lwait_char:
+ R1.l = W[P1];
+ CC = BITTST(R1, 5);
+ if !CC JUMP .Lwait_char;
+ W[P0] = r0;
+ RTS;
+
+#endif /* CONFIG_DEBUG_KERNEL_START */
+
+.data
+
+/*
+ * Set up the usable of RAM stuff. Size of RAM is determined then
+ * an initial stack set up at the end.
+ */
+
+.align 4
+__rambase:
+.long 0
+__ramstart:
+.long 0
+__ramend:
+.long 0
diff --git a/arch/blackfin/mach-bf533/ints-priority.c b/arch/blackfin/mach-bf533/ints-priority.c
new file mode 100644
index 0000000..36a6933
--- /dev/null
+++ b/arch/blackfin/mach-bf533/ints-priority.c
@@ -0,0 +1,65 @@
+/*
+ * File: arch/blackfin/mach-bf533/ints-priority.c
+ * Based on:
+ * Author: Michael Hennerich
+ *
+ * Created: ?
+ * Description: Set up the interupt priorities
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <asm/blackfin.h>
+#include <asm/irq.h>
+
+void program_IAR(void)
+{
+ /* Program the IAR0 Register with the configured priority */
+ bfin_write_SIC_IAR0(((CONFIG_PLLWAKE_ERROR - 7) << PLLWAKE_ERROR_POS) |
+ ((CONFIG_DMA_ERROR - 7) << DMA_ERROR_POS) |
+ ((CONFIG_PPI_ERROR - 7) << PPI_ERROR_POS) |
+ ((CONFIG_SPORT0_ERROR - 7) << SPORT0_ERROR_POS) |
+ ((CONFIG_SPI_ERROR - 7) << SPI_ERROR_POS) |
+ ((CONFIG_SPORT1_ERROR - 7) << SPORT1_ERROR_POS) |
+ ((CONFIG_UART_ERROR - 7) << UART_ERROR_POS) |
+ ((CONFIG_RTC_ERROR - 7) << RTC_ERROR_POS));
+
+ bfin_write_SIC_IAR1(((CONFIG_DMA0_PPI - 7) << DMA0_PPI_POS) |
+ ((CONFIG_DMA1_SPORT0RX - 7) << DMA1_SPORT0RX_POS) |
+ ((CONFIG_DMA2_SPORT0TX - 7) << DMA2_SPORT0TX_POS) |
+ ((CONFIG_DMA3_SPORT1RX - 7) << DMA3_SPORT1RX_POS) |
+ ((CONFIG_DMA4_SPORT1TX - 7) << DMA4_SPORT1TX_POS) |
+ ((CONFIG_DMA5_SPI - 7) << DMA5_SPI_POS) |
+ ((CONFIG_DMA6_UARTRX - 7) << DMA6_UARTRX_POS) |
+ ((CONFIG_DMA7_UARTTX - 7) << DMA7_UARTTX_POS));
+
+ bfin_write_SIC_IAR2(((CONFIG_TIMER0 - 7) << TIMER0_POS) |
+ ((CONFIG_TIMER1 - 7) << TIMER1_POS) |
+ ((CONFIG_TIMER2 - 7) << TIMER2_POS) |
+ ((CONFIG_PFA - 7) << PFA_POS) |
+ ((CONFIG_PFB - 7) << PFB_POS) |
+ ((CONFIG_MEMDMA0 - 7) << MEMDMA0_POS) |
+ ((CONFIG_MEMDMA1 - 7) << MEMDMA1_POS) |
+ ((CONFIG_WDTIMER - 7) << WDTIMER_POS));
+
+ SSYNC();
+}
diff --git a/arch/blackfin/mach-bf537/Kconfig b/arch/blackfin/mach-bf537/Kconfig
new file mode 100644
index 0000000..cc9ae38
--- /dev/null
+++ b/arch/blackfin/mach-bf537/Kconfig
@@ -0,0 +1,141 @@
+if (BF537 || BF534 || BF536)
+
+menu "BF537 Specific Configuration"
+
+comment "PORT F/G Selection"
+choice
+ prompt "Select BF537/6/4 default GPIO PFx PORTx"
+ help
+ Quick Hack for BF537/6/4 default GPIO PFx PORTF.
+
+config BF537_PORT_F
+ bool "Select BF537/6/4 default GPIO PFx PORTF"
+ depends on (BF537 || BF536 || BF534)
+ help
+ Quick Hack for BF537/6/4 default GPIO PFx PORTF.
+
+config BF537_PORT_G
+ bool "Select BF537/6/4 default GPIO PFx PORTG"
+ depends on (BF537 || BF536 || BF534)
+ help
+ Quick Hack for BF537/6/4 default GPIO PFx PORTG.
+
+config BF537_PORT_H
+ bool "Select BF537/6/4 default GPIO PFx PORTH"
+ depends on (BF537 || BF536 || BF534)
+ help
+ Quick Hack for BF537/6/4 default GPIO PFx PORTH
+ Use only when Blackfin EMAC support is not required.
+
+endchoice
+
+comment "Interrupt Priority Assignment"
+menu "Priority"
+
+config IRQ_PLL_WAKEUP
+ int "IRQ_PLL_WAKEUP"
+ default 7
+config IRQ_DMA_ERROR
+ int "IRQ_DMA_ERROR Generic"
+ default 7
+config IRQ_ERROR
+ int "IRQ_ERROR: CAN MAC SPORT0 SPORT1 SPI UART0 UART1"
+ default 7
+config IRQ_RTC
+ int "IRQ_RTC"
+ default 8
+config IRQ_PPI
+ int "IRQ_PPI"
+ default 8
+config IRQ_SPORT0_RX
+ int "IRQ_SPORT0_RX"
+ default 9
+config IRQ_SPORT0_TX
+ int "IRQ_SPORT0_TX"
+ default 9
+config IRQ_SPORT1_RX
+ int "IRQ_SPORT1_RX"
+ default 9
+config IRQ_SPORT1_TX
+ int "IRQ_SPORT1_TX"
+ default 9
+config IRQ_TWI
+ int "IRQ_TWI"
+ default 10
+config IRQ_SPI
+ int "IRQ_SPI"
+ default 10
+config IRQ_UART0_RX
+ int "IRQ_UART0_RX"
+ default 10
+config IRQ_UART0_TX
+ int "IRQ_UART0_TX"
+ default 10
+config IRQ_UART1_RX
+ int "IRQ_UART1_RX"
+ default 10
+config IRQ_UART1_TX
+ int "IRQ_UART1_TX"
+ default 10
+config IRQ_CAN_RX
+ int "IRQ_CAN_RX"
+ default 11
+config IRQ_CAN_TX
+ int "IRQ_CAN_TX"
+ default 11
+config IRQ_MAC_RX
+ int "IRQ_MAC_RX"
+ default 11
+config IRQ_MAC_TX
+ int "IRQ_MAC_TX"
+ default 11
+config IRQ_TMR0
+ int "IRQ_TMR0"
+ default 12
+config IRQ_TMR1
+ int "IRQ_TMR1"
+ default 12
+config IRQ_TMR2
+ int "IRQ_TMR2"
+ default 12
+config IRQ_TMR3
+ int "IRQ_TMR3"
+ default 12
+config IRQ_TMR4
+ int "IRQ_TMR4"
+ default 12
+config IRQ_TMR5
+ int "IRQ_TMR5"
+ default 12
+config IRQ_TMR6
+ int "IRQ_TMR6"
+ default 12
+config IRQ_TMR7
+ int "IRQ_TMR7"
+ default 12
+config IRQ_PROG_INTA
+ int "IRQ_PROG_INTA"
+ default 12
+config IRQ_PORTG_INTB
+ int "IRQ_PORTG_INTB"
+ default 12
+config IRQ_MEM_DMA0
+ int "IRQ_MEM_DMA0"
+ default 13
+config IRQ_MEM_DMA1
+ int "IRQ_MEM_DMA1"
+ default 13
+config IRQ_WATCH
+ int "IRQ_WATCH"
+ default 13
+
+ help
+ Enter the priority numbers between 7-13 ONLY. Others are Reserved.
+ This applies to all the above. It is not recommended to assign the
+ highest priority number 7 to UART or any other device.
+
+endmenu
+
+endmenu
+
+endif
diff --git a/arch/blackfin/mach-bf537/Makefile b/arch/blackfin/mach-bf537/Makefile
new file mode 100644
index 0000000..f32d442
--- /dev/null
+++ b/arch/blackfin/mach-bf537/Makefile
@@ -0,0 +1,9 @@
+#
+# arch/blackfin/mach-bf537/Makefile
+#
+
+extra-y := head.o
+
+obj-y := ints-priority.o
+
+obj-$(CONFIG_CPU_FREQ) += cpu.o
diff --git a/arch/blackfin/mach-bf537/boards/Makefile b/arch/blackfin/mach-bf537/boards/Makefile
new file mode 100644
index 0000000..23323ca
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/Makefile
@@ -0,0 +1,9 @@
+#
+# arch/blackfin/mach-bf537/boards/Makefile
+#
+
+obj-y += eth_mac.o
+obj-$(CONFIG_GENERIC_BOARD) += generic_board.o
+obj-$(CONFIG_BFIN537_STAMP) += stamp.o led.o
+obj-$(CONFIG_BFIN537_BLUETECHNIX_CM) += cm_bf537.o
+obj-$(CONFIG_PNAV10) += pnav10.o
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c
new file mode 100644
index 0000000..6a60618
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537.c
@@ -0,0 +1,364 @@
+/*
+ * File: arch/blackfin/mach-bf537/boards/cm_bf537.c
+ * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created: 2005
+ * Description: Board description file
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/usb_isp1362.h>
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "Bluetechnix CM BF537";
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+static struct bfin5xx_spi_chip spi_mmc_chip_info = {
+ .enable_dma = 1,
+ .bits_per_word = 8,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+ {
+ .modalias = "ad9960-spi",
+ .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .controller_data = &ad9960_spi_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+ {
+ .modalias = "spi_mmc_dummy",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 7,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+ {
+ .modalias = "spi_mmc",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SPI_MMC_CS_CHAN,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .start = 0x20200300,
+ .end = 0x20200300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF14,
+ .end = IRQ_PF14,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+ {
+ .start = 0x20308000,
+ .end = 0x20308000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20308004,
+ .end = 0x20308004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PG15,
+ .end = IRQ_PG15,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+ .sel15Kres = 1,
+ .clknotstop = 0,
+ .oc_enable = 0,
+ .int_act_high = 0,
+ .int_edge_triggered = 0,
+ .remote_wakeup_connected = 0,
+ .no_power_switching = 1,
+ .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+ .name = "isp1362-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &isp1362_priv,
+ },
+ .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+ .resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+ {
+ .start = 0x20200000,
+ .end = 0x20200000 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device net2272_bfin_device = {
+ .name = "net2272",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+ .resource = net2272_bfin_resources,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0xFFC02000,
+ .end = 0xFFC020FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mac_device = {
+ .name = "bfin_mac",
+};
+#endif
+
+static struct platform_device *cm_bf537_devices[] __initdata = {
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+ &bfin_sport0_uart_device,
+ &bfin_sport1_uart_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+ &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+ &net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+};
+
+static int __init cm_bf537_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(cm_bf537_devices, ARRAY_SIZE(cm_bf537_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(cm_bf537_init);
diff --git a/arch/blackfin/mach-bf537/boards/eth_mac.c b/arch/blackfin/mach-bf537/boards/eth_mac.c
new file mode 100644
index 0000000..e129a08
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/eth_mac.c
@@ -0,0 +1,51 @@
+/*
+ * arch/blackfin/mach-bf537/board/eth_mac.c
+ *
+ * Copyright (C) 2007 Analog Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/module.h>
+#include <asm/blackfin.h>
+
+#if defined(CONFIG_GENERIC_BOARD) \
+ || defined(CONFIG_BFIN537_STAMP)
+
+/*
+ * Currently the MAC address is saved in Flash by U-Boot
+ */
+#define FLASH_MAC 0x203f0000
+
+void get_bf537_ether_addr(char *addr)
+{
+ unsigned int flash_mac = (unsigned int) FLASH_MAC;
+ *(u32 *)(&(addr[0])) = bfin_read32(flash_mac);
+ flash_mac += 4;
+ *(u16 *)(&(addr[4])) = bfin_read16(flash_mac);
+}
+
+#else
+
+/*
+ * Provide MAC address function for other specific board setting
+ */
+void get_bf537_ether_addr(char *addr)
+{
+ printk(KERN_WARNING "%s: No valid Ethernet MAC address found\n",__FILE__);
+}
+
+#endif
+
+EXPORT_SYMBOL(get_bf537_ether_addr);
diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c
new file mode 100644
index 0000000..9019c0e
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/generic_board.c
@@ -0,0 +1,445 @@
+/*
+ * File: arch/blackfin/mach-bf537/boards/generic_board.c
+ * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/usb_isp1362.h>
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+#include <linux/usb_sl811.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "UNKNOWN BOARD";
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+static struct resource bfin_pcmcia_cf_resources[] = {
+ {
+ .start = 0x20310000, /* IO PORT */
+ .end = 0x20312000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20311000, /* Attribute Memeory */
+ .end = 0x20311FFF,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PROG_INTA,
+ .end = IRQ_PROG_INTA,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },{
+ .start = IRQ_PF4,
+ .end = IRQ_PF4,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },{
+ .start = 6, /* Card Detect PF6 */
+ .end = 6,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_pcmcia_cf_device = {
+ .name = "bfin_cf_pcmcia",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources),
+ .resource = bfin_pcmcia_cf_resources,
+};
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x20300300,
+ .end = 0x20300300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PROG_INTB,
+ .end = IRQ_PROG_INTB,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },{
+ /*
+ * denotes the flag pin and is used directly if
+ * CONFIG_IRQCHIP_DEMUX_GPIO is defined.
+ */
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+static struct resource sl811_hcd_resources[] = {
+ {
+ .start = 0x20340000,
+ .end = 0x20340000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20340004,
+ .end = 0x20340004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PROG_INTA,
+ .end = IRQ_PROG_INTA,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },{
+ .start = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO,
+ .end = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+void sl811_port_power(struct device *dev, int is_on)
+{
+ unsigned short mask = (1<<CONFIG_USB_SL811_BFIN_GPIO_VBUS);
+
+ bfin_write_PORT_FER(bfin_read_PORT_FER() & ~mask);
+ bfin_write_FIO_DIR(bfin_read_FIO_DIR() | mask);
+
+ if (is_on)
+ bfin_write_FIO_FLAG_S(mask);
+ else
+ bfin_write_FIO_FLAG_C(mask);
+}
+#endif
+
+static struct sl811_platform_data sl811_priv = {
+ .potpg = 10,
+ .power = 250, /* == 500mA */
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+ .port_power = &sl811_port_power,
+#endif
+};
+
+static struct platform_device sl811_hcd_device = {
+ .name = "sl811-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &sl811_priv,
+ },
+ .num_resources = ARRAY_SIZE(sl811_hcd_resources),
+ .resource = sl811_hcd_resources,
+};
+
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+ {
+ .start = 0x20360000,
+ .end = 0x20360000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20360004,
+ .end = 0x20360004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PROG_INTA,
+ .end = IRQ_PROG_INTA,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },{
+ .start = IRQ_PF0 + CONFIG_USB_ISP1362_BFIN_GPIO,
+ .end = IRQ_PF0 + CONFIG_USB_ISP1362_BFIN_GPIO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+ .sel15Kres = 1,
+ .clknotstop = 0,
+ .oc_enable = 0,
+ .int_act_high = 0,
+ .int_edge_triggered = 0,
+ .remote_wakeup_connected = 0,
+ .no_power_switching = 1,
+ .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+ .name = "isp1362-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &isp1362_priv,
+ },
+ .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+ .resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mac_device = {
+ .name = "bfin_mac",
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+ {
+ .start = 0x20300000,
+ .end = 0x20300000 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device net2272_bfin_device = {
+ .name = "net2272",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+ .resource = net2272_bfin_resources,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+ || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 2, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+ {
+ .modalias = "ad9960-spi",
+ .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .controller_data = &ad9960_spi_chip_info,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+static struct platform_device bfin_fb_device = {
+ .name = "bf537-fb",
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0xFFC02000,
+ .end = 0xFFC020FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+static struct platform_device *stamp_devices[] __initdata = {
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+ &bfin_pcmcia_cf_device,
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+ &sl811_hcd_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+ &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+ &net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+ &bfin_fb_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+};
+
+static int __init stamp_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(stamp_init);
diff --git a/arch/blackfin/mach-bf537/boards/led.S b/arch/blackfin/mach-bf537/boards/led.S
new file mode 100644
index 0000000..4e9ea42
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/led.S
@@ -0,0 +1,183 @@
+/****************************************************
+ * LED1 ---- PF6 LED2 ---- PF7 *
+ * LED3 ---- PF8 LED4 ---- PF9 *
+ * LED5 ---- PF10 LED6 ---- PF11 *
+ ****************************************************/
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+
+/* All functions in this file save the registers they uses.
+ So there is no need to save any registers before calling them. */
+
+ .text;
+
+/* Initialize LEDs. */
+
+ENTRY(_led_init)
+ LINK 12;
+ [--SP] = P0;
+ [--SP] = R0;
+ [--SP] = R1;
+ [--SP] = R2;
+ R1 = PF6|PF7|PF8|PF9|PF10|PF11 (Z);
+ R2 = ~R1;
+
+ P0.H = hi(PORTF_FER);
+ P0.L = lo(PORTF_FER);
+ R0 = W[P0](Z);
+ SSYNC;
+ R0 = R0 & R2;
+ W[P0] = R0.L;
+ SSYNC;
+
+ P0.H = hi(PORTFIO_DIR);
+ P0.L = lo(PORTFIO_DIR);
+ R0 = W[P0](Z);
+ SSYNC;
+ R0 = R0 | R1;
+ W[P0] = R0.L;
+ SSYNC;
+
+ P0.H = hi(PORTFIO_INEN);
+ P0.L = lo(PORTFIO_INEN);
+ R0 = W[P0](Z);
+ SSYNC;
+ R0 = R0 & R2;
+ W[P0] = R0.L;
+ SSYNC;
+
+ R2 = [SP++];
+ R1 = [SP++];
+ R0 = [SP++];
+ P0 = [SP++];
+ UNLINK;
+ RTS;
+ .size _led_init, .-_led_init
+
+/* Set one LED on. Leave other LEDs unchanged.
+ It expects the LED number passed through R0. */
+
+ENTRY(_led_on)
+ LINK 12;
+ [--SP] = P0;
+ [--SP] = R1;
+ CALL _led_init;
+ R1 = 1;
+ R0 += 5;
+ R1 <<= R0;
+ P0.H = hi(PORTFIO);
+ P0.L = lo(PORTFIO);
+ R0 = W[P0](Z);
+ SSYNC;
+ R0 = R0 | R1;
+ W[P0] = R0.L;
+ SSYNC;
+ R1 = [SP++];
+ P0 = [SP++];
+ UNLINK;
+ RTS;
+ .size _led_on, .-_led_on
+
+/* Set one LED off. Leave other LEDs unchanged. */
+
+ENTRY(_led_off)
+ LINK 12;
+ [--SP] = P0;
+ [--SP] = R1;
+ CALL _led_init;
+ R1 = 1;
+ R0 += 5;
+ R1 <<= R0;
+ R1 = ~R1;
+ P0.H = hi(PORTFIO);
+ P0.L = lo(PORTFIO);
+ R0 = W[P0](Z);
+ SSYNC;
+ R0 = R0 & R1;
+ W[P0] = R0.L;
+ SSYNC;
+ R1 = [SP++];
+ P0 = [SP++];
+ UNLINK;
+ RTS;
+ .size _led_off, .-_led_off
+
+/* Toggle one LED. Leave other LEDs unchanged. */
+
+ENTRY(_led_toggle)
+ LINK 12;
+ [--SP] = P0;
+ [--SP] = R1;
+ CALL _led_init;
+ R1 = 1;
+ R0 += 5;
+ R1 <<= R0;
+ P0.H = hi(PORTFIO);
+ P0.L = lo(PORTFIO);
+ R0 = W[P0](Z);
+ SSYNC;
+ R0 = R0 ^ R1;
+ W[P0] = R0.L;
+ SSYNC;
+ R1 = [SP++];
+ P0 = [SP++];
+ UNLINK;
+ RTS;
+ .size _led_toggle, .-_led_toggle
+
+/* Display the number using LEDs in binary format. */
+
+ENTRY(_led_disp_num)
+ LINK 12;
+ [--SP] = P0;
+ [--SP] = R1;
+ [--SP] = R2;
+ CALL _led_init;
+ R1 = 0x3f(X);
+ R0 = R0 & R1;
+ R2 = 6(X);
+ R0 <<= R2;
+ R1 <<= R2;
+ P0.H = hi(PORTFIO);
+ P0.L = lo(PORTFIO);
+ R2 = W[P0](Z);
+ SSYNC;
+ R1 = ~R1;
+ R2 = R2 & R1;
+ R2 = R2 | R0;
+ W[P0] = R2.L;
+ SSYNC;
+ R2 = [SP++];
+ R1 = [SP++];
+ P0 = [SP++];
+ UNLINK;
+ RTS;
+ .size _led_disp_num, .-_led_disp_num
+
+/* Toggle the number using LEDs in binary format. */
+
+ENTRY(_led_toggle_num)
+ LINK 12;
+ [--SP] = P0;
+ [--SP] = R1;
+ [--SP] = R2;
+ CALL _led_init;
+ R1 = 0x3f(X);
+ R0 = R0 & R1;
+ R1 = 6(X);
+ R0 <<= R1;
+ P0.H = hi(PORTFIO);
+ P0.L = lo(PORTFIO);
+ R1 = W[P0](Z);
+ SSYNC;
+ R1 = R1 ^ R0;
+ W[P0] = R1.L;
+ SSYNC;
+ R2 = [SP++];
+ R1 = [SP++];
+ P0 = [SP++];
+ UNLINK;
+ RTS;
+ .size _led_toggle_num, .-_led_toggle_num
+
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
new file mode 100644
index 0000000..40d3a1b
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -0,0 +1,523 @@
+/*
+ * File: arch/blackfin/mach-bf537/boards/stamp.c
+ * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+#include <linux/usb_isp1362.h>
+#endif
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+#include <linux/usb_sl811.h>
+
+#include <linux/spi/ad7877.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "PNAV-1.0";
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+static struct resource bfin_pcmcia_cf_resources[] = {
+ {
+ .start = 0x20310000, /* IO PORT */
+ .end = 0x20312000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20311000, /* Attribute Memeory */
+ .end = 0x20311FFF,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF4,
+ .end = IRQ_PF4,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },{
+ .start = 6, /* Card Detect PF6 */
+ .end = 6,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_pcmcia_cf_device = {
+ .name = "bfin_cf_pcmcia",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources),
+ .resource = bfin_pcmcia_cf_resources,
+};
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x20300300,
+ .end = 0x20300300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+static struct resource sl811_hcd_resources[] = {
+ {
+ .start = 0x20340000,
+ .end = 0x20340000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20340004,
+ .end = 0x20340004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = CONFIG_USB_SL811_BFIN_IRQ,
+ .end = CONFIG_USB_SL811_BFIN_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+void sl811_port_power(struct device *dev, int is_on)
+{
+ unsigned short mask = (1 << CONFIG_USB_SL811_BFIN_GPIO_VBUS);
+
+ bfin_write_PORT_FER(bfin_read_PORT_FER() & ~mask);
+ bfin_write_FIO_DIR(bfin_read_FIO_DIR() | mask);
+
+ if (is_on)
+ bfin_write_FIO_FLAG_S(mask);
+ else
+ bfin_write_FIO_FLAG_C(mask);
+}
+#endif
+
+static struct sl811_platform_data sl811_priv = {
+ .potpg = 10,
+ .power = 250, /* == 500mA */
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+ .port_power = &sl811_port_power,
+#endif
+};
+
+static struct platform_device sl811_hcd_device = {
+ .name = "sl811-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &sl811_priv,
+ },
+ .num_resources = ARRAY_SIZE(sl811_hcd_resources),
+ .resource = sl811_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+ {
+ .start = 0x20360000,
+ .end = 0x20360000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20360004,
+ .end = 0x20360004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
+ .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+ .sel15Kres = 1,
+ .clknotstop = 0,
+ .oc_enable = 0,
+ .int_act_high = 0,
+ .int_edge_triggered = 0,
+ .remote_wakeup_connected = 0,
+ .no_power_switching = 1,
+ .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+ .name = "isp1362-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &isp1362_priv,
+ },
+ .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+ .resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mac_device = {
+ .name = "bfin_mac",
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+ {
+ .start = 0x20300000,
+ .end = 0x20300000 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device net2272_bfin_device = {
+ .name = "net2272",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+ .resource = net2272_bfin_resources,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+ || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+static struct bfin5xx_spi_chip spi_mmc_chip_info = {
+ .enable_dma = 1,
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_PBX)
+static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
+ .ctl_reg = 0x4, /* send zero */
+ .enable_dma = 0,
+ .bits_per_word = 8,
+ .cs_change_per_word = 1,
+};
+#endif
+
+
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
+ .cs_change_per_word = 1,
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+
+static const struct ad7877_platform_data bfin_ad7877_ts_info = {
+ .model = 7877,
+ .vref_delay_usecs = 50, /* internal, no capacitor */
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .pressure_max = 1000,
+ .pressure_min = 0,
+ .stopacq_polarity = 1,
+ .first_conversion_delay = 3,
+ .acquisition_time = 1,
+ .averaging = 1,
+ .pen_down_acc_interval = 1,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+ || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+ {
+ .modalias = "ad9960-spi",
+ .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .controller_data = &ad9960_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+ {
+ .modalias = "spi_mmc_dummy",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 7,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+ {
+ .modalias = "spi_mmc",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SPI_MMC_CS_CHAN,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_PBX)
+ {
+ .modalias = "fxs-spi",
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 3,
+ .controller_data= &spi_si3xxx_chip_info,
+ .mode = SPI_MODE_3,
+ },
+ {
+ .modalias = "fxo-spi",
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 2,
+ .controller_data= &spi_si3xxx_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+{
+ .modalias = "ad7877",
+ .platform_data = &bfin_ad7877_ts_info,
+ .irq = IRQ_PF2,
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 5,
+ .controller_data = &spi_ad7877_chip_info,
+},
+#endif
+
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+static struct platform_device bfin_fb_device = {
+ .name = "bf537-fb",
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0xFFC02000,
+ .end = 0xFFC020FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+
+static struct platform_device *stamp_devices[] __initdata = {
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+ &bfin_pcmcia_cf_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+ &sl811_hcd_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+ &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+ &net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+ &bfin_fb_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+};
+
+static int __init stamp_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info,
+ ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(stamp_init);
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
new file mode 100644
index 0000000..ba2f875
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -0,0 +1,615 @@
+/*
+ * File: arch/blackfin/mach-bf537/boards/stamp.c
+ * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+#include <linux/usb_isp1362.h>
+#endif
+#include <asm/irq.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/bfin5xx_spi.h>
+#include <linux/usb_sl811.h>
+
+#include <linux/spi/ad7877.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "ADDS-BF537-STAMP";
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+
+#define ISP1761_BASE 0x203C0000
+#define ISP1761_IRQ IRQ_PF7
+
+#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
+static struct resource bfin_isp1761_resources[] = {
+ [0] = {
+ .name = "isp1761-regs",
+ .start = ISP1761_BASE + 0x00000000,
+ .end = ISP1761_BASE + 0x000fffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = ISP1761_IRQ,
+ .end = ISP1761_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_isp1761_device = {
+ .name = "isp1761",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_isp1761_resources),
+ .resource = bfin_isp1761_resources,
+};
+
+static struct platform_device *bfin_isp1761_devices[] = {
+ &bfin_isp1761_device,
+};
+
+int __init bfin_isp1761_init(void)
+{
+ unsigned int num_devices=ARRAY_SIZE(bfin_isp1761_devices);
+
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING);
+
+ return platform_add_devices(bfin_isp1761_devices, num_devices);
+}
+
+void __exit bfin_isp1761_exit(void)
+{
+ platform_device_unregister(&bfin_isp1761_device);
+}
+
+arch_initcall(bfin_isp1761_init);
+#endif
+
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+static struct resource bfin_pcmcia_cf_resources[] = {
+ {
+ .start = 0x20310000, /* IO PORT */
+ .end = 0x20312000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20311000, /* Attribute Memeory */
+ .end = 0x20311FFF,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF4,
+ .end = IRQ_PF4,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },{
+ .start = 6, /* Card Detect PF6 */
+ .end = 6,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_pcmcia_cf_device = {
+ .name = "bfin_cf_pcmcia",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources),
+ .resource = bfin_pcmcia_cf_resources,
+};
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x20300300,
+ .end = 0x20300300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+static struct resource sl811_hcd_resources[] = {
+ {
+ .start = 0x20340000,
+ .end = 0x20340000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20340004,
+ .end = 0x20340004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = CONFIG_USB_SL811_BFIN_IRQ,
+ .end = CONFIG_USB_SL811_BFIN_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+void sl811_port_power(struct device *dev, int is_on)
+{
+ unsigned short mask = (1 << CONFIG_USB_SL811_BFIN_GPIO_VBUS);
+
+ bfin_write_PORT_FER(bfin_read_PORT_FER() & ~mask);
+ bfin_write_FIO_DIR(bfin_read_FIO_DIR() | mask);
+
+ if (is_on)
+ bfin_write_FIO_FLAG_S(mask);
+ else
+ bfin_write_FIO_FLAG_C(mask);
+}
+#endif
+
+static struct sl811_platform_data sl811_priv = {
+ .potpg = 10,
+ .power = 250, /* == 500mA */
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+ .port_power = &sl811_port_power,
+#endif
+};
+
+static struct platform_device sl811_hcd_device = {
+ .name = "sl811-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &sl811_priv,
+ },
+ .num_resources = ARRAY_SIZE(sl811_hcd_resources),
+ .resource = sl811_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+ {
+ .start = 0x20360000,
+ .end = 0x20360000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x20360004,
+ .end = 0x20360004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
+ .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+ .sel15Kres = 1,
+ .clknotstop = 0,
+ .oc_enable = 0,
+ .int_act_high = 0,
+ .int_edge_triggered = 0,
+ .remote_wakeup_connected = 0,
+ .no_power_switching = 1,
+ .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+ .name = "isp1362-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &isp1362_priv,
+ },
+ .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+ .resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mac_device = {
+ .name = "bfin_mac",
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+ {
+ .start = 0x20300000,
+ .end = 0x20300000 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device net2272_bfin_device = {
+ .name = "net2272",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+ .resource = net2272_bfin_resources,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+ || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+static struct bfin5xx_spi_chip spi_mmc_chip_info = {
+ .enable_dma = 1,
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_PBX)
+static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
+ .ctl_reg = 0x4, /* send zero */
+ .enable_dma = 0,
+ .bits_per_word = 8,
+ .cs_change_per_word = 1,
+};
+#endif
+
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+static struct bfin5xx_spi_chip ad5304_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
+// .cs_change_per_word = 1,
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+
+static const struct ad7877_platform_data bfin_ad7877_ts_info = {
+ .model = 7877,
+ .vref_delay_usecs = 50, /* internal, no capacitor */
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .pressure_max = 1000,
+ .pressure_min = 0,
+ .stopacq_polarity = 1,
+ .first_conversion_delay = 3,
+ .acquisition_time = 1,
+ .averaging = 1,
+ .pen_down_acc_interval = 1,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+ || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+ {
+ .modalias = "ad9960-spi",
+ .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .controller_data = &ad9960_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+ {
+ .modalias = "spi_mmc_dummy",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 0,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+ {
+ .modalias = "spi_mmc",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SPI_MMC_CS_CHAN,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_PBX)
+ {
+ .modalias = "fxs-spi",
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 3,
+ .controller_data= &spi_si3xxx_chip_info,
+ .mode = SPI_MODE_3,
+ },
+ {
+ .modalias = "fxo-spi",
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 2,
+ .controller_data= &spi_si3xxx_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+ {
+ .modalias = "ad5304_spi",
+ .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 2,
+ .platform_data = NULL,
+ .controller_data = &ad5304_chip_info,
+ .mode = SPI_MODE_2,
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+ {
+ .modalias = "ad7877",
+ .platform_data = &bfin_ad7877_ts_info,
+ .irq = IRQ_PF6,
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .controller_data = &spi_ad7877_chip_info,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+static struct platform_device bfin_fb_device = {
+ .name = "bf537-fb",
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0xFFC02000,
+ .end = 0xFFC020FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct platform_device i2c_bfin_twi_device = {
+ .name = "i2c-bfin-twi",
+ .id = 0,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+};
+#endif
+
+static struct platform_device *stamp_devices[] __initdata = {
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+ &bfin_pcmcia_cf_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+ &sl811_hcd_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+ &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+ &net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+ &bfin_fb_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+ &i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+ &bfin_sport0_uart_device,
+ &bfin_sport1_uart_device,
+#endif
+};
+
+static int __init stamp_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info,
+ ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(stamp_init);
diff --git a/arch/blackfin/mach-bf537/cpu.c b/arch/blackfin/mach-bf537/cpu.c
new file mode 100644
index 0000000..2d83b7e
--- /dev/null
+++ b/arch/blackfin/mach-bf537/cpu.c
@@ -0,0 +1,161 @@
+/*
+ * File: arch/blackfin/mach-bf537/cpu.c
+ * Based on:
+ * Author: michael.kang@analog.com
+ *
+ * Created:
+ * Description: clock scaling for the bf537
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <asm/dpmc.h>
+#include <linux/fs.h>
+#include <asm/bfin-global.h>
+
+/* CONFIG_CLKIN_HZ=11059200 */
+#define VCO5 (CONFIG_CLKIN_HZ*45) /*497664000 */
+#define VCO4 (CONFIG_CLKIN_HZ*36) /*398131200 */
+#define VCO3 (CONFIG_CLKIN_HZ*27) /*298598400 */
+#define VCO2 (CONFIG_CLKIN_HZ*18) /*199065600 */
+#define VCO1 (CONFIG_CLKIN_HZ*9) /*99532800 */
+#define VCO(x) VCO##x
+
+#define FREQ(x) {VCO(x),VCO(x)/4},{VCO(x),VCO(x)/2},{VCO(x),VCO(x)}
+/* frequency */
+static struct cpufreq_frequency_table bf537_freq_table[] = {
+ FREQ(1),
+ FREQ(3),
+ {VCO4, VCO4 / 2}, {VCO4, VCO4},
+ FREQ(5),
+ {0, CPUFREQ_TABLE_END},
+};
+
+/*
+ * dpmc_fops->ioctl()
+ * static int dpmc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+ */
+static int bf537_getfreq(unsigned int cpu)
+{
+ unsigned long cclk_mhz, vco_mhz;
+
+ /* The driver only support single cpu */
+ if (cpu == 0)
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_GET_CORECLOCK, &cclk_mhz);
+ else
+ cclk_mhz = -1;
+ return cclk_mhz;
+}
+
+static int bf537_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ unsigned long cclk_mhz;
+ unsigned long vco_mhz;
+ unsigned long flags;
+ unsigned int index, vco_index;
+ int i;
+
+ struct cpufreq_freqs freqs;
+ if (cpufreq_frequency_table_target
+ (policy, bf537_freq_table, target_freq, relation, &index))
+ return -EINVAL;
+ cclk_mhz = bf537_freq_table[index].frequency;
+ vco_mhz = bf537_freq_table[index].index;
+
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_CHANGE_FREQUENCY, &vco_mhz);
+ freqs.old = bf537_getfreq(0);
+ freqs.new = cclk_mhz;
+ freqs.cpu = 0;
+
+ pr_debug("cclk begin change to cclk %d,vco=%d,index=%d,target=%d,oldfreq=%d\n",
+ cclk_mhz, vco_mhz, index, target_freq, freqs.old);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ local_irq_save(flags);
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_SET_CCLK, &cclk_mhz);
+ local_irq_restore(flags);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ vco_mhz = get_vco();
+ cclk_mhz = get_cclk();
+ return 0;
+}
+
+/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on
+ * this platform, anyway.
+ */
+static int bf537_verify_speed(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, &bf537_freq_table);
+}
+
+static int __init __bf537_cpu_init(struct cpufreq_policy *policy)
+{
+ int result;
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ /*Now ,only support one cpu */
+ policy->cur = bf537_getfreq(0);
+ cpufreq_frequency_table_get_attr(bf537_freq_table, policy->cpu);
+ return cpufreq_frequency_table_cpuinfo(policy, bf537_freq_table);
+}
+
+static struct freq_attr *bf537_freq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver bf537_driver = {
+ .verify = bf537_verify_speed,
+ .target = bf537_target,
+ .get = bf537_getfreq,
+ .init = __bf537_cpu_init,
+ .name = "bf537",
+ .owner = THIS_MODULE,
+ .attr = bf537_freq_attr,
+};
+
+static int __init bf537_cpu_init(void)
+{
+ return cpufreq_register_driver(&bf537_driver);
+}
+
+static void __exit bf537_cpu_exit(void)
+{
+ cpufreq_unregister_driver(&bf537_driver);
+}
+
+MODULE_AUTHOR("Mickael Kang");
+MODULE_DESCRIPTION("cpufreq driver for BF537 CPU");
+MODULE_LICENSE("GPL");
+
+module_init(bf537_cpu_init);
+module_exit(bf537_cpu_exit);
diff --git a/arch/blackfin/mach-bf537/head.S b/arch/blackfin/mach-bf537/head.S
new file mode 100644
index 0000000..d104e1d8
--- /dev/null
+++ b/arch/blackfin/mach-bf537/head.S
@@ -0,0 +1,602 @@
+/*
+ * File: arch/blackfin/mach-bf537/head.S
+ * Based on: arch/blackfin/mach-bf533/head.S
+ * Author: Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
+ *
+ * Created: 1998
+ * Description: Startup code for Blackfin BF537
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach/mem_init.h>
+#endif
+
+.global __rambase
+.global __ramstart
+.global __ramend
+.extern ___bss_stop
+.extern ___bss_start
+.extern _bf53x_relocate_l1_mem
+
+#define INITIAL_STACK 0xFFB01000
+
+.text
+
+ENTRY(__start)
+ENTRY(__stext)
+ /* R0: argument of command line string, passed from uboot, save it */
+ R7 = R0;
+ /* Set the SYSCFG register */
+ R0 = 0x36;
+ SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
+ R0 = 0;
+
+ /* Clear Out All the data and pointer Registers*/
+ R1 = R0;
+ R2 = R0;
+ R3 = R0;
+ R4 = R0;
+ R5 = R0;
+ R6 = R0;
+
+ P0 = R0;
+ P1 = R0;
+ P2 = R0;
+ P3 = R0;
+ P4 = R0;
+ P5 = R0;
+
+ LC0 = r0;
+ LC1 = r0;
+ L0 = r0;
+ L1 = r0;
+ L2 = r0;
+ L3 = r0;
+
+ /* Clear Out All the DAG Registers*/
+ B0 = r0;
+ B1 = r0;
+ B2 = r0;
+ B3 = r0;
+
+ I0 = r0;
+ I1 = r0;
+ I2 = r0;
+ I3 = r0;
+
+ M0 = r0;
+ M1 = r0;
+ M2 = r0;
+ M3 = r0;
+
+ /* Turn off the icache */
+ p0.l = (IMEM_CONTROL & 0xFFFF);
+ p0.h = (IMEM_CONTROL >> 16);
+ R1 = [p0];
+ R0 = ~ENICPLB;
+ R0 = R0 & R1;
+
+ /* Anomaly 05000125 */
+#ifdef ANOMALY_05000125
+ CLI R2;
+ SSYNC;
+#endif
+ [p0] = R0;
+ SSYNC;
+#ifdef ANOMALY_05000125
+ STI R2;
+#endif
+
+ /* Turn off the dcache */
+ p0.l = (DMEM_CONTROL & 0xFFFF);
+ p0.h = (DMEM_CONTROL >> 16);
+ R1 = [p0];
+ R0 = ~ENDCPLB;
+ R0 = R0 & R1;
+
+ /* Anomaly 05000125 */
+#ifdef ANOMALY_05000125
+ CLI R2;
+ SSYNC;
+#endif
+ [p0] = R0;
+ SSYNC;
+#ifdef ANOMALY_05000125
+ STI R2;
+#endif
+
+ /* Initialise General-Purpose I/O Modules on BF537 */
+ /* Rev 0.0 Anomaly 05000212 - PORTx_FER,
+ * PORT_MUX Registers Do Not accept "writes" correctly:
+ */
+ p0.h = hi(BFIN_PORT_MUX);
+ p0.l = lo(BFIN_PORT_MUX);
+#ifdef ANOMALY_05000212
+ R0.L = W[P0]; /* Read */
+ SSYNC;
+#endif
+ R0 = (PGDE_UART | PFTE_UART)(Z);
+#ifdef ANOMALY_05000212
+ W[P0] = R0.L; /* Write */
+ SSYNC;
+#endif
+ W[P0] = R0.L; /* Enable both UARTS */
+ SSYNC;
+
+ p0.h = hi(PORTF_FER);
+ p0.l = lo(PORTF_FER);
+#ifdef ANOMALY_05000212
+ R0.L = W[P0]; /* Read */
+ SSYNC;
+#endif
+ R0 = 0x000F(Z);
+#ifdef ANOMALY_05000212
+ W[P0] = R0.L; /* Write */
+ SSYNC;
+#endif
+ /* Enable peripheral function of PORTF for UART0 and UART1 */
+ W[P0] = R0.L;
+ SSYNC;
+
+#if !defined(CONFIG_BF534)
+ p0.h = hi(EMAC_SYSTAT);
+ p0.l = lo(EMAC_SYSTAT);
+ R0.h = 0xFFFF; /* Clear EMAC Interrupt Status bits */
+ R0.l = 0xFFFF;
+ [P0] = R0;
+ SSYNC;
+#endif
+
+#ifdef CONFIG_BF537_PORT_H
+ p0.h = hi(PORTH_FER);
+ p0.l = lo(PORTH_FER);
+ R0.L = W[P0]; /* Read */
+ SSYNC;
+ R0 = 0x0000;
+ W[P0] = R0.L; /* Write */
+ SSYNC;
+ W[P0] = R0.L; /* Disable peripheral function of PORTH */
+ SSYNC;
+#endif
+
+ /*Initialise UART*/
+ p0.h = hi(UART_LCR);
+ p0.l = lo(UART_LCR);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable DLL writes */
+ ssync;
+
+ p0.h = hi(UART_DLL);
+ p0.l = lo(UART_DLL);
+ r0 = 0x00(Z);
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART_DLH);
+ p0.l = lo(UART_DLH);
+ r0 = 0x00(Z);
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART_GCTL);
+ p0.l = lo(UART_GCTL);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable UART clock */
+ ssync;
+
+ /* Initialize stack pointer */
+ sp.l = lo(INITIAL_STACK);
+ sp.h = hi(INITIAL_STACK);
+ fp = sp;
+ usp = sp;
+
+ /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
+ call _bf53x_relocate_l1_mem;
+#if CONFIG_BFIN_KERNEL_CLOCK
+ call _start_dma_code;
+#endif
+ /* Code for initializing Async memory banks */
+
+ p2.h = hi(EBIU_AMBCTL1);
+ p2.l = lo(EBIU_AMBCTL1);
+ r0.h = hi(AMBCTL1VAL);
+ r0.l = lo(AMBCTL1VAL);
+ [p2] = r0;
+ ssync;
+
+ p2.h = hi(EBIU_AMBCTL0);
+ p2.l = lo(EBIU_AMBCTL0);
+ r0.h = hi(AMBCTL0VAL);
+ r0.l = lo(AMBCTL0VAL);
+ [p2] = r0;
+ ssync;
+
+ p2.h = hi(EBIU_AMGCTL);
+ p2.l = lo(EBIU_AMGCTL);
+ r0 = AMGCTLVAL;
+ w[p2] = r0;
+ ssync;
+
+ /* This section keeps the processor in supervisor mode
+ * during kernel boot. Switches to user mode at end of boot.
+ * See page 3-9 of Hardware Reference manual for documentation.
+ */
+
+ /* EVT15 = _real_start */
+
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _real_start;
+ p1.h = _real_start;
+ [p0] = p1;
+ csync;
+
+ p0.l = lo(IMASK);
+ p0.h = hi(IMASK);
+ p1.l = IMASK_IVG15;
+ p1.h = 0x0;
+ [p0] = p1;
+ csync;
+
+ raise 15;
+ p0.l = .LWAIT_HERE;
+ p0.h = .LWAIT_HERE;
+ reti = p0;
+#if defined(ANOMALY_05000281)
+ nop; nop; nop;
+#endif
+ rti;
+
+.LWAIT_HERE:
+ jump .LWAIT_HERE;
+
+ENTRY(_real_start)
+ [ -- sp ] = reti;
+ p0.l = lo(WDOG_CTL);
+ p0.h = hi(WDOG_CTL);
+ r0 = 0xAD6(z);
+ w[p0] = r0; /* watchdog off for now */
+ ssync;
+
+ /* Code update for BSS size == 0
+ * Zero out the bss region.
+ */
+
+ p1.l = ___bss_start;
+ p1.h = ___bss_start;
+ p2.l = ___bss_stop;
+ p2.h = ___bss_stop;
+ r0 = 0;
+ p2 -= p1;
+ lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2;
+.L_clear_bss:
+ B[p1++] = r0;
+
+ /* In case there is a NULL pointer reference
+ * Zero out region before stext
+ */
+
+ p1.l = 0x0;
+ p1.h = 0x0;
+ r0.l = __stext;
+ r0.h = __stext;
+ r0 = r0 >> 1;
+ p2 = r0;
+ r0 = 0;
+ lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2;
+.L_clear_zero:
+ W[p1++] = r0;
+
+ /* pass the uboot arguments to the global value command line */
+ R0 = R7;
+ call _cmdline_init;
+
+ p1.l = __rambase;
+ p1.h = __rambase;
+ r0.l = __sdata;
+ r0.h = __sdata;
+ [p1] = r0;
+
+ p1.l = __ramstart;
+ p1.h = __ramstart;
+ p3.l = ___bss_stop;
+ p3.h = ___bss_stop;
+
+ r1 = p3;
+ [p1] = r1;
+
+
+ /*
+ * load the current thread pointer and stack
+ */
+ r1.l = _init_thread_union;
+ r1.h = _init_thread_union;
+
+ r2.l = 0x2000;
+ r2.h = 0x0000;
+ r1 = r1 + r2;
+ sp = r1;
+ usp = sp;
+ fp = sp;
+ call _start_kernel;
+.L_exit:
+ jump.s .L_exit;
+
+.section .l1.text
+#if CONFIG_BFIN_KERNEL_CLOCK
+ENTRY(_start_dma_code)
+
+ /* Enable PHY CLK buffer output */
+ p0.h = hi(VR_CTL);
+ p0.l = lo(VR_CTL);
+ r0.l = w[p0];
+ bitset(r0, 14);
+ w[p0] = r0.l;
+ ssync;
+
+ p0.h = hi(SIC_IWR);
+ p0.l = lo(SIC_IWR);
+ r0.l = 0x1;
+ r0.h = 0x0;
+ [p0] = r0;
+ SSYNC;
+
+ /*
+ * Set PLL_CTL
+ * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
+ * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK
+ * - [7] = output delay (add 200ps of delay to mem signals)
+ * - [6] = input delay (add 200ps of input delay to mem signals)
+ * - [5] = PDWN : 1=All Clocks off
+ * - [3] = STOPCK : 1=Core Clock off
+ * - [1] = PLL_OFF : 1=Disable Power to PLL
+ * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
+ * all other bits set to zero
+ */
+
+ p0.h = hi(PLL_LOCKCNT);
+ p0.l = lo(PLL_LOCKCNT);
+ r0 = 0x300(Z);
+ w[p0] = r0.l;
+ ssync;
+
+ P2.H = hi(EBIU_SDGCTL);
+ P2.L = lo(EBIU_SDGCTL);
+ R0 = [P2];
+ BITSET (R0, 24);
+ [P2] = R0;
+ SSYNC;
+
+ r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
+ r0 = r0 << 9; /* Shift it over, */
+ r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/
+ r0 = r1 | r0;
+ r1 = PLL_BYPASS; /* Bypass the PLL? */
+ r1 = r1 << 8; /* Shift it over */
+ r0 = r1 | r0; /* add them all together */
+
+ p0.h = hi(PLL_CTL);
+ p0.l = lo(PLL_CTL); /* Load the address */
+ cli r2; /* Disable interrupts */
+ ssync;
+ w[p0] = r0.l; /* Set the value */
+ idle; /* Wait for the PLL to stablize */
+ sti r2; /* Enable interrupts */
+
+.Lcheck_again:
+ p0.h = hi(PLL_STAT);
+ p0.l = lo(PLL_STAT);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,5);
+ if ! CC jump .Lcheck_again;
+
+ /* Configure SCLK & CCLK Dividers */
+ r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
+ p0.h = hi(PLL_DIV);
+ p0.l = lo(PLL_DIV);
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = lo(EBIU_SDRRC);
+ p0.h = hi(EBIU_SDRRC);
+ r0 = mem_SDRRC;
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = (EBIU_SDBCTL & 0xFFFF);
+ p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */
+ r0 = mem_SDBCTL;
+ w[p0] = r0.l;
+ ssync;
+
+ P2.H = hi(EBIU_SDGCTL);
+ P2.L = lo(EBIU_SDGCTL);
+ R0 = [P2];
+ BITCLR (R0, 24);
+ p0.h = hi(EBIU_SDSTAT);
+ p0.l = lo(EBIU_SDSTAT);
+ r2.l = w[p0];
+ cc = bittst(r2,3);
+ if !cc jump .Lskip;
+ NOP;
+ BITSET (R0, 23);
+.Lskip:
+ [P2] = R0;
+ SSYNC;
+
+ R0.L = lo(mem_SDGCTL);
+ R0.H = hi(mem_SDGCTL);
+ R1 = [p2];
+ R1 = R1 | R0;
+ [P2] = R1;
+ SSYNC;
+
+ p0.h = hi(SIC_IWR);
+ p0.l = lo(SIC_IWR);
+ r0.l = lo(IWR_ENABLE_ALL);
+ r0.h = hi(IWR_ENABLE_ALL);
+ [p0] = r0;
+ SSYNC;
+
+ RTS;
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+ENTRY(_bfin_reset)
+ /* No more interrupts to be handled*/
+ CLI R6;
+ SSYNC;
+
+#if defined(CONFIG_MTD_M25P80)
+/*
+ * The following code fix the SPI flash reboot issue,
+ * /CS signal of the chip which is using PF10 return to GPIO mode
+ */
+ p0.h = hi(PORTF_FER);
+ p0.l = lo(PORTF_FER);
+ r0.l = 0x0000;
+ w[p0] = r0.l;
+ SSYNC;
+
+/* /CS return to high */
+ p0.h = hi(PORTFIO);
+ p0.l = lo(PORTFIO);
+ r0.l = 0xFFFF;
+ w[p0] = r0.l;
+ SSYNC;
+
+/* Delay some time, This is necessary */
+ r1.h = 0;
+ r1.l = 0x400;
+ p1 = r1;
+ lsetup (_delay_lab1,_delay_lab1_end ) lc1 = p1;
+_delay_lab1:
+ r0.h = 0;
+ r0.l = 0x8000;
+ p0 = r0;
+ lsetup (_delay_lab0,_delay_lab0_end ) lc0 = p0;
+_delay_lab0:
+ nop;
+_delay_lab0_end:
+ nop;
+_delay_lab1_end:
+ nop;
+#endif
+
+ /* Clear the bits 13-15 in SWRST if they werent cleared */
+ p0.h = hi(SWRST);
+ p0.l = lo(SWRST);
+ csync;
+ r0.l = w[p0];
+
+ /* Clear the IMASK register */
+ p0.h = hi(IMASK);
+ p0.l = lo(IMASK);
+ r0 = 0x0;
+ [p0] = r0;
+
+ /* Clear the ILAT register */
+ p0.h = hi(ILAT);
+ p0.l = lo(ILAT);
+ r0 = [p0];
+ [p0] = r0;
+ SSYNC;
+
+ /* Disable the WDOG TIMER */
+ p0.h = hi(WDOG_CTL);
+ p0.l = lo(WDOG_CTL);
+ r0.l = 0xAD6;
+ w[p0] = r0.l;
+ SSYNC;
+
+ /* Clear the sticky bit incase it is already set */
+ p0.h = hi(WDOG_CTL);
+ p0.l = lo(WDOG_CTL);
+ r0.l = 0x8AD6;
+ w[p0] = r0.l;
+ SSYNC;
+
+ /* Program the count value */
+ R0.l = 0x100;
+ R0.h = 0x0;
+ P0.h = hi(WDOG_CNT);
+ P0.l = lo(WDOG_CNT);
+ [P0] = R0;
+ SSYNC;
+
+ /* Program WDOG_STAT if necessary */
+ P0.h = hi(WDOG_CTL);
+ P0.l = lo(WDOG_CTL);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,1);
+ if !CC JUMP .LWRITESTAT;
+ CC = BITTST(R0,2);
+ if !CC JUMP .LWRITESTAT;
+ JUMP .LSKIP_WRITE;
+
+.LWRITESTAT:
+ /* When watch dog timer is enabled,
+ * a write to STAT will load the contents of CNT to STAT
+ */
+ R0 = 0x0000(z);
+ P0.h = hi(WDOG_STAT);
+ P0.l = lo(WDOG_STAT)
+ [P0] = R0;
+ SSYNC;
+
+.LSKIP_WRITE:
+ /* Enable the reset event */
+ P0.h = hi(WDOG_CTL);
+ P0.l = lo(WDOG_CTL);
+ R0 = W[P0](Z);
+ BITCLR(R0,1);
+ BITCLR(R0,2);
+ W[P0] = R0.L;
+ SSYNC;
+ NOP;
+
+ /* Enable the wdog counter */
+ R0 = W[P0](Z);
+ BITCLR(R0,4);
+ W[P0] = R0.L;
+ SSYNC;
+
+ IDLE;
+
+ RTS;
+
+.data
+
+/*
+ * Set up the usable of RAM stuff. Size of RAM is determined then
+ * an initial stack set up at the end.
+ */
+
+.align 4
+__rambase:
+.long 0
+__ramstart:
+.long 0
+__ramend:
+.long 0
diff --git a/arch/blackfin/mach-bf537/ints-priority.c b/arch/blackfin/mach-bf537/ints-priority.c
new file mode 100644
index 0000000..fd6308e
--- /dev/null
+++ b/arch/blackfin/mach-bf537/ints-priority.c
@@ -0,0 +1,74 @@
+/*
+ * File: arch/blackfin/mach-bf537/ints-priority.c
+ * Based on: arch/blackfin/mach-bf533/ints-priority.c
+ * Author: Michael Hennerich
+ *
+ * Created:
+ * Description: Set up the interupt priorities
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <asm/blackfin.h>
+#include <asm/irq.h>
+
+void program_IAR(void)
+{
+ /* Program the IAR0 Register with the configured priority */
+ bfin_write_SIC_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) |
+ ((CONFIG_IRQ_DMA_ERROR - 7) << IRQ_DMA_ERROR_POS) |
+ ((CONFIG_IRQ_ERROR - 7) << IRQ_ERROR_POS) |
+ ((CONFIG_IRQ_RTC - 7) << IRQ_RTC_POS) |
+ ((CONFIG_IRQ_PPI - 7) << IRQ_PPI_POS) |
+ ((CONFIG_IRQ_SPORT0_RX - 7) << IRQ_SPORT0_RX_POS) |
+ ((CONFIG_IRQ_SPORT0_TX - 7) << IRQ_SPORT0_TX_POS) |
+ ((CONFIG_IRQ_SPORT1_RX - 7) << IRQ_SPORT1_RX_POS));
+
+ bfin_write_SIC_IAR1(((CONFIG_IRQ_SPORT1_TX - 7) << IRQ_SPORT1_TX_POS) |
+ ((CONFIG_IRQ_TWI - 7) << IRQ_TWI_POS) |
+ ((CONFIG_IRQ_SPI - 7) << IRQ_SPI_POS) |
+ ((CONFIG_IRQ_UART0_RX - 7) << IRQ_UART0_RX_POS) |
+ ((CONFIG_IRQ_UART0_TX - 7) << IRQ_UART0_TX_POS) |
+ ((CONFIG_IRQ_UART1_RX - 7) << IRQ_UART1_RX_POS) |
+ ((CONFIG_IRQ_UART1_TX - 7) << IRQ_UART1_TX_POS) |
+ ((CONFIG_IRQ_CAN_RX - 7) << IRQ_CAN_RX_POS));
+
+ bfin_write_SIC_IAR2(((CONFIG_IRQ_CAN_TX - 7) << IRQ_CAN_TX_POS) |
+ ((CONFIG_IRQ_MAC_RX - 7) << IRQ_MAC_RX_POS) |
+ ((CONFIG_IRQ_MAC_TX - 7) << IRQ_MAC_TX_POS) |
+ ((CONFIG_IRQ_TMR0 - 7) << IRQ_TMR0_POS) |
+ ((CONFIG_IRQ_TMR1 - 7) << IRQ_TMR1_POS) |
+ ((CONFIG_IRQ_TMR2 - 7) << IRQ_TMR2_POS) |
+ ((CONFIG_IRQ_TMR3 - 7) << IRQ_TMR3_POS) |
+ ((CONFIG_IRQ_TMR4 - 7) << IRQ_TMR4_POS));
+
+ bfin_write_SIC_IAR3(((CONFIG_IRQ_TMR5 - 7) << IRQ_TMR5_POS) |
+ ((CONFIG_IRQ_TMR6 - 7) << IRQ_TMR6_POS) |
+ ((CONFIG_IRQ_TMR7 - 7) << IRQ_TMR7_POS) |
+ ((CONFIG_IRQ_PROG_INTA - 7) << IRQ_PROG_INTA_POS) |
+ ((CONFIG_IRQ_PORTG_INTB - 7) << IRQ_PORTG_INTB_POS) |
+ ((CONFIG_IRQ_MEM_DMA0 - 7) << IRQ_MEM_DMA0_POS) |
+ ((CONFIG_IRQ_MEM_DMA1 - 7) << IRQ_MEM_DMA1_POS) |
+ ((CONFIG_IRQ_WATCH - 7) << IRQ_WATCH_POS));
+
+ SSYNC();
+}
diff --git a/arch/blackfin/mach-bf561/Kconfig b/arch/blackfin/mach-bf561/Kconfig
new file mode 100644
index 0000000..0a17c4c
--- /dev/null
+++ b/arch/blackfin/mach-bf561/Kconfig
@@ -0,0 +1,222 @@
+if BF561
+
+menu "BF561 Specific Configuration"
+
+comment "Core B Support"
+
+menu "Core B Support"
+
+config BF561_COREB
+ bool "Enable Core B support"
+ default y
+
+config BF561_COREB_RESET
+ bool "Enable Core B reset support"
+ default n
+ help
+ This requires code in the application that is loaded
+ into Core B. In order to reset, the application needs
+ to install an interrupt handler for Supplemental
+ Interrupt 0, that sets RETI to 0xff600000 and writes
+ bit 11 of SICB_SYSCR when bit 5 of SICA_SYSCR is 0.
+ This causes Core B to stall when Supplemental Interrupt
+ 0 is set, and will reset PC to 0xff600000 when
+ COREB_SRAM_INIT is cleared.
+
+endmenu
+
+comment "Interrupt Priority Assignment"
+
+menu "Priority"
+
+config IRQ_PLL_WAKEUP
+ int "PLL Wakeup Interrupt"
+ default 7
+config IRQ_DMA1_ERROR
+ int "DMA1 Error (generic)"
+ default 7
+config IRQ_DMA2_ERROR
+ int "DMA2 Error (generic)"
+ default 7
+config IRQ_IMDMA_ERROR
+ int "IMDMA Error (generic)"
+ default 7
+config IRQ_PPI0_ERROR
+ int "PPI0 Error Interrupt"
+ default 7
+config IRQ_PPI1_ERROR
+ int "PPI1 Error Interrupt"
+ default 7
+config IRQ_SPORT0_ERROR
+ int "SPORT0 Error Interrupt"
+ default 7
+config IRQ_SPORT1_ERROR
+ int "SPORT1 Error Interrupt"
+ default 7
+config IRQ_SPI_ERROR
+ int "SPI Error Interrupt"
+ default 7
+config IRQ_UART_ERROR
+ int "UART Error Interrupt"
+ default 7
+config IRQ_RESERVED_ERROR
+ int "Reserved Interrupt"
+ default 7
+config IRQ_DMA1_0
+ int "DMA1 0 Interrupt(PPI1)"
+ default 8
+config IRQ_DMA1_1
+ int "DMA1 1 Interrupt(PPI2)"
+ default 8
+config IRQ_DMA1_2
+ int "DMA1 2 Interrupt"
+ default 8
+config IRQ_DMA1_3
+ int "DMA1 3 Interrupt"
+ default 8
+config IRQ_DMA1_4
+ int "DMA1 4 Interrupt"
+ default 8
+config IRQ_DMA1_5
+ int "DMA1 5 Interrupt"
+ default 8
+config IRQ_DMA1_6
+ int "DMA1 6 Interrupt"
+ default 8
+config IRQ_DMA1_7
+ int "DMA1 7 Interrupt"
+ default 8
+config IRQ_DMA1_8
+ int "DMA1 8 Interrupt"
+ default 8
+config IRQ_DMA1_9
+ int "DMA1 9 Interrupt"
+ default 8
+config IRQ_DMA1_10
+ int "DMA1 10 Interrupt"
+ default 8
+config IRQ_DMA1_11
+ int "DMA1 11 Interrupt"
+ default 8
+config IRQ_DMA2_0
+ int "DMA2 0 (SPORT0 RX)"
+ default 9
+config IRQ_DMA2_1
+ int "DMA2 1 (SPORT0 TX)"
+ default 9
+config IRQ_DMA2_2
+ int "DMA2 2 (SPORT1 RX)"
+ default 9
+config IRQ_DMA2_3
+ int "DMA2 3 (SPORT2 TX)"
+ default 9
+config IRQ_DMA2_4
+ int "DMA2 4 (SPI)"
+ default 9
+config IRQ_DMA2_5
+ int "DMA2 5 (UART RX)"
+ default 9
+config IRQ_DMA2_6
+ int "DMA2 6 (UART TX)"
+ default 9
+config IRQ_DMA2_7
+ int "DMA2 7 Interrupt"
+ default 9
+config IRQ_DMA2_8
+ int "DMA2 8 Interrupt"
+ default 9
+config IRQ_DMA2_9
+ int "DMA2 9 Interrupt"
+ default 9
+config IRQ_DMA2_10
+ int "DMA2 10 Interrupt"
+ default 9
+config IRQ_DMA2_11
+ int "DMA2 11 Interrupt"
+ default 9
+config IRQ_TIMER0
+ int "TIMER 0 Interrupt"
+ default 10
+config IRQ_TIMER1
+ int "TIMER 1 Interrupt"
+ default 10
+config IRQ_TIMER2
+ int "TIMER 2 Interrupt"
+ default 10
+config IRQ_TIMER3
+ int "TIMER 3 Interrupt"
+ default 10
+config IRQ_TIMER4
+ int "TIMER 4 Interrupt"
+ default 10
+config IRQ_TIMER5
+ int "TIMER 5 Interrupt"
+ default 10
+config IRQ_TIMER6
+ int "TIMER 6 Interrupt"
+ default 10
+config IRQ_TIMER7
+ int "TIMER 7 Interrupt"
+ default 10
+config IRQ_TIMER8
+ int "TIMER 8 Interrupt"
+ default 10
+config IRQ_TIMER9
+ int "TIMER 9 Interrupt"
+ default 10
+config IRQ_TIMER10
+ int "TIMER 10 Interrupt"
+ default 10
+config IRQ_TIMER11
+ int "TIMER 11 Interrupt"
+ default 10
+config IRQ_PROG0_INTA
+ int "Programmable Flags0 A (8)"
+ default 11
+config IRQ_PROG0_INTB
+ int "Programmable Flags0 B (8)"
+ default 11
+config IRQ_PROG1_INTA
+ int "Programmable Flags1 A (8)"
+ default 11
+config IRQ_PROG1_INTB
+ int "Programmable Flags1 B (8)"
+ default 11
+config IRQ_PROG2_INTA
+ int "Programmable Flags2 A (8)"
+ default 11
+config IRQ_PROG2_INTB
+ int "Programmable Flags2 B (8)"
+ default 11
+config IRQ_DMA1_WRRD0
+ int "MDMA1 0 write/read INT"
+ default 8
+config IRQ_DMA1_WRRD1
+ int "MDMA1 1 write/read INT"
+ default 8
+config IRQ_DMA2_WRRD0
+ int "MDMA2 0 write/read INT"
+ default 9
+config IRQ_DMA2_WRRD1
+ int "MDMA2 1 write/read INT"
+ default 9
+config IRQ_IMDMA_WRRD0
+ int "IMDMA 0 write/read INT"
+ default 12
+config IRQ_IMDMA_WRRD1
+ int "IMDMA 1 write/read INT"
+ default 12
+config IRQ_WDTIMER
+ int "Watch Dog Timer"
+ default 13
+
+ help
+ Enter the priority numbers between 7-13 ONLY. Others are Reserved.
+ This applies to all the above. It is not recommended to assign the
+ highest priority number 7 to UART or any other device.
+
+endmenu
+
+endmenu
+
+endif
diff --git a/arch/blackfin/mach-bf561/Makefile b/arch/blackfin/mach-bf561/Makefile
new file mode 100644
index 0000000..57f475a
--- /dev/null
+++ b/arch/blackfin/mach-bf561/Makefile
@@ -0,0 +1,9 @@
+#
+# arch/blackfin/mach-bf561/Makefile
+#
+
+extra-y := head.o
+
+obj-y := ints-priority.o
+
+obj-$(CONFIG_BF561_COREB) += coreb.o
diff --git a/arch/blackfin/mach-bf561/boards/Makefile b/arch/blackfin/mach-bf561/boards/Makefile
new file mode 100644
index 0000000..886edc7
--- /dev/null
+++ b/arch/blackfin/mach-bf561/boards/Makefile
@@ -0,0 +1,7 @@
+#
+# arch/blackfin/mach-bf561/boards/Makefile
+#
+
+obj-$(CONFIG_GENERIC_BOARD) += generic_board.o
+obj-$(CONFIG_BFIN561_EZKIT) += ezkit.o
+obj-$(CONFIG_BFIN561_BLUETECHNIX_CM) += cm_bf561.o
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
new file mode 100644
index 0000000..6824e95
--- /dev/null
+++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -0,0 +1,289 @@
+/*
+ * File: arch/blackfin/mach-bf533/boards/cm_bf561.c
+ * Based on: arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au> Copright 2005
+ *
+ * Created: 2006
+ * Description: Board description file
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/usb_isp1362.h>
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "Bluetechnix CM BF561";
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI perpherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ },{
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ },{
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+static struct bfin5xx_spi_chip spi_mmc_chip_info = {
+ .enable_dma = 1,
+ .bits_per_word = 8,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+ {
+ .modalias = "ad9960-spi",
+ .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .controller_data = &ad9960_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+ {
+ .modalias = "spi_mmc",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SPI_MMC_CS_CHAN,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x28000300,
+ .end = 0x28000300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF0,
+ .end = IRQ_PF0,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+ {
+ .start = 0x24008000,
+ .end = 0x24008000,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = 0x24008004,
+ .end = 0x24008004,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PF47,
+ .end = IRQ_PF47,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+ .sel15Kres = 1,
+ .clknotstop = 0,
+ .oc_enable = 0,
+ .int_act_high = 0,
+ .int_edge_triggered = 0,
+ .remote_wakeup_connected = 0,
+ .no_power_switching = 1,
+ .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+ .name = "isp1362-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &isp1362_priv,
+ },
+ .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+ .resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+static struct platform_device *cm_bf561_devices[] __initdata = {
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+ &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+
+};
+
+static int __init cm_bf561_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(cm_bf561_devices, ARRAY_SIZE(cm_bf561_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+ return 0;
+}
+
+arch_initcall(cm_bf561_init);
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
new file mode 100644
index 0000000..14eb4f9
--- /dev/null
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -0,0 +1,147 @@
+/*
+ * File: arch/blackfin/mach-bf561/ezkit.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <asm/irq.h>
+#include <asm/bfin5xx_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+char *bfin_board_name = "ADDS-BF561-EZKIT";
+
+/*
+ * USB-LAN EzExtender board
+ * Driver needs to know address, irq and flag pin.
+ */
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x2C010300,
+ .end = 0x2C010300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+
+ .start = IRQ_PF9,
+ .end = IRQ_PF9,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+#ifdef CONFIG_SPI_BFIN
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+#endif
+
+/* SPI controller data */
+static struct bfin5xx_spi_master spi_bfin_master_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+static struct platform_device spi_bfin_master_device = {
+ .name = "bfin-spi-master",
+ .id = 1, /* Bus number */
+ .dev = {
+ .platform_data = &spi_bfin_master_info, /* Passed to driver */
+ },
+};
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+};
+
+static struct platform_device *ezkit_devices[] __initdata = {
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &spi_bfin_master_device,
+#endif
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+};
+
+static int __init ezkit_init(void)
+{
+ int ret;
+
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ ret = platform_add_devices(ezkit_devices,
+ ARRAY_SIZE(ezkit_devices));
+ if (ret < 0)
+ return ret;
+ return spi_register_board_info(bfin_spi_board_info,
+ ARRAY_SIZE(bfin_spi_board_info));
+}
+
+arch_initcall(ezkit_init);
diff --git a/arch/blackfin/mach-bf561/boards/generic_board.c b/arch/blackfin/mach-bf561/boards/generic_board.c
new file mode 100644
index 0000000..585ecdd
--- /dev/null
+++ b/arch/blackfin/mach-bf561/boards/generic_board.c
@@ -0,0 +1,82 @@
+/*
+ * File: arch/blackfin/mach-bf561/generic_board.c
+ * Based on: arch/blackfin/mach-bf533/ezkit.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <asm/irq.h>
+
+char *bfin_board_name = "UNKNOWN BOARD";
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .start = 0x2C010300,
+ .end = 0x2C010300 + 16,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = IRQ_PROG_INTB,
+ .end = IRQ_PROG_INTB,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },{
+ /*
+ * denotes the flag pin and is used directly if
+ * CONFIG_IRQCHIP_DEMUX_GPIO is defined.
+ */
+ .start = IRQ_PF9,
+ .end = IRQ_PF9,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+static struct platform_device *generic_board_devices[] __initdata = {
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+};
+
+static int __init generic_board_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ return platform_add_devices(generic_board_devices,
+ ARRAY_SIZE(generic_board_devices));
+}
+
+arch_initcall(generic_board_init);
diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c
new file mode 100644
index 0000000..b28582f
--- /dev/null
+++ b/arch/blackfin/mach-bf561/coreb.c
@@ -0,0 +1,402 @@
+/*
+ * File: arch/blackfin/mach-bf561/coreb.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: Handle CoreB on a BF561
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/device.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <asm/dma.h>
+#include <asm/uaccess.h>
+
+#define MODULE_VER "v0.1"
+
+static spinlock_t coreb_lock;
+static wait_queue_head_t coreb_dma_wait;
+
+#define COREB_IS_OPEN 0x00000001
+#define COREB_IS_RUNNING 0x00000010
+
+#define CMD_COREB_INDEX 1
+#define CMD_COREB_START 2
+#define CMD_COREB_STOP 3
+#define CMD_COREB_RESET 4
+
+#define COREB_MINOR 229
+
+static unsigned long coreb_status = 0;
+static unsigned long coreb_base = 0xff600000;
+static unsigned long coreb_size = 0x4000;
+int coreb_dma_done;
+
+static loff_t coreb_lseek(struct file *file, loff_t offset, int origin);
+static ssize_t coreb_read(struct file *file, char *buf, size_t count,
+ loff_t * ppos);
+static ssize_t coreb_write(struct file *file, const char *buf, size_t count,
+ loff_t * ppos);
+static int coreb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg);
+static int coreb_open(struct inode *inode, struct file *file);
+static int coreb_release(struct inode *inode, struct file *file);
+
+static irqreturn_t coreb_dma_interrupt(int irq, void *dev_id)
+{
+ clear_dma_irqstat(CH_MEM_STREAM2_DEST);
+ coreb_dma_done = 1;
+ wake_up_interruptible(&coreb_dma_wait);
+ return IRQ_HANDLED;
+}
+
+static ssize_t coreb_write(struct file *file, const char *buf, size_t count,
+ loff_t * ppos)
+{
+ unsigned long p = *ppos;
+ ssize_t wrote = 0;
+
+ if (p + count > coreb_size)
+ return -EFAULT;
+
+ while (count > 0) {
+ int len = count;
+
+ if (len > PAGE_SIZE)
+ len = PAGE_SIZE;
+
+ coreb_dma_done = 0;
+
+ /* Source Channel */
+ set_dma_start_addr(CH_MEM_STREAM2_SRC, (unsigned long)buf);
+ set_dma_x_count(CH_MEM_STREAM2_SRC, len);
+ set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char));
+ set_dma_config(CH_MEM_STREAM2_SRC, RESTART);
+ /* Destination Channel */
+ set_dma_start_addr(CH_MEM_STREAM2_DEST, coreb_base + p);
+ set_dma_x_count(CH_MEM_STREAM2_DEST, len);
+ set_dma_x_modify(CH_MEM_STREAM2_DEST, sizeof(char));
+ set_dma_config(CH_MEM_STREAM2_DEST, WNR | RESTART | DI_EN);
+
+ enable_dma(CH_MEM_STREAM2_SRC);
+ enable_dma(CH_MEM_STREAM2_DEST);
+
+ wait_event_interruptible(coreb_dma_wait, coreb_dma_done);
+
+ disable_dma(CH_MEM_STREAM2_SRC);
+ disable_dma(CH_MEM_STREAM2_DEST);
+
+ count -= len;
+ wrote += len;
+ buf += len;
+ p += len;
+ }
+ *ppos = p;
+ return wrote;
+}
+
+static ssize_t coreb_read(struct file *file, char *buf, size_t count,
+ loff_t * ppos)
+{
+ unsigned long p = *ppos;
+ ssize_t read = 0;
+
+ if ((p + count) > coreb_size)
+ return -EFAULT;
+
+ while (count > 0) {
+ int len = count;
+
+ if (len > PAGE_SIZE)
+ len = PAGE_SIZE;
+
+ coreb_dma_done = 0;
+
+ /* Source Channel */
+ set_dma_start_addr(CH_MEM_STREAM2_SRC, coreb_base + p);
+ set_dma_x_count(CH_MEM_STREAM2_SRC, len);
+ set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char));
+ set_dma_config(CH_MEM_STREAM2_SRC, RESTART);
+ /* Destination Channel */
+ set_dma_start_addr(CH_MEM_STREAM2_DEST, (unsigned long)buf);
+ set_dma_x_count(CH_MEM_STREAM2_DEST, len);
+ set_dma_x_modify(CH_MEM_STREAM2_DEST, sizeof(char));
+ set_dma_config(CH_MEM_STREAM2_DEST, WNR | RESTART | DI_EN);
+
+ enable_dma(CH_MEM_STREAM2_SRC);
+ enable_dma(CH_MEM_STREAM2_DEST);
+
+ wait_event_interruptible(coreb_dma_wait, coreb_dma_done);
+
+ disable_dma(CH_MEM_STREAM2_SRC);
+ disable_dma(CH_MEM_STREAM2_DEST);
+
+ count -= len;
+ read += len;
+ buf += len;
+ p += len;
+ }
+
+ return read;
+}
+
+static loff_t coreb_lseek(struct file *file, loff_t offset, int origin)
+{
+ loff_t ret;
+
+ mutex_lock(&file->f_dentry->d_inode->i_mutex);
+
+ switch (origin) {
+ case 0 /* SEEK_SET */ :
+ if (offset < coreb_size) {
+ file->f_pos = offset;
+ ret = file->f_pos;
+ } else
+ ret = -EINVAL;
+ break;
+ case 1 /* SEEK_CUR */ :
+ if ((offset + file->f_pos) < coreb_size) {
+ file->f_pos += offset;
+ ret = file->f_pos;
+ } else
+ ret = -EINVAL;
+ default:
+ ret = -EINVAL;
+ }
+ mutex_unlock(&file->f_dentry->d_inode->i_mutex);
+ return ret;
+}
+
+static int coreb_open(struct inode *inode, struct file *file)
+{
+ spin_lock_irq(&coreb_lock);
+
+ if (coreb_status & COREB_IS_OPEN)
+ goto out_busy;
+
+ coreb_status |= COREB_IS_OPEN;
+
+ spin_unlock_irq(&coreb_lock);
+ return 0;
+
+ out_busy:
+ spin_unlock_irq(&coreb_lock);
+ return -EBUSY;
+}
+
+static int coreb_release(struct inode *inode, struct file *file)
+{
+ spin_lock_irq(&coreb_lock);
+ coreb_status &= ~COREB_IS_OPEN;
+ spin_unlock_irq(&coreb_lock);
+ return 0;
+}
+
+static int coreb_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int retval = 0;
+ int coreb_index = 0;
+
+ switch (cmd) {
+ case CMD_COREB_INDEX:
+ if (copy_from_user(&coreb_index, (int *)arg, sizeof(int))) {
+ retval = -EFAULT;
+ break;
+ }
+
+ spin_lock_irq(&coreb_lock);
+ switch (coreb_index) {
+ case 0:
+ coreb_base = 0xff600000;
+ coreb_size = 0x4000;
+ break;
+ case 1:
+ coreb_base = 0xff610000;
+ coreb_size = 0x4000;
+ break;
+ case 2:
+ coreb_base = 0xff500000;
+ coreb_size = 0x8000;
+ break;
+ case 3:
+ coreb_base = 0xff400000;
+ coreb_size = 0x8000;
+ break;
+ default:
+ retval = -EINVAL;
+ break;
+ }
+ spin_unlock_irq(&coreb_lock);
+
+ mutex_lock(&file->f_dentry->d_inode->i_mutex);
+ file->f_pos = 0;
+ mutex_unlock(&file->f_dentry->d_inode->i_mutex);
+ break;
+ case CMD_COREB_START:
+ spin_lock_irq(&coreb_lock);
+ if (coreb_status & COREB_IS_RUNNING) {
+ retval = -EBUSY;
+ break;
+ }
+ printk(KERN_INFO "Starting Core B\n");
+ coreb_status |= COREB_IS_RUNNING;
+ bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~0x0020);
+ SSYNC();
+ spin_lock_irq(&coreb_lock);
+ break;
+#if defined(CONFIG_BF561_COREB_RESET)
+ case CMD_COREB_STOP:
+ spin_lock_irq(&coreb_lock);
+ printk(KERN_INFO "Stopping Core B\n");
+ bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() | 0x0020);
+ bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080);
+ coreb_status &= ~COREB_IS_RUNNING;
+ spin_lock_irq(&coreb_lock);
+ break;
+ case CMD_COREB_RESET:
+ printk(KERN_INFO "Resetting Core B\n");
+ bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080);
+ break;
+#endif
+ }
+
+ return retval;
+}
+
+static struct file_operations coreb_fops = {
+ .owner = THIS_MODULE,
+ .llseek = coreb_lseek,
+ .read = coreb_read,
+ .write = coreb_write,
+ .ioctl = coreb_ioctl,
+ .open = coreb_open,
+ .release = coreb_release
+};
+
+static struct miscdevice coreb_dev = {
+ COREB_MINOR,
+ "coreb",
+ &coreb_fops
+};
+
+static ssize_t coreb_show_status(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf,
+ "Base Address:\t0x%08lx\n"
+ "Core B is %s\n"
+ "SICA_SYSCR:\t%04x\n"
+ "SICB_SYSCR:\t%04x\n"
+ "\n"
+ "IRQ Status:\tCore A\t\tCore B\n"
+ "ISR0:\t\t%08x\t\t%08x\n"
+ "ISR1:\t\t%08x\t\t%08x\n"
+ "IMASK0:\t\t%08x\t\t%08x\n"
+ "IMASK1:\t\t%08x\t\t%08x\n",
+ coreb_base,
+ coreb_status & COREB_IS_RUNNING ? "running" : "stalled",
+ bfin_read_SICA_SYSCR(), bfin_read_SICB_SYSCR(),
+ bfin_read_SICA_ISR0(), bfin_read_SICB_ISR0(),
+ bfin_read_SICA_ISR1(), bfin_read_SICB_ISR0(),
+ bfin_read_SICA_IMASK0(), bfin_read_SICB_IMASK0(),
+ bfin_read_SICA_IMASK1(), bfin_read_SICB_IMASK1());
+}
+
+static DEVICE_ATTR(coreb_status, S_IRUGO, coreb_show_status, NULL);
+
+int __init bf561_coreb_init(void)
+{
+ init_waitqueue_head(&coreb_dma_wait);
+
+ spin_lock_init(&coreb_lock);
+ /* Request the core memory regions for Core B */
+ if (request_mem_region(0xff600000, 0x4000,
+ "Core B - Instruction SRAM") == NULL)
+ goto exit;
+
+ if (request_mem_region(0xFF610000, 0x4000,
+ "Core B - Instruction SRAM") == NULL)
+ goto release_instruction_a_sram;
+
+ if (request_mem_region(0xFF500000, 0x8000,
+ "Core B - Data Bank B SRAM") == NULL)
+ goto release_instruction_b_sram;
+
+ if (request_mem_region(0xff400000, 0x8000,
+ "Core B - Data Bank A SRAM") == NULL)
+ goto release_data_b_sram;
+
+ if (request_dma(CH_MEM_STREAM2_DEST, "Core B - DMA Destination") < 0)
+ goto release_data_a_sram;
+
+ if (request_dma(CH_MEM_STREAM2_SRC, "Core B - DMA Source") < 0)
+ goto release_dma_dest;
+
+ set_dma_callback(CH_MEM_STREAM2_DEST, coreb_dma_interrupt, NULL);
+
+ misc_register(&coreb_dev);
+
+ if (device_create_file(coreb_dev.this_device, &dev_attr_coreb_status))
+ goto release_dma_src;
+
+ printk(KERN_INFO "BF561 Core B driver %s initialized.\n", MODULE_VER);
+ return 0;
+
+ release_dma_src:
+ free_dma(CH_MEM_STREAM2_SRC);
+ release_dma_dest:
+ free_dma(CH_MEM_STREAM2_DEST);
+ release_data_a_sram:
+ release_mem_region(0xff400000, 0x8000);
+ release_data_b_sram:
+ release_mem_region(0xff500000, 0x8000);
+ release_instruction_b_sram:
+ release_mem_region(0xff610000, 0x4000);
+ release_instruction_a_sram:
+ release_mem_region(0xff600000, 0x4000);
+ exit:
+ return -ENOMEM;
+}
+
+void __exit bf561_coreb_exit(void)
+{
+ device_remove_file(coreb_dev.this_device, &dev_attr_coreb_status);
+ misc_deregister(&coreb_dev);
+
+ release_mem_region(0xff610000, 0x4000);
+ release_mem_region(0xff600000, 0x4000);
+ release_mem_region(0xff500000, 0x8000);
+ release_mem_region(0xff400000, 0x8000);
+
+ free_dma(CH_MEM_STREAM2_DEST);
+ free_dma(CH_MEM_STREAM2_SRC);
+}
+
+module_init(bf561_coreb_init);
+module_exit(bf561_coreb_exit);
+
+MODULE_AUTHOR("Bas Vermeulen <bvermeul@blackstar.xs4all.nl>");
+MODULE_DESCRIPTION("BF561 Core B Support");
diff --git a/arch/blackfin/mach-bf561/head.S b/arch/blackfin/mach-bf561/head.S
new file mode 100644
index 0000000..7bca478
--- /dev/null
+++ b/arch/blackfin/mach-bf561/head.S
@@ -0,0 +1,512 @@
+/*
+ * File: arch/blackfin/mach-bf561/head.S
+ * Based on: arch/blackfin/mach-bf533/head.S
+ * Author:
+ *
+ * Created:
+ * Description: BF561 startup file
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach/mem_init.h>
+#endif
+
+.global __rambase
+.global __ramstart
+.global __ramend
+.extern ___bss_stop
+.extern ___bss_start
+.extern _bf53x_relocate_l1_mem
+
+#define INITIAL_STACK 0xFFB01000
+
+.text
+
+ENTRY(__start)
+ENTRY(__stext)
+ /* R0: argument of command line string, passed from uboot, save it */
+ R7 = R0;
+ /* Set the SYSCFG register */
+ R0 = 0x36;
+ SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
+ R0 = 0;
+
+ /*Clear Out All the data and pointer Registers*/
+ R1 = R0;
+ R2 = R0;
+ R3 = R0;
+ R4 = R0;
+ R5 = R0;
+ R6 = R0;
+
+ P0 = R0;
+ P1 = R0;
+ P2 = R0;
+ P3 = R0;
+ P4 = R0;
+ P5 = R0;
+
+ LC0 = r0;
+ LC1 = r0;
+ L0 = r0;
+ L1 = r0;
+ L2 = r0;
+ L3 = r0;
+
+ /* Clear Out All the DAG Registers*/
+ B0 = r0;
+ B1 = r0;
+ B2 = r0;
+ B3 = r0;
+
+ I0 = r0;
+ I1 = r0;
+ I2 = r0;
+ I3 = r0;
+
+ M0 = r0;
+ M1 = r0;
+ M2 = r0;
+ M3 = r0;
+
+ /* Turn off the icache */
+ p0.l = (IMEM_CONTROL & 0xFFFF);
+ p0.h = (IMEM_CONTROL >> 16);
+ R1 = [p0];
+ R0 = ~ENICPLB;
+ R0 = R0 & R1;
+
+ /* Anomaly 05000125 */
+#ifdef ANOMALY_05000125
+ CLI R2;
+ SSYNC;
+#endif
+ [p0] = R0;
+ SSYNC;
+#ifdef ANOMALY_05000125
+ STI R2;
+#endif
+
+ /* Turn off the dcache */
+ p0.l = (DMEM_CONTROL & 0xFFFF);
+ p0.h = (DMEM_CONTROL >> 16);
+ R1 = [p0];
+ R0 = ~ENDCPLB;
+ R0 = R0 & R1;
+
+ /* Anomaly 05000125 */
+#ifdef ANOMALY_05000125
+ CLI R2;
+ SSYNC;
+#endif
+ [p0] = R0;
+ SSYNC;
+#ifdef ANOMALY_05000125
+ STI R2;
+#endif
+
+ /* Initialise UART*/
+ p0.h = hi(UART_LCR);
+ p0.l = lo(UART_LCR);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable DLL writes */
+ ssync;
+
+ p0.h = hi(UART_DLL);
+ p0.l = lo(UART_DLL);
+ r0 = 0x0(Z);
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART_DLH);
+ p0.l = lo(UART_DLH);
+ r0 = 0x00(Z);
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART_GCTL);
+ p0.l = lo(UART_GCTL);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable UART clock */
+ ssync;
+
+ /* Initialize stack pointer */
+ sp.l = lo(INITIAL_STACK);
+ sp.h = hi(INITIAL_STACK);
+ fp = sp;
+ usp = sp;
+
+ /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
+ call _bf53x_relocate_l1_mem;
+#if CONFIG_BFIN_KERNEL_CLOCK
+ call _start_dma_code;
+#endif
+
+ /* Code for initializing Async memory banks */
+
+ p2.h = hi(EBIU_AMBCTL1);
+ p2.l = lo(EBIU_AMBCTL1);
+ r0.h = hi(AMBCTL1VAL);
+ r0.l = lo(AMBCTL1VAL);
+ [p2] = r0;
+ ssync;
+
+ p2.h = hi(EBIU_AMBCTL0);
+ p2.l = lo(EBIU_AMBCTL0);
+ r0.h = hi(AMBCTL0VAL);
+ r0.l = lo(AMBCTL0VAL);
+ [p2] = r0;
+ ssync;
+
+ p2.h = hi(EBIU_AMGCTL);
+ p2.l = lo(EBIU_AMGCTL);
+ r0 = AMGCTLVAL;
+ w[p2] = r0;
+ ssync;
+
+ /* This section keeps the processor in supervisor mode
+ * during kernel boot. Switches to user mode at end of boot.
+ * See page 3-9 of Hardware Reference manual for documentation.
+ */
+
+ /* EVT15 = _real_start */
+
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _real_start;
+ p1.h = _real_start;
+ [p0] = p1;
+ csync;
+
+ p0.l = lo(IMASK);
+ p0.h = hi(IMASK);
+ p1.l = IMASK_IVG15;
+ p1.h = 0x0;
+ [p0] = p1;
+ csync;
+
+ raise 15;
+ p0.l = .LWAIT_HERE;
+ p0.h = .LWAIT_HERE;
+ reti = p0;
+#if defined(ANOMALY_05000281)
+ nop; nop; nop;
+#endif
+ rti;
+
+.LWAIT_HERE:
+ jump .LWAIT_HERE;
+
+ENTRY(_real_start)
+ [ -- sp ] = reti;
+ p0.l = lo(WDOGA_CTL);
+ p0.h = hi(WDOGA_CTL);
+ r0 = 0xAD6(z);
+ w[p0] = r0; /* watchdog off for now */
+ ssync;
+
+ /* Code update for BSS size == 0
+ * Zero out the bss region.
+ */
+
+ p1.l = ___bss_start;
+ p1.h = ___bss_start;
+ p2.l = ___bss_stop;
+ p2.h = ___bss_stop;
+ r0 = 0;
+ p2 -= p1;
+ lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2;
+.L_clear_bss:
+ B[p1++] = r0;
+
+ /* In case there is a NULL pointer reference
+ * Zero out region before stext
+ */
+
+ p1.l = 0x0;
+ p1.h = 0x0;
+ r0.l = __stext;
+ r0.h = __stext;
+ r0 = r0 >> 1;
+ p2 = r0;
+ r0 = 0;
+ lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2;
+.L_clear_zero:
+ W[p1++] = r0;
+
+/* pass the uboot arguments to the global value command line */
+ R0 = R7;
+ call _cmdline_init;
+
+ p1.l = __rambase;
+ p1.h = __rambase;
+ r0.l = __sdata;
+ r0.h = __sdata;
+ [p1] = r0;
+
+ p1.l = __ramstart;
+ p1.h = __ramstart;
+ p3.l = ___bss_stop;
+ p3.h = ___bss_stop;
+
+ r1 = p3;
+ [p1] = r1;
+
+ /*
+ * load the current thread pointer and stack
+ */
+ r1.l = _init_thread_union;
+ r1.h = _init_thread_union;
+
+ r2.l = 0x2000;
+ r2.h = 0x0000;
+ r1 = r1 + r2;
+ sp = r1;
+ usp = sp;
+ fp = sp;
+ call _start_kernel;
+.L_exit:
+ jump.s .L_exit;
+
+.section .l1.text
+#if CONFIG_BFIN_KERNEL_CLOCK
+ENTRY(_start_dma_code)
+ p0.h = hi(SICA_IWR0);
+ p0.l = lo(SICA_IWR0);
+ r0.l = 0x1;
+ [p0] = r0;
+ SSYNC;
+
+ /*
+ * Set PLL_CTL
+ * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
+ * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK
+ * - [7] = output delay (add 200ps of delay to mem signals)
+ * - [6] = input delay (add 200ps of input delay to mem signals)
+ * - [5] = PDWN : 1=All Clocks off
+ * - [3] = STOPCK : 1=Core Clock off
+ * - [1] = PLL_OFF : 1=Disable Power to PLL
+ * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
+ * all other bits set to zero
+ */
+
+ p0.h = hi(PLL_LOCKCNT);
+ p0.l = lo(PLL_LOCKCNT);
+ r0 = 0x300(Z);
+ w[p0] = r0.l;
+ ssync;
+
+ P2.H = hi(EBIU_SDGCTL);
+ P2.L = lo(EBIU_SDGCTL);
+ R0 = [P2];
+ BITSET (R0, 24);
+ [P2] = R0;
+ SSYNC;
+
+ r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
+ r0 = r0 << 9; /* Shift it over, */
+ r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/
+ r0 = r1 | r0;
+ r1 = PLL_BYPASS; /* Bypass the PLL? */
+ r1 = r1 << 8; /* Shift it over */
+ r0 = r1 | r0; /* add them all together */
+
+ p0.h = hi(PLL_CTL);
+ p0.l = lo(PLL_CTL); /* Load the address */
+ cli r2; /* Disable interrupts */
+ ssync;
+ w[p0] = r0.l; /* Set the value */
+ idle; /* Wait for the PLL to stablize */
+ sti r2; /* Enable interrupts */
+
+.Lcheck_again:
+ p0.h = hi(PLL_STAT);
+ p0.l = lo(PLL_STAT);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,5);
+ if ! CC jump .Lcheck_again;
+
+ /* Configure SCLK & CCLK Dividers */
+ r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
+ p0.h = hi(PLL_DIV);
+ p0.l = lo(PLL_DIV);
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = lo(EBIU_SDRRC);
+ p0.h = hi(EBIU_SDRRC);
+ r0 = mem_SDRRC;
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = (EBIU_SDBCTL & 0xFFFF);
+ p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */
+ r0 = mem_SDBCTL;
+ w[p0] = r0.l;
+ ssync;
+
+ P2.H = hi(EBIU_SDGCTL);
+ P2.L = lo(EBIU_SDGCTL);
+ R0 = [P2];
+ BITCLR (R0, 24);
+ p0.h = hi(EBIU_SDSTAT);
+ p0.l = lo(EBIU_SDSTAT);
+ r2.l = w[p0];
+ cc = bittst(r2,3);
+ if !cc jump .Lskip;
+ NOP;
+ BITSET (R0, 23);
+.Lskip:
+ [P2] = R0;
+ SSYNC;
+
+ R0.L = lo(mem_SDGCTL);
+ R0.H = hi(mem_SDGCTL);
+ R1 = [p2];
+ R1 = R1 | R0;
+ [P2] = R1;
+ SSYNC;
+
+ RTS;
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+ENTRY(_bfin_reset)
+ /* No more interrupts to be handled*/
+ CLI R6;
+ SSYNC;
+
+#if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
+ p0.h = hi(FIO_INEN);
+ p0.l = lo(FIO_INEN);
+ r0.l = ~(PF1 | PF0);
+ w[p0] = r0.l;
+
+ p0.h = hi(FIO_DIR);
+ p0.l = lo(FIO_DIR);
+ r0.l = (PF1 | PF0);
+ w[p0] = r0.l;
+
+ p0.h = hi(FIO_FLAG_C);
+ p0.l = lo(FIO_FLAG_C);
+ r0.l = (PF1 | PF0);
+ w[p0] = r0.l;
+#endif
+
+ /* Clear the bits 13-15 in SWRST if they werent cleared */
+ p0.h = hi(SICA_SWRST);
+ p0.l = lo(SICA_SWRST);
+ csync;
+ r0.l = w[p0];
+
+ /* Clear the IMASK register */
+ p0.h = hi(IMASK);
+ p0.l = lo(IMASK);
+ r0 = 0x0;
+ [p0] = r0;
+
+ /* Clear the ILAT register */
+ p0.h = hi(ILAT);
+ p0.l = lo(ILAT);
+ r0 = [p0];
+ [p0] = r0;
+ SSYNC;
+
+ /* Disable the WDOG TIMER */
+ p0.h = hi(WDOGA_CTL);
+ p0.l = lo(WDOGA_CTL);
+ r0.l = 0xAD6;
+ w[p0] = r0.l;
+ SSYNC;
+
+ /* Clear the sticky bit incase it is already set */
+ p0.h = hi(WDOGA_CTL);
+ p0.l = lo(WDOGA_CTL);
+ r0.l = 0x8AD6;
+ w[p0] = r0.l;
+ SSYNC;
+
+ /* Program the count value */
+ R0.l = 0x100;
+ R0.h = 0x0;
+ P0.h = hi(WDOGA_CNT);
+ P0.l = lo(WDOGA_CNT);
+ [P0] = R0;
+ SSYNC;
+
+ /* Program WDOG_STAT if necessary */
+ P0.h = hi(WDOGA_CTL);
+ P0.l = lo(WDOGA_CTL);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,1);
+ if !CC JUMP .LWRITESTAT;
+ CC = BITTST(R0,2);
+ if !CC JUMP .LWRITESTAT;
+ JUMP .LSKIP_WRITE;
+
+.LWRITESTAT:
+ /* When watch dog timer is enabled,
+ * a write to STAT will load the contents of CNT to STAT
+ */
+ R0 = 0x0000(z);
+ P0.h = hi(WDOGA_STAT);
+ P0.l = lo(WDOGA_STAT)
+ [P0] = R0;
+ SSYNC;
+
+.LSKIP_WRITE:
+ /* Enable the reset event */
+ P0.h = hi(WDOGA_CTL);
+ P0.l = lo(WDOGA_CTL);
+ R0 = W[P0](Z);
+ BITCLR(R0,1);
+ BITCLR(R0,2);
+ W[P0] = R0.L;
+ SSYNC;
+ NOP;
+
+ /* Enable the wdog counter */
+ R0 = W[P0](Z);
+ BITCLR(R0,4);
+ W[P0] = R0.L;
+ SSYNC;
+
+ IDLE;
+
+ RTS;
+
+.data
+
+/*
+ * Set up the usable of RAM stuff. Size of RAM is determined then
+ * an initial stack set up at the end.
+ */
+
+.align 4
+__rambase:
+.long 0
+__ramstart:
+.long 0
+__ramend:
+.long 0
diff --git a/arch/blackfin/mach-bf561/ints-priority.c b/arch/blackfin/mach-bf561/ints-priority.c
new file mode 100644
index 0000000..89c52ff
--- /dev/null
+++ b/arch/blackfin/mach-bf561/ints-priority.c
@@ -0,0 +1,108 @@
+/*
+ * File: arch/blackfin/mach-bf561/ints-priority.c
+ * Based on: arch/blackfin/mach-bf537/ints-priority.c
+ * Author: Michael Hennerich
+ *
+ * Created:
+ * Description: Set up the interupt priorities
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <asm/blackfin.h>
+#include <asm/irq.h>
+
+void program_IAR(void)
+{
+ /* Program the IAR0 Register with the configured priority */
+ bfin_write_SICA_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) |
+ ((CONFIG_IRQ_DMA1_ERROR - 7) << IRQ_DMA1_ERROR_POS) |
+ ((CONFIG_IRQ_DMA2_ERROR - 7) << IRQ_DMA2_ERROR_POS) |
+ ((CONFIG_IRQ_IMDMA_ERROR - 7) << IRQ_IMDMA_ERROR_POS) |
+ ((CONFIG_IRQ_PPI0_ERROR - 7) << IRQ_PPI0_ERROR_POS) |
+ ((CONFIG_IRQ_PPI1_ERROR - 7) << IRQ_PPI1_ERROR_POS) |
+ ((CONFIG_IRQ_SPORT0_ERROR - 7) << IRQ_SPORT0_ERROR_POS) |
+ ((CONFIG_IRQ_SPORT1_ERROR - 7) << IRQ_SPORT1_ERROR_POS));
+
+ bfin_write_SICA_IAR1(((CONFIG_IRQ_SPI_ERROR - 7) << IRQ_SPI_ERROR_POS) |
+ ((CONFIG_IRQ_UART_ERROR - 7) << IRQ_UART_ERROR_POS) |
+ ((CONFIG_IRQ_RESERVED_ERROR - 7) << IRQ_RESERVED_ERROR_POS) |
+ ((CONFIG_IRQ_DMA1_0 - 7) << IRQ_DMA1_0_POS) |
+ ((CONFIG_IRQ_DMA1_1 - 7) << IRQ_DMA1_1_POS) |
+ ((CONFIG_IRQ_DMA1_2 - 7) << IRQ_DMA1_2_POS) |
+ ((CONFIG_IRQ_DMA1_3 - 7) << IRQ_DMA1_3_POS) |
+ ((CONFIG_IRQ_DMA1_4 - 7) << IRQ_DMA1_4_POS));
+
+ bfin_write_SICA_IAR2(((CONFIG_IRQ_DMA1_5 - 7) << IRQ_DMA1_5_POS) |
+ ((CONFIG_IRQ_DMA1_6 - 7) << IRQ_DMA1_6_POS) |
+ ((CONFIG_IRQ_DMA1_7 - 7) << IRQ_DMA1_7_POS) |
+ ((CONFIG_IRQ_DMA1_8 - 7) << IRQ_DMA1_8_POS) |
+ ((CONFIG_IRQ_DMA1_9 - 7) << IRQ_DMA1_9_POS) |
+ ((CONFIG_IRQ_DMA1_10 - 7) << IRQ_DMA1_10_POS) |
+ ((CONFIG_IRQ_DMA1_11 - 7) << IRQ_DMA1_11_POS) |
+ ((CONFIG_IRQ_DMA2_0 - 7) << IRQ_DMA2_0_POS));
+
+ bfin_write_SICA_IAR3(((CONFIG_IRQ_DMA2_1 - 7) << IRQ_DMA2_1_POS) |
+ ((CONFIG_IRQ_DMA2_2 - 7) << IRQ_DMA2_2_POS) |
+ ((CONFIG_IRQ_DMA2_3 - 7) << IRQ_DMA2_3_POS) |
+ ((CONFIG_IRQ_DMA2_4 - 7) << IRQ_DMA2_4_POS) |
+ ((CONFIG_IRQ_DMA2_5 - 7) << IRQ_DMA2_5_POS) |
+ ((CONFIG_IRQ_DMA2_6 - 7) << IRQ_DMA2_6_POS) |
+ ((CONFIG_IRQ_DMA2_7 - 7) << IRQ_DMA2_7_POS) |
+ ((CONFIG_IRQ_DMA2_8 - 7) << IRQ_DMA2_8_POS));
+
+ bfin_write_SICA_IAR4(((CONFIG_IRQ_DMA2_9 - 7) << IRQ_DMA2_9_POS) |
+ ((CONFIG_IRQ_DMA2_10 - 7) << IRQ_DMA2_10_POS) |
+ ((CONFIG_IRQ_DMA2_11 - 7) << IRQ_DMA2_11_POS) |
+ ((CONFIG_IRQ_TIMER0 - 7) << IRQ_TIMER0_POS) |
+ ((CONFIG_IRQ_TIMER1 - 7) << IRQ_TIMER1_POS) |
+ ((CONFIG_IRQ_TIMER2 - 7) << IRQ_TIMER2_POS) |
+ ((CONFIG_IRQ_TIMER3 - 7) << IRQ_TIMER3_POS) |
+ ((CONFIG_IRQ_TIMER4 - 7) << IRQ_TIMER4_POS));
+
+ bfin_write_SICA_IAR5(((CONFIG_IRQ_TIMER5 - 7) << IRQ_TIMER5_POS) |
+ ((CONFIG_IRQ_TIMER6 - 7) << IRQ_TIMER6_POS) |
+ ((CONFIG_IRQ_TIMER7 - 7) << IRQ_TIMER7_POS) |
+ ((CONFIG_IRQ_TIMER8 - 7) << IRQ_TIMER8_POS) |
+ ((CONFIG_IRQ_TIMER9 - 7) << IRQ_TIMER9_POS) |
+ ((CONFIG_IRQ_TIMER10 - 7) << IRQ_TIMER10_POS) |
+ ((CONFIG_IRQ_TIMER11 - 7) << IRQ_TIMER11_POS) |
+ ((CONFIG_IRQ_PROG0_INTA - 7) << IRQ_PROG0_INTA_POS));
+
+ bfin_write_SICA_IAR6(((CONFIG_IRQ_PROG0_INTB - 7) << IRQ_PROG0_INTB_POS) |
+ ((CONFIG_IRQ_PROG1_INTA - 7) << IRQ_PROG1_INTA_POS) |
+ ((CONFIG_IRQ_PROG1_INTB - 7) << IRQ_PROG1_INTB_POS) |
+ ((CONFIG_IRQ_PROG2_INTA - 7) << IRQ_PROG2_INTA_POS) |
+ ((CONFIG_IRQ_PROG2_INTB - 7) << IRQ_PROG2_INTB_POS) |
+ ((CONFIG_IRQ_DMA1_WRRD0 - 7) << IRQ_DMA1_WRRD0_POS) |
+ ((CONFIG_IRQ_DMA1_WRRD1 - 7) << IRQ_DMA1_WRRD1_POS) |
+ ((CONFIG_IRQ_DMA2_WRRD0 - 7) << IRQ_DMA2_WRRD0_POS));
+
+ bfin_write_SICA_IAR7(((CONFIG_IRQ_DMA2_WRRD1 - 7) << IRQ_DMA2_WRRD1_POS) |
+ ((CONFIG_IRQ_IMDMA_WRRD0 - 7) << IRQ_IMDMA_WRRD0_POS) |
+ ((CONFIG_IRQ_IMDMA_WRRD1 - 7) << IRQ_IMDMA_WRRD1_POS) |
+ ((CONFIG_IRQ_WDTIMER - 7) << IRQ_WDTIMER_POS) |
+ (0 << IRQ_RESERVED_1_POS) | (0 << IRQ_RESERVED_2_POS) |
+ (0 << IRQ_SUPPLE_0_POS) | (0 << IRQ_SUPPLE_1_POS));
+
+ SSYNC();
+}
diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile
new file mode 100644
index 0000000..d3a4907
--- /dev/null
+++ b/arch/blackfin/mach-common/Makefile
@@ -0,0 +1,12 @@
+#
+# arch/blackfin/mach-common/Makefile
+#
+
+obj-y := \
+ cache.o cacheinit.o cplbhdlr.o cplbmgr.o entry.o \
+ interrupt.o lock.o dpmc.o irqpanic.o
+
+obj-$(CONFIG_CPLB_INFO) += cplbinfo.o
+obj-$(CONFIG_BFIN_SINGLE_CORE) += ints-priority-sc.o
+obj-$(CONFIG_BFIN_DUAL_CORE) += ints-priority-dc.o
+obj-$(CONFIG_PM) += pm.o
diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S
new file mode 100644
index 0000000..bb9446e
--- /dev/null
+++ b/arch/blackfin/mach-common/cache.S
@@ -0,0 +1,253 @@
+/*
+ * File: arch/blackfin/mach-common/cache.S
+ * Based on:
+ * Author: LG Soft India
+ *
+ * Created:
+ * Description: cache control support
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/cplb.h>
+#include <asm/entry.h>
+#include <asm/blackfin.h>
+#include <asm/cache.h>
+
+.text
+.align 2
+ENTRY(_cache_invalidate)
+
+ /*
+ * Icache or DcacheA or DcacheB Invalidation
+ * or any combination thereof
+ * R0 has bits
+ * CPLB_ENABLE_ICACHE_P,CPLB_ENABLE_DCACHE_P,CPLB_ENABLE_DCACHE2_P
+ * set as required
+ */
+ [--SP] = R7;
+
+ R7 = R0;
+ CC = BITTST(R7,CPLB_ENABLE_ICACHE_P);
+ IF !CC JUMP .Lno_icache;
+ [--SP] = RETS;
+ CALL _icache_invalidate;
+ RETS = [SP++];
+.Lno_icache:
+ CC = BITTST(R7,CPLB_ENABLE_DCACHE_P);
+ IF !CC JUMP .Lno_dcache_a;
+ R0 = 0; /* specifies bank A */
+ [--SP] = RETS;
+ CALL _dcache_invalidate;
+ RETS = [SP++];
+.Lno_dcache_a:
+ CC = BITTST(R7,CPLB_ENABLE_DCACHE2_P);
+ IF !CC JUMP .Lno_dcache_b;
+ R0 = 0;
+ BITSET(R0, 23); /* specifies bank B */
+ [--SP] = RETS;
+ CALL _dcache_invalidate;
+ RETS = [SP++];
+.Lno_dcache_b:
+ R7 = [SP++];
+ RTS;
+
+/* Invalidate the Entire Instruction cache by
+ * disabling IMC bit
+ */
+ENTRY(_icache_invalidate)
+ENTRY(_invalidate_entire_icache)
+ [--SP] = ( R7:5);
+
+ P0.L = (IMEM_CONTROL & 0xFFFF);
+ P0.H = (IMEM_CONTROL >> 16);
+ R7 = [P0];
+
+ /* Clear the IMC bit , All valid bits in the instruction
+ * cache are set to the invalid state
+ */
+ BITCLR(R7,IMC_P);
+ CLI R6;
+ SSYNC; /* SSYNC required before invalidating cache. */
+ .align 8;
+ [P0] = R7;
+ SSYNC;
+ STI R6;
+
+ /* Configures the instruction cache agian */
+ R6 = (IMC | ENICPLB);
+ R7 = R7 | R6;
+
+ CLI R6;
+ SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
+ .align 8;
+ [P0] = R7;
+ SSYNC;
+ STI R6;
+
+ ( R7:5) = [SP++];
+ RTS;
+
+/*
+ * blackfin_cache_flush_range(start, end)
+ * Invalidate all cache lines assocoiated with this
+ * area of memory.
+ *
+ * start: Start address
+ * end: End address
+ */
+ENTRY(_blackfin_icache_flush_range)
+ R2 = -L1_CACHE_BYTES;
+ R2 = R0 & R2;
+ P0 = R2;
+ P1 = R1;
+ CSYNC;
+ IFLUSH [P0];
+1:
+ IFLUSH [P0++];
+ CC = P0 < P1 (iu);
+ IF CC JUMP 1b (bp);
+ IFLUSH [P0];
+ SSYNC;
+ RTS;
+
+/*
+ * blackfin_icache_dcache_flush_range(start, end)
+ * FLUSH all cache lines assocoiated with this
+ * area of memory.
+ *
+ * start: Start address
+ * end: End address
+ */
+
+ENTRY(_blackfin_icache_dcache_flush_range)
+ R2 = -L1_CACHE_BYTES;
+ R2 = R0 & R2;
+ P0 = R2;
+ P1 = R1;
+ CSYNC;
+ IFLUSH [P0];
+1:
+ FLUSH [P0];
+ IFLUSH [P0++];
+ CC = P0 < P1 (iu);
+ IF CC JUMP 1b (bp);
+ IFLUSH [P0];
+ FLUSH [P0];
+ SSYNC;
+ RTS;
+
+/* Throw away all D-cached data in specified region without any obligation to
+ * write them back. However, we must clean the D-cached entries around the
+ * boundaries of the start and/or end address is not cache aligned.
+ *
+ * Start: start address,
+ * end : end address.
+ */
+
+ENTRY(_blackfin_dcache_invalidate_range)
+ R2 = -L1_CACHE_BYTES;
+ R2 = R0 & R2;
+ P0 = R2;
+ P1 = R1;
+ CSYNC;
+ FLUSHINV[P0];
+1:
+ FLUSHINV[P0++];
+ CC = P0 < P1 (iu);
+ IF CC JUMP 1b (bp);
+
+ /* If the data crosses a cache line, then we'll be pointing to
+ * the last cache line, but won't have flushed/invalidated it yet,
+ * so do one more.
+ */
+ FLUSHINV[P0];
+ SSYNC;
+ RTS;
+
+/* Invalidate the Entire Data cache by
+ * clearing DMC[1:0] bits
+ */
+ENTRY(_invalidate_entire_dcache)
+ENTRY(_dcache_invalidate)
+ [--SP] = ( R7:6);
+
+ P0.L = (DMEM_CONTROL & 0xFFFF);
+ P0.H = (DMEM_CONTROL >> 16);
+ R7 = [P0];
+
+ /* Clear the DMC[1:0] bits, All valid bits in the data
+ * cache are set to the invalid state
+ */
+ BITCLR(R7,DMC0_P);
+ BITCLR(R7,DMC1_P);
+ CLI R6;
+ SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
+ .align 8;
+ [P0] = R7;
+ SSYNC;
+ STI R6;
+
+ /* Configures the data cache again */
+
+ R6 = DMEM_CNTR;
+ R7 = R7 | R6;
+
+ CLI R6;
+ SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
+ .align 8;
+ [P0] = R7;
+ SSYNC;
+ STI R6;
+
+ ( R7:6) = [SP++];
+ RTS;
+
+ENTRY(_blackfin_dcache_flush_range)
+ R2 = -L1_CACHE_BYTES;
+ R2 = R0 & R2;
+ P0 = R2;
+ P1 = R1;
+ CSYNC;
+ FLUSH[P0];
+1:
+ FLUSH[P0++];
+ CC = P0 < P1 (iu);
+ IF CC JUMP 1b (bp);
+
+ /* If the data crosses a cache line, then we'll be pointing to
+ * the last cache line, but won't have flushed it yet, so do
+ * one more.
+ */
+ FLUSH[P0];
+ SSYNC;
+ RTS;
+
+ENTRY(_blackfin_dflush_page)
+ P1 = 1 << (PAGE_SHIFT - L1_CACHE_SHIFT);
+ P0 = R0;
+ CSYNC;
+ FLUSH[P0];
+ LSETUP (.Lfl1, .Lfl1) LC0 = P1;
+.Lfl1: FLUSH [P0++];
+ SSYNC;
+ RTS;
diff --git a/arch/blackfin/mach-common/cacheinit.S b/arch/blackfin/mach-common/cacheinit.S
new file mode 100644
index 0000000..8c17f09
--- /dev/null
+++ b/arch/blackfin/mach-common/cacheinit.S
@@ -0,0 +1,137 @@
+/*
+ * File: arch/blackfin/mach-common/cacheinit.S
+ * Based on:
+ * Author: LG Soft India
+ *
+ * Created: ?
+ * Description: cache initialization
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This function sets up the data and instruction cache. The
+ * tables like icplb table, dcplb table and Page Descriptor table
+ * are defined in cplbtab.h. You can configure those tables for
+ * your suitable requirements
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+
+.text
+
+#if defined(CONFIG_BLKFIN_CACHE)
+ENTRY(_bfin_icache_init)
+
+ /* Initialize Instruction CPLBS */
+
+ I0.L = (ICPLB_ADDR0 & 0xFFFF);
+ I0.H = (ICPLB_ADDR0 >> 16);
+
+ I1.L = (ICPLB_DATA0 & 0xFFFF);
+ I1.H = (ICPLB_DATA0 >> 16);
+
+ I2.L = _icplb_table;
+ I2.H = _icplb_table;
+
+ r1 = -1; /* end point comparison */
+ r3 = 15; /* max counter */
+
+/* read entries from table */
+
+.Lread_iaddr:
+ R0 = [I2++];
+ CC = R0 == R1;
+ IF CC JUMP .Lidone;
+ [I0++] = R0;
+
+.Lread_idata:
+ R2 = [I2++];
+ [I1++] = R2;
+ R3 = R3 + R1;
+ CC = R3 == R1;
+ IF !CC JUMP .Lread_iaddr;
+
+.Lidone:
+ /* Enable Instruction Cache */
+ P0.l = (IMEM_CONTROL & 0xFFFF);
+ P0.h = (IMEM_CONTROL >> 16);
+ R1 = [P0];
+ R0 = (IMC | ENICPLB);
+ R0 = R0 | R1;
+
+ /* Anomaly 05000125 */
+ CLI R2;
+ SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
+ .align 8;
+ [P0] = R0;
+ SSYNC;
+ STI R2;
+ RTS;
+#endif
+
+#if defined(CONFIG_BLKFIN_DCACHE)
+ENTRY(_bfin_dcache_init)
+
+ /* Initialize Data CPLBS */
+
+ I0.L = (DCPLB_ADDR0 & 0xFFFF);
+ I0.H = (DCPLB_ADDR0 >> 16);
+
+ I1.L = (DCPLB_DATA0 & 0xFFFF);
+ I1.H = (DCPLB_DATA0 >> 16);
+
+ I2.L = _dcplb_table;
+ I2.H = _dcplb_table;
+
+ R1 = -1; /* end point comparison */
+ R3 = 15; /* max counter */
+
+ /* read entries from table */
+.Lread_daddr:
+ R0 = [I2++];
+ cc = R0 == R1;
+ IF CC JUMP .Lddone;
+ [I0++] = R0;
+
+.Lread_ddata:
+ R2 = [I2++];
+ [I1++] = R2;
+ R3 = R3 + R1;
+ CC = R3 == R1;
+ IF !CC JUMP .Lread_daddr;
+.Lddone:
+ P0.L = (DMEM_CONTROL & 0xFFFF);
+ P0.H = (DMEM_CONTROL >> 16);
+ R1 = [P0];
+
+ R0 = DMEM_CNTR;
+
+ R0 = R0 | R1;
+ /* Anomaly 05000125 */
+ CLI R2;
+ SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
+ .align 8;
+ [P0] = R0;
+ SSYNC;
+ STI R2;
+ RTS;
+#endif
diff --git a/arch/blackfin/mach-common/cplbhdlr.S b/arch/blackfin/mach-common/cplbhdlr.S
new file mode 100644
index 0000000..b979067
--- /dev/null
+++ b/arch/blackfin/mach-common/cplbhdlr.S
@@ -0,0 +1,130 @@
+/*
+ * File: arch/blackfin/mach-common/cplbhdlr.S
+ * Based on:
+ * Author: LG Soft India
+ *
+ * Created: ?
+ * Description: CPLB exception handler
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/cplb.h>
+#include <asm/entry.h>
+
+#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
+.section .l1.text
+#else
+.text
+#endif
+
+.type _cplb_mgr, STT_FUNC;
+.type _panic_cplb_error, STT_FUNC;
+
+.align 2
+
+.global __cplb_hdr;
+.type __cplb_hdr, STT_FUNC;
+ENTRY(__cplb_hdr)
+ R2 = SEQSTAT;
+
+ /* Mask the contents of SEQSTAT and leave only EXCAUSE in R2 */
+ R2 <<= 26;
+ R2 >>= 26;
+
+ R1 = 0x23; /* Data access CPLB protection violation */
+ CC = R2 == R1;
+ IF !CC JUMP .Lnot_data_write;
+ R0 = 2; /* is a write to data space*/
+ JUMP .Lis_icplb_miss;
+
+.Lnot_data_write:
+ R1 = 0x2C; /* CPLB miss on an instruction fetch */
+ CC = R2 == R1;
+ R0 = 0; /* is_data_miss == False*/
+ IF CC JUMP .Lis_icplb_miss;
+
+ R1 = 0x26;
+ CC = R2 == R1;
+ IF !CC JUMP .Lunknown;
+
+ R0 = 1; /* is_data_miss == True*/
+
+.Lis_icplb_miss:
+
+#if defined(CONFIG_BLKFIN_CACHE) || defined(CONFIG_BLKFIN_DCACHE)
+# if defined(CONFIG_BLKFIN_CACHE) && !defined(CONFIG_BLKFIN_DCACHE)
+ R1 = CPLB_ENABLE_ICACHE;
+# endif
+# if !defined(CONFIG_BLKFIN_CACHE) && defined(CONFIG_BLKFIN_DCACHE)
+ R1 = CPLB_ENABLE_DCACHE;
+# endif
+# if defined(CONFIG_BLKFIN_CACHE) && defined(CONFIG_BLKFIN_DCACHE)
+ R1 = CPLB_ENABLE_DCACHE | CPLB_ENABLE_ICACHE;
+# endif
+#else
+ R1 = 0;
+#endif
+
+ [--SP] = RETS;
+ CALL _cplb_mgr;
+ RETS = [SP++];
+ CC = R0 == 0;
+ IF !CC JUMP .Lnot_replaced;
+ RTS;
+
+/*
+ * Diagnostic exception handlers
+ */
+.Lunknown:
+ R0 = CPLB_UNKNOWN_ERR;
+ JUMP .Lcplb_error;
+
+.Lnot_replaced:
+ CC = R0 == CPLB_NO_UNLOCKED;
+ IF !CC JUMP .Lnext_check;
+ R0 = CPLB_NO_UNLOCKED;
+ JUMP .Lcplb_error;
+
+.Lnext_check:
+ CC = R0 == CPLB_NO_ADDR_MATCH;
+ IF !CC JUMP .Lnext_check2;
+ R0 = CPLB_NO_ADDR_MATCH;
+ JUMP .Lcplb_error;
+
+.Lnext_check2:
+ CC = R0 == CPLB_PROT_VIOL;
+ IF !CC JUMP .Lstrange_return_from_cplb_mgr;
+ R0 = CPLB_PROT_VIOL;
+ JUMP .Lcplb_error;
+
+.Lstrange_return_from_cplb_mgr:
+ IDLE;
+ CSYNC;
+ JUMP .Lstrange_return_from_cplb_mgr;
+
+.Lcplb_error:
+ R1 = sp;
+ SP += -12;
+ call _panic_cplb_error;
+ SP += 12;
+ JUMP _handle_bad_cplb;
diff --git a/arch/blackfin/mach-common/cplbinfo.c b/arch/blackfin/mach-common/cplbinfo.c
new file mode 100644
index 0000000..d65fac3
--- /dev/null
+++ b/arch/blackfin/mach-common/cplbinfo.c
@@ -0,0 +1,211 @@
+/*
+ * File: arch/blackfin/mach-common/cplbinfo.c
+ * Based on:
+ * Author: Sonic Zhang <sonic.zhang@analog.com>
+ *
+ * Created: Jan. 2005
+ * Description: Display CPLB status
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+
+#include <asm/current.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+#include <asm/cplb.h>
+#include <asm/blackfin.h>
+
+#define CPLB_I 1
+#define CPLB_D 2
+
+#define SYNC_SYS SSYNC()
+#define SYNC_CORE CSYNC()
+
+#define CPLB_BIT_PAGESIZE 0x30000
+
+static int page_size_table[4] = {
+ 0x00000400, /* 1K */
+ 0x00001000, /* 4K */
+ 0x00100000, /* 1M */
+ 0x00400000 /* 4M */
+};
+
+static char page_size_string_table[][4] = { "1K", "4K", "1M", "4M" };
+
+static int cplb_find_entry(unsigned long *cplb_addr,
+ unsigned long *cplb_data, unsigned long addr,
+ unsigned long data)
+{
+ int ii;
+
+ for (ii = 0; ii < 16; ii++)
+ if (addr >= cplb_addr[ii] && addr < cplb_addr[ii] +
+ page_size_table[(cplb_data[ii] & CPLB_BIT_PAGESIZE) >> 16]
+ && (cplb_data[ii] == data))
+ return ii;
+
+ return -1;
+}
+
+static char *cplb_print_entry(char *buf, int type)
+{
+ unsigned long *p_addr = dpdt_table;
+ unsigned long *p_data = dpdt_table + 1;
+ unsigned long *p_icount = dpdt_swapcount_table;
+ unsigned long *p_ocount = dpdt_swapcount_table + 1;
+ unsigned long *cplb_addr = (unsigned long *)DCPLB_ADDR0;
+ unsigned long *cplb_data = (unsigned long *)DCPLB_DATA0;
+ int entry = 0, used_cplb = 0;
+
+ if (type == CPLB_I) {
+ buf += sprintf(buf, "Instrction CPLB entry:\n");
+ p_addr = ipdt_table;
+ p_data = ipdt_table + 1;
+ p_icount = ipdt_swapcount_table;
+ p_ocount = ipdt_swapcount_table + 1;
+ cplb_addr = (unsigned long *)ICPLB_ADDR0;
+ cplb_data = (unsigned long *)ICPLB_DATA0;
+ } else
+ buf += sprintf(buf, "Data CPLB entry:\n");
+
+ buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\
+\tiCount\toCount\n");
+
+ while (*p_addr != 0xffffffff) {
+ entry = cplb_find_entry(cplb_addr, cplb_data, *p_addr, *p_data);
+ if (entry >= 0)
+ used_cplb |= 1 << entry;
+
+ buf +=
+ sprintf(buf,
+ "0x%08lx\t0x%05lx\t%s\t%c\t%c\t%2d\t%ld\t%ld\n",
+ *p_addr, *p_data,
+ page_size_string_table[(*p_data & 0x30000) >> 16],
+ (*p_data & CPLB_VALID) ? 'Y' : 'N',
+ (*p_data & CPLB_LOCK) ? 'Y' : 'N', entry, *p_icount,
+ *p_ocount);
+
+ p_addr += 2;
+ p_data += 2;
+ p_icount += 2;
+ p_ocount += 2;
+ }
+
+ if (used_cplb != 0xffff) {
+ buf += sprintf(buf, "Unused/mismatched CPLBs:\n");
+
+ for (entry = 0; entry < 16; entry++)
+ if (0 == ((1 << entry) & used_cplb)) {
+ int flags = cplb_data[entry];
+ buf +=
+ sprintf(buf,
+ "%2d: 0x%08lx\t0x%05x\t%s\t%c\t%c\n",
+ entry, cplb_addr[entry], flags,
+ page_size_string_table[(flags &
+ 0x30000) >>
+ 16],
+ (flags & CPLB_VALID) ? 'Y' : 'N',
+ (flags & CPLB_LOCK) ? 'Y' : 'N');
+ }
+ }
+
+ buf += sprintf(buf, "\n");
+
+ return buf;
+}
+
+static int cplbinfo_proc_output(char *buf)
+{
+ char *p;
+
+ p = buf;
+
+ p += sprintf(p,
+ "------------------ CPLB Information ------------------\n\n");
+
+ if (bfin_read_IMEM_CONTROL() & ENICPLB)
+ p = cplb_print_entry(p, CPLB_I);
+ else
+ p += sprintf(p, "Instruction CPLB is disabled.\n\n");
+
+ if (bfin_read_DMEM_CONTROL() & ENDCPLB)
+ p = cplb_print_entry(p, CPLB_D);
+ else
+ p += sprintf(p, "Data CPLB is disabled.\n");
+
+ return p - buf;
+}
+
+static int cplbinfo_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len;
+
+ len = cplbinfo_proc_output(page);
+ if (len <= off + count)
+ *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len > count)
+ len = count;
+ if (len < 0)
+ len = 0;
+ return len;
+}
+
+static int cplbinfo_write_proc(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
+{
+ printk(KERN_INFO "Reset the CPLB swap in/out counts.\n");
+ memset(ipdt_swapcount_table, 0, MAX_SWITCH_I_CPLBS * sizeof(unsigned long));
+ memset(dpdt_swapcount_table, 0, MAX_SWITCH_D_CPLBS * sizeof(unsigned long));
+
+ return count;
+}
+
+static int __init cplbinfo_init(void)
+{
+ struct proc_dir_entry *entry;
+
+ if ((entry = create_proc_entry("cplbinfo", 0, NULL)) == NULL) {
+ return -ENOMEM;
+ }
+
+ entry->read_proc = cplbinfo_read_proc;
+ entry->write_proc = cplbinfo_write_proc;
+ entry->data = NULL;
+
+ return 0;
+}
+
+static void __exit cplbinfo_exit(void)
+{
+ remove_proc_entry("cplbinfo", NULL);
+}
+
+module_init(cplbinfo_init);
+module_exit(cplbinfo_exit);
diff --git a/arch/blackfin/mach-common/cplbmgr.S b/arch/blackfin/mach-common/cplbmgr.S
new file mode 100644
index 0000000..f5efc4b
--- /dev/null
+++ b/arch/blackfin/mach-common/cplbmgr.S
@@ -0,0 +1,607 @@
+/*
+ * File: arch/blackfin/mach-common/cplbmgtr.S
+ * Based on:
+ * Author: LG Soft India
+ *
+ * Created: ?
+ * Description: CPLB replacement routine for CPLB mismatch
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Usage: int _cplb_mgr(is_data_miss,int enable_cache)
+ * is_data_miss==2 => Mark as Dirty, write to the clean data page
+ * is_data_miss==1 => Replace a data CPLB.
+ * is_data_miss==0 => Replace an instruction CPLB.
+ *
+ * Returns:
+ * CPLB_RELOADED => Successfully updated CPLB table.
+ * CPLB_NO_UNLOCKED => All CPLBs are locked, so cannot be evicted.
+ * This indicates that the CPLBs in the configuration
+ * tablei are badly configured, as this should never
+ * occur.
+ * CPLB_NO_ADDR_MATCH => The address being accessed, that triggered the
+ * exception, is not covered by any of the CPLBs in
+ * the configuration table. The application is
+ * presumably misbehaving.
+ * CPLB_PROT_VIOL => The address being accessed, that triggered the
+ * exception, was not a first-write to a clean Write
+ * Back Data page, and so presumably is a genuine
+ * violation of the page's protection attributes.
+ * The application is misbehaving.
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#include <asm/cplb.h>
+
+#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
+.section .l1.text
+#else
+.text
+#endif
+
+.align 2;
+ENTRY(_cplb_mgr)
+
+ [--SP]=( R7:4,P5:3 );
+
+ CC = R0 == 2;
+ IF CC JUMP .Ldcplb_write;
+
+ CC = R0 == 0;
+ IF !CC JUMP .Ldcplb_miss_compare;
+
+ /* ICPLB Miss Exception. We need to choose one of the
+ * currently-installed CPLBs, and replace it with one
+ * from the configuration table.
+ */
+
+ P4.L = (ICPLB_FAULT_ADDR & 0xFFFF);
+ P4.H = (ICPLB_FAULT_ADDR >> 16);
+
+ P1 = 16;
+ P5.L = _page_size_table;
+ P5.H = _page_size_table;
+
+ P0.L = (ICPLB_DATA0 & 0xFFFF);
+ P0.H = (ICPLB_DATA0 >> 16);
+ R4 = [P4]; /* Get faulting address*/
+ R6 = 64; /* Advance past the fault address, which*/
+ R6 = R6 + R4; /* we'll use if we find a match*/
+ R3 = ((16 << 8) | 2); /* Extract mask, bits 16 and 17.*/
+
+ R5 = 0;
+.Lisearch:
+
+ R1 = [P0-0x100]; /* Address for this CPLB */
+
+ R0 = [P0++]; /* Info for this CPLB*/
+ CC = BITTST(R0,0); /* Is the CPLB valid?*/
+ IF !CC JUMP .Lnomatch; /* Skip it, if not.*/
+ CC = R4 < R1(IU); /* If fault address less than page start*/
+ IF CC JUMP .Lnomatch; /* then skip this one.*/
+ R2 = EXTRACT(R0,R3.L) (Z); /* Get page size*/
+ P1 = R2;
+ P1 = P5 + (P1<<2); /* index into page-size table*/
+ R2 = [P1]; /* Get the page size*/
+ R1 = R1 + R2; /* and add to page start, to get page end*/
+ CC = R4 < R1(IU); /* and see whether fault addr is in page.*/
+ IF !CC R4 = R6; /* If so, advance the address and finish loop.*/
+ IF !CC JUMP .Lisearch_done;
+.Lnomatch:
+ /* Go around again*/
+ R5 += 1;
+ CC = BITTST(R5, 4); /* i.e CC = R5 >= 16*/
+ IF !CC JUMP .Lisearch;
+
+.Lisearch_done:
+ I0 = R4; /* Fault address we'll search for*/
+
+ /* set up pointers */
+ P0.L = (ICPLB_DATA0 & 0xFFFF);
+ P0.H = (ICPLB_DATA0 >> 16);
+
+ /* The replacement procedure for ICPLBs */
+
+ P4.L = (IMEM_CONTROL & 0xFFFF);
+ P4.H = (IMEM_CONTROL >> 16);
+
+ /* disable cplbs */
+ R5 = [P4]; /* Control Register*/
+ BITCLR(R5,ENICPLB_P);
+ CLI R1;
+ SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
+ .align 8;
+ [P4] = R5;
+ SSYNC;
+ STI R1;
+
+ R1 = -1; /* end point comparison */
+ R3 = 16; /* counter */
+
+ /* Search through CPLBs for first non-locked entry */
+ /* Overwrite it by moving everyone else up by 1 */
+.Licheck_lock:
+ R0 = [P0++];
+ R3 = R3 + R1;
+ CC = R3 == R1;
+ IF CC JUMP .Lall_locked;
+ CC = BITTST(R0, 0); /* an invalid entry is good */
+ IF !CC JUMP .Lifound_victim;
+ CC = BITTST(R0,1); /* but a locked entry isn't */
+ IF CC JUMP .Licheck_lock;
+
+.Lifound_victim:
+#ifdef CONFIG_CPLB_INFO
+ R7 = [P0 - 0x104];
+ P2.L = _ipdt_table;
+ P2.H = _ipdt_table;
+ P3.L = _ipdt_swapcount_table;
+ P3.H = _ipdt_swapcount_table;
+ P3 += -4;
+.Licount:
+ R2 = [P2]; /* address from config table */
+ P2 += 8;
+ P3 += 8;
+ CC = R2==-1;
+ IF CC JUMP .Licount_done;
+ CC = R7==R2;
+ IF !CC JUMP .Licount;
+ R7 = [P3];
+ R7 += 1;
+ [P3] = R7;
+ CSYNC;
+.Licount_done:
+#endif
+ LC0=R3;
+ LSETUP(.Lis_move,.Lie_move) LC0;
+.Lis_move:
+ R0 = [P0];
+ [P0 - 4] = R0;
+ R0 = [P0 - 0x100];
+ [P0-0x104] = R0;
+.Lie_move:P0+=4;
+
+ /* We've made space in the ICPLB table, so that ICPLB15
+ * is now free to be overwritten. Next, we have to determine
+ * which CPLB we need to install, from the configuration
+ * table. This is a matter of getting the start-of-page
+ * addresses and page-lengths from the config table, and
+ * determining whether the fault address falls within that
+ * range.
+ */
+
+ P2.L = _ipdt_table;
+ P2.H = _ipdt_table;
+#ifdef CONFIG_CPLB_INFO
+ P3.L = _ipdt_swapcount_table;
+ P3.H = _ipdt_swapcount_table;
+ P3 += -8;
+#endif
+ P0.L = _page_size_table;
+ P0.H = _page_size_table;
+
+ /* Retrieve our fault address (which may have been advanced
+ * because the faulting instruction crossed a page boundary).
+ */
+
+ R0 = I0;
+
+ /* An extraction pattern, to get the page-size bits from
+ * the CPLB data entry. Bits 16-17, so two bits at posn 16.
+ */
+
+ R1 = ((16<<8)|2);
+.Linext: R4 = [P2++]; /* address from config table */
+ R2 = [P2++]; /* data from config table */
+#ifdef CONFIG_CPLB_INFO
+ P3 += 8;
+#endif
+
+ CC = R4 == -1; /* End of config table*/
+ IF CC JUMP .Lno_page_in_table;
+
+ /* See if failed address > start address */
+ CC = R4 <= R0(IU);
+ IF !CC JUMP .Linext;
+
+ /* extract page size (17:16)*/
+ R3 = EXTRACT(R2, R1.L) (Z);
+
+ /* add page size to addr to get range */
+
+ P5 = R3;
+ P5 = P0 + (P5 << 2); /* scaled, for int access*/
+ R3 = [P5];
+ R3 = R3 + R4;
+
+ /* See if failed address < (start address + page size) */
+ CC = R0 < R3(IU);
+ IF !CC JUMP .Linext;
+
+ /* We've found a CPLB in the config table that covers
+ * the faulting address, so install this CPLB into the
+ * last entry of the table.
+ */
+
+ P1.L = (ICPLB_DATA15 & 0xFFFF); /* ICPLB_DATA15 */
+ P1.H = (ICPLB_DATA15 >> 16);
+ [P1] = R2;
+ [P1-0x100] = R4;
+#ifdef CONFIG_CPLB_INFO
+ R3 = [P3];
+ R3 += 1;
+ [P3] = R3;
+#endif
+
+ /* P4 points to IMEM_CONTROL, and R5 contains its old
+ * value, after we disabled ICPLBS. Re-enable them.
+ */
+
+ BITSET(R5,ENICPLB_P);
+ CLI R2;
+ SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
+ .align 8;
+ [P4] = R5;
+ SSYNC;
+ STI R2;
+
+ ( R7:4,P5:3 ) = [SP++];
+ R0 = CPLB_RELOADED;
+ RTS;
+
+/* FAILED CASES*/
+.Lno_page_in_table:
+ ( R7:4,P5:3 ) = [SP++];
+ R0 = CPLB_NO_ADDR_MATCH;
+ RTS;
+.Lall_locked:
+ ( R7:4,P5:3 ) = [SP++];
+ R0 = CPLB_NO_UNLOCKED;
+ RTS;
+.Lprot_violation:
+ ( R7:4,P5:3 ) = [SP++];
+ R0 = CPLB_PROT_VIOL;
+ RTS;
+
+.Ldcplb_write:
+
+ /* if a DCPLB is marked as write-back (CPLB_WT==0), and
+ * it is clean (CPLB_DIRTY==0), then a write to the
+ * CPLB's page triggers a protection violation. We have to
+ * mark the CPLB as dirty, to indicate that there are
+ * pending writes associated with the CPLB.
+ */
+
+ P4.L = (DCPLB_STATUS & 0xFFFF);
+ P4.H = (DCPLB_STATUS >> 16);
+ P3.L = (DCPLB_DATA0 & 0xFFFF);
+ P3.H = (DCPLB_DATA0 >> 16);
+ R5 = [P4];
+
+ /* A protection violation can be caused by more than just writes
+ * to a clean WB page, so we have to ensure that:
+ * - It's a write
+ * - to a clean WB page
+ * - and is allowed in the mode the access occurred.
+ */
+
+ CC = BITTST(R5, 16); /* ensure it was a write*/
+ IF !CC JUMP .Lprot_violation;
+
+ /* to check the rest, we have to retrieve the DCPLB.*/
+
+ /* The low half of DCPLB_STATUS is a bit mask*/
+
+ R2 = R5.L (Z); /* indicating which CPLB triggered the event.*/
+ R3 = 30; /* so we can use this to determine the offset*/
+ R2.L = SIGNBITS R2;
+ R2 = R2.L (Z); /* into the DCPLB table.*/
+ R3 = R3 - R2;
+ P4 = R3;
+ P3 = P3 + (P4<<2);
+ R3 = [P3]; /* Retrieve the CPLB*/
+
+ /* Now we can check whether it's a clean WB page*/
+
+ CC = BITTST(R3, 14); /* 0==WB, 1==WT*/
+ IF CC JUMP .Lprot_violation;
+ CC = BITTST(R3, 7); /* 0 == clean, 1 == dirty*/
+ IF CC JUMP .Lprot_violation;
+
+ /* Check whether the write is allowed in the mode that was active.*/
+
+ R2 = 1<<3; /* checking write in user mode*/
+ CC = BITTST(R5, 17); /* 0==was user, 1==was super*/
+ R5 = CC;
+ R2 <<= R5; /* if was super, check write in super mode*/
+ R2 = R3 & R2;
+ CC = R2 == 0;
+ IF CC JUMP .Lprot_violation;
+
+ /* It's a genuine write-to-clean-page.*/
+
+ BITSET(R3, 7); /* mark as dirty*/
+ [P3] = R3; /* and write back.*/
+ NOP;
+ CSYNC;
+ ( R7:4,P5:3 ) = [SP++];
+ R0 = CPLB_RELOADED;
+ RTS;
+
+.Ldcplb_miss_compare:
+
+ /* Data CPLB Miss event. We need to choose a CPLB to
+ * evict, and then locate a new CPLB to install from the
+ * config table, that covers the faulting address.
+ */
+
+ P1.L = (DCPLB_DATA15 & 0xFFFF);
+ P1.H = (DCPLB_DATA15 >> 16);
+
+ P4.L = (DCPLB_FAULT_ADDR & 0xFFFF);
+ P4.H = (DCPLB_FAULT_ADDR >> 16);
+ R4 = [P4];
+ I0 = R4;
+
+ /* The replacement procedure for DCPLBs*/
+
+ R6 = R1; /* Save for later*/
+
+ /* Turn off CPLBs while we work.*/
+ P4.L = (DMEM_CONTROL & 0xFFFF);
+ P4.H = (DMEM_CONTROL >> 16);
+ R5 = [P4];
+ BITCLR(R5,ENDCPLB_P);
+ CLI R0;
+ SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
+ .align 8;
+ [P4] = R5;
+ SSYNC;
+ STI R0;
+
+ /* Start looking for a CPLB to evict. Our order of preference
+ * is: invalid CPLBs, clean CPLBs, dirty CPLBs. Locked CPLBs
+ * are no good.
+ */
+
+ I1.L = (DCPLB_DATA0 & 0xFFFF);
+ I1.H = (DCPLB_DATA0 >> 16);
+ P1 = 2;
+ P2 = 16;
+ I2.L = _dcplb_preference;
+ I2.H = _dcplb_preference;
+ LSETUP(.Lsdsearch1, .Ledsearch1) LC0 = P1;
+.Lsdsearch1:
+ R0 = [I2++]; /* Get the bits we're interested in*/
+ P0 = I1; /* Go back to start of table*/
+ LSETUP (.Lsdsearch2, .Ledsearch2) LC1 = P2;
+.Lsdsearch2:
+ R1 = [P0++]; /* Fetch each installed CPLB in turn*/
+ R2 = R1 & R0; /* and test for interesting bits.*/
+ CC = R2 == 0; /* If none are set, it'll do.*/
+ IF !CC JUMP .Lskip_stack_check;
+
+ R2 = [P0 - 0x104]; /* R2 - PageStart */
+ P3.L = _page_size_table; /* retrieve end address */
+ P3.H = _page_size_table; /* retrieve end address */
+ R3 = 0x1002; /* 16th - position, 2 bits -length */
+#ifdef ANOMALY_05000209
+ nop; /* Anomaly 05000209 */
+#endif
+ R7 = EXTRACT(R1,R3.l);
+ R7 = R7 << 2; /* Page size index offset */
+ P5 = R7;
+ P3 = P3 + P5;
+ R7 = [P3]; /* page size in bytes */
+
+ R7 = R2 + R7; /* R7 - PageEnd */
+ R4 = SP; /* Test SP is in range */
+
+ CC = R7 < R4; /* if PageEnd < SP */
+ IF CC JUMP .Ldfound_victim;
+ R3 = 0x284; /* stack length from start of trap till
+ * the point.
+ * 20 stack locations for future modifications
+ */
+ R4 = R4 + R3;
+ CC = R4 < R2; /* if SP + stacklen < PageStart */
+ IF CC JUMP .Ldfound_victim;
+.Lskip_stack_check:
+
+.Ledsearch2: NOP;
+.Ledsearch1: NOP;
+
+ /* If we got here, we didn't find a DCPLB we considered
+ * replacable, which means all of them were locked.
+ */
+
+ JUMP .Lall_locked;
+.Ldfound_victim:
+
+#ifdef CONFIG_CPLB_INFO
+ R7 = [P0 - 0x104];
+ P2.L = _dpdt_table;
+ P2.H = _dpdt_table;
+ P3.L = _dpdt_swapcount_table;
+ P3.H = _dpdt_swapcount_table;
+ P3 += -4;
+.Ldicount:
+ R2 = [P2];
+ P2 += 8;
+ P3 += 8;
+ CC = R2==-1;
+ IF CC JUMP .Ldicount_done;
+ CC = R7==R2;
+ IF !CC JUMP .Ldicount;
+ R7 = [P3];
+ R7 += 1;
+ [P3] = R7;
+.Ldicount_done:
+#endif
+
+ /* Clean down the hardware loops*/
+ R2 = 0;
+ LC1 = R2;
+ LC0 = R2;
+
+ /* There's a suitable victim in [P0-4] (because we've
+ * advanced already).
+ */
+
+.LDdoverwrite:
+
+ /* [P0-4] is a suitable victim CPLB, so we want to
+ * overwrite it by moving all the following CPLBs
+ * one space closer to the start.
+ */
+
+ R1.L = (DCPLB_DATA16 & 0xFFFF); /* DCPLB_DATA15 + 4 */
+ R1.H = (DCPLB_DATA16 >> 16);
+ R0 = P0;
+
+ /* If the victim happens to be in DCPLB15,
+ * we don't need to move anything.
+ */
+
+ CC = R1 == R0;
+ IF CC JUMP .Lde_moved;
+ R1 = R1 - R0;
+ R1 >>= 2;
+ P1 = R1;
+ LSETUP(.Lds_move, .Lde_move) LC0=P1;
+.Lds_move:
+ R0 = [P0++]; /* move data */
+ [P0 - 8] = R0;
+ R0 = [P0-0x104] /* move address */
+.Lde_move: [P0-0x108] = R0;
+
+ /* We've now made space in DCPLB15 for the new CPLB to be
+ * installed. The next stage is to locate a CPLB in the
+ * config table that covers the faulting address.
+ */
+
+.Lde_moved:NOP;
+ R0 = I0; /* Our faulting address */
+
+ P2.L = _dpdt_table;
+ P2.H = _dpdt_table;
+#ifdef CONFIG_CPLB_INFO
+ P3.L = _dpdt_swapcount_table;
+ P3.H = _dpdt_swapcount_table;
+ P3 += -8;
+#endif
+
+ P1.L = _page_size_table;
+ P1.H = _page_size_table;
+
+ /* An extraction pattern, to retrieve bits 17:16.*/
+
+ R1 = (16<<8)|2;
+.Ldnext: R4 = [P2++]; /* address */
+ R2 = [P2++]; /* data */
+#ifdef CONFIG_CPLB_INFO
+ P3 += 8;
+#endif
+
+ CC = R4 == -1;
+ IF CC JUMP .Lno_page_in_table;
+
+ /* See if failed address > start address */
+ CC = R4 <= R0(IU);
+ IF !CC JUMP .Ldnext;
+
+ /* extract page size (17:16)*/
+ R3 = EXTRACT(R2, R1.L) (Z);
+
+ /* add page size to addr to get range */
+
+ P5 = R3;
+ P5 = P1 + (P5 << 2);
+ R3 = [P5];
+ R3 = R3 + R4;
+
+ /* See if failed address < (start address + page size) */
+ CC = R0 < R3(IU);
+ IF !CC JUMP .Ldnext;
+
+ /* We've found the CPLB that should be installed, so
+ * write it into CPLB15, masking off any caching bits
+ * if necessary.
+ */
+
+ P1.L = (DCPLB_DATA15 & 0xFFFF);
+ P1.H = (DCPLB_DATA15 >> 16);
+
+ /* If the DCPLB has cache bits set, but caching hasn't
+ * been enabled, then we want to mask off the cache-in-L1
+ * bit before installing. Moreover, if caching is off, we
+ * also want to ensure that the DCPLB has WT mode set, rather
+ * than WB, since WB pages still trigger first-write exceptions
+ * even when not caching is off, and the page isn't marked as
+ * cachable. Finally, we could mark the page as clean, not dirty,
+ * but we choose to leave that decision to the user; if the user
+ * chooses to have a CPLB pre-defined as dirty, then they always
+ * pay the cost of flushing during eviction, but don't pay the
+ * cost of first-write exceptions to mark the page as dirty.
+ */
+
+#ifdef CONFIG_BLKFIN_WT
+ BITSET(R6, 14); /* Set WT*/
+#endif
+
+ [P1] = R2;
+ [P1-0x100] = R4;
+#ifdef CONFIG_CPLB_INFO
+ R3 = [P3];
+ R3 += 1;
+ [P3] = R3;
+#endif
+
+ /* We've installed the CPLB, so re-enable CPLBs. P4
+ * points to DMEM_CONTROL, and R5 is the value we
+ * last wrote to it, when we were disabling CPLBs.
+ */
+
+ BITSET(R5,ENDCPLB_P);
+ CLI R2;
+ .align 8;
+ [P4] = R5;
+ SSYNC;
+ STI R2;
+
+ ( R7:4,P5:3 ) = [SP++];
+ R0 = CPLB_RELOADED;
+ RTS;
+
+.data
+.align 4;
+_page_size_table:
+.byte4 0x00000400; /* 1K */
+.byte4 0x00001000; /* 4K */
+.byte4 0x00100000; /* 1M */
+.byte4 0x00400000; /* 4M */
+
+.align 4;
+_dcplb_preference:
+.byte4 0x00000001; /* valid bit */
+.byte4 0x00000002; /* lock bit */
diff --git a/arch/blackfin/mach-common/dpmc.S b/arch/blackfin/mach-common/dpmc.S
new file mode 100644
index 0000000..97cdcd6
--- /dev/null
+++ b/arch/blackfin/mach-common/dpmc.S
@@ -0,0 +1,418 @@
+/*
+ * File: arch/blackfin/mach-common/dpmc.S
+ * Based on:
+ * Author: LG Soft India
+ *
+ * Created: ?
+ * Description: Watchdog Timer APIs
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#include <asm/mach/irq.h>
+
+.text
+
+ENTRY(_unmask_wdog_wakeup_evt)
+ [--SP] = ( R7:0, P5:0 );
+#if defined(CONFIG_BF561)
+ P0.H = hi(SICA_IWR1);
+ P0.L = lo(SICA_IWR1);
+#else
+ P0.h = (SIC_IWR >> 16);
+ P0.l = (SIC_IWR & 0xFFFF);
+#endif
+ R7 = [P0];
+#if defined(CONFIG_BF561)
+ BITSET(R7, 27);
+#else
+ BITSET(R7,(IRQ_WATCH - IVG7));
+#endif
+ [P0] = R7;
+ SSYNC;
+
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+.LWRITE_TO_STAT:
+ /* When watch dog timer is enabled, a write to STAT will load the
+ * contents of CNT to STAT
+ */
+ R7 = 0x0000(z);
+#if defined(CONFIG_BF561)
+ P0.h = (WDOGA_STAT >> 16);
+ P0.l = (WDOGA_STAT & 0xFFFF);
+#else
+ P0.h = (WDOG_STAT >> 16);
+ P0.l = (WDOG_STAT & 0xFFFF);
+#endif
+ [P0] = R7;
+ SSYNC;
+ JUMP .LSKIP_WRITE_TO_STAT;
+
+ENTRY(_program_wdog_timer)
+ [--SP] = ( R7:0, P5:0 );
+#if defined(CONFIG_BF561)
+ P0.h = (WDOGA_CNT >> 16);
+ P0.l = (WDOGA_CNT & 0xFFFF);
+#else
+ P0.h = (WDOG_CNT >> 16);
+ P0.l = (WDOG_CNT & 0xFFFF);
+#endif
+ [P0] = R0;
+ SSYNC;
+
+#if defined(CONFIG_BF561)
+ P0.h = (WDOGA_CTL >> 16);
+ P0.l = (WDOGA_CTL & 0xFFFF);
+#else
+ P0.h = (WDOG_CTL >> 16);
+ P0.l = (WDOG_CTL & 0xFFFF);
+#endif
+ R7 = W[P0](Z);
+ CC = BITTST(R7,1);
+ if !CC JUMP .LWRITE_TO_STAT;
+ CC = BITTST(R7,2);
+ if !CC JUMP .LWRITE_TO_STAT;
+
+.LSKIP_WRITE_TO_STAT:
+#if defined(CONFIG_BF561)
+ P0.h = (WDOGA_CTL >> 16);
+ P0.l = (WDOGA_CTL & 0xFFFF);
+#else
+ P0.h = (WDOG_CTL >> 16);
+ P0.l = (WDOG_CTL & 0xFFFF);
+#endif
+ R7 = W[P0](Z);
+ BITCLR(R7,1); /* Enable GP event */
+ BITSET(R7,2);
+ W[P0] = R7.L;
+ SSYNC;
+ NOP;
+
+ R7 = W[P0](Z);
+ BITCLR(R7,4); /* Enable the wdog counter */
+ W[P0] = R7.L;
+ SSYNC;
+
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+ENTRY(_clear_wdog_wakeup_evt)
+ [--SP] = ( R7:0, P5:0 );
+
+#if defined(CONFIG_BF561)
+ P0.h = (WDOGA_CTL >> 16);
+ P0.l = (WDOGA_CTL & 0xFFFF);
+#else
+ P0.h = (WDOG_CTL >> 16);
+ P0.l = (WDOG_CTL & 0xFFFF);
+#endif
+ R7 = 0x0AD6(Z);
+ W[P0] = R7.L;
+ SSYNC;
+
+ R7 = W[P0](Z);
+ BITSET(R7,15);
+ W[P0] = R7.L;
+ SSYNC;
+
+ R7 = W[P0](Z);
+ BITSET(R7,1);
+ BITSET(R7,2);
+ W[P0] = R7.L;
+ SSYNC;
+
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+ENTRY(_disable_wdog_timer)
+ [--SP] = ( R7:0, P5:0 );
+#if defined(CONFIG_BF561)
+ P0.h = (WDOGA_CTL >> 16);
+ P0.l = (WDOGA_CTL & 0xFFFF);
+#else
+ P0.h = (WDOG_CTL >> 16);
+ P0.l = (WDOG_CTL & 0xFFFF);
+#endif
+ R7 = 0xAD6(Z);
+ W[P0] = R7.L;
+ SSYNC;
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+#if !defined(CONFIG_BF561)
+
+.section .l1.text
+
+ENTRY(_sleep_mode)
+ [--SP] = ( R7:0, P5:0 );
+ [--SP] = RETS;
+
+ call _set_sic_iwr;
+
+ R0 = 0xFFFF (Z);
+ call _set_rtc_istat
+
+ P0.H = hi(PLL_CTL);
+ P0.L = lo(PLL_CTL);
+ R1 = W[P0](z);
+ BITSET (R1, 3);
+ W[P0] = R1.L;
+
+ CLI R2;
+ SSYNC;
+ IDLE;
+ STI R2;
+
+ call _test_pll_locked;
+
+ R0 = IWR_ENABLE(0);
+ call _set_sic_iwr;
+
+ P0.H = hi(PLL_CTL);
+ P0.L = lo(PLL_CTL);
+ R7 = w[p0](z);
+ BITCLR (R7, 3);
+ BITCLR (R7, 5);
+ w[p0] = R7.L;
+ IDLE;
+ call _test_pll_locked;
+
+ RETS = [SP++];
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+ENTRY(_hibernate_mode)
+ [--SP] = ( R7:0, P5:0 );
+ [--SP] = RETS;
+
+ call _set_sic_iwr;
+
+ R0 = 0xFFFF (Z);
+ call _set_rtc_istat
+
+ P0.H = hi(VR_CTL);
+ P0.L = lo(VR_CTL);
+ R1 = W[P0](z);
+ BITSET (R1, 8);
+ BITCLR (R1, 0);
+ BITCLR (R1, 1);
+ W[P0] = R1.L;
+ SSYNC;
+
+ CLI R2;
+ IDLE;
+
+ /* Actually, adding anything may not be necessary...SDRAM contents
+ * are lost
+ */
+
+ENTRY(_deep_sleep)
+ [--SP] = ( R7:0, P5:0 );
+ [--SP] = RETS;
+
+ CLI R4;
+
+ call _set_sic_iwr;
+
+ call _set_sdram_srfs;
+
+ /* Clear all the interrupts,bits sticky */
+ R0 = 0xFFFF (Z);
+ call _set_rtc_istat
+
+ P0.H = hi(PLL_CTL);
+ P0.L = lo(PLL_CTL);
+ R0 = W[P0](z);
+ BITSET (R0, 5);
+ W[P0] = R0.L;
+
+ call _test_pll_locked;
+
+ SSYNC;
+ IDLE;
+
+ call _unset_sdram_srfs;
+
+ call _test_pll_locked;
+
+ R0 = IWR_ENABLE(0);
+ call _set_sic_iwr;
+
+ P0.H = hi(PLL_CTL);
+ P0.L = lo(PLL_CTL);
+ R0 = w[p0](z);
+ BITCLR (R0, 3);
+ BITCLR (R0, 5);
+ BITCLR (R0, 8);
+ w[p0] = R0;
+ IDLE;
+ call _test_pll_locked;
+
+ STI R4;
+
+ RETS = [SP++];
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+ENTRY(_sleep_deeper)
+ [--SP] = ( R7:0, P5:0 );
+ [--SP] = RETS;
+
+ CLI R4;
+
+ P3 = R0;
+ R0 = IWR_ENABLE(0);
+ call _set_sic_iwr;
+ call _set_sdram_srfs;
+
+ /* Clear all the interrupts,bits sticky */
+ R0 = 0xFFFF (Z);
+ call _set_rtc_istat
+
+ P0.H = hi(PLL_DIV);
+ P0.L = lo(PLL_DIV);
+ R6 = W[P0](z);
+ R0.L = 0xF;
+ W[P0] = R0.l;
+
+ P0.H = hi(PLL_CTL);
+ P0.L = lo(PLL_CTL);
+ R5 = W[P0](z);
+ R0.L = (MIN_VC/CONFIG_CLKIN_HZ) << 9;
+ W[P0] = R0.l;
+
+ SSYNC;
+ IDLE;
+
+ call _test_pll_locked;
+
+ P0.H = hi(VR_CTL);
+ P0.L = lo(VR_CTL);
+ R7 = W[P0](z);
+ R1 = 0x6;
+ R1 <<= 16;
+ R2 = 0x0404(Z);
+ R1 = R1|R2;
+
+ R2 = DEPOSIT(R7, R1);
+ W[P0] = R2;
+
+ SSYNC;
+ IDLE;
+
+ call _test_pll_locked;
+
+ P0.H = hi(PLL_CTL);
+ P0.L = lo(PLL_CTL);
+ R0 = W[P0](z);
+ BITSET (R0, 3);
+ W[P0] = R0.L;
+
+ R0 = P3;
+ call _set_sic_iwr;
+
+ SSYNC;
+ IDLE;
+
+ call _test_pll_locked;
+
+ R0 = IWR_ENABLE(0);
+ call _set_sic_iwr;
+
+ P0.H = hi(VR_CTL);
+ P0.L = lo(VR_CTL);
+ W[P0]= R7;
+
+ SSYNC;
+ IDLE;
+
+ call _test_pll_locked;
+
+ P0.H = hi(PLL_DIV);
+ P0.L = lo(PLL_DIV);
+ W[P0]= R6;
+
+ P0.H = hi(PLL_CTL);
+ P0.L = lo(PLL_CTL);
+ w[p0] = R5;
+ IDLE;
+ call _test_pll_locked;
+
+ call _unset_sdram_srfs;
+
+ STI R4;
+
+ RETS = [SP++];
+ ( R7:0, P5:0 ) = [SP++];
+ RTS;
+
+ENTRY(_set_sdram_srfs)
+ /* set the sdram to self refresh mode */
+ P0.H = hi(EBIU_SDGCTL);
+ P0.L = lo(EBIU_SDGCTL);
+ R2 = [P0];
+ R3.H = hi(SRFS);
+ R3.L = lo(SRFS);
+ R2 = R2|R3;
+ [P0] = R2;
+ ssync;
+ RTS;
+
+ENTRY(_unset_sdram_srfs)
+ /* set the sdram out of self refresh mode */
+ P0.H = hi(EBIU_SDGCTL);
+ P0.L = lo(EBIU_SDGCTL);
+ R2 = [P0];
+ R3.H = hi(SRFS);
+ R3.L = lo(SRFS);
+ R3 = ~R3;
+ R2 = R2&R3;
+ [P0] = R2;
+ ssync;
+ RTS;
+
+ENTRY(_set_sic_iwr)
+ P0.H = hi(SIC_IWR);
+ P0.L = lo(SIC_IWR);
+ [P0] = R0;
+ SSYNC;
+ RTS;
+
+ENTRY(_set_rtc_istat)
+ P0.H = hi(RTC_ISTAT);
+ P0.L = lo(RTC_ISTAT);
+ w[P0] = R0.L;
+ SSYNC;
+ RTS;
+
+ENTRY(_test_pll_locked)
+ P0.H = hi(PLL_STAT);
+ P0.L = lo(PLL_STAT);
+1:
+ R0 = W[P0] (Z);
+ CC = BITTST(R0,5);
+ IF !CC JUMP 1b;
+ RTS;
+#endif
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
new file mode 100644
index 0000000..8eb0a90
--- /dev/null
+++ b/arch/blackfin/mach-common/entry.S
@@ -0,0 +1,1207 @@
+/*
+ * File: arch/blackfin/mach-common/entry.S
+ * Based on:
+ * Author: Linus Torvalds
+ *
+ * Created: ?
+ * Description: contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all
+ * interrupts and faults that can result in a task-switch.
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * 25-Dec-2004 - LG Soft India
+ * 1. Fix in return_from_int, to make sure any pending
+ * system call in ILAT for this process to get
+ * executed, otherwise in case context switch happens,
+ * system call of first process (i.e in ILAT) will be
+ * carried forward to the switched process.
+ * 2. Removed Constant references for the following
+ * a. IPEND
+ * b. EXCAUSE mask
+ * c. PAGE Mask
+ */
+
+/*
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ */
+
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+#include <asm/unistd.h>
+#include <asm/errno.h>
+#include <asm/thread_info.h> /* TIF_NEED_RESCHED */
+#include <asm/asm-offsets.h>
+
+#include <asm/mach-common/context.S>
+
+#ifdef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE
+ /*
+ * TODO: this should be proper save/restore, but for now
+ * we'll just cheat and use 0x1/0x13
+ */
+# define DEBUG_START_HWTRACE \
+ P5.l = LO(TBUFCTL); \
+ P5.h = HI(TBUFCTL); \
+ R7 = 0x13; \
+ [P5] = R7;
+# define DEBUG_STOP_HWTRACE \
+ P5.l = LO(TBUFCTL); \
+ P5.h = HI(TBUFCTL); \
+ R7 = 0x01; \
+ [P5] = R7;
+#else
+# define DEBUG_START_HWTRACE
+# define DEBUG_STOP_HWTRACE
+#endif
+
+#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
+.section .l1.text
+#else
+.text
+#endif
+
+/* Slightly simplified and streamlined entry point for CPLB misses.
+ * This one does not lower the level to IRQ5, and thus can be used to
+ * patch up CPLB misses on the kernel stack.
+ */
+ENTRY(_ex_dcplb)
+#if defined(ANOMALY_05000261)
+ /*
+ * Work around an anomaly: if we see a new DCPLB fault, return
+ * without doing anything. Then, if we get the same fault again,
+ * handle it.
+ */
+ p5.l = _last_cplb_fault_retx;
+ p5.h = _last_cplb_fault_retx;
+ r7 = [p5];
+ r6 = retx;
+ [p5] = r6;
+ cc = r6 == r7;
+ if !cc jump _return_from_exception;
+ /* fall through */
+#endif
+
+ENTRY(_ex_icplb)
+ (R7:6,P5:4) = [sp++];
+ ASTAT = [sp++];
+ SAVE_ALL_SYS
+ call __cplb_hdr;
+ DEBUG_START_HWTRACE
+ RESTORE_ALL_SYS
+ SP = RETN;
+ rtx;
+
+ENTRY(_ex_spinlock)
+ /* Transform this into a syscall - twiddle the syscall vector. */
+ p5.l = lo(EVT15);
+ p5.h = hi(EVT15);
+ r7.l = _spinlock_bh;
+ r7.h = _spinlock_bh;
+ [p5] = r7;
+ csync;
+ /* Fall through. */
+
+ENTRY(_ex_syscall)
+ DEBUG_START_HWTRACE
+ (R7:6,P5:4) = [sp++];
+ ASTAT = [sp++];
+ raise 15; /* invoked by TRAP #0, for sys call */
+ sp = retn;
+ rtx
+
+ENTRY(_spinlock_bh)
+ SAVE_ALL_SYS
+ /* To end up here, vector 15 was changed - so we have to change it
+ * back.
+ */
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _evt_system_call;
+ p1.h = _evt_system_call;
+ [p0] = p1;
+ csync;
+ r0 = [sp + PT_R0];
+ sp += -12;
+ call _sys_bfin_spinlock;
+ sp += 12;
+ [SP + PT_R0] = R0;
+ RESTORE_ALL_SYS
+ rti;
+
+ENTRY(_ex_soft_bp)
+ r7 = retx;
+ r7 += -2;
+ retx = r7;
+ jump.s _ex_trap_c;
+
+ENTRY(_ex_single_step)
+ r7 = retx;
+ r6 = reti;
+ cc = r7 == r6;
+ if cc jump _return_from_exception
+ r7 = syscfg;
+ bitclr (r7, 0);
+ syscfg = R7;
+
+ p5.l = lo(IPEND);
+ p5.h = hi(IPEND);
+ r6 = [p5];
+ cc = bittst(r6, 5);
+ if !cc jump _ex_trap_c;
+ p4.l = lo(EVT5);
+ p4.h = hi(EVT5);
+ r6.h = _exception_to_level5;
+ r6.l = _exception_to_level5;
+ r7 = [p4];
+ cc = r6 == r7;
+ if !cc jump _ex_trap_c;
+
+_return_from_exception:
+ DEBUG_START_HWTRACE
+ (R7:6,P5:4) = [sp++];
+ ASTAT = [sp++];
+ sp = retn;
+ rtx;
+
+ENTRY(_handle_bad_cplb)
+ /* To get here, we just tried and failed to change a CPLB
+ * so, handle things in trap_c (C code), by lowering to
+ * IRQ5, just like we normally do. Since this is not a
+ * "normal" return path, we have a do alot of stuff to
+ * the stack to get ready so, we can fall through - we
+ * need to make a CPLB exception look like a normal exception
+ */
+
+ DEBUG_START_HWTRACE
+ RESTORE_ALL_SYS
+ [--sp] = ASTAT;
+ [--sp] = (R7:6, P5:4);
+
+ENTRY(_ex_trap_c)
+ /* Call C code (trap_c) to handle the exception, which most
+ * likely involves sending a signal to the current process.
+ * To avoid double faults, lower our priority to IRQ5 first.
+ */
+ P5.h = _exception_to_level5;
+ P5.l = _exception_to_level5;
+ p4.l = lo(EVT5);
+ p4.h = hi(EVT5);
+ [p4] = p5;
+ csync;
+
+ /* Disable all interrupts, but make sure level 5 is enabled so
+ * we can switch to that level. Save the old mask. */
+ cli r6;
+ p4.l = _excpt_saved_imask;
+ p4.h = _excpt_saved_imask;
+ [p4] = r6;
+ r6 = 0x3f;
+ sti r6;
+
+ /* Save the excause into a circular buffer, in case the instruction
+ * which caused this excecptions causes others.
+ */
+ P5.l = _in_ptr_excause;
+ P5.h = _in_ptr_excause;
+ R7 = [P5];
+ R7 += 4;
+ R6 = 0xF;
+ R7 = R7 & R6;
+ [P5] = R7;
+ R6.l = _excause_circ_buf;
+ R6.h = _excause_circ_buf;
+ R7 = R7 + R6;
+ p5 = R7;
+ R6 = SEQSTAT;
+ [P5] = R6;
+
+ DEBUG_START_HWTRACE
+ (R7:6,P5:4) = [sp++];
+ ASTAT = [sp++];
+ SP = RETN;
+ raise 5;
+ rtx;
+
+ENTRY(_exception_to_level5)
+ SAVE_ALL_SYS
+
+ /* Restore interrupt mask. We haven't pushed RETI, so this
+ * doesn't enable interrupts until we return from this handler. */
+ p4.l = _excpt_saved_imask;
+ p4.h = _excpt_saved_imask;
+ r6 = [p4];
+ sti r6;
+
+ /* Restore the hardware error vector. */
+ P5.h = _evt_ivhw;
+ P5.l = _evt_ivhw;
+ p4.l = lo(EVT5);
+ p4.h = hi(EVT5);
+ [p4] = p5;
+ csync;
+
+ p2.l = lo(IPEND);
+ p2.h = hi(IPEND);
+ csync;
+ r0 = [p2]; /* Read current IPEND */
+ [sp + PT_IPEND] = r0; /* Store IPEND */
+
+ /* Pop the excause from the circular buffer and push it on the stack
+ * (in the right place - if you change the location of SEQSTAT, you
+ * must change this offset.
+ */
+.L_excep_to_5_again:
+ P5.l = _out_ptr_excause;
+ P5.h = _out_ptr_excause;
+ R7 = [P5];
+ R7 += 4;
+ R6 = 0xF;
+ R7 = R7 & R6;
+ [P5] = R7;
+ R6.l = _excause_circ_buf;
+ R6.h = _excause_circ_buf;
+ R7 = R7 + R6;
+ P5 = R7;
+ R1 = [P5];
+ [SP + 8] = r1;
+
+ r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
+ SP += -12;
+ call _trap_c;
+ SP += 12;
+
+ /* See if anything else is in the exception buffer
+ * if there is, process it
+ */
+ P5.l = _out_ptr_excause;
+ P5.h = _out_ptr_excause;
+ P4.l = _in_ptr_excause;
+ P4.h = _in_ptr_excause;
+ R6 = [P5];
+ R7 = [P4];
+ CC = R6 == R7;
+ if ! CC JUMP .L_excep_to_5_again
+
+ call _ret_from_exception;
+ RESTORE_ALL_SYS
+ rti;
+
+ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
+ /* Since the kernel stack can be anywhere, it's not guaranteed to be
+ * covered by a CPLB. Switch to an exception stack; use RETN as a
+ * scratch register (for want of a better option).
+ */
+ retn = sp;
+ sp.l = _exception_stack_top;
+ sp.h = _exception_stack_top;
+ /* Try to deal with syscalls quickly. */
+ [--sp] = ASTAT;
+ [--sp] = (R7:6, P5:4);
+ DEBUG_STOP_HWTRACE
+ r7 = SEQSTAT; /* reason code is in bit 5:0 */
+ r6.l = lo(SEQSTAT_EXCAUSE);
+ r6.h = hi(SEQSTAT_EXCAUSE);
+ r7 = r7 & r6;
+ p5.h = _extable;
+ p5.l = _extable;
+ p4 = r7;
+ p5 = p5 + (p4 << 2);
+ p4 = [p5];
+ jump (p4);
+
+.Lbadsys:
+ r7 = -ENOSYS; /* signextending enough */
+ [sp + PT_R0] = r7; /* return value from system call */
+ jump .Lsyscall_really_exit;
+
+ENTRY(_kernel_execve)
+ link SIZEOF_PTREGS;
+ p0 = sp;
+ r3 = SIZEOF_PTREGS / 4;
+ r4 = 0(x);
+0:
+ [p0++] = r4;
+ r3 += -1;
+ cc = r3 == 0;
+ if !cc jump 0b (bp);
+
+ p0 = sp;
+ sp += -16;
+ [sp + 12] = p0;
+ call _do_execve;
+ SP += 16;
+ cc = r0 == 0;
+ if ! cc jump 1f;
+ /* Success. Copy our temporary pt_regs to the top of the kernel
+ * stack and do a normal exception return.
+ */
+ r1 = sp;
+ r0 = (-KERNEL_STACK_SIZE) (x);
+ r1 = r1 & r0;
+ p2 = r1;
+ p3 = [p2];
+ r0 = KERNEL_STACK_SIZE - 4 (z);
+ p1 = r0;
+ p1 = p1 + p2;
+
+ p0 = fp;
+ r4 = [p0--];
+ r3 = SIZEOF_PTREGS / 4;
+0:
+ r4 = [p0--];
+ [p1--] = r4;
+ r3 += -1;
+ cc = r3 == 0;
+ if ! cc jump 0b (bp);
+
+ r0 = (KERNEL_STACK_SIZE - SIZEOF_PTREGS) (z);
+ p1 = r0;
+ p1 = p1 + p2;
+ sp = p1;
+ r0 = syscfg;
+ [SP + PT_SYSCFG] = r0;
+ [p3 + (TASK_THREAD + THREAD_KSP)] = sp;
+
+ RESTORE_CONTEXT;
+ rti;
+1:
+ unlink;
+ rts;
+
+ENTRY(_system_call)
+ /* Store IPEND */
+ p2.l = lo(IPEND);
+ p2.h = hi(IPEND);
+ csync;
+ r0 = [p2];
+ [sp + PT_IPEND] = r0;
+
+ /* Store RETS for now */
+ r0 = rets;
+ [sp + PT_RESERVED] = r0;
+ /* Set the stack for the current process */
+ r7 = sp;
+ r6.l = lo(ALIGN_PAGE_MASK);
+ r6.h = hi(ALIGN_PAGE_MASK);
+ r7 = r7 & r6; /* thread_info */
+ p2 = r7;
+ p2 = [p2];
+
+ [p2+(TASK_THREAD+THREAD_KSP)] = sp;
+
+ /* Check the System Call */
+ r7 = __NR_syscall;
+ /* System call number is passed in P0 */
+ r6 = p0;
+ cc = r6 < r7;
+ if ! cc jump .Lbadsys;
+
+ /* are we tracing syscalls?*/
+ r7 = sp;
+ r6.l = lo(ALIGN_PAGE_MASK);
+ r6.h = hi(ALIGN_PAGE_MASK);
+ r7 = r7 & r6;
+ p2 = r7;
+ r7 = [p2+TI_FLAGS];
+ CC = BITTST(r7,TIF_SYSCALL_TRACE);
+ if CC JUMP _sys_trace;
+
+ /* Execute the appropriate system call */
+
+ p4 = p0;
+ p5.l = _sys_call_table;
+ p5.h = _sys_call_table;
+ p5 = p5 + (p4 << 2);
+ r0 = [sp + PT_R0];
+ r1 = [sp + PT_R1];
+ r2 = [sp + PT_R2];
+ p5 = [p5];
+
+ [--sp] = r5;
+ [--sp] = r4;
+ [--sp] = r3;
+ SP += -12;
+ call (p5);
+ SP += 24;
+ [sp + PT_R0] = r0;
+
+.Lresume_userspace:
+ r7 = sp;
+ r4.l = lo(ALIGN_PAGE_MASK);
+ r4.h = hi(ALIGN_PAGE_MASK);
+ r7 = r7 & r4; /* thread_info->flags */
+ p5 = r7;
+.Lresume_userspace_1:
+ /* Disable interrupts. */
+ [--sp] = reti;
+ reti = [sp++];
+
+ r7 = [p5 + TI_FLAGS];
+ r4.l = lo(_TIF_WORK_MASK);
+ r4.h = hi(_TIF_WORK_MASK);
+ r7 = r7 & r4;
+
+.Lsyscall_resched:
+ cc = BITTST(r7, TIF_NEED_RESCHED);
+ if !cc jump .Lsyscall_sigpending;
+
+ /* Reenable interrupts. */
+ [--sp] = reti;
+ r0 = [sp++];
+
+ SP += -12;
+ call _schedule;
+ SP += 12;
+
+ jump .Lresume_userspace_1;
+
+.Lsyscall_sigpending:
+ cc = BITTST(r7, TIF_RESTORE_SIGMASK);
+ if cc jump .Lsyscall_do_signals;
+ cc = BITTST(r7, TIF_SIGPENDING);
+ if !cc jump .Lsyscall_really_exit;
+.Lsyscall_do_signals:
+ /* Reenable interrupts. */
+ [--sp] = reti;
+ r0 = [sp++];
+
+ r0 = sp;
+ SP += -12;
+ call _do_signal;
+ SP += 12;
+
+.Lsyscall_really_exit:
+ r5 = [sp + PT_RESERVED];
+ rets = r5;
+ rts;
+
+_sys_trace:
+ call _syscall_trace;
+
+ /* Execute the appropriate system call */
+
+ p4 = [SP + PT_P0];
+ p5.l = _sys_call_table;
+ p5.h = _sys_call_table;
+ p5 = p5 + (p4 << 2);
+ r0 = [sp + PT_R0];
+ r1 = [sp + PT_R1];
+ r2 = [sp + PT_R2];
+ r3 = [sp + PT_R3];
+ r4 = [sp + PT_R4];
+ r5 = [sp + PT_R5];
+ p5 = [p5];
+
+ [--sp] = r5;
+ [--sp] = r4;
+ [--sp] = r3;
+ SP += -12;
+ call (p5);
+ SP += 24;
+ [sp + PT_R0] = r0;
+
+ call _syscall_trace;
+ jump .Lresume_userspace;
+
+ENTRY(_resume)
+ /*
+ * Beware - when entering resume, prev (the current task) is
+ * in r0, next (the new task) is in r1.
+ */
+ p0 = r0;
+ p1 = r1;
+ [--sp] = rets;
+ [--sp] = fp;
+ [--sp] = (r7:4, p5:3);
+
+ /* save usp */
+ p2 = usp;
+ [p0+(TASK_THREAD+THREAD_USP)] = p2;
+
+ /* save current kernel stack pointer */
+ [p0+(TASK_THREAD+THREAD_KSP)] = sp;
+
+ /* save program counter */
+ r1.l = _new_old_task;
+ r1.h = _new_old_task;
+ [p0+(TASK_THREAD+THREAD_PC)] = r1;
+
+ /* restore the kernel stack pointer */
+ sp = [p1+(TASK_THREAD+THREAD_KSP)];
+
+ /* restore user stack pointer */
+ p0 = [p1+(TASK_THREAD+THREAD_USP)];
+ usp = p0;
+
+ /* restore pc */
+ p0 = [p1+(TASK_THREAD+THREAD_PC)];
+ jump (p0);
+
+ /*
+ * Following code actually lands up in a new (old) task.
+ */
+
+_new_old_task:
+ (r7:4, p5:3) = [sp++];
+ fp = [sp++];
+ rets = [sp++];
+
+ /*
+ * When we come out of resume, r0 carries "old" task, becuase we are
+ * in "new" task.
+ */
+ rts;
+
+ENTRY(_ret_from_exception)
+ p2.l = lo(IPEND);
+ p2.h = hi(IPEND);
+
+ csync;
+ r0 = [p2];
+ [sp + PT_IPEND] = r0;
+
+1:
+ r1 = 0x37(Z);
+ r2 = ~r1;
+ r2.h = 0;
+ r0 = r2 & r0;
+ cc = r0 == 0;
+ if !cc jump 4f; /* if not return to user mode, get out */
+
+ /* Make sure any pending system call or deferred exception
+ * return in ILAT for this process to get executed, otherwise
+ * in case context switch happens, system call of
+ * first process (i.e in ILAT) will be carried
+ * forward to the switched process
+ */
+
+ p2.l = lo(ILAT);
+ p2.h = hi(ILAT);
+ r0 = [p2];
+ r1 = (EVT_IVG14 | EVT_IVG15) (z);
+ r0 = r0 & r1;
+ cc = r0 == 0;
+ if !cc jump 5f;
+
+ /* Set the stack for the current process */
+ r7 = sp;
+ r4.l = lo(ALIGN_PAGE_MASK);
+ r4.h = hi(ALIGN_PAGE_MASK);
+ r7 = r7 & r4; /* thread_info->flags */
+ p5 = r7;
+ r7 = [p5 + TI_FLAGS];
+ r4.l = lo(_TIF_WORK_MASK);
+ r4.h = hi(_TIF_WORK_MASK);
+ r7 = r7 & r4;
+ cc = r7 == 0;
+ if cc jump 4f;
+
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _schedule_and_signal;
+ p1.h = _schedule_and_signal;
+ [p0] = p1;
+ csync;
+ raise 15; /* raise evt14 to do signal or reschedule */
+4:
+ r0 = syscfg;
+ bitclr(r0, 0);
+ syscfg = r0;
+5:
+ rts;
+
+ENTRY(_return_from_int)
+ /* If someone else already raised IRQ 15, do nothing. */
+ csync;
+ p2.l = lo(ILAT);
+ p2.h = hi(ILAT);
+ r0 = [p2];
+ cc = bittst (r0, EVT_IVG15_P);
+ if cc jump 2f;
+
+ /* if not return to user mode, get out */
+ p2.l = lo(IPEND);
+ p2.h = hi(IPEND);
+ r0 = [p2];
+ r1 = 0x17(Z);
+ r2 = ~r1;
+ r2.h = 0;
+ r0 = r2 & r0;
+ r1 = 1;
+ r1 = r0 - r1;
+ r2 = r0 & r1;
+ cc = r2 == 0;
+ if !cc jump 2f;
+
+ /* Lower the interrupt level to 15. */
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _schedule_and_signal_from_int;
+ p1.h = _schedule_and_signal_from_int;
+ [p0] = p1;
+ csync;
+#if defined(ANOMALY_05000281)
+ r0.l = lo(CONFIG_BOOT_LOAD);
+ r0.h = hi(CONFIG_BOOT_LOAD);
+ reti = r0;
+#endif
+ r0 = 0x801f (z);
+ STI r0;
+ raise 15; /* raise evt15 to do signal or reschedule */
+ rti;
+2:
+ rts;
+
+ENTRY(_lower_to_irq14)
+#if defined(ANOMALY_05000281)
+ r0.l = lo(CONFIG_BOOT_LOAD);
+ r0.h = hi(CONFIG_BOOT_LOAD);
+ reti = r0;
+#endif
+ r0 = 0x401f;
+ sti r0;
+ raise 14;
+ rti;
+ENTRY(_evt14_softirq)
+#ifdef CONFIG_DEBUG_HWERR
+ r0 = 0x3f;
+ sti r0;
+#else
+ cli r0;
+#endif
+ [--sp] = RETI;
+ SP += 4;
+ rts;
+
+_schedule_and_signal_from_int:
+ /* To end up here, vector 15 was changed - so we have to change it
+ * back.
+ */
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _evt_system_call;
+ p1.h = _evt_system_call;
+ [p0] = p1;
+ csync;
+ p1 = rets;
+ [sp + PT_RESERVED] = p1;
+
+ p0.l = _irq_flags;
+ p0.h = _irq_flags;
+ r0 = [p0];
+ sti r0;
+
+ jump.s .Lresume_userspace;
+
+_schedule_and_signal:
+ SAVE_CONTEXT_SYSCALL
+ /* To end up here, vector 15 was changed - so we have to change it
+ * back.
+ */
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _evt_system_call;
+ p1.h = _evt_system_call;
+ [p0] = p1;
+ csync;
+ p0.l = 1f;
+ p0.h = 1f;
+ [sp + PT_RESERVED] = P0;
+ call .Lresume_userspace;
+1:
+ RESTORE_CONTEXT
+ rti;
+
+/* Make sure when we start, that the circular buffer is initialized properly
+ * R0 and P0 are call clobbered, so we can use them here.
+ */
+ENTRY(_init_exception_buff)
+ r0 = 0;
+ p0.h = _in_ptr_excause;
+ p0.l = _in_ptr_excause;
+ [p0] = r0;
+ p0.h = _out_ptr_excause;
+ p0.l = _out_ptr_excause;
+ [p0] = r0;
+ rts;
+
+/*
+ * Put these in the kernel data section - that should always be covered by
+ * a CPLB. This is needed to ensure we don't get double fault conditions
+ */
+
+#ifdef CONFIG_SYSCALL_TAB_L1
+.section .l1.data
+#else
+.data
+#endif
+ALIGN
+_extable:
+ /* entry for each EXCAUSE[5:0]
+ * This table bmust be in sync with the table in ./kernel/traps.c
+ * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined
+ */
+ .long _ex_syscall; /* 0x00 - User Defined - Linux Syscall */
+ .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */
+ .long _ex_trap_c /* 0x02 - User Defined */
+ .long _ex_trap_c /* 0x03 - User Defined - Atomic test and set service */
+ .long _ex_spinlock /* 0x04 - User Defined */
+ .long _ex_trap_c /* 0x05 - User Defined */
+ .long _ex_trap_c /* 0x06 - User Defined */
+ .long _ex_trap_c /* 0x07 - User Defined */
+ .long _ex_trap_c /* 0x08 - User Defined */
+ .long _ex_trap_c /* 0x09 - User Defined */
+ .long _ex_trap_c /* 0x0A - User Defined */
+ .long _ex_trap_c /* 0x0B - User Defined */
+ .long _ex_trap_c /* 0x0C - User Defined */
+ .long _ex_trap_c /* 0x0D - User Defined */
+ .long _ex_trap_c /* 0x0E - User Defined */
+ .long _ex_trap_c /* 0x0F - User Defined */
+ .long _ex_single_step /* 0x10 - HW Single step */
+ .long _ex_trap_c /* 0x11 - Trace Buffer Full */
+ .long _ex_trap_c /* 0x12 - Reserved */
+ .long _ex_trap_c /* 0x13 - Reserved */
+ .long _ex_trap_c /* 0x14 - Reserved */
+ .long _ex_trap_c /* 0x15 - Reserved */
+ .long _ex_trap_c /* 0x16 - Reserved */
+ .long _ex_trap_c /* 0x17 - Reserved */
+ .long _ex_trap_c /* 0x18 - Reserved */
+ .long _ex_trap_c /* 0x19 - Reserved */
+ .long _ex_trap_c /* 0x1A - Reserved */
+ .long _ex_trap_c /* 0x1B - Reserved */
+ .long _ex_trap_c /* 0x1C - Reserved */
+ .long _ex_trap_c /* 0x1D - Reserved */
+ .long _ex_trap_c /* 0x1E - Reserved */
+ .long _ex_trap_c /* 0x1F - Reserved */
+ .long _ex_trap_c /* 0x20 - Reserved */
+ .long _ex_trap_c /* 0x21 - Undefined Instruction */
+ .long _ex_trap_c /* 0x22 - Illegal Instruction Combination */
+ .long _ex_dcplb /* 0x23 - Data CPLB Protection Violation */
+ .long _ex_trap_c /* 0x24 - Data access misaligned */
+ .long _ex_trap_c /* 0x25 - Unrecoverable Event */
+ .long _ex_dcplb /* 0x26 - Data CPLB Miss */
+ .long _ex_trap_c /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero */
+ .long _ex_trap_c /* 0x28 - Emulation Watchpoint */
+ .long _ex_trap_c /* 0x29 - Instruction fetch access error (535 only) */
+ .long _ex_trap_c /* 0x2A - Instruction fetch misaligned */
+ .long _ex_icplb /* 0x2B - Instruction CPLB protection Violation */
+ .long _ex_icplb /* 0x2C - Instruction CPLB miss */
+ .long _ex_trap_c /* 0x2D - Instruction CPLB Multiple Hits */
+ .long _ex_trap_c /* 0x2E - Illegal use of Supervisor Resource */
+ .long _ex_trap_c /* 0x2E - Illegal use of Supervisor Resource */
+ .long _ex_trap_c /* 0x2F - Reserved */
+ .long _ex_trap_c /* 0x30 - Reserved */
+ .long _ex_trap_c /* 0x31 - Reserved */
+ .long _ex_trap_c /* 0x32 - Reserved */
+ .long _ex_trap_c /* 0x33 - Reserved */
+ .long _ex_trap_c /* 0x34 - Reserved */
+ .long _ex_trap_c /* 0x35 - Reserved */
+ .long _ex_trap_c /* 0x36 - Reserved */
+ .long _ex_trap_c /* 0x37 - Reserved */
+ .long _ex_trap_c /* 0x38 - Reserved */
+ .long _ex_trap_c /* 0x39 - Reserved */
+ .long _ex_trap_c /* 0x3A - Reserved */
+ .long _ex_trap_c /* 0x3B - Reserved */
+ .long _ex_trap_c /* 0x3C - Reserved */
+ .long _ex_trap_c /* 0x3D - Reserved */
+ .long _ex_trap_c /* 0x3E - Reserved */
+ .long _ex_trap_c /* 0x3F - Reserved */
+
+ALIGN
+ENTRY(_sys_call_table)
+ .long _sys_ni_syscall /* 0 - old "setup()" system call*/
+ .long _sys_exit
+ .long _sys_fork
+ .long _sys_read
+ .long _sys_write
+ .long _sys_open /* 5 */
+ .long _sys_close
+ .long _sys_ni_syscall /* old waitpid */
+ .long _sys_creat
+ .long _sys_link
+ .long _sys_unlink /* 10 */
+ .long _sys_execve
+ .long _sys_chdir
+ .long _sys_time
+ .long _sys_mknod
+ .long _sys_chmod /* 15 */
+ .long _sys_chown /* chown16 */
+ .long _sys_ni_syscall /* old break syscall holder */
+ .long _sys_ni_syscall /* old stat */
+ .long _sys_lseek
+ .long _sys_getpid /* 20 */
+ .long _sys_mount
+ .long _sys_ni_syscall /* old umount */
+ .long _sys_setuid
+ .long _sys_getuid
+ .long _sys_stime /* 25 */
+ .long _sys_ptrace
+ .long _sys_alarm
+ .long _sys_ni_syscall /* old fstat */
+ .long _sys_pause
+ .long _sys_ni_syscall /* old utime */ /* 30 */
+ .long _sys_ni_syscall /* old stty syscall holder */
+ .long _sys_ni_syscall /* old gtty syscall holder */
+ .long _sys_access
+ .long _sys_nice
+ .long _sys_ni_syscall /* 35 */ /* old ftime syscall holder */
+ .long _sys_sync
+ .long _sys_kill
+ .long _sys_rename
+ .long _sys_mkdir
+ .long _sys_rmdir /* 40 */
+ .long _sys_dup
+ .long _sys_pipe
+ .long _sys_times
+ .long _sys_ni_syscall /* old prof syscall holder */
+ .long _sys_brk /* 45 */
+ .long _sys_setgid
+ .long _sys_getgid
+ .long _sys_ni_syscall /* old sys_signal */
+ .long _sys_geteuid /* geteuid16 */
+ .long _sys_getegid /* getegid16 */ /* 50 */
+ .long _sys_acct
+ .long _sys_umount /* recycled never used phys() */
+ .long _sys_ni_syscall /* old lock syscall holder */
+ .long _sys_ioctl
+ .long _sys_fcntl /* 55 */
+ .long _sys_ni_syscall /* old mpx syscall holder */
+ .long _sys_setpgid
+ .long _sys_ni_syscall /* old ulimit syscall holder */
+ .long _sys_ni_syscall /* old old uname */
+ .long _sys_umask /* 60 */
+ .long _sys_chroot
+ .long _sys_ustat
+ .long _sys_dup2
+ .long _sys_getppid
+ .long _sys_getpgrp /* 65 */
+ .long _sys_setsid
+ .long _sys_ni_syscall /* old sys_sigaction */
+ .long _sys_sgetmask
+ .long _sys_ssetmask
+ .long _sys_setreuid /* setreuid16 */ /* 70 */
+ .long _sys_setregid /* setregid16 */
+ .long _sys_ni_syscall /* old sys_sigsuspend */
+ .long _sys_ni_syscall /* old sys_sigpending */
+ .long _sys_sethostname
+ .long _sys_setrlimit /* 75 */
+ .long _sys_ni_syscall /* old getrlimit */
+ .long _sys_getrusage
+ .long _sys_gettimeofday
+ .long _sys_settimeofday
+ .long _sys_getgroups /* getgroups16 */ /* 80 */
+ .long _sys_setgroups /* setgroups16 */
+ .long _sys_ni_syscall /* old_select */
+ .long _sys_symlink
+ .long _sys_ni_syscall /* old lstat */
+ .long _sys_readlink /* 85 */
+ .long _sys_uselib
+ .long _sys_ni_syscall /* sys_swapon */
+ .long _sys_reboot
+ .long _sys_ni_syscall /* old_readdir */
+ .long _sys_ni_syscall /* sys_mmap */ /* 90 */
+ .long _sys_munmap
+ .long _sys_truncate
+ .long _sys_ftruncate
+ .long _sys_fchmod
+ .long _sys_fchown /* fchown16 */ /* 95 */
+ .long _sys_getpriority
+ .long _sys_setpriority
+ .long _sys_ni_syscall /* old profil syscall holder */
+ .long _sys_statfs
+ .long _sys_fstatfs /* 100 */
+ .long _sys_ni_syscall
+ .long _sys_ni_syscall /* old sys_socketcall */
+ .long _sys_syslog
+ .long _sys_setitimer
+ .long _sys_getitimer /* 105 */
+ .long _sys_newstat
+ .long _sys_newlstat
+ .long _sys_newfstat
+ .long _sys_ni_syscall /* old uname */
+ .long _sys_ni_syscall /* iopl for i386 */ /* 110 */
+ .long _sys_vhangup
+ .long _sys_ni_syscall /* obsolete idle() syscall */
+ .long _sys_ni_syscall /* vm86old for i386 */
+ .long _sys_wait4
+ .long _sys_ni_syscall /* 115 */ /* sys_swapoff */
+ .long _sys_sysinfo
+ .long _sys_ni_syscall /* old sys_ipc */
+ .long _sys_fsync
+ .long _sys_ni_syscall /* old sys_sigreturn */
+ .long _sys_clone /* 120 */
+ .long _sys_setdomainname
+ .long _sys_newuname
+ .long _sys_ni_syscall /* old sys_modify_ldt */
+ .long _sys_adjtimex
+ .long _sys_ni_syscall /* 125 */ /* sys_mprotect */
+ .long _sys_ni_syscall /* old sys_sigprocmask */
+ .long _sys_ni_syscall /* old "creat_module" */
+ .long _sys_init_module
+ .long _sys_delete_module
+ .long _sys_ni_syscall /* 130: old "get_kernel_syms" */
+ .long _sys_quotactl
+ .long _sys_getpgid
+ .long _sys_fchdir
+ .long _sys_bdflush
+ .long _sys_ni_syscall /* 135 */ /* sys_sysfs */
+ .long _sys_personality
+ .long _sys_ni_syscall /* for afs_syscall */
+ .long _sys_setfsuid /* setfsuid16 */
+ .long _sys_setfsgid /* setfsgid16 */
+ .long _sys_llseek /* 140 */
+ .long _sys_getdents
+ .long _sys_ni_syscall /* sys_select */
+ .long _sys_flock
+ .long _sys_ni_syscall /* sys_msync */
+ .long _sys_readv /* 145 */
+ .long _sys_writev
+ .long _sys_getsid
+ .long _sys_fdatasync
+ .long _sys_sysctl
+ .long _sys_ni_syscall /* 150 */ /* sys_mlock */
+ .long _sys_ni_syscall /* sys_munlock */
+ .long _sys_ni_syscall /* sys_mlockall */
+ .long _sys_ni_syscall /* sys_munlockall */
+ .long _sys_sched_setparam
+ .long _sys_sched_getparam /* 155 */
+ .long _sys_sched_setscheduler
+ .long _sys_sched_getscheduler
+ .long _sys_sched_yield
+ .long _sys_sched_get_priority_max
+ .long _sys_sched_get_priority_min /* 160 */
+ .long _sys_sched_rr_get_interval
+ .long _sys_nanosleep
+ .long _sys_ni_syscall /* sys_mremap */
+ .long _sys_setresuid /* setresuid16 */
+ .long _sys_getresuid /* getresuid16 */ /* 165 */
+ .long _sys_ni_syscall /* for vm86 */
+ .long _sys_ni_syscall /* old "query_module" */
+ .long _sys_ni_syscall /* sys_poll */
+ .long _sys_ni_syscall /* sys_nfsservctl */
+ .long _sys_setresgid /* setresgid16 */ /* 170 */
+ .long _sys_getresgid /* getresgid16 */
+ .long _sys_prctl
+ .long _sys_rt_sigreturn
+ .long _sys_rt_sigaction
+ .long _sys_rt_sigprocmask /* 175 */
+ .long _sys_rt_sigpending
+ .long _sys_rt_sigtimedwait
+ .long _sys_rt_sigqueueinfo
+ .long _sys_rt_sigsuspend
+ .long _sys_pread64 /* 180 */
+ .long _sys_pwrite64
+ .long _sys_lchown /* lchown16 */
+ .long _sys_getcwd
+ .long _sys_capget
+ .long _sys_capset /* 185 */
+ .long _sys_sigaltstack
+ .long _sys_sendfile
+ .long _sys_ni_syscall /* streams1 */
+ .long _sys_ni_syscall /* streams2 */
+ .long _sys_vfork /* 190 */
+ .long _sys_getrlimit
+ .long _sys_mmap2
+ .long _sys_truncate64
+ .long _sys_ftruncate64
+ .long _sys_stat64 /* 195 */
+ .long _sys_lstat64
+ .long _sys_fstat64
+ .long _sys_chown
+ .long _sys_getuid
+ .long _sys_getgid /* 200 */
+ .long _sys_geteuid
+ .long _sys_getegid
+ .long _sys_setreuid
+ .long _sys_setregid
+ .long _sys_getgroups /* 205 */
+ .long _sys_setgroups
+ .long _sys_fchown
+ .long _sys_setresuid
+ .long _sys_getresuid
+ .long _sys_setresgid /* 210 */
+ .long _sys_getresgid
+ .long _sys_lchown
+ .long _sys_setuid
+ .long _sys_setgid
+ .long _sys_setfsuid /* 215 */
+ .long _sys_setfsgid
+ .long _sys_pivot_root
+ .long _sys_ni_syscall /* sys_mincore */
+ .long _sys_ni_syscall /* sys_madvise */
+ .long _sys_getdents64 /* 220 */
+ .long _sys_fcntl64
+ .long _sys_ni_syscall /* reserved for TUX */
+ .long _sys_ni_syscall
+ .long _sys_gettid
+ .long _sys_ni_syscall /* 225 */ /* sys_readahead */
+ .long _sys_setxattr
+ .long _sys_lsetxattr
+ .long _sys_fsetxattr
+ .long _sys_getxattr
+ .long _sys_lgetxattr /* 230 */
+ .long _sys_fgetxattr
+ .long _sys_listxattr
+ .long _sys_llistxattr
+ .long _sys_flistxattr
+ .long _sys_removexattr /* 235 */
+ .long _sys_lremovexattr
+ .long _sys_fremovexattr
+ .long _sys_tkill
+ .long _sys_sendfile64
+ .long _sys_futex /* 240 */
+ .long _sys_sched_setaffinity
+ .long _sys_sched_getaffinity
+ .long _sys_ni_syscall /* sys_set_thread_area */
+ .long _sys_ni_syscall /* sys_get_thread_area */
+ .long _sys_io_setup /* 245 */
+ .long _sys_io_destroy
+ .long _sys_io_getevents
+ .long _sys_io_submit
+ .long _sys_io_cancel
+ .long _sys_ni_syscall /* 250 */ /* sys_alloc_hugepages */
+ .long _sys_ni_syscall /* sys_freec_hugepages */
+ .long _sys_exit_group
+ .long _sys_lookup_dcookie
+ .long _sys_bfin_spinlock
+ .long _sys_epoll_create /* 255 */
+ .long _sys_epoll_ctl
+ .long _sys_epoll_wait
+ .long _sys_ni_syscall /* remap_file_pages */
+ .long _sys_set_tid_address
+ .long _sys_timer_create /* 260 */
+ .long _sys_timer_settime
+ .long _sys_timer_gettime
+ .long _sys_timer_getoverrun
+ .long _sys_timer_delete
+ .long _sys_clock_settime /* 265 */
+ .long _sys_clock_gettime
+ .long _sys_clock_getres
+ .long _sys_clock_nanosleep
+ .long _sys_statfs64
+ .long _sys_fstatfs64 /* 270 */
+ .long _sys_tgkill
+ .long _sys_utimes
+ .long _sys_fadvise64_64
+ .long _sys_ni_syscall /* vserver */
+ .long _sys_ni_syscall /* 275, mbind */
+ .long _sys_ni_syscall /* get_mempolicy */
+ .long _sys_ni_syscall /* set_mempolicy */
+ .long _sys_mq_open
+ .long _sys_mq_unlink
+ .long _sys_mq_timedsend /* 280 */
+ .long _sys_mq_timedreceive
+ .long _sys_mq_notify
+ .long _sys_mq_getsetattr
+ .long _sys_ni_syscall /* kexec_load */
+ .long _sys_waitid /* 285 */
+ .long _sys_add_key
+ .long _sys_request_key
+ .long _sys_keyctl
+ .long _sys_ioprio_set
+ .long _sys_ioprio_get /* 290 */
+ .long _sys_inotify_init
+ .long _sys_inotify_add_watch
+ .long _sys_inotify_rm_watch
+ .long _sys_ni_syscall /* migrate_pages */
+ .long _sys_openat /* 295 */
+ .long _sys_mkdirat
+ .long _sys_mknodat
+ .long _sys_fchownat
+ .long _sys_futimesat
+ .long _sys_fstatat64 /* 300 */
+ .long _sys_unlinkat
+ .long _sys_renameat
+ .long _sys_linkat
+ .long _sys_symlinkat
+ .long _sys_readlinkat /* 305 */
+ .long _sys_fchmodat
+ .long _sys_faccessat
+ .long _sys_pselect6
+ .long _sys_ppoll
+ .long _sys_unshare /* 310 */
+ .long _sys_sram_alloc
+ .long _sys_sram_free
+ .long _sys_dma_memcpy
+ .long _sys_accept
+ .long _sys_bind /* 315 */
+ .long _sys_connect
+ .long _sys_getpeername
+ .long _sys_getsockname
+ .long _sys_getsockopt
+ .long _sys_listen /* 320 */
+ .long _sys_recv
+ .long _sys_recvfrom
+ .long _sys_recvmsg
+ .long _sys_send
+ .long _sys_sendmsg /* 325 */
+ .long _sys_sendto
+ .long _sys_setsockopt
+ .long _sys_shutdown
+ .long _sys_socket
+ .long _sys_socketpair /* 330 */
+ .long _sys_semctl
+ .long _sys_semget
+ .long _sys_semop
+ .long _sys_msgctl
+ .long _sys_msgget /* 335 */
+ .long _sys_msgrcv
+ .long _sys_msgsnd
+ .long _sys_shmat
+ .long _sys_shmctl
+ .long _sys_shmdt /* 340 */
+ .long _sys_shmget
+ .rept NR_syscalls-(.-_sys_call_table)/4
+ .long _sys_ni_syscall
+ .endr
+_excpt_saved_imask:
+ .long 0;
+
+_exception_stack:
+ .rept 1024
+ .long 0;
+ .endr
+_exception_stack_top:
+
+#if defined(ANOMALY_05000261)
+/* Used by the assembly entry point to work around an anomaly. */
+_last_cplb_fault_retx:
+ .long 0;
+#endif
+/*
+ * Single instructions can have multiple faults, which need to be
+ * handled by traps.c, in irq5. We store the exception cause to ensure
+ * we don't miss a double fault condition
+ */
+ENTRY(_in_ptr_excause)
+ .long 0;
+ENTRY(_out_ptr_excause)
+ .long 0;
+ALIGN
+ENTRY(_excause_circ_buf)
+ .rept 4
+ .long 0
+ .endr
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S
new file mode 100644
index 0000000..dd45664
--- /dev/null
+++ b/arch/blackfin/mach-common/interrupt.S
@@ -0,0 +1,253 @@
+/*
+ * File: arch/blackfin/mach-common/interrupt.S
+ * Based on:
+ * Author: D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>
+ * Kenneth Albanowski <kjahds@kjahds.com>
+ *
+ * Created: ?
+ * Description: Interrupt Entries
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <asm/blackfin.h>
+#include <asm/mach/irq.h>
+#include <linux/autoconf.h>
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/asm-offsets.h>
+
+#include <asm/mach-common/context.S>
+
+#ifdef CONFIG_I_ENTRY_L1
+.section .l1.text
+#else
+.text
+#endif
+
+.align 4 /* just in case */
+
+/*
+ * initial interrupt handlers
+ */
+
+#ifndef CONFIG_KGDB
+ /* interrupt routine for emulation - 0 */
+ /* Currently used only if GDB stub is not in - invalid */
+ /* gdb-stub set the evt itself */
+ /* save registers for post-mortem only */
+ENTRY(_evt_emulation)
+ SAVE_ALL_SYS
+#ifdef CONFIG_FRAME_POINTER
+ fp = 0;
+#endif
+ r0 = IRQ_EMU;
+ r1 = sp;
+ SP += -12;
+ call _irq_panic;
+ SP += 12;
+ /* - GDB stub fills this in by itself (if defined) */
+ rte;
+#endif
+
+/* Common interrupt entry code. First we do CLI, then push
+ * RETI, to keep interrupts disabled, but to allow this state to be changed
+ * by local_bh_enable.
+ * R0 contains the interrupt number, while R1 may contain the value of IPEND,
+ * or garbage if IPEND won't be needed by the ISR. */
+__common_int_entry:
+ [--sp] = fp;
+ [--sp] = usp;
+
+ [--sp] = i0;
+ [--sp] = i1;
+ [--sp] = i2;
+ [--sp] = i3;
+
+ [--sp] = m0;
+ [--sp] = m1;
+ [--sp] = m2;
+ [--sp] = m3;
+
+ [--sp] = l0;
+ [--sp] = l1;
+ [--sp] = l2;
+ [--sp] = l3;
+
+ [--sp] = b0;
+ [--sp] = b1;
+ [--sp] = b2;
+ [--sp] = b3;
+ [--sp] = a0.x;
+ [--sp] = a0.w;
+ [--sp] = a1.x;
+ [--sp] = a1.w;
+
+ [--sp] = LC0;
+ [--sp] = LC1;
+ [--sp] = LT0;
+ [--sp] = LT1;
+ [--sp] = LB0;
+ [--sp] = LB1;
+
+ [--sp] = ASTAT;
+
+ [--sp] = r0; /* Skip reserved */
+ [--sp] = RETS;
+ r2 = RETI;
+ [--sp] = r2;
+ [--sp] = RETX;
+ [--sp] = RETN;
+ [--sp] = RETE;
+ [--sp] = SEQSTAT;
+ [--sp] = r1; /* IPEND - R1 may or may not be set up before jumping here. */
+
+ /* Switch to other method of keeping interrupts disabled. */
+#ifdef CONFIG_DEBUG_HWERR
+ r1 = 0x3f;
+ sti r1;
+#else
+ cli r1;
+#endif
+ [--sp] = RETI; /* orig_pc */
+ /* Clear all L registers. */
+ r1 = 0 (x);
+ l0 = r1;
+ l1 = r1;
+ l2 = r1;
+ l3 = r1;
+#ifdef CONFIG_FRAME_POINTER
+ fp = 0;
+#endif
+
+#ifdef ANOMALY_05000283
+ cc = r7 == r7;
+ p5.h = 0xffc0;
+ p5.l = 0x0014;
+ if cc jump 1f;
+ r7.l = W[p5];
+1:
+#endif
+ r1 = sp;
+ SP += -12;
+ call _do_irq;
+ SP += 12;
+ call _return_from_int;
+.Lcommon_restore_context:
+ RESTORE_CONTEXT
+ rti;
+
+/* interrupt routine for ivhw - 5 */
+ENTRY(_evt_ivhw)
+ SAVE_CONTEXT
+#ifdef CONFIG_FRAME_POINTER
+ fp = 0;
+#endif
+#ifdef ANOMALY_05000283
+ cc = r7 == r7;
+ p5.h = 0xffc0;
+ p5.l = 0x0014;
+ if cc jump 1f;
+ r7.l = W[p5];
+1:
+#endif
+ p0.l = lo(TBUFCTL);
+ p0.h = hi(TBUFCTL);
+ r0 = 1;
+ [p0] = r0;
+ r0 = IRQ_HWERR;
+ r1 = sp;
+
+#ifdef CONFIG_HARDWARE_PM
+ r7 = SEQSTAT;
+ r7 = r7 >>> 0xe;
+ r6 = 0x1F;
+ r7 = r7 & r6;
+ r5 = 0x12;
+ cc = r7 == r5;
+ if cc jump .Lcall_do_ovf; /* deal with performance counter overflow */
+#endif
+
+ SP += -12;
+ call _irq_panic;
+ SP += 12;
+ rti;
+#ifdef CONFIG_HARDWARE_PM
+.Lcall_do_ovf:
+
+ SP += -12;
+ call _pm_overflow;
+ SP += 12;
+
+ jump .Lcommon_restore_context;
+#endif
+
+/* interrupt routine for evt2 - 2. This is NMI. */
+ENTRY(_evt_evt2)
+ SAVE_CONTEXT
+#ifdef CONFIG_FRAME_POINTER
+ fp = 0;
+#endif
+#ifdef ANOMALY_05000283
+ cc = r7 == r7;
+ p5.h = 0xffc0;
+ p5.l = 0x0014;
+ if cc jump 1f;
+ r7.l = W[p5];
+1:
+#endif
+ r0 = IRQ_NMI;
+ r1 = sp;
+ SP += -12;
+ call _asm_do_IRQ;
+ SP += 12;
+ RESTORE_CONTEXT
+ rtn;
+
+/* interrupt routine for core timer - 6 */
+ENTRY(_evt_timer)
+ TIMER_INTERRUPT_ENTRY(EVT_IVTMR_P)
+
+/* interrupt routine for evt7 - 7 */
+ENTRY(_evt_evt7)
+ INTERRUPT_ENTRY(EVT_IVG7_P)
+ENTRY(_evt_evt8)
+ INTERRUPT_ENTRY(EVT_IVG8_P)
+ENTRY(_evt_evt9)
+ INTERRUPT_ENTRY(EVT_IVG9_P)
+ENTRY(_evt_evt10)
+ INTERRUPT_ENTRY(EVT_IVG10_P)
+ENTRY(_evt_evt11)
+ INTERRUPT_ENTRY(EVT_IVG11_P)
+ENTRY(_evt_evt12)
+ INTERRUPT_ENTRY(EVT_IVG12_P)
+ENTRY(_evt_evt13)
+ INTERRUPT_ENTRY(EVT_IVG13_P)
+
+
+ /* interrupt routine for system_call - 15 */
+ENTRY(_evt_system_call)
+ SAVE_CONTEXT_SYSCALL
+#ifdef CONFIG_FRAME_POINTER
+ fp = 0;
+#endif
+ call _system_call;
+ jump .Lcommon_restore_context;
diff --git a/arch/blackfin/mach-common/ints-priority-dc.c b/arch/blackfin/mach-common/ints-priority-dc.c
new file mode 100644
index 0000000..f3cf070
--- /dev/null
+++ b/arch/blackfin/mach-common/ints-priority-dc.c
@@ -0,0 +1,476 @@
+/*
+ * File: arch/blackfin/mach-common/ints-priority-dc.c
+ * Based on:
+ * Author:
+ *
+ * Created: ?
+ * Description: Set up the interupt priorities
+ *
+ * Modified:
+ * 1996 Roman Zippel
+ * 1999 D. Jeff Dionne <jeff@uclinux.org>
+ * 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@lineo.ca>
+ * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
+ * 2003 Metrowerks/Motorola
+ * 2003 Bas Vermeulen <bas@buyways.nl>
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel_stat.h>
+#include <linux/seq_file.h>
+#include <linux/irq.h>
+#ifdef CONFIG_KGDB
+#include <linux/kgdb.h>
+#endif
+#include <asm/traps.h>
+#include <asm/blackfin.h>
+#include <asm/gpio.h>
+#include <asm/irq_handler.h>
+
+/*
+ * NOTES:
+ * - we have separated the physical Hardware interrupt from the
+ * levels that the LINUX kernel sees (see the description in irq.h)
+ * -
+ */
+
+unsigned long irq_flags = 0;
+
+/* The number of spurious interrupts */
+atomic_t num_spurious;
+
+struct ivgx {
+ /* irq number for request_irq, available in mach-bf561/irq.h */
+ int irqno;
+ /* corresponding bit in the SICA_ISR0 register */
+ int isrflag0;
+ /* corresponding bit in the SICA_ISR1 register */
+ int isrflag1;
+} ivg_table[NR_PERI_INTS];
+
+struct ivg_slice {
+ /* position of first irq in ivg_table for given ivg */
+ struct ivgx *ifirst;
+ struct ivgx *istop;
+} ivg7_13[IVG13 - IVG7 + 1];
+
+static void search_IAR(void);
+
+/*
+ * Search SIC_IAR and fill tables with the irqvalues
+ * and their positions in the SIC_ISR register.
+ */
+static void __init search_IAR(void)
+{
+ unsigned ivg, irq_pos = 0;
+ for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) {
+ int irqn;
+
+ ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = &ivg_table[irq_pos];
+
+ for (irqn = 0; irqn < NR_PERI_INTS; irqn++) {
+ int iar_shift = (irqn & 7) * 4;
+ if (ivg ==
+ (0xf &
+ bfin_read32((unsigned long *)SICA_IAR0 +
+ (irqn >> 3)) >> iar_shift)) {
+ ivg_table[irq_pos].irqno = IVG7 + irqn;
+ ivg_table[irq_pos].isrflag0 =
+ (irqn < 32 ? (1 << irqn) : 0);
+ ivg_table[irq_pos].isrflag1 =
+ (irqn < 32 ? 0 : (1 << (irqn - 32)));
+ ivg7_13[ivg].istop++;
+ irq_pos++;
+ }
+ }
+ }
+}
+
+/*
+ * This is for BF561 internal IRQs
+ */
+
+static void ack_noop(unsigned int irq)
+{
+ /* Dummy function. */
+}
+
+static void bf561_core_mask_irq(unsigned int irq)
+{
+ irq_flags &= ~(1 << irq);
+ if (!irqs_disabled())
+ local_irq_enable();
+}
+
+static void bf561_core_unmask_irq(unsigned int irq)
+{
+ irq_flags |= 1 << irq;
+ /*
+ * If interrupts are enabled, IMASK must contain the same value
+ * as irq_flags. Make sure that invariant holds. If interrupts
+ * are currently disabled we need not do anything; one of the
+ * callers will take care of setting IMASK to the proper value
+ * when reenabling interrupts.
+ * local_irq_enable just does "STI irq_flags", so it's exactly
+ * what we need.
+ */
+ if (!irqs_disabled())
+ local_irq_enable();
+ return;
+}
+
+static void bf561_internal_mask_irq(unsigned int irq)
+{
+ unsigned long irq_mask;
+ if ((irq - (IRQ_CORETMR + 1)) < 32) {
+ irq_mask = (1 << (irq - (IRQ_CORETMR + 1)));
+ bfin_write_SICA_IMASK0(bfin_read_SICA_IMASK0() & ~irq_mask);
+ } else {
+ irq_mask = (1 << (irq - (IRQ_CORETMR + 1) - 32));
+ bfin_write_SICA_IMASK1(bfin_read_SICA_IMASK1() & ~irq_mask);
+ }
+}
+
+static void bf561_internal_unmask_irq(unsigned int irq)
+{
+ unsigned long irq_mask;
+
+ if ((irq - (IRQ_CORETMR + 1)) < 32) {
+ irq_mask = (1 << (irq - (IRQ_CORETMR + 1)));
+ bfin_write_SICA_IMASK0(bfin_read_SICA_IMASK0() | irq_mask);
+ } else {
+ irq_mask = (1 << (irq - (IRQ_CORETMR + 1) - 32));
+ bfin_write_SICA_IMASK1(bfin_read_SICA_IMASK1() | irq_mask);
+ }
+ SSYNC();
+}
+
+static struct irq_chip bf561_core_irqchip = {
+ .ack = ack_noop,
+ .mask = bf561_core_mask_irq,
+ .unmask = bf561_core_unmask_irq,
+};
+
+static struct irq_chip bf561_internal_irqchip = {
+ .ack = ack_noop,
+ .mask = bf561_internal_mask_irq,
+ .unmask = bf561_internal_unmask_irq,
+};
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
+static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)];
+
+static void bf561_gpio_ack_irq(unsigned int irq)
+{
+ u16 gpionr = irq - IRQ_PF0;
+
+ if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
+ set_gpio_data(gpionr, 0);
+ SSYNC();
+ }
+}
+
+static void bf561_gpio_mask_ack_irq(unsigned int irq)
+{
+ u16 gpionr = irq - IRQ_PF0;
+
+ if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
+ set_gpio_data(gpionr, 0);
+ SSYNC();
+ }
+
+ set_gpio_maska(gpionr, 0);
+ SSYNC();
+}
+
+static void bf561_gpio_mask_irq(unsigned int irq)
+{
+ set_gpio_maska(irq - IRQ_PF0, 0);
+ SSYNC();
+}
+
+static void bf561_gpio_unmask_irq(unsigned int irq)
+{
+ set_gpio_maska(irq - IRQ_PF0, 1);
+ SSYNC();
+}
+
+static unsigned int bf561_gpio_irq_startup(unsigned int irq)
+{
+ unsigned int ret;
+ u16 gpionr = irq - IRQ_PF0;
+
+ if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+
+ ret = gpio_request(gpionr, NULL);
+ if(ret)
+ return ret;
+
+ }
+
+ gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+ bf561_gpio_unmask_irq(irq);
+
+ return ret;
+
+}
+
+static void bf561_gpio_irq_shutdown(unsigned int irq)
+{
+ bf561_gpio_mask_irq(irq);
+ gpio_free(irq - IRQ_PF0);
+ gpio_enabled[gpio_bank(irq - IRQ_PF0)] &= ~gpio_bit(irq - IRQ_PF0);
+}
+
+static int bf561_gpio_irq_type(unsigned int irq, unsigned int type)
+{
+
+ unsigned int ret;
+ u16 gpionr = irq - IRQ_PF0;
+
+
+ if (type == IRQ_TYPE_PROBE) {
+ /* only probe unenabled GPIO interrupt lines */
+ if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))
+ return 0;
+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+
+ }
+
+ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
+ IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
+
+ if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+
+ ret = gpio_request(gpionr, NULL);
+ if(ret)
+ return ret;
+
+ }
+
+ gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+ } else {
+ gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
+ return 0;
+ }
+
+
+ set_gpio_dir(gpionr, 0);
+ set_gpio_inen(gpionr, 1);
+
+
+ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
+ gpio_edge_triggered[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+ set_gpio_edge(gpionr, 1);
+ } else {
+ set_gpio_edge(gpionr, 0);
+ gpio_edge_triggered[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
+ }
+
+ if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+ == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+ set_gpio_both(gpionr, 1);
+ else
+ set_gpio_both(gpionr, 0);
+
+ if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))
+ set_gpio_polar(gpionr, 1); /* low or falling edge denoted by one */
+ else
+ set_gpio_polar(gpionr, 0); /* high or rising edge denoted by zero */
+
+ SSYNC();
+
+ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+ set_irq_handler(irq, handle_edge_irq);
+ else
+ set_irq_handler(irq, handle_level_irq);
+
+ return 0;
+}
+
+static struct irq_chip bf561_gpio_irqchip = {
+ .ack = bf561_gpio_ack_irq,
+ .mask = bf561_gpio_mask_irq,
+ .mask_ack = bf561_gpio_mask_ack_irq,
+ .unmask = bf561_gpio_unmask_irq,
+ .set_type = bf561_gpio_irq_type,
+ .startup = bf561_gpio_irq_startup,
+ .shutdown = bf561_gpio_irq_shutdown
+};
+
+static void bf561_demux_gpio_irq(unsigned int inta_irq,
+ struct irq_desc *intb_desc)
+{
+ int irq, flag_d, mask;
+ u16 gpio;
+
+ switch (inta_irq) {
+ case IRQ_PROG0_INTA:
+ irq = IRQ_PF0;
+ break;
+ case IRQ_PROG1_INTA:
+ irq = IRQ_PF16;
+ break;
+ case IRQ_PROG2_INTA:
+ irq = IRQ_PF32;
+ break;
+ default:
+ dump_stack();
+ return;
+ }
+
+ gpio = irq - IRQ_PF0;
+
+ flag_d = get_gpiop_data(gpio);
+ mask = flag_d & (gpio_enabled[gpio_bank(gpio)] &
+ get_gpiop_maska(gpio));
+
+ do {
+ if (mask & 1) {
+ struct irq_desc *desc = irq_desc + irq;
+ desc->handle_irq(irq, desc);
+ }
+ irq++;
+ mask >>= 1;
+ } while (mask);
+
+
+}
+
+#endif /* CONFIG_IRQCHIP_DEMUX_GPIO */
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the BFin IRQ handling routines.
+ */
+int __init init_arch_irq(void)
+{
+ int irq;
+ unsigned long ilat = 0;
+ /* Disable all the peripheral intrs - page 4-29 HW Ref manual */
+ bfin_write_SICA_IMASK0(SIC_UNMASK_ALL);
+ bfin_write_SICA_IMASK1(SIC_UNMASK_ALL);
+ SSYNC();
+
+ local_irq_disable();
+
+ init_exception_buff();
+
+#ifndef CONFIG_KGDB
+ bfin_write_EVT0(evt_emulation);
+#endif
+ bfin_write_EVT2(evt_evt2);
+ bfin_write_EVT3(trap);
+ bfin_write_EVT5(evt_ivhw);
+ bfin_write_EVT6(evt_timer);
+ bfin_write_EVT7(evt_evt7);
+ bfin_write_EVT8(evt_evt8);
+ bfin_write_EVT9(evt_evt9);
+ bfin_write_EVT10(evt_evt10);
+ bfin_write_EVT11(evt_evt11);
+ bfin_write_EVT12(evt_evt12);
+ bfin_write_EVT13(evt_evt13);
+ bfin_write_EVT14(evt14_softirq);
+ bfin_write_EVT15(evt_system_call);
+ CSYNC();
+
+ for (irq = 0; irq < SYS_IRQS; irq++) {
+ if (irq <= IRQ_CORETMR)
+ set_irq_chip(irq, &bf561_core_irqchip);
+ else
+ set_irq_chip(irq, &bf561_internal_irqchip);
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+ if ((irq != IRQ_PROG0_INTA) &&
+ (irq != IRQ_PROG1_INTA) && (irq != IRQ_PROG2_INTA)) {
+#endif
+ set_irq_handler(irq, handle_simple_irq);
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+ } else {
+ set_irq_chained_handler(irq, bf561_demux_gpio_irq);
+ }
+#endif
+
+ }
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+ for (irq = IRQ_PF0; irq <= IRQ_PF47; irq++) {
+ set_irq_chip(irq, &bf561_gpio_irqchip);
+ /* if configured as edge, then will be changed to do_edge_IRQ */
+ set_irq_handler(irq, handle_level_irq);
+ }
+#endif
+ bfin_write_IMASK(0);
+ CSYNC();
+ ilat = bfin_read_ILAT();
+ CSYNC();
+ bfin_write_ILAT(ilat);
+ CSYNC();
+
+ printk(KERN_INFO "Configuring Blackfin Priority Driven Interrupts\n");
+ /* IMASK=xxx is equivalent to STI xx or irq_flags=xx,
+ * local_irq_enable()
+ */
+ program_IAR();
+ /* Therefore it's better to setup IARs before interrupts enabled */
+ search_IAR();
+
+ /* Enable interrupts IVG7-15 */
+ irq_flags = irq_flags | IMASK_IVG15 |
+ IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
+ IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
+
+ return 0;
+}
+
+#ifdef CONFIG_DO_IRQ_L1
+void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text));
+#endif
+
+void do_irq(int vec, struct pt_regs *fp)
+{
+ if (vec == EVT_IVTMR_P) {
+ vec = IRQ_CORETMR;
+ } else {
+ struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
+ struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
+ unsigned long sic_status0, sic_status1;
+
+ SSYNC();
+ sic_status0 = bfin_read_SICA_IMASK0() & bfin_read_SICA_ISR0();
+ sic_status1 = bfin_read_SICA_IMASK1() & bfin_read_SICA_ISR1();
+
+ for (;; ivg++) {
+ if (ivg >= ivg_stop) {
+ atomic_inc(&num_spurious);
+ return;
+ } else if ((sic_status0 & ivg->isrflag0) ||
+ (sic_status1 & ivg->isrflag1))
+ break;
+ }
+ vec = ivg->irqno;
+ }
+ asm_do_IRQ(vec, fp);
+
+#ifdef CONFIG_KGDB
+ kgdb_process_breakpoint();
+#endif
+}
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c
new file mode 100644
index 0000000..34b6228
--- /dev/null
+++ b/arch/blackfin/mach-common/ints-priority-sc.c
@@ -0,0 +1,577 @@
+/*
+ * File: arch/blackfin/mach-common/ints-priority-sc.c
+ * Based on:
+ * Author:
+ *
+ * Created: ?
+ * Description: Set up the interupt priorities
+ *
+ * Modified:
+ * 1996 Roman Zippel
+ * 1999 D. Jeff Dionne <jeff@uclinux.org>
+ * 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@lineo.ca>
+ * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
+ * 2003 Metrowerks/Motorola
+ * 2003 Bas Vermeulen <bas@buyways.nl>
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel_stat.h>
+#include <linux/seq_file.h>
+#include <linux/irq.h>
+#ifdef CONFIG_KGDB
+#include <linux/kgdb.h>
+#endif
+#include <asm/traps.h>
+#include <asm/blackfin.h>
+#include <asm/gpio.h>
+#include <asm/irq_handler.h>
+
+#ifdef BF537_FAMILY
+# define BF537_GENERIC_ERROR_INT_DEMUX
+#else
+# undef BF537_GENERIC_ERROR_INT_DEMUX
+#endif
+
+/*
+ * NOTES:
+ * - we have separated the physical Hardware interrupt from the
+ * levels that the LINUX kernel sees (see the description in irq.h)
+ * -
+ */
+
+unsigned long irq_flags = 0;
+
+/* The number of spurious interrupts */
+atomic_t num_spurious;
+
+struct ivgx {
+ /* irq number for request_irq, available in mach-bf533/irq.h */
+ int irqno;
+ /* corresponding bit in the SIC_ISR register */
+ int isrflag;
+} ivg_table[NR_PERI_INTS];
+
+struct ivg_slice {
+ /* position of first irq in ivg_table for given ivg */
+ struct ivgx *ifirst;
+ struct ivgx *istop;
+} ivg7_13[IVG13 - IVG7 + 1];
+
+static void search_IAR(void);
+
+/*
+ * Search SIC_IAR and fill tables with the irqvalues
+ * and their positions in the SIC_ISR register.
+ */
+static void __init search_IAR(void)
+{
+ unsigned ivg, irq_pos = 0;
+ for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) {
+ int irqn;
+
+ ivg7_13[ivg].istop = ivg7_13[ivg].ifirst =
+ &ivg_table[irq_pos];
+
+ for (irqn = 0; irqn < NR_PERI_INTS; irqn++) {
+ int iar_shift = (irqn & 7) * 4;
+ if (ivg ==
+ (0xf &
+ bfin_read32((unsigned long *) SIC_IAR0 +
+ (irqn >> 3)) >> iar_shift)) {
+ ivg_table[irq_pos].irqno = IVG7 + irqn;
+ ivg_table[irq_pos].isrflag = 1 << irqn;
+ ivg7_13[ivg].istop++;
+ irq_pos++;
+ }
+ }
+ }
+}
+
+/*
+ * This is for BF533 internal IRQs
+ */
+
+static void ack_noop(unsigned int irq)
+{
+ /* Dummy function. */
+}
+
+static void bfin_core_mask_irq(unsigned int irq)
+{
+ irq_flags &= ~(1 << irq);
+ if (!irqs_disabled())
+ local_irq_enable();
+}
+
+static void bfin_core_unmask_irq(unsigned int irq)
+{
+ irq_flags |= 1 << irq;
+ /*
+ * If interrupts are enabled, IMASK must contain the same value
+ * as irq_flags. Make sure that invariant holds. If interrupts
+ * are currently disabled we need not do anything; one of the
+ * callers will take care of setting IMASK to the proper value
+ * when reenabling interrupts.
+ * local_irq_enable just does "STI irq_flags", so it's exactly
+ * what we need.
+ */
+ if (!irqs_disabled())
+ local_irq_enable();
+ return;
+}
+
+static void bfin_internal_mask_irq(unsigned int irq)
+{
+ bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
+ ~(1 << (irq - (IRQ_CORETMR + 1))));
+ SSYNC();
+}
+
+static void bfin_internal_unmask_irq(unsigned int irq)
+{
+ bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
+ (1 << (irq - (IRQ_CORETMR + 1))));
+ SSYNC();
+}
+
+static struct irq_chip bfin_core_irqchip = {
+ .ack = ack_noop,
+ .mask = bfin_core_mask_irq,
+ .unmask = bfin_core_unmask_irq,
+};
+
+static struct irq_chip bfin_internal_irqchip = {
+ .ack = ack_noop,
+ .mask = bfin_internal_mask_irq,
+ .unmask = bfin_internal_unmask_irq,
+};
+
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+static int error_int_mask;
+
+static void bfin_generic_error_ack_irq(unsigned int irq)
+{
+
+}
+
+static void bfin_generic_error_mask_irq(unsigned int irq)
+{
+ error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR));
+
+ if (!error_int_mask) {
+ local_irq_disable();
+ bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
+ ~(1 <<
+ (IRQ_GENERIC_ERROR -
+ (IRQ_CORETMR + 1))));
+ SSYNC();
+ local_irq_enable();
+ }
+}
+
+static void bfin_generic_error_unmask_irq(unsigned int irq)
+{
+ local_irq_disable();
+ bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 1 <<
+ (IRQ_GENERIC_ERROR - (IRQ_CORETMR + 1)));
+ SSYNC();
+ local_irq_enable();
+
+ error_int_mask |= 1L << (irq - IRQ_PPI_ERROR);
+}
+
+static struct irq_chip bfin_generic_error_irqchip = {
+ .ack = bfin_generic_error_ack_irq,
+ .mask = bfin_generic_error_mask_irq,
+ .unmask = bfin_generic_error_unmask_irq,
+};
+
+static void bfin_demux_error_irq(unsigned int int_err_irq,
+ struct irq_desc *intb_desc)
+{
+ int irq = 0;
+
+ SSYNC();
+
+#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
+ if (bfin_read_EMAC_SYSTAT() & EMAC_ERR_MASK)
+ irq = IRQ_MAC_ERROR;
+ else
+#endif
+ if (bfin_read_SPORT0_STAT() & SPORT_ERR_MASK)
+ irq = IRQ_SPORT0_ERROR;
+ else if (bfin_read_SPORT1_STAT() & SPORT_ERR_MASK)
+ irq = IRQ_SPORT1_ERROR;
+ else if (bfin_read_PPI_STATUS() & PPI_ERR_MASK)
+ irq = IRQ_PPI_ERROR;
+ else if (bfin_read_CAN_GIF() & CAN_ERR_MASK)
+ irq = IRQ_CAN_ERROR;
+ else if (bfin_read_SPI_STAT() & SPI_ERR_MASK)
+ irq = IRQ_SPI_ERROR;
+ else if ((bfin_read_UART0_IIR() & UART_ERR_MASK_STAT1) &&
+ (bfin_read_UART0_IIR() & UART_ERR_MASK_STAT0))
+ irq = IRQ_UART0_ERROR;
+ else if ((bfin_read_UART1_IIR() & UART_ERR_MASK_STAT1) &&
+ (bfin_read_UART1_IIR() & UART_ERR_MASK_STAT0))
+ irq = IRQ_UART1_ERROR;
+
+ if (irq) {
+ if (error_int_mask & (1L << (irq - IRQ_PPI_ERROR))) {
+ struct irq_desc *desc = irq_desc + irq;
+ desc->handle_irq(irq, desc);
+ } else {
+
+ switch (irq) {
+ case IRQ_PPI_ERROR:
+ bfin_write_PPI_STATUS(PPI_ERR_MASK);
+ break;
+#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
+ case IRQ_MAC_ERROR:
+ bfin_write_EMAC_SYSTAT(EMAC_ERR_MASK);
+ break;
+#endif
+ case IRQ_SPORT0_ERROR:
+ bfin_write_SPORT0_STAT(SPORT_ERR_MASK);
+ break;
+
+ case IRQ_SPORT1_ERROR:
+ bfin_write_SPORT1_STAT(SPORT_ERR_MASK);
+ break;
+
+ case IRQ_CAN_ERROR:
+ bfin_write_CAN_GIS(CAN_ERR_MASK);
+ break;
+
+ case IRQ_SPI_ERROR:
+ bfin_write_SPI_STAT(SPI_ERR_MASK);
+ break;
+
+ default:
+ break;
+ }
+
+ pr_debug("IRQ %d:"
+ " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n",
+ irq);
+ }
+ } else
+ printk(KERN_ERR
+ "%s : %s : LINE %d :\nIRQ ?: PERIPHERAL ERROR"
+ " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
+ __FUNCTION__, __FILE__, __LINE__);
+
+
+}
+#endif /* BF537_GENERIC_ERROR_INT_DEMUX */
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+
+static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
+static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)];
+
+static void bfin_gpio_ack_irq(unsigned int irq)
+{
+ u16 gpionr = irq - IRQ_PF0;
+
+ if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
+ set_gpio_data(gpionr, 0);
+ SSYNC();
+ }
+}
+
+static void bfin_gpio_mask_ack_irq(unsigned int irq)
+{
+ u16 gpionr = irq - IRQ_PF0;
+
+ if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) {
+ set_gpio_data(gpionr, 0);
+ SSYNC();
+ }
+
+ set_gpio_maska(gpionr, 0);
+ SSYNC();
+}
+
+static void bfin_gpio_mask_irq(unsigned int irq)
+{
+ set_gpio_maska(irq - IRQ_PF0, 0);
+ SSYNC();
+}
+
+static void bfin_gpio_unmask_irq(unsigned int irq)
+{
+ set_gpio_maska(irq - IRQ_PF0, 1);
+ SSYNC();
+}
+
+static unsigned int bfin_gpio_irq_startup(unsigned int irq)
+{
+ unsigned int ret;
+ u16 gpionr = irq - IRQ_PF0;
+
+ if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+ ret = gpio_request(gpionr, NULL);
+ if (ret)
+ return ret;
+ }
+
+ gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+ bfin_gpio_unmask_irq(irq);
+
+ return ret;
+}
+
+static void bfin_gpio_irq_shutdown(unsigned int irq)
+{
+ bfin_gpio_mask_irq(irq);
+ gpio_free(irq - IRQ_PF0);
+ gpio_enabled[gpio_bank(irq - IRQ_PF0)] &= ~gpio_bit(irq - IRQ_PF0);
+}
+
+static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
+{
+
+ unsigned int ret;
+ u16 gpionr = irq - IRQ_PF0;
+
+ if (type == IRQ_TYPE_PROBE) {
+ /* only probe unenabled GPIO interrupt lines */
+ if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))
+ return 0;
+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+ }
+
+ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
+ IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
+ {
+ if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+ ret = gpio_request(gpionr, NULL);
+ if (ret)
+ return ret;
+ }
+
+ gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+ } else {
+ gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
+ return 0;
+ }
+
+ set_gpio_dir(gpionr, 0);
+ set_gpio_inen(gpionr, 1);
+
+ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
+ gpio_edge_triggered[gpio_bank(gpionr)] |= gpio_bit(gpionr);
+ set_gpio_edge(gpionr, 1);
+ } else {
+ set_gpio_edge(gpionr, 0);
+ gpio_edge_triggered[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
+ }
+
+ if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+ == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+ set_gpio_both(gpionr, 1);
+ else
+ set_gpio_both(gpionr, 0);
+
+ if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))
+ set_gpio_polar(gpionr, 1); /* low or falling edge denoted by one */
+ else
+ set_gpio_polar(gpionr, 0); /* high or rising edge denoted by zero */
+
+ SSYNC();
+
+ if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+ set_irq_handler(irq, handle_edge_irq);
+ else
+ set_irq_handler(irq, handle_level_irq);
+
+ return 0;
+}
+
+
+static struct irq_chip bfin_gpio_irqchip = {
+ .ack = bfin_gpio_ack_irq,
+ .mask = bfin_gpio_mask_irq,
+ .mask_ack = bfin_gpio_mask_ack_irq,
+ .unmask = bfin_gpio_unmask_irq,
+ .set_type = bfin_gpio_irq_type,
+ .startup = bfin_gpio_irq_startup,
+ .shutdown = bfin_gpio_irq_shutdown
+};
+
+static void bfin_demux_gpio_irq(unsigned int intb_irq,
+ struct irq_desc *intb_desc)
+{
+ u16 i;
+
+ for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=16) {
+ int irq = IRQ_PF0 + i;
+ int flag_d = get_gpiop_data(i);
+ int mask =
+ flag_d & (gpio_enabled[gpio_bank(i)] &
+ get_gpiop_maska(i));
+
+ while (mask) {
+ if (mask & 1) {
+ struct irq_desc *desc = irq_desc + irq;
+ desc->handle_irq(irq, desc);
+ }
+ irq++;
+ mask >>= 1;
+ }
+ }
+}
+
+#endif /* CONFIG_IRQCHIP_DEMUX_GPIO */
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the BFin IRQ handling routines.
+ */
+int __init init_arch_irq(void)
+{
+ int irq;
+ unsigned long ilat = 0;
+ /* Disable all the peripheral intrs - page 4-29 HW Ref manual */
+ bfin_write_SIC_IMASK(SIC_UNMASK_ALL);
+ SSYNC();
+
+ local_irq_disable();
+
+#ifndef CONFIG_KGDB
+ bfin_write_EVT0(evt_emulation);
+#endif
+ bfin_write_EVT2(evt_evt2);
+ bfin_write_EVT3(trap);
+ bfin_write_EVT5(evt_ivhw);
+ bfin_write_EVT6(evt_timer);
+ bfin_write_EVT7(evt_evt7);
+ bfin_write_EVT8(evt_evt8);
+ bfin_write_EVT9(evt_evt9);
+ bfin_write_EVT10(evt_evt10);
+ bfin_write_EVT11(evt_evt11);
+ bfin_write_EVT12(evt_evt12);
+ bfin_write_EVT13(evt_evt13);
+ bfin_write_EVT14(evt14_softirq);
+ bfin_write_EVT15(evt_system_call);
+ CSYNC();
+
+ for (irq = 0; irq < SYS_IRQS; irq++) {
+ if (irq <= IRQ_CORETMR)
+ set_irq_chip(irq, &bfin_core_irqchip);
+ else
+ set_irq_chip(irq, &bfin_internal_irqchip);
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+ if (irq != IRQ_GENERIC_ERROR) {
+#endif
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+ if ((irq != IRQ_PROG_INTA) /*PORT F & G MASK_A Interrupt*/
+# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
+ && (irq != IRQ_MAC_RX) /*PORT H MASK_A Interrupt*/
+# endif
+ ) {
+#endif
+ set_irq_handler(irq, handle_simple_irq);
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+ } else {
+ set_irq_chained_handler(irq,
+ bfin_demux_gpio_irq);
+ }
+#endif
+
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+ } else {
+ set_irq_handler(irq, bfin_demux_error_irq);
+ }
+#endif
+ }
+#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+ for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) {
+ set_irq_chip(irq, &bfin_generic_error_irqchip);
+ set_irq_handler(irq, handle_level_irq);
+ }
+#endif
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+ for (irq = IRQ_PF0; irq < NR_IRQS; irq++) {
+ set_irq_chip(irq, &bfin_gpio_irqchip);
+ /* if configured as edge, then will be changed to do_edge_IRQ */
+ set_irq_handler(irq, handle_level_irq);
+ }
+#endif
+ bfin_write_IMASK(0);
+ CSYNC();
+ ilat = bfin_read_ILAT();
+ CSYNC();
+ bfin_write_ILAT(ilat);
+ CSYNC();
+
+ printk(KERN_INFO
+ "Configuring Blackfin Priority Driven Interrupts\n");
+ /* IMASK=xxx is equivalent to STI xx or irq_flags=xx,
+ * local_irq_enable()
+ */
+ program_IAR();
+ /* Therefore it's better to setup IARs before interrupts enabled */
+ search_IAR();
+
+ /* Enable interrupts IVG7-15 */
+ irq_flags = irq_flags | IMASK_IVG15 |
+ IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
+ IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 |
+ IMASK_IVGHW;
+
+ return 0;
+}
+
+#ifdef CONFIG_DO_IRQ_L1
+void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text));
+#endif
+
+void do_irq(int vec, struct pt_regs *fp)
+{
+ if (vec == EVT_IVTMR_P) {
+ vec = IRQ_CORETMR;
+ } else {
+ struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
+ struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
+ unsigned long sic_status;
+
+ SSYNC();
+ sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
+
+ for (;; ivg++) {
+ if (ivg >= ivg_stop) {
+ atomic_inc(&num_spurious);
+ return;
+ } else if (sic_status & ivg->isrflag)
+ break;
+ }
+ vec = ivg->irqno;
+ }
+ asm_do_IRQ(vec, fp);
+
+#ifdef CONFIG_KGDB
+ kgdb_process_breakpoint();
+#endif
+}
diff --git a/arch/blackfin/mach-common/irqpanic.c b/arch/blackfin/mach-common/irqpanic.c
new file mode 100644
index 0000000..f05e3da
--- /dev/null
+++ b/arch/blackfin/mach-common/irqpanic.c
@@ -0,0 +1,194 @@
+/*
+ * File: arch/blackfin/mach-common/irqpanic.c
+ * Based on:
+ * Author:
+ *
+ * Created: ?
+ * Description: panic kernel with dump information
+ *
+ * Modified: rgetz - added cache checking code 14Feb06
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <asm/traps.h>
+#include <asm/blackfin.h>
+
+#include "../oprofile/op_blackfin.h"
+
+#ifdef CONFIG_DEBUG_ICACHE_CHECK
+#define L1_ICACHE_START 0xffa10000
+#define L1_ICACHE_END 0xffa13fff
+void irq_panic(int reason, struct pt_regs *regs) __attribute__ ((l1_text));
+#endif
+
+/*
+ * irq_panic - calls panic with string setup
+ */
+asmlinkage void irq_panic(int reason, struct pt_regs *regs)
+{
+ int sig = 0;
+ siginfo_t info;
+
+#ifdef CONFIG_DEBUG_ICACHE_CHECK
+ unsigned int cmd, tag, ca, cache_hi, cache_lo, *pa;
+ unsigned short i, j, die;
+ unsigned int bad[10][6];
+
+ /* check entire cache for coherency
+ * Since printk is in cacheable memory,
+ * don't call it until you have checked everything
+ */
+
+ die = 0;
+ i = 0;
+
+ /* check icache */
+
+ for (ca = L1_ICACHE_START; ca <= L1_ICACHE_END && i < 10; ca += 32) {
+
+ /* Grab various address bits for the itest_cmd fields */
+ cmd = (((ca & 0x3000) << 4) | /* ca[13:12] for SBNK[1:0] */
+ ((ca & 0x0c00) << 16) | /* ca[11:10] for WAYSEL[1:0] */
+ ((ca & 0x3f8)) | /* ca[09:03] for SET[4:0] and DW[1:0] */
+ 0); /* Access Tag, Read access */
+
+ SSYNC();
+ bfin_write_ITEST_COMMAND(cmd);
+ SSYNC();
+ tag = bfin_read_ITEST_DATA0();
+ SSYNC();
+
+ /* if tag is marked as valid, check it */
+ if (tag & 1) {
+ /* The icache is arranged in 4 groups of 64-bits */
+ for (j = 0; j < 32; j += 8) {
+ cmd = ((((ca + j) & 0x3000) << 4) | /* ca[13:12] for SBNK[1:0] */
+ (((ca + j) & 0x0c00) << 16) | /* ca[11:10] for WAYSEL[1:0] */
+ (((ca + j) & 0x3f8)) | /* ca[09:03] for SET[4:0] and DW[1:0] */
+ 4); /* Access Data, Read access */
+
+ SSYNC();
+ bfin_write_ITEST_COMMAND(cmd);
+ SSYNC();
+
+ cache_hi = bfin_read_ITEST_DATA1();
+ cache_lo = bfin_read_ITEST_DATA0();
+
+ pa = ((unsigned int *)((tag & 0xffffcc00) |
+ ((ca + j) & ~(0xffffcc00))));
+
+ /*
+ * Debugging this, enable
+ *
+ * printk("addr: %08x %08x%08x | %08x%08x\n",
+ * ((unsigned int *)((tag & 0xffffcc00) | ((ca+j) & ~(0xffffcc00)))),
+ * cache_hi, cache_lo, *(pa+1), *pa);
+ */
+
+ if (cache_hi != *(pa + 1) || cache_lo != *pa) {
+ /* Since icache is not working, stay out of it, by not printing */
+ die = 1;
+ bad[i][0] = (ca + j);
+ bad[i][1] = cache_hi;
+ bad[i][2] = cache_lo;
+ bad[i][3] = ((tag & 0xffffcc00) |
+ ((ca + j) & ~(0xffffcc00)));
+ bad[i][4] = *(pa + 1);
+ bad[i][5] = *(pa);
+ i++;
+ }
+ }
+ }
+ }
+ if (die) {
+ printk(KERN_EMERG "icache coherency error\n");
+ for (j = 0; j <= i; j++) {
+ printk(KERN_EMERG
+ "cache address : %08x cache value : %08x%08x\n",
+ bad[j][0], bad[j][1], bad[j][2]);
+ printk(KERN_EMERG
+ "physical address: %08x SDRAM value : %08x%08x\n",
+ bad[j][3], bad[j][4], bad[j][5]);
+ }
+ panic("icache coherency error");
+ } else {
+ printk(KERN_EMERG "icache checked, and OK\n");
+ }
+#endif
+
+ printk(KERN_EMERG "\n");
+ printk(KERN_EMERG "Exception: IRQ 0x%x entered\n", reason);
+ printk(KERN_EMERG " code=[0x%08lx], stack frame=0x%08lx, "
+ " bad PC=0x%08lx\n",
+ (unsigned long)regs->seqstat,
+ (unsigned long)regs,
+ (unsigned long)regs->pc);
+ if (reason == 0x5) {
+ printk(KERN_EMERG "----------- HARDWARE ERROR -----------\n");
+
+ /* There is only need to check for Hardware Errors, since other
+ * EXCEPTIONS are handled in TRAPS.c (MH)
+ */
+ switch (regs->seqstat & SEQSTAT_HWERRCAUSE) {
+ case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR): /* System MMR Error */
+ info.si_code = BUS_ADRALN;
+ sig = SIGBUS;
+ printk(KERN_EMERG HWC_x2);
+ break;
+ case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): /* External Memory Addressing Error */
+ info.si_code = BUS_ADRERR;
+ sig = SIGBUS;
+ printk(KERN_EMERG HWC_x3);
+ break;
+ case (SEQSTAT_HWERRCAUSE_PERF_FLOW): /* Performance Monitor Overflow */
+ printk(KERN_EMERG HWC_x12);
+ break;
+ case (SEQSTAT_HWERRCAUSE_RAISE_5): /* RAISE 5 instruction */
+ printk(KERN_EMERG HWC_x18);
+ break;
+ default: /* Reserved */
+ printk(KERN_EMERG HWC_default);
+ break;
+ }
+ }
+
+ regs->ipend = bfin_read_IPEND();
+ dump_bfin_regs(regs, (void *)regs->pc);
+ if (0 == (info.si_signo = sig) || 0 == user_mode(regs)) /* in kernelspace */
+ panic("Unhandled IRQ or exceptions!\n");
+ else { /* in userspace */
+ info.si_errno = 0;
+ info.si_addr = (void *)regs->pc;
+ force_sig_info(sig, &info, current);
+ }
+}
+
+#ifdef CONFIG_HARDWARE_PM
+/*
+ * call the handler of Performance overflow
+ */
+asmlinkage void pm_overflow(int irq, struct pt_regs *regs)
+{
+ pm_overflow_handler(irq, regs);
+}
+#endif
diff --git a/arch/blackfin/mach-common/lock.S b/arch/blackfin/mach-common/lock.S
new file mode 100644
index 0000000..2cbb15b
--- /dev/null
+++ b/arch/blackfin/mach-common/lock.S
@@ -0,0 +1,204 @@
+/*
+ * File: arch/blackfin/mach-common/lock.S
+ * Based on:
+ * Author: LG Soft India
+ *
+ * Created: ?
+ * Description: kernel locks
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/cplb.h>
+#include <asm/blackfin.h>
+
+.text
+
+#ifdef CONFIG_BLKFIN_CACHE_LOCK
+
+/* When you come here, it is assumed that
+ * R0 - Which way to be locked
+ */
+
+ENTRY(_cache_grab_lock)
+
+ [--SP]=( R7:0,P5:0 );
+
+ P1.H = (IMEM_CONTROL >> 16);
+ P1.L = (IMEM_CONTROL & 0xFFFF);
+ P5.H = (ICPLB_ADDR0 >> 16);
+ P5.L = (ICPLB_ADDR0 & 0xFFFF);
+ P4.H = (ICPLB_DATA0 >> 16);
+ P4.L = (ICPLB_DATA0 & 0xFFFF);
+ R7 = R0;
+
+ /* If the code of interest already resides in the cache
+ * invalidate the entire cache itself.
+ * invalidate_entire_icache;
+ */
+
+ SP += -12;
+ [--SP] = RETS;
+ CALL _invalidate_entire_icache;
+ RETS = [SP++];
+ SP += 12;
+
+ /* Disable the Interrupts*/
+
+ CLI R3;
+
+.LLOCK_WAY:
+
+ /* Way0 - 0xFFA133E0
+ * Way1 - 0xFFA137E0
+ * Way2 - 0xFFA13BE0 Total Way Size = 4K
+ * Way3 - 0xFFA13FE0
+ */
+
+ /* Procedure Ex. -Set the locks for other ways by setting ILOC[3:1]
+ * Only Way0 of the instruction cache can now be
+ * replaced by a new code
+ */
+
+ R5 = R7;
+ CC = BITTST(R7,0);
+ IF CC JUMP .LCLEAR1;
+ R7 = 0;
+ BITSET(R7,0);
+ JUMP .LDONE1;
+
+.LCLEAR1:
+ R7 = 0;
+ BITCLR(R7,0);
+.LDONE1: R4 = R7 << 3;
+ R7 = [P1];
+ R7 = R7 | R4;
+ SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
+ .align 8;
+ [P1] = R7;
+ SSYNC;
+
+ R7 = R5;
+ CC = BITTST(R7,1);
+ IF CC JUMP .LCLEAR2;
+ R7 = 0;
+ BITSET(R7,1);
+ JUMP .LDONE2;
+
+.LCLEAR2:
+ R7 = 0;
+ BITCLR(R7,1);
+.LDONE2: R4 = R7 << 3;
+ R7 = [P1];
+ R7 = R7 | R4;
+ SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
+ .align 8;
+ [P1] = R7;
+ SSYNC;
+
+ R7 = R5;
+ CC = BITTST(R7,2);
+ IF CC JUMP .LCLEAR3;
+ R7 = 0;
+ BITSET(R7,2);
+ JUMP .LDONE3;
+.LCLEAR3:
+ R7 = 0;
+ BITCLR(R7,2);
+.LDONE3: R4 = R7 << 3;
+ R7 = [P1];
+ R7 = R7 | R4;
+ SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
+ .align 8;
+ [P1] = R7;
+ SSYNC;
+
+
+ R7 = R5;
+ CC = BITTST(R7,3);
+ IF CC JUMP .LCLEAR4;
+ R7 = 0;
+ BITSET(R7,3);
+ JUMP .LDONE4;
+.LCLEAR4:
+ R7 = 0;
+ BITCLR(R7,3);
+.LDONE4: R4 = R7 << 3;
+ R7 = [P1];
+ R7 = R7 | R4;
+ SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
+ .align 8;
+ [P1] = R7;
+ SSYNC;
+
+ STI R3;
+
+ ( R7:0,P5:0 ) = [SP++];
+
+ RTS;
+
+/* After the execution of critical code, the code is now locked into
+ * the cache way. Now we need to set ILOC.
+ *
+ * R0 - Which way to be locked
+ */
+
+ENTRY(_cache_lock)
+
+ [--SP]=( R7:0,P5:0 );
+
+ P1.H = (IMEM_CONTROL >> 16);
+ P1.L = (IMEM_CONTROL & 0xFFFF);
+
+ /* Disable the Interrupts*/
+ CLI R3;
+
+ R7 = [P1];
+ R2 = 0xFFFFFF87 (X);
+ R7 = R7 & R2;
+ R0 = R0 << 3;
+ R7 = R0 | R7;
+ SSYNC; /* SSYNC required writing to IMEM_CONTROL. */
+ .align 8;
+ [P1] = R7;
+ SSYNC;
+ /* Renable the Interrupts */
+ STI R3;
+
+ ( R7:0,P5:0 ) = [SP++];
+ RTS;
+
+#endif /* BLKFIN_CACHE_LOCK */
+
+/* Return the ILOC bits of IMEM_CONTROL
+ */
+
+ENTRY(_read_iloc)
+
+ P1.H = (IMEM_CONTROL >> 16);
+ P1.L = (IMEM_CONTROL & 0xFFFF);
+ R1 = 0xF;
+ R0 = [P1];
+ R0 = R0 >> 3;
+ R0 = R0 & R1;
+
+ RTS;
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
new file mode 100644
index 0000000..deb2727
--- /dev/null
+++ b/arch/blackfin/mach-common/pm.c
@@ -0,0 +1,181 @@
+/*
+ * File: arch/blackfin/mach-common/pm.c
+ * Based on: arm/mach-omap/pm.c
+ * Author: Cliff Brake <cbrake@accelent.com> Copyright (c) 2001
+ *
+ * Created: 2001
+ * Description: Power management for the bfin
+ *
+ * Modified: Nicolas Pitre - PXA250 support
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ * David Singleton - OMAP1510
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ * Dirk Behme <dirk.behme@de.bosch.com> - OMAP1510/1610
+ * Copyright 2004
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/pm.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+
+#include <asm/io.h>
+#include <asm/dpmc.h>
+#include <asm/irq.h>
+
+
+#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H
+#define WAKEUP_TYPE PM_WAKE_HIGH
+#endif
+
+#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_L
+#define WAKEUP_TYPE PM_WAKE_LOW
+#endif
+
+#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_F
+#define WAKEUP_TYPE PM_WAKE_FALLING
+#endif
+
+#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_R
+#define WAKEUP_TYPE PM_WAKE_RISING
+#endif
+
+#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_B
+#define WAKEUP_TYPE PM_WAKE_BOTH_EDGES
+#endif
+
+void bfin_pm_suspend_standby_enter(void)
+{
+#ifdef CONFIG_PM_WAKEUP_BY_GPIO
+ gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE);
+#endif
+
+#if defined(CONFIG_PM_WAKEUP_BY_GPIO) || defined(CONFIG_PM_WAKEUP_GPIO_API)
+ {
+ u32 flags;
+
+ local_irq_save(flags);
+
+ sleep_deeper(gpio_pm_setup()); /*Goto Sleep*/
+
+ gpio_pm_restore();
+
+ bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+
+ local_irq_restore(flags);
+ }
+#endif
+
+#if defined(CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR)
+ sleep_deeper(CONFIG_PM_WAKEUP_SIC_IWR);
+ bfin_write_SIC_IWR(IWR_ENABLE_ALL);
+#endif /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */
+}
+
+
+/*
+ * bfin_pm_prepare - Do preliminary suspend work.
+ * @state: suspend state we're entering.
+ *
+ */
+static int bfin_pm_prepare(suspend_state_t state)
+{
+ int error = 0;
+
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ break;
+ case PM_SUSPEND_MEM:
+ return -ENOTSUPP;
+
+ case PM_SUSPEND_DISK:
+ return -ENOTSUPP;
+
+ default:
+ return -EINVAL;
+ }
+
+ return error;
+}
+
+/*
+ * bfin_pm_enter - Actually enter a sleep state.
+ * @state: State we're entering.
+ *
+ */
+static int bfin_pm_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ bfin_pm_suspend_standby_enter();
+ break;
+ case PM_SUSPEND_MEM:
+ return -ENOTSUPP;
+
+ case PM_SUSPEND_DISK:
+ return -ENOTSUPP;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * bfin_pm_finish - Finish up suspend sequence.
+ * @state: State we're coming out of.
+ *
+ * This is called after we wake back up (or if entering the sleep state
+ * failed).
+ */
+static int bfin_pm_finish(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ break;
+
+ case PM_SUSPEND_MEM:
+ return -ENOTSUPP;
+
+ case PM_SUSPEND_DISK:
+ return -ENOTSUPP;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+struct pm_ops bfin_pm_ops = {
+ .pm_disk_mode = PM_DISK_PLATFORM,
+ .prepare = bfin_pm_prepare,
+ .enter = bfin_pm_enter,
+ .finish = bfin_pm_finish,
+};
+
+static int __init bfin_pm_init(void)
+{
+ pm_set_ops(&bfin_pm_ops);
+ return 0;
+}
+
+__initcall(bfin_pm_init);
diff --git a/arch/blackfin/mm/Makefile b/arch/blackfin/mm/Makefile
new file mode 100644
index 0000000..2a7202c
--- /dev/null
+++ b/arch/blackfin/mm/Makefile
@@ -0,0 +1,5 @@
+#
+# arch/blackfin/mm/Makefile
+#
+
+obj-y := blackfin_sram.o init.o
diff --git a/arch/blackfin/mm/blackfin_sram.c b/arch/blackfin/mm/blackfin_sram.c
new file mode 100644
index 0000000..dd0c650
--- /dev/null
+++ b/arch/blackfin/mm/blackfin_sram.c
@@ -0,0 +1,540 @@
+/*
+ * File: arch/blackfin/mm/blackfin_sram.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: SRAM driver for Blackfin ADSP-BF5xx
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/autoconf.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/rtc.h>
+#include <asm/blackfin.h>
+#include "blackfin_sram.h"
+
+spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock;
+
+#if CONFIG_L1_MAX_PIECE < 16
+#undef CONFIG_L1_MAX_PIECE
+#define CONFIG_L1_MAX_PIECE 16
+#endif
+
+#if CONFIG_L1_MAX_PIECE > 1024
+#undef CONFIG_L1_MAX_PIECE
+#define CONFIG_L1_MAX_PIECE 1024
+#endif
+
+#define SRAM_SLT_NULL 0
+#define SRAM_SLT_FREE 1
+#define SRAM_SLT_ALLOCATED 2
+
+/* the data structure for L1 scratchpad and DATA SRAM */
+struct l1_sram_piece {
+ void *paddr;
+ int size;
+ int flag;
+};
+
+static struct l1_sram_piece l1_ssram[CONFIG_L1_MAX_PIECE];
+
+#if L1_DATA_A_LENGTH != 0
+static struct l1_sram_piece l1_data_A_sram[CONFIG_L1_MAX_PIECE];
+#endif
+
+#if L1_DATA_B_LENGTH != 0
+static struct l1_sram_piece l1_data_B_sram[CONFIG_L1_MAX_PIECE];
+#endif
+
+#if L1_CODE_LENGTH != 0
+static struct l1_sram_piece l1_inst_sram[CONFIG_L1_MAX_PIECE];
+#endif
+
+/* L1 Scratchpad SRAM initialization function */
+void l1sram_init(void)
+{
+ printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n",
+ L1_SCRATCH_LENGTH >> 10);
+
+ memset(&l1_ssram, 0x00, sizeof(l1_ssram));
+ l1_ssram[0].paddr = (void*)L1_SCRATCH_START;
+ l1_ssram[0].size = L1_SCRATCH_LENGTH;
+ l1_ssram[0].flag = SRAM_SLT_FREE;
+
+ /* mutex initialize */
+ spin_lock_init(&l1sram_lock);
+}
+
+void l1_data_sram_init(void)
+{
+#if L1_DATA_A_LENGTH != 0
+ printk(KERN_INFO "Blackfin DATA_A SRAM: %d KB\n",
+ L1_DATA_A_LENGTH >> 10);
+
+ memset(&l1_data_A_sram, 0x00, sizeof(l1_data_A_sram));
+ l1_data_A_sram[0].paddr = (void*)L1_DATA_A_START +
+ (_ebss_l1 - _sdata_l1);
+ l1_data_A_sram[0].size = L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1);
+ l1_data_A_sram[0].flag = SRAM_SLT_FREE;
+#endif
+#if L1_DATA_B_LENGTH != 0
+ printk(KERN_INFO "Blackfin DATA_B SRAM: %d KB\n",
+ L1_DATA_B_LENGTH >> 10);
+
+ memset(&l1_data_B_sram, 0x00, sizeof(l1_data_B_sram));
+ l1_data_B_sram[0].paddr = (void*)L1_DATA_B_START;
+ l1_data_B_sram[0].size = L1_DATA_B_LENGTH;
+ l1_data_B_sram[0].flag = SRAM_SLT_FREE;
+#endif
+
+ /* mutex initialize */
+ spin_lock_init(&l1_data_sram_lock);
+}
+
+void l1_inst_sram_init(void)
+{
+#if L1_CODE_LENGTH != 0
+ printk(KERN_INFO "Blackfin Instruction SRAM: %d KB\n",
+ L1_CODE_LENGTH >> 10);
+
+ memset(&l1_inst_sram, 0x00, sizeof(l1_inst_sram));
+ l1_inst_sram[0].paddr = (void*)L1_CODE_START + (_etext_l1 - _stext_l1);
+ l1_inst_sram[0].size = L1_CODE_LENGTH - (_etext_l1 - _stext_l1);
+ l1_inst_sram[0].flag = SRAM_SLT_FREE;
+#endif
+
+ /* mutex initialize */
+ spin_lock_init(&l1_inst_sram_lock);
+}
+
+/* L1 memory allocate function */
+static void *_l1_sram_alloc(size_t size, struct l1_sram_piece *pfree, int count)
+{
+ int i, index = 0;
+ void *addr = NULL;
+
+ if (size <= 0)
+ return NULL;
+
+ /* Align the size */
+ size = (size + 3) & ~3;
+
+ /* not use the good method to match the best slot !!! */
+ /* search an available memeory slot */
+ for (i = 0; i < count; i++) {
+ if ((pfree[i].flag == SRAM_SLT_FREE)
+ && (pfree[i].size >= size)) {
+ addr = pfree[i].paddr;
+ pfree[i].flag = SRAM_SLT_ALLOCATED;
+ index = i;
+ break;
+ }
+ }
+ if (i >= count)
+ return NULL;
+
+ /* updated the NULL memeory slot !!! */
+ if (pfree[i].size > size) {
+ for (i = 0; i < count; i++) {
+ if (pfree[i].flag == SRAM_SLT_NULL) {
+ pfree[i].flag = SRAM_SLT_FREE;
+ pfree[i].paddr = addr + size;
+ pfree[i].size = pfree[index].size - size;
+ pfree[index].size = size;
+ break;
+ }
+ }
+ }
+
+ return addr;
+}
+
+/* Allocate the largest available block. */
+static void *_l1_sram_alloc_max(struct l1_sram_piece *pfree, int count,
+ unsigned long *psize)
+{
+ unsigned long best = 0;
+ int i, index = -1;
+ void *addr = NULL;
+
+ /* search an available memeory slot */
+ for (i = 0; i < count; i++) {
+ if (pfree[i].flag == SRAM_SLT_FREE && pfree[i].size > best) {
+ addr = pfree[i].paddr;
+ index = i;
+ best = pfree[i].size;
+ }
+ }
+ if (index < 0)
+ return NULL;
+ *psize = best;
+
+ pfree[index].flag = SRAM_SLT_ALLOCATED;
+ return addr;
+}
+
+/* L1 memory free function */
+static int _l1_sram_free(const void *addr,
+ struct l1_sram_piece *pfree, int count)
+{
+ int i, index = 0;
+
+ /* search the relevant memory slot */
+ for (i = 0; i < count; i++) {
+ if (pfree[i].paddr == addr) {
+ if (pfree[i].flag != SRAM_SLT_ALLOCATED) {
+ /* error log */
+ return -1;
+ }
+ index = i;
+ break;
+ }
+ }
+ if (i >= count)
+ return -1;
+
+ pfree[index].flag = SRAM_SLT_FREE;
+
+ /* link the next address slot */
+ for (i = 0; i < count; i++) {
+ if (((pfree[index].paddr + pfree[index].size) == pfree[i].paddr)
+ && (pfree[i].flag == SRAM_SLT_FREE)) {
+ pfree[i].flag = SRAM_SLT_NULL;
+ pfree[index].size += pfree[i].size;
+ pfree[index].flag = SRAM_SLT_FREE;
+ break;
+ }
+ }
+
+ /* link the last address slot */
+ for (i = 0; i < count; i++) {
+ if (((pfree[i].paddr + pfree[i].size) == pfree[index].paddr) &&
+ (pfree[i].flag == SRAM_SLT_FREE)) {
+ pfree[index].flag = SRAM_SLT_NULL;
+ pfree[i].size += pfree[index].size;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int sram_free(const void *addr)
+{
+ if (0) {}
+#if L1_CODE_LENGTH != 0
+ else if (addr >= (void *)L1_CODE_START
+ && addr < (void *)(L1_CODE_START + L1_CODE_LENGTH))
+ return l1_inst_sram_free(addr);
+#endif
+#if L1_DATA_A_LENGTH != 0
+ else if (addr >= (void *)L1_DATA_A_START
+ && addr < (void *)(L1_DATA_A_START + L1_DATA_A_LENGTH))
+ return l1_data_A_sram_free(addr);
+#endif
+#if L1_DATA_B_LENGTH != 0
+ else if (addr >= (void *)L1_DATA_B_START
+ && addr < (void *)(L1_DATA_B_START + L1_DATA_B_LENGTH))
+ return l1_data_B_sram_free(addr);
+#endif
+ else
+ return -1;
+}
+EXPORT_SYMBOL(sram_free);
+
+void *l1_data_A_sram_alloc(size_t size)
+{
+ unsigned flags;
+ void *addr = NULL;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1_data_sram_lock, flags);
+
+#if L1_DATA_A_LENGTH != 0
+ addr = _l1_sram_alloc(size, l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram));
+#endif
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1_data_sram_lock, flags);
+
+ pr_debug("Allocated address in l1_data_A_sram_alloc is 0x%lx+0x%lx\n",
+ (long unsigned int)addr, size);
+
+ return addr;
+}
+EXPORT_SYMBOL(l1_data_A_sram_alloc);
+
+int l1_data_A_sram_free(const void *addr)
+{
+ unsigned flags;
+ int ret;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1_data_sram_lock, flags);
+
+#if L1_DATA_A_LENGTH != 0
+ ret = _l1_sram_free(addr,
+ l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram));
+#else
+ ret = -1;
+#endif
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1_data_sram_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(l1_data_A_sram_free);
+
+void *l1_data_B_sram_alloc(size_t size)
+{
+#if L1_DATA_B_LENGTH != 0
+ unsigned flags;
+ void *addr;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1_data_sram_lock, flags);
+
+ addr = _l1_sram_alloc(size, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram));
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1_data_sram_lock, flags);
+
+ pr_debug("Allocated address in l1_data_B_sram_alloc is 0x%lx+0x%lx\n",
+ (long unsigned int)addr, size);
+
+ return addr;
+#else
+ return NULL;
+#endif
+}
+EXPORT_SYMBOL(l1_data_B_sram_alloc);
+
+int l1_data_B_sram_free(const void *addr)
+{
+#if L1_DATA_B_LENGTH != 0
+ unsigned flags;
+ int ret;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1_data_sram_lock, flags);
+
+ ret = _l1_sram_free(addr, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram));
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1_data_sram_lock, flags);
+
+ return ret;
+#else
+ return -1;
+#endif
+}
+EXPORT_SYMBOL(l1_data_B_sram_free);
+
+void *l1_data_sram_alloc(size_t size)
+{
+ void *addr = l1_data_A_sram_alloc(size);
+
+ if (!addr)
+ addr = l1_data_B_sram_alloc(size);
+
+ return addr;
+}
+EXPORT_SYMBOL(l1_data_sram_alloc);
+
+void *l1_data_sram_zalloc(size_t size)
+{
+ void *addr = l1_data_sram_alloc(size);
+
+ if (addr)
+ memset(addr, 0x00, size);
+
+ return addr;
+}
+EXPORT_SYMBOL(l1_data_sram_zalloc);
+
+int l1_data_sram_free(const void *addr)
+{
+ int ret;
+ ret = l1_data_A_sram_free(addr);
+ if (ret == -1)
+ ret = l1_data_B_sram_free(addr);
+ return ret;
+}
+EXPORT_SYMBOL(l1_data_sram_free);
+
+void *l1_inst_sram_alloc(size_t size)
+{
+#if L1_DATA_A_LENGTH != 0
+ unsigned flags;
+ void *addr;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1_inst_sram_lock, flags);
+
+ addr = _l1_sram_alloc(size, l1_inst_sram, ARRAY_SIZE(l1_inst_sram));
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1_inst_sram_lock, flags);
+
+ pr_debug("Allocated address in l1_inst_sram_alloc is 0x%lx+0x%lx\n",
+ (long unsigned int)addr, size);
+
+ return addr;
+#else
+ return NULL;
+#endif
+}
+EXPORT_SYMBOL(l1_inst_sram_alloc);
+
+int l1_inst_sram_free(const void *addr)
+{
+#if L1_CODE_LENGTH != 0
+ unsigned flags;
+ int ret;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1_inst_sram_lock, flags);
+
+ ret = _l1_sram_free(addr, l1_inst_sram, ARRAY_SIZE(l1_inst_sram));
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1_inst_sram_lock, flags);
+
+ return ret;
+#else
+ return -1;
+#endif
+}
+EXPORT_SYMBOL(l1_inst_sram_free);
+
+/* L1 Scratchpad memory allocate function */
+void *l1sram_alloc(size_t size)
+{
+ unsigned flags;
+ void *addr;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1sram_lock, flags);
+
+ addr = _l1_sram_alloc(size, l1_ssram, ARRAY_SIZE(l1_ssram));
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1sram_lock, flags);
+
+ return addr;
+}
+
+/* L1 Scratchpad memory allocate function */
+void *l1sram_alloc_max(size_t *psize)
+{
+ unsigned flags;
+ void *addr;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1sram_lock, flags);
+
+ addr = _l1_sram_alloc_max(l1_ssram, ARRAY_SIZE(l1_ssram), psize);
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1sram_lock, flags);
+
+ return addr;
+}
+
+/* L1 Scratchpad memory free function */
+int l1sram_free(const void *addr)
+{
+ unsigned flags;
+ int ret;
+
+ /* add mutex operation */
+ spin_lock_irqsave(&l1sram_lock, flags);
+
+ ret = _l1_sram_free(addr, l1_ssram, ARRAY_SIZE(l1_ssram));
+
+ /* add mutex operation */
+ spin_unlock_irqrestore(&l1sram_lock, flags);
+
+ return ret;
+}
+
+int sram_free_with_lsl(const void *addr)
+{
+ struct sram_list_struct *lsl, **tmp;
+ struct mm_struct *mm = current->mm;
+
+ for (tmp = &mm->context.sram_list; *tmp; tmp = &(*tmp)->next)
+ if ((*tmp)->addr == addr)
+ goto found;
+ return -1;
+found:
+ lsl = *tmp;
+ sram_free(addr);
+ *tmp = lsl->next;
+ kfree(lsl);
+
+ return 0;
+}
+EXPORT_SYMBOL(sram_free_with_lsl);
+
+void *sram_alloc_with_lsl(size_t size, unsigned long flags)
+{
+ void *addr = NULL;
+ struct sram_list_struct *lsl = NULL;
+ struct mm_struct *mm = current->mm;
+
+ lsl = kmalloc(sizeof(struct sram_list_struct), GFP_KERNEL);
+ if (!lsl)
+ return NULL;
+ memset(lsl, 0, sizeof(*lsl));
+
+ if (flags & L1_INST_SRAM)
+ addr = l1_inst_sram_alloc(size);
+
+ if (addr == NULL && (flags & L1_DATA_A_SRAM))
+ addr = l1_data_A_sram_alloc(size);
+
+ if (addr == NULL && (flags & L1_DATA_B_SRAM))
+ addr = l1_data_B_sram_alloc(size);
+
+ if (addr == NULL) {
+ kfree(lsl);
+ return NULL;
+ }
+ lsl->addr = addr;
+ lsl->length = size;
+ lsl->next = mm->context.sram_list;
+ mm->context.sram_list = lsl;
+ return addr;
+}
+EXPORT_SYMBOL(sram_alloc_with_lsl);
diff --git a/arch/blackfin/mm/blackfin_sram.h b/arch/blackfin/mm/blackfin_sram.h
new file mode 100644
index 0000000..0fb73b7
--- /dev/null
+++ b/arch/blackfin/mm/blackfin_sram.h
@@ -0,0 +1,38 @@
+/*
+ * File: arch/blackfin/mm/blackfin_sram.h
+ * Based on: arch/blackfin/mm/blackfin_sram.c
+ * Author: Mike Frysinger
+ *
+ * Created: Aug 2006
+ * Description: Local prototypes meant for internal use only
+ *
+ * Modified:
+ * Copyright 2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __BLACKFIN_SRAM_H__
+#define __BLACKFIN_SRAM_H__
+
+extern void l1sram_init(void);
+extern void l1_inst_sram_init(void);
+extern void l1_data_sram_init(void);
+extern void *l1sram_alloc(size_t);
+
+#endif
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c
new file mode 100644
index 0000000..73f72ab
--- /dev/null
+++ b/arch/blackfin/mm/init.c
@@ -0,0 +1,208 @@
+/*
+ * File: arch/blackfin/mm/init.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <asm/bfin-global.h>
+#include <asm/uaccess.h>
+#include <asm/l1layout.h>
+#include "blackfin_sram.h"
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+static unsigned long empty_bad_page_table;
+
+static unsigned long empty_bad_page;
+
+unsigned long empty_zero_page;
+
+void show_mem(void)
+{
+ unsigned long i;
+ int free = 0, total = 0, reserved = 0, shared = 0;
+
+ int cached = 0;
+ printk(KERN_INFO "Mem-info:\n");
+ show_free_areas();
+ i = max_mapnr;
+ while (i-- > 0) {
+ total++;
+ if (PageReserved(mem_map + i))
+ reserved++;
+ else if (PageSwapCache(mem_map + i))
+ cached++;
+ else if (!page_count(mem_map + i))
+ free++;
+ else
+ shared += page_count(mem_map + i) - 1;
+ }
+ printk(KERN_INFO "%d pages of RAM\n", total);
+ printk(KERN_INFO "%d free pages\n", free);
+ printk(KERN_INFO "%d reserved pages\n", reserved);
+ printk(KERN_INFO "%d pages shared\n", shared);
+ printk(KERN_INFO "%d pages swap cached\n", cached);
+}
+
+/*
+ * paging_init() continues the virtual memory environment setup which
+ * was begun by the code in arch/head.S.
+ * The parameters are pointers to where to stick the starting and ending
+ * addresses of available kernel virtual memory.
+ */
+void paging_init(void)
+{
+ /*
+ * make sure start_mem is page aligned, otherwise bootmem and
+ * page_alloc get different views og the world
+ */
+ unsigned long end_mem = memory_end & PAGE_MASK;
+
+ pr_debug("start_mem is %#lx virtual_end is %#lx\n", PAGE_ALIGN(memory_start), end_mem);
+
+ /*
+ * initialize the bad page table and bad page to point
+ * to a couple of allocated pages
+ */
+ empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+ empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+ empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+ memset((void *)empty_zero_page, 0, PAGE_SIZE);
+
+ /*
+ * Set up SFC/DFC registers (user data space)
+ */
+ set_fs(KERNEL_DS);
+
+ pr_debug("free_area_init -> start_mem is %#lx virtual_end is %#lx\n",
+ PAGE_ALIGN(memory_start), end_mem);
+
+ {
+ unsigned long zones_size[MAX_NR_ZONES] = { 0, };
+
+ zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
+#ifdef CONFIG_HIGHMEM
+ zones_size[ZONE_HIGHMEM] = 0;
+#endif
+ free_area_init(zones_size);
+ }
+}
+
+void mem_init(void)
+{
+ unsigned int codek = 0, datak = 0, initk = 0;
+ unsigned long tmp;
+ unsigned int len = _ramend - _rambase;
+ unsigned long start_mem = memory_start;
+ unsigned long end_mem = memory_end;
+
+ end_mem &= PAGE_MASK;
+ high_memory = (void *)end_mem;
+
+ start_mem = PAGE_ALIGN(start_mem);
+ max_mapnr = num_physpages = MAP_NR(high_memory);
+ printk(KERN_INFO "Physical pages: %lx\n", num_physpages);
+
+ /* This will put all memory onto the freelists. */
+ totalram_pages = free_all_bootmem();
+
+ codek = (_etext - _stext) >> 10;
+ datak = (__bss_stop - __bss_start) >> 10;
+ initk = (__init_end - __init_begin) >> 10;
+
+ tmp = nr_free_pages() << PAGE_SHIFT;
+ printk(KERN_INFO
+ "Memory available: %luk/%uk RAM, (%uk init code, %uk kernel code, %uk data, %uk dma)\n",
+ tmp >> 10, len >> 10, initk, codek, datak, DMA_UNCACHED_REGION >> 10);
+
+ /* Initialize the blackfin L1 Memory. */
+ l1sram_init();
+ l1_data_sram_init();
+ l1_inst_sram_init();
+
+ /* Allocate this once; never free it. We assume this gives us a
+ pointer to the start of L1 scratchpad memory; panic if it
+ doesn't. */
+ tmp = (unsigned long)l1sram_alloc(sizeof(struct l1_scratch_task_info));
+ if (tmp != (unsigned long)L1_SCRATCH_TASK_INFO) {
+ printk(KERN_EMERG "mem_init(): Did not get the right address from l1sram_alloc: %08lx != %08lx\n",
+ tmp, (unsigned long)L1_SCRATCH_TASK_INFO);
+ panic("No L1, time to give up\n");
+ }
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ int pages = 0;
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(start));
+ init_page_count(virt_to_page(start));
+ free_page(start);
+ totalram_pages++;
+ pages++;
+ }
+ printk(KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages);
+}
+#endif
+
+void free_initmem(void)
+{
+#ifdef CONFIG_RAMKERNEL
+ unsigned long addr;
+/*
+ * the following code should be cool even if these sections
+ * are not page aligned.
+ */
+ addr = PAGE_ALIGN((unsigned long)(__init_begin));
+ /* next to check that the page we free is not a partial page */
+ for (; addr + PAGE_SIZE < (unsigned long)(__init_end);
+ addr += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(addr));
+ init_page_count(virt_to_page(addr));
+ free_page(addr);
+ totalram_pages++;
+ }
+ printk(KERN_NOTICE
+ "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n",
+ (addr - PAGE_ALIGN((long)__init_begin)) >> 10,
+ (int)(PAGE_ALIGN((unsigned long)(__init_begin))),
+ (int)(addr - PAGE_SIZE));
+#endif
+}
diff --git a/arch/blackfin/oprofile/Kconfig b/arch/blackfin/oprofile/Kconfig
new file mode 100644
index 0000000..0a2fd99
--- /dev/null
+++ b/arch/blackfin/oprofile/Kconfig
@@ -0,0 +1,29 @@
+menu "Profiling support"
+depends on EXPERIMENTAL
+
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+config HARDWARE_PM
+ tristate "Hardware Performance Monitor Profiling"
+ depends on PROFILING
+ help
+ take use of hardware performance monitor to profiling the kernel
+ and application.
+
+ If unsure, say N.
+
+endmenu
diff --git a/arch/blackfin/oprofile/Makefile b/arch/blackfin/oprofile/Makefile
new file mode 100644
index 0000000..634e300
--- /dev/null
+++ b/arch/blackfin/oprofile/Makefile
@@ -0,0 +1,14 @@
+#
+# arch/blackfin/oprofile/Makefile
+#
+
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
+ oprof.o cpu_buffer.o buffer_sync.o \
+ event_buffer.o oprofile_files.o \
+ oprofilefs.o oprofile_stats.o \
+ timer_int.o )
+
+oprofile-y := $(DRIVER_OBJS) common.o
+oprofile-$(CONFIG_HARDWARE_PM) += op_model_bf533.o
diff --git a/arch/blackfin/oprofile/common.c b/arch/blackfin/oprofile/common.c
new file mode 100644
index 0000000..009a170
--- /dev/null
+++ b/arch/blackfin/oprofile/common.c
@@ -0,0 +1,168 @@
+/*
+ * File: arch/blackfin/oprofile/common.c
+ * Based on: arch/alpha/oprofile/common.c
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/oprofile.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/blackfin.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include "op_blackfin.h"
+
+#define BFIN_533_ID 0xE5040003
+#define BFIN_537_ID 0xE5040002
+
+static int pfmon_enabled;
+static struct mutex pfmon_lock;
+
+struct op_bfin533_model *model;
+
+struct op_counter_config ctr[OP_MAX_COUNTER];
+
+static int op_bfin_setup(void)
+{
+ int ret;
+
+ /* Pre-compute the values to stuff in the hardware registers. */
+ spin_lock(&oprofilefs_lock);
+ ret = model->reg_setup(ctr);
+ spin_unlock(&oprofilefs_lock);
+
+ return ret;
+}
+
+static void op_bfin_shutdown(void)
+{
+#if 0
+ /* what is the difference between shutdown and stop? */
+#endif
+}
+
+static int op_bfin_start(void)
+{
+ int ret = -EBUSY;
+
+ printk(KERN_INFO "KSDBG:in %s\n", __FUNCTION__);
+ mutex_lock(&pfmon_lock);
+ if (!pfmon_enabled) {
+ ret = model->start(ctr);
+ pfmon_enabled = !ret;
+ }
+ mutex_unlock(&pfmon_lock);
+
+ return ret;
+}
+
+static void op_bfin_stop(void)
+{
+ mutex_lock(&pfmon_lock);
+ if (pfmon_enabled) {
+ model->stop();
+ pfmon_enabled = 0;
+ }
+ mutex_unlock(&pfmon_lock);
+}
+
+static int op_bfin_create_files(struct super_block *sb, struct dentry *root)
+{
+ int i;
+
+ for (i = 0; i < model->num_counters; ++i) {
+ struct dentry *dir;
+ char buf[3];
+ printk(KERN_INFO "Oprofile: creating files... \n");
+
+ snprintf(buf, sizeof buf, "%d", i);
+ dir = oprofilefs_mkdir(sb, root, buf);
+
+ oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
+ oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
+ oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
+ /*
+ * We dont support per counter user/kernel selection, but
+ * we leave the entries because userspace expects them
+ */
+ oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
+ oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
+ oprofilefs_create_ulong(sb, dir, "unit_mask",
+ &ctr[i].unit_mask);
+ }
+
+ return 0;
+}
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+#ifdef CONFIG_HARDWARE_PM
+ unsigned int dspid;
+
+ mutex_init(&pfmon_lock);
+
+ dspid = bfin_read_DSPID();
+
+ printk(KERN_INFO "Oprofile got the cpu id is 0x%x. \n", dspid);
+
+ switch (dspid) {
+ case BFIN_533_ID:
+ model = &op_model_bfin533;
+ model->num_counters = 2;
+ break;
+ case BFIN_537_ID:
+ model = &op_model_bfin533;
+ model->num_counters = 2;
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ ops->cpu_type = model->name;
+ ops->create_files = op_bfin_create_files;
+ ops->setup = op_bfin_setup;
+ ops->shutdown = op_bfin_shutdown;
+ ops->start = op_bfin_start;
+ ops->stop = op_bfin_stop;
+
+ printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
+ ops->cpu_type);
+
+ return 0;
+#else
+ return -1;
+#endif
+}
+
+void oprofile_arch_exit(void)
+{
+}
diff --git a/arch/blackfin/oprofile/op_blackfin.h b/arch/blackfin/oprofile/op_blackfin.h
new file mode 100644
index 0000000..f88f446
--- /dev/null
+++ b/arch/blackfin/oprofile/op_blackfin.h
@@ -0,0 +1,98 @@
+/*
+ * File: arch/blackfin/oprofile/op_blackfin.h
+ * Based on:
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef OP_BLACKFIN_H
+#define OP_BLACKFIN_H 1
+
+#define OP_MAX_COUNTER 2
+
+#include <asm/blackfin.h>
+
+/* Per-counter configuration as set via oprofilefs. */
+struct op_counter_config {
+ unsigned long valid;
+ unsigned long enabled;
+ unsigned long event;
+ unsigned long count;
+ unsigned long kernel;
+ unsigned long user;
+ unsigned long unit_mask;
+};
+
+/* System-wide configuration as set via oprofilefs. */
+struct op_system_config {
+ unsigned long enable_kernel;
+ unsigned long enable_user;
+};
+
+/* Per-arch configuration */
+struct op_bfin533_model {
+ int (*reg_setup) (struct op_counter_config *);
+ int (*start) (struct op_counter_config *);
+ void (*stop) (void);
+ int num_counters;
+ char *name;
+};
+
+extern struct op_bfin533_model op_model_bfin533;
+
+static inline unsigned int ctr_read(void)
+{
+ unsigned int tmp;
+
+ tmp = bfin_read_PFCTL();
+ __builtin_bfin_csync();
+
+ return tmp;
+}
+
+static inline void ctr_write(unsigned int val)
+{
+ bfin_write_PFCTL(val);
+ __builtin_bfin_csync();
+}
+
+static inline void count_read(unsigned int *count)
+{
+ count[0] = bfin_read_PFCNTR0();
+ count[1] = bfin_read_PFCNTR1();
+ __builtin_bfin_csync();
+}
+
+static inline void count_write(unsigned int *count)
+{
+ bfin_write_PFCNTR0(count[0]);
+ bfin_write_PFCNTR1(count[1]);
+ __builtin_bfin_csync();
+}
+
+extern int pm_overflow_handler(int irq, struct pt_regs *regs);
+
+#endif
diff --git a/arch/blackfin/oprofile/op_model_bf533.c b/arch/blackfin/oprofile/op_model_bf533.c
new file mode 100644
index 0000000..b7a20a0
--- /dev/null
+++ b/arch/blackfin/oprofile/op_model_bf533.c
@@ -0,0 +1,161 @@
+/*
+ * File: arch/blackfin/oprofile/op_model_bf533.c
+ * Based on:
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/oprofile.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/blackfin.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include "op_blackfin.h"
+
+#define PM_ENABLE 0x01;
+#define PM_CTL1_ENABLE 0x18
+#define PM_CTL0_ENABLE 0xC000
+#define COUNT_EDGE_ONLY 0x3000000
+
+static int oprofile_running;
+
+static unsigned curr_pfctl, curr_count[2];
+
+static int bfin533_reg_setup(struct op_counter_config *ctr)
+{
+ unsigned int pfctl = ctr_read();
+ unsigned int count[2];
+
+ /* set Blackfin perf monitor regs with ctr */
+ if (ctr[0].enabled) {
+ pfctl |= (PM_CTL0_ENABLE | ((char)ctr[0].event << 5));
+ count[0] = 0xFFFFFFFF - ctr[0].count;
+ curr_count[0] = count[0];
+ }
+ if (ctr[1].enabled) {
+ pfctl |= (PM_CTL1_ENABLE | ((char)ctr[1].event << 16));
+ count[1] = 0xFFFFFFFF - ctr[1].count;
+ curr_count[1] = count[1];
+ }
+
+ pr_debug("ctr[0].enabled=%d,ctr[1].enabled=%d,ctr[0].event<<5=0x%x,ctr[1].event<<16=0x%x\n", ctr[0].enabled, ctr[1].enabled, ctr[0].event << 5, ctr[1].event << 16);
+ pfctl |= COUNT_EDGE_ONLY;
+ curr_pfctl = pfctl;
+
+ pr_debug("write 0x%x to pfctl\n", pfctl);
+ ctr_write(pfctl);
+ count_write(count);
+
+ return 0;
+}
+
+static int bfin533_start(struct op_counter_config *ctr)
+{
+ unsigned int pfctl = ctr_read();
+
+ pfctl |= PM_ENABLE;
+ curr_pfctl = pfctl;
+
+ ctr_write(pfctl);
+
+ oprofile_running = 1;
+ pr_debug("start oprofile counter \n");
+
+ return 0;
+}
+
+static void bfin533_stop(void)
+{
+ int pfctl;
+
+ pfctl = ctr_read();
+ pfctl &= ~PM_ENABLE;
+ /* freeze counters */
+ ctr_write(pfctl);
+
+ oprofile_running = 0;
+ pr_debug("stop oprofile counter \n");
+}
+
+static int get_kernel(void)
+{
+ int ipend, is_kernel;
+
+ ipend = bfin_read_IPEND();
+
+ /* test bit 15 */
+ is_kernel = ((ipend & 0x8000) != 0);
+
+ return is_kernel;
+}
+
+int pm_overflow_handler(int irq, struct pt_regs *regs)
+{
+ int is_kernel;
+ int i, cpu;
+ unsigned int pc, pfctl;
+ unsigned int count[2];
+
+ pr_debug("get interrupt in %s\n", __FUNCTION__);
+ if (oprofile_running == 0) {
+ pr_debug("error: entering interrupt when oprofile is stopped.\n\r");
+ return -1;
+ }
+
+ is_kernel = get_kernel();
+ cpu = smp_processor_id();
+ pc = regs->pc;
+ pfctl = ctr_read();
+
+ /* read the two event counter regs */
+ count_read(count);
+
+ /* if the counter overflows, add sample to oprofile buffer */
+ for (i = 0; i < 2; ++i) {
+ if (oprofile_running) {
+ oprofile_add_sample(regs, i);
+ }
+ }
+
+ /* reset the perfmon counter */
+ ctr_write(curr_pfctl);
+ count_write(curr_count);
+ return 0;
+}
+
+struct op_bfin533_model op_model_bfin533 = {
+ .reg_setup = bfin533_reg_setup,
+ .start = bfin533_start,
+ .stop = bfin533_stop,
+ .num_counters = 2,
+ .name = "blackfin/bf533"
+};
diff --git a/arch/blackfin/oprofile/timer_int.c b/arch/blackfin/oprofile/timer_int.c
new file mode 100644
index 0000000..8fba16c
--- /dev/null
+++ b/arch/blackfin/oprofile/timer_int.c
@@ -0,0 +1,74 @@
+/*
+ * File: arch/blackfin/oprofile/timer_int.c
+ * Based on:
+ * Author: Michael Kang
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+#include <linux/oprofile.h>
+
+#include <asm/ptrace.h>
+
+static void enable_sys_timer0()
+{
+}
+static void disable_sys_timer0()
+{
+}
+
+static irqreturn_t sys_timer0_int_handler(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ oprofile_add_sample(regs, 0);
+ return IRQ_HANDLED;
+}
+
+static int sys_timer0_start(void)
+{
+ enable_sys_timer0();
+ return request_irq(IVG11, sys_timer0_int_handler, 0, "sys_timer0", NULL);
+}
+
+static void sys_timer0_stop(void)
+{
+ disable_sys_timer();
+}
+
+int __init sys_timer0_init(struct oprofile_operations *ops)
+{
+ extern int nmi_active;
+
+ if (nmi_active <= 0)
+ return -ENODEV;
+
+ ops->start = timer_start;
+ ops->stop = timer_stop;
+ ops->cpu_type = "timer";
+ printk(KERN_INFO "oprofile: using NMI timer interrupt.\n");
+ return 0;
+}
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index 961c0d5..fd2129a 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -6,7 +6,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c
index 19bcad0..41d4a5f 100644
--- a/arch/cris/arch-v10/kernel/signal.c
+++ b/arch/cris/arch-v10/kernel/signal.c
@@ -16,7 +16,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/cris/arch-v32/drivers/pci/dma.c b/arch/cris/arch-v32/drivers/pci/dma.c
index 70d3bf0..832fc63 100644
--- a/arch/cris/arch-v32/drivers/pci/dma.c
+++ b/arch/cris/arch-v32/drivers/pci/dma.c
@@ -76,7 +76,7 @@ int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
{
void __iomem *mem_base;
int pages = size >> PAGE_SHIFT;
- int bitmap_size = (pages + 31)/32;
+ int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
goto out;
diff --git a/arch/cris/arch-v32/kernel/fasttimer.c b/arch/cris/arch-v32/kernel/fasttimer.c
index 5daeb6f..79e1e4c 100644
--- a/arch/cris/arch-v32/kernel/fasttimer.c
+++ b/arch/cris/arch-v32/kernel/fasttimer.c
@@ -603,23 +603,8 @@ void schedule_usleep(unsigned long us)
#ifdef CONFIG_PROC_FS
static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
- ,int *eof, void *data_unused
-#else
- ,int unused
-#endif
- );
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+ ,int *eof, void *data_unused);
static struct proc_dir_entry *fasttimer_proc_entry;
-#else
-static struct proc_dir_entry fasttimer_proc_entry =
-{
- 0, 9, "fasttimer",
- S_IFREG | S_IRUGO, 1, 0, 0,
- 0, NULL /* ops -- default to array */,
- &proc_fasttimer_read /* get_info */,
-};
-#endif
#endif /* CONFIG_PROC_FS */
#ifdef CONFIG_PROC_FS
@@ -628,12 +613,7 @@ static struct proc_dir_entry fasttimer_proc_entry =
#define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300)
static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
- ,int *eof, void *data_unused
-#else
- ,int unused
-#endif
- )
+ ,int *eof, void *data_unused)
{
unsigned long flags;
int i = 0;
@@ -808,9 +788,7 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
memcpy(buf, bigbuf + offset, len);
*start = buf;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
*eof = 1;
-#endif
return len;
}
@@ -974,12 +952,8 @@ void fast_timer_init(void)
printk("fast_timer_init()\n");
#ifdef CONFIG_PROC_FS
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 )))
fasttimer_proc_entry->read_proc = proc_fasttimer_read;
-#else
- proc_register_dynamic(&proc_root, &fasttimer_proc_entry);
-#endif
#endif /* PROC_FS */
if(request_irq(TIMER_INTR_VECT, timer_trig_interrupt, IRQF_DISABLED,
"fast timer int", NULL))
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index 82cf2e3..d4d57b7 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -6,7 +6,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/cris/kernel/crisksyms.c b/arch/cris/kernel/crisksyms.c
index 1f20c16..105bb5e 100644
--- a/arch/cris/kernel/crisksyms.c
+++ b/arch/cris/kernel/crisksyms.c
@@ -4,7 +4,6 @@
#include <linux/sched.h>
#include <linux/in6.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/pm.h>
#include <linux/kernel.h>
#include <linux/string.h>
diff --git a/arch/cris/kernel/profile.c b/arch/cris/kernel/profile.c
index 4cfcae6..aad0a9e 100644
--- a/arch/cris/kernel/profile.c
+++ b/arch/cris/kernel/profile.c
@@ -15,39 +15,47 @@ static int prof_running = 0;
void
cris_profile_sample(struct pt_regs* regs)
{
- if (!prof_running)
- return;
- if (user_mode(regs))
- *(unsigned int*)sample_buffer_pos = current->pid;
- else
- *(unsigned int*)sample_buffer_pos = 0;
- *(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs);
- sample_buffer_pos += 8;
- if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE)
- sample_buffer_pos = sample_buffer;
+ if (!prof_running)
+ return;
+
+ if (user_mode(regs))
+ *(unsigned int*)sample_buffer_pos = current->pid;
+ else
+ *(unsigned int*)sample_buffer_pos = 0;
+
+ *(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs);
+ sample_buffer_pos += 8;
+
+ if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE)
+ sample_buffer_pos = sample_buffer;
}
static ssize_t
-read_cris_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+read_cris_profile(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
{
- unsigned long p = *ppos;
- if (p > SAMPLE_BUFFER_SIZE)
- return 0;
- if (p + count > SAMPLE_BUFFER_SIZE)
- count = SAMPLE_BUFFER_SIZE - p;
- if (copy_to_user(buf, sample_buffer + p,count))
+ unsigned long p = *ppos;
+
+ if (p > SAMPLE_BUFFER_SIZE)
+ return 0;
+
+ if (p + count > SAMPLE_BUFFER_SIZE)
+ count = SAMPLE_BUFFER_SIZE - p;
+ if (copy_to_user(buf, sample_buffer + p,count))
return -EFAULT;
- memset(sample_buffer + p, 0, count);
- *ppos += count;
- return count;
+
+ memset(sample_buffer + p, 0, count);
+ *ppos += count;
+
+ return count;
}
static ssize_t
write_cris_profile(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
+ size_t count, loff_t *ppos)
{
- sample_buffer_pos = sample_buffer;
- memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE);
+ sample_buffer_pos = sample_buffer;
+ memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE);
}
static const struct file_operations cris_proc_profile_operations = {
@@ -58,16 +66,23 @@ static const struct file_operations cris_proc_profile_operations = {
static int
__init init_cris_profile(void)
{
- struct proc_dir_entry *entry;
- sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL);
- sample_buffer_pos = sample_buffer;
- entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL);
- if (entry) {
- entry->proc_fops = &cris_proc_profile_operations;
- entry->size = SAMPLE_BUFFER_SIZE;
- }
- prof_running = 1;
- return 0;
+ struct proc_dir_entry *entry;
+
+ sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL);
+ if (!sample_buffer) {
+ return -ENOMEM;
+ }
+
+ sample_buffer_pos = sample_buffer;
+
+ entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL);
+ if (entry) {
+ entry->proc_fops = &cris_proc_profile_operations;
+ entry->size = SAMPLE_BUFFER_SIZE;
+ }
+ prof_running = 1;
+
+ return 0;
}
__initcall(init_cris_profile);
diff --git a/arch/cris/kernel/ptrace.c b/arch/cris/kernel/ptrace.c
index 2b6363c..1085d03 100644
--- a/arch/cris/kernel/ptrace.c
+++ b/arch/cris/kernel/ptrace.c
@@ -67,7 +67,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index cea2374..eed6943 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -53,6 +53,10 @@ config ARCH_HAS_ILOG2_U64
bool
default y
+config ARCH_USES_SLAB_PAGE_STRUCT
+ bool
+ default y
+
mainmenu "Fujitsu FR-V Kernel Configuration"
source "init/Kconfig"
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 87f360a..c7e59dc 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -18,7 +18,6 @@
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/irq.h>
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c
index fcff819..ce88fb9 100644
--- a/arch/frv/kernel/ptrace.c
+++ b/arch/frv/kernel/ptrace.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/frv/kernel/semaphore.c b/arch/frv/kernel/semaphore.c
index f278cdf..8e182ce 100644
--- a/arch/frv/kernel/semaphore.c
+++ b/arch/frv/kernel/semaphore.c
@@ -19,7 +19,7 @@ struct sem_waiter {
struct task_struct *task;
};
-#if SEMAPHORE_DEBUG
+#ifdef CONFIG_DEBUG_SEMAPHORE
void semtrace(struct semaphore *sem, const char *str)
{
if (sem->debug)
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index 85baeae..d64bcaf 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -13,7 +13,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/frv/kernel/sys_frv.c b/arch/frv/kernel/sys_frv.c
index c4d4348..26b3df3 100644
--- a/arch/frv/kernel/sys_frv.c
+++ b/arch/frv/kernel/sys_frv.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/frv/mm/elf-fdpic.c b/arch/frv/mm/elf-fdpic.c
index 9477ccc..cac2c01 100644
--- a/arch/frv/mm/elf-fdpic.c
+++ b/arch/frv/mm/elf-fdpic.c
@@ -64,6 +64,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
if (len > TASK_SIZE)
return -ENOMEM;
+ /* handle MAP_FIXED */
+ if (flags & MAP_FIXED)
+ return addr;
+
/* only honour a hint if we're not going to clobber something doing so */
if (addr) {
addr = PAGE_ALIGN(addr);
diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c
index 19b13be..598a26a 100644
--- a/arch/frv/mm/pgalloc.c
+++ b/arch/frv/mm/pgalloc.c
@@ -151,9 +151,7 @@ void __init pgtable_cache_init(void)
pgd_cache = kmem_cache_create("pgd",
PTRS_PER_PGD * sizeof(pgd_t),
PTRS_PER_PGD * sizeof(pgd_t),
- 0,
+ SLAB_PANIC,
pgd_ctor,
pgd_dtor);
- if (!pgd_cache)
- panic("pgtable_cache_init(): Cannot create pgd cache");
}
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 1734d96..618dbad 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -49,10 +49,18 @@ config GENERIC_HWEIGHT
bool
default y
+config GENERIC_HARDIRQS
+ bool
+ default y
+
config GENERIC_CALIBRATE_DELAY
bool
default y
+config GENERIC_TIME
+ bool
+ default y
+
config TIME_LOW_RES
bool
default y
diff --git a/arch/h8300/Makefile b/arch/h8300/Makefile
index 40b3f56..b2d896a 100644
--- a/arch/h8300/Makefile
+++ b/arch/h8300/Makefile
@@ -41,7 +41,7 @@ LDFLAGS += $(ldflags-y)
CROSS_COMPILE = h8300-elf-
LIBGCC := $(shell $(CROSS-COMPILE)$(CC) $(CFLAGS) -print-libgcc-file-name)
-head-y := arch/$(ARCH)/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o
+head-y := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o
core-y += arch/$(ARCH)/kernel/ \
arch/$(ARCH)/mm/
diff --git a/arch/h8300/boot/Makefile b/arch/h8300/boot/Makefile
index 65086d9..0bb62e0 100644
--- a/arch/h8300/boot/Makefile
+++ b/arch/h8300/boot/Makefile
@@ -1,12 +1,22 @@
# arch/h8300/boot/Makefile
-targets := vmlinux.srec vmlinux.bin
+targets := vmlinux.srec vmlinux.bin zImage
+subdir- := compressed
OBJCOPYFLAGS_vmlinux.srec := -Osrec
OBJCOPYFLAGS_vmlinux.bin := -Obinary
+OBJCOPYFLAGS_zImage := -O binary -R .note -R .comment -R .stab -R .stabstr -S
$(obj)/vmlinux.srec $(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
+$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
+ $(call if_changed,objcopy)
+ @echo 'Kernel: $@ is ready'
+
+$(obj)/compressed/vmlinux: FORCE
+ $(Q)$(MAKE) $(build)=$(obj)/compressed $@
+
CLEAN_FILES += arch/$(ARCH)/vmlinux.bin arch/$(ARCH)/vmlinux.srec
+
diff --git a/arch/h8300/boot/compressed/Makefile b/arch/h8300/boot/compressed/Makefile
new file mode 100644
index 0000000..71aac82
--- /dev/null
+++ b/arch/h8300/boot/compressed/Makefile
@@ -0,0 +1,37 @@
+#
+# linux/arch/sh/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux
+#
+
+targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
+EXTRA_AFLAGS := -traditional
+
+OBJECTS = $(obj)/head.o $(obj)/misc.o
+
+#
+# IMAGE_OFFSET is the load offset of the compression loader
+# Assign dummy values if these 2 variables are not defined,
+# in order to suppress error message.
+#
+CONFIG_MEMORY_START ?= 0x00400000
+CONFIG_BOOT_LINK_OFFSET ?= 0x00400000
+IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET)])
+
+LDFLAGS_vmlinux := -T $(obj)/vmlinux.lds
+
+$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE
+ $(call if_changed,ld)
+ @:
+
+$(obj)/vmlinux.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
+
+$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,gzip)
+
+LDFLAGS_piggy.o := -r --format binary --oformat elf32-h8300 -T
+OBJCOPYFLAGS := -O binary
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+ $(call if_changed,ld)
diff --git a/arch/h8300/boot/compressed/head.S b/arch/h8300/boot/compressed/head.S
new file mode 100644
index 0000000..b8e90d1
--- /dev/null
+++ b/arch/h8300/boot/compressed/head.S
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/h8300/boot/compressed/head.S
+ *
+ * Copyright (C) 2006 Yoshinori Sato
+ */
+
+.h8300h
+#include <linux/linkage.h>
+
+#define SRAM_START 0xff4000
+
+ .section .text.startup
+ .global startup
+startup:
+ mov.l #SRAM_START+0x8000, sp
+ mov.l #__sbss, er0
+ mov.l #__ebss, er1
+ sub.l er0, er1
+ shlr er1
+ shlr er1
+ sub.l er2, er2
+1:
+ mov.l er2, @er0
+ adds #4, er0
+ dec.l #1, er1
+ bne 1b
+ jsr @_decompress_kernel
+ jmp @0x400000
+
+ .align 9
+fake_headers_as_bzImage:
+ .word 0
+ .ascii "HdrS" ; header signature
+ .word 0x0202 ; header version number (>= 0x0105)
+ ; or else old loadlin-1.5 will fail)
+ .word 0 ; default_switch
+ .word 0 ; SETUPSEG
+ .word 0x1000
+ .word 0 ; pointing to kernel version string
+ .byte 0 ; = 0, old one (LILO, Loadlin,
+ ; 0xTV: T=0 for LILO
+ ; V = version
+ .byte 1 ; Load flags bzImage=1
+ .word 0x8000 ; size to move, when setup is not
+ .long 0x100000 ; 0x100000 = default for big kernel
+ .long 0 ; address of loaded ramdisk image
+ .long 0 ; its size in bytes
diff --git a/arch/h8300/boot/compressed/misc.c b/arch/h8300/boot/compressed/misc.c
new file mode 100644
index 0000000..8450745
--- /dev/null
+++ b/arch/h8300/boot/compressed/misc.c
@@ -0,0 +1,219 @@
+/*
+ * arch/h8300/boot/compressed/misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for h8300 by Yoshinori Sato 2006
+ */
+
+#include <asm/uaccess.h>
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args) args
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#define memzero(s, n) memset ((s), 0, (n))
+
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+#define WSIZE 0x8000 /* Window size must be at least 32k, */
+ /* and a power of two */
+
+static uch *inbuf; /* input buffer */
+static uch window[WSIZE]; /* Sliding window buffer */
+
+static unsigned insize = 0; /* valid bytes in inbuf */
+static unsigned inptr = 0; /* index of next byte to be processed in inbuf */
+static unsigned outcnt = 0; /* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
+#define RESERVED 0xC0 /* bit 6,7: reserved */
+
+#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# define Assert(cond,msg) {if(!(cond)) error(msg);}
+# define Trace(x) fprintf x
+# define Tracev(x) {if (verbose) fprintf x ;}
+# define Tracevv(x) {if (verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+static int fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+extern char input_data[];
+extern int input_len;
+
+static long bytes_out = 0;
+static uch *output_data;
+static unsigned long output_ptr = 0;
+
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+int puts(const char *);
+
+extern int _text; /* Defined in vmlinux.lds.S */
+extern int _end;
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#define HEAP_SIZE 0x10000
+
+#include "../../../../lib/inflate.c"
+
+#define SCR *((volatile unsigned char *)0xffff8a)
+#define TDR *((volatile unsigned char *)0xffff8b)
+#define SSR *((volatile unsigned char *)0xffff8c)
+
+static void *malloc(int size)
+{
+ void *p;
+
+ if (size <0) error("Malloc error");
+ if (free_mem_ptr == 0) error("Memory error");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+ p = (void *)free_mem_ptr;
+ free_mem_ptr += size;
+
+ if (free_mem_ptr >= free_mem_end_ptr)
+ error("Out of memory");
+
+ return p;
+}
+
+static void free(void *where)
+{ /* Don't care */
+}
+
+static void gzip_mark(void **ptr)
+{
+ *ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+ free_mem_ptr = (long) *ptr;
+}
+
+int puts(const char *s)
+{
+ return 0;
+}
+
+void* memset(void* s, int c, size_t n)
+{
+ int i;
+ char *ss = (char*)s;
+
+ for (i=0;i<n;i++) ss[i] = c;
+ return s;
+}
+
+void* memcpy(void* __dest, __const void* __src,
+ size_t __n)
+{
+ int i;
+ char *d = (char *)__dest, *s = (char *)__src;
+
+ for (i=0;i<__n;i++) d[i] = s[i];
+ return __dest;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int fill_inbuf(void)
+{
+ if (insize != 0) {
+ error("ran out of input data");
+ }
+
+ inbuf = input_data;
+ insize = input_len;
+ inptr = 1;
+ return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void flush_window(void)
+{
+ ulg c = crc; /* temporary variable */
+ unsigned n;
+ uch *in, *out, ch;
+
+ in = window;
+ out = &output_data[output_ptr];
+ for (n = 0; n < outcnt; n++) {
+ ch = *out++ = *in++;
+ c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+ }
+ crc = c;
+ bytes_out += (ulg)outcnt;
+ output_ptr += (ulg)outcnt;
+ outcnt = 0;
+}
+
+static void error(char *x)
+{
+ puts("\n\n");
+ puts(x);
+ puts("\n\n -- System halted");
+
+ while(1); /* Halt */
+}
+
+#define STACK_SIZE (4096)
+long user_stack [STACK_SIZE];
+long* stack_start = &user_stack[STACK_SIZE];
+
+void decompress_kernel(void)
+{
+ output_data = 0;
+ output_ptr = (unsigned long)0x400000;
+ free_mem_ptr = (unsigned long)&_end;
+ free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
+ makecrc();
+ puts("Uncompressing Linux... ");
+ gunzip();
+ puts("Ok, booting the kernel.\n");
+}
diff --git a/arch/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile
index 4edbc2e..ccc1a7f 100644
--- a/arch/h8300/kernel/Makefile
+++ b/arch/h8300/kernel/Makefile
@@ -4,10 +4,8 @@
extra-y := vmlinux.lds
-obj-y := process.o traps.o ptrace.o ints.o \
+obj-y := process.o traps.o ptrace.o irq.o \
sys_h8300.o time.o semaphore.o signal.o \
- setup.o gpio.o init_task.o syscalls.o devres.o
-
-devres-y = ../../../kernel/irq/devres.o
+ setup.o gpio.o init_task.o syscalls.o
obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o
diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c
new file mode 100644
index 0000000..43d21e9
--- /dev/null
+++ b/arch/h8300/kernel/irq.c
@@ -0,0 +1,211 @@
+/*
+ * linux/arch/h8300/kernel/irq.c
+ *
+ * Copyright 2007 Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <linux/random.h>
+#include <linux/bootmem.h>
+#include <linux/irq.h>
+
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/errno.h>
+
+/*#define DEBUG*/
+
+extern unsigned long *interrupt_redirect_table;
+extern const int h8300_saved_vectors[];
+extern const unsigned long h8300_trap_table[];
+int h8300_enable_irq_pin(unsigned int irq);
+void h8300_disable_irq_pin(unsigned int irq);
+
+#define CPU_VECTOR ((unsigned long *)0x000000)
+#define ADDR_MASK (0xffffff)
+
+static inline int is_ext_irq(unsigned int irq)
+{
+ return (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS));
+}
+
+static void h8300_enable_irq(unsigned int irq)
+{
+ if (is_ext_irq(irq))
+ IER_REGS |= 1 << (irq - EXT_IRQ0);
+}
+
+static void h8300_disable_irq(unsigned int irq)
+{
+ if (is_ext_irq(irq))
+ IER_REGS &= ~(1 << (irq - EXT_IRQ0));
+}
+
+static void h8300_end_irq(unsigned int irq)
+{
+}
+
+static unsigned int h8300_startup_irq(unsigned int irq)
+{
+ if (is_ext_irq(irq))
+ return h8300_enable_irq_pin(irq);
+ else
+ return 0;
+}
+
+static void h8300_shutdown_irq(unsigned int irq)
+{
+ if (is_ext_irq(irq))
+ h8300_disable_irq_pin(irq);
+}
+
+/*
+ * h8300 interrupt controler implementation
+ */
+struct irq_chip h8300irq_chip = {
+ .name = "H8300-INTC",
+ .startup = h8300_startup_irq,
+ .shutdown = h8300_shutdown_irq,
+ .enable = h8300_enable_irq,
+ .disable = h8300_disable_irq,
+ .ack = NULL,
+ .end = h8300_end_irq,
+};
+
+void ack_bad_irq(unsigned int irq)
+{
+ printk("unexpected IRQ trap at vector %02x\n", irq);
+}
+
+#if defined(CONFIG_RAMKERNEL)
+static unsigned long __init *get_vector_address(void)
+{
+ unsigned long *rom_vector = CPU_VECTOR;
+ unsigned long base,tmp;
+ int vec_no;
+
+ base = rom_vector[EXT_IRQ0] & ADDR_MASK;
+
+ /* check romvector format */
+ for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ0+EXT_IRQS; vec_no++) {
+ if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK))
+ return NULL;
+ }
+
+ /* ramvector base address */
+ base -= EXT_IRQ0*4;
+
+ /* writerble check */
+ tmp = ~(*(volatile unsigned long *)base);
+ (*(volatile unsigned long *)base) = tmp;
+ if ((*(volatile unsigned long *)base) != tmp)
+ return NULL;
+ return (unsigned long *)base;
+}
+
+static void __init setup_vector(void)
+{
+ int i;
+ unsigned long *ramvec,*ramvec_p;
+ const unsigned long *trap_entry;
+ const int *saved_vector;
+
+ ramvec = get_vector_address();
+ if (ramvec == NULL)
+ panic("interrupt vector serup failed.");
+ else
+ printk(KERN_INFO "virtual vector at 0x%08lx\n",(unsigned long)ramvec);
+
+ /* create redirect table */
+ ramvec_p = ramvec;
+ trap_entry = h8300_trap_table;
+ saved_vector = h8300_saved_vectors;
+ for ( i = 0; i < NR_IRQS; i++) {
+ if (i == *saved_vector) {
+ ramvec_p++;
+ saved_vector++;
+ } else {
+ if ( i < NR_TRAPS ) {
+ if (*trap_entry)
+ *ramvec_p = VECTOR(*trap_entry);
+ ramvec_p++;
+ trap_entry++;
+ } else
+ *ramvec_p++ = REDIRECT(interrupt_entry);
+ }
+ }
+ interrupt_redirect_table = ramvec;
+#ifdef DEBUG
+ ramvec_p = ramvec;
+ for (i = 0; i < NR_IRQS; i++) {
+ if ((i % 8) == 0)
+ printk(KERN_DEBUG "\n%p: ",ramvec_p);
+ printk(KERN_DEBUG "%p ",*ramvec_p);
+ ramvec_p++;
+ }
+ printk(KERN_DEBUG "\n");
+#endif
+}
+#else
+#define setup_vector() do { } while(0)
+#endif
+
+void __init init_IRQ(void)
+{
+ int c;
+
+ setup_vector();
+
+ for (c = 0; c < NR_IRQS; c++) {
+ irq_desc[c].status = IRQ_DISABLED;
+ irq_desc[c].action = NULL;
+ irq_desc[c].depth = 1;
+ irq_desc[c].chip = &h8300irq_chip;
+ }
+}
+
+asmlinkage void do_IRQ(int irq)
+{
+ irq_enter();
+ __do_IRQ(irq);
+ irq_exit();
+}
+
+#if defined(CONFIG_PROC_FS)
+int show_interrupts(struct seq_file *p, void *v)
+{
+ int i = *(loff_t *) v, j;
+ struct irqaction * action;
+ unsigned long flags;
+
+ if (i == 0)
+ seq_puts(p, " CPU0");
+
+ if (i < NR_IRQS) {
+ spin_lock_irqsave(&irq_desc[i].lock, flags);
+ action = irq_desc[i].action;
+ if (!action)
+ goto unlock;
+ seq_printf(p, "%3d: ",i);
+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, " %14s", irq_desc[i].chip->name);
+ seq_printf(p, "-%-8s", irq_desc[i].name);
+ seq_printf(p, " %s", action->name);
+
+ for (action=action->next; action; action = action->next)
+ seq_printf(p, ", %s", action->name);
+ seq_putc(p, '\n');
+unlock:
+ spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+ }
+ return 0;
+}
+#endif
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
index f603137..8f2411d 100644
--- a/arch/h8300/kernel/ptrace.c
+++ b/arch/h8300/kernel/ptrace.c
@@ -19,7 +19,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c
index 313cd80..b2e86d0 100644
--- a/arch/h8300/kernel/setup.c
+++ b/arch/h8300/kernel/setup.c
@@ -33,10 +33,7 @@
#include <asm/setup.h>
#include <asm/irq.h>
-
-#ifdef CONFIG_BLK_DEV_INITRD
#include <asm/pgtable.h>
-#endif
#if defined(__H8300H__)
#define CPU "H8/300H"
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c
index 302a2df..11ba75a 100644
--- a/arch/h8300/kernel/sys_h8300.c
+++ b/arch/h8300/kernel/sys_h8300.c
@@ -10,7 +10,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c
index d1ef615..3306382 100644
--- a/arch/h8300/kernel/time.c
+++ b/arch/h8300/kernel/time.c
@@ -44,7 +44,7 @@ static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
#ifndef CONFIG_SMP
update_process_times(user_mode(regs));
#endif
- profile_tick(CPU_PROFILING, regs);
+ profile_tick(CPU_PROFILING);
}
void time_init(void)
@@ -66,55 +66,3 @@ void time_init(void)
platform_timer_setup(timer_interrupt);
}
-
-/*
- * This version of gettimeofday has near microsecond resolution.
- */
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
- unsigned long usec, sec;
-
- read_lock_irqsave(&xtime_lock, flags);
- usec = 0;
- sec = xtime.tv_sec;
- usec += (xtime.tv_nsec / 1000);
- read_unlock_irqrestore(&xtime_lock, flags);
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_lock_irq(&xtime_lock);
- /* This is revolting. We need to set the xtime.tv_usec
- * correctly. However, the value in this location is
- * is value at the last tick.
- * Discover what correction gettimeofday
- * would have done, and then undo it!
- */
- while (tv->tv_nsec < 0) {
- tv->tv_nsec += NSEC_PER_SEC;
- tv->tv_sec--;
- }
-
- xtime.tv_sec = tv->tv_sec;
- xtime.tv_nsec = tv->tv_nsec;
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
- return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
diff --git a/arch/h8300/mm/kmap.c b/arch/h8300/mm/kmap.c
index 26ab172..5c7af09 100644
--- a/arch/h8300/mm/kmap.c
+++ b/arch/h8300/mm/kmap.c
@@ -24,12 +24,14 @@
#undef DEBUG
+#define VIRT_OFFSET (0x01000000)
+
/*
* Map some physical address range into the kernel address space.
*/
void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
{
- return (void *)physaddr;
+ return (void *)(physaddr + VIRT_OFFSET);
}
/*
diff --git a/arch/h8300/platform/h8300h/Makefile b/arch/h8300/platform/h8300h/Makefile
index 5d42c77..b24ea08 100644
--- a/arch/h8300/platform/h8300h/Makefile
+++ b/arch/h8300/platform/h8300h/Makefile
@@ -4,4 +4,4 @@
# Reuse any files we can from the H8/300H
#
-obj-y := entry.o ints_h8300h.o ptrace_h8300h.o
+obj-y := entry.o irq_pin.o ptrace_h8300h.o
diff --git a/arch/h8300/platform/h8300h/entry.S b/arch/h8300/platform/h8300h/entry.S
index d2dea24..f86ac3b 100644
--- a/arch/h8300/platform/h8300h/entry.S
+++ b/arch/h8300/platform/h8300h/entry.S
@@ -30,12 +30,12 @@
mov.l er0,@-sp
stc ccr,r0l /* check kernel mode */
- orc #0x10,ccr
btst #4,r0l
bne 5f
mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */
mov.l @sp,er0
+ orc #0x10,ccr
mov.l @SYMBOL_NAME(sw_ksp),sp
sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */
mov.l er0,@-sp
@@ -165,7 +165,7 @@ SYMBOL_NAME_LABEL(interrupt_entry)
dec.l #1,er0
mov.l sp,er1
subs #4,er1 /* adjust ret_pc */
- jsr @SYMBOL_NAME(process_int)
+ jsr @SYMBOL_NAME(do_IRQ)
mov.l @SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,er0
beq 1f
jsr @SYMBOL_NAME(do_softirq)
diff --git a/arch/h8300/platform/h8300h/generic/Makefile b/arch/h8300/platform/h8300h/generic/Makefile
index b6ea768..32b964a 100644
--- a/arch/h8300/platform/h8300h/generic/Makefile
+++ b/arch/h8300/platform/h8300h/generic/Makefile
@@ -2,5 +2,5 @@
# Makefile for the linux kernel.
#
+extra-y := crt0_$(MODEL).o
obj-y := timer.o
-extra-y = crt0_$(MODEL).o
diff --git a/arch/h8300/platform/h8300h/ints_h8300h.c b/arch/h8300/platform/h8300h/ints_h8300h.c
deleted file mode 100644
index f177711..0000000
--- a/arch/h8300/platform/h8300h/ints_h8300h.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * linux/arch/h8300/platform/h8300h/ints_h8300h.c
- * Interrupt handling CPU variants
- *
- * Yoshinori Sato <ysato@users.sourceforge.jp>
- *
- */
-
-#include <linux/init.h>
-#include <linux/errno.h>
-
-#include <asm/ptrace.h>
-#include <asm/traps.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/gpio.h>
-#include <asm/regs306x.h>
-
-/* saved vector list */
-const int __initdata h8300_saved_vectors[]={
-#if defined(CONFIG_GDB_DEBUG)
- TRAP3_VEC,
-#endif
- -1
-};
-
-/* trap entry table */
-const unsigned long __initdata h8300_trap_table[NR_TRAPS]={
- 0,0,0,0,0,0,0,0,
- (unsigned long)system_call, /* TRAPA #0 */
- 0,0,
- (unsigned long)trace_break, /* TRAPA #3 */
-};
-
-int h8300_enable_irq_pin(unsigned int irq)
-{
- int bitmask;
- if (irq < EXT_IRQ0 || irq > EXT_IRQ5)
- return 0;
-
- /* initialize IRQ pin */
- bitmask = 1 << (irq - EXT_IRQ0);
- switch(irq) {
- case EXT_IRQ0:
- case EXT_IRQ1:
- case EXT_IRQ2:
- case EXT_IRQ3:
- if (H8300_GPIO_RESERVE(H8300_GPIO_P8, bitmask) == 0)
- return -EBUSY;
- H8300_GPIO_DDR(H8300_GPIO_P8, bitmask, H8300_GPIO_INPUT);
- break;
- case EXT_IRQ4:
- case EXT_IRQ5:
- if (H8300_GPIO_RESERVE(H8300_GPIO_P9, bitmask) == 0)
- return -EBUSY;
- H8300_GPIO_DDR(H8300_GPIO_P9, bitmask, H8300_GPIO_INPUT);
- break;
- }
-
- return 0;
-}
-
-void h8300_disable_irq_pin(unsigned int irq)
-{
- int bitmask;
- if (irq < EXT_IRQ0 || irq > EXT_IRQ5)
- return;
-
- /* disable interrupt & release IRQ pin */
- bitmask = 1 << (irq - EXT_IRQ0);
- switch(irq) {
- case EXT_IRQ0:
- case EXT_IRQ1:
- case EXT_IRQ2:
- case EXT_IRQ3:
- *(volatile unsigned char *)IER &= ~bitmask;
- H8300_GPIO_FREE(H8300_GPIO_P8, bitmask);
- break ;
- case EXT_IRQ4:
- case EXT_IRQ5:
- *(volatile unsigned char *)IER &= ~bitmask;
- H8300_GPIO_FREE(H8300_GPIO_P9, bitmask);
- break;
- }
-}
diff --git a/arch/h8300/platform/h8s/entry.S b/arch/h8300/platform/h8s/entry.S
index aeb2e9f..f3d6b8e 100644
--- a/arch/h8300/platform/h8s/entry.S
+++ b/arch/h8300/platform/h8s/entry.S
@@ -31,12 +31,13 @@
mov.l er0,@-sp
stc ccr,r0l /* check kernel mode */
- orc #0x10,ccr
btst #4,r0l
bne 5f
- mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */
- mov.l @sp,er0
+ /* user mode */
+ mov.l sp,@SYMBOL_NAME(sw_usp)
+ mov.l @sp,er0 /* restore saved er0 */
+ orc #0x10,ccr /* switch kernel stack */
mov.l @SYMBOL_NAME(sw_ksp),sp
sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */
stm.l er0-er3,@-sp
@@ -55,8 +56,9 @@
mov.l er0,@(LER0-LER3:16,sp) /* copy ER0 */
bra 6f
5:
- mov.l @sp,er0 /* kernel mode */
- subs #2,sp /* dummy ccr */
+ /* kernel mode */
+ mov.l @sp,er0 /* restore saved er0 */
+ subs #2,sp /* set dummy ccr */
stm.l er0-er3,@-sp
mov.w @(LRET-LER3:16,sp),r1 /* copy old ccr */
mov.b r1h,r1l
@@ -94,6 +96,7 @@
mov.l @sp+,er1
add.l #(LRET-LER1),sp /* remove LORIG - LRET */
mov.l sp,@SYMBOL_NAME(sw_ksp)
+ andc #0xef,ccr /* switch to user mode */
mov.l er0,sp
bra 8f
7:
@@ -173,9 +176,6 @@ SYMBOL_NAME_LABEL(interrupt_entry)
SYMBOL_NAME_LABEL(system_call)
subs #4,sp /* dummy LVEC */
SAVE_ALL
- mov.w @(LCCR:16,sp),r1
- bset #4,r1l
- ldc r1l,ccr /* restore ccr */
mov.l er0,er4
mov.l #-ENOSYS,er0
mov.l er0,@(LER0:16,sp)
@@ -198,6 +198,7 @@ SYMBOL_NAME_LABEL(system_call)
mov.l @(LER1:16,sp),er0
mov.l @(LER2:16,sp),er1
mov.l @(LER3:16,sp),er2
+ andc #0x7f,ccr
jsr @er4
mov.l er0,@(LER0:16,sp) /* save the return value */
#if defined(CONFIG_SYSCALL_PRINT)
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index a9af760..64ad10f 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -79,6 +79,10 @@ config ARCH_MAY_HAVE_PC_FDC
bool
default y
+config ARCH_USES_SLAB_PAGE_STRUCT
+ bool
+ default y
+
config DMI
bool
default y
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index 4f98516..91cff8d 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -34,6 +34,7 @@ obj-y += sysenter.o vsyscall.o
obj-$(CONFIG_ACPI_SRAT) += srat.o
obj-$(CONFIG_EFI) += efi.o efi_stub.o
obj-$(CONFIG_DOUBLEFAULT) += doublefault.o
+obj-$(CONFIG_SERIAL_8250) += legacy_serial.o
obj-$(CONFIG_VM86) += vm86.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_HPET_TIMER) += hpet.o
diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c
index e5cec66..d8cda14 100644
--- a/arch/i386/kernel/alternative.c
+++ b/arch/i386/kernel/alternative.c
@@ -390,8 +390,8 @@ void __init alternative_instructions(void)
_text, _etext);
}
free_init_pages("SMP alternatives",
- __pa_symbol(&__smp_locks),
- __pa_symbol(&__smp_locks_end));
+ (unsigned long)__smp_locks,
+ (unsigned long)__smp_locks_end);
} else {
alternatives_smp_module_add(NULL, "core kernel",
__smp_locks, __smp_locks_end,
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index aca054c..67824f3 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -19,7 +19,6 @@
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/mc146818rtc.h>
#include <linux/kernel_stat.h>
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 367ff1d..4112afe 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -223,7 +223,6 @@
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/dmi.h>
#include <linux/suspend.h>
#include <linux/kthread.h>
@@ -1173,7 +1172,7 @@ static void reinit_timer(void)
unsigned long flags;
spin_lock_irqsave(&i8253_lock, flags);
- /* set the clock to 100 Hz */
+ /* set the clock to HZ */
outb_p(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */
udelay(10);
outb_p(LATCH & 0xff, PIT_CH0); /* LSB */
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index a5e0e99..53589d1 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -22,7 +22,7 @@
#include <asm/nmi.h>
#include <asm/hw_irq.h>
#include <asm/apic.h>
-#include <asm/kdebug.h>
+#include <linux/kdebug.h>
#include <asm/smp.h>
#include <mach_ipi.h>
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c
index dd9e7fa..a180802 100644
--- a/arch/i386/kernel/efi.c
+++ b/arch/i386/kernel/efi.c
@@ -347,14 +347,12 @@ void __init efi_init(void)
printk(KERN_ERR PFX "Woah! Couldn't map the EFI system table.\n");
if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
printk(KERN_ERR PFX "Woah! EFI system table signature incorrect\n");
- if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0)
- printk(KERN_ERR PFX
- "Warning: EFI system table major version mismatch: "
- "got %d.%02d, expected %d.%02d\n",
+ if ((efi.systab->hdr.revision >> 16) == 0)
+ printk(KERN_ERR PFX "Warning: EFI system table version "
+ "%d.%02d, expected 1.00 or greater\n",
efi.systab->hdr.revision >> 16,
- efi.systab->hdr.revision & 0xffff,
- EFI_SYSTEM_TABLE_REVISION >> 16,
- EFI_SYSTEM_TABLE_REVISION & 0xffff);
+ efi.systab->hdr.revision & 0xffff);
+
/*
* Grab some details from the system table
*/
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
index 03abfdb..0499cbe 100644
--- a/arch/i386/kernel/i8259.c
+++ b/arch/i386/kernel/i8259.c
@@ -5,7 +5,6 @@
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/random.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/sysdev.h>
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 1b623cd..7f8b7af 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -25,7 +25,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/mc146818rtc.h>
#include <linux/compiler.h>
#include <linux/acpi.h>
diff --git a/arch/i386/kernel/ioport.c b/arch/i386/kernel/ioport.c
index d1e42e0..3d310a9 100644
--- a/arch/i386/kernel/ioport.c
+++ b/arch/i386/kernel/ioport.c
@@ -12,7 +12,6 @@
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/slab.h>
#include <linux/thread_info.h>
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index b545bc7..dde828a 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -31,8 +31,8 @@
#include <linux/kprobes.h>
#include <linux/ptrace.h>
#include <linux/preempt.h>
+#include <linux/kdebug.h>
#include <asm/cacheflush.h>
-#include <asm/kdebug.h>
#include <asm/desc.h>
#include <asm/uaccess.h>
@@ -226,24 +226,15 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
unsigned long *sara = (unsigned long *)&regs->esp;
- struct kretprobe_instance *ri;
+ ri->ret_addr = (kprobe_opcode_t *) *sara;
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *) *sara;
-
- /* Replace the return addr with trampoline addr */
- *sara = (unsigned long) &kretprobe_trampoline;
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ /* Replace the return addr with trampoline addr */
+ *sara = (unsigned long) &kretprobe_trampoline;
}
/*
@@ -449,8 +440,7 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
break;
}
- BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
-
+ kretprobe_assert(ri, orig_ret_address, trampoline_address);
spin_unlock_irqrestore(&kretprobe_lock, flags);
hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
@@ -753,6 +743,11 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
return 0;
}
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+ return 0;
+}
+
int __init arch_init_kprobes(void)
{
return 0;
diff --git a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c
index b410e5f..e0b2d17 100644
--- a/arch/i386/kernel/ldt.c
+++ b/arch/i386/kernel/ldt.c
@@ -10,7 +10,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
diff --git a/arch/i386/kernel/legacy_serial.c b/arch/i386/kernel/legacy_serial.c
new file mode 100644
index 0000000..2151011
--- /dev/null
+++ b/arch/i386/kernel/legacy_serial.c
@@ -0,0 +1,67 @@
+/*
+ * Legacy COM port devices for x86 platforms without PNPBIOS or ACPI.
+ * Data taken from include/asm-i386/serial.h.
+ *
+ * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
+ * Bjorn Helgaas <bjorn.helgaas@hp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pnp.h>
+#include <linux/serial_8250.h>
+
+/* Standard COM flags (except for COM4, because of the 8514 problem) */
+#ifdef CONFIG_SERIAL_DETECT_IRQ
+#define COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ)
+#define COM4_FLAGS (UPF_BOOT_AUTOCONF | UPF_AUTO_IRQ)
+#else
+#define COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
+#define COM4_FLAGS UPF_BOOT_AUTOCONF
+#endif
+
+#define PORT(_base,_irq,_flags) \
+ { \
+ .iobase = _base, \
+ .irq = _irq, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_PORT, \
+ .flags = _flags, \
+ }
+
+static struct plat_serial8250_port x86_com_data[] = {
+ PORT(0x3F8, 4, COM_FLAGS),
+ PORT(0x2F8, 3, COM_FLAGS),
+ PORT(0x3E8, 4, COM_FLAGS),
+ PORT(0x2E8, 3, COM4_FLAGS),
+ { },
+};
+
+static struct platform_device x86_com_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = x86_com_data,
+ },
+};
+
+static int force_legacy_probe;
+module_param_named(force, force_legacy_probe, bool, 0);
+MODULE_PARM_DESC(force, "Force legacy serial port probe");
+
+static int __init serial8250_x86_com_init(void)
+{
+ if (pnp_platform_devices && !force_legacy_probe)
+ return -ENODEV;
+
+ return platform_device_register(&x86_com_device);
+}
+
+module_init(serial8250_x86_com_init);
+
+MODULE_AUTHOR("Bjorn Helgaas");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250/16x50 legacy probe module");
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 0952ecc..13abb4e 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -18,7 +18,6 @@
#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
-#include <linux/smp_lock.h>
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
#include <linux/bitops.h>
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c
index bcaa6e9..8cd0a91 100644
--- a/arch/i386/kernel/msr.c
+++ b/arch/i386/kernel/msr.c
@@ -45,104 +45,6 @@
static struct class *msr_class;
-static inline int wrmsr_eio(u32 reg, u32 eax, u32 edx)
-{
- int err;
-
- err = wrmsr_safe(reg, eax, edx);
- if (err)
- err = -EIO;
- return err;
-}
-
-static inline int rdmsr_eio(u32 reg, u32 *eax, u32 *edx)
-{
- int err;
-
- err = rdmsr_safe(reg, eax, edx);
- if (err)
- err = -EIO;
- return err;
-}
-
-#ifdef CONFIG_SMP
-
-struct msr_command {
- int err;
- u32 reg;
- u32 data[2];
-};
-
-static void msr_smp_wrmsr(void *cmd_block)
-{
- struct msr_command *cmd = (struct msr_command *)cmd_block;
-
- cmd->err = wrmsr_eio(cmd->reg, cmd->data[0], cmd->data[1]);
-}
-
-static void msr_smp_rdmsr(void *cmd_block)
-{
- struct msr_command *cmd = (struct msr_command *)cmd_block;
-
- cmd->err = rdmsr_eio(cmd->reg, &cmd->data[0], &cmd->data[1]);
-}
-
-static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx)
-{
- struct msr_command cmd;
- int ret;
-
- preempt_disable();
- if (cpu == smp_processor_id()) {
- ret = wrmsr_eio(reg, eax, edx);
- } else {
- cmd.reg = reg;
- cmd.data[0] = eax;
- cmd.data[1] = edx;
-
- smp_call_function_single(cpu, msr_smp_wrmsr, &cmd, 1, 1);
- ret = cmd.err;
- }
- preempt_enable();
- return ret;
-}
-
-static inline int do_rdmsr(int cpu, u32 reg, u32 * eax, u32 * edx)
-{
- struct msr_command cmd;
- int ret;
-
- preempt_disable();
- if (cpu == smp_processor_id()) {
- ret = rdmsr_eio(reg, eax, edx);
- } else {
- cmd.reg = reg;
-
- smp_call_function_single(cpu, msr_smp_rdmsr, &cmd, 1, 1);
-
- *eax = cmd.data[0];
- *edx = cmd.data[1];
-
- ret = cmd.err;
- }
- preempt_enable();
- return ret;
-}
-
-#else /* ! CONFIG_SMP */
-
-static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx)
-{
- return wrmsr_eio(reg, eax, edx);
-}
-
-static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx)
-{
- return rdmsr_eio(reg, eax, edx);
-}
-
-#endif /* ! CONFIG_SMP */
-
static loff_t msr_seek(struct file *file, loff_t offset, int orig)
{
loff_t ret = -EINVAL;
@@ -174,9 +76,9 @@ static ssize_t msr_read(struct file *file, char __user * buf,
return -EINVAL; /* Invalid chunk size */
for (; count; count -= 8) {
- err = do_rdmsr(cpu, reg, &data[0], &data[1]);
+ err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]);
if (err)
- return err;
+ return -EIO;
if (copy_to_user(tmp, &data, 8))
return -EFAULT;
tmp += 2;
@@ -200,9 +102,9 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
for (; count; count -= 8) {
if (copy_from_user(&data, tmp, 8))
return -EFAULT;
- err = do_wrmsr(cpu, reg, data[0], data[1]);
+ err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]);
if (err)
- return err;
+ return -EIO;
tmp += 2;
}
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 33cf2f3..fba121f 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -23,10 +23,10 @@
#include <linux/kprobes.h>
#include <linux/cpumask.h>
#include <linux/kernel_stat.h>
+#include <linux/kdebug.h>
#include <asm/smp.h>
#include <asm/nmi.h>
-#include <asm/kdebug.h>
#include "mach_traps.h"
diff --git a/arch/i386/kernel/pci-dma.c b/arch/i386/kernel/pci-dma.c
index 3ebcea0..30b754f 100644
--- a/arch/i386/kernel/pci-dma.c
+++ b/arch/i386/kernel/pci-dma.c
@@ -77,7 +77,7 @@ int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
{
void __iomem *mem_base = NULL;
int pages = size >> PAGE_SHIFT;
- int bitmap_size = (pages + 31)/32;
+ int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
goto out;
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 6199947..d76d9bc 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -21,7 +21,6 @@
#include <linux/mm.h>
#include <linux/elfcore.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 4a8f8a2..0c0ceec 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -9,7 +9,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index 4f99e87..d574e38 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -10,7 +10,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 89a45a9..93f202a 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -13,7 +13,6 @@
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
#include <linux/cache.h>
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index a4b7ad2..b92cc4e 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -40,7 +40,6 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/kernel_stat.h>
-#include <linux/smp_lock.h>
#include <linux/bootmem.h>
#include <linux/notifier.h>
#include <linux/cpu.h>
diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c
index 4048397..e5dcb93 100644
--- a/arch/i386/kernel/sys_i386.c
+++ b/arch/i386/kernel/sys_i386.c
@@ -10,7 +10,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index 2697e92..0772678 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -319,3 +319,4 @@ ENTRY(sys_call_table)
.long sys_move_pages
.long sys_getcpu
.long sys_epoll_pwait
+ .long sys_utimensat /* 320 */
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index f21b41e..4bec0cb 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -52,7 +52,7 @@
#include <asm/unwind.h>
#include <asm/smp.h>
#include <asm/arch_hooks.h>
-#include <asm/kdebug.h>
+#include <linux/kdebug.h>
#include <asm/stacktrace.h>
#include <linux/module.h>
@@ -95,20 +95,6 @@ asmlinkage void machine_check(void);
int kstack_depth_to_print = 24;
static unsigned int code_bytes = 64;
-ATOMIC_NOTIFIER_HEAD(i386die_chain);
-
-int register_die_notifier(struct notifier_block *nb)
-{
- vmalloc_sync_all();
- return atomic_notifier_chain_register(&i386die_chain, nb);
-}
-EXPORT_SYMBOL(register_die_notifier); /* used modular by kdb */
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&i386die_chain, nb);
-}
-EXPORT_SYMBOL(unregister_die_notifier); /* used modular by kdb */
static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
{
@@ -747,6 +733,11 @@ static __kprobes void default_do_nmi(struct pt_regs * regs)
*/
if (nmi_watchdog_tick(regs, reason))
return;
+#endif
+ if (notify_die(DIE_NMI_POST, "nmi_post", regs, reason, 2, 0)
+ == NOTIFY_STOP)
+ return;
+#ifdef CONFIG_X86_LOCAL_APIC
if (!do_nmi_callback(regs, smp_processor_id()))
#endif
unknown_nmi_error(reason, regs);
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
index d1b8f2b..f2dcd1d 100644
--- a/arch/i386/kernel/vm86.c
+++ b/arch/i386/kernel/vm86.c
@@ -39,7 +39,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/highmem.h>
#include <linux/ptrace.h>
#include <linux/audit.h>
diff --git a/arch/i386/lib/msr-on-cpu.c b/arch/i386/lib/msr-on-cpu.c
index 1c46bda..7767962 100644
--- a/arch/i386/lib/msr-on-cpu.c
+++ b/arch/i386/lib/msr-on-cpu.c
@@ -6,6 +6,7 @@
struct msr_info {
u32 msr_no;
u32 l, h;
+ int err;
};
static void __rdmsr_on_cpu(void *info)
@@ -15,20 +16,38 @@ static void __rdmsr_on_cpu(void *info)
rdmsr(rv->msr_no, rv->l, rv->h);
}
-void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
+static void __rdmsr_safe_on_cpu(void *info)
{
+ struct msr_info *rv = info;
+
+ rv->err = rdmsr_safe(rv->msr_no, &rv->l, &rv->h);
+}
+
+static int _rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h, int safe)
+{
+ int err = 0;
preempt_disable();
if (smp_processor_id() == cpu)
- rdmsr(msr_no, *l, *h);
+ if (safe)
+ err = rdmsr_safe(msr_no, l, h);
+ else
+ rdmsr(msr_no, *l, *h);
else {
struct msr_info rv;
rv.msr_no = msr_no;
- smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 0, 1);
+ if (safe) {
+ smp_call_function_single(cpu, __rdmsr_safe_on_cpu,
+ &rv, 0, 1);
+ err = rv.err;
+ } else {
+ smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 0, 1);
+ }
*l = rv.l;
*h = rv.h;
}
preempt_enable();
+ return err;
}
static void __wrmsr_on_cpu(void *info)
@@ -38,21 +57,63 @@ static void __wrmsr_on_cpu(void *info)
wrmsr(rv->msr_no, rv->l, rv->h);
}
-void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+static void __wrmsr_safe_on_cpu(void *info)
{
+ struct msr_info *rv = info;
+
+ rv->err = wrmsr_safe(rv->msr_no, rv->l, rv->h);
+}
+
+static int _wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h, int safe)
+{
+ int err = 0;
preempt_disable();
if (smp_processor_id() == cpu)
- wrmsr(msr_no, l, h);
+ if (safe)
+ err = wrmsr_safe(msr_no, l, h);
+ else
+ wrmsr(msr_no, l, h);
else {
struct msr_info rv;
rv.msr_no = msr_no;
rv.l = l;
rv.h = h;
- smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 0, 1);
+ if (safe) {
+ smp_call_function_single(cpu, __wrmsr_safe_on_cpu,
+ &rv, 0, 1);
+ err = rv.err;
+ } else {
+ smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 0, 1);
+ }
}
preempt_enable();
+ return err;
+}
+
+void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+{
+ _wrmsr_on_cpu(cpu, msr_no, l, h, 0);
+}
+
+void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
+{
+ _rdmsr_on_cpu(cpu, msr_no, l, h, 0);
+}
+
+/* These "safe" variants are slower and should be used when the target MSR
+ may not actually exist. */
+int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+{
+ return _wrmsr_on_cpu(cpu, msr_no, l, h, 1);
+}
+
+int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
+{
+ return _rdmsr_on_cpu(cpu, msr_no, l, h, 1);
}
EXPORT_SYMBOL(rdmsr_on_cpu);
EXPORT_SYMBOL(wrmsr_on_cpu);
+EXPORT_SYMBOL(rdmsr_safe_on_cpu);
+EXPORT_SYMBOL(wrmsr_safe_on_cpu);
diff --git a/arch/i386/mach-default/setup.c b/arch/i386/mach-default/setup.c
index c788162..7f635c7 100644
--- a/arch/i386/mach-default/setup.c
+++ b/arch/i386/mach-default/setup.c
@@ -81,7 +81,7 @@ void __init trap_init_hook(void)
static struct irqaction irq0 = {
.handler = timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_NOBALANCING,
+ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL,
.mask = CPU_MASK_NONE,
.name = "timer"
};
diff --git a/arch/i386/mach-visws/setup.c b/arch/i386/mach-visws/setup.c
index 233ee20..1f81f10 100644
--- a/arch/i386/mach-visws/setup.c
+++ b/arch/i386/mach-visws/setup.c
@@ -116,7 +116,7 @@ void __init pre_setup_arch_hook()
static struct irqaction irq0 = {
.handler = timer_interrupt,
- .flags = IRQF_DISABLED,
+ .flags = IRQF_DISABLED | IRQF_IRQPOLL,
.name = "timer",
};
diff --git a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c
index 38c2b13..710faf7 100644
--- a/arch/i386/mach-visws/visws_apic.c
+++ b/arch/i386/mach-visws/visws_apic.c
@@ -18,7 +18,6 @@
#include <linux/kernel_stat.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/io.h>
diff --git a/arch/i386/mach-voyager/setup.c b/arch/i386/mach-voyager/setup.c
index 447bb10..2b55694 100644
--- a/arch/i386/mach-voyager/setup.c
+++ b/arch/i386/mach-voyager/setup.c
@@ -42,7 +42,7 @@ void __init trap_init_hook(void)
static struct irqaction irq0 = {
.handler = timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_NOBALANCING,
+ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL,
.mask = CPU_MASK_NONE,
.name = "timer"
};
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
index 1a5e448..50d9c52 100644
--- a/arch/i386/mach-voyager/voyager_smp.c
+++ b/arch/i386/mach-voyager/voyager_smp.c
@@ -16,7 +16,6 @@
#include <linux/mc146818rtc.h>
#include <linux/cache.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/bootmem.h>
diff --git a/arch/i386/mach-voyager/voyager_thread.c b/arch/i386/mach-voyager/voyager_thread.c
index fdc1d92..b4b24e0 100644
--- a/arch/i386/mach-voyager/voyager_thread.c
+++ b/arch/i386/mach-voyager/voyager_thread.c
@@ -18,7 +18,6 @@
#include <linux/kernel_stat.h>
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/kmod.h>
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index f534c29..29d7d61 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -14,20 +14,20 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/vt_kern.h> /* For unblank_screen() */
#include <linux/highmem.h>
#include <linux/bootmem.h> /* for max_low_pfn */
+#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/uaccess.h>
+#include <linux/kdebug.h>
#include <asm/system.h>
#include <asm/desc.h>
-#include <asm/kdebug.h>
#include <asm/segment.h>
extern void die(const char *,struct pt_regs *,long);
diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c
index 34728e4..efdf95a 100644
--- a/arch/i386/mm/hugetlbpage.c
+++ b/arch/i386/mm/hugetlbpage.c
@@ -9,7 +9,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/sysctl.h>
@@ -367,6 +366,12 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
if (len > TASK_SIZE)
return -ENOMEM;
+ if (flags & MAP_FIXED) {
+ if (prepare_hugepage_range(addr, len, pgoff))
+ return -EINVAL;
+ return addr;
+ }
+
if (addr) {
addr = ALIGN(addr, HPAGE_SIZE);
vma = find_vma(mm, addr);
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index dbe16f6..c50782e 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -751,12 +751,9 @@ void __init pgtable_cache_init(void)
pmd_cache = kmem_cache_create("pmd",
PTRS_PER_PMD*sizeof(pmd_t),
PTRS_PER_PMD*sizeof(pmd_t),
- 0,
+ SLAB_PANIC,
pmd_ctor,
NULL);
- if (!pmd_cache)
- panic("pgtable_cache_init(): cannot create pmd cache");
-
if (!SHARED_KERNEL_PMD) {
/* If we're in PAE mode and have a non-shared
kernel pmd, then the pgd size must be a
@@ -770,11 +767,9 @@ void __init pgtable_cache_init(void)
pgd_cache = kmem_cache_create("pgd",
pgd_size,
pgd_size,
- 0,
+ SLAB_PANIC,
pgd_ctor,
(!SHARED_KERNEL_PMD) ? pgd_dtor : NULL);
- if (!pgd_cache)
- panic("pgtable_cache_init(): Cannot create pgd cache");
}
/*
@@ -843,11 +838,10 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
unsigned long addr;
for (addr = begin; addr < end; addr += PAGE_SIZE) {
- struct page *page = pfn_to_page(addr >> PAGE_SHIFT);
- ClearPageReserved(page);
- init_page_count(page);
- memset(page_address(page), POISON_FREE_INITMEM, PAGE_SIZE);
- __free_page(page);
+ ClearPageReserved(virt_to_page(addr));
+ init_page_count(virt_to_page(addr));
+ memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
+ free_page(addr);
totalram_pages++;
}
printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
@@ -856,14 +850,14 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
void free_initmem(void)
{
free_init_pages("unused kernel memory",
- __pa_symbol(&__init_begin),
- __pa_symbol(&__init_end));
+ (unsigned long)(&__init_begin),
+ (unsigned long)(&__init_end));
}
#ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end)
{
- free_init_pages("initrd memory", __pa(start), __pa(end));
+ free_init_pages("initrd memory", start, end);
}
#endif
diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
index 695f737..8e18520 100644
--- a/arch/i386/oprofile/nmi_int.c
+++ b/arch/i386/oprofile/nmi_int.c
@@ -14,10 +14,10 @@
#include <linux/sysdev.h>
#include <linux/slab.h>
#include <linux/moduleparam.h>
+#include <linux/kdebug.h>
#include <asm/nmi.h>
#include <asm/msr.h>
#include <asm/apic.h>
-#include <asm/kdebug.h>
#include "op_counter.h"
#include "op_x86_model.h"
diff --git a/arch/i386/oprofile/nmi_timer_int.c b/arch/i386/oprofile/nmi_timer_int.c
index abf0ba5..1418e36 100644
--- a/arch/i386/oprofile/nmi_timer_int.c
+++ b/arch/i386/oprofile/nmi_timer_int.c
@@ -12,12 +12,11 @@
#include <linux/errno.h>
#include <linux/oprofile.h>
#include <linux/rcupdate.h>
-
+#include <linux/kdebug.h>
#include <asm/nmi.h>
#include <asm/apic.h>
#include <asm/ptrace.h>
-#include <asm/kdebug.h>
static int profile_timer_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data)
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 3b71f97..e23af4b 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -439,6 +439,16 @@ config IA64_PALINFO
To use this option, you have to ensure that the "/proc file system
support" (CONFIG_PROC_FS) is enabled, too.
+config IA64_MC_ERR_INJECT
+ tristate "MC error injection support"
+ help
+ Selets whether support for MC error injection. By enabling the
+ support, kernel provide sysfs interface for user application to
+ call MC error injection PAL procedure to inject various errors.
+ This is a useful tool for MCA testing.
+
+ If you're unsure, do not select this option.
+
config SGI_SN
def_bool y if (IA64_SGI_SN2 || IA64_GENERIC)
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
index 153bfdc..90bd960 100644
--- a/arch/ia64/defconfig
+++ b/arch/ia64/defconfig
@@ -164,6 +164,7 @@ CONFIG_COMPAT=y
CONFIG_IA64_MCA_RECOVERY=y
CONFIG_PERFMON=y
CONFIG_IA64_PALINFO=y
+# CONFIG_MC_ERR_INJECT is not set
CONFIG_SGI_SN=y
# CONFIG_IA64_ESI is not set
diff --git a/arch/ia64/hp/sim/boot/fw-emu.c b/arch/ia64/hp/sim/boot/fw-emu.c
index 5a0a7af..300acd9 100644
--- a/arch/ia64/hp/sim/boot/fw-emu.c
+++ b/arch/ia64/hp/sim/boot/fw-emu.c
@@ -287,7 +287,7 @@ sys_fw_init (const char *args, int arglen)
memset(efi_systab, 0, sizeof(efi_systab));
efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
- efi_systab->hdr.revision = EFI_SYSTEM_TABLE_REVISION;
+ efi_systab->hdr.revision = ((1 << 16) | 00);
efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
efi_systab->fw_vendor = __pa("H\0e\0w\0l\0e\0t\0t\0-\0P\0a\0c\0k\0a\0r\0d\0\0");
efi_systab->fw_revision = 1;
diff --git a/arch/ia64/ia32/ia32_ldt.c b/arch/ia64/ia32/ia32_ldt.c
index a152738..16d51c1 100644
--- a/arch/ia64/ia32/ia32_ldt.c
+++ b/arch/ia64/ia32/ia32_ldt.c
@@ -10,7 +10,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>
diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c
index b3355a9..10510e5 100644
--- a/arch/ia64/ia32/ia32_signal.c
+++ b/arch/ia64/ia32/ia32_signal.c
@@ -18,7 +18,6 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/syscalls.h>
#include <linux/unistd.h>
diff --git a/arch/ia64/ia32/ia32_support.c b/arch/ia64/ia32/ia32_support.c
index 6af400a..beea7a0 100644
--- a/arch/ia64/ia32/ia32_support.c
+++ b/arch/ia64/ia32/ia32_support.c
@@ -252,10 +252,8 @@ ia32_init (void)
extern struct kmem_cache *partial_page_cachep;
partial_page_cachep = kmem_cache_create("partial_page_cache",
- sizeof(struct partial_page), 0, 0,
- NULL, NULL);
- if (!partial_page_cachep)
- panic("Cannot create partial page SLAB cache");
+ sizeof(struct partial_page),
+ 0, SLAB_PANIC, NULL, NULL);
}
#endif
return 0;
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 098ee60..33e5a59 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o
obj-$(CONFIG_AUDIT) += audit.o
obj-$(CONFIG_PCI_MSI) += msi_ia64.o
mca_recovery-y += mca_drv.o mca_drv_asm.o
+obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
obj-$(CONFIG_IA64_ESI) += esi.o
ifneq ($(CONFIG_IA64_ESI),)
diff --git a/arch/ia64/kernel/crash.c b/arch/ia64/kernel/crash.c
index 80a94e7..aeb79fb 100644
--- a/arch/ia64/kernel/crash.c
+++ b/arch/ia64/kernel/crash.c
@@ -16,8 +16,8 @@
#include <linux/elfcore.h>
#include <linux/sysctl.h>
#include <linux/init.h>
+#include <linux/kdebug.h>
-#include <asm/kdebug.h>
#include <asm/mca.h>
int kdump_status[NR_CPUS];
@@ -74,7 +74,7 @@ crash_save_this_cpu(void)
buf = (u64 *) per_cpu_ptr(crash_notes, cpu);
if (!buf)
return;
- buf = append_elf_note(buf, "CORE", NT_PRSTATUS, prstatus,
+ buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS, prstatus,
sizeof(*prstatus));
final_note(buf);
}
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index f45f91d..75ec347 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -445,11 +445,11 @@ efi_init (void)
panic("Woah! Can't find EFI system table.\n");
if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
panic("Woah! EFI system table signature incorrect\n");
- if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0)
- printk(KERN_WARNING "Warning: EFI system table major version mismatch: "
- "got %d.%02d, expected %d.%02d\n",
- efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff,
- EFI_SYSTEM_TABLE_REVISION >> 16, EFI_SYSTEM_TABLE_REVISION & 0xffff);
+ if ((efi.systab->hdr.revision >> 16) == 0)
+ printk(KERN_WARNING "Warning: EFI system table version "
+ "%d.%02d, expected 1.00 or greater\n",
+ efi.systab->hdr.revision >> 16,
+ efi.systab->hdr.revision & 0xffff);
config_tables = __va(efi.systab->tables);
@@ -660,6 +660,29 @@ efi_memory_descriptor (unsigned long phys_addr)
return NULL;
}
+static int
+efi_memmap_intersects (unsigned long phys_addr, unsigned long size)
+{
+ void *efi_map_start, *efi_map_end, *p;
+ efi_memory_desc_t *md;
+ u64 efi_desc_size;
+ unsigned long end;
+
+ efi_map_start = __va(ia64_boot_param->efi_memmap);
+ efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
+ efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+ end = phys_addr + size;
+
+ for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+ md = p;
+
+ if (md->phys_addr < end && efi_md_end(md) > phys_addr)
+ return 1;
+ }
+ return 0;
+}
+
u32
efi_mem_type (unsigned long phys_addr)
{
@@ -766,11 +789,28 @@ valid_phys_addr_range (unsigned long phys_addr, unsigned long size)
int
valid_mmap_phys_addr_range (unsigned long pfn, unsigned long size)
{
+ unsigned long phys_addr = pfn << PAGE_SHIFT;
+ u64 attr;
+
+ attr = efi_mem_attribute(phys_addr, size);
+
/*
- * MMIO regions are often missing from the EFI memory map.
- * We must allow mmap of them for programs like X, so we
- * currently can't do any useful validation.
+ * /dev/mem mmap uses normal user pages, so we don't need the entire
+ * granule, but the entire region we're mapping must support the same
+ * attribute.
*/
+ if (attr & EFI_MEMORY_WB || attr & EFI_MEMORY_UC)
+ return 1;
+
+ /*
+ * Intel firmware doesn't tell us about all the MMIO regions, so
+ * in general we have to allow mmap requests. But if EFI *does*
+ * tell us about anything inside this region, we should deny it.
+ * The user can always map a smaller region to avoid the overlap.
+ */
+ if (efi_memmap_intersects(phys_addr, size))
+ return 0;
+
return 1;
}
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index e7873ee..55fd2d5 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -767,7 +767,7 @@ ENTRY(ia64_leave_syscall)
ld8.fill r15=[r3] // M0|1 restore r15
mov b6=r18 // I0 restore b6
- addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A
+ LOAD_PHYS_STACK_REG_SIZE(r17)
mov f9=f0 // F clear f9
(pKStk) br.cond.dpnt.many skip_rbs_switch // B
@@ -775,7 +775,6 @@ ENTRY(ia64_leave_syscall)
shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition
cover // B add current frame into dirty partition & set cr.ifs
;;
-(pUStk) ld4 r17=[r17] // M0|1 r17 = cpu_data->phys_stacked_size_p8
mov r19=ar.bsp // M2 get new backing store pointer
mov f10=f0 // F clear f10
@@ -953,9 +952,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
shr.u r18=r19,16 // get byte size of existing "dirty" partition
;;
mov r16=ar.bsp // get existing backing store pointer
- addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0
- ;;
- ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8
+ LOAD_PHYS_STACK_REG_SIZE(r17)
(pKStk) br.cond.dpnt skip_rbs_switch
/*
diff --git a/arch/ia64/kernel/err_inject.c b/arch/ia64/kernel/err_inject.c
new file mode 100644
index 0000000..d3e9f33
--- /dev/null
+++ b/arch/ia64/kernel/err_inject.c
@@ -0,0 +1,293 @@
+/*
+ * err_inject.c -
+ * 1.) Inject errors to a processor.
+ * 2.) Query error injection capabilities.
+ * This driver along with user space code can be acting as an error
+ * injection tool.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Written by: Fenghua Yu <fenghua.yu@intel.com>, Intel Corporation
+ * Copyright (C) 2006, Intel Corp. All rights reserved.
+ *
+ */
+#include <linux/sysdev.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/cpu.h>
+#include <linux/module.h>
+
+#define ERR_INJ_DEBUG
+
+#define ERR_DATA_BUFFER_SIZE 3 // Three 8-byte;
+
+#define define_one_ro(name) \
+static SYSDEV_ATTR(name, 0444, show_##name, NULL)
+
+#define define_one_rw(name) \
+static SYSDEV_ATTR(name, 0644, show_##name, store_##name)
+
+static u64 call_start[NR_CPUS];
+static u64 phys_addr[NR_CPUS];
+static u64 err_type_info[NR_CPUS];
+static u64 err_struct_info[NR_CPUS];
+static struct {
+ u64 data1;
+ u64 data2;
+ u64 data3;
+} __attribute__((__aligned__(16))) err_data_buffer[NR_CPUS];
+static s64 status[NR_CPUS];
+static u64 capabilities[NR_CPUS];
+static u64 resources[NR_CPUS];
+
+#define show(name) \
+static ssize_t \
+show_##name(struct sys_device *dev, char *buf) \
+{ \
+ u32 cpu=dev->id; \
+ return sprintf(buf, "%lx\n", name[cpu]); \
+}
+
+#define store(name) \
+static ssize_t \
+store_##name(struct sys_device *dev, const char *buf, size_t size) \
+{ \
+ unsigned int cpu=dev->id; \
+ name[cpu] = simple_strtoull(buf, NULL, 16); \
+ return size; \
+}
+
+show(call_start)
+
+/* It's user's responsibility to call the PAL procedure on a specific
+ * processor. The cpu number in driver is only used for storing data.
+ */
+static ssize_t
+store_call_start(struct sys_device *dev, const char *buf, size_t size)
+{
+ unsigned int cpu=dev->id;
+ unsigned long call_start = simple_strtoull(buf, NULL, 16);
+
+#ifdef ERR_INJ_DEBUG
+ printk(KERN_DEBUG "pal_mc_err_inject for cpu%d:\n", cpu);
+ printk(KERN_DEBUG "err_type_info=%lx,\n", err_type_info[cpu]);
+ printk(KERN_DEBUG "err_struct_info=%lx,\n", err_struct_info[cpu]);
+ printk(KERN_DEBUG "err_data_buffer=%lx, %lx, %lx.\n",
+ err_data_buffer[cpu].data1,
+ err_data_buffer[cpu].data2,
+ err_data_buffer[cpu].data3);
+#endif
+ switch (call_start) {
+ case 0: /* Do nothing. */
+ break;
+ case 1: /* Call pal_mc_error_inject in physical mode. */
+ status[cpu]=ia64_pal_mc_error_inject_phys(err_type_info[cpu],
+ err_struct_info[cpu],
+ ia64_tpa(&err_data_buffer[cpu]),
+ &capabilities[cpu],
+ &resources[cpu]);
+ break;
+ case 2: /* Call pal_mc_error_inject in virtual mode. */
+ status[cpu]=ia64_pal_mc_error_inject_virt(err_type_info[cpu],
+ err_struct_info[cpu],
+ ia64_tpa(&err_data_buffer[cpu]),
+ &capabilities[cpu],
+ &resources[cpu]);
+ break;
+ default:
+ status[cpu] = -EINVAL;
+ break;
+ }
+
+#ifdef ERR_INJ_DEBUG
+ printk(KERN_DEBUG "Returns: status=%d,\n", (int)status[cpu]);
+ printk(KERN_DEBUG "capapbilities=%lx,\n", capabilities[cpu]);
+ printk(KERN_DEBUG "resources=%lx\n", resources[cpu]);
+#endif
+ return size;
+}
+
+show(err_type_info)
+store(err_type_info)
+
+static ssize_t
+show_virtual_to_phys(struct sys_device *dev, char *buf)
+{
+ unsigned int cpu=dev->id;
+ return sprintf(buf, "%lx\n", phys_addr[cpu]);
+}
+
+static ssize_t
+store_virtual_to_phys(struct sys_device *dev, const char *buf, size_t size)
+{
+ unsigned int cpu=dev->id;
+ u64 virt_addr=simple_strtoull(buf, NULL, 16);
+ int ret;
+
+ ret = get_user_pages(current, current->mm, virt_addr,
+ 1, VM_READ, 0, NULL, NULL);
+ if (ret<=0) {
+#ifdef ERR_INJ_DEBUG
+ printk("Virtual address %lx is not existing.\n",virt_addr);
+#endif
+ return -EINVAL;
+ }
+
+ phys_addr[cpu] = ia64_tpa(virt_addr);
+ return size;
+}
+
+show(err_struct_info)
+store(err_struct_info)
+
+static ssize_t
+show_err_data_buffer(struct sys_device *dev, char *buf)
+{
+ unsigned int cpu=dev->id;
+
+ return sprintf(buf, "%lx, %lx, %lx\n",
+ err_data_buffer[cpu].data1,
+ err_data_buffer[cpu].data2,
+ err_data_buffer[cpu].data3);
+}
+
+static ssize_t
+store_err_data_buffer(struct sys_device *dev, const char *buf, size_t size)
+{
+ unsigned int cpu=dev->id;
+ int ret;
+
+#ifdef ERR_INJ_DEBUG
+ printk("write err_data_buffer=[%lx,%lx,%lx] on cpu%d\n",
+ err_data_buffer[cpu].data1,
+ err_data_buffer[cpu].data2,
+ err_data_buffer[cpu].data3,
+ cpu);
+#endif
+ ret=sscanf(buf, "%lx, %lx, %lx",
+ &err_data_buffer[cpu].data1,
+ &err_data_buffer[cpu].data2,
+ &err_data_buffer[cpu].data3);
+ if (ret!=ERR_DATA_BUFFER_SIZE)
+ return -EINVAL;
+
+ return size;
+}
+
+show(status)
+show(capabilities)
+show(resources)
+
+define_one_rw(call_start);
+define_one_rw(err_type_info);
+define_one_rw(err_struct_info);
+define_one_rw(err_data_buffer);
+define_one_rw(virtual_to_phys);
+define_one_ro(status);
+define_one_ro(capabilities);
+define_one_ro(resources);
+
+static struct attribute *default_attrs[] = {
+ &attr_call_start.attr,
+ &attr_virtual_to_phys.attr,
+ &attr_err_type_info.attr,
+ &attr_err_struct_info.attr,
+ &attr_err_data_buffer.attr,
+ &attr_status.attr,
+ &attr_capabilities.attr,
+ &attr_resources.attr,
+ NULL
+};
+
+static struct attribute_group err_inject_attr_group = {
+ .attrs = default_attrs,
+ .name = "err_inject"
+};
+/* Add/Remove err_inject interface for CPU device */
+static int __cpuinit err_inject_add_dev(struct sys_device * sys_dev)
+{
+ return sysfs_create_group(&sys_dev->kobj, &err_inject_attr_group);
+}
+
+static int __cpuinit err_inject_remove_dev(struct sys_device * sys_dev)
+{
+ sysfs_remove_group(&sys_dev->kobj, &err_inject_attr_group);
+ return 0;
+}
+static int __cpuinit err_inject_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+ struct sys_device *sys_dev;
+
+ sys_dev = get_cpu_sysdev(cpu);
+ switch (action) {
+ case CPU_ONLINE:
+ err_inject_add_dev(sys_dev);
+ break;
+ case CPU_DEAD:
+ err_inject_remove_dev(sys_dev);
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata err_inject_cpu_notifier =
+{
+ .notifier_call = err_inject_cpu_callback,
+};
+
+static int __init
+err_inject_init(void)
+{
+ int i;
+
+#ifdef ERR_INJ_DEBUG
+ printk(KERN_INFO "Enter error injection driver.\n");
+#endif
+ for_each_online_cpu(i) {
+ err_inject_cpu_callback(&err_inject_cpu_notifier, CPU_ONLINE,
+ (void *)(long)i);
+ }
+
+ register_hotcpu_notifier(&err_inject_cpu_notifier);
+
+ return 0;
+}
+
+static void __exit
+err_inject_exit(void)
+{
+ int i;
+ struct sys_device *sys_dev;
+
+#ifdef ERR_INJ_DEBUG
+ printk(KERN_INFO "Exit error injection driver.\n");
+#endif
+ for_each_online_cpu(i) {
+ sys_dev = get_cpu_sysdev(i);
+ sysfs_remove_group(&sys_dev->kobj, &err_inject_attr_group);
+ }
+ unregister_hotcpu_notifier(&err_inject_cpu_notifier);
+}
+
+module_init(err_inject_init);
+module_exit(err_inject_exit);
+
+MODULE_AUTHOR("Fenghua Yu <fenghua.yu@intel.com>");
+MODULE_DESCRIPTION("MC error injection kenrel sysfs interface");
+MODULE_LICENSE("GPL");
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index dcfbf3e..93d9ab1 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -87,7 +87,6 @@
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/bootmem.h>
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 456f57b..1c5044a 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -27,7 +27,6 @@
#include <linux/random.h> /* for rand_initialize_irq() */
#include <linux/signal.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/threads.h>
#include <linux/bitops.h>
#include <linux/irq.h>
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
index 6b7fcbd..34f44d8 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -374,6 +374,7 @@ ENTRY(alt_dtlb_miss)
movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
mov r21=cr.ipsr
mov r31=pr
+ mov r24=PERCPU_ADDR
;;
#ifdef CONFIG_DISABLE_VHPT
shr.u r22=r16,61 // get the region number into r21
@@ -386,22 +387,30 @@ ENTRY(alt_dtlb_miss)
(p8) mov r29=b0 // save b0
(p8) br.cond.dptk dtlb_fault
#endif
+ cmp.ge p10,p11=r16,r24 // access to per_cpu_data?
+ tbit.z p12,p0=r16,61 // access to region 6?
+ mov r25=PERCPU_PAGE_SHIFT << 2
+ mov r26=PERCPU_PAGE_SIZE
+ nop.m 0
+ nop.b 0
+ ;;
+(p10) mov r19=IA64_KR(PER_CPU_DATA)
+(p11) and r19=r19,r16 // clear non-ppn fields
extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl
and r22=IA64_ISR_CODE_MASK,r20 // get the isr.code field
tbit.nz p6,p7=r20,IA64_ISR_SP_BIT // is speculation bit on?
- shr.u r18=r16,57 // move address bit 61 to bit 4
- and r19=r19,r16 // clear ed, reserved bits, and PTE control bits
tbit.nz p9,p0=r20,IA64_ISR_NA_BIT // is non-access bit on?
;;
- andcm r18=0x10,r18 // bit 4=~address-bit(61)
+(p10) sub r19=r19,r26
+(p10) mov cr.itir=r25
cmp.ne p8,p0=r0,r23
(p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22 // check isr.code field
+(p12) dep r17=-1,r17,4,1 // set ma=UC for region 6 addr
(p8) br.cond.spnt page_fault
dep r21=-1,r21,IA64_PSR_ED_BIT,1
- or r19=r19,r17 // insert PTE control bits into r19
;;
- or r19=r19,r18 // set bit 4 (uncached) if the access was to region 6
+ or r19=r19,r17 // insert PTE control bits into r19
(p6) mov cr.ipsr=r21
;;
(p7) itc.d r19 // insert the TLB entry
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 6cb56dd..4f5fd09 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -29,9 +29,9 @@
#include <linux/slab.h>
#include <linux/preempt.h>
#include <linux/moduleloader.h>
+#include <linux/kdebug.h>
#include <asm/pgtable.h>
-#include <asm/kdebug.h>
#include <asm/sections.h>
#include <asm/uaccess.h>
@@ -444,7 +444,8 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
break;
}
- BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
+ kretprobe_assert(ri, orig_ret_address, trampoline_address);
+
regs->cr_iip = orig_ret_address;
reset_current_kprobe();
@@ -464,23 +465,13 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
- struct kretprobe_instance *ri;
-
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *)regs->b0;
-
- /* Replace the return addr with trampoline addr */
- regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip;
+ ri->ret_addr = (kprobe_opcode_t *)regs->b0;
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ /* Replace the return addr with trampoline addr */
+ regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip;
}
int __kprobes arch_prepare_kprobe(struct kprobe *p)
@@ -1021,3 +1012,12 @@ int __init arch_init_kprobes(void)
(kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip;
return register_kprobe(&trampoline_p);
}
+
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+ if (p->addr ==
+ (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip)
+ return 1;
+
+ return 0;
+}
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 491687f..1d7cc7e 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -63,7 +63,6 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
-#include <linux/smp_lock.h>
#include <linux/bootmem.h>
#include <linux/acpi.h>
#include <linux/timer.h>
@@ -72,9 +71,9 @@
#include <linux/smp.h>
#include <linux/workqueue.h>
#include <linux/cpumask.h>
+#include <linux/kdebug.h>
#include <asm/delay.h>
-#include <asm/kdebug.h>
#include <asm/machvec.h>
#include <asm/meminit.h>
#include <asm/page.h>
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S
index c6b607c..8c9c26a 100644
--- a/arch/ia64/kernel/mca_asm.S
+++ b/arch/ia64/kernel/mca_asm.S
@@ -101,14 +101,6 @@ ia64_do_tlb_purge:
;;
srlz.d
;;
- // 2. Purge DTR for PERCPU data.
- movl r16=PERCPU_ADDR
- mov r18=PERCPU_PAGE_SHIFT<<2
- ;;
- ptr.d r16,r18
- ;;
- srlz.d
- ;;
// 3. Purge ITR for PAL code.
GET_THIS_PADDR(r2, ia64_mca_pal_base)
;;
@@ -196,22 +188,6 @@ ia64_reload_tr:
srlz.i
srlz.d
;;
- // 2. Reload DTR register for PERCPU data.
- GET_THIS_PADDR(r2, ia64_mca_per_cpu_pte)
- ;;
- movl r16=PERCPU_ADDR // vaddr
- movl r18=PERCPU_PAGE_SHIFT<<2
- ;;
- mov cr.itir=r18
- mov cr.ifa=r16
- ;;
- ld8 r18=[r2] // load per-CPU PTE
- mov r16=IA64_TR_PERCPU_DATA;
- ;;
- itr.d dtr[r16]=r18
- ;;
- srlz.d
- ;;
// 3. Reload ITR for PAL code.
GET_THIS_PADDR(r2, ia64_mca_pal_pte)
;;
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index 832cf1e..70b8bdb 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -14,7 +14,6 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kallsyms.h>
-#include <linux/smp_lock.h>
#include <linux/bootmem.h>
#include <linux/acpi.h>
#include <linux/timer.h>
diff --git a/arch/ia64/kernel/patch.c b/arch/ia64/kernel/patch.c
index bc11bb0..e796e29 100644
--- a/arch/ia64/kernel/patch.c
+++ b/arch/ia64/kernel/patch.c
@@ -195,3 +195,23 @@ ia64_patch_gate (void)
ia64_patch_vtop(START(vtop), END(vtop));
ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9));
}
+
+void ia64_patch_phys_stack_reg(unsigned long val)
+{
+ s32 * offp = (s32 *) __start___phys_stack_reg_patchlist;
+ s32 * end = (s32 *) __end___phys_stack_reg_patchlist;
+ u64 ip, mask, imm;
+
+ /* see instruction format A4: adds r1 = imm13, r3 */
+ mask = (0x3fUL << 27) | (0x7f << 13);
+ imm = (((val >> 7) & 0x3f) << 27) | (val & 0x7f) << 13;
+
+ while (offp < end) {
+ ip = (u64) offp + *offp;
+ ia64_patch(ip, mask, imm);
+ ia64_fc(ip);
+ ++offp;
+ }
+ ia64_sync_i();
+ ia64_srlz_i();
+}
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index abc7ad0..e7191ca 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -23,7 +23,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index ae96d41..8bb571a 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -20,20 +20,19 @@
#include <linux/personality.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/thread_info.h>
#include <linux/unistd.h>
#include <linux/efi.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/kdebug.h>
#include <asm/cpu.h>
#include <asm/delay.h>
#include <asm/elf.h>
#include <asm/ia32.h>
#include <asm/irq.h>
-#include <asm/kdebug.h>
#include <asm/kexec.h>
#include <asm/pgalloc.h>
#include <asm/processor.h>
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c
index af9f875..a51f1d0 100644
--- a/arch/ia64/kernel/salinfo.c
+++ b/arch/ia64/kernel/salinfo.c
@@ -42,7 +42,6 @@
#include <linux/proc_fs.h>
#include <linux/module.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/vmalloc.h>
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index dc7dd76..6e19da1 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -75,7 +75,6 @@ extern void ia64_setup_printk_clock(void);
DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
DEFINE_PER_CPU(unsigned long, local_per_cpu_offset);
-DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8);
unsigned long ia64_cycles_per_usec;
struct ia64_boot_param *ia64_boot_param;
struct screen_info screen_info;
@@ -869,6 +868,7 @@ void __cpuinit
cpu_init (void)
{
extern void __cpuinit ia64_mmu_init (void *);
+ static unsigned long max_num_phys_stacked = IA64_NUM_PHYS_STACK_REG;
unsigned long num_phys_stacked;
pal_vm_info_2_u_t vmi;
unsigned int max_ctx;
@@ -982,7 +982,10 @@ cpu_init (void)
num_phys_stacked = 96;
}
/* size of physical stacked register partition plus 8 bytes: */
- __get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8;
+ if (num_phys_stacked > max_num_phys_stacked) {
+ ia64_patch_phys_stack_reg(num_phys_stacked*8 + 8);
+ max_num_phys_stacked = num_phys_stacked;
+ }
platform_cpu_init();
pm_idle = default_idle;
}
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 77f8b49..0dcd56da 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index ff7df43..a44792d 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -35,7 +35,6 @@
#include <linux/mm.h>
#include <linux/notifier.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/efi.h>
#include <linux/percpu.h>
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
index 9ef62a3..1eda194 100644
--- a/arch/ia64/kernel/sys_ia64.c
+++ b/arch/ia64/kernel/sys_ia64.c
@@ -13,7 +13,6 @@
#include <linux/shm.h>
#include <linux/file.h> /* doh, must come after sched.h... */
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/highuid.h>
#include <linux/hugetlb.h>
@@ -33,6 +32,13 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len
if (len > RGN_MAP_LIMIT)
return -ENOMEM;
+ /* handle fixed mapping: prevent overlap with huge pages */
+ if (flags & MAP_FIXED) {
+ if (is_hugepage_only_range(mm, addr, len))
+ return -EINVAL;
+ return addr;
+ }
+
#ifdef CONFIG_HUGETLB_PAGE
if (REGION_NUMBER(addr) == RGN_HPAGE)
addr = 0;
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 39e0cd3..a06667c 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -235,7 +235,7 @@ ia64_init_itm (void)
static struct irqaction timer_irqaction = {
.handler = timer_interrupt,
- .flags = IRQF_DISABLED,
+ .flags = IRQF_DISABLED | IRQF_IRQPOLL,
.name = "timer"
};
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index 765cbe5..5bfb8be 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -16,33 +16,17 @@
#include <linux/hardirq.h>
#include <linux/kprobes.h>
#include <linux/delay.h> /* for ssleep() */
+#include <linux/kdebug.h>
#include <asm/fpswa.h>
#include <asm/ia32.h>
#include <asm/intrinsics.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
-#include <asm/kdebug.h>
fpswa_interface_t *fpswa_interface;
EXPORT_SYMBOL(fpswa_interface);
-ATOMIC_NOTIFIER_HEAD(ia64die_chain);
-
-int
-register_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_register(&ia64die_chain, nb);
-}
-EXPORT_SYMBOL_GPL(register_die_notifier);
-
-int
-unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&ia64die_chain, nb);
-}
-EXPORT_SYMBOL_GPL(unregister_die_notifier);
-
void __init
trap_init (void)
{
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index 1e35755..fe6aa5a 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -15,7 +15,6 @@
*/
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/tty.h>
#include <asm/intrinsics.h>
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 25dd55e..6923826 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -78,6 +78,13 @@ SECTIONS
__stop___mca_table = .;
}
+ .data.patch.phys_stack_reg : AT(ADDR(.data.patch.phys_stack_reg) - LOAD_OFFSET)
+ {
+ __start___phys_stack_reg_patchlist = .;
+ *(.data.patch.phys_stack_reg)
+ __end___phys_stack_reg_patchlist = .;
+ }
+
/* Global data */
_data = .;
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 872da7a..9484444 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -693,6 +693,7 @@ void __init paging_init(void)
zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
}
+#ifdef CONFIG_MEMORY_HOTPLUG
pg_data_t *arch_alloc_nodedata(int nid)
{
unsigned long size = compute_pernodesize(nid);
@@ -710,3 +711,4 @@ void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat)
pgdat_list[update_node] = update_pgdat;
scatter_node_data();
}
+#endif
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 59f3ab9..21658e0 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -7,15 +7,14 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kprobes.h>
+#include <linux/kdebug.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/uaccess.h>
-#include <asm/kdebug.h>
extern void die (char *, struct pt_regs *, long);
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
index 0c7e94e..1346b7f 100644
--- a/arch/ia64/mm/hugetlbpage.c
+++ b/arch/ia64/mm/hugetlbpage.c
@@ -13,7 +13,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
#include <asm/mman.h>
@@ -148,6 +147,14 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, u
return -ENOMEM;
if (len & ~HPAGE_MASK)
return -EINVAL;
+
+ /* Handle MAP_FIXED */
+ if (flags & MAP_FIXED) {
+ if (prepare_hugepage_range(addr, len, pgoff))
+ return -EINVAL;
+ return addr;
+ }
+
/* This code assumes that RGN_HPAGE != 0. */
if ((REGION_NUMBER(addr) != RGN_HPAGE) || (addr & (HPAGE_SIZE - 1)))
addr = HPAGE_REGION_BASE;
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 4f36987..cffb1e8 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -121,7 +121,7 @@ lazy_mmu_prot_update (pte_t pte)
return; /* i-cache is already coherent with d-cache */
if (PageCompound(page)) {
- order = (unsigned long) (page[1].lru.prev);
+ order = compound_order(page);
flush_icache_range(addr, addr + (1UL << order << PAGE_SHIFT));
}
else
@@ -355,7 +355,7 @@ setup_gate (void)
void __devinit
ia64_mmu_init (void *my_cpu_data)
{
- unsigned long psr, pta, impl_va_bits;
+ unsigned long pta, impl_va_bits;
extern void __devinit tlb_init (void);
#ifdef CONFIG_DISABLE_VHPT
@@ -364,15 +364,6 @@ ia64_mmu_init (void *my_cpu_data)
# define VHPT_ENABLE_BIT 1
#endif
- /* Pin mapping for percpu area into TLB */
- psr = ia64_clear_ic();
- ia64_itr(0x2, IA64_TR_PERCPU_DATA, PERCPU_ADDR,
- pte_val(pfn_pte(__pa(my_cpu_data) >> PAGE_SHIFT, PAGE_KERNEL)),
- PERCPU_PAGE_SHIFT);
-
- ia64_set_psr(psr);
- ia64_srlz_i();
-
/*
* Check if the virtually mapped linear page table (VMLPT) overlaps with a mapped
* address space. The IA-64 architecture guarantees that at least 50 bits of
diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c
index 4280c07..2a14062 100644
--- a/arch/ia64/mm/ioremap.c
+++ b/arch/ia64/mm/ioremap.c
@@ -1,5 +1,5 @@
/*
- * (c) Copyright 2006 Hewlett-Packard Development Company, L.P.
+ * (c) Copyright 2006, 2007 Hewlett-Packard Development Company, L.P.
* Bjorn Helgaas <bjorn.helgaas@hp.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -10,51 +10,101 @@
#include <linux/compiler.h>
#include <linux/module.h>
#include <linux/efi.h>
+#include <linux/io.h>
+#include <linux/vmalloc.h>
#include <asm/io.h>
#include <asm/meminit.h>
static inline void __iomem *
-__ioremap (unsigned long offset, unsigned long size)
+__ioremap (unsigned long phys_addr)
{
- return (void __iomem *) (__IA64_UNCACHED_OFFSET | offset);
+ return (void __iomem *) (__IA64_UNCACHED_OFFSET | phys_addr);
}
void __iomem *
-ioremap (unsigned long offset, unsigned long size)
+ioremap (unsigned long phys_addr, unsigned long size)
{
+ void __iomem *addr;
+ struct vm_struct *area;
+ unsigned long offset;
+ pgprot_t prot;
u64 attr;
unsigned long gran_base, gran_size;
+ unsigned long page_base;
/*
* For things in kern_memmap, we must use the same attribute
* as the rest of the kernel. For more details, see
* Documentation/ia64/aliasing.txt.
*/
- attr = kern_mem_attribute(offset, size);
+ attr = kern_mem_attribute(phys_addr, size);
if (attr & EFI_MEMORY_WB)
- return (void __iomem *) phys_to_virt(offset);
+ return (void __iomem *) phys_to_virt(phys_addr);
else if (attr & EFI_MEMORY_UC)
- return __ioremap(offset, size);
+ return __ioremap(phys_addr);
/*
* Some chipsets don't support UC access to memory. If
* WB is supported for the whole granule, we prefer that.
*/
- gran_base = GRANULEROUNDDOWN(offset);
- gran_size = GRANULEROUNDUP(offset + size) - gran_base;
+ gran_base = GRANULEROUNDDOWN(phys_addr);
+ gran_size = GRANULEROUNDUP(phys_addr + size) - gran_base;
if (efi_mem_attribute(gran_base, gran_size) & EFI_MEMORY_WB)
- return (void __iomem *) phys_to_virt(offset);
+ return (void __iomem *) phys_to_virt(phys_addr);
- return __ioremap(offset, size);
+ /*
+ * WB is not supported for the whole granule, so we can't use
+ * the region 7 identity mapping. If we can safely cover the
+ * area with kernel page table mappings, we can use those
+ * instead.
+ */
+ page_base = phys_addr & PAGE_MASK;
+ size = PAGE_ALIGN(phys_addr + size) - page_base;
+ if (efi_mem_attribute(page_base, size) & EFI_MEMORY_WB) {
+ prot = PAGE_KERNEL;
+
+ /*
+ * Mappings have to be page-aligned
+ */
+ offset = phys_addr & ~PAGE_MASK;
+ phys_addr &= PAGE_MASK;
+
+ /*
+ * Ok, go for it..
+ */
+ area = get_vm_area(size, VM_IOREMAP);
+ if (!area)
+ return NULL;
+
+ area->phys_addr = phys_addr;
+ addr = (void __iomem *) area->addr;
+ if (ioremap_page_range((unsigned long) addr,
+ (unsigned long) addr + size, phys_addr, prot)) {
+ vunmap((void __force *) addr);
+ return NULL;
+ }
+
+ return (void __iomem *) (offset + (char __iomem *)addr);
+ }
+
+ return __ioremap(phys_addr);
}
EXPORT_SYMBOL(ioremap);
void __iomem *
-ioremap_nocache (unsigned long offset, unsigned long size)
+ioremap_nocache (unsigned long phys_addr, unsigned long size)
{
- if (kern_mem_attribute(offset, size) & EFI_MEMORY_WB)
+ if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB)
return NULL;
- return __ioremap(offset, size);
+ return __ioremap(phys_addr);
}
EXPORT_SYMBOL(ioremap_nocache);
+
+void
+iounmap (volatile void __iomem *addr)
+{
+ if (REGION_NUMBER(addr) == RGN_GATE)
+ vunmap((void *) ((unsigned long) addr & PAGE_MASK));
+}
+EXPORT_SYMBOL(iounmap);
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 0e83f3b..3549f3b 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -18,7 +18,6 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <asm/machvec.h>
@@ -659,8 +658,6 @@ pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma)
return -EINVAL;
prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size,
vma->vm_page_prot);
- if (pgprot_val(prot) != pgprot_val(pgprot_noncached(vma->vm_page_prot)))
- return -EINVAL;
addr = pci_get_legacy_mem(bus);
if (IS_ERR(addr))
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index 68355ef..e336e16 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -55,9 +55,9 @@
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/completion.h>
+#include <linux/kdebug.h>
#include <asm/sn/intr.h>
#include <asm/sn/sn_sal.h>
-#include <asm/kdebug.h>
#include <asm/uaccess.h>
#include <asm/sn/xpc.h>
@@ -1332,7 +1332,7 @@ xpc_init(void)
dev_warn(xpc_part, "can't register reboot notifier\n");
}
- /* add ourselves to the die_notifier list (i.e., ia64die_chain) */
+ /* add ourselves to the die_notifier list */
ret = register_die_notifier(&xpc_die_notifier);
if (ret != 0) {
dev_warn(xpc_part, "can't register die notifier\n");
diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c
index 8cbbb0b..41a4c95 100644
--- a/arch/m32r/kernel/m32r_ksyms.c
+++ b/arch/m32r/kernel/m32r_ksyms.c
@@ -5,7 +5,6 @@
#include <linux/sched.h>
#include <linux/in6.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/string.h>
#include <asm/semaphore.h>
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index 4b15605..916faf6 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -13,7 +13,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index 48d376f..3eb3059 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -43,7 +43,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/irq.h>
#include <linux/bootmem.h>
#include <linux/delay.h>
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c
index b4e7bcb..bda8554 100644
--- a/arch/m32r/kernel/sys_m32r.c
+++ b/arch/m32r/kernel/sys_m32r.c
@@ -11,7 +11,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/m32r/mm/fault-nommu.c b/arch/m32r/mm/fault-nommu.c
index 9880aba..8846917 100644
--- a/arch/m32r/mm/fault-nommu.c
+++ b/arch/m32r/mm/fault-nommu.c
@@ -17,7 +17,6 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/vt_kern.h> /* For unblank_screen() */
diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c
index 037d58e..f3935ba 100644
--- a/arch/m32r/mm/fault.c
+++ b/arch/m32r/mm/fault.c
@@ -18,7 +18,6 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/tty.h>
diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c
index 28d95cf..907a553 100644
--- a/arch/m68k/amiga/amiints.c
+++ b/arch/m68k/amiga/amiints.c
@@ -54,7 +54,7 @@ static irqreturn_t ami_int5(int irq, void *dev_id);
static struct irq_controller amiga_irq_controller = {
.name = "amiga",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(amiga_irq_controller.lock),
.enable = amiga_enable_irq,
.disable = amiga_disable_irq,
};
diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c
index 7a20058..c4a4ffd 100644
--- a/arch/m68k/amiga/cia.c
+++ b/arch/m68k/amiga/cia.c
@@ -123,7 +123,7 @@ static void cia_disable_irq(unsigned int irq)
static struct irq_controller cia_irq_controller = {
.name = "cia",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(cia_irq_controller.lock),
.enable = cia_enable_irq,
.disable = cia_disable_irq,
};
@@ -160,7 +160,7 @@ static void auto_disable_irq(unsigned int irq)
static struct irq_controller auto_irq_controller = {
.name = "auto",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock),
.enable = auto_enable_irq,
.disable = auto_disable_irq,
};
diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c
index 4274af1..13bd41be 100644
--- a/arch/m68k/apollo/dn_ints.c
+++ b/arch/m68k/apollo/dn_ints.c
@@ -31,7 +31,7 @@ void apollo_irq_shutdown(unsigned int irq)
static struct irq_controller apollo_irq_controller = {
.name = "apollo",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(apollo_irq_controller.lock),
.startup = apollo_irq_startup,
.shutdown = apollo_irq_shutdown,
};
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index 7f81264..b85ca22 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -339,7 +339,7 @@ static void atari_shutdown_irq(unsigned int irq)
static struct irq_controller atari_irq_controller = {
.name = "atari",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(atari_irq_controller.lock),
.startup = atari_startup_irq,
.shutdown = atari_shutdown_irq,
.enable = atari_enable_irq,
diff --git a/arch/m68k/atari/atasound.h b/arch/m68k/atari/atasound.h
deleted file mode 100644
index 1362762..0000000
--- a/arch/m68k/atari/atasound.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Minor numbers for the sound driver.
- *
- * Unfortunately Creative called the codec chip of SB as a DSP. For this
- * reason the /dev/dsp is reserved for digitized audio use. There is a
- * device for true DSP processors but it will be called something else.
- * In v3.0 it's /dev/sndproc but this could be a temporary solution.
- */
-
-#define SND_NDEVS 256 /* Number of supported devices */
-#define SND_DEV_CTL 0 /* Control port /dev/mixer */
-#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM
- synthesizer and MIDI output) */
-#define SND_DEV_MIDIN 2 /* Raw midi access */
-#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */
-#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */
-#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */
-#define SND_DEV_STATUS 6 /* /dev/sndstat */
-/* #7 not in use now. Was in 2.4. Free for use after v3.0. */
-#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */
-#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */
-#define SND_DEV_PSS SND_DEV_SNDPROC
-
-#define DSP_DEFAULT_SPEED 8000
-
-#define ON 1
-#define OFF 0
-
-#define MAX_AUDIO_DEV 5
-#define MAX_MIXER_DEV 2
-#define MAX_SYNTH_DEV 3
-#define MAX_MIDI_DEV 6
-#define MAX_TIMER_DEV 3
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
index b66c97c..60d4d75 100644
--- a/arch/m68k/kernel/ints.c
+++ b/arch/m68k/kernel/ints.c
@@ -59,14 +59,14 @@ static int m68k_first_user_vec;
static struct irq_controller auto_irq_controller = {
.name = "auto",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock),
.startup = m68k_irq_startup,
.shutdown = m68k_irq_shutdown,
};
static struct irq_controller user_irq_controller = {
.name = "user",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(user_irq_controller.lock),
.startup = m68k_irq_startup,
.shutdown = m68k_irq_shutdown,
};
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index 7fd2720..cdba9fd 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
index f6fcd75..0fc72d8 100644
--- a/arch/m68k/mac/macints.c
+++ b/arch/m68k/mac/macints.c
@@ -219,7 +219,7 @@ static void mac_disable_irq(unsigned int irq);
static struct irq_controller mac_irq_controller = {
.name = "mac",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(mac_irq_controller.lock),
.enable = mac_enable_irq,
.disable = mac_disable_irq,
};
diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c
index 272d47e..e341387 100644
--- a/arch/m68k/mvme16x/rtc.c
+++ b/arch/m68k/mvme16x/rtc.c
@@ -16,7 +16,6 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/mc146818rtc.h> /* For struct rtc_time and ioctls, etc */
-#include <linux/smp_lock.h>
#include <linux/bcd.h>
#include <asm/mvme16xhw.h>
diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c
index 31cc07d..2fb25ae 100644
--- a/arch/m68k/q40/q40ints.c
+++ b/arch/m68k/q40/q40ints.c
@@ -59,7 +59,7 @@ static void q40_irq_shutdown(unsigned int irq)
static struct irq_controller q40_irq_controller = {
.name = "q40",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(q40_irq_controller.lock),
.startup = q40_irq_startup,
.shutdown = q40_irq_shutdown,
.enable = q40_enable_irq,
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index 4232a2c..50df34b 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -90,7 +90,7 @@ static void sun3_inthandle(unsigned int irq, struct pt_regs *fp)
static struct irq_controller sun3_irq_controller = {
.name = "sun3",
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(sun3_irq_controller.lock),
.startup = m68k_irq_startup,
.shutdown = m68k_irq_shutdown,
.enable = sun3_enable_irq,
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index 72d3496..f54b6a3 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c
index 3265b2d..48e6b33 100644
--- a/arch/m68knommu/kernel/sys_m68k.c
+++ b/arch/m68knommu/kernel/sys_m68k.c
@@ -10,7 +10,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 130d825..b7cb048 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -784,7 +784,6 @@ config TOSHIBA_RBTX4927
select HAS_TXX9_SERIAL
select HW_HAS_PCI
select I8259
- select ISA
select SWAP_IO_SPACE
select SYS_HAS_CPU_TX49XX
select SYS_SUPPORTS_32BIT_KERNEL
@@ -806,7 +805,6 @@ config TOSHIBA_RBTX4938
select HAS_TXX9_SERIAL
select HW_HAS_PCI
select I8259
- select ISA
select SWAP_IO_SPACE
select SYS_HAS_CPU_TX49XX
select SYS_SUPPORTS_32BIT_KERNEL
@@ -1042,6 +1040,9 @@ config SOC_AU1X00
select SYS_SUPPORTS_APM_EMULATION
select SYS_SUPPORTS_KGDB
+config SERIAL_RM9000
+ bool
+
config PNX8550
bool
select SOC_PNX8550
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index 29e0df9..7d0f217 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -245,7 +245,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
#
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
-CONFIG_ISA=y
CONFIG_MMU=y
#
@@ -573,7 +572,6 @@ CONFIG_MTD_CFI_UTIL=y
#
# Plug and Play support
#
-# CONFIG_PNP is not set
# CONFIG_PNPACPI is not set
#
@@ -658,7 +656,6 @@ CONFIG_BLK_DEV_IT8213=m
# CONFIG_BLK_DEV_VIA82CXXX is not set
CONFIG_BLK_DEV_TC86C001=m
# CONFIG_IDE_ARM is not set
-# CONFIG_IDE_CHIPSETS is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
# CONFIG_IDEDMA_AUTO is not set
@@ -677,11 +674,6 @@ CONFIG_RAID_ATTRS=m
# CONFIG_ATA is not set
#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
@@ -742,37 +734,20 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_DM9000 is not set
-# CONFIG_NET_VENDOR_RACAL is not set
#
# Tulip family network device support
#
# CONFIG_NET_TULIP is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
# CONFIG_HP100 is not set
-CONFIG_NET_ISA=y
-# CONFIG_E2100 is not set
-# CONFIG_EWRK3 is not set
-# CONFIG_EEXPRESS is not set
-# CONFIG_EEXPRESS_PRO is not set
-# CONFIG_HPLAN_PLUS is not set
-# CONFIG_HPLAN is not set
-# CONFIG_LP486E is not set
-# CONFIG_ETH16I is not set
CONFIG_NE2000=y
-# CONFIG_SEEQ8005 is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
-# CONFIG_CS89x0 is not set
# CONFIG_DGRS is not set
# CONFIG_EEPRO100 is not set
# CONFIG_E100 is not set
@@ -833,8 +808,6 @@ CONFIG_NET_RADIO=y
# Obsolete Wireless cards support (pre-802.11)
#
# CONFIG_STRIP is not set
-# CONFIG_ARLAN is not set
-# CONFIG_WAVELAN is not set
#
# Wireless 802.11b ISA/PCI cards support
@@ -920,9 +893,6 @@ CONFIG_KEYBOARD_ATKBD=y
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
@@ -1072,7 +1042,6 @@ CONFIG_FB_ATY_CT=y
#
CONFIG_VGA_CONSOLE=y
# CONFIG_VGACON_SOFT_SCROLLBACK is not set
-# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE is not set
diff --git a/arch/mips/kernel/early_printk.c b/arch/mips/kernel/early_printk.c
index 304efdc..4fa54b2 100644
--- a/arch/mips/kernel/early_printk.c
+++ b/arch/mips/kernel/early_printk.c
@@ -33,8 +33,3 @@ void __init setup_early_printk(void)
{
register_console(&early_console);
}
-
-void __init disable_early_printk(void)
-{
- unregister_console(&early_console);
-}
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 3cc25c0..403d96f 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -31,7 +31,6 @@
#include <linux/shm.h>
#include <linux/personality.h>
#include <linux/elfcore.h>
-#include <linux/smp_lock.h>
#include <asm/mipsregs.h>
#include <asm/namei.h>
diff --git a/arch/mips/kernel/irixioctl.c b/arch/mips/kernel/irixioctl.c
index e286382..30f9eb0 100644
--- a/arch/mips/kernel/irixioctl.c
+++ b/arch/mips/kernel/irixioctl.c
@@ -9,7 +9,6 @@
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sockios.h>
#include <linux/syscalls.h>
#include <linux/tty.h>
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 2132485..6980deb 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -10,7 +10,6 @@
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/time.h>
#include <linux/ptrace.h>
#include <linux/resource.h>
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 201ae19..b5a7b46 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -22,7 +22,6 @@
#include <linux/ptrace.h>
#include <linux/audit.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/user.h>
#include <linux/security.h>
#include <linux/signal.h>
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 07d6730..2a08ce4 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -12,7 +12,6 @@
#include <linux/mm.h>
#include <linux/personality.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index b9a0144..003f815 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -12,7 +12,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/syscalls.h>
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index a9202fa..4cf9ff2 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -19,7 +19,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c
index a586aba..ebd9db8 100644
--- a/arch/mips/kernel/stacktrace.c
+++ b/arch/mips/kernel/stacktrace.c
@@ -31,8 +31,7 @@ static void save_raw_context_stack(struct stack_trace *trace,
}
}
-static void save_context_stack(struct stack_trace *trace,
- struct task_struct *task, struct pt_regs *regs)
+static void save_context_stack(struct stack_trace *trace, struct pt_regs *regs)
{
unsigned long sp = regs->regs[29];
#ifdef CONFIG_KALLSYMS
@@ -41,7 +40,7 @@ static void save_context_stack(struct stack_trace *trace,
if (raw_show_trace || !__kernel_text_address(pc)) {
unsigned long stack_page =
- (unsigned long)task_stack_page(task);
+ (unsigned long)task_stack_page(current);
if (stack_page && sp >= stack_page &&
sp <= stack_page + THREAD_SIZE - 32)
save_raw_context_stack(trace, sp);
@@ -54,7 +53,7 @@ static void save_context_stack(struct stack_trace *trace,
trace->entries[trace->nr_entries++] = pc;
if (trace->nr_entries >= trace->max_entries)
break;
- pc = unwind_stack(task, &sp, pc, &ra);
+ pc = unwind_stack(current, &sp, pc, &ra);
} while (pc);
#else
save_raw_context_stack(trace, sp);
@@ -64,22 +63,13 @@ static void save_context_stack(struct stack_trace *trace,
/*
* Save stack-backtrace addresses into a stack_trace buffer.
*/
-void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+void save_stack_trace(struct stack_trace *trace)
{
struct pt_regs dummyregs;
struct pt_regs *regs = &dummyregs;
WARN_ON(trace->nr_entries || !trace->max_entries);
- if (task && task != current) {
- regs->regs[29] = task->thread.reg29;
- regs->regs[31] = 0;
- regs->cp0_epc = task->thread.reg31;
- } else {
- if (!task)
- task = current;
- prepare_frametrace(regs);
- }
-
- save_context_stack(trace, task, regs);
+ prepare_frametrace(regs);
+ save_context_stack(trace, regs);
}
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 26e1a7e..9dd5a2d 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -13,7 +13,6 @@
#include <linux/linkage.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/mman.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 493cb29..ff45a4b 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -16,7 +16,6 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/kallsyms.h>
#include <linux/bootmem.h>
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
index 24b7b05..a7d49ae 100644
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -76,7 +76,6 @@
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <asm/asm.h>
#include <asm/branch.h>
diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c
index 8079f3d..ea6ba72 100644
--- a/arch/mips/math-emu/dsemul.c
+++ b/arch/mips/math-emu/dsemul.c
@@ -2,7 +2,6 @@
#include <linux/mm.h>
#include <linux/signal.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <asm/asm.h>
#include <asm/bootinfo.h>
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index f9c595d..7ebea33 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -16,7 +16,6 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/vt_kern.h> /* For unblank_screen() */
#include <linux/module.h>
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_serial.c b/arch/mips/pmc-sierra/msp71xx/msp_serial.c
new file mode 100644
index 0000000..c41b53f
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_serial.c
@@ -0,0 +1,165 @@
+/*
+ * The setup file for serial related hardware on PMC-Sierra MSP processors.
+ *
+ * Copyright 2005 PMC-Sierra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/serial.h>
+
+#include <msp_prom.h>
+#include <msp_int.h>
+#include <msp_regs.h>
+
+#ifdef CONFIG_KGDB
+/*
+ * kgdb uses serial port 1 so the console can remain on port 0.
+ * To use port 0 change the definition to read as follows:
+ * #define DEBUG_PORT_BASE KSEG1ADDR(MSP_UART0_BASE)
+ */
+#define DEBUG_PORT_BASE KSEG1ADDR(MSP_UART1_BASE)
+
+int putDebugChar(char c)
+{
+ volatile uint32_t *uart = (volatile uint32_t *)DEBUG_PORT_BASE;
+ uint32_t val = (uint32_t)c;
+
+ local_irq_disable();
+ while( !(uart[5] & 0x20) ); /* Wait for TXRDY */
+ uart[0] = val;
+ while( !(uart[5] & 0x20) ); /* Wait for TXRDY */
+ local_irq_enable();
+
+ return 1;
+}
+
+char getDebugChar(void)
+{
+ volatile uint32_t *uart = (volatile uint32_t *)DEBUG_PORT_BASE;
+ uint32_t val;
+
+ while( !(uart[5] & 0x01) ); /* Wait for RXRDY */
+ val = uart[0];
+
+ return (char)val;
+}
+
+void initDebugPort(unsigned int uartclk, unsigned int baudrate)
+{
+ unsigned int baud_divisor = (uartclk + 8 * baudrate)/(16 * baudrate);
+
+ /* Enable FIFOs */
+ writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
+ UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_4,
+ (char *)DEBUG_PORT_BASE + (UART_FCR * 4));
+
+ /* Select brtc divisor */
+ writeb(UART_LCR_DLAB, (char *)DEBUG_PORT_BASE + (UART_LCR * 4));
+
+ /* Store divisor lsb */
+ writeb(baud_divisor, (char *)DEBUG_PORT_BASE + (UART_TX * 4));
+
+ /* Store divisor msb */
+ writeb(baud_divisor >> 8, (char *)DEBUG_PORT_BASE + (UART_IER * 4));
+
+ /* Set 8N1 mode */
+ writeb(UART_LCR_WLEN8, (char *)DEBUG_PORT_BASE + (UART_LCR * 4));
+
+ /* Disable flow control */
+ writeb(0, (char *)DEBUG_PORT_BASE + (UART_MCR * 4));
+
+ /* Disable receive interrupt(!) */
+ writeb(0, (char *)DEBUG_PORT_BASE + (UART_IER * 4));
+}
+#endif
+
+void __init msp_serial_setup(void)
+{
+ char *s;
+ char *endp;
+ struct uart_port up;
+ unsigned int uartclk;
+
+ memset(&up, 0, sizeof(up));
+
+ /* Check if clock was specified in environment */
+ s = prom_getenv("uartfreqhz");
+ if(!(s && *s && (uartclk = simple_strtoul(s, &endp, 10)) && *endp == 0))
+ uartclk = MSP_BASE_BAUD;
+ ppfinit("UART clock set to %d\n", uartclk);
+
+ /* Initialize first serial port */
+ up.mapbase = MSP_UART0_BASE;
+ up.membase = ioremap_nocache(up.mapbase,MSP_UART_REG_LEN);
+ up.irq = MSP_INT_UART0;
+ up.uartclk = uartclk;
+ up.regshift = 2;
+ up.iotype = UPIO_DWAPB; /* UPIO_MEM like */
+ up.flags = STD_COM_FLAGS;
+ up.type = PORT_16550A;
+ up.line = 0;
+ up.private_data = (void*)UART0_STATUS_REG;
+ if (early_serial_setup(&up))
+ printk(KERN_ERR "Early serial init of port 0 failed\n");
+
+ /* Initialize the second serial port, if one exists */
+ switch (mips_machtype) {
+ case MACH_MSP4200_EVAL:
+ case MACH_MSP4200_GW:
+ case MACH_MSP4200_FPGA:
+ case MACH_MSP7120_EVAL:
+ case MACH_MSP7120_GW:
+ case MACH_MSP7120_FPGA:
+ /* Enable UART1 on MSP4200 and MSP7120 */
+ *GPIO_CFG2_REG = 0x00002299;
+
+#ifdef CONFIG_KGDB
+ /* Initialize UART1 for kgdb since PMON doesn't */
+ if( DEBUG_PORT_BASE == KSEG1ADDR(MSP_UART1_BASE) ) {
+ if( mips_machtype == MACH_MSP4200_FPGA
+ || mips_machtype == MACH_MSP7120_FPGA )
+ initDebugPort(uartclk,19200);
+ else
+ initDebugPort(uartclk,57600);
+ }
+#endif
+ break;
+
+ default:
+ return; /* No second serial port, good-bye. */
+ }
+
+ up.mapbase = MSP_UART1_BASE;
+ up.membase = ioremap_nocache(up.mapbase,MSP_UART_REG_LEN);
+ up.irq = MSP_INT_UART1;
+ up.line = 1;
+ up.private_data = (void*)UART1_STATUS_REG;
+ if (early_serial_setup(&up))
+ printk(KERN_ERR "Early serial init of port 1 failed\n");
+}
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index 60ade76..ba8e079 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -19,7 +19,6 @@
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c
index ad5fc47..9ccffdf 100644
--- a/arch/mips/sni/irq.c
+++ b/arch/mips/sni/irq.c
@@ -42,7 +42,7 @@ static irqreturn_t sni_isa_irq_handler(int dummy, void *p)
struct irqaction sni_isa_irq = {
.handler = sni_isa_irq_handler,
.name = "ISA",
- .flags = SA_SHIRQ
+ .flags = IRQF_SHARED
};
/*
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index 0f7576d..a0c11ef 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -1049,3 +1049,22 @@ static int __init toshiba_rbtx4927_rtc_init(void)
return IS_ERR(dev) ? PTR_ERR(dev) : 0;
}
device_initcall(toshiba_rbtx4927_rtc_init);
+
+static int __init rbtx4927_ne_init(void)
+{
+ static struct resource __initdata res[] = {
+ {
+ .start = RBTX4927_RTL_8019_BASE,
+ .end = RBTX4927_RTL_8019_BASE + 0x20 - 1,
+ .flags = IORESOURCE_IO,
+ }, {
+ .start = RBTX4927_RTL_8019_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+ struct platform_device *dev =
+ platform_device_register_simple("ne", -1,
+ res, ARRAY_SIZE(res));
+ return IS_ERR(dev) ? PTR_ERR(dev) : 0;
+}
+device_initcall(rbtx4927_ne_init);
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index 66163ba..f5d1ce7 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -20,6 +20,7 @@
#include <linux/console.h>
#include <linux/pci.h>
#include <linux/pm.h>
+#include <linux/platform_device.h>
#include <asm/wbflush.h>
#include <asm/reboot.h>
@@ -1037,3 +1038,22 @@ static int __init tx4938_spi_proc_setup(void)
__initcall(tx4938_spi_proc_setup);
#endif
+
+static int __init rbtx4938_ne_init(void)
+{
+ struct resource res[] = {
+ {
+ .start = RBTX4938_RTL_8019_BASE,
+ .end = RBTX4938_RTL_8019_BASE + 0x20 - 1,
+ .flags = IORESOURCE_IO,
+ }, {
+ .start = RBTX4938_RTL_8019_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+ struct platform_device *dev =
+ platform_device_register_simple("ne", -1,
+ res, ARRAY_SIZE(res));
+ return IS_ERR(dev) ? PTR_ERR(dev) : 0;
+}
+device_initcall(rbtx4938_ne_init);
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c
index c7a81a2..d86e157 100644
--- a/arch/parisc/hpux/fs.c
+++ b/arch/parisc/hpux/fs.c
@@ -24,7 +24,6 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/file.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/ptrace.h>
#include <asm/errno.h>
diff --git a/arch/parisc/hpux/ioctl.c b/arch/parisc/hpux/ioctl.c
index b34b4f3..dede476 100644
--- a/arch/parisc/hpux/ioctl.c
+++ b/arch/parisc/hpux/ioctl.c
@@ -34,7 +34,6 @@
*/
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <asm/errno.h>
#include <asm/ioctl.h>
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index e9d09b0..c5c9125 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -388,7 +388,7 @@ void do_cpu_irq_mask(struct pt_regs *regs)
static struct irqaction timer_action = {
.handler = timer_interrupt,
.name = "timer",
- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_PERCPU,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_PERCPU | IRQF_IRQPOLL,
};
#ifdef CONFIG_SMP
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 0d0d617..8a0db37 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -10,7 +10,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 9784e40..fb35ebc 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -16,7 +16,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
index 1c1a37f..db94aff 100644
--- a/arch/parisc/kernel/signal32.c
+++ b/arch/parisc/kernel/signal32.c
@@ -26,7 +26,6 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/unistd.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/syscalls.h>
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index 512642d..4f58921 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -29,7 +29,6 @@
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/shm.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/utsname.h>
#include <linux/personality.h>
@@ -106,6 +105,11 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
{
if (len > TASK_SIZE)
return -ENOMEM;
+ /* Might want to check for cache aliasing issues for MAP_FIXED case
+ * like ARM or MIPS ??? --BenH.
+ */
+ if (flags & MAP_FIXED)
+ return addr;
if (!addr)
addr = TASK_UNMAPPED_BASE;
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 55bc147..745ff74 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -20,7 +20,6 @@
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/interrupt.h>
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index 5f75b3e..89c0370 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -216,11 +216,8 @@ static void unwind_frame_regs(struct unwind_frame_info *info)
/* Handle some frequent special cases.... */
{
char symname[KSYM_NAME_LEN+1];
- char *modname;
- unsigned long symsize, offset;
- kallsyms_lookup(info->ip, &symsize, &offset,
- &modname, symname);
+ kallsyms_lookup(info->ip, NULL, NULL, NULL, symname);
dbg("info->ip = 0x%lx, name = %s\n", info->ip, symname);
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a54a9a2..808d2ef 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -117,12 +117,33 @@ config GENERIC_BUG
default y
depends on BUG
+config SYS_SUPPORTS_APM_EMULATION
+ bool
+
+#
+# Powerpc uses the slab allocator to manage its ptes and the
+# page structs of ptes are used for splitting the page table
+# lock for configurations supporting more than SPLIT_PTLOCK_CPUS.
+#
+# In that special configuration the page structs of slabs are modified.
+# This setting disables the selection of SLUB as a slab allocator.
+#
+config ARCH_USES_SLAB_PAGE_STRUCT
+ bool
+ default y
+ depends on SPLIT_PTLOCK_CPUS <= NR_CPUS
+
config DEFAULT_UIMAGE
bool
help
Used to allow a board to specify it wants a uImage built by default
default n
+config PPC64_SWSUSP
+ bool
+ depends on PPC64 && (BROKEN || (PPC_PMAC64 && EXPERIMENTAL))
+ default y
+
menu "Processor support"
choice
prompt "Processor Type"
@@ -193,6 +214,7 @@ config 40x
config 44x
bool "AMCC 44x"
select PPC_DCR_NATIVE
+ select WANT_DEVICE_TREE
config E200
bool "Freescale e200"
@@ -257,9 +279,14 @@ config PPC_OF_PLATFORM_PCI
depends on PPC64 # not supported on 32 bits yet
default n
+config 4xx
+ bool
+ depends on 40x || 44x
+ default y
+
config BOOKE
bool
- depends on E200 || E500
+ depends on E200 || E500 || 44x
default y
config FSL_BOOKE
@@ -656,11 +683,12 @@ config MCA
config PCI
bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
|| PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \
- || MPC7448HPC2 || PPC_PS3
+ || MPC7448HPC2 || PPC_PS3 || PPC_HOLLY
default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx \
&& !PPC_85xx && !PPC_86xx
default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS
default PCI_QSPAN if !4xx && !CPM2 && 8xx
+ select ARCH_SUPPORTS_MSI
help
Find out whether your system includes a PCI bus. PCI is the name of
a bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 86aa374..f70e795 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -139,10 +139,6 @@ config BOOTX_TEXT
Say Y here to see progress messages from the boot firmware in text
mode. Requires either BootX or Open Firmware.
-config SERIAL_TEXT_DEBUG
- bool "Support for early boot texts over serial port"
- depends on 4xx
-
config PPC_EARLY_DEBUG
bool "Early debugging (dangerous)"
@@ -207,6 +203,24 @@ config PPC_EARLY_DEBUG_BEAT
help
Select this to enable early debugging for Celleb with Beat.
+config PPC_EARLY_DEBUG_44x
+ bool "Early serial debugging for IBM/AMCC 44x CPUs"
+ depends on 44x
+ select PPC_UDBG_16550
+ help
+ Select this to enable early debugging for IBM 44x chips via the
+ inbuilt serial port.
+
endchoice
+config PPC_EARLY_DEBUG_44x_PHYSLOW
+ hex "Low 32 bits of early debug UART physical address"
+ depends PPC_EARLY_DEBUG_44x
+ default "0x40000200"
+
+config PPC_EARLY_DEBUG_44x_PHYSHIGH
+ hex "EPRN of early debug UART physical address"
+ depends PPC_EARLY_DEBUG_44x
+ default "0x1"
+
endmenu
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 7949920..81a531d 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -148,7 +148,7 @@ all: $(KBUILD_IMAGE)
CPPFLAGS_vmlinux.lds := -Upowerpc
-BOOT_TARGETS = zImage zImage.initrd uImage cuImage
+BOOT_TARGETS = zImage zImage.initrd uImage
PHONY += $(BOOT_TARGETS)
diff --git a/arch/powerpc/boot/44x.c b/arch/powerpc/boot/44x.c
new file mode 100644
index 0000000..d51377d
--- /dev/null
+++ b/arch/powerpc/boot/44x.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2007 David Gibson, IBM Corporation.
+ *
+ * Based on earlier code:
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003, 2004 Zultys Technologies
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stddef.h>
+#include "types.h"
+#include "string.h"
+#include "stdio.h"
+#include "ops.h"
+#include "reg.h"
+#include "dcr.h"
+
+/* Read the 44x memory controller to get size of system memory. */
+void ibm44x_fixup_memsize(void)
+{
+ int i;
+ unsigned long memsize, bank_config;
+
+ memsize = 0;
+ for (i = 0; i < ARRAY_SIZE(sdram_bxcr); i++) {
+ mtdcr(DCRN_SDRAM0_CFGADDR, sdram_bxcr[i]);
+ bank_config = mfdcr(DCRN_SDRAM0_CFGDATA);
+
+ if (bank_config & SDRAM_CONFIG_BANK_ENABLE)
+ memsize += SDRAM_CONFIG_BANK_SIZE(bank_config);
+ }
+
+ dt_fixup_memory(0, memsize);
+}
diff --git a/arch/powerpc/boot/44x.h b/arch/powerpc/boot/44x.h
new file mode 100644
index 0000000..7b129ad
--- /dev/null
+++ b/arch/powerpc/boot/44x.h
@@ -0,0 +1,16 @@
+/*
+ * PowerPC 44x related functions
+ *
+ * Copyright 2007 David Gibson, IBM Corporation.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#ifndef _PPC_BOOT_44X_H_
+#define _PPC_BOOT_44X_H_
+
+void ibm44x_fixup_memsize(void);
+void ebony_init(void *mac0, void *mac1);
+
+#endif /* _PPC_BOOT_44X_H_ */
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 3716594..5c384aa 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -37,13 +37,15 @@ zlib := inffast.c inflate.c inftrees.c
zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
zliblinuxheader := zlib.h zconf.h zutil.h
-$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \
- $(addprefix $(obj)/,$(zlibheader))
+$(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
+ $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
- gunzip_util.c elf_util.c $(zlib) devtree.c
-src-plat := of.c cuboot-83xx.c cuboot-85xx.c
+ gunzip_util.c elf_util.c $(zlib) devtree.c \
+ 44x.c ebony.c
+src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \
+ cuboot-ebony.c treeboot-ebony.c
src-boot := $(src-wlib) $(src-plat) empty.c
src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -129,7 +131,14 @@ image-$(CONFIG_PPC_CELLEB) += zImage.pseries
image-$(CONFIG_PPC_CHRP) += zImage.chrp
image-$(CONFIG_PPC_EFIKA) += zImage.chrp
image-$(CONFIG_PPC_PMAC) += zImage.pmac
-image-$(CONFIG_DEFAULT_UIMAGE) += uImage cuImage
+image-$(CONFIG_PPC_HOLLY) += zImage.holly-elf
+image-$(CONFIG_DEFAULT_UIMAGE) += uImage
+
+ifneq ($(CONFIG_DEVICE_TREE),"")
+image-$(CONFIG_PPC_83xx) += cuImage.83xx
+image-$(CONFIG_PPC_85xx) += cuImage.85xx
+image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony
+endif
# For 32-bit powermacs, build the COFF and miboot images
# as well as the ELF images.
@@ -138,7 +147,8 @@ image-$(CONFIG_PPC_PMAC) += zImage.coff zImage.miboot
endif
initrd- := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-))
-initrd-y := $(patsubst zImage%, zImage.initrd%, $(image-y))
+initrd-y := $(patsubst zImage%, zImage.initrd%, \
+ $(patsubst treeImage%, treeImage.initrd%, $(image-y)))
initrd-y := $(filter-out $(image-y), $(initrd-y))
targets += $(image-y) $(initrd-y)
@@ -159,18 +169,27 @@ $(obj)/zImage.ps3: vmlinux
$(obj)/zImage.initrd.ps3: vmlinux
@echo " WARNING zImage.initrd.ps3 not supported (yet)"
+$(obj)/zImage.holly-elf: vmlinux $(wrapperbits)
+ $(call if_changed,wrap,holly,$(obj)/dts/holly.dts,,)
+
+$(obj)/zImage.initrd.holly-elf: vmlinux $(wrapperbits) $(obj)/ramdisk.image.gz
+ $(call if_changed,wrap,holly,$(obj)/dts/holly.dts,,$(obj)/ramdisk.image.gz)
+
$(obj)/uImage: vmlinux $(wrapperbits)
$(call if_changed,wrap,uboot)
-cuboot-plat-$(CONFIG_83xx) += 83xx
-cuboot-plat-$(CONFIG_85xx) += 85xx
-cuboot-plat-y += unknown-platform
-
+# CONFIG_DEVICE_TREE will have "" around it, make sure to strip them
dts = $(if $(shell echo $(CONFIG_DEVICE_TREE) | grep '^/'),\
- ,$(srctree)/$(src)/dts/)$(CONFIG_DEVICE_TREE)
+ ,$(srctree)/$(src)/dts/)$(CONFIG_DEVICE_TREE:"%"=%)
+
+$(obj)/cuImage.%: vmlinux $(dts) $(wrapperbits)
+ $(call if_changed,wrap,cuboot-$*,$(dts))
+
+$(obj)/treeImage.%: vmlinux $(dts) $(wrapperbits)
+ $(call if_changed,wrap,treeboot-$*,$(dts))
-$(obj)/cuImage: vmlinux $(wrapperbits)
- $(call if_changed,wrap,cuboot-$(word 1,$(cuboot-plat-y)),$(dts))
+$(obj)/treeImage.initrd.%: vmlinux $(dts) $(wrapperbits)
+ $(call if_changed,wrap,treeboot-$*,$(dts),,$(obj)/ramdisk.image.gz)
$(obj)/zImage: $(addprefix $(obj)/, $(image-y))
@rm -f $@; ln $< $@
@@ -181,8 +200,8 @@ install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y))
sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $<
# anything not in $(targets)
-clean-files += $(image-) $(initrd-) zImage zImage.initrd \
- cuImage.elf cuImage.bin.gz
+clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* \
+ treeImage.*
# clean up files cached by wrapper
clean-kernel := vmlinux.strip vmlinux.bin
diff --git a/arch/powerpc/boot/cuboot-ebony.c b/arch/powerpc/boot/cuboot-ebony.c
new file mode 100644
index 0000000..4464c5f
--- /dev/null
+++ b/arch/powerpc/boot/cuboot-ebony.c
@@ -0,0 +1,42 @@
+/*
+ * Old U-boot compatibility for Ebony
+ *
+ * Author: David Gibson <david@gibson.dropbear.id.au>
+ *
+ * Copyright 2007 David Gibson, IBM Corporatio.
+ * Based on cuboot-83xx.c, which is:
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "ops.h"
+#include "stdio.h"
+#include "44x.h"
+
+#define TARGET_44x
+#include "ppcboot.h"
+
+static bd_t bd;
+extern char _end[];
+
+BSS_STACK(4096);
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7)
+{
+ unsigned long end_of_ram = bd.bi_memstart + bd.bi_memsize;
+ unsigned long avail_ram = end_of_ram - (unsigned long)_end;
+
+ memcpy(&bd, (bd_t *)r3, sizeof(bd));
+ loader_info.initrd_addr = r4;
+ loader_info.initrd_size = r4 ? r5 : 0;
+ loader_info.cmdline = (char *)r6;
+ loader_info.cmdline_len = r7 - r6;
+
+ simple_alloc_init(_end, avail_ram, 32, 64);
+
+ ebony_init(&bd.bi_enetaddr, &bd.bi_enet1addr);
+}
diff --git a/arch/powerpc/boot/dcr.h b/arch/powerpc/boot/dcr.h
new file mode 100644
index 0000000..877bc97
--- /dev/null
+++ b/arch/powerpc/boot/dcr.h
@@ -0,0 +1,87 @@
+#ifndef _PPC_BOOT_DCR_H_
+#define _PPC_BOOT_DCR_H_
+
+#define mfdcr(rn) \
+ ({ \
+ unsigned long rval; \
+ asm volatile("mfdcr %0,%1" : "=r"(rval) : "i"(rn)); \
+ rval; \
+ })
+#define mtdcr(rn, val) \
+ asm volatile("mtdcr %0,%1" : : "i"(rn), "r"(val))
+
+/* 440GP/440GX SDRAM controller DCRs */
+#define DCRN_SDRAM0_CFGADDR 0x010
+#define DCRN_SDRAM0_CFGDATA 0x011
+
+#define SDRAM0_B0CR 0x40
+#define SDRAM0_B1CR 0x44
+#define SDRAM0_B2CR 0x48
+#define SDRAM0_B3CR 0x4c
+
+static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR, SDRAM0_B2CR, SDRAM0_B3CR };
+
+#define SDRAM_CONFIG_BANK_ENABLE 0x00000001
+#define SDRAM_CONFIG_SIZE_MASK 0x000e0000
+#define SDRAM_CONFIG_BANK_SIZE(reg) \
+ (0x00400000 << ((reg & SDRAM_CONFIG_SIZE_MASK) >> 17))
+
+/* 440GP Clock, PM, chip control */
+#define DCRN_CPC0_SR 0x0b0
+#define DCRN_CPC0_ER 0x0b1
+#define DCRN_CPC0_FR 0x0b2
+#define DCRN_CPC0_SYS0 0x0e0
+#define CPC0_SYS0_TUNE 0xffc00000
+#define CPC0_SYS0_FBDV_MASK 0x003c0000
+#define CPC0_SYS0_FWDVA_MASK 0x00038000
+#define CPC0_SYS0_FWDVB_MASK 0x00007000
+#define CPC0_SYS0_OPDV_MASK 0x00000c00
+#define CPC0_SYS0_EPDV_MASK 0x00000300
+/* Helper macros to compute the actual clock divider values from the
+ * encodings in the CPC0 register */
+#define CPC0_SYS0_FBDV(reg) \
+ ((((((reg) & CPC0_SYS0_FBDV_MASK) >> 18) - 1) & 0xf) + 1)
+#define CPC0_SYS0_FWDVA(reg) \
+ (8 - (((reg) & CPC0_SYS0_FWDVA_MASK) >> 15))
+#define CPC0_SYS0_FWDVB(reg) \
+ (8 - (((reg) & CPC0_SYS0_FWDVB_MASK) >> 12))
+#define CPC0_SYS0_OPDV(reg) \
+ ((((reg) & CPC0_SYS0_OPDV_MASK) >> 10) + 1)
+#define CPC0_SYS0_EPDV(reg) \
+ ((((reg) & CPC0_SYS0_EPDV_MASK) >> 8) + 1)
+#define CPC0_SYS0_EXTSL 0x00000080
+#define CPC0_SYS0_RW_MASK 0x00000060
+#define CPC0_SYS0_RL 0x00000010
+#define CPC0_SYS0_ZMIISL_MASK 0x0000000c
+#define CPC0_SYS0_BYPASS 0x00000002
+#define CPC0_SYS0_NTO1 0x00000001
+#define DCRN_CPC0_SYS1 0x0e1
+#define DCRN_CPC0_CUST0 0x0e2
+#define DCRN_CPC0_CUST1 0x0e3
+#define DCRN_CPC0_STRP0 0x0e4
+#define DCRN_CPC0_STRP1 0x0e5
+#define DCRN_CPC0_STRP2 0x0e6
+#define DCRN_CPC0_STRP3 0x0e7
+#define DCRN_CPC0_GPIO 0x0e8
+#define DCRN_CPC0_PLB 0x0e9
+#define DCRN_CPC0_CR1 0x0ea
+#define DCRN_CPC0_CR0 0x0eb
+#define CPC0_CR0_SWE 0x80000000
+#define CPC0_CR0_CETE 0x40000000
+#define CPC0_CR0_U1FCS 0x20000000
+#define CPC0_CR0_U0DTE 0x10000000
+#define CPC0_CR0_U0DRE 0x08000000
+#define CPC0_CR0_U0DC 0x04000000
+#define CPC0_CR0_U1DTE 0x02000000
+#define CPC0_CR0_U1DRE 0x01000000
+#define CPC0_CR0_U1DC 0x00800000
+#define CPC0_CR0_U0EC 0x00400000
+#define CPC0_CR0_U1EC 0x00200000
+#define CPC0_CR0_UDIV_MASK 0x001f0000
+#define CPC0_CR0_UDIV(reg) \
+ ((((reg) & CPC0_CR0_UDIV_MASK) >> 16) + 1)
+#define DCRN_CPC0_MIRQ0 0x0ec
+#define DCRN_CPC0_MIRQ1 0x0ed
+#define DCRN_CPC0_JTAGID 0x0ef
+
+#endif /* _PPC_BOOT_DCR_H_ */
diff --git a/arch/powerpc/boot/dts/ebony.dts b/arch/powerpc/boot/dts/ebony.dts
new file mode 100644
index 0000000..b679186
--- /dev/null
+++ b/arch/powerpc/boot/dts/ebony.dts
@@ -0,0 +1,307 @@
+/*
+ * Device Tree Source for IBM Ebony
+ *
+ * Copyright (c) 2006, 2007 IBM Corp.
+ * Josh Boyer <jwboyer@linux.vnet.ibm.com>, David Gibson <dwg@au1.ibm.com>
+ *
+ * FIXME: Draft only!
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * To build:
+ * dtc -I dts -O asm -o ebony.S -b 0 ebony.dts
+ * dtc -I dts -O dtb -o ebony.dtb -b 0 ebony.dts
+ */
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ model = "ibm,ebony";
+ compatible = "ibm,ebony";
+ dcr-parent = <&/cpus/PowerPC,440GP@0>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,440GP@0 {
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency = <0>; // Filled in by zImage
+ timebase-frequency = <0>; // Filled in by zImage
+ i-cache-line-size = <32>;
+ d-cache-line-size = <32>;
+ i-cache-size = <0>;
+ d-cache-size = <0>;
+ dcr-controller;
+ dcr-access-method = "native";
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0 0>; // Filled in by zImage
+ };
+
+ UIC0: interrupt-controller0 {
+ device_type = "ibm,uic";
+ compatible = "ibm,uic-440gp", "ibm,uic";
+ interrupt-controller;
+ cell-index = <0>;
+ dcr-reg = <0c0 009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+
+ };
+
+ UIC1: interrupt-controller1 {
+ device_type = "ibm,uic";
+ compatible = "ibm,uic-440gp", "ibm,uic";
+ interrupt-controller;
+ cell-index = <1>;
+ dcr-reg = <0d0 009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <1e 4 1f 4>; /* cascade */
+ interrupt-parent = <&UIC0>;
+ };
+
+ CPC0: cpc {
+ device_type = "ibm,cpc";
+ compatible = "ibm,cpc-440gp";
+ dcr-reg = <0b0 003 0e0 010>;
+ // FIXME: anything else?
+ };
+
+ plb {
+ device_type = "ibm,plb";
+ compatible = "ibm,plb-440gp", "ibm,plb4";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges;
+ clock-frequency = <0>; // Filled in by zImage
+
+ SDRAM0: sdram {
+ device_type = "memory-controller";
+ compatible = "ibm,sdram-440gp", "ibm,sdram";
+ dcr-reg = <010 2>;
+ // FIXME: anything else?
+ };
+
+ DMA0: dma {
+ // FIXME: ???
+ device_type = "ibm,dma-4xx";
+ compatible = "ibm,dma-440gp", "ibm,dma-4xx";
+ dcr-reg = <100 027>;
+ };
+
+ MAL0: mcmal {
+ device_type = "mcmal-dma";
+ compatible = "ibm,mcmal-440gp", "ibm,mcmal";
+ dcr-reg = <180 62>;
+ num-tx-chans = <4>;
+ num-rx-chans = <4>;
+ interrupt-parent = <&MAL0>;
+ interrupts = <0 1 2 3 4>;
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = </*TXEOB*/ 0 &UIC0 a 4
+ /*RXEOB*/ 1 &UIC0 b 4
+ /*SERR*/ 2 &UIC1 0 4
+ /*TXDE*/ 3 &UIC1 1 4
+ /*RXDE*/ 4 &UIC1 2 4>;
+ interrupt-map-mask = <ffffffff>;
+ };
+
+ POB0: opb {
+ device_type = "ibm,opb";
+ compatible = "ibm,opb-440gp", "ibm,opb";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ /* Wish there was a nicer way of specifying a full 32-bit
+ range */
+ ranges = <00000000 1 00000000 80000000
+ 80000000 1 80000000 80000000>;
+ dcr-reg = <090 00b>;
+ interrupt-parent = <&UIC1>;
+ interrupts = <7 4>;
+ clock-frequency = <0>; // Filled in by zImage
+
+ EBC0: ebc {
+ device_type = "ibm,ebc";
+ compatible = "ibm,ebc-440gp";
+ dcr-reg = <012 2>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clock-frequency = <0>; // Filled in by zImage
+ ranges = <0 00000000 fff00000 100000
+ 1 00000000 48000000 100000
+ 2 00000000 ff800000 400000
+ 3 00000000 48200000 100000
+ 7 00000000 48300000 100000>;
+ interrupts = <5 4>;
+ interrupt-parent = <&UIC1>;
+
+ small-flash@0,0 {
+ device_type = "rom";
+ compatible = "direct-mapped";
+ probe-type = "JEDEC";
+ bank-width = <1>;
+ partitions = <0 80000>;
+ partition-names = "OpenBIOS";
+ reg = <0 80000 80000>;
+ };
+
+ ds1743@1,0 {
+ /* NVRAM & RTC */
+ device_type = "nvram";
+ compatible = "ds1743";
+ reg = <1 0 2000>;
+ };
+
+ large-flash@2,0 {
+ device_type = "rom";
+ compatible = "direct-mapped";
+ probe-type = "JEDEC";
+ bank-width = <1>;
+ partitions = <0 380000
+ 280000 80000>;
+ partition-names = "fs", "firmware";
+ reg = <2 0 400000>;
+ };
+
+ ir@3,0 {
+ reg = <3 0 10>;
+ };
+
+ fpga@7,0 {
+ compatible = "Ebony-FPGA";
+ reg = <7 0 10>;
+ };
+ };
+
+ UART0: serial@40000200 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <40000200 8>;
+ virtual-reg = <e0000200>;
+ clock-frequency = <A8C000>;
+ current-speed = <2580>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0 4>;
+ };
+
+ UART1: serial@40000300 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <40000300 8>;
+ virtual-reg = <e0000300>;
+ clock-frequency = <A8C000>;
+ current-speed = <2580>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <1 4>;
+ };
+
+ IIC0: i2c@40000400 {
+ /* FIXME */
+ device_type = "i2c";
+ compatible = "ibm,iic-440gp", "ibm,iic";
+ reg = <40000400 14>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <2 4>;
+ };
+ IIC1: i2c@40000500 {
+ /* FIXME */
+ device_type = "i2c";
+ compatible = "ibm,iic-440gp", "ibm,iic";
+ reg = <40000500 14>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <3 4>;
+ };
+
+ GPIO0: gpio@40000700 {
+ /* FIXME */
+ device_type = "gpio";
+ compatible = "ibm,gpio-440gp";
+ reg = <40000700 20>;
+ };
+
+ ZMII0: emac-zmii@40000780 {
+ device_type = "emac-zmii";
+ compatible = "ibm,zmii-440gp", "ibm,zmii";
+ reg = <40000780 c>;
+ };
+
+ EMAC0: ethernet@40000800 {
+ linux,network-index = <0>;
+ device_type = "network";
+ compatible = "ibm,emac-440gp", "ibm,emac";
+ interrupt-parent = <&UIC1>;
+ interrupts = <1c 4 1d 4>;
+ reg = <40000800 70>;
+ local-mac-address = [000000000000]; // Filled in by zImage
+ mal-device = <&MAL0>;
+ mal-tx-channel = <0 1>;
+ mal-rx-channel = <0>;
+ cell-index = <0>;
+ max-frame-size = <5dc>;
+ rx-fifo-size = <1000>;
+ tx-fifo-size = <800>;
+ phy-mode = "rmii";
+ phy-map = <00000001>;
+ zmii-device = <&ZMII0>;
+ zmii-channel = <0>;
+ };
+ EMAC1: ethernet@40000900 {
+ linux,network-index = <1>;
+ device_type = "network";
+ compatible = "ibm,emac-440gp", "ibm,emac";
+ interrupt-parent = <&UIC1>;
+ interrupts = <1e 4 1f 4>;
+ reg = <40000900 70>;
+ local-mac-address = [000000000000]; // Filled in by zImage
+ mal-device = <&MAL0>;
+ mal-tx-channel = <2 3>;
+ mal-rx-channel = <1>;
+ cell-index = <1>;
+ max-frame-size = <5dc>;
+ rx-fifo-size = <1000>;
+ tx-fifo-size = <800>;
+ phy-mode = "rmii";
+ phy-map = <00000001>;
+ zmii-device = <&ZMII0>;
+ zmii-channel = <1>;
+ };
+
+
+ GPT0: gpt@40000a00 {
+ /* FIXME */
+ reg = <40000a00 d4>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <12 4 13 4 14 4 15 4 16 4>;
+ };
+
+ };
+
+ PCIX0: pci@1234 {
+ device_type = "pci";
+ /* FIXME */
+ reg = <2 0ec00000 8
+ 2 0ec80000 f0
+ 2 0ec80100 fc>;
+ };
+ };
+
+ chosen {
+ linux,stdout-path = "/plb/opb/serial@40000200";
+// linux,initrd-start = <0>; /* FIXME */
+// linux,initrd-end = <0>;
+// bootargs = "";
+ };
+};
+
diff --git a/arch/powerpc/boot/dts/holly.dts b/arch/powerpc/boot/dts/holly.dts
new file mode 100644
index 0000000..254499b
--- /dev/null
+++ b/arch/powerpc/boot/dts/holly.dts
@@ -0,0 +1,198 @@
+/*
+ * Device Tree Source for IBM Holly (PPC 750CL with TSI controller)
+ * Copyright 2007, IBM Corporation
+ *
+ * Stephen Winiecki <stevewin@us.ibm.com>
+ * Josh Boyer <jwboyer@linux.vnet.ibm.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * To build:
+ * dtc -I dts -O asm -o holly.S -b 0 holly.dts
+ * dtc -I dts -O dtb -o holly.dtb -b 0 holly.dts
+ */
+
+/ {
+ model = "41K7339";
+ compatible = "ibm,holly";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells =<0>;
+ PowerPC,750CL@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <20>;
+ i-cache-line-size = <20>;
+ d-cache-size = <8000>;
+ i-cache-size = <8000>;
+ d-cache-sets = <80>;
+ i-cache-sets = <80>;
+ timebase-frequency = <2faf080>;
+ clock-frequency = <23c34600>;
+ bus-frequency = <bebc200>;
+ 32-bit;
+ };
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <00000000 20000000>;
+ };
+
+ tsi109@c0000000 {
+ device_type = "tsi-bridge";
+ compatible = "tsi-bridge";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <00000000 c0000000 00010000>;
+ reg = <c0000000 00010000>;
+
+ i2c@7000 {
+ device_type = "i2c";
+ compatible = "tsi-i2c";
+ interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+ interrupts = <e 2>;
+ reg = <7000 400>;
+ };
+
+ mdio@6000 {
+ device_type = "mdio";
+ compatible = "tsi-ethernet";
+
+ PHY1: ethernet-phy@6000 {
+ device_type = "ethernet-phy";
+ compatible = "bcm54xx";
+ reg = <6000 50>;
+ phy-id = <1>;
+ };
+
+ PHY2: ethernet-phy@6400 {
+ device_type = "ethernet-phy";
+ compatible = "bcm54xx";
+ reg = <6000 50>;
+ phy-id = <2>;
+ };
+ };
+
+ ethernet@6200 {
+ device_type = "network";
+ compatible = "tsi-ethernet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6000 200>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+ interrupts = <10 2>;
+ phy-handle = <&PHY1>;
+ };
+
+ ethernet@6600 {
+ device_type = "network";
+ compatible = "tsi-ethernet";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <6400 200>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+ interrupts = <11 2>;
+ phy-handle = <&PHY2>;
+ };
+
+ serial@7808 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <7808 200>;
+ virtual-reg = <c0007808>;
+ clock-frequency = <3F9C6000>;
+ current-speed = <1c200>;
+ interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+ interrupts = <c 2>;
+ };
+
+ serial@7c08 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <7c08 200>;
+ virtual-reg = <c0007c08>;
+ clock-frequency = <3F9C6000>;
+ current-speed = <1c200>;
+ interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+ interrupts = <d 2>;
+ };
+
+ MPIC: pic@7400 {
+ device_type = "open-pic";
+ compatible = "chrp,open-pic";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <7400 400>;
+ big-endian;
+ };
+
+ pci@1000 {
+ device_type = "pci";
+ compatible = "tsi109";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <1000 1000>;
+ bus-range = <0 0>;
+ /*----------------------------------------------------+
+ | PCI memory range.
+ | 01 denotes I/O space
+ | 02 denotes 32-bit memory space
+ +----------------------------------------------------*/
+ ranges = <02000000 0 40000000 40000000 0 10000000
+ 01000000 0 00000000 7e000000 0 00010000>;
+ clock-frequency = <7f28154>;
+ interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+ interrupts = <17 2>;
+ interrupt-map-mask = <f800 0 0 7>;
+ /*----------------------------------------------------+
+ | The INTA, INTB, INTC, INTD are shared.
+ +----------------------------------------------------*/
+ interrupt-map = <
+ 0800 0 0 1 &RT0 24 0
+ 0800 0 0 2 &RT0 25 0
+ 0800 0 0 3 &RT0 26 0
+ 0800 0 0 4 &RT0 27 0
+
+ 1000 0 0 1 &RT0 25 0
+ 1000 0 0 2 &RT0 26 0
+ 1000 0 0 3 &RT0 27 0
+ 1000 0 0 4 &RT0 24 0
+
+ 1800 0 0 1 &RT0 26 0
+ 1800 0 0 2 &RT0 27 0
+ 1800 0 0 3 &RT0 24 0
+ 1800 0 0 4 &RT0 25 0
+
+ 2000 0 0 1 &RT0 27 0
+ 2000 0 0 2 &RT0 24 0
+ 2000 0 0 3 &RT0 25 0
+ 2000 0 0 4 &RT0 26 0
+ >;
+
+ RT0: router@1180 {
+ device_type = "pic-router";
+ interrupt-controller;
+ big-endian;
+ clock-frequency = <0>;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <17 2>;
+ interrupt-parent = < &/tsi109@c0000000/pic@7400 >;
+ };
+ };
+ };
+
+ chosen {
+ linux,stdout-path = "/tsi109@c0000000/serial@7808";
+ bootargs = "console=ttyS0,115200";
+ };
+};
diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts
index ba54c6b..e13ac6e 100644
--- a/arch/powerpc/boot/dts/lite5200.dts
+++ b/arch/powerpc/boot/dts/lite5200.dts
@@ -48,6 +48,7 @@
soc5200@f0000000 {
model = "fsl,mpc5200";
+ compatible = "mpc5200";
revision = "" // from bootloader
#interrupt-cells = <3>;
device_type = "soc";
@@ -166,7 +167,7 @@
device_type = "mscan";
compatible = "mpc5200-mscan";
cell-index = <1>;
- interrupts = <1 12 0>;
+ interrupts = <2 12 0>;
interrupt-parent = <500>;
reg = <980 80>;
};
@@ -178,7 +179,7 @@
interrupt-parent = <500>;
};
- gpio-wkup@b00 {
+ gpio-wkup@c00 {
compatible = "mpc5200-gpio-wkup";
reg = <c00 40>;
interrupts = <1 8 0 0 3 0>;
@@ -317,20 +318,22 @@
i2c@3d00 {
device_type = "i2c";
- compatible = "mpc5200-i2c";
+ compatible = "mpc5200-i2c\0fsl-i2c";
cell-index = <0>;
reg = <3d00 40>;
interrupts = <2 f 0>;
interrupt-parent = <500>;
+ fsl5200-clocking;
};
i2c@3d40 {
device_type = "i2c";
- compatible = "mpc5200-i2c";
+ compatible = "mpc5200-i2c\0fsl-i2c";
cell-index = <1>;
reg = <3d40 40>;
interrupts = <2 10 0>;
interrupt-parent = <500>;
+ fsl5200-clocking;
};
sram@8000 {
device_type = "sram";
diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts
index 2e00308..00211b3 100644
--- a/arch/powerpc/boot/dts/lite5200b.dts
+++ b/arch/powerpc/boot/dts/lite5200b.dts
@@ -48,6 +48,7 @@
soc5200@f0000000 {
model = "fsl,mpc5200b";
+ compatible = "mpc5200";
revision = ""; // from bootloader
#interrupt-cells = <3>;
device_type = "soc";
@@ -166,7 +167,7 @@
device_type = "mscan";
compatible = "mpc5200b-mscan\0mpc5200-mscan";
cell-index = <1>;
- interrupts = <1 12 0>;
+ interrupts = <2 12 0>;
interrupt-parent = <500>;
reg = <980 80>;
};
@@ -178,7 +179,7 @@
interrupt-parent = <500>;
};
- gpio-wkup@b00 {
+ gpio-wkup@c00 {
compatible = "mpc5200b-gpio-wkup\0mpc5200-gpio-wkup";
reg = <c00 40>;
interrupts = <1 8 0 0 3 0>;
@@ -322,20 +323,22 @@
i2c@3d00 {
device_type = "i2c";
- compatible = "mpc5200b-i2c\0mpc5200-i2c";
+ compatible = "mpc5200b-i2c\0mpc5200-i2c\0fsl-i2c";
cell-index = <0>;
reg = <3d00 40>;
interrupts = <2 f 0>;
interrupt-parent = <500>;
+ fsl5200-clocking;
};
i2c@3d40 {
device_type = "i2c";
- compatible = "mpc5200b-i2c\0mpc5200-i2c";
+ compatible = "mpc5200b-i2c\0mpc5200-i2c\0fsl-i2c";
cell-index = <1>;
reg = <3d40 40>;
interrupts = <2 10 0>;
interrupt-parent = <500>;
+ fsl5200-clocking;
};
sram@8000 {
device_type = "sram";
diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index c798491..93b7606 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -306,14 +306,12 @@
interrupts = <11 8>;
reg = <3>;
device_type = "ethernet-phy";
- interface = <3>; //ENET_100_MII
};
phy4: ethernet-phy@04 {
interrupt-parent = < &ipic >;
interrupts = <12 8>;
reg = <4>;
device_type = "ethernet-phy";
- interface = <3>;
};
};
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index b55bced..be4c357 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -265,14 +265,12 @@
interrupts = <0>;
reg = <0>;
device_type = "ethernet-phy";
- interface = <3>; //ENET_100_MII
};
phy04:ethernet-phy@04 {
interrupt-parent = <&pic>;
interrupts = <0>;
reg = <4>;
device_type = "ethernet-phy";
- interface = <3>;
};
};
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index 7f578eb..38c8594 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -305,6 +305,7 @@
rx-clock = <0>;
tx-clock = <19>;
phy-handle = < &phy0 >;
+ phy-connection-type = "rgmii-id";
pio-handle = < &pio1 >;
};
@@ -320,6 +321,7 @@
rx-clock = <0>;
tx-clock = <14>;
phy-handle = < &phy1 >;
+ phy-connection-type = "rgmii-id";
pio-handle = < &pio2 >;
};
@@ -335,14 +337,12 @@
interrupts = <11 8>;
reg = <0>;
device_type = "ethernet-phy";
- interface = <6>; //ENET_1000_GMII
};
phy1: ethernet-phy@01 {
interrupt-parent = < &ipic >;
interrupts = <12 8>;
reg = <1>;
device_type = "ethernet-phy";
- interface = <6>;
};
};
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index 7361b36..948a3b6 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -288,6 +288,7 @@
rx-clock = <0>;
tx-clock = <19>;
phy-handle = <&qe_phy0>;
+ phy-connection-type = "gmii";
pio-handle = <&pio1>;
};
@@ -303,6 +304,7 @@
rx-clock = <0>;
tx-clock = <14>;
phy-handle = <&qe_phy1>;
+ phy-connection-type = "gmii";
pio-handle = <&pio2>;
};
@@ -320,28 +322,24 @@
interrupts = <31 1>;
reg = <0>;
device_type = "ethernet-phy";
- interface = <6>; //ENET_1000_GMII
};
qe_phy1: ethernet-phy@01 {
interrupt-parent = <&mpic>;
interrupts = <32 1>;
reg = <1>;
device_type = "ethernet-phy";
- interface = <6>;
};
qe_phy2: ethernet-phy@02 {
interrupt-parent = <&mpic>;
interrupts = <31 1>;
reg = <2>;
device_type = "ethernet-phy";
- interface = <6>; //ENET_1000_GMII
};
qe_phy3: ethernet-phy@03 {
interrupt-parent = <&mpic>;
interrupts = <32 1>;
reg = <3>;
device_type = "ethernet-phy";
- interface = <6>; //ENET_1000_GMII
};
};
diff --git a/arch/powerpc/boot/ebony.c b/arch/powerpc/boot/ebony.c
new file mode 100644
index 0000000..b1251ee
--- /dev/null
+++ b/arch/powerpc/boot/ebony.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2007 David Gibson, IBM Corporation.
+ *
+ * Based on earlier code:
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003, 2004 Zultys Technologies
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "string.h"
+#include "stdio.h"
+#include "page.h"
+#include "ops.h"
+#include "reg.h"
+#include "dcr.h"
+#include "44x.h"
+
+extern char _dtb_start[];
+extern char _dtb_end[];
+
+static u8 *ebony_mac0, *ebony_mac1;
+
+/* Calculate 440GP clocks */
+void ibm440gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk)
+{
+ u32 sys0 = mfdcr(DCRN_CPC0_SYS0);
+ u32 cr0 = mfdcr(DCRN_CPC0_CR0);
+ u32 cpu, plb, opb, ebc, tb, uart0, uart1, m;
+ u32 opdv = CPC0_SYS0_OPDV(sys0);
+ u32 epdv = CPC0_SYS0_EPDV(sys0);
+
+ if (sys0 & CPC0_SYS0_BYPASS) {
+ /* Bypass system PLL */
+ cpu = plb = sysclk;
+ } else {
+ if (sys0 & CPC0_SYS0_EXTSL)
+ /* PerClk */
+ m = CPC0_SYS0_FWDVB(sys0) * opdv * epdv;
+ else
+ /* CPU clock */
+ m = CPC0_SYS0_FBDV(sys0) * CPC0_SYS0_FWDVA(sys0);
+ cpu = sysclk * m / CPC0_SYS0_FWDVA(sys0);
+ plb = sysclk * m / CPC0_SYS0_FWDVB(sys0);
+ }
+
+ opb = plb / opdv;
+ ebc = opb / epdv;
+
+ /* FIXME: Check if this is for all 440GP, or just Ebony */
+ if ((mfpvr() & 0xf0000fff) == 0x40000440)
+ /* Rev. B 440GP, use external system clock */
+ tb = sysclk;
+ else
+ /* Rev. C 440GP, errata force us to use internal clock */
+ tb = cpu;
+
+ if (cr0 & CPC0_CR0_U0EC)
+ /* External UART clock */
+ uart0 = ser_clk;
+ else
+ /* Internal UART clock */
+ uart0 = plb / CPC0_CR0_UDIV(cr0);
+
+ if (cr0 & CPC0_CR0_U1EC)
+ /* External UART clock */
+ uart1 = ser_clk;
+ else
+ /* Internal UART clock */
+ uart1 = plb / CPC0_CR0_UDIV(cr0);
+
+ printf("PPC440GP: SysClk = %dMHz (%x)\n\r",
+ (sysclk + 500000) / 1000000, sysclk);
+
+ dt_fixup_cpu_clocks(cpu, tb, 0);
+
+ dt_fixup_clock("/plb", plb);
+ dt_fixup_clock("/plb/opb", opb);
+ dt_fixup_clock("/plb/opb/ebc", ebc);
+ dt_fixup_clock("/plb/opb/serial@40000200", uart0);
+ dt_fixup_clock("/plb/opb/serial@40000300", uart1);
+}
+
+static void ebony_fixups(void)
+{
+ // FIXME: sysclk should be derived by reading the FPGA registers
+ unsigned long sysclk = 33000000;
+
+ ibm440gp_fixup_clocks(sysclk, 6 * 1843200);
+ ibm44x_fixup_memsize();
+ dt_fixup_mac_addresses(ebony_mac0, ebony_mac1);
+}
+
+#define SPRN_DBCR0 0x134
+#define DBCR0_RST_SYSTEM 0x30000000
+
+static void ebony_exit(void)
+{
+ unsigned long tmp;
+
+ asm volatile (
+ "mfspr %0,%1\n"
+ "oris %0,%0,%2@h\n"
+ "mtspr %1,%0"
+ : "=&r"(tmp) : "i"(SPRN_DBCR0), "i"(DBCR0_RST_SYSTEM)
+ );
+
+}
+
+void ebony_init(void *mac0, void *mac1)
+{
+ platform_ops.fixups = ebony_fixups;
+ platform_ops.exit = ebony_exit;
+ ebony_mac0 = mac0;
+ ebony_mac1 = mac1;
+ ft_init(_dtb_start, _dtb_end - _dtb_start, 32);
+ serial_console_init();
+}
diff --git a/arch/powerpc/boot/holly.c b/arch/powerpc/boot/holly.c
new file mode 100644
index 0000000..7d6539f
--- /dev/null
+++ b/arch/powerpc/boot/holly.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2007 IBM Corporation
+ *
+ * Stephen Winiecki <stevewin@us.ibm.com>
+ * Josh Boyer <jwboyer@linux.vnet.ibm.com>
+ *
+ * Based on earlier code:
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "string.h"
+#include "stdio.h"
+#include "page.h"
+#include "ops.h"
+#include "io.h"
+
+extern char _start[];
+extern char _end[];
+extern char _dtb_start[];
+extern char _dtb_end[];
+
+BSS_STACK(4096);
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5)
+{
+ u32 heapsize = 0x8000000 - (u32)_end; /* 128M */
+
+ simple_alloc_init(_end, heapsize, 32, 64);
+ ft_init(_dtb_start, 0, 4);
+ serial_console_init();
+}
diff --git a/arch/powerpc/boot/mktree.c b/arch/powerpc/boot/mktree.c
index 4cb8929..45d06a8 100644
--- a/arch/powerpc/boot/mktree.c
+++ b/arch/powerpc/boot/mktree.c
@@ -46,8 +46,8 @@ int main(int argc, char *argv[])
struct stat st;
boot_block_t bt;
- if (argc < 3) {
- fprintf(stderr, "usage: %s <zImage-file> <boot-image> [entry-point]\n",argv[0]);
+ if (argc < 5) {
+ fprintf(stderr, "usage: %s <zImage-file> <boot-image> <load address> <entry point>\n",argv[0]);
exit(1);
}
@@ -61,10 +61,8 @@ int main(int argc, char *argv[])
bt.bb_magic = htonl(0x0052504F);
/* If we have the optional entry point parameter, use it */
- if (argc == 4)
- bt.bb_dest = bt.bb_entry_point = htonl(strtoul(argv[3], NULL, 0));
- else
- bt.bb_dest = bt.bb_entry_point = htonl(0x500000);
+ bt.bb_dest = htonl(strtoul(argv[3], NULL, 0));
+ bt.bb_entry_point = htonl(strtoul(argv[4], NULL, 0));
/* We know these from the linker command.
* ...and then move it up into memory a little more so the
diff --git a/arch/powerpc/boot/treeboot-ebony.c b/arch/powerpc/boot/treeboot-ebony.c
new file mode 100644
index 0000000..8436a9c
--- /dev/null
+++ b/arch/powerpc/boot/treeboot-ebony.c
@@ -0,0 +1,34 @@
+/*
+ * Old U-boot compatibility for Ebony
+ *
+ * Author: David Gibson <david@gibson.dropbear.id.au>
+ *
+ * Copyright 2007 David Gibson, IBM Corporatio.
+ * Based on cuboot-83xx.c, which is:
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "ops.h"
+#include "stdio.h"
+#include "44x.h"
+
+extern char _end[];
+
+BSS_STACK(4096);
+
+#define OPENBIOS_MAC_BASE 0xfffffe0c
+#define OPENBIOS_MAC_OFFSET 0xc
+
+void platform_init(void)
+{
+ unsigned long end_of_ram = 0x8000000;
+ unsigned long avail_ram = end_of_ram - (unsigned long)_end;
+
+ simple_alloc_init(_end, avail_ram, 32, 64);
+ ebony_init((u8 *)OPENBIOS_MAC_BASE,
+ (u8 *)(OPENBIOS_MAC_BASE + OPENBIOS_MAC_OFFSET));
+}
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index 5cedd90..2ed8b8b 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -163,20 +163,19 @@ fi
vmz="$vmz$gzip"
-case "$platform" in
-uboot|cuboot*)
- version=`${CROSS}strings "$kernel" | grep '^Linux version [-0-9.]' | \
- cut -d' ' -f3`
- if [ -n "$version" ]; then
- version="-n Linux-$version"
- fi
-esac
+# Extract kernel version information, some platforms want to include
+# it in the image header
+version=`${CROSS}strings "$kernel" | grep '^Linux version [-0-9.]' | \
+ cut -d' ' -f3`
+if [ -n "$version" ]; then
+ uboot_version="-n Linux-$version"
+fi
case "$platform" in
uboot)
rm -f "$ofile"
mkimage -A ppc -O linux -T kernel -C gzip -a 00000000 -e 00000000 \
- $version -d "$vmz" "$ofile"
+ $uboot_version -d "$vmz" "$ofile"
if [ -z "$cacheit" ]; then
rm -f "$vmz"
fi
@@ -212,25 +211,32 @@ if [ "$platform" != "miboot" ]; then
rm $tmp
fi
+# Some platforms need the zImage's entry point and base address
+base=0x`${CROSS}nm "$ofile" | grep ' _start$' | cut -d' ' -f1`
+entry=`${CROSS}objdump -f "$ofile" | grep '^start address ' | cut -d' ' -f3`
+
# post-processing needed for some platforms
case "$platform" in
pseries|chrp)
$object/addnote "$ofile"
;;
pmaccoff)
- entry=`objdump -f "$ofile" | grep '^start address ' | \
- cut -d' ' -f3`
${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile"
$object/hack-coff "$ofile"
;;
cuboot*)
- base=`${CROSS}nm "$ofile" | grep ' _start$' | cut -d' ' -f1`
- entry=`${CROSS}objdump -f "$ofile" | grep '^start address ' | \
- cut -d' ' -f3`
mv "$ofile" "$ofile".elf
${CROSS}objcopy -O binary "$ofile".elf "$ofile".bin
gzip -f -9 "$ofile".bin
mkimage -A ppc -O linux -T kernel -C gzip -a "$base" -e "$entry" \
- $version -d "$ofile".bin.gz "$ofile"
+ $uboot_version -d "$ofile".bin.gz "$ofile"
+ ;;
+treeboot*)
+ mv "$ofile" "$ofile.elf"
+ $object/mktree "$ofile.elf" "$ofile" "$base" "$entry"
+ if [ -z "$cacheit" ]; then
+ rm -f "$ofile.elf"
+ fi
+ exit 0
;;
esac
diff --git a/arch/powerpc/configs/ebony_defconfig b/arch/powerpc/configs/ebony_defconfig
new file mode 100644
index 0000000..c3b96ef
--- /dev/null
+++ b/arch/powerpc/configs/ebony_defconfig
@@ -0,0 +1,905 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21
+# Fri May 4 13:47:08 2007
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+# CONFIG_CLASSIC32 is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+CONFIG_44x=y
+# CONFIG_E200 is not set
+CONFIG_PPC_DCR_NATIVE=y
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_PPC_DCR=y
+CONFIG_4xx=y
+CONFIG_BOOKE=y
+CONFIG_PTE_64BIT=y
+CONFIG_PHYS_64BIT=y
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Platform support
+#
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+CONFIG_EBONY=y
+CONFIG_440GP=y
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPM2 is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_MATH_EMULATION=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_SECCOMP=y
+CONFIG_WANT_DEVICE_TREE=y
+CONFIG_DEVICE_TREE="ebony.dts"
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+# CONFIG_PPC_INDIRECT_PCI_BE is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_BOOT_LOAD=0x01000000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=35000
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=128
+CONFIG_IBM_NEW_EMAC_TXB=64
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+# CONFIG_IBM_NEW_EMAC_DEBUG is not set
+CONFIG_IBM_NEW_EMAC_ZMII=y
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+# CONFIG_UCC_SLOW is not set
+# CONFIG_UCC_FAST is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUGGER is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=y
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/configs/holly_defconfig b/arch/powerpc/configs/holly_defconfig
new file mode 100644
index 0000000..be633b9
--- /dev/null
+++ b/arch/powerpc/configs/holly_defconfig
@@ -0,0 +1,1070 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21
+# Sat May 5 11:02:35 2007
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_6xx=y
+CONFIG_PPC_FPU=y
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+# CONFIG_ALTIVEC is not set
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_SMP is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Platform support
+#
+# CONFIG_PPC_MULTIPLATFORM is not set
+CONFIG_EMBEDDED6xx=y
+# CONFIG_APUS is not set
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_LINKSTATION is not set
+# CONFIG_MPC7448HPC2 is not set
+CONFIG_PPC_HOLLY=y
+CONFIG_TSI108_BRIDGE=y
+CONFIG_MPIC=y
+CONFIG_MPIC_WEIRD=y
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_CPM2 is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_WANT_DEVICE_TREE is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+# CONFIG_PPC_INDIRECT_PCI is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_ESP_CORE is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=y
+# CONFIG_TYPHOON is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_TSI108_ETH=y
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+# CONFIG_UCC_SLOW is not set
+# CONFIG_UCC_FAST is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+# CONFIG_KPROBES is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_DEBUGGER=y
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
+CONFIG_XMON_DISASSEMBLY=y
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
diff --git a/arch/powerpc/configs/mpc832x_mds_defconfig b/arch/powerpc/configs/mpc832x_mds_defconfig
index e1b36de..83192c0 100644
--- a/arch/powerpc/configs/mpc832x_mds_defconfig
+++ b/arch/powerpc/configs/mpc832x_mds_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20-rc5
-# Tue Jan 30 14:27:25 2007
+# Linux kernel version: 2.6.21-rc5
+# Mon Apr 9 16:09:16 2007
#
# CONFIG_PPC64 is not set
CONFIG_PPC32=y
@@ -34,9 +34,9 @@ CONFIG_DEFAULT_UIMAGE=y
CONFIG_PPC_83xx=y
# CONFIG_PPC_85xx is not set
# CONFIG_PPC_86xx is not set
+# CONFIG_PPC_8xx is not set
# CONFIG_40x is not set
# CONFIG_44x is not set
-# CONFIG_8xx is not set
# CONFIG_E200 is not set
CONFIG_6xx=y
CONFIG_83xx=y
@@ -63,6 +63,7 @@ CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
@@ -71,6 +72,7 @@ CONFIG_SYSVIPC=y
# CONFIG_IKCONFIG is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
@@ -123,16 +125,17 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
CONFIG_QUICC_ENGINE=y
-CONFIG_PPC_GEN550=y
# CONFIG_WANT_EARLY_SERIAL is not set
#
# Platform support
#
+# CONFIG_MPC8313_RDB is not set
CONFIG_MPC832x_MDS=y
-# CONFIG_MPC834x_SYS is not set
+# CONFIG_MPC832x_RDB is not set
+# CONFIG_MPC834x_MDS is not set
# CONFIG_MPC834x_ITX is not set
-# CONFIG_MPC8360E_PB is not set
+# CONFIG_MPC836x_MDS is not set
CONFIG_PPC_MPC832x=y
# CONFIG_MPIC is not set
@@ -163,6 +166,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
CONFIG_PROC_DEVICETREE=y
# CONFIG_CMDLINE_BOOL is not set
# CONFIG_PM is not set
@@ -172,6 +176,7 @@ CONFIG_ISA_DMA_API=y
#
# Bus options
#
+CONFIG_ZONE_DMA=y
CONFIG_GENERIC_ISA_DMA=y
# CONFIG_MPIC_WEIRD is not set
# CONFIG_PPC_I8259 is not set
@@ -220,6 +225,7 @@ CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -324,6 +330,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -342,7 +349,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=32768
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -482,7 +488,21 @@ CONFIG_NETDEVICES=y
#
# PHY device support
#
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+CONFIG_DAVICOM_PHY=y
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_FIXED_PHY is not set
#
# Ethernet (10 or 100Mbit)
@@ -524,11 +544,13 @@ CONFIG_UCC_GETH=y
# CONFIG_UGETH_FILTERING is not set
# CONFIG_UGETH_TX_ON_DEMOND is not set
# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
#
# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
@@ -621,6 +643,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -691,6 +714,7 @@ CONFIG_I2C_MPC=y
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PASEMI is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
# CONFIG_I2C_SIS5595 is not set
@@ -738,6 +762,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
@@ -779,6 +804,11 @@ CONFIG_HWMON=y
# CONFIG_HWMON_DEBUG_CHIP is not set
#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -791,10 +821,9 @@ CONFIG_HWMON=y
#
# Graphics support
#
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# CONFIG_FB is not set
# CONFIG_FB_IBM_GXT4500 is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -805,6 +834,7 @@ CONFIG_FIRMWARE_EDID=y
# HID Devices
#
CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
#
# USB support
@@ -869,6 +899,10 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
#
+# Auxiliary Display support
+#
+
+#
# Virtualization
#
@@ -995,11 +1029,7 @@ CONFIG_PARTITION_ADVANCED=y
# Distributed Lock Manager
#
# CONFIG_DLM is not set
-
-#
-# QE Options
-#
-CONFIG_UCC_SLOW=y
+# CONFIG_UCC_SLOW is not set
CONFIG_UCC_FAST=y
CONFIG_UCC=y
@@ -1012,7 +1042,8 @@ CONFIG_BITREVERSE=y
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
-CONFIG_IOMAP_COPY=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
#
# Instrumentation Support
@@ -1032,7 +1063,6 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_BOOTX_TEXT is not set
-# CONFIG_SERIAL_TEXT_DEBUG is not set
# CONFIG_PPC_EARLY_DEBUG is not set
#
@@ -1061,8 +1091,10 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_LRW is not set
CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_SERPENT is not set
@@ -1076,6 +1108,7 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
#
diff --git a/arch/powerpc/configs/mpc832x_rdb_defconfig b/arch/powerpc/configs/mpc832x_rdb_defconfig
index 56fc0a8..4a4da87 100644
--- a/arch/powerpc/configs/mpc832x_rdb_defconfig
+++ b/arch/powerpc/configs/mpc832x_rdb_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21-rc3
-# Mon Mar 12 17:32:19 2007
+# Linux kernel version: 2.6.21-rc5
+# Mon Apr 9 16:12:43 2007
#
# CONFIG_PPC64 is not set
CONFIG_PPC32=y
@@ -125,7 +125,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
CONFIG_QUICC_ENGINE=y
-CONFIG_PPC_GEN550=y
# CONFIG_WANT_EARLY_SERIAL is not set
#
@@ -490,7 +489,21 @@ CONFIG_NETDEVICES=y
#
# PHY device support
#
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+CONFIG_ICPLUS_PHY=y
+# CONFIG_FIXED_PHY is not set
#
# Ethernet (10 or 100Mbit)
@@ -1200,11 +1213,7 @@ CONFIG_NLS_ISO8859_1=y
# Distributed Lock Manager
#
# CONFIG_DLM is not set
-
-#
-# QE Options
-#
-CONFIG_UCC_SLOW=y
+# CONFIG_UCC_SLOW is not set
CONFIG_UCC_FAST=y
CONFIG_UCC=y
@@ -1238,7 +1247,6 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_BOOTX_TEXT is not set
-# CONFIG_SERIAL_TEXT_DEBUG is not set
# CONFIG_PPC_EARLY_DEBUG is not set
#
diff --git a/arch/powerpc/configs/mpc836x_mds_defconfig b/arch/powerpc/configs/mpc836x_mds_defconfig
index 8eb475c..921a151 100644
--- a/arch/powerpc/configs/mpc836x_mds_defconfig
+++ b/arch/powerpc/configs/mpc836x_mds_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Sat Feb 17 10:09:26 2007
+# Linux kernel version: 2.6.21-rc5
+# Mon Apr 9 16:14:05 2007
#
# CONFIG_PPC64 is not set
CONFIG_PPC32=y
@@ -72,6 +72,7 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_IKCONFIG is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
@@ -124,7 +125,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
CONFIG_QUICC_ENGINE=y
-CONFIG_PPC_GEN550=y
# CONFIG_WANT_EARLY_SERIAL is not set
#
@@ -132,6 +132,7 @@ CONFIG_PPC_GEN550=y
#
# CONFIG_MPC8313_RDB is not set
# CONFIG_MPC832x_MDS is not set
+# CONFIG_MPC832x_RDB is not set
# CONFIG_MPC834x_MDS is not set
# CONFIG_MPC834x_ITX is not set
CONFIG_MPC836x_MDS=y
@@ -328,6 +329,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -346,7 +348,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=32768
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -486,7 +487,21 @@ CONFIG_NETDEVICES=y
#
# PHY device support
#
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_FIXED_PHY is not set
#
# Ethernet (10 or 100Mbit)
@@ -528,6 +543,7 @@ CONFIG_UCC_GETH=y
# CONFIG_UGETH_FILTERING is not set
# CONFIG_UGETH_TX_ON_DEMOND is not set
# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
@@ -745,6 +761,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
@@ -786,6 +803,11 @@ CONFIG_HWMON=y
# CONFIG_HWMON_DEBUG_CHIP is not set
#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -798,10 +820,9 @@ CONFIG_HWMON=y
#
# Graphics support
#
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# CONFIG_FB is not set
# CONFIG_FB_IBM_GXT4500 is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -1007,11 +1028,7 @@ CONFIG_PARTITION_ADVANCED=y
# Distributed Lock Manager
#
# CONFIG_DLM is not set
-
-#
-# QE Options
-#
-CONFIG_UCC_SLOW=y
+# CONFIG_UCC_SLOW is not set
CONFIG_UCC_FAST=y
CONFIG_UCC=y
@@ -1045,7 +1062,6 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_BOOTX_TEXT is not set
-# CONFIG_SERIAL_TEXT_DEBUG is not set
# CONFIG_PPC_EARLY_DEBUG is not set
#
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
index 0345a2c..fd60496 100644
--- a/arch/powerpc/configs/ps3_defconfig
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20-rc6
-# Thu Jan 25 13:35:34 2007
+# Linux kernel version: 2.6.21
+# Mon Apr 30 12:03:35 2007
#
CONFIG_PPC64=y
CONFIG_64BIT=y
@@ -60,6 +60,7 @@ CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
@@ -69,6 +70,7 @@ CONFIG_SYSVIPC=y
# CONFIG_CPUSETS is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
@@ -131,13 +133,36 @@ CONFIG_PPC_MULTIPLATFORM=y
# CONFIG_PPC_PSERIES is not set
# CONFIG_PPC_ISERIES is not set
# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_MPC5200 is not set
# CONFIG_PPC_PMAC is not set
# CONFIG_PPC_MAPLE is not set
# CONFIG_PPC_PASEMI is not set
+# CONFIG_PPC_CELLEB is not set
+CONFIG_PPC_PS3=y
+
+#
+# PS3 Platform Options
+#
+# CONFIG_PS3_ADVANCED is not set
+CONFIG_PS3_HTAB_SIZE=20
+# CONFIG_PS3_DYNAMIC_DMA is not set
+CONFIG_PS3_USE_LPAR_ADDR=y
+CONFIG_PS3_VUART=y
+CONFIG_PS3_PS3AV=y
+CONFIG_PS3_SYS_MANAGER=y
CONFIG_PPC_CELL=y
# CONFIG_PPC_CELL_NATIVE is not set
# CONFIG_PPC_IBM_CELL_BLADE is not set
-CONFIG_PPC_PS3=y
+
+#
+# Cell Broadband Engine options
+#
+CONFIG_SPU_FS=y
+CONFIG_SPU_BASE=y
+# CONFIG_PQ2ADS is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
# CONFIG_U3_DART is not set
# CONFIG_PPC_RTAS is not set
# CONFIG_MMIO_NVRAM is not set
@@ -146,24 +171,7 @@ CONFIG_PPC_PS3=y
# CONFIG_PPC_INDIRECT_IO is not set
# CONFIG_GENERIC_IOMAP is not set
# CONFIG_CPU_FREQ is not set
-# CONFIG_WANT_EARLY_SERIAL is not set
-# CONFIG_MPIC is not set
-
-#
-# Cell Broadband Engine options
-#
-CONFIG_SPU_FS=y
-CONFIG_SPU_BASE=y
-# CONFIG_CBE_RAS is not set
-
-#
-# PS3 Platform Options
-#
-CONFIG_PS3_HTAB_SIZE=20
-# CONFIG_PS3_DYNAMIC_DMA is not set
-CONFIG_PS3_USE_LPAR_ADDR=y
-CONFIG_PS3_VUART=y
-CONFIG_PS3_PS3AV=y
+# CONFIG_CPM2 is not set
#
# Kernel options
@@ -179,10 +187,10 @@ CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_BKL is not set
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=y
-CONFIG_FORCE_MAX_ZONEORDER=9
+CONFIG_FORCE_MAX_ZONEORDER=13
# CONFIG_IOMMU_VMERGE is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
-# CONFIG_KEXEC is not set
+CONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set
# CONFIG_IRQ_ALL_CPUS is not set
# CONFIG_NUMA is not set
@@ -203,22 +211,22 @@ CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTPLUG_SPARSE=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
CONFIG_ARCH_MEMORY_PROBE=y
-CONFIG_PPC_64K_PAGES=y
+# CONFIG_PPC_64K_PAGES is not set
# CONFIG_SCHED_SMT is not set
CONFIG_PROC_DEVICETREE=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="root=/dev/sda1 ip=dhcp"
+# CONFIG_CMDLINE_BOOL is not set
# CONFIG_PM is not set
# CONFIG_SECCOMP is not set
+# CONFIG_WANT_DEVICE_TREE is not set
CONFIG_ISA_DMA_API=y
#
# Bus options
#
+CONFIG_ZONE_DMA=y
CONFIG_GENERIC_ISA_DMA=y
-# CONFIG_MPIC_WEIRD is not set
-# CONFIG_PPC_I8259 is not set
# CONFIG_PCI is not set
# CONFIG_PCI_DOMAINS is not set
@@ -240,10 +248,13 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -261,7 +272,7 @@ CONFIG_IP_PNP_DHCP=y
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
# CONFIG_INET_XFRM_MODE_TUNNEL is not set
# CONFIG_INET_XFRM_MODE_BEET is not set
@@ -270,9 +281,23 @@ CONFIG_IP_PNP_DHCP=y
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
-# CONFIG_IPV6 is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
@@ -313,7 +338,31 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
-# CONFIG_BT is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+# CONFIG_BT_RFCOMM_TTY is not set
+# CONFIG_BT_BNEP is not set
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
# CONFIG_IEEE80211 is not set
#
@@ -327,16 +376,13 @@ CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
#
# Connector - unified userspace <-> kernelspace linker
#
# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
# CONFIG_MTD is not set
#
@@ -347,24 +393,27 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_UB is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65535
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
#
# Misc devices
#
-# CONFIG_TIFM_CORE is not set
#
# ATA/ATAPI/MFM/RLL support
@@ -388,7 +437,7 @@ CONFIG_BLK_DEV_SD=y
# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=y
# CONFIG_BLK_DEV_SR_VENDOR is not set
-# CONFIG_CHR_DEV_SG is not set
+CONFIG_CHR_DEV_SG=m
# CONFIG_CHR_DEV_SCH is not set
#
@@ -413,6 +462,7 @@ CONFIG_BLK_DEV_SR=y
#
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_ESP_CORE is not set
#
# Serial ATA (prod) and Parallel ATA (experimental) drivers
@@ -460,7 +510,7 @@ CONFIG_NETDEVICES=y
# Ethernet (10 or 100Mbit)
#
# CONFIG_NET_ETHERNET is not set
-CONFIG_MII=y
+CONFIG_MII=m
#
# Ethernet (1000 Mbit)
@@ -475,9 +525,10 @@ CONFIG_MII=y
#
#
-# Wireless LAN (non-hamradio)
+# Wireless LAN
#
-# CONFIG_NET_RADIO is not set
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
#
# Wan interfaces
@@ -551,7 +602,8 @@ CONFIG_HW_CONSOLE=y
# Non-8250 serial port support
#
CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
#
# IPMI
@@ -598,6 +650,11 @@ CONFIG_GEN_RTC=y
# CONFIG_HWMON_VID is not set
#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -611,15 +668,22 @@ CONFIG_GEN_RTC=y
#
# Graphics support
#
-# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
# CONFIG_FB_OF is not set
# CONFIG_FB_VGA16 is not set
# CONFIG_FB_S1D13XXX is not set
@@ -634,7 +698,7 @@ CONFIG_FB_PS3_DEFAULT_SIZE_M=18
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
@@ -646,17 +710,62 @@ CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
#
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA PowerMac devices
+#
+
+#
+# ALSA PowerMac requires I2C
+#
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_USX2Y is not set
+
+#
+# SoC audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
#
# HID Devices
#
CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
#
# USB support
@@ -665,13 +774,13 @@ CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
-CONFIG_USB_DEBUG=y
+# CONFIG_USB_DEBUG is not set
#
# Miscellaneous USB options
#
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
@@ -704,7 +813,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
#
# may also be needed; see USB_STORAGE Help for more information
#
-CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
@@ -720,10 +829,16 @@ CONFIG_USB_STORAGE=y
#
# USB Input Devices
#
-CONFIG_USB_HID=y
+CONFIG_USB_HID=m
# CONFIG_USB_HIDINPUT_POWERBOOK is not set
# CONFIG_HID_FF is not set
# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
# CONFIG_USB_ACECAD is not set
@@ -736,6 +851,7 @@ CONFIG_USB_HID=y
# CONFIG_USB_ATI_REMOTE2 is not set
# CONFIG_USB_KEYSPAN_REMOTE is not set
# CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
#
# USB Imaging devices
@@ -748,15 +864,16 @@ CONFIG_USB_HID=y
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
+CONFIG_USB_PEGASUS=m
# CONFIG_USB_RTL8150 is not set
-CONFIG_USB_USBNET_MII=y
-CONFIG_USB_USBNET=y
-CONFIG_USB_NET_CDCETHER=y
+CONFIG_USB_USBNET_MII=m
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_CDCETHER is not set
+# CONFIG_USB_NET_DM9601 is not set
# CONFIG_USB_NET_GL620A is not set
# CONFIG_USB_NET_NET1080 is not set
# CONFIG_USB_NET_PLUSB is not set
-CONFIG_USB_NET_MCS7830=y
+CONFIG_USB_NET_MCS7830=m
# CONFIG_USB_NET_RNDIS_HOST is not set
# CONFIG_USB_NET_CDC_SUBSET is not set
# CONFIG_USB_NET_ZAURUS is not set
@@ -781,6 +898,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
@@ -791,6 +909,8 @@ CONFIG_USB_MON=y
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
#
# USB DSL modem support
@@ -846,13 +966,19 @@ CONFIG_USB_MON=y
#
#
+# Auxiliary Display support
+#
+
+#
# Virtualization
#
#
# File systems
#
-# CONFIG_EXT2_FS is not set
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -871,27 +997,30 @@ CONFIG_FS_MBCACHE=y
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS4_FS=y
# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
#
-CONFIG_ISO9660_FS=y
+CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
# CONFIG_ZISOFS is not set
-CONFIG_UDF_FS=y
+CONFIG_UDF_FS=m
CONFIG_UDF_NLS=y
#
# DOS/FAT/NT Filesystems
#
-CONFIG_FAT_FS=y
+CONFIG_FAT_FS=m
# CONFIG_MSDOS_FS is not set
-CONFIG_VFAT_FS=y
+CONFIG_VFAT_FS=m
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set
@@ -933,7 +1062,7 @@ CONFIG_RAMFS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
+CONFIG_NFS_V4=y
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
@@ -941,10 +1070,16 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
@@ -1004,6 +1139,8 @@ CONFIG_NLS_ISO8859_1=y
# Distributed Lock Manager
#
# CONFIG_DLM is not set
+# CONFIG_UCC_SLOW is not set
+# CONFIG_UCC_FAST is not set
#
# Library routines
@@ -1014,7 +1151,8 @@ CONFIG_BITREVERSE=y
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
-CONFIG_IOMAP_COPY=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
#
# Instrumentation Support
@@ -1032,16 +1170,16 @@ CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
CONFIG_LOG_BUF_SHIFT=17
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
-CONFIG_DEBUG_SLAB=y
-# CONFIG_DEBUG_SLAB_LEAK is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_RWSEMS=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
@@ -1051,8 +1189,10 @@ CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_LIST=y
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUGGER is not set
CONFIG_IRQSTACKS=y
# CONFIG_BOOTX_TEXT is not set
@@ -1063,6 +1203,8 @@ CONFIG_PPC_EARLY_DEBUG=y
# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
+# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
+# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
#
# Security options
@@ -1073,4 +1215,43 @@ CONFIG_PPC_EARLY_DEBUG=y
#
# Cryptographic options
#
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index aa693d0..3e779f0 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -36,8 +36,9 @@ obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
obj-$(CONFIG_TAU) += tau_6xx.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o suspend.o
obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o
-obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
+obj64-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_64.o swsusp_asm64.o
obj32-$(CONFIG_MODULES) += module_32.o
ifeq ($(CONFIG_PPC_MERGE),y)
@@ -67,6 +68,7 @@ obj-$(CONFIG_MODULES) += $(module-y)
pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o
pci32-$(CONFIG_PPC32) := pci_32.o
obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y)
+obj-$(CONFIG_PCI_MSI) += msi.o
kexec-$(CONFIG_PPC64) := machine_kexec_64.o
kexec-$(CONFIG_PPC32) := machine_kexec_32.o
obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o $(kexec-y)
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 0c5150c..8f48560 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -21,12 +21,12 @@
#include <linux/types.h>
#include <linux/mman.h>
#include <linux/mm.h>
+#include <linux/suspend.h>
#ifdef CONFIG_PPC64
#include <linux/time.h>
#include <linux/hardirq.h>
#else
#include <linux/ptrace.h>
-#include <linux/suspend.h>
#endif
#include <asm/io.h>
@@ -257,11 +257,11 @@ int main(void)
DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
-#ifndef CONFIG_PPC64
DEFINE(pbe_address, offsetof(struct pbe, address));
DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
DEFINE(pbe_next, offsetof(struct pbe, next));
+#ifndef CONFIG_PPC64
DEFINE(TASK_SIZE, TASK_SIZE);
DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
#endif /* ! CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index a15d4b8..8869596 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -120,8 +120,8 @@ skpinv: addi r4,r4,1 /* Increment */
* Configure and load pinned entry into TLB slot 63.
*/
- lis r3,KERNELBASE@h /* Load the kernel virtual address */
- ori r3,r3,KERNELBASE@l
+ lis r3,PAGE_OFFSET@h
+ ori r3,r3,PAGE_OFFSET@l
/* Kernel is at the base of RAM */
li r4, 0 /* Load the kernel physical address */
@@ -172,36 +172,28 @@ skpinv: addi r4,r4,1 /* Increment */
isync
4:
-#ifdef CONFIG_SERIAL_TEXT_DEBUG
- /*
- * Add temporary UART mapping for early debug.
- * We can map UART registers wherever we want as long as they don't
- * interfere with other system mappings (e.g. with pinned entries).
- * For an example of how we handle this - see ocotea.h. --ebs
- */
+#ifdef CONFIG_PPC_EARLY_DEBUG_44x
+ /* Add UART mapping for early debug. */
+
/* pageid fields */
- lis r3,UART0_IO_BASE@h
- ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_4K
+ lis r3,PPC44x_EARLY_DEBUG_VIRTADDR@h
+ ori r3,r3,PPC44x_TLB_VALID|PPC44x_TLB_TS|PPC44x_TLB_64K
/* xlat fields */
- lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */
-#ifndef CONFIG_440EP
- ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */
-#endif
+ lis r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h
+ ori r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH
/* attrib fields */
- li r5,0
- ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G)
+ li r5,(PPC44x_TLB_SW|PPC44x_TLB_SR|PPC44x_TLB_I|PPC44x_TLB_G)
+ li r0,62 /* TLB slot 0 */
- li r0,0 /* TLB slot 0 */
-
- tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
- tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */
- tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
+ tlbwe r3,r0,PPC44x_TLB_PAGEID
+ tlbwe r4,r0,PPC44x_TLB_XLAT
+ tlbwe r5,r0,PPC44x_TLB_ATTRIB
/* Force context change */
isync
-#endif /* CONFIG_SERIAL_TEXT_DEBUG */
+#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
/* Establish the interrupt vector offsets */
SET_IVOR(0, CriticalInput);
@@ -709,16 +701,6 @@ _GLOBAL(giveup_fpu)
blr
#endif
-/*
- * extern void abort(void)
- *
- * At present, this routine just applies a system reset.
- */
-_GLOBAL(abort)
- mfspr r13,SPRN_DBCR0
- oris r13,r13,DBCR0_RST_SYSTEM@h
- mtspr SPRN_DBCR0,r13
-
_GLOBAL(set_context)
#ifdef CONFIG_BDI_SWITCH
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index 6e7f509..a9e9cbd 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -33,8 +33,11 @@
#include <asm/smp.h>
#ifdef CONFIG_HOTPLUG_CPU
+/* this is used for software suspend, and that shuts down
+ * CPUs even while the system is still booting... */
#define cpu_should_die() (cpu_is_offline(smp_processor_id()) && \
- system_state == SYSTEM_RUNNING)
+ (system_state == SYSTEM_RUNNING \
+ || system_state == SYSTEM_BOOTING))
#else
#define cpu_should_die() 0
#endif
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index ba31954..5328709 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -53,3 +53,24 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
isync
b 1b
+_GLOBAL(power4_cpu_offline_powersave)
+ /* Go to NAP now */
+ mfmsr r7
+ rldicl r0,r7,48,1
+ rotldi r0,r0,16
+ mtmsrd r0,1 /* hard-disable interrupts */
+ li r0,1
+ li r6,0
+ stb r0,PACAHARDIRQEN(r13) /* we'll hard-enable shortly */
+ stb r6,PACASOFTIRQEN(r13) /* soft-disable irqs */
+BEGIN_FTR_SECTION
+ DSSALL
+ sync
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ ori r7,r7,MSR_EE
+ oris r7,r7,MSR_POW@h
+ sync
+ isync
+ mtmsrd r7
+ isync
+ blr
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 6c83fe2..9ed4931 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -67,6 +67,7 @@
#ifdef CONFIG_PPC64
#include <asm/paca.h>
#include <asm/firmware.h>
+#include <asm/lv1call.h>
#endif
int __irq_offset_value;
@@ -162,6 +163,16 @@ void local_irq_restore(unsigned long en)
local_paca->hard_enabled = en;
if ((int)mfspr(SPRN_DEC) < 0)
mtspr(SPRN_DEC, 1);
+
+ /*
+ * Force the delivery of pending soft-disabled interrupts on PS3.
+ * Any HV call will have this side effect.
+ */
+ if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
+ u64 tmp;
+ lv1_get_version_info(&tmp);
+ }
+
hard_irq_enable();
}
#endif /* CONFIG_PPC64 */
@@ -947,33 +958,6 @@ arch_initcall(irq_late_init);
#endif /* CONFIG_PPC_MERGE */
-#ifdef CONFIG_PCI_MSI
-int pci_enable_msi(struct pci_dev * pdev)
-{
- if (ppc_md.enable_msi)
- return ppc_md.enable_msi(pdev);
- else
- return -1;
-}
-EXPORT_SYMBOL(pci_enable_msi);
-
-void pci_disable_msi(struct pci_dev * pdev)
-{
- if (ppc_md.disable_msi)
- ppc_md.disable_msi(pdev);
-}
-EXPORT_SYMBOL(pci_disable_msi);
-
-void pci_scan_msi_device(struct pci_dev *dev) {}
-int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;}
-void pci_disable_msix(struct pci_dev *dev) {}
-void msi_remove_pci_irq_vectors(struct pci_dev *dev) {}
-void pci_no_msi(void) {}
-EXPORT_SYMBOL(pci_enable_msix);
-EXPORT_SYMBOL(pci_disable_msix);
-
-#endif
-
#ifdef CONFIG_PPC64
static int __init setup_noirqdistrib(char *str)
{
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index ef647e7..0c96611 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -30,8 +30,8 @@
#include <linux/ptrace.h>
#include <linux/preempt.h>
#include <linux/module.h>
+#include <linux/kdebug.h>
#include <asm/cacheflush.h>
-#include <asm/kdebug.h>
#include <asm/sstep.h>
#include <asm/uaccess.h>
@@ -126,22 +126,13 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
- struct kretprobe_instance *ri;
-
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *)regs->link;
-
- /* Replace the return addr with trampoline addr */
- regs->link = (unsigned long)kretprobe_trampoline;
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ ri->ret_addr = (kprobe_opcode_t *)regs->link;
+
+ /* Replace the return addr with trampoline addr */
+ regs->link = (unsigned long)kretprobe_trampoline;
}
static int __kprobes kprobe_handler(struct pt_regs *regs)
@@ -336,7 +327,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
break;
}
- BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
+ kretprobe_assert(ri, orig_ret_address, trampoline_address);
regs->nip = orig_ret_address;
reset_current_kprobe();
@@ -410,7 +401,7 @@ out:
return 1;
}
-static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
{
struct kprobe *cur = kprobe_running();
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -495,14 +486,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
if (post_kprobe_handler(args->regs))
ret = NOTIFY_STOP;
break;
- case DIE_PAGE_FAULT:
- /* kprobe_running() needs smp_processor_id() */
- preempt_disable();
- if (kprobe_running() &&
- kprobe_fault_handler(args->regs, args->trapnr))
- ret = NOTIFY_STOP;
- preempt_enable();
- break;
default:
break;
}
@@ -559,3 +542,11 @@ int __init arch_init_kprobes(void)
{
return register_kprobe(&trampoline_p);
}
+
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+ if (p->addr == (kprobe_opcode_t *)&kretprobe_trampoline)
+ return 1;
+
+ return 0;
+}
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 63dd2c3..cea8045 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -115,7 +115,8 @@ static int __init add_legacy_soc_port(struct device_node *np,
{
u64 addr;
const u32 *addrp;
- upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
+ upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ
+ | UPF_FIXED_PORT;
struct device_node *tsi = of_get_parent(np);
/* We only support ports that have a clock frequency properly
@@ -243,9 +244,9 @@ static int __init add_legacy_pci_port(struct device_node *np,
* doesn't work for these settings, you'll have to add your own special
* cases here
*/
- if (device_is_compatible(pci_dev, "pci13a8,152") ||
- device_is_compatible(pci_dev, "pci13a8,154") ||
- device_is_compatible(pci_dev, "pci13a8,158")) {
+ if (of_device_is_compatible(pci_dev, "pci13a8,152") ||
+ of_device_is_compatible(pci_dev, "pci13a8,154") ||
+ of_device_is_compatible(pci_dev, "pci13a8,158")) {
addr += 0x200 * lindex;
base += 0x200 * lindex;
} else {
@@ -364,11 +365,11 @@ void __init find_legacy_serial_ports(void)
/* Check for known pciclass, and also check wether we have
* a device with child nodes for ports or not
*/
- if (device_is_compatible(np, "pciclass,0700") ||
- device_is_compatible(np, "pciclass,070002"))
+ if (of_device_is_compatible(np, "pciclass,0700") ||
+ of_device_is_compatible(np, "pciclass,070002"))
pci = np;
- else if (device_is_compatible(parent, "pciclass,0700") ||
- device_is_compatible(parent, "pciclass,070002"))
+ else if (of_device_is_compatible(parent, "pciclass,0700") ||
+ of_device_is_compatible(parent, "pciclass,070002"))
pci = parent;
else {
of_node_put(parent);
diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c
new file mode 100644
index 0000000..c62d101
--- /dev/null
+++ b/arch/powerpc/kernel/msi.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/msi.h>
+
+#include <asm/machdep.h>
+
+int arch_msi_check_device(struct pci_dev* dev, int nvec, int type)
+{
+ if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) {
+ pr_debug("msi: Platform doesn't provide MSI callbacks.\n");
+ return -ENOSYS;
+ }
+
+ if (ppc_md.msi_check_device) {
+ pr_debug("msi: Using platform check routine.\n");
+ return ppc_md.msi_check_device(dev, nvec, type);
+ }
+
+ return 0;
+}
+
+int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+{
+ return ppc_md.setup_msi_irqs(dev, nvec, type);
+}
+
+void arch_teardown_msi_irqs(struct pci_dev *dev)
+{
+ return ppc_md.teardown_msi_irqs(dev);
+}
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 0c8ea76..a464d67 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -27,7 +27,7 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches,
match &= node->type
&& !strcmp(matches->type, node->type);
if (matches->compatible[0])
- match &= device_is_compatible(node,
+ match &= of_device_is_compatible(node,
matches->compatible);
if (match)
return matches;
@@ -120,8 +120,8 @@ void of_device_unregister(struct of_device *ofdev)
}
-static ssize_t of_device_get_modalias(struct of_device *ofdev,
- char *str, ssize_t len)
+ssize_t of_device_get_modalias(struct of_device *ofdev,
+ char *str, ssize_t len)
{
const char *compat;
int cplen, i;
@@ -239,3 +239,4 @@ EXPORT_SYMBOL(of_dev_get);
EXPORT_SYMBOL(of_dev_put);
EXPORT_SYMBOL(of_release_dev);
EXPORT_SYMBOL(of_device_uevent);
+EXPORT_SYMBOL(of_device_get_modalias);
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index 908ed79..84c34d9 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -29,7 +29,6 @@
#include <asm/ppc-pci.h>
#include <asm/atomic.h>
-
/*
* The list of OF IDs below is used for matching bus types in the
* system whose devices are to be exposed as of_platform_devices.
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index f022862..e66064b 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -1658,7 +1658,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file,
int i;
if (page_is_ram(pfn))
- return prot;
+ return __pgprot(prot);
prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 7138092..6d05a1f 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -1006,8 +1006,9 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
switch ((pci_space >> 24) & 0x3) {
case 1: /* I/O space */
- hose->io_base_phys = cpu_phys_addr;
- hose->pci_io_size = size;
+ hose->io_base_phys = cpu_phys_addr - pci_addr;
+ /* handle from 0 to top of I/O window */
+ hose->pci_io_size = pci_addr + size;
res = &hose->io_resource;
res->flags = IORESOURCE_IO;
@@ -1117,8 +1118,8 @@ static int get_bus_io_range(struct pci_bus *bus, unsigned long *start_phys,
} else {
/* Root Bus */
res = &hose->io_resource;
- *start_phys = hose->io_base_phys;
- *start_virt = (unsigned long) hose->io_base_virt;
+ *start_phys = hose->io_base_phys + res->start;
+ *start_virt = (unsigned long) hose->io_base_virt + res->start;
if (res->end > res->start)
*size = res->end - res->start + 1;
else {
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index ff252aa..c96fa9b 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -66,7 +66,6 @@ EXPORT_SYMBOL(clear_pages);
EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
EXPORT_SYMBOL(DMA_MODE_READ);
EXPORT_SYMBOL(DMA_MODE_WRITE);
-EXPORT_SYMBOL(__div64_32);
EXPORT_SYMBOL(do_signal);
EXPORT_SYMBOL(transfer_to_handler);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index e509aae..6e2f035 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -19,7 +19,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index e27d9d1..d6047c4 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -635,6 +635,12 @@ static void __init early_cmdline_parse(void)
/* ibm,dynamic-reconfiguration-memory property supported */
#define OV5_DRCONF_MEMORY 0x20
#define OV5_LARGE_PAGES 0x10 /* large pages supported */
+/* PCIe/MSI support. Without MSI full PCIe is not supported */
+#ifdef CONFIG_PCI_MSI
+#define OV5_MSI 0x01 /* PCIe/MSI support */
+#else
+#define OV5_MSI 0x00
+#endif /* CONFIG_PCI_MSI */
/*
* The architecture vector has an array of PVR mask/value pairs,
@@ -679,7 +685,7 @@ static unsigned char ibm_architecture_vec[] = {
/* option vector 5: PAPR/OF options */
3 - 2, /* length */
0, /* don't ignore, don't halt */
- OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY,
+ OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY | OV5_MSI,
};
/* Old method - ELF header with PT_NOTE sections */
@@ -967,7 +973,7 @@ static unsigned long __init prom_next_cell(int s, cell_t **cellp)
* If problems seem to show up, it would be a good start to track
* them down.
*/
-static void reserve_mem(u64 base, u64 size)
+static void __init reserve_mem(u64 base, u64 size)
{
u64 top = base + size;
unsigned long cnt = RELOC(mem_reserve_cnt);
@@ -2153,7 +2159,7 @@ static void __init fixup_device_tree_efika(void)
3,12,0, 3,13,0, 3,14,0, 3,15,0 };
struct subst_entry efika_subst_table[] = {
{ "/", "device_type", prop_cstr("efika") },
- { "/builtin", "compatible", prop_cstr("soc") },
+ { "/builtin", "device_type", prop_cstr("soc") },
{ "/builtin/ata", "compatible", prop_cstr("mpc5200b-ata\0mpc5200-ata"), },
{ "/builtin/bestcomm", "compatible", prop_cstr("mpc5200b-bestcomm\0mpc5200-bestcomm") },
{ "/builtin/bestcomm", "interrupts", prop_bcomm_irq, sizeof(prop_bcomm_irq) },
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index aa40a53..b5c96af 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -1042,3 +1042,28 @@ const void *of_get_mac_address(struct device_node *np)
}
EXPORT_SYMBOL(of_get_mac_address);
+int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
+{
+ int irq = irq_of_parse_and_map(dev, index);
+
+ /* Only dereference the resource if both the
+ * resource and the irq are valid. */
+ if (r && irq != NO_IRQ) {
+ r->start = r->end = irq;
+ r->flags = IORESOURCE_IRQ;
+ }
+
+ return irq;
+}
+EXPORT_SYMBOL_GPL(of_irq_to_resource);
+
+void __iomem *of_iomap(struct device_node *np, int index)
+{
+ struct resource res;
+
+ if (of_address_to_resource(np, index, &res))
+ return NULL;
+
+ return ioremap(res.start, 1 + res.end - res.start);
+}
+EXPORT_SYMBOL(of_iomap);
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index cc44c7b..f4f391c 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -19,7 +19,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 6b405a3..dd1dca5 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -20,7 +20,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index f72e8e8..1ce0ae3 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -15,7 +15,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index d8e503b..22f1ef1 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -176,10 +176,10 @@ static struct call_data_struct {
#define SMP_CALL_TIMEOUT 8
/*
- * This function sends a 'generic call function' IPI to all other CPUs
- * in the system.
+ * These functions send a 'generic call function' IPI to other online
+ * CPUS in the system.
*
- * [SUMMARY] Run a function on all other CPUs.
+ * [SUMMARY] Run a function on other CPUs.
* <func> The function to run. This must be fast and non-blocking.
* <info> An arbitrary pointer to pass to the function.
* <nonatomic> currently unused.
@@ -190,18 +190,26 @@ static struct call_data_struct {
* You must not call this function with disabled interrupts or from a
* hardware interrupt handler or from a bottom half handler.
*/
-int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
- int wait)
-{
+int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic,
+ int wait, cpumask_t map)
+{
struct call_data_struct data;
- int ret = -1, cpus;
+ int ret = -1, num_cpus;
+ int cpu;
u64 timeout;
/* Can deadlock when called with interrupts disabled */
WARN_ON(irqs_disabled());
+ /* remove 'self' from the map */
+ if (cpu_isset(smp_processor_id(), map))
+ cpu_clear(smp_processor_id(), map);
+
+ /* sanity check the map, remove any non-online processors. */
+ cpus_and(map, map, cpu_online_map);
+
if (unlikely(smp_ops == NULL))
- return -1;
+ return ret;
data.func = func;
data.info = info;
@@ -213,40 +221,42 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
spin_lock(&call_lock);
/* Must grab online cpu count with preempt disabled, otherwise
* it can change. */
- cpus = num_online_cpus() - 1;
- if (!cpus) {
+ num_cpus = num_online_cpus() - 1;
+ if (!num_cpus || cpus_empty(map)) {
ret = 0;
goto out;
}
call_data = &data;
smp_wmb();
- /* Send a message to all other CPUs and wait for them to respond */
- smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION);
+ /* Send a message to all CPUs in the map */
+ for_each_cpu_mask(cpu, map)
+ smp_ops->message_pass(cpu, PPC_MSG_CALL_FUNCTION);
timeout = get_tb() + (u64) SMP_CALL_TIMEOUT * tb_ticks_per_sec;
- /* Wait for response */
- while (atomic_read(&data.started) != cpus) {
+ /* Wait for indication that they have received the message */
+ while (atomic_read(&data.started) != num_cpus) {
HMT_low();
if (get_tb() >= timeout) {
printk("smp_call_function on cpu %d: other cpus not "
- "responding (%d)\n", smp_processor_id(),
- atomic_read(&data.started));
+ "responding (%d)\n", smp_processor_id(),
+ atomic_read(&data.started));
debugger(NULL);
goto out;
}
}
+ /* optionally wait for the CPUs to complete */
if (wait) {
- while (atomic_read(&data.finished) != cpus) {
+ while (atomic_read(&data.finished) != num_cpus) {
HMT_low();
if (get_tb() >= timeout) {
printk("smp_call_function on cpu %d: other "
- "cpus not finishing (%d/%d)\n",
- smp_processor_id(),
- atomic_read(&data.finished),
- atomic_read(&data.started));
+ "cpus not finishing (%d/%d)\n",
+ smp_processor_id(),
+ atomic_read(&data.finished),
+ atomic_read(&data.started));
debugger(NULL);
goto out;
}
@@ -262,8 +272,29 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
return ret;
}
+int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
+ int wait)
+{
+ return smp_call_function_map(func,info,nonatomic,wait,cpu_online_map);
+}
EXPORT_SYMBOL(smp_call_function);
+int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int nonatomic,
+ int wait)
+{
+ cpumask_t map=CPU_MASK_NONE;
+
+ if (!cpu_online(cpu))
+ return -EINVAL;
+
+ if (cpu == smp_processor_id())
+ return -EBUSY;
+
+ cpu_set(cpu, map);
+ return smp_call_function_map(func,info,nonatomic,wait,map);
+}
+EXPORT_SYMBOL(smp_call_function_single);
+
void smp_call_function_interrupt(void)
{
void (*func) (void *info);
diff --git a/arch/powerpc/kernel/swsusp.c b/arch/powerpc/kernel/swsusp.c
new file mode 100644
index 0000000..064a7ba
--- /dev/null
+++ b/arch/powerpc/kernel/swsusp.c
@@ -0,0 +1,43 @@
+/*
+ * Common powerpc suspend code for 32 and 64 bits
+ *
+ * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/sched.h>
+#include <asm/suspend.h>
+#include <asm/system.h>
+#include <asm/current.h>
+#include <asm/mmu_context.h>
+
+void save_processor_state(void)
+{
+ /*
+ * flush out all the special registers so we don't need
+ * to save them in the snapshot
+ */
+ flush_fp_to_thread(current);
+ flush_altivec_to_thread(current);
+ flush_spe_to_thread(current);
+
+#ifdef CONFIG_PPC64
+ hard_irq_disable();
+#endif
+
+}
+
+void restore_processor_state(void)
+{
+#ifdef CONFIG_PPC32
+ set_context(current->active_mm->context.id, current->active_mm->pgd);
+#endif
+
+#ifdef CONFIG_PPC64
+ hard_irq_enable();
+#endif
+}
diff --git a/arch/powerpc/kernel/swsusp_64.c b/arch/powerpc/kernel/swsusp_64.c
new file mode 100644
index 0000000..6f3f069
--- /dev/null
+++ b/arch/powerpc/kernel/swsusp_64.c
@@ -0,0 +1,24 @@
+/*
+ * PowerPC 64-bit swsusp implementation
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPLv2
+ */
+
+#include <asm/system.h>
+#include <asm/iommu.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+void do_after_copyback(void)
+{
+ iommu_restore();
+ touch_softlockup_watchdog();
+ mb();
+}
+
+void _iommu_save(void)
+{
+ iommu_save();
+}
diff --git a/arch/powerpc/kernel/swsusp_asm64.S b/arch/powerpc/kernel/swsusp_asm64.S
new file mode 100644
index 0000000..e092c3c
--- /dev/null
+++ b/arch/powerpc/kernel/swsusp_asm64.S
@@ -0,0 +1,228 @@
+/*
+ * PowerPC 64-bit swsusp implementation
+ *
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * GPLv2
+ */
+
+#include <linux/threads.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+/*
+ * Structure for storing CPU registers on the save area.
+ */
+#define SL_r1 0x00 /* stack pointer */
+#define SL_PC 0x08
+#define SL_MSR 0x10
+#define SL_SDR1 0x18
+#define SL_XER 0x20
+#define SL_TB 0x40
+#define SL_r2 0x48
+#define SL_CR 0x50
+#define SL_LR 0x58
+#define SL_r12 0x60
+#define SL_r13 0x68
+#define SL_r14 0x70
+#define SL_r15 0x78
+#define SL_r16 0x80
+#define SL_r17 0x88
+#define SL_r18 0x90
+#define SL_r19 0x98
+#define SL_r20 0xa0
+#define SL_r21 0xa8
+#define SL_r22 0xb0
+#define SL_r23 0xb8
+#define SL_r24 0xc0
+#define SL_r25 0xc8
+#define SL_r26 0xd0
+#define SL_r27 0xd8
+#define SL_r28 0xe0
+#define SL_r29 0xe8
+#define SL_r30 0xf0
+#define SL_r31 0xf8
+#define SL_SIZE SL_r31+8
+
+/* these macros rely on the save area being
+ * pointed to by r11 */
+#define SAVE_SPECIAL(special) \
+ mf##special r0 ;\
+ std r0, SL_##special(r11)
+#define RESTORE_SPECIAL(special) \
+ ld r0, SL_##special(r11) ;\
+ mt##special r0
+#define SAVE_REGISTER(reg) \
+ std reg, SL_##reg(r11)
+#define RESTORE_REGISTER(reg) \
+ ld reg, SL_##reg(r11)
+
+/* space for storing cpu state */
+ .section .data
+ .align 5
+swsusp_save_area:
+ .space SL_SIZE
+
+ .section ".toc","aw"
+swsusp_save_area_ptr:
+ .tc swsusp_save_area[TC],swsusp_save_area
+restore_pblist_ptr:
+ .tc restore_pblist[TC],restore_pblist
+
+ .section .text
+ .align 5
+_GLOBAL(swsusp_arch_suspend)
+ ld r11,swsusp_save_area_ptr@toc(r2)
+ SAVE_SPECIAL(LR)
+ SAVE_REGISTER(r1)
+ SAVE_SPECIAL(CR)
+ SAVE_SPECIAL(TB)
+ SAVE_REGISTER(r2)
+ SAVE_REGISTER(r12)
+ SAVE_REGISTER(r13)
+ SAVE_REGISTER(r14)
+ SAVE_REGISTER(r15)
+ SAVE_REGISTER(r16)
+ SAVE_REGISTER(r17)
+ SAVE_REGISTER(r18)
+ SAVE_REGISTER(r19)
+ SAVE_REGISTER(r20)
+ SAVE_REGISTER(r21)
+ SAVE_REGISTER(r22)
+ SAVE_REGISTER(r23)
+ SAVE_REGISTER(r24)
+ SAVE_REGISTER(r25)
+ SAVE_REGISTER(r26)
+ SAVE_REGISTER(r27)
+ SAVE_REGISTER(r28)
+ SAVE_REGISTER(r29)
+ SAVE_REGISTER(r30)
+ SAVE_REGISTER(r31)
+ SAVE_SPECIAL(MSR)
+ SAVE_SPECIAL(SDR1)
+ SAVE_SPECIAL(XER)
+
+ /* we push the stack up 128 bytes but don't store the
+ * stack pointer on the stack like a real stackframe */
+ addi r1,r1,-128
+
+ bl _iommu_save
+ bl swsusp_save
+
+ /* restore LR */
+ ld r11,swsusp_save_area_ptr@toc(r2)
+ RESTORE_SPECIAL(LR)
+ addi r1,r1,128
+
+ blr
+
+/* Resume code */
+_GLOBAL(swsusp_arch_resume)
+ /* Stop pending alitvec streams and memory accesses */
+BEGIN_FTR_SECTION
+ DSSALL
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+ sync
+
+ ld r12,restore_pblist_ptr@toc(r2)
+ ld r12,0(r12)
+
+ cmpdi r12,0
+ beq- nothing_to_copy
+ li r15,512
+copyloop:
+ ld r13,pbe_address(r12)
+ ld r14,pbe_orig_address(r12)
+
+ mtctr r15
+ li r10,0
+copy_page_loop:
+ ldx r0,r10,r13
+ stdx r0,r10,r14
+ addi r10,r10,8
+ bdnz copy_page_loop
+
+ ld r12,pbe_next(r12)
+ cmpdi r12,0
+ bne+ copyloop
+nothing_to_copy:
+
+ /* flush caches */
+ lis r3, 0x10
+ mtctr r3
+ li r3, 0
+ ori r3, r3, CONFIG_KERNEL_START>>48
+ li r0, 48
+ sld r3, r3, r0
+ li r0, 0
+1:
+ dcbf r0,r3
+ addi r3,r3,0x20
+ bdnz 1b
+
+ sync
+
+ tlbia
+
+ ld r11,swsusp_save_area_ptr@toc(r2)
+
+ RESTORE_SPECIAL(CR)
+
+ /* restore timebase */
+ /* load saved tb */
+ ld r1, SL_TB(r11)
+ /* get upper 32 bits of it */
+ srdi r2, r1, 32
+ /* clear tb lower to avoid wrap */
+ li r0, 0
+ mttbl r0
+ /* set tb upper */
+ mttbu r2
+ /* set tb lower */
+ mttbl r1
+
+ /* restore registers */
+ RESTORE_REGISTER(r1)
+ RESTORE_REGISTER(r2)
+ RESTORE_REGISTER(r12)
+ RESTORE_REGISTER(r13)
+ RESTORE_REGISTER(r14)
+ RESTORE_REGISTER(r15)
+ RESTORE_REGISTER(r16)
+ RESTORE_REGISTER(r17)
+ RESTORE_REGISTER(r18)
+ RESTORE_REGISTER(r19)
+ RESTORE_REGISTER(r20)
+ RESTORE_REGISTER(r21)
+ RESTORE_REGISTER(r22)
+ RESTORE_REGISTER(r23)
+ RESTORE_REGISTER(r24)
+ RESTORE_REGISTER(r25)
+ RESTORE_REGISTER(r26)
+ RESTORE_REGISTER(r27)
+ RESTORE_REGISTER(r28)
+ RESTORE_REGISTER(r29)
+ RESTORE_REGISTER(r30)
+ RESTORE_REGISTER(r31)
+ /* can't use RESTORE_SPECIAL(MSR) */
+ ld r0, SL_MSR(r11)
+ mtmsrd r0, 0
+ RESTORE_SPECIAL(SDR1)
+ RESTORE_SPECIAL(XER)
+
+ sync
+
+ addi r1,r1,-128
+ bl slb_flush_and_rebolt
+ bl do_after_copyback
+ addi r1,r1,128
+
+ ld r11,swsusp_save_area_ptr@toc(r2)
+ RESTORE_SPECIAL(LR)
+
+ li r3, 0
+ blr
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index d358866..fc6647d 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -24,7 +24,6 @@
#include <linux/syscalls.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 933e214..cae39d9 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -499,4 +499,4 @@ static int __init topology_init(void)
return 0;
}
-__initcall(topology_init);
+subsys_initcall(topology_init);
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index f786222..bf6445a 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -33,8 +33,8 @@
#include <linux/kexec.h>
#include <linux/backlight.h>
#include <linux/bug.h>
+#include <linux/kdebug.h>
-#include <asm/kdebug.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -72,20 +72,6 @@ EXPORT_SYMBOL(__debugger_dabr_match);
EXPORT_SYMBOL(__debugger_fault_handler);
#endif
-ATOMIC_NOTIFIER_HEAD(powerpc_die_chain);
-
-int register_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_register(&powerpc_die_chain, nb);
-}
-EXPORT_SYMBOL(register_die_notifier);
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&powerpc_die_chain, nb);
-}
-EXPORT_SYMBOL(unregister_die_notifier);
-
/*
* Trap & Exception support
*/
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 7e09718..87703df 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -51,6 +51,9 @@ void __init udbg_early_init(void)
udbg_init_pas_realmode();
#elif defined(CONFIG_BOOTX_TEXT)
udbg_init_btext();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
+ /* PPC44x debug */
+ udbg_init_44x_as1();
#endif
}
@@ -142,29 +145,22 @@ static void udbg_console_write(struct console *con, const char *s,
static struct console udbg_console = {
.name = "udbg",
.write = udbg_console_write,
- .flags = CON_PRINTBUFFER | CON_ENABLED,
+ .flags = CON_PRINTBUFFER | CON_ENABLED | CON_BOOT,
.index = -1,
};
static int early_console_initialized;
-void __init disable_early_printk(void)
-{
- if (!early_console_initialized)
- return;
- if (strstr(boot_command_line, "udbg-immortal")) {
- printk(KERN_INFO "early console immortal !\n");
- return;
- }
- unregister_console(&udbg_console);
- early_console_initialized = 0;
-}
-
/* called by setup_system */
void register_early_udbg_console(void)
{
if (early_console_initialized)
return;
+
+ if (strstr(boot_command_line, "udbg-immortal")) {
+ printk(KERN_INFO "early console immortal !\n");
+ udbg_console.flags &= ~CON_BOOT;
+ }
early_console_initialized = 1;
register_console(&udbg_console);
}
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index a963f65..7afab5b 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -191,3 +191,26 @@ void udbg_init_pas_realmode(void)
udbg_getc_poll = NULL;
}
#endif /* CONFIG_PPC_MAPLE */
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_44x
+#include <platforms/44x/44x.h>
+
+static void udbg_44x_as1_putc(char c)
+{
+ if (udbg_comport) {
+ while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
+ /* wait for idle */;
+ as1_writeb(c, &udbg_comport->thr); eieio();
+ if (c == '\n')
+ udbg_44x_as1_putc('\r');
+ }
+}
+
+void __init udbg_init_44x_as1(void)
+{
+ udbg_comport =
+ (volatile struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR;
+
+ udbg_putc = udbg_44x_as1_putc;
+}
+#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index e46c31b..4245579 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/slab.h>
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index b2c1b67a..62c1bc1 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -117,7 +117,7 @@ static const struct vio_device_id *vio_match_device(
{
while (ids->type[0] != '\0') {
if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) &&
- device_is_compatible(dev->dev.archdata.of_node,
+ of_device_is_compatible(dev->dev.archdata.of_node,
ids->compat))
return ids;
ids++;
diff --git a/arch/powerpc/lib/dma-noncoherent.c b/arch/powerpc/lib/dma-noncoherent.c
index 48f3d13..6656d47 100644
--- a/arch/powerpc/lib/dma-noncoherent.c
+++ b/arch/powerpc/lib/dma-noncoherent.c
@@ -306,13 +306,15 @@ EXPORT_SYMBOL(__dma_free_coherent);
static int __init dma_alloc_init(void)
{
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
int ret = 0;
do {
pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
- pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE);
+ pud = pud_alloc(&init_mm, pgd, CONSISTENT_BASE);
+ pmd = pmd_alloc(&init_mm, pud, CONSISTENT_BASE);
if (!pmd) {
printk(KERN_ERR "%s: no pmd tables\n", __func__);
ret = -ENOMEM;
diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c
index 0a0a0487b..ca4dcb0 100644
--- a/arch/powerpc/mm/44x_mmu.c
+++ b/arch/powerpc/mm/44x_mmu.c
@@ -24,73 +24,38 @@
*
*/
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/ptrace.h>
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/swap.h>
-#include <linux/stddef.h>
-#include <linux/vmalloc.h>
#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/highmem.h>
-
-#include <asm/pgalloc.h>
-#include <asm/prom.h>
-#include <asm/io.h>
-#include <asm/mmu_context.h>
-#include <asm/pgtable.h>
#include <asm/mmu.h>
-#include <asm/uaccess.h>
-#include <asm/smp.h>
-#include <asm/bootx.h>
-#include <asm/machdep.h>
-#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/page.h>
#include "mmu_decl.h"
-extern char etext[], _stext[];
-
/* Used by the 44x TLB replacement exception handler.
* Just needed it declared someplace.
*/
-unsigned int tlb_44x_index = 0;
-unsigned int tlb_44x_hwater = 62;
+unsigned int tlb_44x_index; /* = 0 */
+unsigned int tlb_44x_hwater = PPC44x_TLB_SIZE - 1 - PPC44x_EARLY_TLBS;
/*
* "Pins" a 256MB TLB entry in AS0 for kernel lowmem
*/
-static void __init
-ppc44x_pin_tlb(int slot, unsigned int virt, unsigned int phys)
+static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys)
{
- unsigned long attrib = 0;
-
- __asm__ __volatile__("\
- clrrwi %2,%2,10\n\
- ori %2,%2,%4\n\
- clrrwi %1,%1,10\n\
- li %0,0\n\
- ori %0,%0,%5\n\
- tlbwe %2,%3,%6\n\
- tlbwe %1,%3,%7\n\
- tlbwe %0,%3,%8"
+ __asm__ __volatile__(
+ "tlbwe %2,%3,%4\n"
+ "tlbwe %1,%3,%5\n"
+ "tlbwe %0,%3,%6\n"
:
- : "r" (attrib), "r" (phys), "r" (virt), "r" (slot),
- "i" (PPC44x_TLB_VALID | PPC44x_TLB_256M),
- "i" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
+ : "r" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
+ "r" (phys),
+ "r" (virt | PPC44x_TLB_VALID | PPC44x_TLB_256M),
+ "r" (tlb_44x_hwater--), /* slot for this TLB entry */
"i" (PPC44x_TLB_PAGEID),
"i" (PPC44x_TLB_XLAT),
"i" (PPC44x_TLB_ATTRIB));
}
-/*
- * MMU_init_hw does the chip-specific initialization of the MMU hardware.
- */
void __init MMU_init_hw(void)
{
flush_instruction_cache();
@@ -98,22 +63,13 @@ void __init MMU_init_hw(void)
unsigned long __init mmu_mapin_ram(void)
{
- unsigned int pinned_tlbs = 1;
- int i;
-
- /* Determine number of entries necessary to cover lowmem */
- pinned_tlbs = (unsigned int)
- (_ALIGN(total_lowmem, PPC_PIN_SIZE) >> PPC44x_PIN_SHIFT);
-
- /* Write upper watermark to save location */
- tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs;
+ unsigned long addr;
- /* If necessary, set additional pinned TLBs */
- if (pinned_tlbs > 1)
- for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) {
- unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC_PIN_SIZE;
- ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr);
- }
+ /* Pin in enough TLBs to cover any lowmem not covered by the
+ * initial 256M mapping established in head_44x.S */
+ for (addr = PPC_PIN_SIZE; addr < total_lowmem;
+ addr += PPC_PIN_SIZE)
+ ppc44x_pin_tlb(addr + PAGE_OFFSET, addr);
return total_lowmem;
}
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 03aeb3a..bfe9013 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -28,6 +28,7 @@
#include <linux/highmem.h>
#include <linux/module.h>
#include <linux/kprobes.h>
+#include <linux/kdebug.h>
#include <asm/page.h>
#include <asm/pgtable.h>
@@ -36,40 +37,28 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/tlbflush.h>
-#include <asm/kdebug.h>
#include <asm/siginfo.h>
-#ifdef CONFIG_KPROBES
-ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
-/* Hook to register for page fault notifications */
-int register_page_fault_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
-}
-
-int unregister_page_fault_notifier(struct notifier_block *nb)
+#ifdef CONFIG_KPROBES
+static inline int notify_page_fault(struct pt_regs *regs)
{
- return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
-}
+ int ret = 0;
+
+ /* kprobe_running() needs smp_processor_id() */
+ if (!user_mode(regs)) {
+ preempt_disable();
+ if (kprobe_running() && kprobe_fault_handler(regs, 11))
+ ret = 1;
+ preempt_enable();
+ }
-static inline int notify_page_fault(enum die_val val, const char *str,
- struct pt_regs *regs, long err, int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .str = str,
- .err = err,
- .trapnr = trap,
- .signr = sig
- };
- return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
+ return ret;
}
#else
-static inline int notify_page_fault(enum die_val val, const char *str,
- struct pt_regs *regs, long err, int trap, int sig)
+static inline int notify_page_fault(struct pt_regs *regs)
{
- return NOTIFY_DONE;
+ return 0;
}
#endif
@@ -175,8 +164,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
is_write = error_code & ESR_DST;
#endif /* CONFIG_4xx || CONFIG_BOOKE */
- if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, error_code,
- 11, SIGSEGV) == NOTIFY_STOP)
+ if (notify_page_fault(regs))
return 0;
if (trap == 0x300) {
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index 79aedaf..7b7fe2d 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -26,6 +26,7 @@
#include <asm/tlb.h>
#include <asm/cputable.h>
#include <asm/udbg.h>
+#include <asm/kexec.h>
#ifdef DEBUG_LOW
#define DBG_LOW(fmt...) udbg_printf(fmt)
@@ -340,31 +341,70 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va,
local_irq_restore(flags);
}
-/*
- * XXX This need fixing based on page size. It's only used by
- * native_hpte_clear() for now which needs fixing too so they
- * make a good pair...
- */
-static unsigned long slot2va(unsigned long hpte_v, unsigned long slot)
-{
- unsigned long avpn = HPTE_V_AVPN_VAL(hpte_v);
- unsigned long va;
+#define LP_SHIFT 12
+#define LP_BITS 8
+#define LP_MASK(i) ((0xFF >> (i)) << LP_SHIFT)
- va = avpn << 23;
+static void hpte_decode(hpte_t *hpte, unsigned long slot,
+ int *psize, unsigned long *va)
+{
+ unsigned long hpte_r = hpte->r;
+ unsigned long hpte_v = hpte->v;
+ unsigned long avpn;
+ int i, size, shift, penc, avpnm_bits;
+
+ if (!(hpte_v & HPTE_V_LARGE))
+ size = MMU_PAGE_4K;
+ else {
+ for (i = 0; i < LP_BITS; i++) {
+ if ((hpte_r & LP_MASK(i+1)) == LP_MASK(i+1))
+ break;
+ }
+ penc = LP_MASK(i+1) >> LP_SHIFT;
+ for (size = 0; size < MMU_PAGE_COUNT; size++) {
- if (! (hpte_v & HPTE_V_LARGE)) {
- unsigned long vpi, pteg;
+ /* 4K pages are not represented by LP */
+ if (size == MMU_PAGE_4K)
+ continue;
- pteg = slot / HPTES_PER_GROUP;
- if (hpte_v & HPTE_V_SECONDARY)
- pteg = ~pteg;
+ /* valid entries have a shift value */
+ if (!mmu_psize_defs[size].shift)
+ continue;
- vpi = ((va >> 28) ^ pteg) & htab_hash_mask;
+ if (penc == mmu_psize_defs[size].penc)
+ break;
+ }
+ }
- va |= vpi << PAGE_SHIFT;
+ /*
+ * FIXME, the code below works for 16M, 64K, and 4K pages as these
+ * fall under the p<=23 rules for calculating the virtual address.
+ * In the case of 16M pages, an extra bit is stolen from the AVPN
+ * field to achieve the requisite 24 bits.
+ *
+ * Does not work for 16G pages or 1 TB segments.
+ */
+ shift = mmu_psize_defs[size].shift;
+ if (mmu_psize_defs[size].avpnm)
+ avpnm_bits = __ilog2_u64(mmu_psize_defs[size].avpnm) + 1;
+ else
+ avpnm_bits = 0;
+ if (shift - avpnm_bits <= 23) {
+ avpn = HPTE_V_AVPN_VAL(hpte_v) << 23;
+
+ if (shift < 23) {
+ unsigned long vpi, pteg;
+
+ pteg = slot / HPTES_PER_GROUP;
+ if (hpte_v & HPTE_V_SECONDARY)
+ pteg = ~pteg;
+ vpi = ((avpn >> 28) ^ pteg) & htab_hash_mask;
+ avpn |= (vpi << mmu_psize_defs[size].shift);
+ }
}
- return va;
+ *va = avpn;
+ *psize = size;
}
/*
@@ -374,15 +414,14 @@ static unsigned long slot2va(unsigned long hpte_v, unsigned long slot)
*
* TODO: add batching support when enabled. remember, no dynamic memory here,
* athough there is the control page available...
- *
- * XXX FIXME: 4k only for now !
*/
static void native_hpte_clear(void)
{
unsigned long slot, slots, flags;
hpte_t *hptep = htab_address;
- unsigned long hpte_v;
+ unsigned long hpte_v, va;
unsigned long pteg_count;
+ int psize;
pteg_count = htab_hash_mask + 1;
@@ -408,8 +447,9 @@ static void native_hpte_clear(void)
* already hold the native_tlbie_lock.
*/
if (hpte_v & HPTE_V_VALID) {
+ hpte_decode(hptep, slot, &psize, &va);
hptep->v = 0;
- __tlbie(slot2va(hpte_v, slot), MMU_PAGE_4K);
+ __tlbie(va, psize);
}
}
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 4961846..9b226fa 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -103,7 +103,7 @@ int mmu_ci_restrictions;
#ifdef CONFIG_DEBUG_PAGEALLOC
static u8 *linear_map_hash_slots;
static unsigned long linear_map_hash_count;
-static spinlock_t linear_map_hash_lock;
+static DEFINE_SPINLOCK(linear_map_hash_lock);
#endif /* CONFIG_DEBUG_PAGEALLOC */
/* There are definitions of page sizes arrays to be used when none
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 8508f97..fb95926 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -12,7 +12,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/sysctl.h>
@@ -566,6 +565,13 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
if (len > TASK_SIZE)
return -ENOMEM;
+ /* handle fixed mapping: prevent overlap with huge pages */
+ if (flags & MAP_FIXED) {
+ if (is_hugepage_only_range(mm, addr, len))
+ return -EINVAL;
+ return addr;
+ }
+
if (addr) {
addr = PAGE_ALIGN(addr);
vma = find_vma(mm, addr);
@@ -641,6 +647,13 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
if (len > TASK_SIZE)
return -ENOMEM;
+ /* handle fixed mapping: prevent overlap with huge pages */
+ if (flags & MAP_FIXED) {
+ if (is_hugepage_only_range(mm, addr, len))
+ return -EINVAL;
+ return addr;
+ }
+
/* dont allow allocations above current base */
if (mm->free_area_cache > base)
mm->free_area_cache = base;
@@ -823,6 +836,13 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
/* Paranoia, caller should have dealt with this */
BUG_ON((addr + len) < addr);
+ /* Handle MAP_FIXED */
+ if (flags & MAP_FIXED) {
+ if (prepare_hugepage_range(addr, len, pgoff))
+ return -EINVAL;
+ return addr;
+ }
+
if (test_thread_flag(TIF_32BIT)) {
curareas = current->mm->context.low_htlb_areas;
@@ -1057,8 +1077,7 @@ static int __init hugetlbpage_init(void)
huge_pgtable_cache = kmem_cache_create("hugepte_cache",
HUGEPTE_TABLE_SIZE,
HUGEPTE_TABLE_SIZE,
- SLAB_HWCACHE_ALIGN |
- SLAB_MUST_HWCACHE_ALIGN,
+ 0,
zero_ctor, NULL);
if (! huge_pgtable_cache)
panic("hugetlbpage_init(): could not create hugepte cache\n");
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index d12a87e..fe1fe85 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -183,12 +183,8 @@ void pgtable_cache_init(void)
"for size: %08x...\n", name, i, size);
pgtable_cache[i] = kmem_cache_create(name,
size, size,
- SLAB_HWCACHE_ALIGN |
- SLAB_MUST_HWCACHE_ALIGN,
+ SLAB_PANIC,
zero_ctor,
NULL);
- if (! pgtable_cache[i])
- panic("pgtable_cache_init(): could not create %s!\n",
- name);
}
}
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index c4bcd75..1a6e08f 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -80,7 +80,6 @@ int page_is_ram(unsigned long pfn)
return 0;
#endif
}
-EXPORT_SYMBOL(page_is_ram);
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot)
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 9c4538b..2558c34 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -40,7 +40,8 @@ extern int __map_without_bats;
extern unsigned long ioremap_base;
extern unsigned int rtas_data, rtas_size;
-extern PTE *Hash, *Hash_end;
+struct _PTE;
+extern struct _PTE *Hash, *Hash_end;
extern unsigned long Hash_size, Hash_mask;
extern unsigned int num_tlbcam_entries;
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index bca5603..d8232b7 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -261,7 +261,7 @@ int map_page(unsigned long va, phys_addr_t pa, int flags)
int err = -ENOMEM;
/* Use upper 10 bits of VA to index the first level map */
- pd = pmd_offset(pgd_offset_k(va), va);
+ pd = pmd_offset(pud_offset(pgd_offset_k(va), va), va);
/* Use middle 10 bits of VA to index the second-level map */
pg = pte_alloc_kernel(pd, va);
if (pg != 0) {
@@ -354,23 +354,27 @@ int
get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp)
{
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
int retval = 0;
pgd = pgd_offset(mm, addr & PAGE_MASK);
if (pgd) {
- pmd = pmd_offset(pgd, addr & PAGE_MASK);
- if (pmd_present(*pmd)) {
- pte = pte_offset_map(pmd, addr & PAGE_MASK);
- if (pte) {
- retval = 1;
- *ptep = pte;
- if (pmdp)
- *pmdp = pmd;
- /* XXX caller needs to do pte_unmap, yuck */
- }
- }
+ pud = pud_offset(pgd, addr & PAGE_MASK);
+ if (pud && pud_present(*pud)) {
+ pmd = pmd_offset(pud, addr & PAGE_MASK);
+ if (pmd_present(*pmd)) {
+ pte = pte_offset_map(pmd, addr & PAGE_MASK);
+ if (pte) {
+ retval = 1;
+ *ptep = pte;
+ if (pmdp)
+ *pmdp = pmd;
+ /* XXX caller needs to do pte_unmap, yuck */
+ }
+ }
+ }
}
return(retval);
}
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
index eeeacab..132c6bc 100644
--- a/arch/powerpc/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -227,7 +227,7 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm)
* the first (bolted) segment, so that do_stab_bolted won't get a
* recursive segment miss on the segment table itself.
*/
-void stabs_alloc(void)
+void __init stabs_alloc(void)
{
int cpu;
diff --git a/arch/powerpc/platforms/44x/44x.h b/arch/powerpc/platforms/44x/44x.h
new file mode 100644
index 0000000..42eabf8
--- /dev/null
+++ b/arch/powerpc/platforms/44x/44x.h
@@ -0,0 +1,8 @@
+#ifndef __POWERPC_PLATFORMS_44X_44X_H
+#define __POWERPC_PLATFORMS_44X_44X_H
+
+extern u8 as1_readb(volatile u8 __iomem *addr);
+extern void as1_writeb(u8 data, volatile u8 __iomem *addr);
+extern void ppc44x_reset_system(char *cmd);
+
+#endif /* __POWERPC_PLATFORMS_44X_44X_H */
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
new file mode 100644
index 0000000..8e66949
--- /dev/null
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -0,0 +1,56 @@
+#config BAMBOO
+# bool "Bamboo"
+# depends on 44x
+# default n
+# select 440EP
+# help
+# This option enables support for the IBM PPC440EP evaluation board.
+
+config EBONY
+ bool "Ebony"
+ depends on 44x
+ default y
+ select 440GP
+ help
+ This option enables support for the IBM PPC440GP evaluation board.
+
+#config LUAN
+# bool "Luan"
+# depends on 44x
+# default n
+# select 440SP
+# help
+# This option enables support for the IBM PPC440SP evaluation board.
+
+#config OCOTEA
+# bool "Ocotea"
+# depends on 44x
+# default n
+# select 440GX
+# help
+# This option enables support for the IBM PPC440GX evaluation board.
+
+# 44x specific CPU modules, selected based on the board above.
+config 440EP
+ bool
+ select PPC_FPU
+ select IBM440EP_ERR42
+
+config 440GP
+ bool
+ select IBM_NEW_EMAC_ZMII
+
+config 440GX
+ bool
+
+config 440SP
+ bool
+
+config 440A
+ bool
+ depends on 440GX
+ default y
+
+# 44x errata/workaround config symbols, selected by the CPU models above
+config IBM440EP_ERR42
+ bool
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile
new file mode 100644
index 0000000..41d0a18
--- /dev/null
+++ b/arch/powerpc/platforms/44x/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_44x) := misc_44x.o
+obj-$(CONFIG_EBONY) += ebony.o
diff --git a/arch/powerpc/platforms/44x/ebony.c b/arch/powerpc/platforms/44x/ebony.c
new file mode 100644
index 0000000..ad526ea
--- /dev/null
+++ b/arch/powerpc/platforms/44x/ebony.c
@@ -0,0 +1,73 @@
+/*
+ * Ebony board specific routines
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003-2005 Zultys Technologies
+ *
+ * Rewritten and ported to the merged powerpc tree:
+ * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/time.h>
+#include <asm/uic.h>
+#include <asm/of_platform.h>
+
+#include "44x.h"
+
+static struct of_device_id ebony_of_bus[] = {
+ { .type = "ibm,plb", },
+ { .type = "ibm,opb", },
+ { .type = "ibm,ebc", },
+ {},
+};
+
+static int __init ebony_device_probe(void)
+{
+ if (!machine_is(ebony))
+ return 0;
+
+ of_platform_bus_probe(NULL, ebony_of_bus, NULL);
+
+ return 0;
+}
+device_initcall(ebony_device_probe);
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init ebony_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (!of_flat_dt_is_compatible(root, "ibm,ebony"))
+ return 0;
+
+ return 1;
+}
+
+static void __init ebony_setup_arch(void)
+{
+}
+
+define_machine(ebony) {
+ .name = "Ebony",
+ .probe = ebony_probe,
+ .setup_arch = ebony_setup_arch,
+ .progress = udbg_progress,
+ .init_IRQ = uic_init_tree,
+ .get_irq = uic_get_irq,
+ .restart = ppc44x_reset_system,
+ .calibrate_decr = generic_calibrate_decr,
+};
diff --git a/arch/powerpc/platforms/44x/misc_44x.S b/arch/powerpc/platforms/44x/misc_44x.S
new file mode 100644
index 0000000..3bce71d
--- /dev/null
+++ b/arch/powerpc/platforms/44x/misc_44x.S
@@ -0,0 +1,57 @@
+/*
+ * This file contains miscellaneous low-level functions for PPC 44x.
+ * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <asm/reg.h>
+#include <asm/ppc_asm.h>
+
+ .text
+
+/*
+ * Do an IO access in AS1
+ */
+_GLOBAL(as1_readb)
+ mfmsr r7
+ ori r0,r7,MSR_DS
+ sync
+ mtmsr r0
+ sync
+ isync
+ lbz r3,0(r3)
+ sync
+ mtmsr r7
+ sync
+ isync
+ blr
+
+_GLOBAL(as1_writeb)
+ mfmsr r7
+ ori r0,r7,MSR_DS
+ sync
+ mtmsr r0
+ sync
+ isync
+ stb r3,0(r4)
+ sync
+ mtmsr r7
+ sync
+ isync
+ blr
+
+/*
+ * void ppc44x_reset_system(char *cmd)
+ *
+ * At present, this routine just applies a system reset.
+ */
+_GLOBAL(ppc44x_reset_system)
+ mfspr r13,SPRN_DBCR0
+ oris r13,r13,DBCR0_RST_SYSTEM@h
+ mtspr SPRN_DBCR0,r13
+ b . /* Just in case the reset doesn't work */
diff --git a/arch/powerpc/platforms/52xx/Kconfig b/arch/powerpc/platforms/52xx/Kconfig
index bc4aa4a..3ffaa06 100644
--- a/arch/powerpc/platforms/52xx/Kconfig
+++ b/arch/powerpc/platforms/52xx/Kconfig
@@ -1,5 +1,6 @@
config PPC_MPC52xx
bool
+ select FSL_SOC
default n
config PPC_MPC5200
diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile
index 07cdbca..b91e39c 100644
--- a/arch/powerpc/platforms/52xx/Makefile
+++ b/arch/powerpc/platforms/52xx/Makefile
@@ -8,3 +8,5 @@ endif
obj-$(CONFIG_PPC_EFIKA) += efika.o
obj-$(CONFIG_PPC_LITE5200) += lite5200.o
+
+obj-$(CONFIG_PM) += mpc52xx_sleep.o mpc52xx_pm.o
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c
index a6bba97..f591a9f 100644
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -184,6 +184,16 @@ static void efika_show_cpuinfo(struct seq_file *m)
of_node_put(root);
}
+#ifdef CONFIG_PM
+static void efika_suspend_prepare(void __iomem *mbar)
+{
+ u8 pin = 4; /* GPIO_WKUP_4 (GPIO_PSC6_0 - IRDA_RX) */
+ u8 level = 1; /* wakeup on high level */
+ /* IOW. to wake it up, short pins 1 and 3 on IRDA connector */
+ mpc52xx_set_wakeup_gpio(pin, level);
+}
+#endif
+
static void __init efika_setup_arch(void)
{
rtas_initialize();
@@ -199,6 +209,11 @@ static void __init efika_setup_arch(void)
efika_pcisetup();
+#ifdef CONFIG_PM
+ mpc52xx_suspend.board_suspend_prepare = efika_suspend_prepare;
+ mpc52xx_pm_init();
+#endif
+
if (ppc_md.progress)
ppc_md.progress("Linux/PPC " UTS_RELEASE " running on Efika ;-)\n", 0x0);
}
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
index 8e2646a..1cfc00d 100644
--- a/arch/powerpc/platforms/52xx/lite5200.c
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -85,6 +85,28 @@ error:
iounmap(gpio);
}
+#ifdef CONFIG_PM
+static u32 descr_a;
+static void lite5200_suspend_prepare(void __iomem *mbar)
+{
+ u8 pin = 1; /* GPIO_WKUP_1 (GPIO_PSC2_4) */
+ u8 level = 0; /* wakeup on low level */
+ mpc52xx_set_wakeup_gpio(pin, level);
+
+ /*
+ * power down usb port
+ * this needs to be called before of-ohci suspend code
+ */
+ descr_a = in_be32(mbar + 0x1048);
+ out_be32(mbar + 0x1048, (descr_a & ~0x200) | 0x100);
+}
+
+static void lite5200_resume_finish(void __iomem *mbar)
+{
+ out_be32(mbar + 0x1048, descr_a);
+}
+#endif
+
static void __init lite5200_setup_arch(void)
{
struct device_node *np;
@@ -107,6 +129,12 @@ static void __init lite5200_setup_arch(void)
mpc52xx_setup_cpu(); /* Generic */
lite5200_setup_cpu(); /* Platorm specific */
+#ifdef CONFIG_PM
+ mpc52xx_suspend.board_suspend_prepare = lite5200_suspend_prepare;
+ mpc52xx_suspend.board_resume_finish = lite5200_resume_finish;
+ mpc52xx_pm_init();
+#endif
+
#ifdef CONFIG_PCI
np = of_find_node_by_type(NULL, "pci");
if (np) {
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
new file mode 100644
index 0000000..fd40044
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
@@ -0,0 +1,191 @@
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/io.h>
+#include <asm/time.h>
+#include <asm/cacheflush.h>
+#include <asm/mpc52xx.h>
+
+#include "mpc52xx_pic.h"
+
+
+/* these are defined in mpc52xx_sleep.S, and only used here */
+extern void mpc52xx_deep_sleep(void *sram, void *sdram_regs,
+ struct mpc52xx_cdm *, struct mpc52xx_intr *);
+extern void mpc52xx_ds_sram(void);
+extern const long mpc52xx_ds_sram_size;
+extern void mpc52xx_ds_cached(void);
+extern const long mpc52xx_ds_cached_size;
+
+static void __iomem *mbar;
+static void __iomem *sdram;
+static struct mpc52xx_cdm __iomem *cdm;
+static struct mpc52xx_intr __iomem *intr;
+static struct mpc52xx_gpio_wkup __iomem *gpiow;
+static void *sram;
+static int sram_size;
+
+struct mpc52xx_suspend mpc52xx_suspend;
+
+static int mpc52xx_pm_valid(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+int mpc52xx_set_wakeup_gpio(u8 pin, u8 level)
+{
+ u16 tmp;
+
+ /* enable gpio */
+ out_8(&gpiow->wkup_gpioe, in_8(&gpiow->wkup_gpioe) | (1 << pin));
+ /* set as input */
+ out_8(&gpiow->wkup_ddr, in_8(&gpiow->wkup_ddr) & ~(1 << pin));
+ /* enable deep sleep interrupt */
+ out_8(&gpiow->wkup_inten, in_8(&gpiow->wkup_inten) | (1 << pin));
+ /* low/high level creates wakeup interrupt */
+ tmp = in_be16(&gpiow->wkup_itype);
+ tmp &= ~(0x3 << (pin * 2));
+ tmp |= (!level + 1) << (pin * 2);
+ out_be16(&gpiow->wkup_itype, tmp);
+ /* master enable */
+ out_8(&gpiow->wkup_maste, 1);
+
+ return 0;
+}
+
+int mpc52xx_pm_prepare(suspend_state_t state)
+{
+ if (state != PM_SUSPEND_STANDBY)
+ return -EINVAL;
+
+ /* map the whole register space */
+ mbar = mpc52xx_find_and_map("mpc5200");
+ if (!mbar) {
+ printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__);
+ return -ENOSYS;
+ }
+ /* these offsets are from mpc5200 users manual */
+ sdram = mbar + 0x100;
+ cdm = mbar + 0x200;
+ intr = mbar + 0x500;
+ gpiow = mbar + 0xc00;
+ sram = mbar + 0x8000; /* Those will be handled by the */
+ sram_size = 0x4000; /* bestcomm driver soon */
+
+ /* call board suspend code, if applicable */
+ if (mpc52xx_suspend.board_suspend_prepare)
+ mpc52xx_suspend.board_suspend_prepare(mbar);
+ else {
+ printk(KERN_ALERT "%s: %i don't know how to wake up the board\n",
+ __func__, __LINE__);
+ goto out_unmap;
+ }
+
+ return 0;
+
+ out_unmap:
+ iounmap(mbar);
+ return -ENOSYS;
+}
+
+
+char saved_sram[0x4000];
+
+int mpc52xx_pm_enter(suspend_state_t state)
+{
+ u32 clk_enables;
+ u32 msr, hid0;
+ u32 intr_main_mask;
+ void __iomem * irq_0x500 = (void *)CONFIG_KERNEL_START + 0x500;
+ unsigned long irq_0x500_stop = (unsigned long)irq_0x500 + mpc52xx_ds_cached_size;
+ char saved_0x500[mpc52xx_ds_cached_size];
+
+ /* disable all interrupts in PIC */
+ intr_main_mask = in_be32(&intr->main_mask);
+ out_be32(&intr->main_mask, intr_main_mask | 0x1ffff);
+
+ /* don't let DEC expire any time soon */
+ mtspr(SPRN_DEC, 0x7fffffff);
+
+ /* save SRAM */
+ memcpy(saved_sram, sram, sram_size);
+
+ /* copy low level suspend code to sram */
+ memcpy(sram, mpc52xx_ds_sram, mpc52xx_ds_sram_size);
+
+ out_8(&cdm->ccs_sleep_enable, 1);
+ out_8(&cdm->osc_sleep_enable, 1);
+ out_8(&cdm->ccs_qreq_test, 1);
+
+ /* disable all but SDRAM and bestcomm (SRAM) clocks */
+ clk_enables = in_be32(&cdm->clk_enables);
+ out_be32(&cdm->clk_enables, clk_enables & 0x00088000);
+
+ /* disable power management */
+ msr = mfmsr();
+ mtmsr(msr & ~MSR_POW);
+
+ /* enable sleep mode, disable others */
+ hid0 = mfspr(SPRN_HID0);
+ mtspr(SPRN_HID0, (hid0 & ~(HID0_DOZE | HID0_NAP | HID0_DPM)) | HID0_SLEEP);
+
+ /* save original, copy our irq handler, flush from dcache and invalidate icache */
+ memcpy(saved_0x500, irq_0x500, mpc52xx_ds_cached_size);
+ memcpy(irq_0x500, mpc52xx_ds_cached, mpc52xx_ds_cached_size);
+ flush_icache_range((unsigned long)irq_0x500, irq_0x500_stop);
+
+ /* call low-level sleep code */
+ mpc52xx_deep_sleep(sram, sdram, cdm, intr);
+
+ /* restore original irq handler */
+ memcpy(irq_0x500, saved_0x500, mpc52xx_ds_cached_size);
+ flush_icache_range((unsigned long)irq_0x500, irq_0x500_stop);
+
+ /* restore old power mode */
+ mtmsr(msr & ~MSR_POW);
+ mtspr(SPRN_HID0, hid0);
+ mtmsr(msr);
+
+ out_be32(&cdm->clk_enables, clk_enables);
+ out_8(&cdm->ccs_sleep_enable, 0);
+ out_8(&cdm->osc_sleep_enable, 0);
+
+ /* restore SRAM */
+ memcpy(sram, saved_sram, sram_size);
+
+ /* restart jiffies */
+ wakeup_decrementer();
+
+ /* reenable interrupts in PIC */
+ out_be32(&intr->main_mask, intr_main_mask);
+
+ return 0;
+}
+
+int mpc52xx_pm_finish(suspend_state_t state)
+{
+ /* call board resume code */
+ if (mpc52xx_suspend.board_resume_finish)
+ mpc52xx_suspend.board_resume_finish(mbar);
+
+ iounmap(mbar);
+
+ return 0;
+}
+
+static struct pm_ops mpc52xx_pm_ops = {
+ .valid = mpc52xx_pm_valid,
+ .prepare = mpc52xx_pm_prepare,
+ .enter = mpc52xx_pm_enter,
+ .finish = mpc52xx_pm_finish,
+};
+
+int __init mpc52xx_pm_init(void)
+{
+ pm_set_ops(&mpc52xx_pm_ops);
+ return 0;
+}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_sleep.S b/arch/powerpc/platforms/52xx/mpc52xx_sleep.S
new file mode 100644
index 0000000..4dc170b
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/mpc52xx_sleep.S
@@ -0,0 +1,154 @@
+#include <asm/reg.h>
+#include <asm/ppc_asm.h>
+#include <asm/processor.h>
+
+
+.text
+
+_GLOBAL(mpc52xx_deep_sleep)
+mpc52xx_deep_sleep: /* args r3-r6: SRAM, SDRAM regs, CDM regs, INTR regs */
+
+ /* enable interrupts */
+ mfmsr r7
+ ori r7, r7, 0x8000 /* EE */
+ mtmsr r7
+ sync; isync;
+
+ li r10, 0 /* flag that irq handler sets */
+
+ /* enable tmr7 (or any other) interrupt */
+ lwz r8, 0x14(r6) /* intr->main_mask */
+ ori r8, r8, 0x1
+ xori r8, r8, 0x1
+ stw r8, 0x14(r6)
+ sync
+
+ /* emulate tmr7 interrupt */
+ li r8, 0x1
+ stw r8, 0x40(r6) /* intr->main_emulate */
+ sync
+
+ /* wait for it to happen */
+1:
+ cmpi cr0, r10, 1
+ bne cr0, 1b
+
+ /* lock icache */
+ mfspr r10, SPRN_HID0
+ ori r10, r10, 0x2000
+ sync; isync;
+ mtspr SPRN_HID0, r10
+ sync; isync;
+
+
+ mflr r9 /* save LR */
+
+ /* jump to sram */
+ mtlr r3
+ blrl
+
+ mtlr r9 /* restore LR */
+
+ /* unlock icache */
+ mfspr r10, SPRN_HID0
+ ori r10, r10, 0x2000
+ xori r10, r10, 0x2000
+ sync; isync;
+ mtspr SPRN_HID0, r10
+ sync; isync;
+
+
+ /* return to C code */
+ blr
+
+
+_GLOBAL(mpc52xx_ds_sram)
+mpc52xx_ds_sram:
+ /* put SDRAM into self-refresh */
+ lwz r8, 0x4(r4) /* sdram->ctrl */
+
+ oris r8, r8, 0x8000 /* mode_en */
+ stw r8, 0x4(r4)
+ sync
+
+ ori r8, r8, 0x0002 /* soft_pre */
+ stw r8, 0x4(r4)
+ sync
+ xori r8, r8, 0x0002
+
+ xoris r8, r8, 0x8000 /* !mode_en */
+ stw r8, 0x4(r4)
+ sync
+
+ oris r8, r8, 0x5000
+ xoris r8, r8, 0x4000 /* ref_en !cke */
+ stw r8, 0x4(r4)
+ sync
+
+ /* disable SDRAM clock */
+ lwz r8, 0x14(r5) /* cdm->clkenable */
+ ori r8, r8, 0x0008
+ xori r8, r8, 0x0008
+ stw r8, 0x14(r5)
+ sync
+
+
+ /* put mpc5200 to sleep */
+ mfmsr r10
+ oris r10, r10, 0x0004 /* POW = 1 */
+ sync; isync;
+ mtmsr r10
+ sync; isync;
+
+
+ /* enable clock */
+ lwz r8, 0x14(r5)
+ ori r8, r8, 0x0008
+ stw r8, 0x14(r5)
+ sync
+
+ /* get ram out of self-refresh */
+ lwz r8, 0x4(r4)
+ oris r8, r8, 0x5000 /* cke ref_en */
+ stw r8, 0x4(r4)
+ sync
+
+ blr
+_GLOBAL(mpc52xx_ds_sram_size)
+mpc52xx_ds_sram_size:
+ .long $-mpc52xx_ds_sram
+
+
+/* ### interrupt handler for wakeup from deep-sleep ### */
+_GLOBAL(mpc52xx_ds_cached)
+mpc52xx_ds_cached:
+ mtspr SPRN_SPRG0, r7
+ mtspr SPRN_SPRG1, r8
+
+ /* disable emulated interrupt */
+ mfspr r7, 311 /* MBAR */
+ addi r7, r7, 0x540 /* intr->main_emul */
+ li r8, 0
+ stw r8, 0(r7)
+ sync
+ dcbf 0, r7
+
+ /* acknowledge wakeup, so CCS releases power pown */
+ mfspr r7, 311 /* MBAR */
+ addi r7, r7, 0x524 /* intr->enc_status */
+ lwz r8, 0(r7)
+ ori r8, r8, 0x0400
+ stw r8, 0(r7)
+ sync
+ dcbf 0, r7
+
+ /* flag - we handled the interrupt */
+ li r10, 1
+
+ mfspr r8, SPRN_SPRG1
+ mfspr r7, SPRN_SPRG0
+
+ rfi
+_GLOBAL(mpc52xx_ds_cached_size)
+mpc52xx_ds_cached_size:
+ .long $-mpc52xx_ds_cached
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index fff09f5..94843ed 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -111,6 +111,7 @@ static struct of_device_id mpc832x_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
+ { .type = "mdio", },
{},
};
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index 6b71e9f..b0b22bb 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -73,6 +73,7 @@ static struct of_device_id mpc832x_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
+ { .type = "mdio", },
{},
};
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index 526ed09..bceeff8 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -118,6 +118,7 @@ static struct of_device_id mpc836x_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
+ { .type = "mdio", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/mpc8544_ds.c b/arch/powerpc/platforms/85xx/mpc8544_ds.c
index 2867f85..bec84ff 100644
--- a/arch/powerpc/platforms/85xx/mpc8544_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc8544_ds.c
@@ -84,7 +84,7 @@ void __init mpc8544_ds_pic_init(void)
#ifdef CONFIG_PPC_I8259
/* Initialize the i8259 controller */
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "chrp,iic")) {
+ if (of_device_is_compatible(np, "chrp,iic")) {
cascade_node = np;
break;
}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 7e71636..1490eb3 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -197,7 +197,7 @@ static void __init mpc85xx_cds_pic_init(void)
#ifdef CONFIG_PPC_I8259
/* Initialize the i8259 controller */
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "chrp,iic")) {
+ if (of_device_is_compatible(np, "chrp,iic")) {
cascade_node = np;
break;
}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 54db416..e3dddbf 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -147,6 +147,7 @@ static struct of_device_id mpc85xx_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
+ { .type = "mdio", },
{},
};
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 3d3d98f..9087756 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -102,7 +102,7 @@ mpc86xx_hpcn_init_irq(void)
#ifdef CONFIG_PCI
/* Initialize i8259 controller */
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "chrp,iic")) {
+ if (of_device_is_compatible(np, "chrp,iic")) {
cascade_node = np;
break;
}
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 51e3334..361acfa 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -42,6 +42,7 @@ source "arch/powerpc/platforms/83xx/Kconfig"
source "arch/powerpc/platforms/85xx/Kconfig"
source "arch/powerpc/platforms/86xx/Kconfig"
source "arch/powerpc/platforms/embedded6xx/Kconfig"
+source "arch/powerpc/platforms/44x/Kconfig"
#source "arch/powerpc/platforms/4xx/Kconfig
config PPC_NATIVE
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 4520042..d6e041a 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -6,7 +6,8 @@ obj-$(CONFIG_PPC_PMAC) += powermac/
endif
endif
obj-$(CONFIG_PPC_CHRP) += chrp/
-obj-$(CONFIG_4xx) += 4xx/
+#obj-$(CONFIG_4xx) += 4xx/
+obj-$(CONFIG_44x) += 44x/
obj-$(CONFIG_PPC_MPC52xx) += 52xx/
obj-$(CONFIG_PPC_8xx) += 8xx/
obj-$(CONFIG_PPC_82xx) += 82xx/
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 4fc4e927..47264e7 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -227,7 +227,7 @@ void iic_request_IPIs(void)
static int iic_host_match(struct irq_host *h, struct device_node *node)
{
- return device_is_compatible(node,
+ return of_device_is_compatible(node,
"IBM,CBEA-Internal-Interrupt-Controller");
}
@@ -256,7 +256,7 @@ static int iic_host_xlate(struct irq_host *h, struct device_node *ct,
unsigned int node, ext, unit, class;
const u32 *val;
- if (!device_is_compatible(ct,
+ if (!of_device_is_compatible(ct,
"IBM,CBEA-Internal-Interrupt-Controller"))
return -ENODEV;
if (intsize != 1)
@@ -324,7 +324,7 @@ static int __init setup_iic(void)
for (dn = NULL;
(dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) {
- if (!device_is_compatible(dn,
+ if (!of_device_is_compatible(dn,
"IBM,CBEA-Internal-Interrupt-Controller"))
continue;
np = of_get_property(dn, "ibm,interrupt-server-ranges", NULL);
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 54b9618..db66542 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -112,7 +112,7 @@ static void __init mpic_init_IRQ(void)
for (dn = NULL;
(dn = of_find_node_by_name(dn, "interrupt-controller"));) {
- if (!device_is_compatible(dn, "CBEA,platform-open-pic"))
+ if (!of_device_is_compatible(dn, "CBEA,platform-open-pic"))
continue;
/* The MPIC driver will get everything it needs from the
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index fb1f157..05f4b3d 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -358,12 +358,12 @@ void __init spider_init_IRQ(void)
*/
for (dn = NULL;
(dn = of_find_node_by_name(dn, "interrupt-controller"));) {
- if (device_is_compatible(dn, "CBEA,platform-spider-pic")) {
+ if (of_device_is_compatible(dn, "CBEA,platform-spider-pic")) {
if (of_address_to_resource(dn, 0, &r)) {
printk(KERN_WARNING "spider-pic: Failed\n");
continue;
}
- } else if (device_is_compatible(dn, "sti,platform-spider-pic")
+ } else if (of_device_is_compatible(dn, "sti,platform-spider-pic")
&& (chip < 2)) {
static long hard_coded_pics[] =
{ 0x24000008000ul, 0x34000008000ul};
diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c
index 3322528..d32db9f 100644
--- a/arch/powerpc/platforms/cell/spufs/backing_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c
@@ -28,7 +28,6 @@
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/poll.h>
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c
index 428875c..fc4ed1f 100644
--- a/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -25,7 +25,6 @@
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 13e4f70..a93f328 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -71,8 +71,7 @@ spufs_init_once(void *p, struct kmem_cache * cachep, unsigned long flags)
{
struct spufs_inode_info *ei = p;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
inode_init_once(&ei->vfs_inode);
}
}
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 91030b8..b6ecb30 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -30,7 +30,6 @@
#include <linux/completion.h>
#include <linux/vmalloc.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/numa.h>
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 8347c4a..29dc59c 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -39,7 +39,6 @@
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index 1469d64..d32fedc 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -267,7 +267,7 @@ chrp_find_bridges(void)
model = of_get_property(dev, "model", NULL);
if (model == NULL)
model = "<none>";
- if (device_is_compatible(dev, "IBM,python")) {
+ if (of_device_is_compatible(dev, "IBM,python")) {
setup_python(hose, dev);
} else if (is_mot
|| strncmp(model, "Motorola, Grackle", 17) == 0) {
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 1870038..373de4c 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -448,7 +448,7 @@ static void __init chrp_find_8259(void)
/* Look for cascade */
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "chrp,iic")) {
+ if (of_device_is_compatible(np, "chrp,iic")) {
pic = np;
break;
}
diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c
index 1d2307e..3ea0eb7 100644
--- a/arch/powerpc/platforms/chrp/smp.c
+++ b/arch/powerpc/platforms/chrp/smp.c
@@ -11,7 +11,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index 9557908..8f3c2a7 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -20,16 +20,24 @@ config MPC7448HPC2
select TSI108_BRIDGE
select DEFAULT_UIMAGE
select PPC_UDBG_16550
- select MPIC
- select MPIC_WEIRD
help
Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga)
platform
+
+config PPC_HOLLY
+ bool "PPC750GX/CL with TSI10x bridge (Hickory/Holly)"
+ select TSI108_BRIDGE
+ select PPC_UDBG_16550
+ help
+ Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval
+ Board with TSI108/9 bridge (Hickory/Holly)
endchoice
config TSI108_BRIDGE
bool
- depends on MPC7448HPC2
+ depends on MPC7448HPC2 || PPC_HOLLY
+ select MPIC
+ select MPIC_WEIRD
default y
config MPC10X_BRIDGE
diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile
index d3d11a3..b39fe4f 100644
--- a/arch/powerpc/platforms/embedded6xx/Makefile
+++ b/arch/powerpc/platforms/embedded6xx/Makefile
@@ -3,3 +3,4 @@
#
obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o
obj-$(CONFIG_LINKSTATION) += linkstation.o ls_uart.o
+obj-$(CONFIG_PPC_HOLLY) += holly.o
diff --git a/arch/powerpc/platforms/embedded6xx/holly.c b/arch/powerpc/platforms/embedded6xx/holly.c
new file mode 100644
index 0000000..3a0b4a0
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/holly.c
@@ -0,0 +1,317 @@
+/*
+ * Board setup routines for the IBM 750GX/CL platform w/ TSI10x bridge
+ *
+ * Copyright 2007 IBM Corporation
+ *
+ * Stephen Winiecki <stevewin@us.ibm.com>
+ * Josh Boyer <jwboyer@linux.vnet.ibm.com>
+ *
+ * Based on code from mpc7448_hpc2.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/ide.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/tsi108.h>
+#include <asm/pci-bridge.h>
+#include <asm/reg.h>
+#include <mm/mmu_decl.h>
+#include <asm/tsi108_irq.h>
+#include <asm/tsi108_pci.h>
+#include <asm/mpic.h>
+#include <asm/of_platform.h>
+
+#undef DEBUG
+
+#define HOLLY_PCI_CFG_PHYS 0x7c000000
+
+int holly_exclude_device(u_char bus, u_char devfn)
+{
+ if (bus == 0 && PCI_SLOT(devfn) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ else
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static void holly_remap_bridge(void)
+{
+ u32 lut_val, lut_addr;
+ int i;
+
+ printk(KERN_INFO "Remapping PCI bridge\n");
+
+ /* Re-init the PCI bridge and LUT registers to have mappings that don't
+ * rely on PIBS
+ */
+ lut_addr = 0x900;
+ for (i = 0; i < 31; i++) {
+ tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x00000201);
+ lut_addr += 4;
+ tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x0);
+ lut_addr += 4;
+ }
+
+ /* Reserve the last LUT entry for PCI I/O space */
+ tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x00000241);
+ lut_addr += 4;
+ tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x0);
+
+ /* Map PCI I/O space */
+ tsi108_write_reg(TSI108_PCI_PFAB_IO_UPPER, 0x0);
+ tsi108_write_reg(TSI108_PCI_PFAB_IO, 0x1);
+
+ /* Map PCI CFG space */
+ tsi108_write_reg(TSI108_PCI_PFAB_BAR0_UPPER, 0x0);
+ tsi108_write_reg(TSI108_PCI_PFAB_BAR0, 0x7c000000 | 0x01);
+
+ /* We don't need MEM32 and PRM remapping so disable them */
+ tsi108_write_reg(TSI108_PCI_PFAB_MEM32, 0x0);
+ tsi108_write_reg(TSI108_PCI_PFAB_PFM3, 0x0);
+ tsi108_write_reg(TSI108_PCI_PFAB_PFM4, 0x0);
+
+ /* Set P2O_BAR0 */
+ tsi108_write_reg(TSI108_PCI_P2O_BAR0_UPPER, 0x0);
+ tsi108_write_reg(TSI108_PCI_P2O_BAR0, 0xc0000000);
+
+ /* Init the PCI LUTs to do no remapping */
+ lut_addr = 0x500;
+ lut_val = 0x00000002;
+
+ for (i = 0; i < 32; i++) {
+ tsi108_write_reg(TSI108_PCI_OFFSET + lut_addr, lut_val);
+ lut_addr += 4;
+ tsi108_write_reg(TSI108_PCI_OFFSET + lut_addr, 0x40000000);
+ lut_addr += 4;
+ lut_val += 0x02000000;
+ }
+ tsi108_write_reg(TSI108_PCI_P2O_PAGE_SIZES, 0x00007900);
+
+ /* Set 64-bit PCI bus address for system memory */
+ tsi108_write_reg(TSI108_PCI_P2O_BAR2_UPPER, 0x0);
+ tsi108_write_reg(TSI108_PCI_P2O_BAR2, 0x0);
+}
+
+static void __init holly_setup_arch(void)
+{
+ struct device_node *cpu;
+ struct device_node *np;
+
+ if (ppc_md.progress)
+ ppc_md.progress("holly_setup_arch():set_bridge", 0);
+
+ cpu = of_find_node_by_type(NULL, "cpu");
+ if (cpu) {
+ const unsigned int *fp;
+
+ fp = of_get_property(cpu, "clock-frequency", NULL);
+ if (fp)
+ loops_per_jiffy = *fp / HZ;
+ else
+ loops_per_jiffy = 50000000 / HZ;
+ of_node_put(cpu);
+ }
+ tsi108_csr_vir_base = get_vir_csrbase();
+
+ /* setup PCI host bridge */
+ holly_remap_bridge();
+
+ np = of_find_node_by_type(NULL, "pci");
+ if (np)
+ tsi108_setup_pci(np, HOLLY_PCI_CFG_PHYS, 1);
+
+ ppc_md.pci_exclude_device = holly_exclude_device;
+ if (ppc_md.progress)
+ ppc_md.progress("tsi108: resources set", 0x100);
+
+ printk(KERN_INFO "PPC750GX/CL Platform\n");
+}
+
+/*
+ * Interrupt setup and service. Interrrupts on the holly come
+ * from the four external INT pins, PCI interrupts are routed via
+ * PCI interrupt control registers, it generates internal IRQ23
+ *
+ * Interrupt routing on the Holly Board:
+ * TSI108:PB_INT[0] -> CPU0:INT#
+ * TSI108:PB_INT[1] -> CPU0:MCP#
+ * TSI108:PB_INT[2] -> N/C
+ * TSI108:PB_INT[3] -> N/C
+ */
+static void __init holly_init_IRQ(void)
+{
+ struct mpic *mpic;
+ phys_addr_t mpic_paddr = 0;
+ struct device_node *tsi_pic;
+#ifdef CONFIG_PCI
+ unsigned int cascade_pci_irq;
+ struct device_node *tsi_pci;
+ struct device_node *cascade_node = NULL;
+#endif
+
+ tsi_pic = of_find_node_by_type(NULL, "open-pic");
+ if (tsi_pic) {
+ unsigned int size;
+ const void *prop = of_get_property(tsi_pic, "reg", &size);
+ mpic_paddr = of_translate_address(tsi_pic, prop);
+ }
+
+ if (mpic_paddr == 0) {
+ printk(KERN_ERR "%s: No tsi108 PIC found !\n", __func__);
+ return;
+ }
+
+ pr_debug("%s: tsi108 pic phys_addr = 0x%x\n", __func__, (u32) mpic_paddr);
+
+ mpic = mpic_alloc(tsi_pic, mpic_paddr,
+ MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET |
+ MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108,
+ 24,
+ NR_IRQS-4, /* num_sources used */
+ "Tsi108_PIC");
+
+ BUG_ON(mpic == NULL);
+
+ mpic_assign_isu(mpic, 0, mpic_paddr + 0x100);
+
+ mpic_init(mpic);
+
+#ifdef CONFIG_PCI
+ tsi_pci = of_find_node_by_type(NULL, "pci");
+ if (tsi_pci == NULL) {
+ printk(KERN_ERR "%s: No tsi108 pci node found !\n", __func__);
+ return;
+ }
+
+ cascade_node = of_find_node_by_type(NULL, "pic-router");
+ if (cascade_node == NULL) {
+ printk(KERN_ERR "%s: No tsi108 pci cascade node found !\n", __func__);
+ return;
+ }
+
+ cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0);
+ pr_debug("%s: tsi108 cascade_pci_irq = 0x%x\n", __func__, (u32) cascade_pci_irq);
+ tsi108_pci_int_init(cascade_node);
+ set_irq_data(cascade_pci_irq, mpic);
+ set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
+#endif
+ /* Configure MPIC outputs to CPU0 */
+ tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
+ of_node_put(tsi_pic);
+}
+
+void holly_show_cpuinfo(struct seq_file *m)
+{
+ seq_printf(m, "vendor\t\t: IBM\n");
+ seq_printf(m, "machine\t\t: PPC750 GX/CL\n");
+}
+
+void holly_restart(char *cmd)
+{
+ __be32 __iomem *ocn_bar1 = NULL;
+ unsigned long bar;
+ struct device_node *bridge = NULL;
+ const void *prop;
+ int size;
+ phys_addr_t addr = 0xc0000000;
+
+ local_irq_disable();
+
+ bridge = of_find_node_by_type(NULL, "tsi-bridge");
+ if (bridge) {
+ prop = of_get_property(bridge, "reg", &size);
+ addr = of_translate_address(bridge, prop);
+ }
+ addr += (TSI108_PB_OFFSET + 0x414);
+
+ ocn_bar1 = ioremap(addr, 0x4);
+
+ /* Turn on the BOOT bit so the addresses are correctly
+ * routed to the HLP interface */
+ bar = ioread32be(ocn_bar1);
+ bar |= 2;
+ iowrite32be(bar, ocn_bar1);
+ iosync();
+
+ /* Set SRR0 to the reset vector and turn on MSR_IP */
+ mtspr(SPRN_SRR0, 0xfff00100);
+ mtspr(SPRN_SRR1, MSR_IP);
+
+ /* Do an rfi to jump back to firmware. Somewhat evil,
+ * but it works
+ */
+ __asm__ __volatile__("rfi" : : : "memory");
+
+ /* Spin until reset happens. Shouldn't really get here */
+ for (;;) ;
+}
+
+void holly_power_off(void)
+{
+ local_irq_disable();
+ /* No way to shut power off with software */
+ for (;;) ;
+}
+
+void holly_halt(void)
+{
+ holly_power_off();
+}
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init holly_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (!of_flat_dt_is_compatible(root, "ibm,holly"))
+ return 0;
+ return 1;
+}
+
+static int ppc750_machine_check_exception(struct pt_regs *regs)
+{
+ const struct exception_table_entry *entry;
+
+ /* Are we prepared to handle this fault */
+ if ((entry = search_exception_tables(regs->nip)) != NULL) {
+ tsi108_clear_pci_cfg_error();
+ regs->msr |= MSR_RI;
+ regs->nip = entry->fixup;
+ return 1;
+ }
+ return 0;
+}
+
+define_machine(holly){
+ .name = "PPC750 GX/CL TSI",
+ .probe = holly_probe,
+ .setup_arch = holly_setup_arch,
+ .init_IRQ = holly_init_IRQ,
+ .show_cpuinfo = holly_show_cpuinfo,
+ .get_irq = mpic_get_irq,
+ .restart = holly_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .machine_check_exception = ppc750_machine_check_exception,
+ .progress = udbg_progress,
+};
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
index c3f64dd..4542e0c8 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
@@ -41,6 +41,7 @@
#include <asm/reg.h>
#include <mm/mmu_decl.h>
#include "mpc7448_hpc2.h"
+#include <asm/tsi108_pci.h>
#include <asm/tsi108_irq.h>
#include <asm/mpic.h>
@@ -51,16 +52,15 @@
#define DBG(fmt...) do { } while(0)
#endif
+#define MPC7448HPC2_PCI_CFG_PHYS 0xfb000000
+
#ifndef CONFIG_PCI
isa_io_base = MPC7448_HPC2_ISA_IO_BASE;
isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE;
pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET;
#endif
-extern int tsi108_setup_pci(struct device_node *dev);
extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
-extern void tsi108_pci_int_init(struct device_node *node);
-extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc);
int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn)
{
@@ -72,28 +72,16 @@ int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn)
static void __init mpc7448_hpc2_setup_arch(void)
{
- struct device_node *cpu;
struct device_node *np;
if (ppc_md.progress)
ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0);
- cpu = of_find_node_by_type(NULL, "cpu");
- if (cpu != 0) {
- const unsigned int *fp;
-
- fp = of_get_property(cpu, "clock-frequency", NULL);
- if (fp != 0)
- loops_per_jiffy = *fp / HZ;
- else
- loops_per_jiffy = 50000000 / HZ;
- of_node_put(cpu);
- }
tsi108_csr_vir_base = get_vir_csrbase();
/* setup PCI host bridge */
#ifdef CONFIG_PCI
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
- tsi108_setup_pci(np);
+ tsi108_setup_pci(np, MPC7448HPC2_PCI_CFG_PHYS, 0);
ppc_md.pci_exclude_device = mpc7448_hpc2_exclude_device;
if (ppc_md.progress)
@@ -222,7 +210,6 @@ static int __init mpc7448_hpc2_probe(void)
static int mpc7448_machine_check_exception(struct pt_regs *regs)
{
- extern void tsi108_clear_pci_cfg_error(void);
const struct exception_table_entry *entry;
/* Are we prepared to handle this fault */
diff --git a/arch/powerpc/platforms/iseries/smp.c b/arch/powerpc/platforms/iseries/smp.c
index aee5908..722335e 100644
--- a/arch/powerpc/platforms/iseries/smp.c
+++ b/arch/powerpc/platforms/iseries/smp.c
@@ -18,7 +18,6 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
index 2ca2d8a..354b8dd 100644
--- a/arch/powerpc/platforms/iseries/viopath.c
+++ b/arch/powerpc/platforms/iseries/viopath.c
@@ -36,7 +36,6 @@
#include <linux/dma-mapping.h>
#include <linux/wait.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <asm/system.h>
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index b1d3b99..7aaa5bb 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -467,15 +467,15 @@ static int __init add_bridge(struct device_node *dev)
hose->last_busno = bus_range ? bus_range[1] : 0xff;
disp_name = NULL;
- if (device_is_compatible(dev, "u3-agp")) {
+ if (of_device_is_compatible(dev, "u3-agp")) {
setup_u3_agp(hose);
disp_name = "U3-AGP";
primary = 0;
- } else if (device_is_compatible(dev, "u3-ht")) {
+ } else if (of_device_is_compatible(dev, "u3-ht")) {
setup_u3_ht(hose);
disp_name = "U3-HT";
primary = 1;
- } else if (device_is_compatible(dev, "u4-pcie")) {
+ } else if (of_device_is_compatible(dev, "u4-pcie")) {
setup_u4_pcie(hose);
disp_name = "U4-PCIE";
primary = 0;
@@ -556,12 +556,12 @@ void __init maple_pci_init(void)
continue;
if (strcmp(np->type, "pci") && strcmp(np->type, "ht"))
continue;
- if ((device_is_compatible(np, "u4-pcie") ||
- device_is_compatible(np, "u3-agp")) &&
+ if ((of_device_is_compatible(np, "u4-pcie") ||
+ of_device_is_compatible(np, "u3-agp")) &&
add_bridge(np) == 0)
of_node_get(np);
- if (device_is_compatible(np, "u3-ht")) {
+ if (of_device_is_compatible(np, "u3-ht")) {
of_node_get(np);
ht = np;
}
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index 2a30c5b..354c058 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -231,7 +231,7 @@ static void __init maple_init_IRQ(void)
*/
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "open-pic")) {
+ if (of_device_is_compatible(np, "open-pic")) {
mpic_node = np;
break;
}
diff --git a/arch/powerpc/platforms/pasemi/cpufreq.c b/arch/powerpc/platforms/pasemi/cpufreq.c
index 2a57d60..3ae0838 100644
--- a/arch/powerpc/platforms/pasemi/cpufreq.c
+++ b/arch/powerpc/platforms/pasemi/cpufreq.c
@@ -31,6 +31,7 @@
#include <asm/hw_irq.h>
#include <asm/io.h>
#include <asm/prom.h>
+#include <asm/time.h>
#define SDCASR_REG 0x0100
#define SDCASR_REG_STRIDE 0x1000
@@ -204,6 +205,8 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
policy->cur = pas_freqs[cur_astate].frequency;
policy->cpus = cpu_online_map;
+ ppc_proc_freq = policy->cur * 1000ul;
+
cpufreq_frequency_table_get_attr(pas_freqs, policy->cpu);
/* this ensures that policy->cpuinfo_min and policy->cpuinfo_max
@@ -270,6 +273,7 @@ static int pas_cpufreq_target(struct cpufreq_policy *policy,
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
mutex_unlock(&pas_switch_mutex);
+ ppc_proc_freq = freqs.new * 1000ul;
return 0;
}
diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c
index 056243d..bbc6dfc 100644
--- a/arch/powerpc/platforms/pasemi/pci.c
+++ b/arch/powerpc/platforms/pasemi/pci.c
@@ -173,19 +173,6 @@ static void __init pas_fixup_phb_resources(void)
}
-void __devinit pas_pci_irq_fixup(struct pci_dev *dev)
-{
- /* DMA is special, 84 interrupts (128 -> 211), all but 128
- * need to be mapped by hand here.
- */
- if (dev->vendor == 0x1959 && dev->device == 0xa007) {
- int i;
- for (i = 129; i < 212; i++)
- irq_create_mapping(NULL, i);
- }
-}
-
-
void __init pas_pci_init(void)
{
struct device_node *np, *root;
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index f88f0ec..c5a3f61 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -114,7 +114,7 @@ static __init void pas_init_IRQ(void)
mpic_node = NULL;
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "open-pic")) {
+ if (of_device_is_compatible(np, "open-pic")) {
mpic_node = np;
break;
}
@@ -211,7 +211,10 @@ static struct of_device_id pasemi_bus_ids[] = {
static int __init pasemi_publish_devices(void)
{
- /* Publish OF platform devices for southbridge IOs */
+ if (!machine_is(pasemi))
+ return 0;
+
+ /* Publish OF platform devices for SDC and other non-PCI devices */
of_platform_bus_probe(NULL, pasemi_bus_ids, NULL);
return 0;
@@ -248,5 +251,4 @@ define_machine(pas) {
.calibrate_decr = generic_calibrate_decr,
.progress = pas_progress,
.machine_check_exception = pas_machine_check_handler,
- .pci_irq_fixup = pas_pci_irq_fixup,
};
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
index 567d552..00f5029 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -357,13 +357,13 @@ static unsigned int g5_cpufreq_get_speed(unsigned int cpu)
static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
- if (policy->cpu != 0)
- return -ENODEV;
-
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->cur = g5_cpu_freqs[g5_query_freq()].frequency;
- policy->cpus = cpu_possible_map;
+ /* secondary CPUs are tied to the primary one by the
+ * cpufreq core if in the secondary policy we tell it that
+ * it actually must be one policy together with all others. */
+ policy->cpus = cpu_online_map;
cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu);
return cpufreq_frequency_table_cpuinfo(policy,
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index 52cfdd8..f29705f 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -1418,7 +1418,7 @@ static long g5_eth_phy_reset(struct device_node *node, long param, long value)
phy = of_get_next_child(node, NULL);
if (!phy)
return -ENODEV;
- need_reset = device_is_compatible(phy, "B5221");
+ need_reset = of_device_is_compatible(phy, "B5221");
of_node_put(phy);
if (!need_reset)
return 0;
@@ -2624,7 +2624,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ
for (node = NULL; (node = of_find_node_by_name(node, name)) != NULL;) {
if (!compat)
break;
- if (device_is_compatible(node, compat))
+ if (of_device_is_compatible(node, compat))
break;
}
if (!node)
@@ -2728,7 +2728,7 @@ initial_serial_shutdown(struct device_node *np)
conn = of_get_property(np, "AAPL,connector", &len);
if (conn && (strcmp(conn, "infrared") == 0))
port_type = PMAC_SCC_IRDA;
- else if (device_is_compatible(np, "cobalt"))
+ else if (of_device_is_compatible(np, "cobalt"))
modem = 1;
else if (slots && slots->count > 0) {
if (strcmp(slots->name, "IrDA") == 0)
@@ -2787,7 +2787,7 @@ set_initial_features(void)
*/
np = of_find_node_by_name(NULL, "ethernet");
while(np) {
- if (device_is_compatible(np, "K2-GMAC"))
+ if (of_device_is_compatible(np, "K2-GMAC"))
g5_gmac_enable(np, 0, 1);
np = of_find_node_by_name(np, "ethernet");
}
@@ -2799,7 +2799,7 @@ set_initial_features(void)
*/
np = of_find_node_by_name(NULL, "firewire");
while(np) {
- if (device_is_compatible(np, "pci106b,5811")) {
+ if (of_device_is_compatible(np, "pci106b,5811")) {
macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
g5_fw_enable(np, 0, 1);
}
@@ -2817,8 +2817,8 @@ set_initial_features(void)
np = of_find_node_by_name(NULL, "ethernet");
while(np) {
if (np->parent
- && device_is_compatible(np->parent, "uni-north")
- && device_is_compatible(np, "gmac"))
+ && of_device_is_compatible(np->parent, "uni-north")
+ && of_device_is_compatible(np, "gmac"))
core99_gmac_enable(np, 0, 1);
np = of_find_node_by_name(np, "ethernet");
}
@@ -2831,10 +2831,10 @@ set_initial_features(void)
np = of_find_node_by_name(NULL, "firewire");
while(np) {
if (np->parent
- && device_is_compatible(np->parent, "uni-north")
- && (device_is_compatible(np, "pci106b,18") ||
- device_is_compatible(np, "pci106b,30") ||
- device_is_compatible(np, "pci11c1,5811"))) {
+ && of_device_is_compatible(np->parent, "uni-north")
+ && (of_device_is_compatible(np, "pci106b,18") ||
+ of_device_is_compatible(np, "pci106b,30") ||
+ of_device_is_compatible(np, "pci11c1,5811"))) {
macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
core99_firewire_enable(np, 0, 1);
}
@@ -2845,8 +2845,8 @@ set_initial_features(void)
np = of_find_node_by_name(NULL, "ata-6");
while(np) {
if (np->parent
- && device_is_compatible(np->parent, "uni-north")
- && device_is_compatible(np, "kauai-ata")) {
+ && of_device_is_compatible(np->parent, "uni-north")
+ && of_device_is_compatible(np, "kauai-ata")) {
core99_ata100_enable(np, 1);
}
np = of_find_node_by_name(np, "ata-6");
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index 5430e14..3f507ab 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -1207,7 +1207,7 @@ static void pmac_i2c_devscan(void (*callback)(struct device_node *dev,
if (strcmp(np->name, p->name))
continue;
if (p->compatible &&
- !device_is_compatible(np, p->compatible))
+ !of_device_is_compatible(np, p->compatible))
continue;
if (p->quirks & pmac_i2c_quirk_skip)
break;
diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c
index 692945c..c6f0f9e 100644
--- a/arch/powerpc/platforms/powermac/nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -553,7 +553,7 @@ static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr)
* identify the chip using flash id commands and base ourselves on
* a list of known chips IDs
*/
- if (device_is_compatible(dp, "amd-0137")) {
+ if (of_device_is_compatible(dp, "amd-0137")) {
core99_erase_bank = amd_erase_bank;
core99_write_bank = amd_write_bank;
} else {
@@ -588,7 +588,7 @@ int __init pmac_nvram_init(void)
}
}
- is_core_99 = device_is_compatible(dp, "nvram,flash");
+ is_core_99 = of_device_is_compatible(dp, "nvram,flash");
if (is_core_99) {
err = core99_nvram_setup(dp, r1.start);
goto bail;
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 22c4ae4..c4af9e2 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -934,15 +934,15 @@ static int __init add_bridge(struct device_node *dev)
/* 64 bits only bridges */
#ifdef CONFIG_PPC64
- if (device_is_compatible(dev, "u3-agp")) {
+ if (of_device_is_compatible(dev, "u3-agp")) {
setup_u3_agp(hose);
disp_name = "U3-AGP";
primary = 0;
- } else if (device_is_compatible(dev, "u3-ht")) {
+ } else if (of_device_is_compatible(dev, "u3-ht")) {
setup_u3_ht(hose);
disp_name = "U3-HT";
primary = 1;
- } else if (device_is_compatible(dev, "u4-pcie")) {
+ } else if (of_device_is_compatible(dev, "u4-pcie")) {
setup_u4_pcie(hose);
disp_name = "U4-PCIE";
primary = 0;
@@ -953,7 +953,7 @@ static int __init add_bridge(struct device_node *dev)
/* 32 bits only bridges */
#ifdef CONFIG_PPC32
- if (device_is_compatible(dev, "uni-north")) {
+ if (of_device_is_compatible(dev, "uni-north")) {
primary = setup_uninorth(hose, &rsrc);
disp_name = "UniNorth";
} else if (strcmp(dev->name, "pci") == 0) {
@@ -1129,21 +1129,21 @@ pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
return 0;
uninorth_child = node->parent &&
- device_is_compatible(node->parent, "uni-north");
+ of_device_is_compatible(node->parent, "uni-north");
/* Firewire & GMAC were disabled after PCI probe, the driver is
* claiming them, we must re-enable them now.
*/
if (uninorth_child && !strcmp(node->name, "firewire") &&
- (device_is_compatible(node, "pci106b,18") ||
- device_is_compatible(node, "pci106b,30") ||
- device_is_compatible(node, "pci11c1,5811"))) {
+ (of_device_is_compatible(node, "pci106b,18") ||
+ of_device_is_compatible(node, "pci106b,30") ||
+ of_device_is_compatible(node, "pci11c1,5811"))) {
pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1);
pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1);
updatecfg = 1;
}
if (uninorth_child && !strcmp(node->name, "ethernet") &&
- device_is_compatible(node, "gmac")) {
+ of_device_is_compatible(node, "gmac")) {
pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1);
updatecfg = 1;
}
@@ -1203,18 +1203,18 @@ void __init pmac_pcibios_after_init(void)
#endif /* CONFIG_BLK_DEV_IDE */
for_each_node_by_name(nd, "firewire") {
- if (nd->parent && (device_is_compatible(nd, "pci106b,18") ||
- device_is_compatible(nd, "pci106b,30") ||
- device_is_compatible(nd, "pci11c1,5811"))
- && device_is_compatible(nd->parent, "uni-north")) {
+ if (nd->parent && (of_device_is_compatible(nd, "pci106b,18") ||
+ of_device_is_compatible(nd, "pci106b,30") ||
+ of_device_is_compatible(nd, "pci11c1,5811"))
+ && of_device_is_compatible(nd->parent, "uni-north")) {
pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0);
pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0);
}
}
of_node_put(nd);
for_each_node_by_name(nd, "ethernet") {
- if (nd->parent && device_is_compatible(nd, "gmac")
- && device_is_compatible(nd->parent, "uni-north"))
+ if (nd->parent && of_device_is_compatible(nd, "gmac")
+ && of_device_is_compatible(nd->parent, "uni-north"))
pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0);
}
of_node_put(nd);
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index ae5097a..87cd68051 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -364,7 +364,7 @@ static void __init pmac_pic_probe_oldstyle(void)
slave = of_find_node_by_name(master, "mac-io");
/* Check ordering of master & slave */
- if (device_is_compatible(master, "gatwick")) {
+ if (of_device_is_compatible(master, "gatwick")) {
struct device_node *tmp;
BUG_ON(slave == NULL);
tmp = master;
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index b820cab..a410bc76 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -439,76 +439,14 @@ static void __init find_boot_device(void)
#endif
}
-/* TODO: Merge the suspend-to-ram with the common code !!!
- * currently, this is a stub implementation for suspend-to-disk
- * only
- */
-
-#ifdef CONFIG_SOFTWARE_SUSPEND
-
-static int pmac_pm_prepare(suspend_state_t state)
-{
- printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
- return 0;
-}
-
-static int pmac_pm_enter(suspend_state_t state)
-{
- printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
- /* Giveup the lazy FPU & vec so we don't have to back them
- * up from the low level code
- */
- enable_kernel_fp();
-
-#ifdef CONFIG_ALTIVEC
- if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
- enable_kernel_altivec();
-#endif /* CONFIG_ALTIVEC */
-
- return 0;
-}
-
-static int pmac_pm_finish(suspend_state_t state)
-{
- printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
- /* Restore userland MMU context */
- set_context(current->active_mm->context.id, current->active_mm->pgd);
-
- return 0;
-}
-
-static int pmac_pm_valid(suspend_state_t state)
-{
- switch (state) {
- case PM_SUSPEND_DISK:
- return 1;
- /* can't do any other states via generic mechanism yet */
- default:
- return 0;
- }
-}
-
-static struct pm_ops pmac_pm_ops = {
- .pm_disk_mode = PM_DISK_SHUTDOWN,
- .prepare = pmac_pm_prepare,
- .enter = pmac_pm_enter,
- .finish = pmac_pm_finish,
- .valid = pmac_pm_valid,
-};
-
-#endif /* CONFIG_SOFTWARE_SUSPEND */
-
static int initializing = 1;
static int pmac_late_init(void)
{
initializing = 0;
-#ifdef CONFIG_SOFTWARE_SUSPEND
- pm_set_ops(&pmac_pm_ops);
-#endif /* CONFIG_SOFTWARE_SUSPEND */
+ /* this is udbg (which is __init) and we can later use it during
+ * cpu hotplug (in smp_core99_kick_cpu) */
+ ppc_md.progress = NULL;
return 0;
}
@@ -721,12 +659,57 @@ static int pmac_pci_probe_mode(struct pci_bus *bus)
/* We need to use normal PCI probing for the AGP bus,
* since the device for the AGP bridge isn't in the tree.
*/
- if (bus->self == NULL && (device_is_compatible(node, "u3-agp") ||
- device_is_compatible(node, "u4-pcie")))
+ if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") ||
+ of_device_is_compatible(node, "u4-pcie")))
return PCI_PROBE_NORMAL;
return PCI_PROBE_DEVTREE;
}
-#endif
+
+#ifdef CONFIG_HOTPLUG_CPU
+/* access per cpu vars from generic smp.c */
+DECLARE_PER_CPU(int, cpu_state);
+
+static void pmac_cpu_die(void)
+{
+ /*
+ * turn off as much as possible, we'll be
+ * kicked out as this will only be invoked
+ * on core99 platforms for now ...
+ */
+
+ printk(KERN_INFO "CPU#%d offline\n", smp_processor_id());
+ __get_cpu_var(cpu_state) = CPU_DEAD;
+ smp_wmb();
+
+ /*
+ * during the path that leads here preemption is disabled,
+ * reenable it now so that when coming up preempt count is
+ * zero correctly
+ */
+ preempt_enable();
+
+ /*
+ * hard-disable interrupts for the non-NAP case, the NAP code
+ * needs to re-enable interrupts (but soft-disables them)
+ */
+ hard_irq_disable();
+
+ while (1) {
+ /* let's not take timer interrupts too often ... */
+ set_dec(0x7fffffff);
+
+ /* should always be true at this point */
+ if (cpu_has_feature(CPU_FTR_CAN_NAP))
+ power4_cpu_offline_powersave();
+ else {
+ HMT_low();
+ HMT_very_low();
+ }
+ }
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
+#endif /* CONFIG_PPC64 */
define_machine(powermac) {
.name = "PowerMac",
@@ -763,6 +746,6 @@ define_machine(powermac) {
.phys_mem_access_prot = pci_phys_mem_access_prot,
#endif
#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
- .cpu_die = generic_mach_cpu_die,
+ .cpu_die = pmac_cpu_die,
#endif
};
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 6f32c4e..686ed82 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -24,7 +24,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
@@ -562,7 +561,7 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus)
/* Look for the clock chip */
while ((cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL) {
p = of_get_parent(cc);
- ok = p && device_is_compatible(p, "uni-n-i2c");
+ ok = p && of_device_is_compatible(p, "uni-n-i2c");
of_node_put(p);
if (!ok)
continue;
@@ -575,11 +574,11 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus)
continue;
switch (*reg) {
case 0xd2:
- if (device_is_compatible(cc,"pulsar-legacy-slewing")) {
+ if (of_device_is_compatible(cc,"pulsar-legacy-slewing")) {
pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
pmac_tb_pulsar_addr = 0xd2;
name = "Pulsar";
- } else if (device_is_compatible(cc, "cy28508")) {
+ } else if (of_device_is_compatible(cc, "cy28508")) {
pmac_tb_freeze = smp_core99_cypress_tb_freeze;
name = "Cypress";
}
@@ -900,7 +899,7 @@ void smp_core99_cpu_die(unsigned int cpu)
cpu_dead[cpu] = 0;
}
-#endif
+#endif /* CONFIG_HOTPLUG_CPU && CONFIG_PP32 */
/* Core99 Macs (dual G4s and G5s) */
struct smp_ops_t core99_smp_ops = {
@@ -910,8 +909,16 @@ struct smp_ops_t core99_smp_ops = {
.setup_cpu = smp_core99_setup_cpu,
.give_timebase = smp_core99_give_timebase,
.take_timebase = smp_core99_take_timebase,
-#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
+#if defined(CONFIG_HOTPLUG_CPU)
+# if defined(CONFIG_PPC32)
.cpu_disable = smp_core99_cpu_disable,
.cpu_die = smp_core99_cpu_die,
+# endif
+# if defined(CONFIG_PPC64)
+ .cpu_disable = generic_cpu_disable,
+ .cpu_die = generic_cpu_die,
+ /* intentionally do *NOT* assign cpu_enable,
+ * the generic code will use kick_cpu then! */
+# endif
#endif
};
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
index ea60c45..a1409e4 100644
--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -273,7 +273,8 @@ void __init ps3_map_htab(void)
result = lv1_map_htab(0, &htab_addr);
- htab = (hpte_t *)__ioremap(htab_addr, htab_size, PAGE_READONLY_X);
+ htab = (hpte_t *)__ioremap(htab_addr, htab_size,
+ pgprot_val(PAGE_READONLY_X));
DBG("%s:%d: lpar %016lxh, virt %016lxh\n", __func__, __LINE__,
htab_addr, (unsigned long)htab);
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 631c300..9da82c2 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -89,7 +89,18 @@ struct ps3_private {
static DEFINE_PER_CPU(struct ps3_private, ps3_private);
-int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
+/**
+ * ps3_virq_setup - virq related setup.
+ * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
+ * serviced on.
+ * @outlet: The HV outlet from the various create outlet routines.
+ * @virq: The assigned Linux virq.
+ *
+ * Calls irq_create_mapping() to get a virq and sets the chip data to
+ * ps3_private data.
+ */
+
+int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
unsigned int *virq)
{
int result;
@@ -111,17 +122,6 @@ int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
goto fail_create;
}
- /* Binds outlet to cpu + virq. */
-
- result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0);
-
- if (result) {
- pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
- __func__, __LINE__, ps3_result(result));
- result = -EPERM;
- goto fail_connect;
- }
-
pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__,
outlet, cpu, *virq);
@@ -136,94 +136,118 @@ int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
return result;
fail_set:
- lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, *virq);
-fail_connect:
irq_dispose_mapping(*virq);
fail_create:
return result;
}
-EXPORT_SYMBOL_GPL(ps3_alloc_irq);
-int ps3_free_irq(unsigned int virq)
+/**
+ * ps3_virq_destroy - virq related teardown.
+ * @virq: The assigned Linux virq.
+ *
+ * Clears chip data and calls irq_dispose_mapping() for the virq.
+ */
+
+int ps3_virq_destroy(unsigned int virq)
{
- int result;
const struct ps3_private *pd = get_irq_chip_data(virq);
pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
pd->node, pd->cpu, virq);
- result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);
-
- if (result)
- pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
- __func__, __LINE__, ps3_result(result));
-
set_irq_chip_data(virq, NULL);
irq_dispose_mapping(virq);
- return result;
+
+ pr_debug("%s:%d <-\n", __func__, __LINE__);
+ return 0;
}
-EXPORT_SYMBOL_GPL(ps3_free_irq);
/**
- * ps3_alloc_io_irq - Assign a virq to a system bus device.
+ * ps3_irq_plug_setup - Generic outlet and virq related setup.
* @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
* serviced on.
- * @interrupt_id: The device interrupt id read from the system repository.
+ * @outlet: The HV outlet from the various create outlet routines.
* @virq: The assigned Linux virq.
*
- * An io irq represents a non-virtualized device interrupt. interrupt_id
- * coresponds to the interrupt number of the interrupt controller.
+ * Sets up virq and connects the irq plug.
*/
-int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
+int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
unsigned int *virq)
{
int result;
- unsigned long outlet;
+ struct ps3_private *pd;
- result = lv1_construct_io_irq_outlet(interrupt_id, &outlet);
+ result = ps3_virq_setup(cpu, outlet, virq);
if (result) {
- pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n",
- __func__, __LINE__, ps3_result(result));
- return result;
+ pr_debug("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__);
+ goto fail_setup;
}
- result = ps3_alloc_irq(cpu, outlet, virq);
- BUG_ON(result);
+ pd = get_irq_chip_data(*virq);
+
+ /* Binds outlet to cpu + virq. */
+
+ result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0);
+ if (result) {
+ pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
+ __func__, __LINE__, ps3_result(result));
+ result = -EPERM;
+ goto fail_connect;
+ }
+
+ return result;
+
+fail_connect:
+ ps3_virq_destroy(*virq);
+fail_setup:
return result;
}
-EXPORT_SYMBOL_GPL(ps3_alloc_io_irq);
+EXPORT_SYMBOL_GPL(ps3_irq_plug_setup);
+
+/**
+ * ps3_irq_plug_destroy - Generic outlet and virq related teardown.
+ * @virq: The assigned Linux virq.
+ *
+ * Disconnects the irq plug and tears down virq.
+ * Do not call for system bus event interrupts setup with
+ * ps3_sb_event_receive_port_setup().
+ */
-int ps3_free_io_irq(unsigned int virq)
+int ps3_irq_plug_destroy(unsigned int virq)
{
int result;
+ const struct ps3_private *pd = get_irq_chip_data(virq);
- result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
+ pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
+ pd->node, pd->cpu, virq);
+
+ result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);
if (result)
- pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
- __func__, __LINE__, ps3_result(result));
+ pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
+ __func__, __LINE__, ps3_result(result));
- ps3_free_irq(virq);
+ ps3_virq_destroy(virq);
return result;
}
-EXPORT_SYMBOL_GPL(ps3_free_io_irq);
+EXPORT_SYMBOL_GPL(ps3_irq_plug_destroy);
/**
- * ps3_alloc_event_irq - Allocate a virq for use with a system event.
+ * ps3_event_receive_port_setup - Setup an event receive port.
* @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
* serviced on.
* @virq: The assigned Linux virq.
*
* The virq can be used with lv1_connect_interrupt_event_receive_port() to
- * arrange to receive events, or with ps3_send_event_locally() to signal
- * events.
+ * arrange to receive interrupts from system-bus devices, or with
+ * ps3_send_event_locally() to signal events.
*/
-int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq)
+int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq)
{
int result;
unsigned long outlet;
@@ -237,17 +261,27 @@ int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq)
return result;
}
- result = ps3_alloc_irq(cpu, outlet, virq);
+ result = ps3_irq_plug_setup(cpu, outlet, virq);
BUG_ON(result);
return result;
}
+EXPORT_SYMBOL_GPL(ps3_event_receive_port_setup);
+
+/**
+ * ps3_event_receive_port_destroy - Destroy an event receive port.
+ * @virq: The assigned Linux virq.
+ *
+ * Since ps3_event_receive_port_destroy destroys the receive port outlet,
+ * SB devices need to call disconnect_interrupt_event_receive_port() before
+ * this.
+ */
-int ps3_free_event_irq(unsigned int virq)
+int ps3_event_receive_port_destroy(unsigned int virq)
{
int result;
- pr_debug(" -> %s:%d\n", __func__, __LINE__);
+ pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq);
result = lv1_destruct_event_receive_port(virq_to_hw(virq));
@@ -255,11 +289,17 @@ int ps3_free_event_irq(unsigned int virq)
pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
__func__, __LINE__, ps3_result(result));
- ps3_free_irq(virq);
+ /* lv1_destruct_event_receive_port() destroys the IRQ plug,
+ * so don't call ps3_irq_plug_destroy() here.
+ */
+
+ result = ps3_virq_destroy(virq);
+ BUG_ON(result);
pr_debug(" <- %s:%d\n", __func__, __LINE__);
return result;
}
+EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy);
int ps3_send_event_locally(unsigned int virq)
{
@@ -267,7 +307,7 @@ int ps3_send_event_locally(unsigned int virq)
}
/**
- * ps3_connect_event_irq - Assign a virq to a system bus device.
+ * ps3_sb_event_receive_port_setup - Setup a system bus event receive port.
* @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
* serviced on.
* @did: The HV device identifier read from the system repository.
@@ -278,13 +318,15 @@ int ps3_send_event_locally(unsigned int virq)
* coresponds to the software interrupt number.
*/
-int ps3_connect_event_irq(enum ps3_cpu_binding cpu,
+int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
const struct ps3_device_id *did, unsigned int interrupt_id,
unsigned int *virq)
{
+ /* this should go in system-bus.c */
+
int result;
- result = ps3_alloc_event_irq(cpu, virq);
+ result = ps3_event_receive_port_setup(cpu, virq);
if (result)
return result;
@@ -296,7 +338,7 @@ int ps3_connect_event_irq(enum ps3_cpu_binding cpu,
pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port"
" failed: %s\n", __func__, __LINE__,
ps3_result(result));
- ps3_free_event_irq(*virq);
+ ps3_event_receive_port_destroy(*virq);
*virq = NO_IRQ;
return result;
}
@@ -306,10 +348,13 @@ int ps3_connect_event_irq(enum ps3_cpu_binding cpu,
return 0;
}
+EXPORT_SYMBOL(ps3_sb_event_receive_port_setup);
-int ps3_disconnect_event_irq(const struct ps3_device_id *did,
+int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did,
unsigned int interrupt_id, unsigned int virq)
{
+ /* this should go in system-bus.c */
+
int result;
pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
@@ -323,14 +368,65 @@ int ps3_disconnect_event_irq(const struct ps3_device_id *did,
" failed: %s\n", __func__, __LINE__,
ps3_result(result));
- ps3_free_event_irq(virq);
+ result = ps3_event_receive_port_destroy(virq);
+ BUG_ON(result);
pr_debug(" <- %s:%d\n", __func__, __LINE__);
return result;
}
+EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy);
/**
- * ps3_alloc_vuart_irq - Configure the system virtual uart virq.
+ * ps3_io_irq_setup - Setup a system bus io irq.
+ * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
+ * serviced on.
+ * @interrupt_id: The device interrupt id read from the system repository.
+ * @virq: The assigned Linux virq.
+ *
+ * An io irq represents a non-virtualized device interrupt. interrupt_id
+ * coresponds to the interrupt number of the interrupt controller.
+ */
+
+int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
+ unsigned int *virq)
+{
+ int result;
+ unsigned long outlet;
+
+ result = lv1_construct_io_irq_outlet(interrupt_id, &outlet);
+
+ if (result) {
+ pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n",
+ __func__, __LINE__, ps3_result(result));
+ return result;
+ }
+
+ result = ps3_irq_plug_setup(cpu, outlet, virq);
+ BUG_ON(result);
+
+ return result;
+}
+EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
+
+int ps3_io_irq_destroy(unsigned int virq)
+{
+ int result;
+
+ result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
+
+ if (result)
+ pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
+ __func__, __LINE__, ps3_result(result));
+
+ result = ps3_irq_plug_destroy(virq);
+ BUG_ON(result);
+
+ return result;
+}
+EXPORT_SYMBOL_GPL(ps3_io_irq_destroy);
+
+/**
+ * ps3_vuart_irq_setup - Setup the system virtual uart virq.
* @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
* serviced on.
* @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap.
@@ -340,7 +436,7 @@ int ps3_disconnect_event_irq(const struct ps3_device_id *did,
* freeing the interrupt will return a wrong state error.
*/
-int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
+int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
unsigned int *virq)
{
int result;
@@ -359,13 +455,13 @@ int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
return result;
}
- result = ps3_alloc_irq(cpu, outlet, virq);
+ result = ps3_irq_plug_setup(cpu, outlet, virq);
BUG_ON(result);
return result;
}
-int ps3_free_vuart_irq(unsigned int virq)
+int ps3_vuart_irq_destroy(unsigned int virq)
{
int result;
@@ -377,13 +473,14 @@ int ps3_free_vuart_irq(unsigned int virq)
return result;
}
- ps3_free_irq(virq);
+ result = ps3_irq_plug_destroy(virq);
+ BUG_ON(result);
return result;
}
/**
- * ps3_alloc_spe_irq - Configure an spe virq.
+ * ps3_spe_irq_setup - Setup an spe virq.
* @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
* serviced on.
* @spe_id: The spe_id returned from lv1_construct_logical_spe().
@@ -392,7 +489,7 @@ int ps3_free_vuart_irq(unsigned int virq)
*
*/
-int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id,
+int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
unsigned int class, unsigned int *virq)
{
int result;
@@ -408,15 +505,16 @@ int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id,
return result;
}
- result = ps3_alloc_irq(cpu, outlet, virq);
+ result = ps3_irq_plug_setup(cpu, outlet, virq);
BUG_ON(result);
return result;
}
-int ps3_free_spe_irq(unsigned int virq)
+int ps3_spe_irq_destroy(unsigned int virq)
{
- ps3_free_irq(virq);
+ int result = ps3_irq_plug_destroy(virq);
+ BUG_ON(result);
return 0;
}
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 2014d2b..f8a3e20 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -826,5 +826,4 @@ void __init ps3_mm_init(void)
void ps3_mm_shutdown(void)
{
ps3_mm_region_destroy(&map.r1);
- map.total = map.rm.size;
}
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index ac5df96..c989493 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -137,6 +137,12 @@ early_param("ps3fb", early_parse_ps3fb);
#define prealloc_ps3fb_videomemory() do { } while (0)
#endif
+static int ps3_set_dabr(u64 dabr)
+{
+ enum {DABR_USER = 1, DABR_KERNEL = 2,};
+
+ return lv1_set_dabr(dabr, DABR_KERNEL | DABR_USER) ? -1 : 0;
+}
static void __init ps3_setup_arch(void)
{
@@ -234,6 +240,7 @@ define_machine(ps3) {
.get_boot_time = ps3_get_boot_time,
.set_rtc_time = ps3_set_rtc_time,
.get_rtc_time = ps3_get_rtc_time,
+ .set_dabr = ps3_set_dabr,
.calibrate_decr = ps3_calibrate_decr,
.progress = ps3_progress,
.restart = ps3_restart,
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
index 6fb8879..8729348 100644
--- a/arch/powerpc/platforms/ps3/smp.c
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -110,7 +110,7 @@ static void __init ps3_smp_setup_cpu(int cpu)
BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3);
for (i = 0; i < MSG_COUNT; i++) {
- result = ps3_alloc_event_irq(cpu, &virqs[i]);
+ result = ps3_event_receive_port_setup(cpu, &virqs[i]);
if (result)
continue;
@@ -134,11 +134,13 @@ void ps3_smp_cleanup_cpu(int cpu)
int i;
DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
+
for (i = 0; i < MSG_COUNT; i++) {
- ps3_free_event_irq(virqs[i]);
free_irq(virqs[i], (void*)(long)i);
+ ps3_event_receive_port_destroy(virqs[i]);
virqs[i] = NO_IRQ;
}
+
DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
}
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c
index a397e4e..651437c 100644
--- a/arch/powerpc/platforms/ps3/spu.c
+++ b/arch/powerpc/platforms/ps3/spu.c
@@ -184,7 +184,7 @@ static int __init setup_areas(struct spu *spu)
spu_pdata(spu)->shadow = __ioremap(
spu_pdata(spu)->shadow_addr, sizeof(struct spe_shadow),
- PAGE_READONLY | _PAGE_NO_CACHE | _PAGE_GUARDED);
+ pgprot_val(PAGE_READONLY) | _PAGE_NO_CACHE | _PAGE_GUARDED);
if (!spu_pdata(spu)->shadow) {
pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__);
goto fail_ioremap;
@@ -230,19 +230,19 @@ static int __init setup_interrupts(struct spu *spu)
{
int result;
- result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+ result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
0, &spu->irqs[0]);
if (result)
goto fail_alloc_0;
- result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+ result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
1, &spu->irqs[1]);
if (result)
goto fail_alloc_1;
- result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+ result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
2, &spu->irqs[2]);
if (result)
@@ -251,9 +251,9 @@ static int __init setup_interrupts(struct spu *spu)
return result;
fail_alloc_2:
- ps3_free_spe_irq(spu->irqs[1]);
+ ps3_spe_irq_destroy(spu->irqs[1]);
fail_alloc_1:
- ps3_free_spe_irq(spu->irqs[0]);
+ ps3_spe_irq_destroy(spu->irqs[0]);
fail_alloc_0:
spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ;
return result;
@@ -301,9 +301,9 @@ static int ps3_destroy_spu(struct spu *spu)
result = lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0);
BUG_ON(result);
- ps3_free_spe_irq(spu->irqs[2]);
- ps3_free_spe_irq(spu->irqs[1]);
- ps3_free_spe_irq(spu->irqs[0]);
+ ps3_spe_irq_destroy(spu->irqs[2]);
+ ps3_spe_irq_destroy(spu->irqs[1]);
+ ps3_spe_irq_destroy(spu->irqs[0]);
spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ;
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 90235d5..ae1fc92 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SCANLOG) += scanlog.o
obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o
obj-$(CONFIG_KEXEC) += kexec.o
obj-$(CONFIG_PCI) += pci.o pci_dlpar.o
+obj-$(CONFIG_PCI_MSI) += msi.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 48fbd44..63e2306 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -580,6 +580,36 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state)
}
/**
+ * pcibios_set_pcie_slot_reset - Set PCI-E reset state
+ * @dev: pci device struct
+ * @state: reset state to enter
+ *
+ * Return value:
+ * 0 if success
+ **/
+int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state)
+{
+ struct device_node *dn = pci_device_to_OF_node(dev);
+ struct pci_dn *pdn = PCI_DN(dn);
+
+ switch (state) {
+ case pcie_deassert_reset:
+ rtas_pci_slot_reset(pdn, 0);
+ break;
+ case pcie_hot_reset:
+ rtas_pci_slot_reset(pdn, 1);
+ break;
+ case pcie_warm_reset:
+ rtas_pci_slot_reset(pdn, 3);
+ break;
+ default:
+ return -EINVAL;
+ };
+
+ return 0;
+}
+
+/**
* rtas_set_slot_reset -- assert the pci #RST line for 1/4 second
* @pdn: pci device node to be reset.
*
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 66665c8..eec684a 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -504,6 +504,12 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
break;
}
+ if (!pdn || !PCI_DN(pdn)) {
+ printk(KERN_WARNING "pci_dma_dev_setup_pSeriesLP: "
+ "no DMA window found for pci dev=%s dn=%s\n",
+ pci_name(dev), dn? dn->full_name : "<null>");
+ return;
+ }
DBG(" parent is %s\n", pdn->full_name);
/* Check for parent == NULL so we don't try to setup the empty EADS
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 3a70e8a..362dfbc 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -231,13 +231,13 @@ void __init find_udbg_vterm(void)
goto out;
vtermno = termno[0];
- if (device_is_compatible(stdout_node, "hvterm1")) {
+ if (of_device_is_compatible(stdout_node, "hvterm1")) {
udbg_putc = udbg_putcLP;
udbg_getc = udbg_getcLP;
udbg_getc_poll = udbg_getc_pollLP;
if (add_console)
add_preferred_console("hvc", termno[0] & 0xff, NULL);
- } else if (device_is_compatible(stdout_node, "hvterm-protocol")) {
+ } else if (of_device_is_compatible(stdout_node, "hvterm-protocol")) {
vtermno = termno[0];
udbg_putc = udbg_hvsi_putc;
udbg_getc = udbg_hvsi_getc;
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
new file mode 100644
index 0000000..6063ea2
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -0,0 +1,270 @@
+/*
+ * Copyright 2006 Jake Moilanen <moilanen@austin.ibm.com>, IBM Corp.
+ * Copyright 2006-2007 Michael Ellerman, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/irq.h>
+#include <linux/msi.h>
+
+#include <asm/rtas.h>
+#include <asm/hw_irq.h>
+#include <asm/ppc-pci.h>
+
+static int query_token, change_token;
+
+#define RTAS_QUERY_FN 0
+#define RTAS_CHANGE_FN 1
+#define RTAS_RESET_FN 2
+#define RTAS_CHANGE_MSI_FN 3
+#define RTAS_CHANGE_MSIX_FN 4
+
+static struct pci_dn *get_pdn(struct pci_dev *pdev)
+{
+ struct device_node *dn;
+ struct pci_dn *pdn;
+
+ dn = pci_device_to_OF_node(pdev);
+ if (!dn) {
+ dev_dbg(&pdev->dev, "rtas_msi: No OF device node\n");
+ return NULL;
+ }
+
+ pdn = PCI_DN(dn);
+ if (!pdn) {
+ dev_dbg(&pdev->dev, "rtas_msi: No PCI DN\n");
+ return NULL;
+ }
+
+ return pdn;
+}
+
+/* RTAS Helpers */
+
+static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs)
+{
+ u32 addr, seq_num, rtas_ret[3];
+ unsigned long buid;
+ int rc;
+
+ addr = rtas_config_addr(pdn->busno, pdn->devfn, 0);
+ buid = pdn->phb->buid;
+
+ seq_num = 1;
+ do {
+ if (func == RTAS_CHANGE_MSI_FN || func == RTAS_CHANGE_MSIX_FN)
+ rc = rtas_call(change_token, 6, 4, rtas_ret, addr,
+ BUID_HI(buid), BUID_LO(buid),
+ func, num_irqs, seq_num);
+ else
+ rc = rtas_call(change_token, 6, 3, rtas_ret, addr,
+ BUID_HI(buid), BUID_LO(buid),
+ func, num_irqs, seq_num);
+
+ seq_num = rtas_ret[1];
+ } while (rtas_busy_delay(rc));
+
+ if (rc == 0) /* Success */
+ rc = rtas_ret[0];
+
+ pr_debug("rtas_msi: ibm,change_msi(func=%d,num=%d) = (%d)\n",
+ func, num_irqs, rc);
+
+ return rc;
+}
+
+static void rtas_disable_msi(struct pci_dev *pdev)
+{
+ struct pci_dn *pdn;
+
+ pdn = get_pdn(pdev);
+ if (!pdn)
+ return;
+
+ if (rtas_change_msi(pdn, RTAS_CHANGE_FN, 0) != 0)
+ pr_debug("rtas_msi: Setting MSIs to 0 failed!\n");
+}
+
+static int rtas_query_irq_number(struct pci_dn *pdn, int offset)
+{
+ u32 addr, rtas_ret[2];
+ unsigned long buid;
+ int rc;
+
+ addr = rtas_config_addr(pdn->busno, pdn->devfn, 0);
+ buid = pdn->phb->buid;
+
+ do {
+ rc = rtas_call(query_token, 4, 3, rtas_ret, addr,
+ BUID_HI(buid), BUID_LO(buid), offset);
+ } while (rtas_busy_delay(rc));
+
+ if (rc) {
+ pr_debug("rtas_msi: error (%d) querying source number\n", rc);
+ return rc;
+ }
+
+ return rtas_ret[0];
+}
+
+static void rtas_teardown_msi_irqs(struct pci_dev *pdev)
+{
+ struct msi_desc *entry;
+
+ list_for_each_entry(entry, &pdev->msi_list, list) {
+ if (entry->irq == NO_IRQ)
+ continue;
+
+ set_irq_msi(entry->irq, NULL);
+ irq_dispose_mapping(entry->irq);
+ }
+
+ rtas_disable_msi(pdev);
+}
+
+static int check_req_msi(struct pci_dev *pdev, int nvec)
+{
+ struct device_node *dn;
+ struct pci_dn *pdn;
+ const u32 *req_msi;
+
+ pdn = get_pdn(pdev);
+ if (!pdn)
+ return -ENODEV;
+
+ dn = pdn->node;
+
+ req_msi = of_get_property(dn, "ibm,req#msi", NULL);
+ if (!req_msi) {
+ pr_debug("rtas_msi: No ibm,req#msi on %s\n", dn->full_name);
+ return -ENOENT;
+ }
+
+ if (*req_msi < nvec) {
+ pr_debug("rtas_msi: ibm,req#msi requests < %d MSIs\n", nvec);
+ return -ENOSPC;
+ }
+
+ return 0;
+}
+
+static int rtas_msi_check_device(struct pci_dev *pdev, int nvec, int type)
+{
+ if (type == PCI_CAP_ID_MSIX)
+ pr_debug("rtas_msi: MSI-X untested, trying anyway.\n");
+
+ return check_req_msi(pdev, nvec);
+}
+
+static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+{
+ struct pci_dn *pdn;
+ int hwirq, virq, i, rc;
+ struct msi_desc *entry;
+
+ pdn = get_pdn(pdev);
+ if (!pdn)
+ return -ENODEV;
+
+ /*
+ * Try the new more explicit firmware interface, if that fails fall
+ * back to the old interface. The old interface is known to never
+ * return MSI-Xs.
+ */
+ if (type == PCI_CAP_ID_MSI) {
+ rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec);
+
+ if (rc != nvec) {
+ pr_debug("rtas_msi: trying the old firmware call.\n");
+ rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec);
+ }
+ } else
+ rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec);
+
+ if (rc != nvec) {
+ pr_debug("rtas_msi: rtas_change_msi() failed\n");
+
+ /*
+ * In case of an error it's not clear whether the device is
+ * left with MSI enabled or not, so we explicitly disable.
+ */
+ goto out_free;
+ }
+
+ i = 0;
+ list_for_each_entry(entry, &pdev->msi_list, list) {
+ hwirq = rtas_query_irq_number(pdn, i);
+ if (hwirq < 0) {
+ rc = hwirq;
+ pr_debug("rtas_msi: error (%d) getting hwirq\n", rc);
+ goto out_free;
+ }
+
+ virq = irq_create_mapping(NULL, hwirq);
+
+ if (virq == NO_IRQ) {
+ pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq);
+ rc = -ENOSPC;
+ goto out_free;
+ }
+
+ dev_dbg(&pdev->dev, "rtas_msi: allocated virq %d\n", virq);
+ set_irq_msi(virq, entry);
+ unmask_msi_irq(virq);
+ }
+
+ return 0;
+
+ out_free:
+ rtas_teardown_msi_irqs(pdev);
+ return rc;
+}
+
+static void rtas_msi_pci_irq_fixup(struct pci_dev *pdev)
+{
+ /* No LSI -> leave MSIs (if any) configured */
+ if (pdev->irq == NO_IRQ) {
+ dev_dbg(&pdev->dev, "rtas_msi: no LSI, nothing to do.\n");
+ return;
+ }
+
+ /* No MSI -> MSIs can't have been assigned by fw, leave LSI */
+ if (check_req_msi(pdev, 1)) {
+ dev_dbg(&pdev->dev, "rtas_msi: no req#msi, nothing to do.\n");
+ return;
+ }
+
+ dev_dbg(&pdev->dev, "rtas_msi: disabling existing MSI.\n");
+ rtas_disable_msi(pdev);
+}
+
+static int rtas_msi_init(void)
+{
+ query_token = rtas_token("ibm,query-interrupt-source-number");
+ change_token = rtas_token("ibm,change-msi");
+
+ if ((query_token == RTAS_UNKNOWN_SERVICE) ||
+ (change_token == RTAS_UNKNOWN_SERVICE)) {
+ pr_debug("rtas_msi: no RTAS tokens, no MSI support.\n");
+ return -1;
+ }
+
+ pr_debug("rtas_msi: Registering RTAS MSI callbacks.\n");
+
+ WARN_ON(ppc_md.setup_msi_irqs);
+ ppc_md.setup_msi_irqs = rtas_setup_msi_irqs;
+ ppc_md.teardown_msi_irqs = rtas_teardown_msi_irqs;
+ ppc_md.msi_check_device = rtas_msi_check_device;
+
+ WARN_ON(ppc_md.pci_irq_fixup);
+ ppc_md.pci_irq_fixup = rtas_msi_pci_irq_fixup;
+
+ return 0;
+}
+arch_initcall(rtas_msi_init);
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index fdc1a36..ffaf6c5 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -79,6 +79,7 @@ pcibios_remove_pci_devices(struct pci_bus *bus)
pci_remove_bus_device(dev);
}
}
+EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
/* Must be called before pci_bus_add_devices */
void
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 33eec28..470db6e 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -168,7 +168,7 @@ static void __init pseries_mpic_init_IRQ(void)
/* Look for cascade */
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "chrp,iic")) {
+ if (of_device_is_compatible(np, "chrp,iic")) {
cascade = np;
break;
}
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 896cbf3..b854e7f 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -477,7 +477,7 @@ static int xics_host_match(struct irq_host *h, struct device_node *node)
* like vdevices, events, etc... The trick we use here is to match
* everything here except the legacy 8259 which is compatible "chrp,iic"
*/
- return !device_is_compatible(node, "chrp,iic");
+ return !of_device_is_compatible(node, "chrp,iic");
}
static int xics_host_map_direct(struct irq_host *h, unsigned int virq,
@@ -618,7 +618,7 @@ static void __init xics_setup_8259_cascade(void)
unsigned long intack = 0;
for_each_node_by_type(np, "interrupt-controller")
- if (device_is_compatible(np, "chrp,iic")) {
+ if (of_device_is_compatible(np, "chrp,iic")) {
found = np;
break;
}
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index e96ca96..9ce775c 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -2,7 +2,9 @@ ifeq ($(CONFIG_PPC64),y)
EXTRA_CFLAGS += -mno-minimal-toc
endif
-obj-$(CONFIG_MPIC) += mpic.o
+mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o
+obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y)
+
obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
obj-$(CONFIG_PPC_MPC106) += grackle.o
obj-$(CONFIG_PPC_DCR) += dcr.o
@@ -26,7 +28,6 @@ endif
# Temporary hack until we have migrated to asm-powerpc
ifeq ($(ARCH),powerpc)
-obj-$(CONFIG_MTD) += rom.o
obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o
obj-$(CONFIG_8xx) += mpc8xx_pic.o commproc.o
obj-$(CONFIG_UCODE_PATCH) += micropatch.o
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 336186d..a1d2042 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -36,6 +36,7 @@
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/vmalloc.h>
+#include <linux/suspend.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/iommu.h>
@@ -54,6 +55,9 @@ static unsigned long dart_tablesize;
/* Virtual base address of the DART table */
static u32 *dart_vbase;
+#ifdef CONFIG_PM
+static u32 *dart_copy;
+#endif
/* Mapped base address for the dart */
static unsigned int __iomem *dart;
@@ -346,6 +350,48 @@ void iommu_init_early_dart(void)
set_pci_dma_ops(&dma_direct_ops);
}
+#ifdef CONFIG_PM
+static void iommu_dart_save(void)
+{
+ memcpy(dart_copy, dart_vbase, 2*1024*1024);
+}
+
+static void iommu_dart_restore(void)
+{
+ memcpy(dart_vbase, dart_copy, 2*1024*1024);
+ dart_tlb_invalidate_all();
+}
+
+static int __init iommu_init_late_dart(void)
+{
+ unsigned long tbasepfn;
+ struct page *p;
+
+ /* if no dart table exists then we won't need to save it
+ * and the area has also not been reserved */
+ if (!dart_tablebase)
+ return 0;
+
+ tbasepfn = __pa(dart_tablebase) >> PAGE_SHIFT;
+ register_nosave_region_late(tbasepfn,
+ tbasepfn + ((1<<24) >> PAGE_SHIFT));
+
+ /* For suspend we need to copy the dart contents because
+ * it is not part of the regular mapping (see above) and
+ * thus not saved automatically. The memory for this copy
+ * must be allocated early because we need 2 MB. */
+ p = alloc_pages(GFP_KERNEL, 21 - PAGE_SHIFT);
+ BUG_ON(!p);
+ dart_copy = page_address(p);
+
+ ppc_md.iommu_save = iommu_dart_save;
+ ppc_md.iommu_restore = iommu_dart_restore;
+
+ return 0;
+}
+
+late_initcall(iommu_init_late_dart);
+#endif
void __init alloc_dart_table(void)
{
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 0b84b7c..4fd2bec 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -36,6 +36,8 @@
#include <asm/mpic.h>
#include <asm/smp.h>
+#include "mpic.h"
+
#ifdef DEBUG
#define DBG(fmt...) printk(fmt)
#else
@@ -354,6 +356,12 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
tmp |= 0x22;
writel(tmp, fixup->base + 4);
spin_unlock_irqrestore(&mpic->fixup_lock, flags);
+
+#ifdef CONFIG_PM
+ /* use the lowest bit inverted to the actual HW,
+ * set if this fixup was enabled, clear otherwise */
+ mpic->save_data[source].fixup_data = tmp | 1;
+#endif
}
static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
@@ -375,8 +383,58 @@ static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
tmp |= 1;
writel(tmp, fixup->base + 4);
spin_unlock_irqrestore(&mpic->fixup_lock, flags);
+
+#ifdef CONFIG_PM
+ /* use the lowest bit inverted to the actual HW,
+ * set if this fixup was enabled, clear otherwise */
+ mpic->save_data[source].fixup_data = tmp & ~1;
+#endif
}
+#ifdef CONFIG_PCI_MSI
+static void __init mpic_scan_ht_msi(struct mpic *mpic, u8 __iomem *devbase,
+ unsigned int devfn)
+{
+ u8 __iomem *base;
+ u8 pos, flags;
+ u64 addr = 0;
+
+ for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0;
+ pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) {
+ u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
+ if (id == PCI_CAP_ID_HT) {
+ id = readb(devbase + pos + 3);
+ if ((id & HT_5BIT_CAP_MASK) == HT_CAPTYPE_MSI_MAPPING)
+ break;
+ }
+ }
+
+ if (pos == 0)
+ return;
+
+ base = devbase + pos;
+
+ flags = readb(base + HT_MSI_FLAGS);
+ if (!(flags & HT_MSI_FLAGS_FIXED)) {
+ addr = readl(base + HT_MSI_ADDR_LO) & HT_MSI_ADDR_LO_MASK;
+ addr = addr | ((u64)readl(base + HT_MSI_ADDR_HI) << 32);
+ }
+
+ printk(KERN_DEBUG "mpic: - HT:%02x.%x %s MSI mapping found @ 0x%lx\n",
+ PCI_SLOT(devfn), PCI_FUNC(devfn),
+ flags & HT_MSI_FLAGS_ENABLE ? "enabled" : "disabled", addr);
+
+ if (!(flags & HT_MSI_FLAGS_ENABLE))
+ writeb(flags | HT_MSI_FLAGS_ENABLE, base + HT_MSI_FLAGS);
+}
+#else
+static void __init mpic_scan_ht_msi(struct mpic *mpic, u8 __iomem *devbase,
+ unsigned int devfn)
+{
+ return;
+}
+#endif
+
static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
unsigned int devfn, u32 vdid)
{
@@ -468,6 +526,7 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
goto next;
mpic_scan_ht_pic(mpic, devbase, devfn, l);
+ mpic_scan_ht_msi(mpic, devbase, devfn);
next:
/* next device, if function 0 */
@@ -559,7 +618,7 @@ static irqreturn_t mpic_ipi_action(int irq, void *dev_id)
*/
-static void mpic_unmask_irq(unsigned int irq)
+void mpic_unmask_irq(unsigned int irq)
{
unsigned int loops = 100000;
struct mpic *mpic = mpic_from_irq(irq);
@@ -579,7 +638,7 @@ static void mpic_unmask_irq(unsigned int irq)
} while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);
}
-static void mpic_mask_irq(unsigned int irq)
+void mpic_mask_irq(unsigned int irq)
{
unsigned int loops = 100000;
struct mpic *mpic = mpic_from_irq(irq);
@@ -600,7 +659,7 @@ static void mpic_mask_irq(unsigned int irq)
} while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
}
-static void mpic_end_irq(unsigned int irq)
+void mpic_end_irq(unsigned int irq)
{
struct mpic *mpic = mpic_from_irq(irq);
@@ -733,7 +792,7 @@ static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
}
}
-static int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
+int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
{
struct mpic *mpic = mpic_from_irq(virq);
unsigned int src = mpic_irq_to_hw(virq);
@@ -834,6 +893,8 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
if (hw >= mpic->irq_count)
return -EINVAL;
+ mpic_msi_reserve_hwirq(mpic, hw);
+
/* Default chip */
chip = &mpic->hc_irq;
@@ -1142,8 +1203,10 @@ void __init mpic_init(struct mpic *mpic)
/* Do the HT PIC fixups on U3 broken mpic */
DBG("MPIC flags: %x\n", mpic->flags);
- if ((mpic->flags & MPIC_U3_HT_IRQS) && (mpic->flags & MPIC_PRIMARY))
- mpic_scan_ht_pics(mpic);
+ if ((mpic->flags & MPIC_U3_HT_IRQS) && (mpic->flags & MPIC_PRIMARY)) {
+ mpic_scan_ht_pics(mpic);
+ mpic_u3msi_init(mpic);
+ }
for (i = 0; i < mpic->num_sources; i++) {
/* start with vector = source number, and masked */
@@ -1167,6 +1230,12 @@ void __init mpic_init(struct mpic *mpic)
/* Set current processor priority to 0 */
mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
+
+#ifdef CONFIG_PM
+ /* allocate memory to save mpic state */
+ mpic->save_data = alloc_bootmem(mpic->num_sources * sizeof(struct mpic_irq_save));
+ BUG_ON(mpic->save_data == NULL);
+#endif
}
void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio)
@@ -1333,8 +1402,11 @@ unsigned int mpic_get_one_irq(struct mpic *mpic)
#ifdef DEBUG_LOW
DBG("%s: get_one_irq(): %d\n", mpic->name, src);
#endif
- if (unlikely(src == mpic->spurious_vec))
+ if (unlikely(src == mpic->spurious_vec)) {
+ if (mpic->flags & MPIC_SPV_EOI)
+ mpic_eoi(mpic);
return NO_IRQ;
+ }
return irq_linear_revmap(mpic->irqhost, src);
}
@@ -1417,3 +1489,79 @@ void __devinit smp_mpic_setup_cpu(int cpu)
mpic_setup_this_cpu();
}
#endif /* CONFIG_SMP */
+
+#ifdef CONFIG_PM
+static int mpic_suspend(struct sys_device *dev, pm_message_t state)
+{
+ struct mpic *mpic = container_of(dev, struct mpic, sysdev);
+ int i;
+
+ for (i = 0; i < mpic->num_sources; i++) {
+ mpic->save_data[i].vecprio =
+ mpic_irq_read(i, MPIC_INFO(IRQ_VECTOR_PRI));
+ mpic->save_data[i].dest =
+ mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION));
+ }
+
+ return 0;
+}
+
+static int mpic_resume(struct sys_device *dev)
+{
+ struct mpic *mpic = container_of(dev, struct mpic, sysdev);
+ int i;
+
+ for (i = 0; i < mpic->num_sources; i++) {
+ mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI),
+ mpic->save_data[i].vecprio);
+ mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
+ mpic->save_data[i].dest);
+
+#ifdef CONFIG_MPIC_U3_HT_IRQS
+ {
+ struct mpic_irq_fixup *fixup = &mpic->fixups[i];
+
+ if (fixup->base) {
+ /* we use the lowest bit in an inverted meaning */
+ if ((mpic->save_data[i].fixup_data & 1) == 0)
+ continue;
+
+ /* Enable and configure */
+ writeb(0x10 + 2 * fixup->index, fixup->base + 2);
+
+ writel(mpic->save_data[i].fixup_data & ~1,
+ fixup->base + 4);
+ }
+ }
+#endif
+ } /* end for loop */
+
+ return 0;
+}
+#endif
+
+static struct sysdev_class mpic_sysclass = {
+#ifdef CONFIG_PM
+ .resume = mpic_resume,
+ .suspend = mpic_suspend,
+#endif
+ set_kset_name("mpic"),
+};
+
+static int mpic_init_sys(void)
+{
+ struct mpic *mpic = mpics;
+ int error, id = 0;
+
+ error = sysdev_class_register(&mpic_sysclass);
+
+ while (mpic && !error) {
+ mpic->sysdev.cls = &mpic_sysclass;
+ mpic->sysdev.id = id++;
+ error = sysdev_register(&mpic->sysdev);
+ mpic = mpic->next;
+ }
+ return error;
+}
+
+device_initcall(mpic_init_sys);
diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h
new file mode 100644
index 0000000..3a1c3d2
--- /dev/null
+++ b/arch/powerpc/sysdev/mpic.h
@@ -0,0 +1,38 @@
+#ifndef _POWERPC_SYSDEV_MPIC_H
+#define _POWERPC_SYSDEV_MPIC_H
+
+/*
+ * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#ifdef CONFIG_PCI_MSI
+extern void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq);
+extern int mpic_msi_init_allocator(struct mpic *mpic);
+extern irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num);
+extern void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num);
+extern int mpic_u3msi_init(struct mpic *mpic);
+#else
+static inline void mpic_msi_reserve_hwirq(struct mpic *mpic,
+ irq_hw_number_t hwirq)
+{
+ return;
+}
+
+static inline int mpic_u3msi_init(struct mpic *mpic)
+{
+ return -1;
+}
+#endif
+
+extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
+extern void mpic_end_irq(unsigned int irq);
+extern void mpic_mask_irq(unsigned int irq);
+extern void mpic_unmask_irq(unsigned int irq);
+
+#endif /* _POWERPC_SYSDEV_MPIC_H */
diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c
new file mode 100644
index 0000000..b076793
--- /dev/null
+++ b/arch/powerpc/sysdev/mpic_msi.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/irq.h>
+#include <linux/bootmem.h>
+#include <linux/bitmap.h>
+#include <linux/msi.h>
+#include <asm/mpic.h>
+#include <asm/prom.h>
+#include <asm/hw_irq.h>
+#include <asm/ppc-pci.h>
+
+
+static void __mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
+{
+ pr_debug("mpic: reserving hwirq 0x%lx\n", hwirq);
+ bitmap_allocate_region(mpic->hwirq_bitmap, hwirq, 0);
+}
+
+void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
+{
+ unsigned long flags;
+
+ /* The mpic calls this even when there is no allocator setup */
+ if (!mpic->hwirq_bitmap)
+ return;
+
+ spin_lock_irqsave(&mpic->bitmap_lock, flags);
+ __mpic_msi_reserve_hwirq(mpic, hwirq);
+ spin_unlock_irqrestore(&mpic->bitmap_lock, flags);
+}
+
+irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num)
+{
+ unsigned long flags;
+ int offset, order = get_count_order(num);
+
+ spin_lock_irqsave(&mpic->bitmap_lock, flags);
+ /*
+ * This is fast, but stricter than we need. We might want to add
+ * a fallback routine which does a linear search with no alignment.
+ */
+ offset = bitmap_find_free_region(mpic->hwirq_bitmap, mpic->irq_count,
+ order);
+ spin_unlock_irqrestore(&mpic->bitmap_lock, flags);
+
+ pr_debug("mpic: allocated 0x%x (2^%d) at offset 0x%x\n",
+ num, order, offset);
+
+ return offset;
+}
+
+void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num)
+{
+ unsigned long flags;
+ int order = get_count_order(num);
+
+ pr_debug("mpic: freeing 0x%x (2^%d) at offset 0x%x\n",
+ num, order, offset);
+
+ spin_lock_irqsave(&mpic->bitmap_lock, flags);
+ bitmap_release_region(mpic->hwirq_bitmap, offset, order);
+ spin_unlock_irqrestore(&mpic->bitmap_lock, flags);
+}
+
+#ifdef CONFIG_MPIC_U3_HT_IRQS
+static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
+{
+ irq_hw_number_t hwirq;
+ struct irq_host_ops *ops = mpic->irqhost->ops;
+ struct device_node *np;
+ int flags, index, i;
+ struct of_irq oirq;
+
+ pr_debug("mpic: found U3, guessing msi allocator setup\n");
+
+ /* Reserve source numbers we know are reserved in the HW */
+ for (i = 0; i < 8; i++)
+ __mpic_msi_reserve_hwirq(mpic, i);
+
+ for (i = 42; i < 46; i++)
+ __mpic_msi_reserve_hwirq(mpic, i);
+
+ for (i = 100; i < 105; i++)
+ __mpic_msi_reserve_hwirq(mpic, i);
+
+ np = NULL;
+ while ((np = of_find_all_nodes(np))) {
+ pr_debug("mpic: mapping hwirqs for %s\n", np->full_name);
+
+ index = 0;
+ while (of_irq_map_one(np, index++, &oirq) == 0) {
+ ops->xlate(mpic->irqhost, NULL, oirq.specifier,
+ oirq.size, &hwirq, &flags);
+ __mpic_msi_reserve_hwirq(mpic, hwirq);
+ }
+ }
+
+ return 0;
+}
+#else
+static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
+{
+ return -1;
+}
+#endif
+
+static int mpic_msi_reserve_dt_hwirqs(struct mpic *mpic)
+{
+ int i, len;
+ const u32 *p;
+
+ p = of_get_property(mpic->of_node, "msi-available-ranges", &len);
+ if (!p) {
+ pr_debug("mpic: no msi-available-ranges property found on %s\n",
+ mpic->of_node->full_name);
+ return -ENODEV;
+ }
+
+ if (len % 8 != 0) {
+ printk(KERN_WARNING "mpic: Malformed msi-available-ranges "
+ "property on %s\n", mpic->of_node->full_name);
+ return -EINVAL;
+ }
+
+ bitmap_allocate_region(mpic->hwirq_bitmap, 0,
+ get_count_order(mpic->irq_count));
+
+ /* Format is: (<u32 start> <u32 count>)+ */
+ len /= sizeof(u32);
+ for (i = 0; i < len / 2; i++, p += 2)
+ mpic_msi_free_hwirqs(mpic, *p, *(p + 1));
+
+ return 0;
+}
+
+int mpic_msi_init_allocator(struct mpic *mpic)
+{
+ int rc, size;
+
+ BUG_ON(mpic->hwirq_bitmap);
+ spin_lock_init(&mpic->bitmap_lock);
+
+ size = BITS_TO_LONGS(mpic->irq_count) * sizeof(long);
+ pr_debug("mpic: allocator bitmap size is 0x%x bytes\n", size);
+
+ if (mem_init_done)
+ mpic->hwirq_bitmap = kmalloc(size, GFP_KERNEL);
+ else
+ mpic->hwirq_bitmap = alloc_bootmem(size);
+
+ if (!mpic->hwirq_bitmap) {
+ pr_debug("mpic: ENOMEM allocating allocator bitmap!\n");
+ return -ENOMEM;
+ }
+
+ memset(mpic->hwirq_bitmap, 0, size);
+
+ rc = mpic_msi_reserve_dt_hwirqs(mpic);
+ if (rc) {
+ if (mpic->flags & MPIC_U3_HT_IRQS)
+ rc = mpic_msi_reserve_u3_hwirqs(mpic);
+
+ if (rc)
+ goto out_free;
+ }
+
+ return 0;
+
+ out_free:
+ if (mem_init_done)
+ kfree(mpic->hwirq_bitmap);
+
+ mpic->hwirq_bitmap = NULL;
+ return rc;
+}
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
new file mode 100644
index 0000000..305b864
--- /dev/null
+++ b/arch/powerpc/sysdev/mpic_u3msi.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2006, Segher Boessenkool, IBM Corporation.
+ * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/irq.h>
+#include <linux/bootmem.h>
+#include <linux/msi.h>
+#include <asm/mpic.h>
+#include <asm/prom.h>
+#include <asm/hw_irq.h>
+#include <asm/ppc-pci.h>
+
+#include "mpic.h"
+
+/* A bit ugly, can we get this from the pci_dev somehow? */
+static struct mpic *msi_mpic;
+
+static void mpic_u3msi_mask_irq(unsigned int irq)
+{
+ mask_msi_irq(irq);
+ mpic_mask_irq(irq);
+}
+
+static void mpic_u3msi_unmask_irq(unsigned int irq)
+{
+ mpic_unmask_irq(irq);
+ unmask_msi_irq(irq);
+}
+
+static struct irq_chip mpic_u3msi_chip = {
+ .shutdown = mpic_u3msi_mask_irq,
+ .mask = mpic_u3msi_mask_irq,
+ .unmask = mpic_u3msi_unmask_irq,
+ .eoi = mpic_end_irq,
+ .set_type = mpic_set_irq_type,
+ .typename = "MPIC-U3MSI",
+};
+
+static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos)
+{
+ u8 flags;
+ u32 tmp;
+ u64 addr;
+
+ pci_read_config_byte(pdev, pos + HT_MSI_FLAGS, &flags);
+
+ if (flags & HT_MSI_FLAGS_FIXED)
+ return HT_MSI_FIXED_ADDR;
+
+ pci_read_config_dword(pdev, pos + HT_MSI_ADDR_LO, &tmp);
+ addr = tmp & HT_MSI_ADDR_LO_MASK;
+ pci_read_config_dword(pdev, pos + HT_MSI_ADDR_HI, &tmp);
+ addr = addr | ((u64)tmp << 32);
+
+ return addr;
+}
+
+static u64 find_ht_magic_addr(struct pci_dev *pdev)
+{
+ struct pci_bus *bus;
+ unsigned int pos;
+
+ for (bus = pdev->bus; bus; bus = bus->parent) {
+ pos = pci_find_ht_capability(bus->self, HT_CAPTYPE_MSI_MAPPING);
+ if (pos)
+ return read_ht_magic_addr(bus->self, pos);
+ }
+
+ return 0;
+}
+
+static int u3msi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
+{
+ if (type == PCI_CAP_ID_MSIX)
+ pr_debug("u3msi: MSI-X untested, trying anyway.\n");
+
+ /* If we can't find a magic address then MSI ain't gonna work */
+ if (find_ht_magic_addr(pdev) == 0) {
+ pr_debug("u3msi: no magic address found for %s\n",
+ pci_name(pdev));
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static void u3msi_teardown_msi_irqs(struct pci_dev *pdev)
+{
+ struct msi_desc *entry;
+
+ list_for_each_entry(entry, &pdev->msi_list, list) {
+ if (entry->irq == NO_IRQ)
+ continue;
+
+ set_irq_msi(entry->irq, NULL);
+ mpic_msi_free_hwirqs(msi_mpic, virq_to_hw(entry->irq), 1);
+ irq_dispose_mapping(entry->irq);
+ }
+
+ return;
+}
+
+static void u3msi_compose_msi_msg(struct pci_dev *pdev, int virq,
+ struct msi_msg *msg)
+{
+ u64 addr;
+
+ addr = find_ht_magic_addr(pdev);
+ msg->address_lo = addr & 0xFFFFFFFF;
+ msg->address_hi = addr >> 32;
+ msg->data = virq_to_hw(virq);
+
+ pr_debug("u3msi: allocated virq 0x%x (hw 0x%lx) at address 0x%lx\n",
+ virq, virq_to_hw(virq), addr);
+}
+
+static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+{
+ irq_hw_number_t hwirq;
+ int rc;
+ unsigned int virq;
+ struct msi_desc *entry;
+ struct msi_msg msg;
+
+ list_for_each_entry(entry, &pdev->msi_list, list) {
+ hwirq = mpic_msi_alloc_hwirqs(msi_mpic, 1);
+ if (hwirq < 0) {
+ rc = hwirq;
+ pr_debug("u3msi: failed allocating hwirq\n");
+ goto out_free;
+ }
+
+ virq = irq_create_mapping(msi_mpic->irqhost, hwirq);
+ if (virq == NO_IRQ) {
+ pr_debug("u3msi: failed mapping hwirq 0x%lx\n", hwirq);
+ mpic_msi_free_hwirqs(msi_mpic, hwirq, 1);
+ rc = -ENOSPC;
+ goto out_free;
+ }
+
+ set_irq_msi(virq, entry);
+ set_irq_chip(virq, &mpic_u3msi_chip);
+ set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
+
+ u3msi_compose_msi_msg(pdev, virq, &msg);
+ write_msi_msg(virq, &msg);
+
+ hwirq++;
+ }
+
+ return 0;
+
+ out_free:
+ u3msi_teardown_msi_irqs(pdev);
+ return rc;
+}
+
+int mpic_u3msi_init(struct mpic *mpic)
+{
+ int rc;
+
+ rc = mpic_msi_init_allocator(mpic);
+ if (rc) {
+ pr_debug("u3msi: Error allocating bitmap!\n");
+ return rc;
+ }
+
+ pr_debug("u3msi: Registering MPIC U3 MSI callbacks.\n");
+
+ BUG_ON(msi_mpic);
+ msi_mpic = mpic;
+
+ WARN_ON(ppc_md.setup_msi_irqs);
+ ppc_md.setup_msi_irqs = u3msi_setup_msi_irqs;
+ ppc_md.teardown_msi_irqs = u3msi_teardown_msi_irqs;
+ ppc_md.msi_check_device = u3msi_msi_check_device;
+
+ return 0;
+}
diff --git a/arch/powerpc/sysdev/rom.c b/arch/powerpc/sysdev/rom.c
deleted file mode 100644
index c855a3b..0000000
--- a/arch/powerpc/sysdev/rom.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * ROM device registration
- *
- * (C) 2006 MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#include <linux/kernel.h>
-#include <asm/of_device.h>
-#include <asm/of_platform.h>
-
-static int __init powerpc_flash_init(void)
-{
- struct device_node *node = NULL;
-
- /*
- * Register all the devices which type is "rom"
- */
- while ((node = of_find_node_by_type(node, "rom")) != NULL) {
- if (node->name == NULL) {
- printk(KERN_WARNING "powerpc_flash_init: found 'rom' "
- "device, but with no name, skipping...\n");
- continue;
- }
- of_platform_device_create(node, node->name, NULL);
- }
- return 0;
-}
-
-arch_initcall(powerpc_flash_init);
diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c
index 337039e..7d3b09b 100644
--- a/arch/powerpc/sysdev/tsi108_dev.c
+++ b/arch/powerpc/sysdev/tsi108_dev.c
@@ -107,8 +107,9 @@ static int __init tsi108_eth_of_init(void)
goto err;
}
- mac_addr = of_get_property(np, "address", NULL);
- memcpy(tsi_eth_data.mac_addr, mac_addr, 6);
+ mac_addr = of_get_mac_address(np);
+ if (mac_addr)
+ memcpy(tsi_eth_data.mac_addr, mac_addr, 6);
ph = of_get_property(np, "phy-handle", NULL);
phy = of_find_node_by_phandle(*ph);
@@ -129,6 +130,8 @@ static int __init tsi108_eth_of_init(void)
tsi_eth_data.phyregs = res.start;
tsi_eth_data.phy = *phy_id;
tsi_eth_data.irq_num = irq_of_parse_and_map(np, 0);
+ if (of_device_is_compatible(phy, "bcm54xx"))
+ tsi_eth_data.phy_type = TSI108_PHY_BCM54XX;
of_node_put(phy);
ret =
platform_device_add_data(tsi_eth_dev, &tsi_eth_data,
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 58b9e7f..2153163 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -35,6 +35,7 @@
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
#include <asm/tsi108.h>
+#include <asm/tsi108_pci.h>
#include <asm/tsi108_irq.h>
#include <asm/prom.h>
@@ -49,6 +50,7 @@
((((bus)<<16) | ((devfunc)<<8) | (offset & 0xfc)) + tsi108_pci_cfg_base)
u32 tsi108_pci_cfg_base;
+static u32 tsi108_pci_cfg_phys;
u32 tsi108_csr_vir_base;
static struct device_node *pci_irq_node;
static struct irq_host *pci_irq_host;
@@ -185,7 +187,7 @@ tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
void tsi108_clear_pci_cfg_error(void)
{
- tsi108_clear_pci_error(TSI108_PCI_CFG_BASE_PHYS);
+ tsi108_clear_pci_error(tsi108_pci_cfg_phys);
}
static struct pci_ops tsi108_direct_pci_ops = {
@@ -193,17 +195,17 @@ static struct pci_ops tsi108_direct_pci_ops = {
tsi108_direct_write_config
};
-int __init tsi108_setup_pci(struct device_node *dev)
+int __init tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary)
{
int len;
struct pci_controller *hose;
struct resource rsrc;
const int *bus_range;
- int primary = 0, has_address = 0;
+ int has_address = 0;
/* PCI Config mapping */
- tsi108_pci_cfg_base = (u32)ioremap(TSI108_PCI_CFG_BASE_PHYS,
- TSI108_PCI_CFG_SIZE);
+ tsi108_pci_cfg_base = (u32)ioremap(cfg_phys, TSI108_PCI_CFG_SIZE);
+ tsi108_pci_cfg_phys = cfg_phys;
DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __FUNCTION__,
tsi108_pci_cfg_base);
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 968fb40..8905989 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -221,7 +221,7 @@ static struct uic * __init uic_init_one(struct device_node *node)
const u32 *indexp, *dcrreg;
int len;
- BUG_ON(! device_is_compatible(node, "ibm,uic"));
+ BUG_ON(! of_device_is_compatible(node, "ibm,uic"));
uic = alloc_bootmem(sizeof(*uic));
if (! uic)
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index b481db1..28fdf4f 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1217,7 +1217,6 @@ static void get_function_bounds(unsigned long pc, unsigned long *startp,
{
unsigned long size, offset;
const char *name;
- char *modname;
*startp = *endp = 0;
if (pc == 0)
@@ -1225,7 +1224,7 @@ static void get_function_bounds(unsigned long pc, unsigned long *startp,
if (setjmp(bus_error_jmp) == 0) {
catch_memory_errors = 1;
sync();
- name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
+ name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
if (name != NULL) {
*startp = pc - offset;
*endp = pc - offset + size;
diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c
index 0a7e42d..aa07b63 100644
--- a/arch/ppc/kernel/ppc_htab.c
+++ b/arch/ppc/kernel/ppc_htab.c
@@ -18,7 +18,6 @@
#include <linux/capability.h>
#include <linux/ctype.h>
#include <linux/threads.h>
-#include <linux/smp_lock.h>
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/bitops.h>
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index 96a5597..0559985 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -12,7 +12,6 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
diff --git a/arch/ppc/syslib/ppc4xx_sgdma.c b/arch/ppc/syslib/ppc4xx_sgdma.c
index 5dadca3e..c4b369b 100644
--- a/arch/ppc/syslib/ppc4xx_sgdma.c
+++ b/arch/ppc/syslib/ppc4xx_sgdma.c
@@ -23,10 +23,10 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/dma-mapping.h>
#include <asm/system.h>
#include <asm/io.h>
-#include <asm/dma-mapping.h>
#include <asm/ppc4xx_dma.h>
void
diff --git a/arch/ppc/syslib/virtex_devices.h b/arch/ppc/syslib/virtex_devices.h
index 4a17dd3..3d4be14 100644
--- a/arch/ppc/syslib/virtex_devices.h
+++ b/arch/ppc/syslib/virtex_devices.h
@@ -13,6 +13,13 @@
#include <linux/platform_device.h>
+/* ML300/403 reference design framebuffer driver platform data struct */
+struct xilinxfb_platform_data {
+ u32 rotate_screen;
+ u32 screen_height_mm;
+ u32 screen_width_mm;
+};
+
void __init virtex_early_serial_map(void);
/* Prototype for device fixup routine. Implement this routine in the
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index e6ec418..1a84719 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -49,6 +49,9 @@ config GENERIC_BUG
config NO_IOMEM
def_bool y
+config NO_DMA
+ def_bool y
+
mainmenu "Linux Kernel Configuration"
config S390
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index 80a54a0..a5692c4 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index dabaf98..a057ebf 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -23,6 +23,7 @@
#include <linux/kallsyms.h>
#include <linux/reboot.h>
#include <linux/kprobes.h>
+#include <linux/kdebug.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -33,7 +34,6 @@
#include <asm/s390_ext.h>
#include <asm/lowcore.h>
#include <asm/debug.h>
-#include <asm/kdebug.h>
#ifndef CONFIG_64BIT
#define ONELONG "%08lx: "
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 23c61f6..e39333a 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -24,8 +24,8 @@
#include <linux/ptrace.h>
#include <linux/preempt.h>
#include <linux/stop_machine.h>
+#include <linux/kdebug.h>
#include <asm/cacheflush.h>
-#include <asm/kdebug.h>
#include <asm/sections.h>
#include <asm/uaccess.h>
#include <linux/module.h>
@@ -271,23 +271,13 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
- struct kretprobe_instance *ri;
+ ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
-
- /* Replace the return addr with trampoline addr */
- regs->gprs[14] = (unsigned long)&kretprobe_trampoline;
-
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ /* Replace the return addr with trampoline addr */
+ regs->gprs[14] = (unsigned long)&kretprobe_trampoline;
}
static int __kprobes kprobe_handler(struct pt_regs *regs)
@@ -671,3 +661,10 @@ int __init arch_init_kprobes(void)
{
return register_kprobe(&trampoline_p);
}
+
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+ if (p->addr == (kprobe_opcode_t *) & kretprobe_trampoline)
+ return 1;
+ return 0;
+}
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 11d9b01..eb43c3b 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -22,7 +22,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 3c41907..d264671 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 3754e20..b797702 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -25,7 +25,6 @@
#include <linux/mm.h>
#include <linux/spinlock.h>
#include <linux/kernel_stat.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/cache.h>
#include <linux/interrupt.h>
diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c
index 2e5c65a..515ff90 100644
--- a/arch/s390/kernel/stacktrace.c
+++ b/arch/s390/kernel/stacktrace.c
@@ -59,7 +59,7 @@ static unsigned long save_context_stack(struct stack_trace *trace,
}
}
-void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+void save_stack_trace(struct stack_trace *trace)
{
register unsigned long sp asm ("15");
unsigned long orig_sp, new_sp;
@@ -69,20 +69,16 @@ void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
new_sp = save_context_stack(trace, &trace->skip, orig_sp,
S390_lowcore.panic_stack - PAGE_SIZE,
S390_lowcore.panic_stack);
- if ((new_sp != orig_sp) && !trace->all_contexts)
+ if (new_sp != orig_sp)
return;
new_sp = save_context_stack(trace, &trace->skip, new_sp,
S390_lowcore.async_stack - ASYNC_SIZE,
S390_lowcore.async_stack);
- if ((new_sp != orig_sp) && !trace->all_contexts)
+ if (new_sp != orig_sp)
return;
- if (task)
- save_context_stack(trace, &trace->skip, new_sp,
- (unsigned long) task_stack_page(task),
- (unsigned long) task_stack_page(task) + THREAD_SIZE);
- else
- save_context_stack(trace, &trace->skip, new_sp,
- S390_lowcore.thread_info,
- S390_lowcore.thread_info + THREAD_SIZE);
+
+ save_context_stack(trace, &trace->skip, new_sp,
+ S390_lowcore.thread_info,
+ S390_lowcore.thread_info + THREAD_SIZE);
return;
}
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index 3a77c22..1c90c7e 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -17,7 +17,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 711dae8..9c2872a 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -21,6 +21,7 @@
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/time.h>
+#include <linux/sysdev.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/smp.h>
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 49dec83..cbfe730 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -22,11 +22,11 @@
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/module.h>
+#include <linux/kdebug.h>
#include <linux/kallsyms.h>
#include <linux/reboot.h>
#include <linux/kprobes.h>
@@ -40,7 +40,6 @@
#include <asm/s390_ext.h>
#include <asm/lowcore.h>
#include <asm/debug.h>
-#include <asm/kdebug.h>
/* Called from entry.S only */
extern void handle_per_exception(struct pt_regs *regs);
@@ -70,20 +69,6 @@ static int kstack_depth_to_print = 12;
static int kstack_depth_to_print = 20;
#endif /* CONFIG_64BIT */
-ATOMIC_NOTIFIER_HEAD(s390die_chain);
-
-int register_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_register(&s390die_chain, nb);
-}
-EXPORT_SYMBOL(register_die_notifier);
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&s390die_chain, nb);
-}
-EXPORT_SYMBOL(unregister_die_notifier);
-
/*
* For show_trace we have tree different stack to consider:
* - the panic stack which is used if the kernel stack has overflown
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 91f705a..8b924b3 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -20,6 +20,7 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
+#include <linux/kdebug.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/console.h>
@@ -30,7 +31,6 @@
#include <asm/system.h>
#include <asm/pgtable.h>
-#include <asm/kdebug.h>
#include <asm/s390_ext.h>
#ifndef CONFIG_64BIT
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 4d16d89..d74eb12 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -22,6 +22,10 @@ config RWSEM_GENERIC_SPINLOCK
config RWSEM_XCHGADD_ALGORITHM
bool
+config GENERIC_BUG
+ def_bool y
+ depends on BUG
+
config GENERIC_FIND_NEXT_BIT
bool
default y
@@ -88,6 +92,14 @@ config SH_SOLUTION_ENGINE
Select SolutionEngine if configuring for a Hitachi SH7709
or SH7750 evaluation board.
+config SH_7722_SOLUTION_ENGINE
+ bool "SolutionEngine7722"
+ select SOLUTION_ENGINE
+ select CPU_SUBTYPE_SH7722
+ help
+ Select 7722 SolutionEngine if configuring for a Hitachi SH772
+ evaluation board.
+
config SH_7751_SOLUTION_ENGINE
bool "SolutionEngine7751"
select SOLUTION_ENGINE
@@ -95,6 +107,14 @@ config SH_7751_SOLUTION_ENGINE
help
Select 7751 SolutionEngine if configuring for a Hitachi SH7751
evaluation board.
+
+config SH_7780_SOLUTION_ENGINE
+ bool "SolutionEngine7780"
+ select SOLUTION_ENGINE
+ select CPU_SUBTYPE_SH7780
+ help
+ Select 7780 SolutionEngine if configuring for a Renesas SH7780
+ evaluation board.
config SH_7300_SOLUTION_ENGINE
bool "SolutionEngine7300"
@@ -193,12 +213,8 @@ config SH_RTS7751R2D
Select RTS7751R2D if configuring for a Renesas Technology
Sales SH-Graphics board.
-config SH_R7780RP
- bool "R7780RP-1"
- select CPU_SUBTYPE_SH7780
- help
- Select R7780RP-1 if configuring for a Renesas Solutions
- HIGHLANDER board.
+config SH_HIGHLANDER
+ bool "Highlander"
config SH_EDOSK7705
bool "EDOSK7705"
@@ -243,6 +259,12 @@ config SH_7619_SOLUTION_ENGINE
help
Select 7619 SolutionEngine if configuring for a Hitachi SH7619
evaluation board.
+
+config SH_LBOX_RE2
+ bool "L-BOX RE2"
+ select CPU_SUBTYPE_SH7751R
+ help
+ Select L-BOX RE2 if configuring for the NTT COMWARE L-BOX RE2.
config SH_UNKNOWN
bool "BareCPU"
@@ -258,6 +280,10 @@ config SH_UNKNOWN
endchoice
+source "arch/sh/boards/renesas/hs7751rvoip/Kconfig"
+source "arch/sh/boards/renesas/rts7751r2d/Kconfig"
+source "arch/sh/boards/renesas/r7780rp/Kconfig"
+
source "arch/sh/mm/Kconfig"
config CF_ENABLER
@@ -366,6 +392,16 @@ config SH_STORE_QUEUES
Selecting this option will enable an in-kernel API for manipulating
the store queues integrated in the SH-4 processors.
+config SPECULATIVE_EXECUTION
+ bool "Speculative subroutine return"
+ depends on CPU_SUBTYPE_SH7780 && EXPERIMENTAL
+ help
+ This enables support for a speculative instruction fetch for
+ subroutine return. There are various pitfalls associated with
+ this, as outlined in the SH7780 hardware manual.
+
+ If unsure, say N.
+
config CPU_HAS_INTEVT
bool
@@ -398,8 +434,9 @@ config CPU_HAS_PTEA
endmenu
-menu "Timer support"
-depends on !GENERIC_TIME
+menu "Timer and clock configuration"
+
+if !GENERIC_TIME
config SH_TMU
bool "TMU timer support"
@@ -422,17 +459,11 @@ config SH_MTU2
help
This enables the use of the MTU2 as the system timer.
-endmenu
-
-source "arch/sh/boards/renesas/hs7751rvoip/Kconfig"
-
-source "arch/sh/boards/renesas/rts7751r2d/Kconfig"
-
-source "arch/sh/boards/renesas/r7780rp/Kconfig"
+endif
config SH_TIMER_IRQ
int
- default "28" if CPU_SUBTYPE_SH7780
+ default "28" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
default "86" if CPU_SUBTYPE_SH7619
default "140" if CPU_SUBTYPE_SH7206
default "16"
@@ -462,7 +493,8 @@ config SH_PCLK_FREQ
default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \
CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \
CPU_SUBTYPE_SH7206
- default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780
+ default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780 || \
+ CPU_SUBTYPE_SH7785
default "60000000" if CPU_SUBTYPE_SH7751
default "66000000" if CPU_SUBTYPE_SH4_202
help
@@ -477,6 +509,8 @@ config SH_CLK_MD
help
MD2 - MD0 pin setting.
+endmenu
+
menu "CPU Frequency scaling"
source "drivers/cpufreq/Kconfig"
@@ -495,21 +529,6 @@ config SH_CPU_FREQ
endmenu
-source "arch/sh/drivers/dma/Kconfig"
-
-source "arch/sh/cchips/Kconfig"
-
-config HEARTBEAT
- bool "Heartbeat LED"
- depends on SH_MPC1211 || SH_SH03 || \
- SOLUTION_ENGINE || \
- SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_LANDISK || \
- SH_R7780RP
- help
- Use the power-on LED on your machine as a load meter. The exact
- behavior is platform-dependent, but normally the flash frequency is
- a hyperbolic function of the 5-minute load average.
-
source "arch/sh/drivers/Kconfig"
endmenu
@@ -540,6 +559,20 @@ config KEXEC
support. As of this writing the exact hardware interface is
strongly in flux, so no good recommendation can be made.
+config CRASH_DUMP
+ bool "kernel crash dumps (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ help
+ Generate crash dump after being started by kexec.
+ This should be normally only set in special crash dump kernels
+ which are loaded in the main kernel with kexec-tools into
+ a specially reserved region and then later executed after
+ a crash by kdump/kexec. The crash dump kernel must be compiled
+ to a memory address not used by the main kernel using
+ MEMORY_START.
+
+ For more details see Documentation/kdump/kdump.txt
+
config SMP
bool "Symmetric multi-processing support"
---help---
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index 87902e0..b563072 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -33,6 +33,7 @@ config EARLY_SCIF_CONSOLE_PORT
default "0xffe00000" if CPU_SUBTYPE_SH7780
default "0xfffe9800" if CPU_SUBTYPE_SH7206
default "0xf8420000" if CPU_SUBTYPE_SH7619
+ default "0xa4400000" if CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7705
default "0xffe80000" if CPU_SH4
config EARLY_PRINTK
@@ -77,16 +78,17 @@ config 4KSTACKS
on the VM subsystem for higher order allocations. This option
will also use IRQ stacks to compensate for the reduced stackspace.
-config KGDB
+config SH_KGDB
bool "Include KGDB kernel debugger"
select FRAME_POINTER
+ select DEBUG_INFO
help
Include in-kernel hooks for kgdb, the Linux kernel source level
debugger. See <http://kgdb.sourceforge.net/> for more information.
Unless you are intending to debug the kernel, say N here.
menu "KGDB configuration options"
- depends on KGDB
+ depends on SH_KGDB
config MORE_COMPILE_OPTIONS
bool "Add any additional compile options"
@@ -103,22 +105,16 @@ config KGDB_NMI
bool "Enter KGDB on NMI"
default n
-config KGDB_THREAD
- bool "Include KGDB thread support"
- default y
-
config SH_KGDB_CONSOLE
bool "Console messages through GDB"
+ depends on !SERIAL_SH_SCI_CONSOLE
+ select SERIAL_CORE_CONSOLE
default n
config KGDB_SYSRQ
bool "Allow SysRq 'G' to enter KGDB"
default y
-config KGDB_KERNEL_ASSERTS
- bool "Include KGDB kernel assertions"
- default n
-
comment "Serial port setup"
config KGDB_DEFPORT
@@ -131,7 +127,7 @@ config KGDB_DEFBAUD
choice
prompt "Parity"
- depends on KGDB
+ depends on SH_KGDB
default KGDB_DEFPARITY_N
config KGDB_DEFPARITY_N
@@ -147,7 +143,7 @@ endchoice
choice
prompt "Data bits"
- depends on KGDB
+ depends on SH_KGDB
default KGDB_DEFBITS_8
config KGDB_DEFBITS_8
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index bd9b172..7b11224 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -47,7 +47,6 @@ cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml
cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding
cflags-$(CONFIG_SH_DSP) += -Wa,-dsp
-cflags-$(CONFIG_SH_KGDB) += -g
cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \
$(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
@@ -89,7 +88,9 @@ core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/
# Boards
machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x
+machdir-$(CONFIG_SH_7722_SOLUTION_ENGINE) := se/7722
machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751
+machdir-$(CONFIG_SH_7780_SOLUTION_ENGINE) := se/7780
machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300
machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) := se/7343
machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180
@@ -103,7 +104,7 @@ machdir-$(CONFIG_SH_HS7751RVOIP) := renesas/hs7751rvoip
machdir-$(CONFIG_SH_RTS7751R2D) := renesas/rts7751r2d
machdir-$(CONFIG_SH_7751_SYSTEMH) := renesas/systemh
machdir-$(CONFIG_SH_EDOSK7705) := renesas/edosk7705
-machdir-$(CONFIG_SH_R7780RP) := renesas/r7780rp
+machdir-$(CONFIG_SH_HIGHLANDER) := renesas/r7780rp
machdir-$(CONFIG_SH_7710VOIPGW) := renesas/sh7710voipgw
machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev
machdir-$(CONFIG_SH_LANDISK) := landisk
@@ -111,6 +112,7 @@ machdir-$(CONFIG_SH_TITAN) := titan
machdir-$(CONFIG_SH_SHMIN) := shmin
machdir-$(CONFIG_SH_7206_SOLUTION_ENGINE) := se/7206
machdir-$(CONFIG_SH_7619_SOLUTION_ENGINE) := se/7619
+machdir-$(CONFIG_SH_LBOX_RE2) := lboxre2
machdir-$(CONFIG_SH_UNKNOWN) := unknown
incdir-y := $(notdir $(machdir-y))
diff --git a/arch/sh/boards/hp6xx/Makefile b/arch/sh/boards/hp6xx/Makefile
index ff1b7f5..b312427 100644
--- a/arch/sh/boards/hp6xx/Makefile
+++ b/arch/sh/boards/hp6xx/Makefile
@@ -2,6 +2,6 @@
# Makefile for the HP6xx specific parts of the kernel
#
-obj-y := setup.o
+obj-y := setup.o
obj-$(CONFIG_PM) += pm.o pm_wakeup.o
-obj-$(CONFIG_APM) += hp6xx_apm.o
+obj-$(CONFIG_APM_EMULATION) += hp6xx_apm.o
diff --git a/arch/sh/boards/hp6xx/setup.c b/arch/sh/boards/hp6xx/setup.c
index b5a9664..6aeee85 100644
--- a/arch/sh/boards/hp6xx/setup.c
+++ b/arch/sh/boards/hp6xx/setup.c
@@ -2,6 +2,7 @@
* linux/arch/sh/boards/hp6xx/setup.c
*
* Copyright (C) 2002 Andriy Skulysh
+ * Copyright (C) 2007 Kristoffer Ericson <Kristoffer_e1@hotmail.com>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
@@ -10,6 +11,7 @@
*/
#include <linux/types.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <asm/hd64461.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -19,6 +21,40 @@
#define SCPCR 0xa4000116
#define SCPDR 0xa4000136
+/* CF Slot */
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = 0x15000000 + 0x1f0,
+ .end = 0x15000000 + 0x1f0 + 0x08 - 0x01,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0x15000000 + 0x1fe,
+ .end = 0x15000000 + 0x1fe + 0x01,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = 93,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
+static struct platform_device *hp6xx_devices[] __initdata = {
+ &cf_ide_device,
+};
+
+static int __init hp6xx_devices_setup(void)
+{
+ return platform_add_devices(hp6xx_devices, ARRAY_SIZE(hp6xx_devices));
+}
+
static void __init hp6xx_setup(char **cmdline_p)
{
u8 v8;
@@ -60,41 +96,12 @@ static void __init hp6xx_setup(char **cmdline_p)
v |= SCPCR_TS_ENABLE;
ctrl_outw(v, SCPCR);
}
+device_initcall(hp6xx_devices_setup);
-/*
- * XXX: This is stupid, we should have a generic machine vector for the cchips
- * and just wrap the platform setup code in to this, as it's the only thing
- * that ends up being different.
- */
struct sh_machine_vector mv_hp6xx __initmv = {
.mv_name = "hp6xx",
.mv_setup = hp6xx_setup,
.mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM,
-
- .mv_inb = hd64461_inb,
- .mv_inw = hd64461_inw,
- .mv_inl = hd64461_inl,
- .mv_outb = hd64461_outb,
- .mv_outw = hd64461_outw,
- .mv_outl = hd64461_outl,
-
- .mv_inb_p = hd64461_inb_p,
- .mv_inw_p = hd64461_inw,
- .mv_inl_p = hd64461_inl,
- .mv_outb_p = hd64461_outb_p,
- .mv_outw_p = hd64461_outw,
- .mv_outl_p = hd64461_outl,
-
- .mv_insb = hd64461_insb,
- .mv_insw = hd64461_insw,
- .mv_insl = hd64461_insl,
- .mv_outsb = hd64461_outsb,
- .mv_outsw = hd64461_outsw,
- .mv_outsl = hd64461_outsl,
-
- .mv_readw = hd64461_readw,
- .mv_writew = hd64461_writew,
-
.mv_irq_demux = hd64461_irq_demux,
};
ALIAS_MV(hp6xx)
diff --git a/arch/sh/boards/landisk/Makefile b/arch/sh/boards/landisk/Makefile
index 89e4beb..a696b42 100644
--- a/arch/sh/boards/landisk/Makefile
+++ b/arch/sh/boards/landisk/Makefile
@@ -2,4 +2,4 @@
# Makefile for I-O DATA DEVICE, INC. "LANDISK Series"
#
-obj-y := setup.o io.o irq.o rtc.o landisk_pwb.o
+obj-y := setup.o irq.o psw.o gio.o
diff --git a/arch/sh/boards/landisk/gio.c b/arch/sh/boards/landisk/gio.c
new file mode 100644
index 0000000..50d38be
--- /dev/null
+++ b/arch/sh/boards/landisk/gio.c
@@ -0,0 +1,167 @@
+/*
+ * arch/sh/boards/landisk/gio.c - driver for landisk
+ *
+ * This driver will also support the I-O DATA Device, Inc. LANDISK Board.
+ * LANDISK and USL-5P Button, LED and GIO driver drive function.
+ *
+ * Copylight (C) 2006 kogiidena
+ * Copylight (C) 2002 Atom Create Engineering Co., Ltd. *
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/landisk/gio.h>
+#include <asm/landisk/iodata_landisk.h>
+
+#define DEVCOUNT 4
+#define GIO_MINOR 2 /* GIO minor no. */
+
+static dev_t dev;
+static struct cdev *cdev_p;
+static int openCnt;
+
+static int gio_open(struct inode *inode, struct file *filp)
+{
+ int minor;
+
+ minor = MINOR(inode->i_rdev);
+ if (minor < DEVCOUNT) {
+ if (openCnt > 0) {
+ return -EALREADY;
+ } else {
+ openCnt++;
+ return 0;
+ }
+ }
+ return -ENOENT;
+}
+
+static int gio_close(struct inode *inode, struct file *filp)
+{
+ int minor;
+
+ minor = MINOR(inode->i_rdev);
+ if (minor < DEVCOUNT) {
+ openCnt--;
+ }
+ return 0;
+}
+
+static int gio_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ unsigned int data;
+ static unsigned int addr = 0;
+
+ if (cmd & 0x01) { /* write */
+ if (copy_from_user(&data, (int *)arg, sizeof(int))) {
+ return -EFAULT;
+ }
+ }
+
+ switch (cmd) {
+ case GIODRV_IOCSGIOSETADDR: /* addres set */
+ addr = data;
+ break;
+
+ case GIODRV_IOCSGIODATA1: /* write byte */
+ ctrl_outb((unsigned char)(0x0ff & data), addr);
+ break;
+
+ case GIODRV_IOCSGIODATA2: /* write word */
+ if (addr & 0x01) {
+ return -EFAULT;
+ }
+ ctrl_outw((unsigned short int)(0x0ffff & data), addr);
+ break;
+
+ case GIODRV_IOCSGIODATA4: /* write long */
+ if (addr & 0x03) {
+ return -EFAULT;
+ }
+ ctrl_outl(data, addr);
+ break;
+
+ case GIODRV_IOCGGIODATA1: /* read byte */
+ data = ctrl_inb(addr);
+ break;
+
+ case GIODRV_IOCGGIODATA2: /* read word */
+ if (addr & 0x01) {
+ return -EFAULT;
+ }
+ data = ctrl_inw(addr);
+ break;
+
+ case GIODRV_IOCGGIODATA4: /* read long */
+ if (addr & 0x03) {
+ return -EFAULT;
+ }
+ data = ctrl_inl(addr);
+ break;
+ default:
+ return -EFAULT;
+ break;
+ }
+
+ if ((cmd & 0x01) == 0) { /* read */
+ if (copy_to_user((int *)arg, &data, sizeof(int))) {
+ return -EFAULT;
+ }
+ }
+ return 0;
+}
+
+static struct file_operations gio_fops = {
+ .owner = THIS_MODULE,
+ .open = gio_open, /* open */
+ .release = gio_close, /* release */
+ .ioctl = gio_ioctl, /* ioctl */
+};
+
+static int __init gio_init(void)
+{
+ int error;
+
+ printk(KERN_INFO "gio: driver initialized\n");
+
+ openCnt = 0;
+
+ if ((error = alloc_chrdev_region(&dev, 0, DEVCOUNT, "gio")) < 0) {
+ printk(KERN_ERR
+ "gio: Couldn't alloc_chrdev_region, error=%d\n",
+ error);
+ return 1;
+ }
+
+ cdev_p = cdev_alloc();
+ cdev_p->ops = &gio_fops;
+ error = cdev_add(cdev_p, dev, DEVCOUNT);
+ if (error) {
+ printk(KERN_ERR
+ "gio: Couldn't cdev_add, error=%d\n", error);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void __exit gio_exit(void)
+{
+ cdev_del(cdev_p);
+ unregister_chrdev_region(dev, DEVCOUNT);
+}
+
+module_init(gio_init);
+module_exit(gio_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/arch/sh/boards/landisk/io.c b/arch/sh/boards/landisk/io.c
deleted file mode 100644
index 92498b4..0000000
--- a/arch/sh/boards/landisk/io.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * arch/sh/boards/landisk/io.c
- *
- * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
- * Based largely on io_se.c.
- *
- * I/O routine for I-O Data Device, Inc. LANDISK.
- *
- * Initial version only to support LAN access; some
- * placeholder code from io_landisk.c left in with the
- * expectation of later SuperIO and PCMCIA access.
- */
-/*
- * modifed by kogiidena
- * 2005.03.03
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <asm/landisk/iodata_landisk.h>
-#include <asm/addrspace.h>
-#include <asm/io.h>
-
-extern void *area5_io_base; /* Area 5 I/O Base address */
-extern void *area6_io_base; /* Area 6 I/O Base address */
-
-static inline unsigned long port2adr(unsigned int port)
-{
- if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
- if (port == 0x3f6)
- return ((unsigned long)area5_io_base + 0x2c);
- else
- return ((unsigned long)area5_io_base + PA_PIDE_OFFSET +
- ((port - 0x1f0) << 1));
- else if ((0x170 <= port && port < 0x178) || port == 0x376)
- if (port == 0x376)
- return ((unsigned long)area6_io_base + 0x2c);
- else
- return ((unsigned long)area6_io_base + PA_SIDE_OFFSET +
- ((port - 0x170) << 1));
- else
- maybebadio((unsigned long)port);
-
- return port;
-}
-
-/*
- * General outline: remap really low stuff [eventually] to SuperIO,
- * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
- * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
- * should be way beyond the window, and is used w/o translation for
- * compatibility.
- */
-u8 landisk_inb(unsigned long port)
-{
- if (PXSEG(port))
- return ctrl_inb(port);
- else if (is_pci_ioaddr(port))
- return ctrl_inb(pci_ioaddr(port));
-
- return ctrl_inw(port2adr(port)) & 0xff;
-}
-
-u8 landisk_inb_p(unsigned long port)
-{
- u8 v;
-
- if (PXSEG(port))
- v = ctrl_inb(port);
- else if (is_pci_ioaddr(port))
- v = ctrl_inb(pci_ioaddr(port));
- else
- v = ctrl_inw(port2adr(port)) & 0xff;
-
- ctrl_delay();
-
- return v;
-}
-
-u16 landisk_inw(unsigned long port)
-{
- if (PXSEG(port))
- return ctrl_inw(port);
- else if (is_pci_ioaddr(port))
- return ctrl_inw(pci_ioaddr(port));
- else
- maybebadio(port);
-
- return 0;
-}
-
-u32 landisk_inl(unsigned long port)
-{
- if (PXSEG(port))
- return ctrl_inl(port);
- else if (is_pci_ioaddr(port))
- return ctrl_inl(pci_ioaddr(port));
- else
- maybebadio(port);
-
- return 0;
-}
-
-void landisk_outb(u8 value, unsigned long port)
-{
- if (PXSEG(port))
- ctrl_outb(value, port);
- else if (is_pci_ioaddr(port))
- ctrl_outb(value, pci_ioaddr(port));
- else
- ctrl_outw(value, port2adr(port));
-}
-
-void landisk_outb_p(u8 value, unsigned long port)
-{
- if (PXSEG(port))
- ctrl_outb(value, port);
- else if (is_pci_ioaddr(port))
- ctrl_outb(value, pci_ioaddr(port));
- else
- ctrl_outw(value, port2adr(port));
- ctrl_delay();
-}
-
-void landisk_outw(u16 value, unsigned long port)
-{
- if (PXSEG(port))
- ctrl_outw(value, port);
- else if (is_pci_ioaddr(port))
- ctrl_outw(value, pci_ioaddr(port));
- else
- maybebadio(port);
-}
-
-void landisk_outl(u32 value, unsigned long port)
-{
- if (PXSEG(port))
- ctrl_outl(value, port);
- else if (is_pci_ioaddr(port))
- ctrl_outl(value, pci_ioaddr(port));
- else
- maybebadio(port);
-}
-
-void landisk_insb(unsigned long port, void *dst, unsigned long count)
-{
- volatile u16 *p;
- u8 *buf = dst;
-
- if (PXSEG(port)) {
- while (count--)
- *buf++ = *(volatile u8 *)port;
- } else if (is_pci_ioaddr(port)) {
- volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
-
- while (count--)
- *buf++ = *bp;
- } else {
- p = (volatile u16 *)port2adr(port);
- while (count--)
- *buf++ = *p & 0xff;
- }
-}
-
-void landisk_insw(unsigned long port, void *dst, unsigned long count)
-{
- volatile u16 *p;
- u16 *buf = dst;
-
- if (PXSEG(port))
- p = (volatile u16 *)port;
- else if (is_pci_ioaddr(port))
- p = (volatile u16 *)pci_ioaddr(port);
- else
- p = (volatile u16 *)port2adr(port);
- while (count--)
- *buf++ = *p;
-}
-
-void landisk_insl(unsigned long port, void *dst, unsigned long count)
-{
- u32 *buf = dst;
-
- if (is_pci_ioaddr(port)) {
- volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
-
- while (count--)
- *buf++ = *p;
- } else
- maybebadio(port);
-}
-
-void landisk_outsb(unsigned long port, const void *src, unsigned long count)
-{
- volatile u16 *p;
- const u8 *buf = src;
-
- if (PXSEG(port))
- while (count--)
- ctrl_outb(*buf++, port);
- else if (is_pci_ioaddr(port)) {
- volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
-
- while (count--)
- *bp = *buf++;
- } else {
- p = (volatile u16 *)port2adr(port);
- while (count--)
- *p = *buf++;
- }
-}
-
-void landisk_outsw(unsigned long port, const void *src, unsigned long count)
-{
- volatile u16 *p;
- const u16 *buf = src;
-
- if (PXSEG(port))
- p = (volatile u16 *)port;
- else if (is_pci_ioaddr(port))
- p = (volatile u16 *)pci_ioaddr(port);
- else
- p = (volatile u16 *)port2adr(port);
-
- while (count--)
- *p = *buf++;
-}
-
-void landisk_outsl(unsigned long port, const void *src, unsigned long count)
-{
- const u32 *buf = src;
-
- if (is_pci_ioaddr(port)) {
- volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
-
- while (count--)
- *p = *buf++;
- } else
- maybebadio(port);
-}
-
-void __iomem *landisk_ioport_map(unsigned long port, unsigned int size)
-{
- if (PXSEG(port))
- return (void __iomem *)port;
- else if (is_pci_ioaddr(port))
- return (void __iomem *)pci_ioaddr(port);
-
- return (void __iomem *)port2adr(port);
-}
diff --git a/arch/sh/boards/landisk/irq.c b/arch/sh/boards/landisk/irq.c
index 3eba6d0..2586494 100644
--- a/arch/sh/boards/landisk/irq.c
+++ b/arch/sh/boards/landisk/irq.c
@@ -1,18 +1,16 @@
/*
* arch/sh/boards/landisk/irq.c
*
+ * I-O DATA Device, Inc. LANDISK Support
+ *
+ * Copyright (C) 2005-2007 kogiidena
+ *
* Copyright (C) 2001 Ian da Silva, Jeremy Siegel
* Based largely on io_se.c.
*
- * I/O routine for I-O Data Device, Inc. LANDISK.
- *
- * Initial version only to support LAN access; some
- * placeholder code from io_landisk.c left in with the
- * expectation of later SuperIO and PCMCIA access.
- */
-/*
- * modified by kogiidena
- * 2005.03.03
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
*/
#include <linux/init.h>
#include <linux/irq.h>
@@ -20,71 +18,27 @@
#include <linux/io.h>
#include <asm/landisk/iodata_landisk.h>
-static void enable_landisk_irq(unsigned int irq);
-static void disable_landisk_irq(unsigned int irq);
-
-/* shutdown is same as "disable" */
-#define shutdown_landisk_irq disable_landisk_irq
-
-static void ack_landisk_irq(unsigned int irq);
-static void end_landisk_irq(unsigned int irq);
-
-static unsigned int startup_landisk_irq(unsigned int irq)
-{
- enable_landisk_irq(irq);
- return 0; /* never anything pending */
-}
-
static void disable_landisk_irq(unsigned int irq)
{
- unsigned char val;
unsigned char mask = 0xff ^ (0x01 << (irq - 5));
- /* Set the priority in IPR to 0 */
- val = ctrl_inb(PA_IMASK);
- val &= mask;
- ctrl_outb(val, PA_IMASK);
+ ctrl_outb(ctrl_inb(PA_IMASK) & mask, PA_IMASK);
}
static void enable_landisk_irq(unsigned int irq)
{
- unsigned char val;
unsigned char value = (0x01 << (irq - 5));
- /* Set priority in IPR back to original value */
- val = ctrl_inb(PA_IMASK);
- val |= value;
- ctrl_outb(val, PA_IMASK);
-}
-
-static void ack_landisk_irq(unsigned int irq)
-{
- disable_landisk_irq(irq);
-}
-
-static void end_landisk_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
- enable_landisk_irq(irq);
+ ctrl_outb(ctrl_inb(PA_IMASK) | value, PA_IMASK);
}
-static struct hw_interrupt_type landisk_irq_type = {
- .typename = "LANDISK IRQ",
- .startup = startup_landisk_irq,
- .shutdown = shutdown_landisk_irq,
- .enable = enable_landisk_irq,
- .disable = disable_landisk_irq,
- .ack = ack_landisk_irq,
- .end = end_landisk_irq
+static struct irq_chip landisk_irq_chip __read_mostly = {
+ .name = "LANDISK",
+ .mask = disable_landisk_irq,
+ .unmask = enable_landisk_irq,
+ .mask_ack = disable_landisk_irq,
};
-static void make_landisk_irq(unsigned int irq)
-{
- disable_irq_nosync(irq);
- irq_desc[irq].chip = &landisk_irq_type;
- disable_landisk_irq(irq);
-}
-
/*
* Initialize IRQ setting
*/
@@ -92,6 +46,11 @@ void __init init_landisk_IRQ(void)
{
int i;
- for (i = 5; i < 14; i++)
- make_landisk_irq(i);
+ for (i = 5; i < 14; i++) {
+ disable_irq_nosync(i);
+ set_irq_chip_and_handler_name(i, &landisk_irq_chip,
+ handle_level_irq, "level");
+ enable_landisk_irq(i);
+ }
+ ctrl_outb(0x00, PA_PWRINT_CLR);
}
diff --git a/arch/sh/boards/landisk/landisk_pwb.c b/arch/sh/boards/landisk/landisk_pwb.c
deleted file mode 100644
index 47a63c6..0000000
--- a/arch/sh/boards/landisk/landisk_pwb.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * arch/sh/boards/landisk/landisk_pwb.c -- driver for the Power control switch.
- *
- * This driver will also support the I-O DATA Device, Inc. LANDISK Board.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copylight (C) 2002 Atom Create Engineering Co., Ltd.
- *
- * LED control drive function added by kogiidena
- */
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/major.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/landisk/iodata_landisk.h>
-
-#define SHUTDOWN_BTN_MINOR 1 /* Shutdown button device minor no. */
-#define LED_MINOR 21 /* LED minor no. */
-#define BTN_MINOR 22 /* BUTTON minor no. */
-#define GIO_MINOR 40 /* GIO minor no. */
-
-static int openCnt;
-static int openCntLED;
-static int openCntGio;
-static int openCntBtn;
-static int landisk_btn;
-static int landisk_btnctrlpid;
-/*
- * Functions prototypes
- */
-
-static int gio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg);
-
-static int swdrv_open(struct inode *inode, struct file *filp)
-{
- int minor;
-
- minor = MINOR(inode->i_rdev);
- filp->private_data = (void *)minor;
-
- if (minor == SHUTDOWN_BTN_MINOR) {
- if (openCnt > 0) {
- return -EALREADY;
- } else {
- openCnt++;
- return 0;
- }
- } else if (minor == LED_MINOR) {
- if (openCntLED > 0) {
- return -EALREADY;
- } else {
- openCntLED++;
- return 0;
- }
- } else if (minor == BTN_MINOR) {
- if (openCntBtn > 0) {
- return -EALREADY;
- } else {
- openCntBtn++;
- return 0;
- }
- } else if (minor == GIO_MINOR) {
- if (openCntGio > 0) {
- return -EALREADY;
- } else {
- openCntGio++;
- return 0;
- }
- }
- return -ENOENT;
-
-}
-
-static int swdrv_close(struct inode *inode, struct file *filp)
-{
- int minor;
-
- minor = MINOR(inode->i_rdev);
- if (minor == SHUTDOWN_BTN_MINOR) {
- openCnt--;
- } else if (minor == LED_MINOR) {
- openCntLED--;
- } else if (minor == BTN_MINOR) {
- openCntBtn--;
- } else if (minor == GIO_MINOR) {
- openCntGio--;
- }
- return 0;
-}
-
-static int swdrv_read(struct file *filp, char *buff, size_t count,
- loff_t * ppos)
-{
- int minor;
- minor = (int)(filp->private_data);
-
- if (!access_ok(VERIFY_WRITE, (void *)buff, count))
- return -EFAULT;
-
- if (minor == SHUTDOWN_BTN_MINOR) {
- if (landisk_btn & 0x10) {
- put_user(1, buff);
- return 1;
- } else {
- return 0;
- }
- }
- return 0;
-}
-
-static int swdrv_write(struct file *filp, const char *buff, size_t count,
- loff_t * ppos)
-{
- int minor;
- minor = (int)(filp->private_data);
-
- if (minor == SHUTDOWN_BTN_MINOR) {
- return count;
- }
- return count;
-}
-
-static irqreturn_t sw_interrupt(int irq, void *dev_id)
-{
- landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS)));
- disable_irq(IRQ_BUTTON);
- disable_irq(IRQ_POWER);
- ctrl_outb(0x00, PA_PWRINT_CLR);
-
- if (landisk_btnctrlpid != 0) {
- kill_proc(landisk_btnctrlpid, SIGUSR1, 1);
- landisk_btnctrlpid = 0;
- }
-
- return IRQ_HANDLED;
-}
-
-static const struct file_operations swdrv_fops = {
- .read = swdrv_read, /* read */
- .write = swdrv_write, /* write */
- .open = swdrv_open, /* open */
- .release = swdrv_close, /* release */
- .ioctl = gio_ioctl, /* ioctl */
-
-};
-
-static char banner[] __initdata =
- KERN_INFO "LANDISK and USL-5P Button, LED and GIO driver initialized\n";
-
-int __init swdrv_init(void)
-{
- int error;
-
- printk("%s", banner);
-
- openCnt = 0;
- openCntLED = 0;
- openCntBtn = 0;
- openCntGio = 0;
- landisk_btn = 0;
- landisk_btnctrlpid = 0;
-
- if ((error = register_chrdev(SHUTDOWN_BTN_MAJOR, "swdrv", &swdrv_fops))) {
- printk(KERN_ERR
- "Button, LED and GIO driver:Couldn't register driver, error=%d\n",
- error);
- return 1;
- }
-
- if (request_irq(IRQ_POWER, sw_interrupt, 0, "SHUTDOWNSWITCH", NULL)) {
- printk(KERN_ERR "Unable to get IRQ 11.\n");
- return 1;
- }
- if (request_irq(IRQ_BUTTON, sw_interrupt, 0, "USL-5P BUTTON", NULL)) {
- printk(KERN_ERR "Unable to get IRQ 12.\n");
- return 1;
- }
- ctrl_outb(0x00, PA_PWRINT_CLR);
-
- return 0;
-}
-
-module_init(swdrv_init);
-
-/*
- * gio driver
- *
- */
-
-#include <asm/landisk/gio.h>
-
-static int gio_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- int minor;
- unsigned int data, mask;
- static unsigned int addr = 0;
-
- minor = (int)(filp->private_data);
-
- /* access control */
- if (minor == GIO_MINOR) {
- ;
- } else if (minor == LED_MINOR) {
- if (((cmd & 0x0ff) >= 9) && ((cmd & 0x0ff) < 20)) {
- ;
- } else {
- return -EINVAL;
- }
- } else if (minor == BTN_MINOR) {
- if (((cmd & 0x0ff) >= 20) && ((cmd & 0x0ff) < 30)) {
- ;
- } else {
- return -EINVAL;
- }
- } else {
- return -EINVAL;
- }
-
- if (cmd & 0x01) { /* write */
- if (copy_from_user(&data, (int *)arg, sizeof(int))) {
- return -EFAULT;
- }
- }
-
- switch (cmd) {
- case GIODRV_IOCSGIOSETADDR: /* addres set */
- addr = data;
- break;
-
- case GIODRV_IOCSGIODATA1: /* write byte */
- ctrl_outb((unsigned char)(0x0ff & data), addr);
- break;
-
- case GIODRV_IOCSGIODATA2: /* write word */
- if (addr & 0x01) {
- return -EFAULT;
- }
- ctrl_outw((unsigned short int)(0x0ffff & data), addr);
- break;
-
- case GIODRV_IOCSGIODATA4: /* write long */
- if (addr & 0x03) {
- return -EFAULT;
- }
- ctrl_outl(data, addr);
- break;
-
- case GIODRV_IOCGGIODATA1: /* read byte */
- data = ctrl_inb(addr);
- break;
-
- case GIODRV_IOCGGIODATA2: /* read word */
- if (addr & 0x01) {
- return -EFAULT;
- }
- data = ctrl_inw(addr);
- break;
-
- case GIODRV_IOCGGIODATA4: /* read long */
- if (addr & 0x03) {
- return -EFAULT;
- }
- data = ctrl_inl(addr);
- break;
- case GIODRV_IOCSGIO_LED: /* write */
- mask = ((data & 0x00ffffff) << 8)
- | ((data & 0x0000ffff) << 16)
- | ((data & 0x000000ff) << 24);
- landisk_ledparam = data & (~mask);
- if (landisk_arch == 0) { /* arch == landisk */
- landisk_ledparam &= 0x03030303;
- mask = (~(landisk_ledparam >> 22)) & 0x000c;
- landisk_ledparam |= mask;
- } else { /* arch == usl-5p */
- mask = (landisk_ledparam >> 24) & 0x0001;
- landisk_ledparam |= mask;
- landisk_ledparam &= 0x007f7f7f;
- }
- landisk_ledparam |= 0x80;
- break;
- case GIODRV_IOCGGIO_LED: /* read */
- data = landisk_ledparam;
- if (landisk_arch == 0) { /* arch == landisk */
- data &= 0x03030303;
- } else { /* arch == usl-5p */
- ;
- }
- data &= (~0x080);
- break;
- case GIODRV_IOCSGIO_BUZZER: /* write */
- landisk_buzzerparam = data;
- landisk_ledparam |= 0x80;
- break;
- case GIODRV_IOCGGIO_LANDISK: /* read */
- data = landisk_arch & 0x01;
- break;
- case GIODRV_IOCGGIO_BTN: /* read */
- data = (0x0ff & ctrl_inb(PA_PWRINT_CLR));
- data <<= 8;
- data |= (0x0ff & ctrl_inb(PA_IMASK));
- data <<= 8;
- data |= (0x0ff & landisk_btn);
- data <<= 8;
- data |= (0x0ff & (~ctrl_inb(PA_STATUS)));
- break;
- case GIODRV_IOCSGIO_BTNPID: /* write */
- landisk_btnctrlpid = data;
- landisk_btn = 0;
- if (irq_desc[IRQ_BUTTON].depth) {
- enable_irq(IRQ_BUTTON);
- }
- if (irq_desc[IRQ_POWER].depth) {
- enable_irq(IRQ_POWER);
- }
- break;
- case GIODRV_IOCGGIO_BTNPID: /* read */
- data = landisk_btnctrlpid;
- break;
- default:
- return -EFAULT;
- break;
- }
-
- if ((cmd & 0x01) == 0) { /* read */
- if (copy_to_user((int *)arg, &data, sizeof(int))) {
- return -EFAULT;
- }
- }
- return 0;
-}
diff --git a/arch/sh/boards/landisk/psw.c b/arch/sh/boards/landisk/psw.c
new file mode 100644
index 0000000..5a9b70b
--- /dev/null
+++ b/arch/sh/boards/landisk/psw.c
@@ -0,0 +1,143 @@
+/*
+ * arch/sh/boards/landisk/psw.c
+ *
+ * push switch support for LANDISK and USL-5P
+ *
+ * Copyright (C) 2006-2007 Paul Mundt
+ * Copyright (C) 2007 kogiidena
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <asm/landisk/iodata_landisk.h>
+#include <asm/push-switch.h>
+
+static irqreturn_t psw_irq_handler(int irq, void *arg)
+{
+ struct platform_device *pdev = arg;
+ struct push_switch *psw = platform_get_drvdata(pdev);
+ struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
+ unsigned int sw_value;
+ int ret = 0;
+
+ sw_value = (0x0ff & (~ctrl_inb(PA_STATUS)));
+
+ /* Nothing to do if there's no state change */
+ if (psw->state) {
+ ret = 1;
+ goto out;
+ }
+
+ /* Figure out who raised it */
+ if (sw_value & (1 << psw_info->bit)) {
+ psw->state = 1;
+ mod_timer(&psw->debounce, jiffies + 50);
+ ret = 1;
+ }
+
+out:
+ /* Clear the switch IRQs */
+ ctrl_outb(0x00, PA_PWRINT_CLR);
+
+ return IRQ_RETVAL(ret);
+}
+
+static struct resource psw_power_resources[] = {
+ [0] = {
+ .start = IRQ_POWER,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource psw_usl5p_resources[] = {
+ [0] = {
+ .start = IRQ_BUTTON,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct push_switch_platform_info psw_power_platform_data = {
+ .name = "psw_power",
+ .bit = 4,
+ .irq_flags = IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct push_switch_platform_info psw1_platform_data = {
+ .name = "psw1",
+ .bit = 0,
+ .irq_flags = IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct push_switch_platform_info psw2_platform_data = {
+ .name = "psw2",
+ .bit = 2,
+ .irq_flags = IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct push_switch_platform_info psw3_platform_data = {
+ .name = "psw3",
+ .bit = 1,
+ .irq_flags = IRQF_SHARED,
+ .irq_handler = psw_irq_handler,
+};
+
+static struct platform_device psw_power_switch_device = {
+ .name = "push-switch",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(psw_power_resources),
+ .resource = psw_power_resources,
+ .dev = {
+ .platform_data = &psw_power_platform_data,
+ },
+};
+
+static struct platform_device psw1_switch_device = {
+ .name = "push-switch",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(psw_usl5p_resources),
+ .resource = psw_usl5p_resources,
+ .dev = {
+ .platform_data = &psw1_platform_data,
+ },
+};
+
+static struct platform_device psw2_switch_device = {
+ .name = "push-switch",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(psw_usl5p_resources),
+ .resource = psw_usl5p_resources,
+ .dev = {
+ .platform_data = &psw2_platform_data,
+ },
+};
+
+static struct platform_device psw3_switch_device = {
+ .name = "push-switch",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(psw_usl5p_resources),
+ .resource = psw_usl5p_resources,
+ .dev = {
+ .platform_data = &psw3_platform_data,
+ },
+};
+
+static struct platform_device *psw_devices[] = {
+ &psw_power_switch_device,
+ &psw1_switch_device,
+ &psw2_switch_device,
+ &psw3_switch_device,
+};
+
+static int __init psw_init(void)
+{
+ return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
+}
+module_init(psw_init);
diff --git a/arch/sh/boards/landisk/rtc.c b/arch/sh/boards/landisk/rtc.c
deleted file mode 100644
index 0a9a2a2..0000000
--- a/arch/sh/boards/landisk/rtc.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * arch/sh/boards/landisk/rtc.c -- RTC support
- *
- * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
- */
-/*
- * modifed by kogiidena
- * 2005.09.16
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/time.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/bcd.h>
-#include <asm/rtc.h>
-
-extern spinlock_t rtc_lock;
-
-extern void
-rs5c313_set_cmos_time(unsigned int BCD_yr, unsigned int BCD_mon,
- unsigned int BCD_day, unsigned int BCD_hr,
- unsigned int BCD_min, unsigned int BCD_sec);
-
-extern unsigned long
-rs5c313_get_cmos_time(unsigned int *BCD_yr, unsigned int *BCD_mon,
- unsigned int *BCD_day, unsigned int *BCD_hr,
- unsigned int *BCD_min, unsigned int *BCD_sec);
-
-void landisk_rtc_gettimeofday(struct timespec *tv)
-{
- unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec;
- unsigned long flags;
-
- spin_lock_irqsave(&rtc_lock, flags);
- tv->tv_sec = rs5c313_get_cmos_time
- (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec);
- tv->tv_nsec = 0;
- spin_unlock_irqrestore(&rtc_lock, flags);
-}
-
-int landisk_rtc_settimeofday(const time_t secs)
-{
- int retval = 0;
- int real_seconds, real_minutes, cmos_minutes;
- unsigned long flags;
- unsigned long nowtime = secs;
- unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec;
-
- spin_lock_irqsave(&rtc_lock, flags);
-
- rs5c313_get_cmos_time
- (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec);
- cmos_minutes = BCD_min;
- BCD_TO_BIN(cmos_minutes);
-
- /*
- * since we're only adjusting minutes and seconds,
- * don't interfere with hour overflow. This avoids
- * messing with unknown time zones but requires your
- * RTC not to be off by more than 15 minutes
- */
- real_seconds = nowtime % 60;
- real_minutes = nowtime / 60;
- if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1)
- real_minutes += 30; /* correct for half hour time zone */
- real_minutes %= 60;
-
- if (abs(real_minutes - cmos_minutes) < 30) {
- BIN_TO_BCD(real_seconds);
- BIN_TO_BCD(real_minutes);
- rs5c313_set_cmos_time(BCD_yr, BCD_mon, BCD_day, BCD_hr,
- real_minutes, real_seconds);
- } else {
- printk(KERN_WARNING
- "set_rtc_time: can't update from %d to %d\n",
- cmos_minutes, real_minutes);
- retval = -1;
- }
-
- spin_unlock_irqrestore(&rtc_lock, flags);
- return retval;
-}
-
-void landisk_time_init(void)
-{
- rtc_sh_get_time = landisk_rtc_gettimeofday;
- rtc_sh_set_time = landisk_rtc_settimeofday;
-}
diff --git a/arch/sh/boards/landisk/setup.c b/arch/sh/boards/landisk/setup.c
index 122d699..a83a5d9 100644
--- a/arch/sh/boards/landisk/setup.c
+++ b/arch/sh/boards/landisk/setup.c
@@ -1,144 +1,90 @@
/*
* arch/sh/boards/landisk/setup.c
*
- * Copyright (C) 2000 Kazumoto Kojima
- * Copyright (C) 2002 Paul Mundt
- *
* I-O DATA Device, Inc. LANDISK Support.
*
- * Modified for LANDISK by
- * Atom Create Engineering Co., Ltd. 2002.
- *
- * modifed by kogiidena
- * 2005.09.16
+ * Copyright (C) 2000 Kazumoto Kojima
+ * Copyright (C) 2002 Paul Mundt
+ * Copylight (C) 2002 Atom Create Engineering Co., Ltd.
+ * Copyright (C) 2005-2007 kogiidena
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pata_platform.h>
#include <linux/pm.h>
#include <linux/mm.h>
#include <asm/machvec.h>
-#include <asm/rtc.h>
#include <asm/landisk/iodata_landisk.h>
#include <asm/io.h>
-void landisk_time_init(void);
void init_landisk_IRQ(void);
-int landisk_ledparam;
-int landisk_buzzerparam;
-int landisk_arch;
-
-/* cycle the led's in the clasic knightrider/sun pattern */
-static void heartbeat_landisk(void)
-{
- static unsigned int cnt = 0, blink = 0x00, period = 25;
- volatile u8 *p = (volatile u8 *)PA_LED;
- char data;
-
- if ((landisk_ledparam & 0x080) == 0)
- return;
-
- cnt += 1;
-
- if (cnt < period)
- return;
-
- cnt = 0;
- blink++;
-
- data = (blink & 0x01) ? (landisk_ledparam >> 16) : 0;
- data |= (blink & 0x02) ? (landisk_ledparam >> 8) : 0;
- data |= landisk_ledparam;
-
- /* buzzer */
- if (landisk_buzzerparam & 0x1) {
- data |= 0x80;
- } else {
- data &= 0x7f;
- }
- *p = data;
-
- if (((landisk_ledparam & 0x007f7f00) == 0) &&
- (landisk_buzzerparam == 0))
- landisk_ledparam &= (~0x0080);
-
- landisk_buzzerparam >>= 1;
-}
-
static void landisk_power_off(void)
{
ctrl_outb(0x01, PA_SHUTDOWN);
}
-static void check_usl5p(void)
-{
- volatile u8 *p = (volatile u8 *)PA_LED;
- u8 tmp1, tmp2;
+static struct resource cf_ide_resources[3];
- tmp1 = *p;
- *p = 0x40;
- tmp2 = *p;
- *p = tmp1;
+static struct pata_platform_info pata_info = {
+ .ioport_shift = 1,
+};
- landisk_arch = (tmp2 == 0x40);
- if (landisk_arch == 1) {
- /* arch == usl-5p */
- landisk_ledparam = 0x00000380;
- landisk_ledparam |= (tmp1 & 0x07c);
- } else {
- /* arch == landisk */
- landisk_ledparam = 0x02000180;
- landisk_ledparam |= 0x04;
- }
-}
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+ .dev = {
+ .platform_data = &pata_info,
+ },
+};
-void *area5_io_base;
-void *area6_io_base;
+static struct platform_device *landisk_devices[] __initdata = {
+ &cf_ide_device,
+};
-static int __init landisk_cf_init(void)
+static int __init landisk_devices_setup(void)
{
pgprot_t prot;
- unsigned long paddrbase, psize;
+ unsigned long paddrbase;
+ void *cf_ide_base;
/* open I/O area window */
paddrbase = virt_to_phys((void *)PA_AREA5_IO);
- psize = PAGE_SIZE;
prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
- area5_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
- if (!area5_io_base) {
+ cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
+ if (!cf_ide_base) {
printk("allocate_cf_area : can't open CF I/O window!\n");
return -ENOMEM;
}
- paddrbase = virt_to_phys((void *)PA_AREA6_IO);
- psize = PAGE_SIZE;
- prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16);
- area6_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
- if (!area6_io_base) {
- printk("allocate_cf_area : can't open HDD I/O window!\n");
- return -ENOMEM;
- }
-
- printk(KERN_INFO "Allocate Area5/6 success.\n");
-
- /* XXX : do we need attribute and common-memory area also? */
-
- return 0;
+ /* IDE cmd address : 0x1f0-0x1f7 and 0x3f6 */
+ cf_ide_resources[0].start = (unsigned long)cf_ide_base + 0x40;
+ cf_ide_resources[0].end = (unsigned long)cf_ide_base + 0x40 + 0x0f;
+ cf_ide_resources[0].flags = IORESOURCE_IO;
+ cf_ide_resources[1].start = (unsigned long)cf_ide_base + 0x2c;
+ cf_ide_resources[1].end = (unsigned long)cf_ide_base + 0x2c + 0x03;
+ cf_ide_resources[1].flags = IORESOURCE_IO;
+ cf_ide_resources[2].start = IRQ_FATA;
+ cf_ide_resources[2].flags = IORESOURCE_IRQ;
+
+ return platform_add_devices(landisk_devices,
+ ARRAY_SIZE(landisk_devices));
}
+__initcall(landisk_devices_setup);
+
static void __init landisk_setup(char **cmdline_p)
{
- device_initcall(landisk_cf_init);
-
- landisk_buzzerparam = 0;
- check_usl5p();
+ /* LED ON */
+ ctrl_outb(ctrl_inb(PA_LED) | 0x03, PA_LED);
printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n");
-
- board_time_init = landisk_time_init;
pm_power_off = landisk_power_off;
}
@@ -148,29 +94,6 @@ static void __init landisk_setup(char **cmdline_p)
struct sh_machine_vector mv_landisk __initmv = {
.mv_name = "LANDISK",
.mv_setup = landisk_setup,
- .mv_nr_irqs = 72,
- .mv_inb = landisk_inb,
- .mv_inw = landisk_inw,
- .mv_inl = landisk_inl,
- .mv_outb = landisk_outb,
- .mv_outw = landisk_outw,
- .mv_outl = landisk_outl,
- .mv_inb_p = landisk_inb_p,
- .mv_inw_p = landisk_inw,
- .mv_inl_p = landisk_inl,
- .mv_outb_p = landisk_outb_p,
- .mv_outw_p = landisk_outw,
- .mv_outl_p = landisk_outl,
- .mv_insb = landisk_insb,
- .mv_insw = landisk_insw,
- .mv_insl = landisk_insl,
- .mv_outsb = landisk_outsb,
- .mv_outsw = landisk_outsw,
- .mv_outsl = landisk_outsl,
- .mv_ioport_map = landisk_ioport_map,
.mv_init_irq = init_landisk_IRQ,
-#ifdef CONFIG_HEARTBEAT
- .mv_heartbeat = heartbeat_landisk,
-#endif
};
ALIAS_MV(landisk)
diff --git a/arch/sh/boards/lboxre2/Makefile b/arch/sh/boards/lboxre2/Makefile
new file mode 100644
index 0000000..e9ed140
--- /dev/null
+++ b/arch/sh/boards/lboxre2/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the L-BOX RE2 specific parts of the kernel
+# Copyright (c) 2007 Nobuhiro Iwamatsu
+
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/lboxre2/irq.c b/arch/sh/boards/lboxre2/irq.c
new file mode 100644
index 0000000..5a1c3bb
--- /dev/null
+++ b/arch/sh/boards/lboxre2/irq.c
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/sh/boards/lboxre2/irq.c
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * NTT COMWARE L-BOX RE2 Support.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/lboxre2.h>
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_lboxre2_IRQ(void)
+{
+ make_imask_irq(IRQ_CF1);
+ make_imask_irq(IRQ_CF0);
+ make_imask_irq(IRQ_INTD);
+ make_imask_irq(IRQ_ETH1);
+ make_imask_irq(IRQ_ETH0);
+ make_imask_irq(IRQ_INTA);
+}
diff --git a/arch/sh/boards/lboxre2/setup.c b/arch/sh/boards/lboxre2/setup.c
new file mode 100644
index 0000000..4e20f7c
--- /dev/null
+++ b/arch/sh/boards/lboxre2/setup.c
@@ -0,0 +1,85 @@
+/*
+ * linux/arch/sh/boards/lbox/setup.c
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * NTT COMWARE L-BOX RE2 Support
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pata_platform.h>
+#include <asm/machvec.h>
+#include <asm/addrspace.h>
+#include <asm/lboxre2.h>
+#include <asm/io.h>
+
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = 0x1f0,
+ .end = 0x1f0 + 8 ,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .start = 0x1f0 + 0x206,
+ .end = 0x1f0 +8 + 0x206 + 8,
+ .flags = IORESOURCE_IO,
+ },
+ [2] = {
+ .start = IRQ_CF0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
+static struct platform_device *lboxre2_devices[] __initdata = {
+ &cf_ide_device,
+};
+
+static int __init lboxre2_devices_setup(void)
+{
+ u32 cf0_io_base; /* Boot CF base address */
+ pgprot_t prot;
+ unsigned long paddrbase, psize;
+
+ /* open I/O area window */
+ paddrbase = virt_to_phys((void*)PA_AREA5_IO);
+ psize = PAGE_SIZE;
+ prot = PAGE_KERNEL_PCC( 1 , _PAGE_PCC_IO16);
+ cf0_io_base = (u32)p3_ioremap(paddrbase, psize, prot.pgprot);
+ if (!cf0_io_base) {
+ printk(KERN_ERR "%s : can't open CF I/O window!\n" , __func__ );
+ return -ENOMEM;
+ }
+
+ cf_ide_resources[0].start += cf0_io_base ;
+ cf_ide_resources[0].end += cf0_io_base ;
+ cf_ide_resources[1].start += cf0_io_base ;
+ cf_ide_resources[1].end += cf0_io_base ;
+
+ return platform_add_devices(lboxre2_devices,
+ ARRAY_SIZE(lboxre2_devices));
+
+}
+device_initcall(lboxre2_devices_setup);
+
+/*
+ * The Machine Vector
+ */
+struct sh_machine_vector mv_lboxre2 __initmv = {
+ .mv_name = "L-BOX RE2",
+ .mv_nr_irqs = 72,
+ .mv_init_irq = init_lboxre2_IRQ,
+};
+ALIAS_MV(lboxre2)
diff --git a/arch/sh/boards/renesas/r7780rp/Kconfig b/arch/sh/boards/renesas/r7780rp/Kconfig
index c26d981..9fb1164 100644
--- a/arch/sh/boards/renesas/r7780rp/Kconfig
+++ b/arch/sh/boards/renesas/r7780rp/Kconfig
@@ -1,14 +1,24 @@
-if SH_R7780RP
+if SH_HIGHLANDER
-menu "R7780RP options"
+choice
+ prompt "Highlander options"
+ default SH_R7780MP
+
+config SH_R7780RP
+ bool "R7780RP-1 board support"
+ select CPU_SUBTYPE_SH7780
config SH_R7780MP
bool "R7780MP board support"
- default y
+ select CPU_SUBTYPE_SH7780
help
Selecting this option will enable support for the mass-production
version of the R7780RP. If in doubt, say Y.
-endmenu
+config SH_R7785RP
+ bool "R7785RP board support"
+ select CPU_SUBTYPE_SH7785
+
+endchoice
endif
diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile
index ed5f5a9..609e5d5 100644
--- a/arch/sh/boards/renesas/r7780rp/Makefile
+++ b/arch/sh/boards/renesas/r7780rp/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for the R7780RP-1 specific parts of the kernel
#
-
-obj-y := setup.o irq.o
-
+irqinit-y := irq-r7780rp.o
+irqinit-$(CONFIG_SH_R7785RP) := irq-r7785rp.o
obj-$(CONFIG_PUSH_SWITCH) += psw.o
+obj-y := setup.o irq.o $(irqinit-y)
diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c
new file mode 100644
index 0000000..f5f3587
--- /dev/null
+++ b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c
@@ -0,0 +1,21 @@
+/*
+ * Renesas Solutions Highlander R7780RP-1 Support.
+ *
+ * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
+ * Copyright (C) 2006 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/r7780rp.h>
+
+void __init highlander_init_irq(void)
+{
+ int i;
+
+ for (i = 0; i < 15; i++)
+ make_r7780rp_irq(i);
+}
diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c
new file mode 100644
index 0000000..dd6ec4c
--- /dev/null
+++ b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c
@@ -0,0 +1,29 @@
+/*
+ * Renesas Solutions Highlander R7780RP-1 Support.
+ *
+ * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
+ * Copyright (C) 2006 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/r7780rp.h>
+
+void __init highlander_init_irq(void)
+{
+ ctrl_outw(0x0000, PA_IRLSSR1); /* FPGA IRLSSR1(CF_CD clear) */
+
+ /* Setup the FPGA IRL */
+ ctrl_outw(0x0000, PA_IRLPRA); /* FPGA IRLA */
+ ctrl_outw(0xe598, PA_IRLPRB); /* FPGA IRLB */
+ ctrl_outw(0x7060, PA_IRLPRC); /* FPGA IRLC */
+ ctrl_outw(0x0000, PA_IRLPRD); /* FPGA IRLD */
+ ctrl_outw(0x4321, PA_IRLPRE); /* FPGA IRLE */
+ ctrl_outw(0x0000, PA_IRLPRF); /* FPGA IRLF */
+
+ make_r7780rp_irq(1); /* CF card */
+ make_r7780rp_irq(10); /* On-board ethernet */
+}
diff --git a/arch/sh/boards/renesas/r7780rp/irq.c b/arch/sh/boards/renesas/r7780rp/irq.c
index cc381e1..e0b8eb5 100644
--- a/arch/sh/boards/renesas/r7780rp/irq.c
+++ b/arch/sh/boards/renesas/r7780rp/irq.c
@@ -14,10 +14,12 @@
#include <linux/io.h>
#include <asm/r7780rp.h>
-#ifdef CONFIG_SH_R7780MP
-static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0};
-#else
+#ifdef CONFIG_SH_R7780RP
static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0};
+#elif defined(CONFIG_SH_R7780MP)
+static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0};
+#elif defined(CONFIG_SH_R7785RP)
+static int mask_pos[] = {2, 11, 2, 2, 2, 2, 9, 8, 7, 5, 10, 2, 2, 2, 2, 2};
#endif
static void enable_r7780rp_irq(unsigned int irq)
@@ -40,17 +42,10 @@ static struct irq_chip r7780rp_irq_chip __read_mostly = {
.mask_ack = disable_r7780rp_irq,
};
-/*
- * Initialize IRQ setting
- */
-void __init init_r7780rp_IRQ(void)
+void make_r7780rp_irq(unsigned int irq)
{
- int i;
-
- for (i = 0; i < 15; i++) {
- disable_irq_nosync(i);
- set_irq_chip_and_handler_name(i, &r7780rp_irq_chip,
- handle_level_irq, "level");
- enable_r7780rp_irq(i);
- }
+ disable_irq_nosync(irq);
+ set_irq_chip_and_handler_name(irq, &r7780rp_irq_chip,
+ handle_level_irq, "level");
+ enable_r7780rp_irq(irq);
}
diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c
index 2faba66..0727ef9 100644
--- a/arch/sh/boards/renesas/r7780rp/setup.c
+++ b/arch/sh/boards/renesas/r7780rp/setup.c
@@ -1,10 +1,13 @@
/*
* arch/sh/boards/renesas/r7780rp/setup.c
*
+ * Renesas Solutions Highlander Support.
+ *
* Copyright (C) 2002 Atom Create Engineering Co., Ltd.
* Copyright (C) 2005 - 2007 Paul Mundt
*
- * Renesas Solutions Highlander R7780RP-1 Support.
+ * This contains support for the R7780RP-1, R7780MP, and R7785RP
+ * Highlander modules.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -18,32 +21,6 @@
#include <asm/clock.h>
#include <asm/io.h>
-extern void init_r7780rp_IRQ(void);
-
-static struct resource m66596_usb_host_resources[] = {
- [0] = {
- .start = 0xa4800000,
- .end = 0xa4ffffff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = 6, /* irq number */
- .end = 6,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device m66596_usb_host_device = {
- .name = "m66596-hcd",
- .id = 0,
- .dev = {
- .dma_mask = NULL, /* don't use dma */
- .coherent_dma_mask = 0xffffffff,
- },
- .num_resources = ARRAY_SIZE(m66596_usb_host_resources),
- .resource = m66596_usb_host_resources,
-};
-
static struct resource cf_ide_resources[] = {
[0] = {
.start = PA_AREA5_IO + 0x1000,
@@ -56,10 +33,10 @@ static struct resource cf_ide_resources[] = {
.flags = IORESOURCE_MEM,
},
[2] = {
-#ifdef CONFIG_SH_R7780MP
- .start = 1,
-#else
+#ifdef CONFIG_SH_R7780RP
.start = 4,
+#else
+ .start = 1,
#endif
.flags = IORESOURCE_IRQ,
},
@@ -92,15 +69,18 @@ static struct resource heartbeat_resources[] = {
static struct platform_device heartbeat_device = {
.name = "heartbeat",
.id = -1,
+
+ /* R7785RP has a slightly more sensible FPGA.. */
+#ifndef CONFIG_SH_R7785RP
.dev = {
.platform_data = heartbeat_bit_pos,
},
+#endif
.num_resources = ARRAY_SIZE(heartbeat_resources),
.resource = heartbeat_resources,
};
static struct platform_device *r7780rp_devices[] __initdata = {
- &m66596_usb_host_device,
&cf_ide_device,
&heartbeat_device,
};
@@ -110,18 +90,19 @@ static int __init r7780rp_devices_setup(void)
return platform_add_devices(r7780rp_devices,
ARRAY_SIZE(r7780rp_devices));
}
+device_initcall(r7780rp_devices_setup);
/*
* Platform specific clocks
*/
static void ivdr_clk_enable(struct clk *clk)
{
- ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << 8), PA_IVDRCTL);
+ ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL);
}
static void ivdr_clk_disable(struct clk *clk)
{
- ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << 8), PA_IVDRCTL);
+ ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL);
}
static struct clk_ops ivdr_clk_ops = {
@@ -140,22 +121,22 @@ static struct clk *r7780rp_clocks[] = {
static void r7780rp_power_off(void)
{
-#ifdef CONFIG_SH_R7780MP
- ctrl_outw(0x0001, PA_POFF);
-#endif
+ if (mach_is_r7780mp() || mach_is_r7785rp())
+ ctrl_outw(0x0001, PA_POFF);
}
/*
* Initialize the board
*/
-static void __init r7780rp_setup(char **cmdline_p)
+static void __init highlander_setup(char **cmdline_p)
{
u16 ver = ctrl_inw(PA_VERREG);
int i;
- device_initcall(r7780rp_devices_setup);
-
- printk(KERN_INFO "Renesas Solutions Highlander R7780RP-1 support.\n");
+ printk(KERN_INFO "Renesas Solutions Highlander %s support.\n",
+ mach_is_r7780rp() ? "R7780RP-1" :
+ mach_is_r7780mp() ? "R7780MP" :
+ "R7785RP");
printk(KERN_INFO "Board version: %d (revision %d), "
"FPGA version: %d (revision %d)\n",
@@ -173,9 +154,10 @@ static void __init r7780rp_setup(char **cmdline_p)
}
ctrl_outw(0x0000, PA_OBLED); /* Clear LED. */
-#ifndef CONFIG_SH_R7780MP
- ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */
-#endif
+
+ if (mach_is_r7780rp())
+ ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */
+
ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x01, PA_IVDRCTL); /* Si13112 */
pm_power_off = r7780rp_power_off;
@@ -184,10 +166,10 @@ static void __init r7780rp_setup(char **cmdline_p)
/*
* The Machine Vector
*/
-struct sh_machine_vector mv_r7780rp __initmv = {
- .mv_name = "Highlander R7780RP-1",
- .mv_setup = r7780rp_setup,
+struct sh_machine_vector mv_highlander __initmv = {
+ .mv_name = "Highlander",
.mv_nr_irqs = 109,
- .mv_init_irq = init_r7780rp_IRQ,
+ .mv_setup = highlander_setup,
+ .mv_init_irq = highlander_init_irq,
};
-ALIAS_MV(r7780rp)
+ALIAS_MV(highlander)
diff --git a/arch/sh/boards/se/770x/io.c b/arch/sh/boards/se/770x/io.c
index 9941949..c455047 100644
--- a/arch/sh/boards/se/770x/io.c
+++ b/arch/sh/boards/se/770x/io.c
@@ -27,6 +27,8 @@ int sh_pcic_io_dummy;
static inline volatile __u16 *
port2adr(unsigned int port)
{
+ if (port & 0xff000000)
+ return ( volatile __u16 *) port;
if (port >= 0x2000)
return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
else if (port >= 0x1000)
diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c
index 307ca5d..c8eccff 100644
--- a/arch/sh/boards/se/770x/irq.c
+++ b/arch/sh/boards/se/770x/irq.c
@@ -55,23 +55,34 @@ void make_se770x_irq(struct ipr_data *table, unsigned int nr_irqs)
}
static struct ipr_data se770x_ipr_map[] = {
+ /*
+ * Super I/O (Just mimic PC):
+ * 1: keyboard
+ * 3: serial 0
+ * 4: serial 1
+ * 5: printer
+ * 6: floppy
+ * 8: rtc
+ * 12: mouse
+ * 14: ide0
+ */
#if defined(CONFIG_CPU_SUBTYPE_SH7705)
/* This is default value */
- { 0xf-0x2, 0, 8, 0x2 , BCR_ILCRA},
- { 0xf-0xa, 0, 4, 0xa , BCR_ILCRA},
- { 0xf-0x5, 0, 0, 0x5 , BCR_ILCRB},
- { 0xf-0x8, 0, 4, 0x8 , BCR_ILCRC},
- { 0xf-0xc, 0, 0, 0xc , BCR_ILCRC},
- { 0xf-0xe, 0, 12, 0xe , BCR_ILCRD},
- { 0xf-0x3, 0, 4, 0x3 , BCR_ILCRD}, /* LAN */
- { 0xf-0xd, 0, 8, 0xd , BCR_ILCRE},
- { 0xf-0x9, 0, 4, 0x9 , BCR_ILCRE},
- { 0xf-0x1, 0, 0, 0x1 , BCR_ILCRE},
- { 0xf-0xf, 0, 12, 0xf , BCR_ILCRF},
- { 0xf-0xb, 0, 4, 0xb , BCR_ILCRF},
- { 0xf-0x7, 0, 12, 0x7 , BCR_ILCRG},
- { 0xf-0x6, 0, 8, 0x6 , BCR_ILCRG},
- { 0xf-0x4, 0, 4, 0x4 , BCR_ILCRG},
+ { 13, 0, 8, 0x0f-13 ,BCR_ILCRA},
+ { 5 , 0, 4, 0x0f- 5 ,BCR_ILCRA},
+ { 10, 0, 0, 0x0f-10, BCR_ILCRB},
+ { 7 , 0, 4, 0x0f- 7, BCR_ILCRC},
+ { 3 , 0, 0, 0x0f- 3, BCR_ILCRC},
+ { 1 , 0, 12, 0x0f- 1, BCR_ILCRD},
+ { 12, 0, 4, 0x0f-12, BCR_ILCRD}, /* LAN */
+ { 2 , 0, 8, 0x0f- 2, BCR_ILCRE}, /* PCIRQ2 */
+ { 6 , 0, 4, 0x0f- 6, BCR_ILCRE}, /* PCIRQ1 */
+ { 14, 0, 0, 0x0f-14, BCR_ILCRE}, /* PCIRQ0 */
+ { 0 , 0, 12, 0x0f , BCR_ILCRF},
+ { 4 , 0, 4, 0x0f- 4, BCR_ILCRF},
+ { 8 , 0, 12, 0x0f- 8, BCR_ILCRG},
+ { 9 , 0, 8, 0x0f- 9, BCR_ILCRG},
+ { 11, 0, 4, 0x0f-11, BCR_ILCRG},
#else
{ 14, 0, 8, 0x0f-14 ,BCR_ILCRA},
{ 12, 0, 4, 0x0f-12 ,BCR_ILCRA},
@@ -81,8 +92,10 @@ static struct ipr_data se770x_ipr_map[] = {
{ 4, 0, 4, 0x0f- 4 ,BCR_ILCRC},
{ 3, 0, 0, 0x0f- 3 ,BCR_ILCRC},
{ 1, 0, 12, 0x0f- 1 ,BCR_ILCRD},
+#if defined(CONFIG_STNIC)
/* ST NIC */
{ 10, 0, 4, 0x0f-10 ,BCR_ILCRD}, /* LAN */
+#endif
/* MRSHPC IRQs setting */
{ 0, 0, 12, 0x0f- 0 ,BCR_ILCRE}, /* PCIRQ3 */
{ 11, 0, 8, 0x0f-11 ,BCR_ILCRE}, /* PCIRQ2 */
@@ -100,18 +113,6 @@ static struct ipr_data se770x_ipr_map[] = {
*/
void __init init_se_IRQ(void)
{
- /*
- * Super I/O (Just mimic PC):
- * 1: keyboard
- * 3: serial 0
- * 4: serial 1
- * 5: printer
- * 6: floppy
- * 8: rtc
- * 12: mouse
- * 14: ide0
- */
-#if defined(CONFIG_CPU_SUBTYPE_SH7705)
/* Disable all interrupts */
ctrl_outw(0, BCR_ILCRA);
ctrl_outw(0, BCR_ILCRB);
@@ -120,6 +121,6 @@ void __init init_se_IRQ(void)
ctrl_outw(0, BCR_ILCRE);
ctrl_outw(0, BCR_ILCRF);
ctrl_outw(0, BCR_ILCRG);
-#endif
+
make_se770x_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map));
}
diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c
index 45cbc36..17a2631 100644
--- a/arch/sh/boards/se/770x/setup.c
+++ b/arch/sh/boards/se/770x/setup.c
@@ -63,6 +63,31 @@ static void __init smsc_setup(char **cmdline_p)
outb_p(CONFIG_EXIT, CONFIG_PORT);
}
+
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = PA_MRSHPC_IO + 0x1f0,
+ .end = PA_MRSHPC_IO + 0x1f0 + 8,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PA_MRSHPC_IO + 0x1f0 + 0x206,
+ .end = PA_MRSHPC_IO + 0x1f0 +8 + 0x206 + 8,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_CFCARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
static struct resource heartbeat_resources[] = {
@@ -85,13 +110,14 @@ static struct platform_device heartbeat_device = {
static struct platform_device *se_devices[] __initdata = {
&heartbeat_device,
+ &cf_ide_device,
};
static int __init se_devices_setup(void)
{
return platform_add_devices(se_devices, ARRAY_SIZE(se_devices));
}
-__initcall(se_devices_setup);
+device_initcall(se_devices_setup);
/*
* The Machine Vector
@@ -107,6 +133,8 @@ struct sh_machine_vector mv_se __initmv = {
.mv_nr_irqs = 61,
#elif defined(CONFIG_CPU_SUBTYPE_SH7705)
.mv_nr_irqs = 86,
+#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
+ .mv_nr_irqs = 104,
#endif
.mv_inb = se_inb,
diff --git a/arch/sh/boards/se/7722/Makefile b/arch/sh/boards/se/7722/Makefile
new file mode 100644
index 0000000..8694373
--- /dev/null
+++ b/arch/sh/boards/se/7722/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the HITACHI UL SolutionEngine 7722 specific parts of the kernel
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+#
+
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/se/7722/irq.c b/arch/sh/boards/se/7722/irq.c
new file mode 100644
index 0000000..099e5de
--- /dev/null
+++ b/arch/sh/boards/se/7722/irq.c
@@ -0,0 +1,101 @@
+/*
+ * linux/arch/sh/boards/se/7722/irq.c
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * Hitachi UL SolutionEngine 7722 Support.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/se7722.h>
+
+#define INTC_INTMSK0 0xFFD00044
+#define INTC_INTMSKCLR0 0xFFD00064
+
+static void disable_se7722_irq(unsigned int irq)
+{
+ struct ipr_data *p = get_irq_chip_data(irq);
+ ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr );
+}
+
+static void enable_se7722_irq(unsigned int irq)
+{
+ struct ipr_data *p = get_irq_chip_data(irq);
+ ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr );
+}
+
+static struct irq_chip se7722_irq_chip __read_mostly = {
+ .name = "SE7722",
+ .mask = disable_se7722_irq,
+ .unmask = enable_se7722_irq,
+ .mask_ack = disable_se7722_irq,
+};
+
+static struct ipr_data ipr_irq_table[] = {
+ /* irq ,idx,sft, priority , addr */
+ { MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } ,
+ { MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } ,
+ { MRSHPC_IRQ2 , 0 , 0 , MRSHPC_BIT2 , IRQ01_MASK } ,
+ { MRSHPC_IRQ3 , 0 , 0 , MRSHPC_BIT3 , IRQ01_MASK } ,
+ { SMC_IRQ , 0 , 0 , SMC_BIT , IRQ01_MASK } ,
+ { EXT_IRQ , 0 , 0 , EXT_BIT , IRQ01_MASK } ,
+};
+
+int se7722_irq_demux(int irq)
+{
+
+ if ((irq == IRQ0_IRQ)||(irq == IRQ1_IRQ)) {
+ volatile unsigned short intv =
+ *(volatile unsigned short *)IRQ01_STS;
+ if (irq == IRQ0_IRQ){
+ if(intv & SMC_BIT ) {
+ return SMC_IRQ;
+ } else if(intv & USB_BIT) {
+ return USB_IRQ;
+ } else {
+ printk("intv =%04x\n", intv);
+ return SMC_IRQ;
+ }
+ } else if(irq == IRQ1_IRQ){
+ if(intv & MRSHPC_BIT0) {
+ return MRSHPC_IRQ0;
+ } else if(intv & MRSHPC_BIT1) {
+ return MRSHPC_IRQ1;
+ } else if(intv & MRSHPC_BIT2) {
+ return MRSHPC_IRQ2;
+ } else if(intv & MRSHPC_BIT3) {
+ return MRSHPC_IRQ3;
+ } else {
+ printk("BIT_EXTENTION =%04x\n", intv);
+ return EXT_IRQ;
+ }
+ }
+ }
+ return irq;
+
+}
+/*
+ * Initialize IRQ setting
+ */
+void __init init_se7722_IRQ(void)
+{
+ int i = 0;
+ ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */
+ ctrl_outl((3 << ((7 - 0) * 4))|(3 << ((7 - 1) * 4)), INTC_INTPRI0); /* irq0 pri=3,irq1,pri=3 */
+ ctrl_outw((2 << ((7 - 0) * 2))|(2 << ((7 - 1) * 2)), INTC_ICR1); /* irq0,1 low-level irq */
+
+ for (i = 0; i < ARRAY_SIZE(ipr_irq_table); i++) {
+ disable_irq_nosync(ipr_irq_table[i].irq);
+ set_irq_chip_and_handler_name( ipr_irq_table[i].irq, &se7722_irq_chip,
+ handle_level_irq, "level");
+ set_irq_chip_data( ipr_irq_table[i].irq, &ipr_irq_table[i] );
+ disable_se7722_irq(ipr_irq_table[i].irq);
+ }
+}
diff --git a/arch/sh/boards/se/7722/setup.c b/arch/sh/boards/se/7722/setup.c
new file mode 100644
index 0000000..636ca6c
--- /dev/null
+++ b/arch/sh/boards/se/7722/setup.c
@@ -0,0 +1,148 @@
+/*
+ * linux/arch/sh/boards/se/7722/setup.c
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * Hitachi UL SolutionEngine 7722 Support.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pata_platform.h>
+#include <asm/machvec.h>
+#include <asm/se7722.h>
+#include <asm/io.h>
+
+/* Heartbeat */
+static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+
+static struct resource heartbeat_resources[] = {
+ [0] = {
+ .start = PA_LED,
+ .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = heartbeat_bit_pos,
+ },
+ .num_resources = ARRAY_SIZE(heartbeat_resources),
+ .resource = heartbeat_resources,
+};
+
+/* SMC91x */
+static struct resource smc91x_eth_resources[] = {
+ [0] = {
+ .name = "smc91x-regs" ,
+ .start = PA_LAN + 0x300,
+ .end = PA_LAN + 0x300 + 0x10 ,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SMC_IRQ,
+ .end = SMC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_eth_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL, /* don't use dma */
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_eth_resources),
+ .resource = smc91x_eth_resources,
+};
+
+static struct resource cf_ide_resources[] = {
+ [0] = {
+ .start = PA_MRSHPC_IO + 0x1f0,
+ .end = PA_MRSHPC_IO + 0x1f0 + 8 ,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .start = PA_MRSHPC_IO + 0x1f0 + 0x206,
+ .end = PA_MRSHPC_IO + 0x1f0 +8 + 0x206 + 8,
+ .flags = IORESOURCE_IO,
+ },
+ [2] = {
+ .start = MRSHPC_IRQ0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_ide_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cf_ide_resources),
+ .resource = cf_ide_resources,
+};
+
+static struct platform_device *se7722_devices[] __initdata = {
+ &heartbeat_device,
+ &smc91x_eth_device,
+ &cf_ide_device,
+};
+
+static int __init se7722_devices_setup(void)
+{
+ return platform_add_devices(se7722_devices,
+ ARRAY_SIZE(se7722_devices));
+}
+device_initcall(se7722_devices_setup);
+
+static void __init se7722_setup(char **cmdline_p)
+{
+ ctrl_outw(0x010D, FPGA_OUT); /* FPGA */
+
+ ctrl_outl(0x00051001, MSTPCR0);
+ ctrl_outl(0x00000000, MSTPCR1);
+ /* KEYSC, VOU, BEU, CEU, VEU, VPU, LCDC */
+ ctrl_outl(0xffffbfC0, MSTPCR2);
+
+ ctrl_outw(0x0000, PORT_PECR); /* PORT E 1 = IRQ5 ,E 0 = BS */
+ ctrl_outw(0x1000, PORT_PJCR); /* PORT J 1 = IRQ1,J 0 =IRQ0 */
+
+ /* LCDC I/O */
+ ctrl_outw(0x0020, PORT_PSELD);
+
+ /* SIOF1*/
+ ctrl_outw(0x0003, PORT_PSELB);
+ ctrl_outw(0xe000, PORT_PSELC);
+ ctrl_outw(0x0000, PORT_PKCR);
+
+ /* LCDC */
+ ctrl_outw(0x4020, PORT_PHCR);
+ ctrl_outw(0x0000, PORT_PLCR);
+ ctrl_outw(0x0000, PORT_PMCR);
+ ctrl_outw(0x0002, PORT_PRCR);
+ ctrl_outw(0x0000, PORT_PXCR); /* LCDC,CS6A */
+
+ /* KEYSC */
+ ctrl_outw(0x0A10, PORT_PSELA); /* BS,SHHID2 */
+ ctrl_outw(0x0000, PORT_PYCR);
+ ctrl_outw(0x0000, PORT_PZCR);
+}
+
+/*
+ * The Machine Vector
+ */
+struct sh_machine_vector mv_se7722 __initmv = {
+ .mv_name = "Solution Engine 7722" ,
+ .mv_setup = se7722_setup ,
+ .mv_nr_irqs = 109 ,
+ .mv_init_irq = init_se7722_IRQ,
+ .mv_irq_demux = se7722_irq_demux,
+
+};
+ALIAS_MV(se7722)
diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c
index e3feae6..770defe 100644
--- a/arch/sh/boards/se/7751/setup.c
+++ b/arch/sh/boards/se/7751/setup.c
@@ -14,153 +14,6 @@
#include <asm/se7751.h>
#include <asm/io.h>
-void init_7751se_IRQ(void);
-
-#ifdef CONFIG_SH_KGDB
-#include <asm/kgdb.h>
-static int kgdb_uart_setup(void);
-static struct kgdb_sermap kgdb_uart_sermap =
-{ "ttyS", 0, kgdb_uart_setup, NULL };
-#endif
-
-/*
- * Initialize the board
- */
-static void __init sh7751se_setup(char **cmdline_p)
-{
- /* Call init_smsc() replacement to set up SuperIO. */
- /* XXX: RTC setting comes here */
-#ifdef CONFIG_SH_KGDB
- kgdb_register_sermap(&kgdb_uart_sermap);
-#endif
-}
-
-/*********************************************************************
- * Currently a hack (e.g. does not interact well w/serial.c, lots of *
- * hardcoded stuff) but may be useful if SCI/F needs debugging. *
- * Mostly copied from x86 code (see files asm-i386/kgdb_local.h and *
- * arch/i386/lib/kgdb_serial.c). *
- *********************************************************************/
-
-#ifdef CONFIG_SH_KGDB
-#include <linux/types.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-
-#define COM1_PORT 0x3f8 /* Base I/O address */
-#define COM1_IRQ 4 /* IRQ not used yet */
-#define COM2_PORT 0x2f8 /* Base I/O address */
-#define COM2_IRQ 3 /* IRQ not used yet */
-
-#define SB_CLOCK 1843200 /* Serial baud clock */
-#define SB_BASE (SB_CLOCK/16)
-#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS
-
-struct uart_port {
- int base;
-};
-#define UART_NPORTS 2
-struct uart_port uart_ports[] = {
- { COM1_PORT },
- { COM2_PORT },
-};
-struct uart_port *kgdb_uart_port;
-
-#define UART_IN(reg) inb_p(kgdb_uart_port->base + reg)
-#define UART_OUT(reg,v) outb_p((v), kgdb_uart_port->base + reg)
-
-/* Basic read/write functions for the UART */
-#define UART_LSR_RXCERR (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE)
-static int kgdb_uart_getchar(void)
-{
- int lsr;
- int c = -1;
-
- while (c == -1) {
- lsr = UART_IN(UART_LSR);
- if (lsr & UART_LSR_DR)
- c = UART_IN(UART_RX);
- if ((lsr & UART_LSR_RXCERR))
- c = -1;
- }
- return c;
-}
-
-static void kgdb_uart_putchar(int c)
-{
- while ((UART_IN(UART_LSR) & UART_LSR_THRE) == 0)
- ;
- UART_OUT(UART_TX, c);
-}
-
-/*
- * Initialize UART to configured/requested values.
- * (But we don't interrupts yet, or interact w/serial.c)
- */
-static int kgdb_uart_setup(void)
-{
- int port;
- int lcr = 0;
- int bdiv = 0;
-
- if (kgdb_portnum >= UART_NPORTS) {
- KGDB_PRINTK("uart port %d invalid.\n", kgdb_portnum);
- return -1;
- }
-
- kgdb_uart_port = &uart_ports[kgdb_portnum];
-
- /* Init sequence from gdb_hook_interrupt */
- UART_IN(UART_RX);
- UART_OUT(UART_IER, 0);
-
- UART_IN(UART_RX); /* Serial driver comments say */
- UART_IN(UART_IIR); /* this clears interrupt regs */
- UART_IN(UART_MSR);
-
- /* Figure basic LCR values */
- switch (kgdb_bits) {
- case '7':
- lcr |= UART_LCR_WLEN7;
- break;
- default: case '8':
- lcr |= UART_LCR_WLEN8;
- break;
- }
- switch (kgdb_parity) {
- case 'O':
- lcr |= UART_LCR_PARITY;
- break;
- case 'E':
- lcr |= (UART_LCR_PARITY | UART_LCR_EPAR);
- break;
- default: break;
- }
-
- /* Figure the baud rate divisor */
- bdiv = (SB_BASE/kgdb_baud);
-
- /* Set the baud rate and LCR values */
- UART_OUT(UART_LCR, (lcr | UART_LCR_DLAB));
- UART_OUT(UART_DLL, (bdiv & 0xff));
- UART_OUT(UART_DLM, ((bdiv >> 8) & 0xff));
- UART_OUT(UART_LCR, lcr);
-
- /* Set the MCR */
- UART_OUT(UART_MCR, SB_MCR);
-
- /* Turn off FIFOs for now */
- UART_OUT(UART_FCR, 0);
-
- /* Setup complete: initialize function pointers */
- kgdb_getchar = kgdb_uart_getchar;
- kgdb_putchar = kgdb_uart_putchar;
-
- return 0;
-}
-#endif /* CONFIG_SH_KGDB */
-
static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
static struct resource heartbeat_resources[] = {
@@ -197,7 +50,6 @@ __initcall(se7751_devices_setup);
*/
struct sh_machine_vector mv_7751se __initmv = {
.mv_name = "7751 SolutionEngine",
- .mv_setup = sh7751se_setup,
.mv_nr_irqs = 72,
.mv_inb = sh7751se_inb,
diff --git a/arch/sh/boards/se/7780/Makefile b/arch/sh/boards/se/7780/Makefile
new file mode 100644
index 0000000..6b88ada
--- /dev/null
+++ b/arch/sh/boards/se/7780/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the HITACHI UL SolutionEngine 7780 specific parts of the kernel
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+#
+
+obj-y := setup.o irq.o
diff --git a/arch/sh/boards/se/7780/irq.c b/arch/sh/boards/se/7780/irq.c
new file mode 100644
index 0000000..3d0625c
--- /dev/null
+++ b/arch/sh/boards/se/7780/irq.c
@@ -0,0 +1,89 @@
+/*
+ * linux/arch/sh/boards/se/7780/irq.c
+ *
+ * Copyright (C) 2006,2007 Nobuhiro Iwamatsu
+ *
+ * Hitachi UL SolutionEngine 7780 Support.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/se7780.h>
+
+#define INTC_INTMSK0 0xFFD00044
+#define INTC_INTMSKCLR0 0xFFD00064
+
+static void disable_se7780_irq(unsigned int irq)
+{
+ struct intc2_data *p = get_irq_chip_data(irq);
+ ctrl_outl(1 << p->msk_shift, INTC_INTMSK0 + p->msk_offset);
+}
+
+static void enable_se7780_irq(unsigned int irq)
+{
+ struct intc2_data *p = get_irq_chip_data(irq);
+ ctrl_outl(1 << p->msk_shift, INTC_INTMSKCLR0 + p->msk_offset);
+}
+
+static struct irq_chip se7780_irq_chip __read_mostly = {
+ .name = "SE7780",
+ .mask = disable_se7780_irq,
+ .unmask = enable_se7780_irq,
+ .mask_ack = disable_se7780_irq,
+};
+
+static struct intc2_data intc2_irq_table[] = {
+ { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT1 */
+ { 4, 0, 30, 0, 30, 3 }, /* daughter board EXTINT2 */
+ { 6, 0, 29, 0, 29, 3 }, /* daughter board EXTINT3 */
+ { 8, 0, 28, 0, 28, 3 }, /* SMC 91C111 (LAN) */
+ { 10, 0, 27, 0, 27, 3 }, /* daughter board EXTINT4 */
+ { 4, 0, 30, 0, 30, 3 }, /* daughter board EXTINT5 */
+ { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT6 */
+ { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT7 */
+ { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT8 */
+ { 0 , 0, 24, 0, 24, 3 }, /* SM501 */
+};
+
+/*
+ * Initialize IRQ setting
+ */
+void __init init_se7780_IRQ(void)
+{
+ int i ;
+
+ /* enable all interrupt at FPGA */
+ ctrl_outw(0, FPGA_INTMSK1);
+ /* mask SM501 interrupt */
+ ctrl_outw((ctrl_inw(FPGA_INTMSK1) | 0x0002), FPGA_INTMSK1);
+ /* enable all interrupt at FPGA */
+ ctrl_outw(0, FPGA_INTMSK2);
+
+ /* set FPGA INTSEL register */
+ /* FPGA + 0x06 */
+ ctrl_outw( ((IRQPIN_SM501 << IRQPOS_SM501) |
+ (IRQPIN_SMC91CX << IRQPOS_SMC91CX)), FPGA_INTSEL1);
+
+ /* FPGA + 0x08 */
+ ctrl_outw(((IRQPIN_EXTINT4 << IRQPOS_EXTINT4) |
+ (IRQPIN_EXTINT3 << IRQPOS_EXTINT3) |
+ (IRQPIN_EXTINT2 << IRQPOS_EXTINT2) |
+ (IRQPIN_EXTINT1 << IRQPOS_EXTINT1)), FPGA_INTSEL2);
+
+ /* FPGA + 0x0A */
+ ctrl_outw((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3);
+
+ for (i = 0; i < ARRAY_SIZE(intc2_irq_table); i++) {
+ disable_irq_nosync(intc2_irq_table[i].irq);
+ set_irq_chip_and_handler_name( intc2_irq_table[i].irq, &se7780_irq_chip,
+ handle_level_irq, "level");
+ set_irq_chip_data( intc2_irq_table[i].irq, &intc2_irq_table[i] );
+ disable_se7780_irq(intc2_irq_table[i].irq);
+ }
+}
diff --git a/arch/sh/boards/se/7780/setup.c b/arch/sh/boards/se/7780/setup.c
new file mode 100644
index 0000000..df7d08a
--- /dev/null
+++ b/arch/sh/boards/se/7780/setup.c
@@ -0,0 +1,122 @@
+/*
+ * linux/arch/sh/boards/se/7780/setup.c
+ *
+ * Copyright (C) 2006,2007 Nobuhiro Iwamatsu
+ *
+ * Hitachi UL SolutionEngine 7780 Support.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <asm/machvec.h>
+#include <asm/se7780.h>
+#include <asm/io.h>
+
+/* Heartbeat */
+static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+
+static struct resource heartbeat_resources[] = {
+ [0] = {
+ .start = PA_LED,
+ .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = heartbeat_bit_pos,
+ },
+ .num_resources = ARRAY_SIZE(heartbeat_resources),
+ .resource = heartbeat_resources,
+};
+
+/* SMC91x */
+static struct resource smc91x_eth_resources[] = {
+ [0] = {
+ .name = "smc91x-regs" ,
+ .start = PA_LAN + 0x300,
+ .end = PA_LAN + 0x300 + 0x10 ,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SMC_IRQ,
+ .end = SMC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_eth_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL, /* don't use dma */
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_eth_resources),
+ .resource = smc91x_eth_resources,
+};
+
+static struct platform_device *se7780_devices[] __initdata = {
+ &heartbeat_device,
+ &smc91x_eth_device,
+};
+
+static int __init se7780_devices_setup(void)
+{
+ return platform_add_devices(se7780_devices,
+ ARRAY_SIZE(se7780_devices));
+}
+device_initcall(se7780_devices_setup);
+
+#define GPIO_PHCR 0xFFEA000E
+#define GPIO_PMSELR 0xFFEA0080
+#define GPIO_PECR 0xFFEA0008
+
+static void __init se7780_setup(char **cmdline_p)
+{
+ /* "SH-Linux" on LED Display */
+ ctrl_outw( 'S' , PA_LED_DISP + (DISP_SEL0_ADDR << 1) );
+ ctrl_outw( 'H' , PA_LED_DISP + (DISP_SEL1_ADDR << 1) );
+ ctrl_outw( '-' , PA_LED_DISP + (DISP_SEL2_ADDR << 1) );
+ ctrl_outw( 'L' , PA_LED_DISP + (DISP_SEL3_ADDR << 1) );
+ ctrl_outw( 'i' , PA_LED_DISP + (DISP_SEL4_ADDR << 1) );
+ ctrl_outw( 'n' , PA_LED_DISP + (DISP_SEL5_ADDR << 1) );
+ ctrl_outw( 'u' , PA_LED_DISP + (DISP_SEL6_ADDR << 1) );
+ ctrl_outw( 'x' , PA_LED_DISP + (DISP_SEL7_ADDR << 1) );
+
+ printk(KERN_INFO "Hitachi UL Solutions Engine 7780SE03 support.\n");
+
+ /*
+ * PCI REQ/GNT setting
+ * REQ0/GNT0 -> USB
+ * REQ1/GNT1 -> PC Card
+ * REQ2/GNT2 -> Serial ATA
+ * REQ3/GNT3 -> PCI slot
+ */
+ ctrl_outw(0x0213, FPGA_REQSEL);
+
+ /* GPIO setting */
+ ctrl_outw(0x0000, GPIO_PECR);
+ ctrl_outw(ctrl_inw(GPIO_PHCR)&0xfff3, GPIO_PHCR);
+ ctrl_outw(0x0c00, GPIO_PMSELR);
+
+ /* iVDR Power ON */
+ ctrl_outw(0x0001, FPGA_IVDRPW);
+}
+
+/*
+ * The Machine Vector
+ */
+struct sh_machine_vector mv_se7780 __initmv = {
+ .mv_name = "Solution Engine 7780" ,
+ .mv_setup = se7780_setup ,
+ .mv_nr_irqs = 111 ,
+ .mv_init_irq = init_se7780_IRQ,
+};
+ALIAS_MV(se7780)
diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig
new file mode 100644
index 0000000..be86414
--- /dev/null
+++ b/arch/sh/configs/lboxre2_defconfig
@@ -0,0 +1,1271 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-rc4
+# Sat Mar 24 22:04:27 2007
+#
+CONFIG_SUPERH=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System type
+#
+# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_HP6XX is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_HIGHLANDER is not set
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_7206_SOLUTION_ENGINE is not set
+# CONFIG_SH_7619_SOLUTION_ENGINE is not set
+CONFIG_SH_LBOX_RE2=y
+# CONFIG_SH_UNKNOWN is not set
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH4=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+
+#
+# SH-2A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+CONFIG_CPU_SUBTYPE_SH7751=y
+CONFIG_CPU_SUBTYPE_SH7751R=y
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+
+#
+# Memory management options
+#
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_VSYSCALL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_IPR_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_SH_PCLK_FREQ=40000000
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_KEXEC=y
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,115200 root=/dev/sda1"
+
+#
+# Bus options
+#
+CONFIG_ISA=y
+CONFIG_PCI=y
+CONFIG_SH_PCIDMA_NONCOHERENT=y
+CONFIG_PCI_AUTO=y
+CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_DEBUG=y
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+# CONFIG_YENTA_RICOH is not set
+# CONFIG_YENTA_TI is not set
+# CONFIG_YENTA_TOSHIBA is not set
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PCMCIA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_QDI is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_WINBOND_VLB is not set
+CONFIG_PATA_PLATFORM=y
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_STNIC is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_SMC91X is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+CONFIG_NE2K_PCI=y
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+CONFIG_8139TOO_PIO=y
+CONFIG_8139TOO_TUNE_TWISTER=y
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_SH is not set
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_SH_STANDARD_BIOS=y
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_EARLY_PRINTK is not set
+# CONFIG_SH_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/sh/configs/r7780rp_defconfig b/arch/sh/configs/r7780rp_defconfig
index 2b75b48..48c6a21 100644
--- a/arch/sh/configs/r7780rp_defconfig
+++ b/arch/sh/configs/r7780rp_defconfig
@@ -1,10 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19
-# Wed Dec 6 11:59:38 2006
+# Linux kernel version: 2.6.21-rc7
+# Tue May 1 12:28:39 2007
#
CONFIG_SUPERH=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
@@ -13,6 +14,8 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
# CONFIG_GENERIC_TIME is not set
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -31,6 +34,7 @@ CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
@@ -41,7 +45,7 @@ CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
-CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
@@ -99,23 +103,23 @@ CONFIG_DEFAULT_IOSCHED="noop"
# System type
#
# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_7722_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7780_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_BIGSUR is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
-CONFIG_SH_R7780RP=y
+CONFIG_SH_HIGHLANDER=y
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
# CONFIG_SH_LANDISK is not set
@@ -123,7 +127,11 @@ CONFIG_SH_R7780RP=y
# CONFIG_SH_SHMIN is not set
# CONFIG_SH_7206_SOLUTION_ENGINE is not set
# CONFIG_SH_7619_SOLUTION_ENGINE is not set
+# CONFIG_SH_LBOX_RE2 is not set
# CONFIG_SH_UNKNOWN is not set
+CONFIG_SH_R7780RP=y
+# CONFIG_SH_R7780MP is not set
+# CONFIG_SH_R7785RP is not set
#
# Processor selection
@@ -152,6 +160,7 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
#
# SH-4 Processor Support
@@ -183,6 +192,7 @@ CONFIG_CPU_SUBTYPE_SH7780=y
#
# CONFIG_CPU_SUBTYPE_SH73180 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
#
# Memory management options
@@ -193,6 +203,8 @@ CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
# CONFIG_32BIT is not set
CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_64KB is not set
@@ -210,6 +222,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
#
# Cache configuration
@@ -226,20 +239,15 @@ CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_SH_FPU=y
# CONFIG_SH_DSP is not set
CONFIG_SH_STORE_QUEUES=y
+CONFIG_SPECULATIVE_EXECUTION=y
CONFIG_CPU_HAS_INTEVT=y
CONFIG_CPU_HAS_INTC2_IRQ=y
CONFIG_CPU_HAS_SR_RB=y
-CONFIG_CPU_HAS_PTEA=y
#
-# Timer support
+# Timer and clock configuration
#
CONFIG_SH_TMU=y
-
-#
-# R7780RP options
-#
-CONFIG_SH_R7780MP=y
CONFIG_SH_TIMER_IRQ=28
CONFIG_NO_IDLE_HZ=y
CONFIG_SH_PCLK_FREQ=32000000
@@ -262,6 +270,7 @@ CONFIG_SH_PCLK_FREQ=32000000
#
# Additional SuperH Device Drivers
#
+# CONFIG_HEARTBEAT is not set
CONFIG_PUSH_SWITCH=y
#
@@ -269,9 +278,11 @@ CONFIG_PUSH_SWITCH=y
#
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
# CONFIG_SMP is not set
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
@@ -294,7 +305,6 @@ CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
CONFIG_PCI_AUTO=y
CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
-# CONFIG_PCI_MULTITHREAD_PROBE is not set
# CONFIG_PCI_DEBUG is not set
#
@@ -334,6 +344,7 @@ CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -425,6 +436,7 @@ CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=m
# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
#
@@ -445,6 +457,7 @@ CONFIG_FW_LOADER=m
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -461,7 +474,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -481,6 +493,7 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
@@ -500,6 +513,7 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
#
# SCSI Transports
@@ -544,11 +558,13 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
#
# Serial ATA (prod) and Parallel ATA (experimental) drivers
#
CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SVW is not set
# CONFIG_ATA_PIIX is not set
@@ -564,6 +580,7 @@ CONFIG_SATA_SIL=y
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
@@ -579,6 +596,7 @@ CONFIG_SATA_SIL=y
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_MARVELL is not set
@@ -685,6 +703,7 @@ CONFIG_8139TOO_8129=y
CONFIG_VIA_RHINE=m
CONFIG_VIA_RHINE_MMIO=y
# CONFIG_VIA_RHINE_NAPI is not set
+# CONFIG_SC92031 is not set
#
# Ethernet (1000 Mbit)
@@ -707,11 +726,13 @@ CONFIG_R8169=y
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
#
# Ethernet (10000 Mbit)
#
# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
@@ -889,10 +910,16 @@ CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -905,9 +932,8 @@ CONFIG_HWMON=y
#
# Graphics support
#
-CONFIG_FIRMWARE_EDID=y
-# CONFIG_FB is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
#
# Sound
@@ -923,9 +949,8 @@ CONFIG_SOUND=m
# Open Sound System
#
CONFIG_SOUND_PRIME=m
-# CONFIG_OSS_OBSOLETE_DRIVER is not set
+# CONFIG_OBSOLETE_OSS is not set
# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_ES1371 is not set
# CONFIG_SOUND_ICH is not set
# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
@@ -933,6 +958,12 @@ CONFIG_SOUND_PRIME=m
# CONFIG_SOUND_VIA82CXXX is not set
#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
@@ -1017,6 +1048,14 @@ CONFIG_RTC_DRV_SH=y
#
#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
@@ -1175,6 +1214,11 @@ CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_UTF8 is not set
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
CONFIG_PROFILING=y
@@ -1184,19 +1228,22 @@ CONFIG_OPROFILE=m
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_PRINTK_TIME=y
+# CONFIG_PRINTK_TIME is not set
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_RWSEMS is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
@@ -1204,19 +1251,19 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_FS=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
-CONFIG_FRAME_POINTER=y
+# CONFIG_FRAME_POINTER is not set
CONFIG_FORCED_INLINING=y
-# CONFIG_HEADERS_CHECK is not set
# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_SH_STANDARD_BIOS=y
# CONFIG_EARLY_SCIF_CONSOLE is not set
+CONFIG_EARLY_PRINTK=y
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_4KSTACKS is not set
-# CONFIG_KGDB is not set
+# CONFIG_SH_KGDB is not set
#
# Security options
@@ -1233,6 +1280,7 @@ CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
@@ -1241,9 +1289,13 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_SERPENT is not set
@@ -1257,6 +1309,7 @@ CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
#
@@ -1266,7 +1319,10 @@ CONFIG_CRYPTO_DES=y
#
# Library routines
#
+CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig
new file mode 100644
index 0000000..0f5ec64
--- /dev/null
+++ b/arch/sh/configs/r7785rp_defconfig
@@ -0,0 +1,1334 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-rc3
+# Mon Mar 12 14:26:33 2007
+#
+CONFIG_SUPERH=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
+# System type
+#
+# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_HP6XX is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
+# CONFIG_SH_RTS7751R2D is not set
+CONFIG_SH_HIGHLANDER=y
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_7206_SOLUTION_ENGINE is not set
+# CONFIG_SH_7619_SOLUTION_ENGINE is not set
+# CONFIG_SH_UNKNOWN is not set
+# CONFIG_SH_R7780RP is not set
+# CONFIG_SH_R7780MP is not set
+CONFIG_SH_R7785RP=y
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SHX2=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+
+#
+# SH-2A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+CONFIG_CPU_SUBTYPE_SH7785=y
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+
+#
+# Memory management options
+#
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_32BIT=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64K is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256K is not set
+CONFIG_HUGETLB_PAGE_SIZE_1MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
+CONFIG_SH_STORE_QUEUES=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_INTC2_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=28
+CONFIG_NO_IDLE_HZ=y
+CONFIG_SH_PCLK_FREQ=50000000
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+CONFIG_PUSH_SWITCH=y
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_KEXEC=y
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1"
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_SH_PCIDMA_NONCOHERENT=y
+CONFIG_PCI_AUTO=y
+CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+CONFIG_WIRELESS_EXT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+CONFIG_PATA_PLATFORM=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_STNIC is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+CONFIG_R8169=y
+# CONFIG_R8169_NAPI is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+# CONFIG_NET_WIRELESS_RTNETLINK is not set
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+# CONFIG_STRIP is not set
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frambuffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_EPSON1355 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=m
+# CONFIG_OBSOLETE_OSS is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_SH=y
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+CONFIG_NLS_CODEPAGE_932=y
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_LOCK_ALLOC=y
+# CONFIG_PROVE_LOCKING is not set
+CONFIG_LOCKDEP=y
+# CONFIG_DEBUG_LOCKDEP is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_SH_STANDARD_BIOS=y
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_STACK_USAGE=y
+# CONFIG_4KSTACKS is not set
+# CONFIG_SH_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig
index 06ebd6e..87ae5c1 100644
--- a/arch/sh/configs/se7705_defconfig
+++ b/arch/sh/configs/se7705_defconfig
@@ -1,15 +1,21 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Tue Oct 3 12:03:04 2006
+# Linux kernel version: 2.6.21-rc5
+# Thu Apr 26 09:16:31 2007
#
CONFIG_SUPERH=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -33,7 +39,9 @@ CONFIG_LOCALVERSION_AUTO=y
# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
@@ -91,27 +99,30 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
CONFIG_SOLUTION_ENGINE=y
CONFIG_SH_SOLUTION_ENGINE=y
# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7780_SOLUTION_ENGINE is not set
# CONFIG_SH_7300_SOLUTION_ENGINE is not set
# CONFIG_SH_7343_SOLUTION_ENGINE is not set
# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7722_SOLUTION_ENGINE is not set
# CONFIG_SH_7751_SYSTEMH is not set
# CONFIG_SH_HP6XX is not set
-# CONFIG_SH_EC3104 is not set
# CONFIG_SH_SATURN is not set
# CONFIG_SH_DREAMCAST is not set
-# CONFIG_SH_BIGSUR is not set
# CONFIG_SH_MPC1211 is not set
# CONFIG_SH_SH03 is not set
# CONFIG_SH_SECUREEDGE5410 is not set
# CONFIG_SH_HS7751RVOIP is not set
# CONFIG_SH_7710VOIPGW is not set
# CONFIG_SH_RTS7751R2D is not set
-# CONFIG_SH_R7780RP is not set
+# CONFIG_SH_HIGHLANDER is not set
# CONFIG_SH_EDOSK7705 is not set
# CONFIG_SH_SH4202_MICRODEV is not set
# CONFIG_SH_LANDISK is not set
# CONFIG_SH_TITAN is not set
# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_7206_SOLUTION_ENGINE is not set
+# CONFIG_SH_7619_SOLUTION_ENGINE is not set
+# CONFIG_SH_LBOX_RE2 is not set
# CONFIG_SH_UNKNOWN is not set
#
@@ -123,6 +134,12 @@ CONFIG_CPU_SH3=y
# SH-2 Processor Support
#
# CONFIG_CPU_SUBTYPE_SH7604 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+
+#
+# SH-2A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
#
# SH-3 Processor Support
@@ -134,6 +151,7 @@ CONFIG_CPU_SUBTYPE_SH7705=y
# CONFIG_CPU_SUBTYPE_SH7708 is not set
# CONFIG_CPU_SUBTYPE_SH7709 is not set
# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
#
# SH-4 Processor Support
@@ -158,12 +176,14 @@ CONFIG_CPU_SUBTYPE_SH7705=y
#
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
#
# SH4AL-DSP Processor Support
#
# CONFIG_CPU_SUBTYPE_SH73180 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
#
# Memory management options
@@ -173,6 +193,11 @@ CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x0c000000
CONFIG_MEMORY_SIZE=0x02000000
CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -182,6 +207,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
#
# Cache configuration
@@ -190,23 +216,31 @@ CONFIG_SH7705_CACHE_32KB=y
# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_SH_WRITETHROUGH is not set
# CONFIG_SH_OCRAM is not set
-# CONFIG_CF_ENABLER is not set
+CONFIG_CF_ENABLER=y
+# CONFIG_CF_AREA5 is not set
+CONFIG_CF_AREA6=y
+# CONFIG_CF_AREA4 is not set
+CONFIG_CF_BASE_ADDR=0xb8000000
#
# Processor features
#
CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
# CONFIG_SH_FPU_EMU is not set
# CONFIG_SH_DSP is not set
# CONFIG_SH_ADC is not set
CONFIG_CPU_HAS_INTEVT=y
CONFIG_CPU_HAS_PINT_IRQ=y
+CONFIG_CPU_HAS_IPR_IRQ=y
CONFIG_CPU_HAS_SR_RB=y
#
-# Timer support
+# Timer and clock configuration
#
CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+# CONFIG_NO_IDLE_HZ is not set
CONFIG_SH_PCLK_FREQ=33333333
#
@@ -223,13 +257,19 @@ CONFIG_SH_PCLK_FREQ=33333333
# Companion Chips
#
# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
#
# Kernel features
#
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
# CONFIG_KEXEC is not set
@@ -287,6 +327,7 @@ CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
@@ -307,11 +348,13 @@ CONFIG_IP_PNP_RARP=y
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
@@ -388,6 +431,7 @@ CONFIG_MTD_PARTITIONS=y
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
@@ -461,6 +505,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# Plug and Play support
#
+# CONFIG_PNPACPI is not set
#
# Block devices
@@ -472,11 +517,14 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
#
+# Misc devices
+#
+
+#
# ATA/ATAPI/MFM/RLL support
#
# CONFIG_IDE is not set
@@ -649,17 +697,12 @@ CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
# CONFIG_RAW_DRIVER is not set
#
# TPM devices
#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
#
# I2C support
@@ -675,6 +718,7 @@ CONFIG_HW_RANDOM=y
#
# Dallas's 1-wire bus
#
+# CONFIG_W1 is not set
#
# Hardware Monitoring support
@@ -683,18 +727,19 @@ CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ABITUGURU is not set
# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
-# Misc devices
+# Multifunction device drivers
#
+# CONFIG_MFD_SM501 is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
#
# Digital Video Broadcasting Devices
@@ -704,7 +749,7 @@ CONFIG_VIDEO_V4L2=y
#
# Graphics support
#
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
# CONFIG_FB is not set
#
@@ -713,6 +758,12 @@ CONFIG_FIRMWARE_EDID=y
# CONFIG_SOUND is not set
#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
# USB support
#
# CONFIG_USB_ARCH_HAS_HCD is not set
@@ -773,16 +824,26 @@ CONFIG_FIRMWARE_EDID=y
#
#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
@@ -828,7 +889,6 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
@@ -878,6 +938,10 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
#
+# Distributed Lock Manager
+#
+
+#
# Profiling support
#
# CONFIG_PROFILING is not set
@@ -885,15 +949,18 @@ CONFIG_MSDOS_PARTITION=y
#
# Kernel hacking
#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_SH_STANDARD_BIOS is not set
-# CONFIG_KGDB is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_SH_KGDB is not set
#
# Security options
@@ -908,6 +975,7 @@ CONFIG_LOG_BUF_SHIFT=14
#
# Library routines
#
+CONFIG_BITREVERSE=y
CONFIG_CRC_CCITT=y
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
@@ -915,3 +983,5 @@ CONFIG_CRC32=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig
new file mode 100644
index 0000000..a5e37db
--- /dev/null
+++ b/arch/sh/configs/se7712_defconfig
@@ -0,0 +1,1088 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-rc4
+# Wed Mar 28 10:19:02 2007
+#
+CONFIG_SUPERH=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+# CONFIG_BUG is not set
+CONFIG_ELF_CORE=y
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_SHMEM is not set
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=1
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
+# System type
+#
+CONFIG_SOLUTION_ENGINE=y
+CONFIG_SH_SOLUTION_ENGINE=y
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_HP6XX is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_HIGHLANDER is not set
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_7206_SOLUTION_ENGINE is not set
+# CONFIG_SH_7619_SOLUTION_ENGINE is not set
+# CONFIG_SH_LBOX_RE2 is not set
+# CONFIG_SH_UNKNOWN is not set
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH3=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+
+#
+# SH-2A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+CONFIG_CPU_SUBTYPE_SH7712=y
+
+#
+# SH-4 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+
+#
+# Memory management options
+#
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x02000000
+CONFIG_VSYSCALL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
+CONFIG_CF_ENABLER=y
+# CONFIG_CF_AREA5 is not set
+CONFIG_CF_AREA6=y
+CONFIG_CF_BASE_ADDR=0xb8000000
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+# CONFIG_SH_FPU_EMU is not set
+# CONFIG_SH_DSP is not set
+# CONFIG_SH_ADC is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_IPR_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_SH_PCLK_FREQ=33333333
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_KEXEC is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1"
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_FIFO=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_HFSC=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_SCH_RED=y
+CONFIG_NET_SCH_SFQ=y
+CONFIG_NET_SCH_TEQL=y
+CONFIG_NET_SCH_TBF=y
+CONFIG_NET_SCH_GRED=y
+CONFIG_NET_SCH_DSMARK=y
+CONFIG_NET_SCH_NETEM=y
+CONFIG_NET_SCH_INGRESS=y
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+# CONFIG_NET_CLS_BASIC is not set
+CONFIG_NET_CLS_TCINDEX=y
+CONFIG_NET_CLS_ROUTE4=y
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=y
+# CONFIG_NET_CLS_U32 is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+# CONFIG_NET_CLS_POLICE is not set
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_ESTIMATOR=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+CONFIG_FIB_RULES=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_PATA_PLATFORM=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
+# CONFIG_SH_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig
new file mode 100644
index 0000000..ca4c663
--- /dev/null
+++ b/arch/sh/configs/se7722_defconfig
@@ -0,0 +1,980 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-rc7
+# Fri Apr 27 16:30:30 2007
+#
+CONFIG_SUPERH=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
+# System type
+#
+CONFIG_SOLUTION_ENGINE=y
+# CONFIG_SH_SOLUTION_ENGINE is not set
+CONFIG_SH_7722_SOLUTION_ENGINE=y
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+# CONFIG_SH_7780_SOLUTION_ENGINE is not set
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_HP6XX is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_HIGHLANDER is not set
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_7206_SOLUTION_ENGINE is not set
+# CONFIG_SH_7619_SOLUTION_ENGINE is not set
+# CONFIG_SH_LBOX_RE2 is not set
+# CONFIG_SH_UNKNOWN is not set
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SH4AL_DSP=y
+CONFIG_CPU_SHX2=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+
+#
+# SH-2A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+
+#
+# SH-4 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+CONFIG_CPU_SUBTYPE_SH7722=y
+
+#
+# Memory management options
+#
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+# CONFIG_32BIT is not set
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_HUGETLB_PAGE_SIZE_64K=y
+# CONFIG_HUGETLB_PAGE_SIZE_256K is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
+CONFIG_CF_ENABLER=y
+# CONFIG_CF_AREA5 is not set
+CONFIG_CF_AREA6=y
+CONFIG_CF_BASE_ADDR=0xb8000000
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+# CONFIG_SH_FPU is not set
+# CONFIG_SH_FPU_EMU is not set
+CONFIG_SH_DSP=y
+CONFIG_SH_STORE_QUEUES=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_IPR_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+CONFIG_NO_IDLE_HZ=y
+CONFIG_SH_PCLK_FREQ=33333333
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_BKL=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_PATA_PLATFORM=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_STNIC is not set
+CONFIG_SMC91X=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_SH=y
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_SH_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig
new file mode 100644
index 0000000..538661e
--- /dev/null
+++ b/arch/sh/configs/se7780_defconfig
@@ -0,0 +1,1309 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-rc3
+# Thu Mar 15 14:06:20 2007
+#
+CONFIG_SUPERH=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+
+#
+# System type
+#
+CONFIG_SOLUTION_ENGINE=y
+# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SOLUTION_ENGINE is not set
+CONFIG_SH_7780_SOLUTION_ENGINE=y
+# CONFIG_SH_7300_SOLUTION_ENGINE is not set
+# CONFIG_SH_7343_SOLUTION_ENGINE is not set
+# CONFIG_SH_73180_SOLUTION_ENGINE is not set
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_HP6XX is not set
+# CONFIG_SH_SATURN is not set
+# CONFIG_SH_DREAMCAST is not set
+# CONFIG_SH_MPC1211 is not set
+# CONFIG_SH_SH03 is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+# CONFIG_SH_HS7751RVOIP is not set
+# CONFIG_SH_7710VOIPGW is not set
+# CONFIG_SH_RTS7751R2D is not set
+# CONFIG_SH_HIGHLANDER is not set
+# CONFIG_SH_EDOSK7705 is not set
+# CONFIG_SH_SH4202_MICRODEV is not set
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_SHMIN is not set
+# CONFIG_SH_7206_SOLUTION_ENGINE is not set
+# CONFIG_SH_7619_SOLUTION_ENGINE is not set
+# CONFIG_SH_UNKNOWN is not set
+
+#
+# Processor selection
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+
+#
+# SH-2 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7604 is not set
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+
+#
+# SH-2A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+
+#
+# SH-3 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7300 is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+
+#
+# SH-4 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+
+#
+# ST40 Processor Support
+#
+# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
+# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
+
+#
+# SH-4A Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+CONFIG_CPU_SUBTYPE_SH7780=y
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+
+#
+# SH4AL-DSP Processor Support
+#
+# CONFIG_CPU_SUBTYPE_SH73180 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+
+#
+# Memory management options
+#
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_32BIT=y
+CONFIG_VSYSCALL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+# CONFIG_SH_WRITETHROUGH is not set
+# CONFIG_SH_OCRAM is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_DSP is not set
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_INTC2_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=28
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_SH_PCLK_FREQ=33333333
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+# CONFIG_HD6446X_SERIES is not set
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00810000
+# CONFIG_UBC_WAKEUP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_SH_PCIDMA_NONCOHERENT=y
+CONFIG_PCI_AUTO=y
+CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+# CONFIG_MTD_CFI_I1 is not set
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+CONFIG_MTD_ROM=y
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_STNIC is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+CONFIG_SMC91X=y
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frambuffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_EPSON1355 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_LOGO_SUPERH_MONO is not set
+# CONFIG_LOGO_SUPERH_VGA16 is not set
+CONFIG_LOGO_SUPERH_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+# CONFIG_OBSOLETE_OSS is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_TOUCHSCREEN is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+# CONFIG_SYSFS is not set
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_SH_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/arch/sh/drivers/Kconfig b/arch/sh/drivers/Kconfig
index c54c758..420c6b2 100644
--- a/arch/sh/drivers/Kconfig
+++ b/arch/sh/drivers/Kconfig
@@ -1,5 +1,15 @@
+source "arch/sh/drivers/dma/Kconfig"
+source "arch/sh/cchips/Kconfig"
+
menu "Additional SuperH Device Drivers"
+config HEARTBEAT
+ bool "Heartbeat LED"
+ help
+ Use the power-on LED on your machine as a load meter. The exact
+ behavior is platform-dependent, but normally the flash frequency is
+ a hyperbolic function of the 5-minute load average.
+
config PUSH_SWITCH
tristate "Push switch support"
help
diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c
index bc59cb6..23dd608 100644
--- a/arch/sh/drivers/heartbeat.c
+++ b/arch/sh/drivers/heartbeat.c
@@ -40,16 +40,9 @@ static void heartbeat_timer(unsigned long data)
static unsigned bit = 0, up = 1;
ctrl_outw(1 << hd->bit_pos[bit], (unsigned long)hd->base);
- if (up)
- if (bit == (ARRAY_SIZE(hd->bit_pos) - 1)) {
- bit--;
- up = 0;
- } else
- bit++;
- else if (bit == 0)
- up = 1;
- else
- bit--;
+ bit += up;
+ if ((bit == 0) || (bit == ARRAY_SIZE(hd->bit_pos)-1))
+ up = -up;
mod_timer(&hd->timer, jiffies + (110 - ((300 << FSHIFT) /
((avenrun[0] / 5) + (3 << FSHIFT)))));
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
index cc8d0d0..0e9b532 100644
--- a/arch/sh/drivers/pci/Makefile
+++ b/arch/sh/drivers/pci/Makefile
@@ -8,12 +8,15 @@ obj-$(CONFIG_PCI_AUTO) += pci-auto.o
obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o
obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o
obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o
obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \
dma-dreamcast.o
obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o
obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o
obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o
-obj-$(CONFIG_SH_R7780RP) += ops-r7780rp.o fixups-r7780rp.o
+obj-$(CONFIG_SH_HIGHLANDER) += ops-r7780rp.o fixups-r7780rp.o
obj-$(CONFIG_SH_TITAN) += ops-titan.o
obj-$(CONFIG_SH_LANDISK) += ops-landisk.o
+obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o
+obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += ops-se7780.o fixups-se7780.o
diff --git a/arch/sh/drivers/pci/fixups-lboxre2.c b/arch/sh/drivers/pci/fixups-lboxre2.c
new file mode 100644
index 0000000..40b19bd
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-lboxre2.c
@@ -0,0 +1,41 @@
+/*
+ * arch/sh/drivers/pci/fixups-lboxre2.c
+ *
+ * L-BOX RE2 PCI fixups
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include "pci-sh4.h"
+
+#define PCIMCR_MRSET_OFF 0xBFFFFFFF
+#define PCIMCR_RFSH_OFF 0xFFFFFFFB
+
+int pci_fixup_pcic(void)
+{
+ unsigned long bcr1, mcr;
+
+ bcr1 = inl(SH7751_BCR1);
+ bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */
+ pci_write_reg(bcr1, SH4_PCIBCR1);
+
+ /* Enable all interrupts, so we known what to fix */
+ pci_write_reg(0x0000c3ff, SH4_PCIINTM);
+ pci_write_reg(0x0000380f, SH4_PCIAINTM);
+ pci_write_reg(0xfb900047, SH7751_PCICONF1);
+ pci_write_reg(0xab000001, SH7751_PCICONF4);
+
+ mcr = inl(SH7751_MCR);
+ mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
+ pci_write_reg(mcr, SH4_PCIMCR);
+
+ pci_write_reg(0x0c000000, SH7751_PCICONF5);
+ pci_write_reg(0xd0000000, SH7751_PCICONF6);
+ pci_write_reg(0x0c000000, SH4_PCILAR0);
+ pci_write_reg(0x00000000, SH4_PCILAR1);
+
+ return 0;
+}
diff --git a/arch/sh/drivers/pci/fixups-se7780.c b/arch/sh/drivers/pci/fixups-se7780.c
new file mode 100644
index 0000000..880cea1
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-se7780.c
@@ -0,0 +1,60 @@
+/*
+ * arch/sh/drivers/pci/fixups-se7780.c
+ *
+ * HITACHI UL Solution Engine 7780 PCI fixups
+ *
+ * Copyright (C) 2003 Lineo uSolutions, Inc.
+ * Copyright (C) 2004 - 2006 Paul Mundt
+ * Copyright (C) 2006 Nobuhiro Iwamatsu
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/pci.h>
+#include "pci-sh4.h"
+#include <asm/io.h>
+
+int pci_fixup_pcic(void)
+{
+ ctrl_outl(0x00000001, SH7780_PCI_VCR2);
+
+ /* Enable all interrupts, so we know what to fix */
+ pci_write_reg(0x0000C3FF, SH7780_PCIIMR);
+ pci_write_reg(0x0000380F, SH7780_PCIAINTM);
+
+ /* Set up standard PCI config registers */
+ ctrl_outw(0xFB00, PCI_REG(SH7780_PCISTATUS));
+ ctrl_outw(0x0047, PCI_REG(SH7780_PCICMD));
+ ctrl_outb( 0x00, PCI_REG(SH7780_PCIPIF));
+ ctrl_outb( 0x00, PCI_REG(SH7780_PCISUB));
+ ctrl_outb( 0x06, PCI_REG(SH7780_PCIBCC));
+ ctrl_outw(0x1912, PCI_REG(SH7780_PCISVID));
+ ctrl_outw(0x0001, PCI_REG(SH7780_PCISID));
+
+ pci_write_reg(0x08000000, SH7780_PCIMBAR0); /* PCI */
+ pci_write_reg(0x08000000, SH7780_PCILAR0); /* SHwy */
+ pci_write_reg(0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */
+
+ pci_write_reg(0x00000000, SH7780_PCIMBAR1);
+ pci_write_reg(0x00000000, SH7780_PCILAR1);
+ pci_write_reg(0x00000000, SH7780_PCILSR1);
+
+ pci_write_reg(0xAB000801, SH7780_PCIIBAR);
+
+ /*
+ * Set the MBR so PCI address is one-to-one with window,
+ * meaning all calls go straight through... use ifdef to
+ * catch erroneous assumption.
+ */
+ pci_write_reg(0xFD000000 , SH7780_PCIMBR0);
+ pci_write_reg(0x00FC0000 , SH7780_PCIMBMR0); /* 16M */
+
+ /* Set IOBR for window containing area specified in pci.h */
+ pci_write_reg(PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR);
+ pci_write_reg((SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR);
+
+ pci_write_reg(0xA5000C01, SH7780_PCICR);
+
+ return 0;
+}
diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/ops-landisk.c
index d060308..bff09ec 100644
--- a/arch/sh/drivers/pci/ops-landisk.c
+++ b/arch/sh/drivers/pci/ops-landisk.c
@@ -17,8 +17,8 @@
static struct resource sh7751_io_resource = {
.name = "SH7751 IO",
- .start = 0x4000,
- .end = 0x4000 + SH7751_PCI_IO_SIZE - 1,
+ .start = SH7751_PCI_IO_BASE,
+ .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
.flags = IORESOURCE_IO
};
diff --git a/arch/sh/drivers/pci/ops-lboxre2.c b/arch/sh/drivers/pci/ops-lboxre2.c
new file mode 100644
index 0000000..a13cb76
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-lboxre2.c
@@ -0,0 +1,63 @@
+/*
+ * linux/arch/sh/drivers/pci/ops-lboxre2.c
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * PCI initialization for the NTT COMWARE L-BOX RE2
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <asm/lboxre2.h>
+#include "pci-sh4.h"
+
+static char lboxre2_irq_tab[] __initdata = {
+ IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD,
+};
+
+int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
+{
+ return lboxre2_irq_tab[slot];
+}
+
+static struct resource sh7751_io_resource = {
+ .name = "SH7751_IO",
+ .start = SH7751_PCI_IO_BASE ,
+ .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
+ .flags = IORESOURCE_IO
+};
+
+static struct resource sh7751_mem_resource = {
+ .name = "SH7751_mem",
+ .start = SH7751_PCI_MEMORY_BASE,
+ .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM
+};
+
+extern struct pci_ops sh7751_pci_ops;
+
+struct pci_channel board_pci_channels[] = {
+ { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
+ { NULL, NULL, NULL, 0, 0 },
+};
+
+EXPORT_SYMBOL(board_pci_channels);
+
+static struct sh4_pci_address_map sh7751_pci_map = {
+ .window0 = {
+ .base = SH7751_CS3_BASE_ADDR,
+ .size = 0x04000000,
+ },
+ .window1 = {
+ .base = 0x00000000, /* Unused */
+ .size = 0x00000000, /* Unused */
+ },
+ .flags = SH4_PCIC_NO_RESET,
+};
+
+int __init pcibios_init_platform(void)
+{
+ return sh7751_pcic_init(&sh7751_pci_map);
+}
diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c
index eeea157..f221608 100644
--- a/arch/sh/drivers/pci/ops-r7780rp.c
+++ b/arch/sh/drivers/pci/ops-r7780rp.c
@@ -17,18 +17,25 @@
#include <asm/io.h>
#include "pci-sh4.h"
+static char r7780rp_irq_tab[] __initdata = {
+ 0, 1, 2, 3,
+};
+
+static char r7780mp_irq_tab[] __initdata = {
+ 65, 66, 67, 68,
+};
+
int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
{
- switch (slot) {
- case 0: return IRQ_PCISLOT1; /* PCI Interrupt #1 */
- case 1: return IRQ_PCISLOT2; /* PCI Interrupt #2 */
- case 2: return IRQ_PCISLOT3; /* PCI Interrupt #3 */
- case 3: return IRQ_PCISLOT4; /* PCI Interrupt E4 */
- default:
- printk(KERN_ERR "PCI: Bad IRQ mapping "
- "request for slot %d, func %d\n", slot, pin-1);
- return -1;
- }
+ if (mach_is_r7780rp())
+ return r7780rp_irq_tab[slot];
+ if (mach_is_r7780mp() || mach_is_r7785rp())
+ return r7780mp_irq_tab[slot];
+
+ printk(KERN_ERR "PCI: Bad IRQ mapping "
+ "request for slot %d, func %d\n", slot, pin-1);
+
+ return -1;
}
static struct resource sh7780_io_resource = {
diff --git a/arch/sh/drivers/pci/ops-se7780.c b/arch/sh/drivers/pci/ops-se7780.c
new file mode 100644
index 0000000..212674df
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-se7780.c
@@ -0,0 +1,96 @@
+/*
+ * linux/arch/sh/drivers/pci/ops-se7780.c
+ *
+ * Copyright (C) 2006 Nobuhiro Iwamatsu
+ *
+ * PCI initialization for the Hitachi UL Solution Engine 7780SE03
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <asm/se7780.h>
+#include <asm/io.h>
+#include "pci-sh4.h"
+
+/*
+ * IDSEL = AD16 PCI slot
+ * IDSEL = AD17 PCI slot
+ * IDSEL = AD18 Serial ATA Controller (Silicon Image SiL3512A)
+ * IDSEL = AD19 USB Host Controller (NEC uPD7210100A)
+ */
+
+/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */
+static char se7780_irq_tab[4][16] __initdata = {
+ /* INTA */
+ { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ /* INTB */
+ { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ /* INTC */
+ { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ /* INTD */
+ { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+};
+
+int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
+{
+ return se7780_irq_tab[pin-1][slot];
+}
+
+static struct resource se7780_io_resource = {
+ .name = "SH7780_IO",
+ .start = 0x2000,
+ .end = 0x2000 + SH7780_PCI_IO_SIZE - 1,
+ .flags = IORESOURCE_IO
+};
+
+static struct resource se7780_mem_resource = {
+ .name = "SH7780_mem",
+ .start = SH7780_PCI_MEMORY_BASE,
+ .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM
+};
+
+extern struct pci_ops se7780_pci_ops;
+
+struct pci_channel board_pci_channels[] = {
+ { &sh4_pci_ops, &se7780_io_resource, &se7780_mem_resource, 0, 0xff },
+ { NULL, NULL, NULL, 0, 0 },
+};
+EXPORT_SYMBOL(board_pci_channels);
+
+static struct sh4_pci_address_map se7780_pci_map = {
+ .window0 = {
+ .base = SH7780_CS2_BASE_ADDR,
+ .size = 0x04000000,
+ },
+ .flags = SH4_PCIC_NO_RESET,
+};
+
+int __init pcibios_init_platform(void)
+{
+ printk("SH7780 PCI: Finished initialization of the PCI controller\n");
+
+ /*
+ * FPGA PCISEL register initialize
+ *
+ * CPU || SLOT1 | SLOT2 | S-ATA | USB
+ * -------------------------------------
+ * INTA || INTA | INTD | -- | INTB
+ * -------------------------------------
+ * INTB || INTB | INTA | -- | INTC
+ * -------------------------------------
+ * INTC || INTC | INTB | INTA | --
+ * -------------------------------------
+ * INTD || INTD | INTC | -- | INTA
+ * -------------------------------------
+ */
+ ctrl_outw(0x0013, FPGA_PCI_INTSEL1);
+ ctrl_outw(0xE402, FPGA_PCI_INTSEL2);
+
+ return sh7780_pcic_init(&se7780_pci_map);
+}
diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c
index 2d437100..54232f1 100644
--- a/arch/sh/drivers/pci/ops-sh4.c
+++ b/arch/sh/drivers/pci/ops-sh4.c
@@ -162,3 +162,9 @@ char * __init pcibios_setup(char *str)
return str;
}
+
+int __attribute__((weak)) pci_fixup_pcic(void)
+{
+ /* Nothing to do. */
+ return 0;
+}
diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h
index 5a61d60..1901c33 100644
--- a/arch/sh/drivers/pci/pci-sh4.h
+++ b/arch/sh/drivers/pci/pci-sh4.h
@@ -1,7 +1,7 @@
#ifndef __PCI_SH4_H
#define __PCI_SH4_H
-#ifdef CONFIG_CPU_SUBTYPE_SH7780
+#if defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785)
#include "pci-sh7780.h"
#else
#include "pci-sh7751.h"
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
index 9ddff76..1aca7fe 100644
--- a/arch/sh/drivers/pci/pci-sh7751.c
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -12,7 +12,6 @@
* License. See linux/COPYING for more information.
*
*/
-
#undef DEBUG
#include <linux/init.h>
@@ -28,7 +27,7 @@
* Initialization. Try all known PCI access methods. Note that we support
* using both PCI BIOS and direct access: in such cases, we use I/O ports
* to access config space.
- *
+ *
* Note that the platform specific initialization (BSC registers, and memory
* space mapping) will be called via the platform defined function
* pcibios_init_platform().
@@ -115,7 +114,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
* Wait Cycle Control + Parity Enable + Bus Master +
* Mem space enable
*/
- word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER |
+ word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER |
SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES;
pci_write_reg(word, SH7751_PCICONF1);
@@ -123,10 +122,10 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
word = PCI_BASE_CLASS_BRIDGE << 24;
pci_write_reg(word, SH7751_PCICONF2);
- /* Set IO and Mem windows to local address
- * Make PCI and local address the same for easy 1 to 1 mapping
+ /* Set IO and Mem windows to local address
+ * Make PCI and local address the same for easy 1 to 1 mapping
* Window0 = map->window0.size @ non-cached area base = SDRAM
- * Window1 = map->window1.size @ cached area base = SDRAM
+ * Window1 = map->window1.size @ cached area base = SDRAM
*/
word = map->window0.size - 1;
pci_write_reg(word, SH4_PCILSR0);
@@ -175,7 +174,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(5); break;
case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(6); break;
}
-
+
if (!word)
return 0;
@@ -194,9 +193,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
* DMA interrupts...
*/
-#ifdef CONFIG_SH_RTS7751R2D
pci_fixup_pcic();
-#endif
/* SH7751 init done, set central function init complete */
/* use round robin mode to stop a device starving/overruning */
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index 602b644..5508e45 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -48,7 +48,7 @@
static int __init sh7780_pci_init(void)
{
unsigned int id;
- int ret;
+ int ret, match = 0;
pr_debug("PCI: Starting intialization.\n");
@@ -56,19 +56,43 @@ static int __init sh7780_pci_init(void)
/* check for SH7780/SH7780R hardware */
id = pci_read_reg(SH7780_PCIVID);
- if ((id != ((SH7780_DEVICE_ID << 16) | SH7780_VENDOR_ID)) &&
- (id != ((SH7781_DEVICE_ID << 16) | SH7780_VENDOR_ID))) {
+ if ((id & 0xffff) == SH7780_VENDOR_ID) {
+ switch ((id >> 16) & 0xffff) {
+ case SH7780_DEVICE_ID:
+ case SH7781_DEVICE_ID:
+ case SH7785_DEVICE_ID:
+ match = 1;
+ break;
+ }
+ }
+
+ if (unlikely(!match)) {
printk(KERN_ERR "PCI: This is not an SH7780 (%x)\n", id);
return -ENODEV;
}
/* Setup the INTC */
- ctrl_outl(0x00200000, INTC_ICR0); /* INTC SH-4 Mode */
- ctrl_outl(0x00078000, INTC_INT2MSKCR); /* enable PCIINTA - PCIINTD */
- ctrl_outl(0x40000000, INTC_INTMSK1); /* disable IRL4-7 Interrupt */
- ctrl_outl(0x0000fffe, INTC_INTMSK2); /* disable IRL4-7 Interrupt */
- ctrl_outl(0x80000000, INTC_INTMSKCLR1); /* enable IRL0-3 Interrupt */
- ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); /* enable IRL0-3 Interrupt */
+ if (mach_is_7780se()) {
+ /* ICR0: IRL=use separately */
+ ctrl_outl(0x00C00020, INTC_ICR0);
+ /* ICR1: detect low level(for 2ndcut) */
+ ctrl_outl(0xAAAA0000, INTC_ICR1);
+ /* INTPRI: priority=3(all) */
+ ctrl_outl(0x33333333, INTC_INTPRI);
+ } else {
+ /* INTC SH-4 Mode */
+ ctrl_outl(0x00200000, INTC_ICR0);
+ /* enable PCIINTA - PCIINTD */
+ ctrl_outl(0x00078000, INTC_INT2MSKCR);
+ /* disable IRL4-7 Interrupt */
+ ctrl_outl(0x40000000, INTC_INTMSK1);
+ /* disable IRL4-7 Interrupt */
+ ctrl_outl(0x0000fffe, INTC_INTMSK2);
+ /* enable IRL0-3 Interrupt */
+ ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+ /* enable IRL0-3 Interrupt */
+ ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
+ }
if ((ret = sh4_pci_check_direct()) != 0)
return ret;
@@ -138,9 +162,8 @@ int __init sh7780_pcic_init(struct sh4_pci_address_map *map)
* DMA interrupts...
*/
-#ifdef CONFIG_SH_R7780RP
+ /* Apply any last-minute PCIC fixups */
pci_fixup_pcic();
-#endif
/* SH7780 init done, set central function init complete */
/* use round robin mode to stop a device starving/overruning */
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h
index f02d218..00d12d0 100644
--- a/arch/sh/drivers/pci/pci-sh7780.h
+++ b/arch/sh/drivers/pci/pci-sh7780.h
@@ -14,8 +14,9 @@
/* Platform Specific Values */
#define SH7780_VENDOR_ID 0x1912
-#define SH7780_DEVICE_ID 0x0002
#define SH7781_DEVICE_ID 0x0001
+#define SH7780_DEVICE_ID 0x0002
+#define SH7785_DEVICE_ID 0x0007
/* SH7780 Control Registers */
#define SH7780_PCI_VCR0 0xFE000000
@@ -65,6 +66,22 @@
#define SH7780_PCIPMCSR_BSE 0x046
#define SH7780_PCICDD 0x047
+#define SH7780_PCICR 0x100 /* PCI Control Register */
+#define SH7780_PCILSR 0x104 /* PCI Local Space Register0 */
+#define SH7780_PCILSR1 0x108 /* PCI Local Space Register1 */
+#define SH7780_PCILAR0 0x10C /* PCI Local Address Register1 */
+#define SH7780_PCILAR1 0x110 /* PCI Local Address Register1 */
+#define SH7780_PCIIR 0x114 /* PCI Interrupt Register */
+#define SH7780_PCIIMR 0x118 /* PCI Interrupt Mask Register */
+#define SH7780_PCIAIR 0x11C /* Error Address Register */
+#define SH7780_PCICIR 0x120 /* Error Command/Data Register */
+#define SH7780_PCIAINT 0x130 /* Arbiter Interrupt Register */
+#define SH7780_PCIAINTM 0x134 /* Arbiter Int. Mask Register */
+#define SH7780_PCIBMIR 0x138 /* Error Bus Master Register */
+#define SH7780_PCIPAR 0x1C0 /* PIO Address Register */
+#define SH7780_PCIPINT 0x1CC /* Power Mgmnt Int. Register */
+#define SH7780_PCIPINTM 0x1D0 /* Power Mgmnt Mask Register */
+
#define SH7780_PCIMBR0 0x1E0
#define SH7780_PCIMBMR0 0x1E4
#define SH7780_PCIMBR2 0x1F0
diff --git a/arch/sh/drivers/pci/pci-st40.c b/arch/sh/drivers/pci/pci-st40.c
index efecb3d..d67656a 100644
--- a/arch/sh/drivers/pci/pci-st40.c
+++ b/arch/sh/drivers/pci/pci-st40.c
@@ -9,7 +9,6 @@
#include <linux/kernel.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/pci.h>
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index ff30d7f..9104b62 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -20,5 +20,6 @@ obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c
index 3e5fa1e..0758d48 100644
--- a/arch/sh/kernel/cf-enabler.c
+++ b/arch/sh/kernel/cf-enabler.c
@@ -29,7 +29,7 @@
* 0xB8001000 : Common Memory
* 0xBA000000 : I/O
*/
-#if defined(CONFIG_IDE) && defined(CONFIG_CPU_SH4)
+#if defined(CONFIG_CPU_SH4)
/* SH4 can't access PCMCIA interface through P2 area.
* we must remap it with appropreate attribute bit of the page set.
* this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */
@@ -71,7 +71,7 @@ static int __init cf_init_default(void)
/* You must have enabled the card, and set the level interrupt
* before reaching this point. Possibly in boot ROM or boot loader.
*/
-#if defined(CONFIG_IDE) && defined(CONFIG_CPU_SH4)
+#if defined(CONFIG_CPU_SH4)
allocate_cf_area();
#endif
#if defined(CONFIG_SH_UNKNOWN)
@@ -84,15 +84,25 @@ static int __init cf_init_default(void)
#if defined(CONFIG_SH_SOLUTION_ENGINE)
#include <asm/se.h>
+#elif defined(CONFIG_SH_7722_SOLUTION_ENGINE)
+#include <asm/se7722.h>
+#endif
/*
- * SolutionEngine
+ * SolutionEngine Seriese
*
+ * about MS770xSE
* 0xB8400000 : Common Memory
* 0xB8500000 : Attribute
* 0xB8600000 : I/O
+ *
+ * about MS7722SE
+ * 0xB0400000 : Common Memory
+ * 0xB0500000 : Attribute
+ * 0xB0600000 : I/O
*/
+#if defined(CONFIG_SH_SOLUTION_ENGINE) || defined(CONFIG_SH_7722_SOLUTION_ENGINE)
static int __init cf_init_se(void)
{
if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0)
@@ -109,7 +119,7 @@ static int __init cf_init_se(void)
* flag == COMMON/ATTRIBUTE/IO
*/
/* common window open */
- ctrl_outw(0x8a84, MRSHPC_MW0CR1);/* window 0xb8400000 */
+ ctrl_outw(0x8a84, MRSHPC_MW0CR1);
if((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
/* common mode & bus width 16bit SWAP = 1*/
ctrl_outw(0x0b00, MRSHPC_MW0CR2);
@@ -118,7 +128,7 @@ static int __init cf_init_se(void)
ctrl_outw(0x0300, MRSHPC_MW0CR2);
/* attribute window open */
- ctrl_outw(0x8a85, MRSHPC_MW1CR1);/* window 0xb8500000 */
+ ctrl_outw(0x8a85, MRSHPC_MW1CR1);
if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
/* attribute mode & bus width 16bit SWAP = 1*/
ctrl_outw(0x0a00, MRSHPC_MW1CR2);
@@ -127,7 +137,7 @@ static int __init cf_init_se(void)
ctrl_outw(0x0200, MRSHPC_MW1CR2);
/* I/O window open */
- ctrl_outw(0x8a86, MRSHPC_IOWCR1);/* I/O window 0xb8600000 */
+ ctrl_outw(0x8a86, MRSHPC_IOWCR1);
ctrl_outw(0x0008, MRSHPC_CDCR); /* I/O card mode */
if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0)
ctrl_outw(0x0a00, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 1*/
@@ -143,10 +153,10 @@ static int __init cf_init_se(void)
int __init cf_init(void)
{
-#if defined(CONFIG_SH_SOLUTION_ENGINE)
- if (MACH_SE)
+ if( mach_is_se() || mach_is_7722se() ){
return cf_init_se();
-#endif
+ }
+
return cf_init_default();
}
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index abb586b1..014f318 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -1,7 +1,7 @@
/*
* arch/sh/kernel/cpu/clock.c - SuperH clock framework
*
- * Copyright (C) 2005, 2006 Paul Mundt
+ * Copyright (C) 2005, 2006, 2007 Paul Mundt
*
* This clock framework is derived from the OMAP version by:
*
@@ -23,6 +23,7 @@
#include <linux/seq_file.h>
#include <linux/err.h>
#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
#include <asm/clock.h>
#include <asm/timer.h>
@@ -98,15 +99,17 @@ int __clk_enable(struct clk *clk)
if (clk->ops && clk->ops->init)
clk->ops->init(clk);
+ kref_get(&clk->kref);
+
if (clk->flags & CLK_ALWAYS_ENABLED)
return 0;
if (likely(clk->ops && clk->ops->enable))
clk->ops->enable(clk);
- kref_get(&clk->kref);
return 0;
}
+EXPORT_SYMBOL_GPL(__clk_enable);
int clk_enable(struct clk *clk)
{
@@ -119,6 +122,7 @@ int clk_enable(struct clk *clk)
return ret;
}
+EXPORT_SYMBOL_GPL(clk_enable);
static void clk_kref_release(struct kref *kref)
{
@@ -127,11 +131,17 @@ static void clk_kref_release(struct kref *kref)
void __clk_disable(struct clk *clk)
{
+ int count = kref_put(&clk->kref, clk_kref_release);
+
if (clk->flags & CLK_ALWAYS_ENABLED)
return;
- kref_put(&clk->kref, clk_kref_release);
+ if (!count) { /* count reaches zero, disable the clock */
+ if (likely(clk->ops && clk->ops->disable))
+ clk->ops->disable(clk);
+ }
}
+EXPORT_SYMBOL_GPL(__clk_disable);
void clk_disable(struct clk *clk)
{
@@ -141,6 +151,7 @@ void clk_disable(struct clk *clk)
__clk_disable(clk);
spin_unlock_irqrestore(&clock_lock, flags);
}
+EXPORT_SYMBOL_GPL(clk_disable);
int clk_register(struct clk *clk)
{
@@ -151,8 +162,18 @@ int clk_register(struct clk *clk)
mutex_unlock(&clock_list_sem);
+ if (clk->flags & CLK_ALWAYS_ENABLED) {
+ pr_debug( "Clock '%s' is ALWAYS_ENABLED\n", clk->name);
+ if (clk->ops && clk->ops->init)
+ clk->ops->init(clk);
+ if (clk->ops && clk->ops->enable)
+ clk->ops->enable(clk);
+ pr_debug( "Enabled.");
+ }
+
return 0;
}
+EXPORT_SYMBOL_GPL(clk_register);
void clk_unregister(struct clk *clk)
{
@@ -160,21 +181,29 @@ void clk_unregister(struct clk *clk)
list_del(&clk->node);
mutex_unlock(&clock_list_sem);
}
+EXPORT_SYMBOL_GPL(clk_unregister);
-inline unsigned long clk_get_rate(struct clk *clk)
+unsigned long clk_get_rate(struct clk *clk)
{
return clk->rate;
}
+EXPORT_SYMBOL_GPL(clk_get_rate);
int clk_set_rate(struct clk *clk, unsigned long rate)
{
+ return clk_set_rate_ex(clk, rate, 0);
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
+{
int ret = -EOPNOTSUPP;
if (likely(clk->ops && clk->ops->set_rate)) {
unsigned long flags;
spin_lock_irqsave(&clock_lock, flags);
- ret = clk->ops->set_rate(clk, rate);
+ ret = clk->ops->set_rate(clk, rate, algo_id);
spin_unlock_irqrestore(&clock_lock, flags);
}
@@ -183,6 +212,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
return ret;
}
+EXPORT_SYMBOL_GPL(clk_set_rate_ex);
void clk_recalc_rate(struct clk *clk)
{
@@ -197,6 +227,7 @@ void clk_recalc_rate(struct clk *clk)
if (unlikely(clk->flags & CLK_RATE_PROPAGATES))
propagate_rate(clk);
}
+EXPORT_SYMBOL_GPL(clk_recalc_rate);
/*
* Returns a clock. Note that we first try to use device id on the bus
@@ -233,18 +264,43 @@ found:
return clk;
}
+EXPORT_SYMBOL_GPL(clk_get);
void clk_put(struct clk *clk)
{
if (clk && !IS_ERR(clk))
module_put(clk->owner);
}
+EXPORT_SYMBOL_GPL(clk_put);
void __init __attribute__ ((weak))
arch_init_clk_ops(struct clk_ops **ops, int type)
{
}
+static int show_clocks(char *buf, char **start, off_t off,
+ int len, int *eof, void *data)
+{
+ struct clk *clk;
+ char *p = buf;
+
+ list_for_each_entry_reverse(clk, &clock_list, node) {
+ unsigned long rate = clk_get_rate(clk);
+
+ /*
+ * Don't bother listing dummy clocks with no ancestry
+ * that only support enable and disable ops.
+ */
+ if (unlikely(!rate && !clk->parent))
+ continue;
+
+ p += sprintf(p, "%-12s\t: %ld.%02ldMHz\n", clk->name,
+ rate / 1000000, (rate % 1000000) / 10000);
+ }
+
+ return p - buf;
+}
+
int __init clk_init(void)
{
int i, ret = 0;
@@ -256,7 +312,6 @@ int __init clk_init(void)
arch_init_clk_ops(&clk->ops, i);
ret |= clk_register(clk);
- clk_enable(clk);
}
/* Kick the child clocks.. */
@@ -266,35 +321,14 @@ int __init clk_init(void)
return ret;
}
-int show_clocks(struct seq_file *m)
+static int __init clk_proc_init(void)
{
- struct clk *clk;
-
- list_for_each_entry_reverse(clk, &clock_list, node) {
- unsigned long rate = clk_get_rate(clk);
-
- /*
- * Don't bother listing dummy clocks with no ancestry
- * that only support enable and disable ops.
- */
- if (unlikely(!rate && !clk->parent))
- continue;
-
- seq_printf(m, "%-12s\t: %ld.%02ldMHz\n", clk->name,
- rate / 1000000, (rate % 1000000) / 10000);
- }
+ struct proc_dir_entry *p;
+ p = create_proc_read_entry("clocks", S_IRUSR, NULL,
+ show_clocks, NULL);
+ if (unlikely(!p))
+ return -EINVAL;
return 0;
}
-
-EXPORT_SYMBOL_GPL(clk_register);
-EXPORT_SYMBOL_GPL(clk_unregister);
-EXPORT_SYMBOL_GPL(clk_get);
-EXPORT_SYMBOL_GPL(clk_put);
-EXPORT_SYMBOL_GPL(clk_enable);
-EXPORT_SYMBOL_GPL(clk_disable);
-EXPORT_SYMBOL_GPL(__clk_enable);
-EXPORT_SYMBOL_GPL(__clk_disable);
-EXPORT_SYMBOL_GPL(clk_get_rate);
-EXPORT_SYMBOL_GPL(clk_set_rate);
-EXPORT_SYMBOL_GPL(clk_recalc_rate);
+subsys_initcall(clk_proc_init);
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 726acfc..6451ad6 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -41,6 +41,23 @@ __setup("no" __stringify(x), x##_setup);
onchip_setup(fpu);
onchip_setup(dsp);
+#ifdef CONFIG_SPECULATIVE_EXECUTION
+#define CPUOPM 0xff2f0000
+#define CPUOPM_RABD (1 << 5)
+
+static void __init speculative_execution_init(void)
+{
+ /* Clear RABD */
+ ctrl_outl(ctrl_inl(CPUOPM) & ~CPUOPM_RABD, CPUOPM);
+
+ /* Flush the update */
+ (void)ctrl_inl(CPUOPM);
+ ctrl_barrier();
+}
+#else
+#define speculative_execution_init() do { } while (0)
+#endif
+
/*
* Generic first-level cache init
*/
@@ -261,4 +278,6 @@ asmlinkage void __init sh_cpu_init(void)
*/
ubc_wakeup();
#endif
+
+ speculative_execution_init();
}
diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile
index 0049d21..1c23308 100644
--- a/arch/sh/kernel/cpu/irq/Makefile
+++ b/arch/sh/kernel/cpu/irq/Makefile
@@ -4,6 +4,6 @@
obj-y += imask.o
obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o
-obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o
+obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o
obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o
obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o
diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c
index 74defe7..d8e22f4 100644
--- a/arch/sh/kernel/cpu/irq/intc2.c
+++ b/arch/sh/kernel/cpu/irq/intc2.c
@@ -18,7 +18,8 @@
#define INTC2_BASE 0xfe080000
#define INTC2_INTMSK (INTC2_BASE + 0x40)
#define INTC2_INTMSKCLR (INTC2_BASE + 0x60)
-#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7785)
#define INTC2_BASE 0xffd40000
#define INTC2_INTMSK (INTC2_BASE + 0x38)
#define INTC2_INTMSKCLR (INTC2_BASE + 0x3c)
diff --git a/arch/sh/kernel/cpu/irq/pint.c b/arch/sh/kernel/cpu/irq/pint.c
index f600077..6760268 100644
--- a/arch/sh/kernel/cpu/irq/pint.c
+++ b/arch/sh/kernel/cpu/irq/pint.c
@@ -18,6 +18,58 @@
#include <asm/io.h>
#include <asm/machvec.h>
+#if defined(CONFIG_CPU_SUBTYPE_SH7705)
+#define INTC_INTER 0xA4000014UL
+#define INTC_IPRD 0xA4000018UL
+#define INTC_ICR2 0xA4000012UL
+
+/* PFC */
+#define PORT_PACR 0xA4000100UL
+#define PORT_PBCR 0xA4000102UL
+#define PORT_PCCR 0xA4000104UL
+#define PORT_PDCR 0xA4000106UL
+#define PORT_PECR 0xA4000108UL
+#define PORT_PFCR 0xA400010AUL
+#define PORT_PGCR 0xA400010CUL
+#define PORT_PHCR 0xA400010EUL
+#define PORT_PJCR 0xA4000110UL
+#define PORT_PKCR 0xA4000112UL
+#define PORT_PLCR 0xA4000114UL
+#define PORT_PMCR 0xA4000118UL
+#define PORT_PNCR 0xA400011AUL
+#define PORT_PECR2 0xA4050148UL
+#define PORT_PFCR2 0xA405014AUL
+#define PORT_PNCR2 0xA405015AUL
+
+/* I/O port */
+#define PORT_PADR 0xA4000120UL
+#define PORT_PBDR 0xA4000122UL
+#define PORT_PCDR 0xA4000124UL
+#define PORT_PDDR 0xA4000126UL
+#define PORT_PEDR 0xA4000128UL
+#define PORT_PFDR 0xA400012AUL
+#define PORT_PGDR 0xA400012CUL
+#define PORT_PHDR 0xA400012EUL
+#define PORT_PJDR 0xA4000130UL
+#define PORT_PKDR 0xA4000132UL
+#define PORT_PLDR 0xA4000134UL
+#define PORT_PMDR 0xA4000138UL
+#define PORT_PNDR 0xA400013AUL
+
+#define PINT0_IRQ 40
+#define PINT8_IRQ 41
+#define PINT_IRQ_BASE 86
+
+#define PINT0_IPR_ADDR INTC_IPRD
+#define PINT0_IPR_POS 3
+#define PINT0_PRIORITY 2
+
+#define PINT8_IPR_ADDR INTC_IPRD
+#define PINT8_IPR_POS 2
+#define PINT8_PRIORITY 2
+
+#endif /* CONFIG_CPU_SUBTYPE_SH7705 */
+
static unsigned char pint_map[256];
static unsigned long portcr_mask;
@@ -126,7 +178,7 @@ int ipr_irq_demux(int irq)
unsigned long creg, dreg, d, sav;
if (irq == PINT0_IRQ) {
-#if defined(CONFIG_CPU_SUBTYPE_SH7707)
+#if defined(CONFIG_CPU_SUBTYPE_SH7705) || defined(CONFIG_CPU_SUBTYPE_SH7707)
creg = PORT_PACR;
dreg = PORT_PADR;
#else
@@ -144,7 +196,7 @@ int ipr_irq_demux(int irq)
return PINT_IRQ_BASE + pint_map[d];
} else if (irq == PINT8_IRQ) {
-#if defined(CONFIG_CPU_SUBTYPE_SH7707)
+#if defined(CONFIG_CPU_SUBTYPE_SH7705) || defined(CONFIG_CPU_SUBTYPE_SH7707)
creg = PORT_PBCR;
dreg = PORT_PBDR;
#else
diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile
index 83905e4..09faa05 100644
--- a/arch/sh/kernel/cpu/sh3/Makefile
+++ b/arch/sh/kernel/cpu/sh3/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh7708.o
obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh7709.o
obj-$(CONFIG_CPU_SUBTYPE_SH7300) += setup-sh7300.o
obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o
# Primary on-chip clocks (common)
clock-$(CONFIG_CPU_SH3) := clock-sh3.o
diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c
index 821b0ab..647623b 100644
--- a/arch/sh/kernel/cpu/sh3/probe.c
+++ b/arch/sh/kernel/cpu/sh3/probe.c
@@ -78,6 +78,9 @@ int __init detect_cpu_and_cache_system(void)
#if defined(CONFIG_CPU_SUBTYPE_SH7710)
current_cpu_data.type = CPU_SH7710;
#endif
+#if defined(CONFIG_CPU_SUBTYPE_SH7712)
+ current_cpu_data.type = CPU_SH7712;
+#endif
#if defined(CONFIG_CPU_SUBTYPE_SH7705)
current_cpu_data.type = CPU_SH7705;
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index a8e41c5..1983fb7 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -2,6 +2,7 @@
* SH7705 Setup
*
* Copyright (C) 2006 Paul Mundt
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -14,15 +15,15 @@
static struct plat_sci_port sci_platform_data[] = {
{
- .mapbase = 0xa4400000,
+ .mapbase = 0xa4410000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 52, 53, 55, 54 },
+ .irqs = { 56, 57, 59 },
}, {
- .mapbase = 0xa4410000,
+ .mapbase = 0xa4400000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 56, 57, 59, 58 },
+ .irqs = { 52, 53, 55 },
}, {
.flags = 0,
}
@@ -46,3 +47,48 @@ static int __init sh7705_devices_setup(void)
ARRAY_SIZE(sh7705_devices));
}
__initcall(sh7705_devices_setup);
+
+static struct ipr_data sh7705_ipr_map[] = {
+ /* IRQ, IPR-idx, shift, priority */
+ { 16, 0, 12, 2 }, /* TMU0 TUNI*/
+ { 17, 0, 8, 2 }, /* TMU1 TUNI */
+ { 18, 0, 4, 2 }, /* TMU2 TUNI */
+ { 27, 1, 12, 2 }, /* WDT ITI */
+ { 20, 0, 0, 2 }, /* RTC ATI (alarm) */
+ { 21, 0, 0, 2 }, /* RTC PRI (period) */
+ { 22, 0, 0, 2 }, /* RTC CUI (carry) */
+ { 48, 4, 12, 7 }, /* DMAC DMTE0 */
+ { 49, 4, 12, 7 }, /* DMAC DMTE1 */
+ { 50, 4, 12, 7 }, /* DMAC DMTE2 */
+ { 51, 4, 12, 7 }, /* DMAC DMTE3 */
+ { 52, 4, 8, 3 }, /* SCIF0 ERI */
+ { 53, 4, 8, 3 }, /* SCIF0 RXI */
+ { 55, 4, 8, 3 }, /* SCIF0 TXI */
+ { 56, 4, 4, 3 }, /* SCIF1 ERI */
+ { 57, 4, 4, 3 }, /* SCIF1 RXI */
+ { 59, 4, 4, 3 }, /* SCIF1 TXI */
+};
+
+static unsigned long ipr_offsets[] = {
+ 0xFFFFFEE2 /* 0: IPRA */
+, 0xFFFFFEE4 /* 1: IPRB */
+, 0xA4000016 /* 2: IPRC */
+, 0xA4000018 /* 3: IPRD */
+, 0xA400001A /* 4: IPRE */
+, 0xA4080000 /* 5: IPRF */
+, 0xA4080002 /* 6: IPRG */
+, 0xA4080004 /* 7: IPRH */
+};
+
+/* given the IPR index return the address of the IPR register */
+unsigned int map_ipridx_to_addr(int idx)
+{
+ if (idx >= ARRAY_SIZE(ipr_offsets))
+ return 0;
+ return ipr_offsets[idx];
+}
+
+void __init init_IRQ_ipr()
+{
+ make_ipr_irq(sh7705_ipr_map, ARRAY_SIZE(sh7705_ipr_map));
+}
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/arch/sh/kernel/cpu/sh3/setup-sh7709.c
index dc9b211..c7d7c35 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7709.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7709.c
@@ -48,24 +48,33 @@ static struct platform_device *sh7709_devices[] __initdata = {
static int __init sh7709_devices_setup(void)
{
return platform_add_devices(sh7709_devices,
- ARRAY_SIZE(sh7709_devices));
+ ARRAY_SIZE(sh7709_devices));
}
__initcall(sh7709_devices_setup);
-#define IPRx(A,N) .addr=A, .shift=0*N*-1
+#define IPRx(A,N) .addr=A, .shift=N
#define IPRA(N) IPRx(0xfffffee2UL,N)
#define IPRB(N) IPRx(0xfffffee4UL,N)
+#define IPRC(N) IPRx(0xa4000016UL,N)
+#define IPRD(N) IPRx(0xa4000018UL,N)
#define IPRE(N) IPRx(0xa400001aUL,N)
static struct ipr_data sh7709_ipr_map[] = {
- [16] = { IPRA(15-12), 2 }, /* TMU TUNI0 */
- [17] = { IPRA(11-8), 4 }, /* TMU TUNI1 */
- [22] = { IPRA(3-0), 2 }, /* RTC CUI */
- [23 ... 26] = { IPRB(7-4), 3 }, /* SCI */
- [27] = { IPRB(15-12), 2 }, /* WDT ITI */
- [48 ... 51] = { IPRE(15-12), 7 }, /* DMA */
- [52 ... 55] = { IPRE(11-8), 3 }, /* IRDA */
- [56 ... 59] = { IPRE(7-4), 3 }, /* SCIF */
+ [16] = { IPRA(12), 2 }, /* TMU TUNI0 */
+ [17] = { IPRA(8), 4 }, /* TMU TUNI1 */
+ [18 ... 19] = { IPRA(4), 1 }, /* TMU TUNI1 */
+ [20 ... 22] = { IPRA(0), 2 }, /* RTC CUI */
+ [23 ... 26] = { IPRB(4), 3 }, /* SCI */
+ [27] = { IPRB(12), 2 }, /* WDT ITI */
+ [32] = { IPRC(0), 1 }, /* IRQ 0 */
+ [33] = { IPRC(4), 1 }, /* IRQ 1 */
+ [34] = { IPRC(8), 1 }, /* IRQ 2 APM */
+ [35] = { IPRC(12), 1 }, /* IRQ 3 TOUCHSCREEN */
+ [36] = { IPRD(0), 1 }, /* IRQ 4 */
+ [37] = { IPRD(4), 1 }, /* IRQ 5 */
+ [48 ... 51] = { IPRE(12), 7 }, /* DMA */
+ [52 ... 55] = { IPRE(8), 3 }, /* IRDA */
+ [56 ... 59] = { IPRE(4), 3 }, /* SCIF */
};
void __init init_IRQ_ipr()
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 895f99e..51760a7 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -2,6 +2,7 @@
* SH7710 Setup
*
* Copyright (C) 2006 Paul Mundt
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -19,6 +20,12 @@ static struct plat_sci_port sci_platform_data[] = {
.type = PORT_SCIF,
.irqs = { 52, 53, 55, 54 },
}, {
+ .mapbase = 0xa4420000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 56, 57, 59, 58 },
+ }, {
+
.flags = 0,
}
};
@@ -41,3 +48,56 @@ static int __init sh7710_devices_setup(void)
ARRAY_SIZE(sh7710_devices));
}
__initcall(sh7710_devices_setup);
+
+static struct ipr_data sh7710_ipr_map[] = {
+ /* IRQ, IPR-idx, shift, priority */
+ { 16, 0, 12, 2 }, /* TMU0 TUNI*/
+ { 17, 0, 8, 2 }, /* TMU1 TUNI */
+ { 18, 0, 4, 2 }, /* TMU2 TUNI */
+ { 27, 1, 12, 2 }, /* WDT ITI */
+ { 20, 0, 0, 2 }, /* RTC ATI (alarm) */
+ { 21, 0, 0, 2 }, /* RTC PRI (period) */
+ { 22, 0, 0, 2 }, /* RTC CUI (carry) */
+ { 48, 4, 12, 7 }, /* DMAC DMTE0 */
+ { 49, 4, 12, 7 }, /* DMAC DMTE1 */
+ { 50, 4, 12, 7 }, /* DMAC DMTE2 */
+ { 51, 4, 12, 7 }, /* DMAC DMTE3 */
+ { 52, 4, 8, 3 }, /* SCIF0 ERI */
+ { 53, 4, 8, 3 }, /* SCIF0 RXI */
+ { 54, 4, 8, 3 }, /* SCIF0 BRI */
+ { 55, 4, 8, 3 }, /* SCIF0 TXI */
+ { 56, 4, 4, 3 }, /* SCIF1 ERI */
+ { 57, 4, 4, 3 }, /* SCIF1 RXI */
+ { 58, 4, 4, 3 }, /* SCIF1 BRI */
+ { 59, 4, 4, 3 }, /* SCIF1 TXI */
+ { 76, 5, 8, 7 }, /* DMAC DMTE4 */
+ { 77, 5, 8, 7 }, /* DMAC DMTE5 */
+ { 80, 6, 12, 5 }, /* EDMAC EINT0 */
+ { 81, 6, 8, 5 }, /* EDMAC EINT1 */
+ { 82, 6, 4, 5 }, /* EDMAC EINT2 */
+};
+
+static unsigned long ipr_offsets[] = {
+ 0xA414FEE2 /* 0: IPRA */
+, 0xA414FEE4 /* 1: IPRB */
+, 0xA4140016 /* 2: IPRC */
+, 0xA4140018 /* 3: IPRD */
+, 0xA414001A /* 4: IPRE */
+, 0xA4080000 /* 5: IPRF */
+, 0xA4080002 /* 6: IPRG */
+, 0xA4080004 /* 7: IPRH */
+, 0xA4080006 /* 8: IPRI */
+};
+
+/* given the IPR index return the address of the IPR register */
+unsigned int map_ipridx_to_addr(int idx)
+{
+ if (idx >= ARRAY_SIZE(ipr_offsets))
+ return 0;
+ return ipr_offsets[idx];
+}
+
+void __init init_IRQ_ipr()
+{
+ make_ipr_irq(sh7710_ipr_map, ARRAY_SIZE(sh7710_ipr_map));
+}
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
index fa2019a..fcb2c41b 100644
--- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
@@ -82,7 +82,8 @@ static void shoc_clk_init(struct clk *clk)
for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) {
int divisor = frqcr3_divisors[i];
- if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0)
+ if (clk->ops->set_rate(clk, clk->parent->rate /
+ divisor, 0) == 0)
break;
}
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 58950de..8cd0490 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -124,6 +124,14 @@ int __init detect_cpu_and_cache_system(void)
current_cpu_data.dcache.ways = 4;
current_cpu_data.flags |= CPU_HAS_LLSC;
break;
+ case 0x3004:
+ case 0x3007:
+ current_cpu_data.type = CPU_SH7785;
+ current_cpu_data.icache.ways = 4;
+ current_cpu_data.dcache.ways = 4;
+ current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
+ CPU_HAS_LLSC;
+ break;
case 0x3008:
if (prr == 0xa0) {
current_cpu_data.type = CPU_SH7722;
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index a8f493f..ab7422f 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -5,6 +5,7 @@
# CPU subtype setup
obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o
obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o
obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o
obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o
obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o
@@ -13,7 +14,8 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o
clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o
clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o
clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7343.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o
obj-y += $(clock-y)
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
new file mode 100644
index 0000000..2909003
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -0,0 +1,600 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+ *
+ * SH7722 support for the clock framework
+ *
+ * Copyright (c) 2006-2007 Nomad Global Solutions Inc
+ * Based on code for sh7343 by Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+
+#define SH7722_PLL_FREQ (32000000/8)
+#define N (-1)
+#define NM (-2)
+#define ROUND_NEAREST 0
+#define ROUND_DOWN -1
+#define ROUND_UP +1
+
+static int adjust_algos[][3] = {
+ {}, /* NO_CHANGE */
+ { NM, N, 1 }, /* N:1, N:1 */
+ { 3, 2, 2 }, /* 3:2:2 */
+ { 5, 2, 2 }, /* 5:2:2 */
+ { N, 1, 1 }, /* N:1:1 */
+
+ { N, 1 }, /* N:1 */
+
+ { N, 1 }, /* N:1 */
+ { 3, 2 },
+ { 4, 3 },
+ { 5, 4 },
+
+ { N, 1 }
+};
+
+static unsigned long adjust_pair_of_clocks(unsigned long r1, unsigned long r2,
+ int m1, int m2, int round_flag)
+{
+ unsigned long rem, div;
+ int the_one = 0;
+
+ pr_debug( "Actual values: r1 = %ld\n", r1);
+ pr_debug( "...............r2 = %ld\n", r2);
+
+ if (m1 == m2) {
+ r2 = r1;
+ pr_debug( "setting equal rates: r2 now %ld\n", r2);
+ } else if ((m2 == N && m1 == 1) ||
+ (m2 == NM && m1 == N)) { /* N:1 or NM:N */
+ pr_debug( "Setting rates as 1:N (N:N*M)\n");
+ rem = r2 % r1;
+ pr_debug( "...remainder = %ld\n", rem);
+ if (rem) {
+ div = r2 / r1;
+ pr_debug( "...div = %ld\n", div);
+ switch (round_flag) {
+ case ROUND_NEAREST:
+ the_one = rem >= r1/2 ? 1 : 0; break;
+ case ROUND_UP:
+ the_one = 1; break;
+ case ROUND_DOWN:
+ the_one = 0; break;
+ }
+
+ r2 = r1 * (div + the_one);
+ pr_debug( "...setting r2 to %ld\n", r2);
+ }
+ } else if ((m2 == 1 && m1 == N) ||
+ (m2 == N && m1 == NM)) { /* 1:N or N:NM */
+ pr_debug( "Setting rates as N:1 (N*M:N)\n");
+ rem = r1 % r2;
+ pr_debug( "...remainder = %ld\n", rem);
+ if (rem) {
+ div = r1 / r2;
+ pr_debug( "...div = %ld\n", div);
+ switch (round_flag) {
+ case ROUND_NEAREST:
+ the_one = rem > r2/2 ? 1 : 0; break;
+ case ROUND_UP:
+ the_one = 0; break;
+ case ROUND_DOWN:
+ the_one = 1; break;
+ }
+
+ r2 = r1 / (div + the_one);
+ pr_debug( "...setting r2 to %ld\n", r2);
+ }
+ } else { /* value:value */
+ pr_debug( "Setting rates as %d:%d\n", m1, m2);
+ div = r1 / m1;
+ r2 = div * m2;
+ pr_debug( "...div = %ld\n", div);
+ pr_debug( "...setting r2 to %ld\n", r2);
+ }
+
+ return r2;
+}
+
+static void adjust_clocks(int originate, int *l, unsigned long v[],
+ int n_in_line)
+{
+ int x;
+
+ pr_debug( "Go down from %d...\n", originate);
+ /* go up recalculation clocks */
+ for (x = originate; x>0; x -- )
+ v[x-1] = adjust_pair_of_clocks(v[x], v[x-1],
+ l[x], l[x-1],
+ ROUND_UP);
+
+ pr_debug( "Go up from %d...\n", originate);
+ /* go down recalculation clocks */
+ for (x = originate; x<n_in_line - 1; x ++ )
+ v[x+1] = adjust_pair_of_clocks(v[x], v[x+1],
+ l[x], l[x+1],
+ ROUND_UP);
+}
+
+
+/*
+ * SH7722 uses a common set of multipliers and divisors, so this
+ * is quite simple..
+ */
+
+/*
+ * Instead of having two separate multipliers/divisors set, like this:
+ *
+ * static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+ * static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
+ *
+ * I created the divisors2 array, which is used to calculate rate like
+ * rate = parent * 2 / divisors2[ divisor ];
+*/
+static int divisors2[] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40 };
+
+static void master_clk_init(struct clk *clk)
+{
+ clk_set_rate(clk, clk_get_rate(clk));
+}
+
+static void master_clk_recalc(struct clk *clk)
+{
+ unsigned long frqcr = ctrl_inl(FRQCR);
+
+ clk->rate = CONFIG_SH_PCLK_FREQ * (1 + (frqcr >> 24 & 0xF));
+}
+
+static int master_clk_setrate(struct clk *clk, unsigned long rate, int id)
+{
+ int div = rate / SH7722_PLL_FREQ;
+ int master_divs[] = { 2, 3, 4, 6, 8, 16 };
+ int index;
+ unsigned long frqcr;
+
+ if (rate < SH7722_PLL_FREQ * 2)
+ return -EINVAL;
+
+ for (index = 1; index < ARRAY_SIZE(master_divs); index++)
+ if (div >= master_divs[index - 1] && div < master_divs[index])
+ break;
+
+ if (index >= ARRAY_SIZE(master_divs))
+ index = ARRAY_SIZE(master_divs);
+ div = master_divs[index - 1];
+
+ frqcr = ctrl_inl(FRQCR);
+ frqcr &= ~(0xF << 24);
+ frqcr |= ( (div-1) << 24);
+ ctrl_outl(frqcr, FRQCR);
+
+ return 0;
+}
+
+static struct clk_ops sh7722_master_clk_ops = {
+ .init = master_clk_init,
+ .recalc = master_clk_recalc,
+ .set_rate = master_clk_setrate,
+};
+
+struct frqcr_context {
+ unsigned mask;
+ unsigned shift;
+};
+
+struct frqcr_context sh7722_get_clk_context(const char *name)
+{
+ struct frqcr_context ctx = { 0, };
+
+ if (!strcmp(name, "peripheral_clk")) {
+ ctx.shift = 0;
+ ctx.mask = 0xF;
+ } else if (!strcmp(name, "sdram_clk")) {
+ ctx.shift = 4;
+ ctx.mask = 0xF;
+ } else if (!strcmp(name, "bus_clk")) {
+ ctx.shift = 8;
+ ctx.mask = 0xF;
+ } else if (!strcmp(name, "sh_clk")) {
+ ctx.shift = 12;
+ ctx.mask = 0xF;
+ } else if (!strcmp(name, "umem_clk")) {
+ ctx.shift = 16;
+ ctx.mask = 0xF;
+ } else if (!strcmp(name, "cpu_clk")) {
+ ctx.shift = 20;
+ ctx.mask = 7;
+ }
+ return ctx;
+}
+
+/**
+ * sh7722_find_divisors - find divisor for setting rate
+ *
+ * All sh7722 clocks use the same set of multipliers/divisors. This function
+ * chooses correct divisor to set the rate of clock with parent clock that
+ * generates frequency of 'parent_rate'
+ *
+ * @parent_rate: rate of parent clock
+ * @rate: requested rate to be set
+ */
+static int sh7722_find_divisors(unsigned long parent_rate, unsigned rate)
+{
+ unsigned div2 = parent_rate * 2 / rate;
+ int index;
+
+ if (rate > parent_rate)
+ return -EINVAL;
+
+ for (index = 1; index < ARRAY_SIZE(divisors2); index++) {
+ if (div2 > divisors2[index] && div2 <= divisors2[index])
+ break;
+ }
+ if (index >= ARRAY_SIZE(divisors2))
+ index = ARRAY_SIZE(divisors2) - 1;
+ return divisors2[index];
+}
+
+static void sh7722_frqcr_recalc(struct clk *clk)
+{
+ struct frqcr_context ctx = sh7722_get_clk_context(clk->name);
+ unsigned long frqcr = ctrl_inl(FRQCR);
+ int index;
+
+ index = (frqcr >> ctx.shift) & ctx.mask;
+ clk->rate = clk->parent->rate * 2 / divisors2[index];
+}
+
+static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate,
+ int algo_id)
+{
+ struct frqcr_context ctx = sh7722_get_clk_context(clk->name);
+ unsigned long parent_rate = clk->parent->rate;
+ int div;
+ unsigned long frqcr;
+ int err = 0;
+
+ /* pretty invalid */
+ if (parent_rate < rate)
+ return -EINVAL;
+
+ /* look for multiplier/divisor pair */
+ div = sh7722_find_divisors(parent_rate, rate);
+ if (div<0)
+ return div;
+
+ /* calculate new value of clock rate */
+ clk->rate = parent_rate * 2 / div;
+ frqcr = ctrl_inl(FRQCR);
+
+ /* FIXME: adjust as algo_id specifies */
+ if (algo_id != NO_CHANGE) {
+ int originator;
+ char *algo_group_1[] = { "cpu_clk", "umem_clk", "sh_clk" };
+ char *algo_group_2[] = { "sh_clk", "bus_clk" };
+ char *algo_group_3[] = { "sh_clk", "sdram_clk" };
+ char *algo_group_4[] = { "bus_clk", "peripheral_clk" };
+ char *algo_group_5[] = { "cpu_clk", "peripheral_clk" };
+ char **algo_current = NULL;
+ /* 3 is the maximum number of clocks in relation */
+ struct clk *ck[3];
+ unsigned long values[3]; /* the same comment as above */
+ int part_length = -1;
+ int i;
+
+ /*
+ * all the steps below only required if adjustion was
+ * requested
+ */
+ if (algo_id == IUS_N1_N1 ||
+ algo_id == IUS_322 ||
+ algo_id == IUS_522 ||
+ algo_id == IUS_N11) {
+ algo_current = algo_group_1;
+ part_length = 3;
+ }
+ if (algo_id == SB_N1) {
+ algo_current = algo_group_2;
+ part_length = 2;
+ }
+ if (algo_id == SB3_N1 ||
+ algo_id == SB3_32 ||
+ algo_id == SB3_43 ||
+ algo_id == SB3_54) {
+ algo_current = algo_group_3;
+ part_length = 2;
+ }
+ if (algo_id == BP_N1) {
+ algo_current = algo_group_4;
+ part_length = 2;
+ }
+ if (algo_id == IP_N1) {
+ algo_current = algo_group_5;
+ part_length = 2;
+ }
+ if (!algo_current)
+ goto incorrect_algo_id;
+
+ originator = -1;
+ for (i = 0; i < part_length; i ++ ) {
+ if (originator >= 0 && !strcmp(clk->name,
+ algo_current[i]))
+ originator = i;
+ ck[i] = clk_get(NULL, algo_current[i]);
+ values[i] = clk_get_rate(ck[i]);
+ }
+
+ if (originator >= 0)
+ adjust_clocks(originator, adjust_algos[algo_id],
+ values, part_length);
+
+ for (i = 0; i < part_length; i ++ ) {
+ struct frqcr_context part_ctx;
+ int part_div;
+
+ if (likely(!err)) {
+ part_div = sh7722_find_divisors(parent_rate,
+ rate);
+ if (part_div > 0) {
+ part_ctx = sh7722_get_clk_context(
+ ck[i]->name);
+ frqcr &= ~(part_ctx.mask <<
+ part_ctx.shift);
+ frqcr |= part_div << part_ctx.shift;
+ } else
+ err = part_div;
+ }
+
+ ck[i]->ops->recalc(ck[i]);
+ clk_put(ck[i]);
+ }
+ }
+
+ /* was there any error during recalculation ? If so, bail out.. */
+ if (unlikely(err!=0))
+ goto out_err;
+
+ /* clear FRQCR bits */
+ frqcr &= ~(ctx.mask << ctx.shift);
+ frqcr |= div << ctx.shift;
+
+ /* ...and perform actual change */
+ ctrl_outl(frqcr, FRQCR);
+ return 0;
+
+incorrect_algo_id:
+ return -EINVAL;
+out_err:
+ return err;
+}
+
+static struct clk_ops sh7722_frqcr_clk_ops = {
+ .recalc = sh7722_frqcr_recalc,
+ .set_rate = sh7722_frqcr_set_rate,
+};
+
+/*
+ * clock ops methods for SIU A/B and IrDA clock
+ *
+ */
+static int sh7722_siu_which(struct clk *clk)
+{
+ if (!strcmp(clk->name, "siu_a_clk"))
+ return 0;
+ if (!strcmp(clk->name, "siu_b_clk"))
+ return 1;
+ if (!strcmp(clk->name, "irda_clk"))
+ return 2;
+ return -EINVAL;
+}
+
+static unsigned long sh7722_siu_regs[] = {
+ [0] = SCLKACR,
+ [1] = SCLKBCR,
+ [2] = IrDACLKCR,
+};
+
+static int sh7722_siu_start_stop(struct clk *clk, int enable)
+{
+ int siu = sh7722_siu_which(clk);
+ unsigned long r;
+
+ if (siu < 0)
+ return siu;
+ BUG_ON(siu > 2);
+ r = ctrl_inl(sh7722_siu_regs[siu]);
+ if (enable)
+ ctrl_outl(r & ~(1 << 8), sh7722_siu_regs[siu]);
+ else
+ ctrl_outl(r | (1 << 8), sh7722_siu_regs[siu]);
+ return 0;
+}
+
+static void sh7722_siu_enable(struct clk *clk)
+{
+ sh7722_siu_start_stop(clk, 1);
+}
+
+static void sh7722_siu_disable(struct clk *clk)
+{
+ sh7722_siu_start_stop(clk, 0);
+}
+
+static void sh7722_video_enable(struct clk *clk)
+{
+ unsigned long r;
+
+ r = ctrl_inl(VCLKCR);
+ ctrl_outl( r & ~(1<<8), VCLKCR);
+}
+
+static void sh7722_video_disable(struct clk *clk)
+{
+ unsigned long r;
+
+ r = ctrl_inl(VCLKCR);
+ ctrl_outl( r | (1<<8), VCLKCR);
+}
+
+static int sh7722_video_set_rate(struct clk *clk, unsigned long rate,
+ int algo_id)
+{
+ unsigned long r;
+
+ r = ctrl_inl(VCLKCR);
+ r &= ~0x3F;
+ r |= ((clk->parent->rate / rate - 1) & 0x3F);
+ ctrl_outl(r, VCLKCR);
+ return 0;
+}
+
+static void sh7722_video_recalc(struct clk *clk)
+{
+ unsigned long r;
+
+ r = ctrl_inl(VCLKCR);
+ clk->rate = clk->parent->rate / ((r & 0x3F) + 1);
+}
+
+static int sh7722_siu_set_rate(struct clk *clk, unsigned long rate, int algo_id)
+{
+ int siu = sh7722_siu_which(clk);
+ unsigned long r;
+ int div;
+
+ if (siu < 0)
+ return siu;
+ BUG_ON(siu > 2);
+ r = ctrl_inl(sh7722_siu_regs[siu]);
+ div = sh7722_find_divisors(clk->parent->rate, rate);
+ if (div < 0)
+ return div;
+ r = (r & ~0xF) | div;
+ ctrl_outl(r, sh7722_siu_regs[siu]);
+ return 0;
+}
+
+static void sh7722_siu_recalc(struct clk *clk)
+{
+ int siu = sh7722_siu_which(clk);
+ unsigned long r;
+
+ if (siu < 0)
+ return /* siu */ ;
+ BUG_ON(siu > 1);
+ r = ctrl_inl(sh7722_siu_regs[siu]);
+ clk->rate = clk->parent->rate * 2 / divisors2[r & 0xF];
+}
+
+static struct clk_ops sh7722_siu_clk_ops = {
+ .recalc = sh7722_siu_recalc,
+ .set_rate = sh7722_siu_set_rate,
+ .enable = sh7722_siu_enable,
+ .disable = sh7722_siu_disable,
+};
+
+static struct clk_ops sh7722_video_clk_ops = {
+ .recalc = sh7722_video_recalc,
+ .set_rate = sh7722_video_set_rate,
+ .enable = sh7722_video_enable,
+ .disable = sh7722_video_disable,
+};
+/*
+ * and at last, clock definitions themselves
+ */
+static struct clk sh7722_umem_clock = {
+ .name = "umem_clk",
+ .ops = &sh7722_frqcr_clk_ops,
+};
+
+static struct clk sh7722_sh_clock = {
+ .name = "sh_clk",
+ .ops = &sh7722_frqcr_clk_ops,
+};
+
+static struct clk sh7722_peripheral_clock = {
+ .name = "peripheral_clk",
+ .ops = &sh7722_frqcr_clk_ops,
+};
+
+static struct clk sh7722_sdram_clock = {
+ .name = "sdram_clk",
+ .ops = &sh7722_frqcr_clk_ops,
+};
+
+/*
+ * these three clocks - SIU A, SIU B, IrDA - share the same clk_ops
+ * methods of clk_ops determine which register they should access by
+ * examining clk->name field
+ */
+static struct clk sh7722_siu_a_clock = {
+ .name = "siu_a_clk",
+ .ops = &sh7722_siu_clk_ops,
+};
+
+static struct clk sh7722_siu_b_clock = {
+ .name = "siu_b_clk",
+ .ops = &sh7722_siu_clk_ops,
+};
+
+static struct clk sh7722_irda_clock = {
+ .name = "irda_clk",
+ .ops = &sh7722_siu_clk_ops,
+};
+
+static struct clk sh7722_video_clock = {
+ .name = "video_clk",
+ .ops = &sh7722_video_clk_ops,
+};
+
+static struct clk *sh7722_clocks[] = {
+ &sh7722_umem_clock,
+ &sh7722_sh_clock,
+ &sh7722_peripheral_clock,
+ &sh7722_sdram_clock,
+ &sh7722_siu_a_clock,
+ &sh7722_siu_b_clock,
+ &sh7722_irda_clock,
+ &sh7722_video_clock,
+};
+
+/*
+ * init in order: master, module, bus, cpu
+ */
+struct clk_ops *onchip_ops[] = {
+ &sh7722_master_clk_ops,
+ &sh7722_frqcr_clk_ops,
+ &sh7722_frqcr_clk_ops,
+ &sh7722_frqcr_clk_ops,
+};
+
+void __init
+arch_init_clk_ops(struct clk_ops **ops, int type)
+{
+ BUG_ON(type < 0 || type > ARRAY_SIZE(onchip_ops));
+ *ops = onchip_ops[type];
+}
+
+int __init sh7722_clock_init(void)
+{
+ struct clk *master;
+ int i;
+
+ master = clk_get(NULL, "master_clk");
+ for (i = 0; i < ARRAY_SIZE(sh7722_clocks); i++) {
+ pr_debug( "Registering clock '%s'\n", sh7722_clocks[i]->name);
+ sh7722_clocks[i]->parent = master;
+ clk_register(sh7722_clocks[i]);
+ }
+ clk_put(master);
+ return 0;
+}
+arch_initcall(sh7722_clock_init);
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
new file mode 100644
index 0000000..805535a
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
@@ -0,0 +1,162 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/clock-sh7785.c
+ *
+ * SH7785 support for the clock framework
+ *
+ * Copyright (C) 2007 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+#include <asm/io.h>
+
+static int ifc_divisors[] = { 1, 2, 4, 6 };
+static int ufc_divisors[] = { 1, 1, 4, 6 };
+static int sfc_divisors[] = { 1, 1, 4, 6 };
+static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18,
+ 24, 32, 36, 48, 1, 1, 1, 1 };
+static int mfc_divisors[] = { 1, 1, 4, 6 };
+static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18,
+ 24, 32, 36, 48, 1, 1, 1, 1 };
+
+static void master_clk_init(struct clk *clk)
+{
+ clk->rate *= 36;
+}
+
+static struct clk_ops sh7785_master_clk_ops = {
+ .init = master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+ int idx = (ctrl_inl(FRQMR1) & 0x000f);
+ clk->rate = clk->parent->rate / pfc_divisors[idx];
+}
+
+static struct clk_ops sh7785_module_clk_ops = {
+ .recalc = module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+ int idx = ((ctrl_inl(FRQMR1) >> 16) & 0x000f);
+ clk->rate = clk->parent->rate / bfc_divisors[idx];
+}
+
+static struct clk_ops sh7785_bus_clk_ops = {
+ .recalc = bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+ int idx = ((ctrl_inl(FRQMR1) >> 28) & 0x0003);
+ clk->rate = clk->parent->rate / ifc_divisors[idx];
+}
+
+static struct clk_ops sh7785_cpu_clk_ops = {
+ .recalc = cpu_clk_recalc,
+};
+
+static struct clk_ops *sh7785_clk_ops[] = {
+ &sh7785_master_clk_ops,
+ &sh7785_module_clk_ops,
+ &sh7785_bus_clk_ops,
+ &sh7785_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+ if (idx < ARRAY_SIZE(sh7785_clk_ops))
+ *ops = sh7785_clk_ops[idx];
+}
+
+static void shyway_clk_recalc(struct clk *clk)
+{
+ int idx = ((ctrl_inl(FRQMR1) >> 20) & 0x0003);
+ clk->rate = clk->parent->rate / sfc_divisors[idx];
+}
+
+static struct clk_ops sh7785_shyway_clk_ops = {
+ .recalc = shyway_clk_recalc,
+};
+
+static struct clk sh7785_shyway_clk = {
+ .name = "shyway_clk",
+ .flags = CLK_ALWAYS_ENABLED,
+ .ops = &sh7785_shyway_clk_ops,
+};
+
+static void ddr_clk_recalc(struct clk *clk)
+{
+ int idx = ((ctrl_inl(FRQMR1) >> 12) & 0x0003);
+ clk->rate = clk->parent->rate / mfc_divisors[idx];
+}
+
+static struct clk_ops sh7785_ddr_clk_ops = {
+ .recalc = ddr_clk_recalc,
+};
+
+static struct clk sh7785_ddr_clk = {
+ .name = "ddr_clk",
+ .flags = CLK_ALWAYS_ENABLED,
+ .ops = &sh7785_ddr_clk_ops,
+};
+
+static void ram_clk_recalc(struct clk *clk)
+{
+ int idx = ((ctrl_inl(FRQMR1) >> 24) & 0x0003);
+ clk->rate = clk->parent->rate / ufc_divisors[idx];
+}
+
+static struct clk_ops sh7785_ram_clk_ops = {
+ .recalc = ram_clk_recalc,
+};
+
+static struct clk sh7785_ram_clk = {
+ .name = "ram_clk",
+ .flags = CLK_ALWAYS_ENABLED,
+ .ops = &sh7785_ram_clk_ops,
+};
+
+/*
+ * Additional SH7785-specific on-chip clocks that aren't already part of the
+ * clock framework
+ */
+static struct clk *sh7785_onchip_clocks[] = {
+ &sh7785_shyway_clk,
+ &sh7785_ddr_clk,
+ &sh7785_ram_clk,
+};
+
+static int __init sh7785_clk_init(void)
+{
+ struct clk *clk = clk_get(NULL, "master_clk");
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sh7785_onchip_clocks); i++) {
+ struct clk *clkp = sh7785_onchip_clocks[i];
+
+ clkp->parent = clk;
+ clk_register(clkp);
+ clk_enable(clkp);
+ }
+
+ /*
+ * Now that we have the rest of the clocks registered, we need to
+ * force the parent clock to propagate so that these clocks will
+ * automatically figure out their rate. We cheat by handing the
+ * parent clock its current rate and forcing child propagation.
+ */
+ clk_set_rate(clk, clk_get_rate(clk));
+
+ clk_put(clk);
+
+ return 0;
+}
+arch_initcall(sh7785_clk_init);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
new file mode 100644
index 0000000..07b0de8
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -0,0 +1,103 @@
+/*
+ * SH7785 Setup
+ *
+ * Copyright (C) 2007 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <asm/sci.h>
+
+static struct plat_sci_port sci_platform_data[] = {
+ {
+ .mapbase = 0xffea0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 40, 41, 43, 42 },
+ }, {
+ .mapbase = 0xffeb0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 44, 45, 47, 46 },
+ },
+
+ /*
+ * The rest of these all have multiplexed IRQs
+ */
+ {
+ .mapbase = 0xffec0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 60, 60, 60, 60 },
+ }, {
+ .mapbase = 0xffed0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 61, 61, 61, 61 },
+ }, {
+ .mapbase = 0xffee0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 62, 62, 62, 62 },
+ }, {
+ .mapbase = 0xffef0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 63, 63, 63, 63 },
+ }, {
+ .flags = 0,
+ }
+};
+
+static struct platform_device sci_device = {
+ .name = "sh-sci",
+ .id = -1,
+ .dev = {
+ .platform_data = sci_platform_data,
+ },
+};
+
+static struct platform_device *sh7785_devices[] __initdata = {
+ &sci_device,
+};
+
+static int __init sh7785_devices_setup(void)
+{
+ return platform_add_devices(sh7785_devices,
+ ARRAY_SIZE(sh7785_devices));
+}
+__initcall(sh7785_devices_setup);
+
+static struct intc2_data intc2_irq_table[] = {
+ { 28, 0, 24, 0, 0, 2 }, /* TMU0 */
+
+ { 40, 8, 24, 0, 2, 3 }, /* SCIF0 ERI */
+ { 41, 8, 24, 0, 2, 3 }, /* SCIF0 RXI */
+ { 42, 8, 24, 0, 2, 3 }, /* SCIF0 BRI */
+ { 43, 8, 24, 0, 2, 3 }, /* SCIF0 TXI */
+
+ { 44, 8, 16, 0, 3, 3 }, /* SCIF1 ERI */
+ { 45, 8, 16, 0, 3, 3 }, /* SCIF1 RXI */
+ { 46, 8, 16, 0, 3, 3 }, /* SCIF1 BRI */
+ { 47, 8, 16, 0, 3, 3 }, /* SCIF1 TXI */
+
+ { 64, 0x14, 8, 0, 14, 2 }, /* PCIC0 */
+ { 65, 0x14, 0, 0, 15, 2 }, /* PCIC1 */
+ { 66, 0x18, 24, 0, 16, 2 }, /* PCIC2 */
+ { 67, 0x18, 16, 0, 17, 2 }, /* PCIC3 */
+ { 68, 0x18, 8, 0, 18, 2 }, /* PCIC4 */
+
+ { 60, 8, 8, 0, 4, 3 }, /* SCIF2 ERI, RXI, BRI, TXI */
+ { 60, 8, 0, 0, 5, 3 }, /* SCIF3 ERI, RXI, BRI, TXI */
+ { 60, 12, 24, 0, 6, 3 }, /* SCIF4 ERI, RXI, BRI, TXI */
+ { 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */
+};
+
+void __init init_IRQ_intc2(void)
+{
+ make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table));
+}
diff --git a/arch/sh/kernel/crash_dump.c b/arch/sh/kernel/crash_dump.c
new file mode 100644
index 0000000..4a2ecbe
--- /dev/null
+++ b/arch/sh/kernel/crash_dump.c
@@ -0,0 +1,46 @@
+/*
+ * crash_dump.c - Memory preserving reboot related code.
+ *
+ * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ * Copyright (C) IBM Corporation, 2004. All rights reserved
+ */
+
+#include <linux/errno.h>
+#include <linux/crash_dump.h>
+#include <linux/io.h>
+#include <asm/uaccess.h>
+
+/**
+ * copy_oldmem_page - copy one page from "oldmem"
+ * @pfn: page frame number to be copied
+ * @buf: target memory address for the copy; this can be in kernel address
+ * space or user address space (see @userbuf)
+ * @csize: number of bytes to copy
+ * @offset: offset in bytes into the page (based on pfn) to begin the copy
+ * @userbuf: if set, @buf is in user address space, use copy_to_user(),
+ * otherwise @buf is in kernel address space, use memcpy().
+ *
+ * Copy a page from "oldmem". For this page, there is no pte mapped
+ * in the current kernel. We stitch up a pte, similar to kmap_atomic.
+ */
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+ size_t csize, unsigned long offset, int userbuf)
+{
+ void *vaddr;
+
+ if (!csize)
+ return 0;
+
+ vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
+
+ if (userbuf) {
+ if (copy_to_user(buf, (vaddr + offset), csize)) {
+ iounmap(vaddr);
+ return -EFAULT;
+ }
+ } else
+ memcpy(buf, (vaddr + offset), csize);
+
+ iounmap(vaddr);
+ return csize;
+}
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
index 9048c03..9833493 100644
--- a/arch/sh/kernel/early_printk.c
+++ b/arch/sh/kernel/early_printk.c
@@ -192,20 +192,14 @@ int __init setup_early_printk(char *buf)
}
#endif
- if (likely(early_console))
+ if (likely(early_console)) {
+ if (keep_early)
+ early_console->flags &= ~CON_BOOT;
+ else
+ early_console->flags |= CON_BOOT;
register_console(early_console);
+ }
return 0;
}
early_param("earlyprintk", setup_early_printk);
-
-void __init disable_early_printk(void)
-{
- if (!early_console_initialized || !early_console)
- return;
- if (!keep_early) {
- printk("disabling early console\n");
- unregister_console(early_console);
- } else
- printk("keeping early console\n");
-}
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 9bdd8a0..27b923c 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -13,6 +13,7 @@
#include <linux/seq_file.h>
#include <linux/irq.h>
#include <asm/processor.h>
+#include <asm/machvec.h>
#include <asm/uaccess.h>
#include <asm/thread_info.h>
#include <asm/cpu/mmu_context.h>
@@ -44,7 +45,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n');
}
- if (i < NR_IRQS) {
+ if (i < sh_mv.mv_nr_irqs) {
spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action;
if (!action)
@@ -61,7 +62,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n');
unlock:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
- } else if (i == NR_IRQS)
+ } else if (i == sh_mv.mv_nr_irqs)
seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count));
return 0;
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
index d8927d8..a532336 100644
--- a/arch/sh/kernel/kgdb_stub.c
+++ b/arch/sh/kernel/kgdb_stub.c
@@ -6,11 +6,11 @@
* David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>,
* Amit S. Kale <akale@veritas.com>, William Gatliff <bgat@open-widgets.com>,
* Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>.
- *
+ *
* This version by Henry Bell <henry.bell@st.com>
* Minor modifications by Jeremy Siegel <jsiegel@mvista.com>
- *
- * Contains low-level support for remote debug using GDB.
+ *
+ * Contains low-level support for remote debug using GDB.
*
* To enable debugger support, two things need to happen. A call to
* set_debug_traps() is necessary in order to allow any breakpoints
@@ -48,7 +48,7 @@
* k kill (Detach GDB)
*
* d Toggle debug flag
- * D Detach GDB
+ * D Detach GDB
*
* Hct Set thread t for operations, OK or ENN
* c = 'c' (step, cont), c = 'g' (other
@@ -58,7 +58,7 @@
* qfThreadInfo Get list of current threads (first) m<id>
* qsThreadInfo " " " " " (subsequent)
* qOffsets Get section offsets Text=x;Data=y;Bss=z
- *
+ *
* TXX Find if thread XX is alive OK or ENN
* ? What was the last sigval ? SNN (signal NN)
* O Output to GDB console
@@ -74,7 +74,7 @@
* '$' or '#'. If <data> starts with two characters followed by
* ':', then the existing stubs interpret this as a sequence number.
*
- * CSUM1 and CSUM2 are ascii hex representation of an 8-bit
+ * CSUM1 and CSUM2 are ascii hex representation of an 8-bit
* checksum of <data>, the most significant nibble is sent first.
* the hex digits 0-9,a-f are used.
*
@@ -86,8 +86,8 @@
* Responses can be run-length encoded to save space. A '*' means that
* the next character is an ASCII encoding giving a repeat count which
* stands for that many repititions of the character preceding the '*'.
- * The encoding is n+29, yielding a printable character where n >=3
- * (which is where RLE starts to win). Don't use an n > 126.
+ * The encoding is n+29, yielding a printable character where n >=3
+ * (which is where RLE starts to win). Don't use an n > 126.
*
* So "0* " means the same as "0000".
*/
@@ -100,12 +100,10 @@
#include <linux/delay.h>
#include <linux/linkage.h>
#include <linux/init.h>
-
-#ifdef CONFIG_SH_KGDB_CONSOLE
#include <linux/console.h>
-#endif
-
+#include <linux/sysrq.h>
#include <asm/system.h>
+#include <asm/cacheflush.h>
#include <asm/current.h>
#include <asm/signal.h>
#include <asm/pgtable.h>
@@ -153,7 +151,6 @@ char kgdb_in_gdb_mode;
char in_nmi; /* Set during NMI to prevent reentry */
int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */
int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */
-int kgdb_halt;
/* Exposed for user access */
struct task_struct *kgdb_current;
@@ -246,14 +243,6 @@ static char out_buffer[OUTBUFMAX];
static void kgdb_to_gdb(const char *s);
-#ifdef CONFIG_KGDB_THREAD
-static struct task_struct *trapped_thread;
-static struct task_struct *current_thread;
-typedef unsigned char threadref[8];
-#define BUF_THREAD_ID_SIZE 16
-#endif
-
-
/* Convert ch to hex */
static int hex(const char ch)
{
@@ -328,7 +317,7 @@ static int hex_to_int(char **ptr, int *int_value)
}
/* Copy the binary array pointed to by buf into mem. Fix $, #,
- and 0x7d escaped with 0x7d. Return a pointer to the character
+ and 0x7d escaped with 0x7d. Return a pointer to the character
after the last byte written. */
static char *ebin_to_mem(const char *buf, char *mem, int count)
{
@@ -349,66 +338,6 @@ static char *pack_hex_byte(char *pkt, int byte)
return pkt;
}
-#ifdef CONFIG_KGDB_THREAD
-
-/* Pack a thread ID */
-static char *pack_threadid(char *pkt, threadref * id)
-{
- char *limit;
- unsigned char *altid;
-
- altid = (unsigned char *) id;
-
- limit = pkt + BUF_THREAD_ID_SIZE;
- while (pkt < limit)
- pkt = pack_hex_byte(pkt, *altid++);
- return pkt;
-}
-
-/* Convert an integer into our threadref */
-static void int_to_threadref(threadref * id, const int value)
-{
- unsigned char *scan = (unsigned char *) id;
- int i = 4;
-
- while (i--)
- *scan++ = 0;
-
- *scan++ = (value >> 24) & 0xff;
- *scan++ = (value >> 16) & 0xff;
- *scan++ = (value >> 8) & 0xff;
- *scan++ = (value & 0xff);
-}
-
-/* Return a task structure ptr for a particular pid */
-static struct task_struct *get_thread(int pid)
-{
- struct task_struct *thread;
-
- /* Use PID_MAX w/gdb for pid 0 */
- if (pid == PID_MAX) pid = 0;
-
- /* First check via PID */
- thread = find_task_by_pid(pid);
-
- if (thread)
- return thread;
-
- /* Start at the start */
- thread = init_tasks[0];
-
- /* Walk along the linked list of tasks */
- do {
- if (thread->pid == pid)
- return thread;
- thread = thread->next_task;
- } while (thread != init_tasks[0]);
-
- return NULL;
-}
-
-#endif /* CONFIG_KGDB_THREAD */
-
/* Scan for the start char '$', read the packet and check the checksum */
static void get_packet(char *buffer, int buflen)
{
@@ -452,7 +381,7 @@ static void get_packet(char *buffer, int buflen)
/* Ack successful transfer */
put_debug_char('+');
- /* If a sequence char is present, reply
+ /* If a sequence char is present, reply
the sequence ID */
if (buffer[2] == ':') {
put_debug_char(buffer[0]);
@@ -611,74 +540,6 @@ static void gdb_regs_to_kgdb_regs(const int *gdb_regs,
regs->vbr = gdb_regs[VBR];
}
-#ifdef CONFIG_KGDB_THREAD
-/* Make a local copy of registers from the specified thread */
-asmlinkage void ret_from_fork(void);
-static void thread_regs_to_gdb_regs(const struct task_struct *thread,
- int *gdb_regs)
-{
- int regno;
- int *tregs;
-
- /* Initialize to zero */
- for (regno = 0; regno < MAXREG; regno++)
- gdb_regs[regno] = 0;
-
- /* Just making sure... */
- if (thread == NULL)
- return;
-
- /* A new fork has pt_regs on the stack from a fork() call */
- if (thread->thread.pc == (unsigned long)ret_from_fork) {
-
- int vbr_val;
- struct pt_regs *kregs;
- kregs = (struct pt_regs*)thread->thread.sp;
-
- gdb_regs[R0] = kregs->regs[R0];
- gdb_regs[R1] = kregs->regs[R1];
- gdb_regs[R2] = kregs->regs[R2];
- gdb_regs[R3] = kregs->regs[R3];
- gdb_regs[R4] = kregs->regs[R4];
- gdb_regs[R5] = kregs->regs[R5];
- gdb_regs[R6] = kregs->regs[R6];
- gdb_regs[R7] = kregs->regs[R7];
- gdb_regs[R8] = kregs->regs[R8];
- gdb_regs[R9] = kregs->regs[R9];
- gdb_regs[R10] = kregs->regs[R10];
- gdb_regs[R11] = kregs->regs[R11];
- gdb_regs[R12] = kregs->regs[R12];
- gdb_regs[R13] = kregs->regs[R13];
- gdb_regs[R14] = kregs->regs[R14];
- gdb_regs[R15] = kregs->regs[R15];
- gdb_regs[PC] = kregs->pc;
- gdb_regs[PR] = kregs->pr;
- gdb_regs[GBR] = kregs->gbr;
- gdb_regs[MACH] = kregs->mach;
- gdb_regs[MACL] = kregs->macl;
- gdb_regs[SR] = kregs->sr;
-
- asm("stc vbr, %0":"=r"(vbr_val));
- gdb_regs[VBR] = vbr_val;
- return;
- }
-
- /* Otherwise, we have only some registers from switch_to() */
- tregs = (int *)thread->thread.sp;
- gdb_regs[R15] = (int)tregs;
- gdb_regs[R14] = *tregs++;
- gdb_regs[R13] = *tregs++;
- gdb_regs[R12] = *tregs++;
- gdb_regs[R11] = *tregs++;
- gdb_regs[R10] = *tregs++;
- gdb_regs[R9] = *tregs++;
- gdb_regs[R8] = *tregs++;
- gdb_regs[PR] = *tregs++;
- gdb_regs[GBR] = *tregs++;
- gdb_regs[PC] = thread->thread.pc;
-}
-#endif /* CONFIG_KGDB_THREAD */
-
/* Calculate the new address for after a step */
static short *get_step_address(void)
{
@@ -759,7 +620,7 @@ static short *get_step_address(void)
return (short *) addr;
}
-/* Set up a single-step. Replace the instruction immediately after the
+/* Set up a single-step. Replace the instruction immediately after the
current instruction (i.e. next in the expected flow of control) with a
trap instruction, so that returning will cause only a single instruction
to be executed. Note that this model is slightly broken for instructions
@@ -797,37 +658,11 @@ static void undo_single_step(void)
/* Send a signal message */
static void send_signal_msg(const int signum)
{
-#ifndef CONFIG_KGDB_THREAD
out_buffer[0] = 'S';
out_buffer[1] = highhex(signum);
out_buffer[2] = lowhex(signum);
out_buffer[3] = 0;
put_packet(out_buffer);
-#else /* CONFIG_KGDB_THREAD */
- int threadid;
- threadref thref;
- char *out = out_buffer;
- const char *tstring = "thread";
-
- *out++ = 'T';
- *out++ = highhex(signum);
- *out++ = lowhex(signum);
-
- while (*tstring) {
- *out++ = *tstring++;
- }
- *out++ = ':';
-
- threadid = trapped_thread->pid;
- if (threadid == 0) threadid = PID_MAX;
- int_to_threadref(&thref, threadid);
- pack_threadid(out, &thref);
- out += BUF_THREAD_ID_SIZE;
- *out++ = ';';
-
- *out = 0;
- put_packet(out_buffer);
-#endif /* CONFIG_KGDB_THREAD */
}
/* Reply that all was well */
@@ -962,15 +797,7 @@ static void step_with_sig_msg(void)
/* Send register contents */
static void send_regs_msg(void)
{
-#ifdef CONFIG_KGDB_THREAD
- if (!current_thread)
- kgdb_regs_to_gdb_regs(&trap_registers, registers);
- else
- thread_regs_to_gdb_regs(current_thread, registers);
-#else
kgdb_regs_to_gdb_regs(&trap_registers, registers);
-#endif
-
mem_to_hex((char *) registers, out_buffer, NUMREGBYTES);
put_packet(out_buffer);
}
@@ -978,201 +805,13 @@ static void send_regs_msg(void)
/* Set register contents - currently can't set other thread's registers */
static void set_regs_msg(void)
{
-#ifdef CONFIG_KGDB_THREAD
- if (!current_thread) {
-#endif
- kgdb_regs_to_gdb_regs(&trap_registers, registers);
- hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES);
- gdb_regs_to_kgdb_regs(registers, &trap_registers);
- send_ok_msg();
-#ifdef CONFIG_KGDB_THREAD
- } else
- send_err_msg();
-#endif
-}
-
-
-#ifdef CONFIG_KGDB_THREAD
-
-/* Set the status for a thread */
-void set_thread_msg(void)
-{
- int threadid;
- struct task_struct *thread = NULL;
- char *ptr;
-
- switch (in_buffer[1]) {
-
- /* To select which thread for gG etc messages, i.e. supported */
- case 'g':
-
- ptr = &in_buffer[2];
- hex_to_int(&ptr, &threadid);
- thread = get_thread(threadid);
-
- /* If we haven't found it */
- if (!thread) {
- send_err_msg();
- break;
- }
-
- /* Set current_thread (or not) */
- if (thread == trapped_thread)
- current_thread = NULL;
- else
- current_thread = thread;
- send_ok_msg();
- break;
-
- /* To select which thread for cCsS messages, i.e. unsupported */
- case 'c':
- send_ok_msg();
- break;
-
- default:
- send_empty_msg();
- break;
- }
-}
-
-/* Is a thread alive? */
-static void thread_status_msg(void)
-{
- char *ptr;
- int threadid;
- struct task_struct *thread = NULL;
-
- ptr = &in_buffer[1];
- hex_to_int(&ptr, &threadid);
- thread = get_thread(threadid);
- if (thread)
- send_ok_msg();
- else
- send_err_msg();
-}
-/* Send the current thread ID */
-static void thread_id_msg(void)
-{
- int threadid;
- threadref thref;
-
- out_buffer[0] = 'Q';
- out_buffer[1] = 'C';
-
- if (current_thread)
- threadid = current_thread->pid;
- else if (trapped_thread)
- threadid = trapped_thread->pid;
- else /* Impossible, but just in case! */
- {
- send_err_msg();
- return;
- }
-
- /* Translate pid 0 to PID_MAX for gdb */
- if (threadid == 0) threadid = PID_MAX;
-
- int_to_threadref(&thref, threadid);
- pack_threadid(out_buffer + 2, &thref);
- out_buffer[2 + BUF_THREAD_ID_SIZE] = '\0';
- put_packet(out_buffer);
-}
-
-/* Send thread info */
-static void thread_info_msg(void)
-{
- struct task_struct *thread = NULL;
- int threadid;
- char *pos;
- threadref thref;
-
- /* Start with 'm' */
- out_buffer[0] = 'm';
- pos = &out_buffer[1];
-
- /* For all possible thread IDs - this will overrun if > 44 threads! */
- /* Start at 1 and include PID_MAX (since GDB won't use pid 0...) */
- for (threadid = 1; threadid <= PID_MAX; threadid++) {
-
- read_lock(&tasklist_lock);
- thread = get_thread(threadid);
- read_unlock(&tasklist_lock);
-
- /* If it's a valid thread */
- if (thread) {
- int_to_threadref(&thref, threadid);
- pack_threadid(pos, &thref);
- pos += BUF_THREAD_ID_SIZE;
- *pos++ = ',';
- }
- }
- *--pos = 0; /* Lose final comma */
- put_packet(out_buffer);
-
-}
-
-/* Return printable info for gdb's 'info threads' command */
-static void thread_extra_info_msg(void)
-{
- int threadid;
- struct task_struct *thread = NULL;
- char buffer[20], *ptr;
- int i;
-
- /* Extract thread ID */
- ptr = &in_buffer[17];
- hex_to_int(&ptr, &threadid);
- thread = get_thread(threadid);
-
- /* If we don't recognise it, say so */
- if (thread == NULL)
- strcpy(buffer, "(unknown)");
- else
- strcpy(buffer, thread->comm);
-
- /* Construct packet */
- for (i = 0, ptr = out_buffer; buffer[i]; i++)
- ptr = pack_hex_byte(ptr, buffer[i]);
-
- if (thread->thread.pc == (unsigned long)ret_from_fork) {
- strcpy(buffer, "<new fork>");
- for (i = 0; buffer[i]; i++)
- ptr = pack_hex_byte(ptr, buffer[i]);
- }
-
- *ptr = '\0';
- put_packet(out_buffer);
-}
-
-/* Handle all qFooBarBaz messages - have to use an if statement as
- opposed to a switch because q messages can have > 1 char id. */
-static void query_msg(void)
-{
- const char *q_start = &in_buffer[1];
-
- /* qC = return current thread ID */
- if (strncmp(q_start, "C", 1) == 0)
- thread_id_msg();
-
- /* qfThreadInfo = query all threads (first) */
- else if (strncmp(q_start, "fThreadInfo", 11) == 0)
- thread_info_msg();
-
- /* qsThreadInfo = query all threads (subsequent). We know we have sent
- them all after the qfThreadInfo message, so there are no to send */
- else if (strncmp(q_start, "sThreadInfo", 11) == 0)
- put_packet("l"); /* el = last */
-
- /* qThreadExtraInfo = supply printable information per thread */
- else if (strncmp(q_start, "ThreadExtraInfo", 15) == 0)
- thread_extra_info_msg();
-
- /* Unsupported - empty message as per spec */
- else
- send_empty_msg();
+ kgdb_regs_to_gdb_regs(&trap_registers, registers);
+ hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES);
+ gdb_regs_to_kgdb_regs(registers, &trap_registers);
+ send_ok_msg();
}
-#endif /* CONFIG_KGDB_THREAD */
+#ifdef CONFIG_SH_KGDB_CONSOLE
/*
* Bring up the ports..
*/
@@ -1185,6 +824,9 @@ static int kgdb_serial_setup(void)
return 0;
}
+#else
+#define kgdb_serial_setup() 0
+#endif
/* The command loop, read and act on requests */
static void kgdb_command_loop(const int excep_code, const int trapa_value)
@@ -1193,7 +835,7 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
if (excep_code == NMI_VEC) {
#ifndef CONFIG_KGDB_NMI
- KGDB_PRINTK("Ignoring unexpected NMI?\n");
+ printk(KERN_NOTICE "KGDB: Ignoring unexpected NMI?\n");
return;
#else /* CONFIG_KGDB_NMI */
if (!kgdb_enabled) {
@@ -1207,19 +849,10 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
if (!kgdb_enabled)
return;
-#ifdef CONFIG_KGDB_THREAD
- /* Until GDB specifies a thread */
- current_thread = NULL;
- trapped_thread = current;
-#endif
-
/* Enter GDB mode (e.g. after detach) */
if (!kgdb_in_gdb_mode) {
/* Do serial setup, notify user, issue preemptive ack */
- kgdb_serial_setup();
- KGDB_PRINTK("Waiting for GDB (on %s%d at %d baud)\n",
- (kgdb_porttype ? kgdb_porttype->name : ""),
- kgdb_portnum, kgdb_baud);
+ printk(KERN_NOTICE "KGDB: Waiting for GDB\n");
kgdb_in_gdb_mode = 1;
put_debug_char('+');
}
@@ -1233,21 +866,18 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
will later be replaced by its original one. Do NOT do this for
trap 0xff, since that indicates a compiled-in breakpoint which
will not be replaced (and we would retake the trap forever) */
- if ((excep_code == TRAP_VEC) && (trapa_value != (0xff << 2))) {
+ if ((excep_code == TRAP_VEC) && (trapa_value != (0x3c << 2)))
trap_registers.pc -= 2;
- }
/* Undo any stepping we may have done */
undo_single_step();
while (1) {
-
out_buffer[0] = 0;
get_packet(in_buffer, BUFMAX);
/* Examine first char of buffer to see what we need to do */
switch (in_buffer[0]) {
-
case '?': /* Send which signal we've received */
send_signal_msg(sigval);
break;
@@ -1291,21 +921,6 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
step_msg();
return;
-#ifdef CONFIG_KGDB_THREAD
-
- case 'H': /* Task related */
- set_thread_msg();
- break;
-
- case 'T': /* Query thread status */
- thread_status_msg();
- break;
-
- case 'q': /* Handle query - currently thread-related */
- query_msg();
- break;
-#endif
-
case 'k': /* 'Kill the program' with a kernel ? */
break;
@@ -1323,11 +938,8 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
}
/* There has been an exception, most likely a breakpoint. */
-asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
- unsigned long r6, unsigned long r7,
- struct pt_regs __regs)
+static void handle_exception(struct pt_regs *regs)
{
- struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
int excep_code, vbr_val;
int count;
int trapa_value = ctrl_inl(TRA);
@@ -1355,7 +967,7 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
kgdb_trapa_val = trapa_value;
/* Act on the exception */
- kgdb_command_loop(excep_code >> 5, trapa_value);
+ kgdb_command_loop(excep_code, trapa_value);
kgdb_current = NULL;
@@ -1373,14 +985,12 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
asm("ldc %0, vbr": :"r"(vbr_val));
}
-/* Trigger a breakpoint by function */
-void breakpoint(void)
+asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs __regs)
{
- if (!kgdb_enabled) {
- kgdb_enabled = 1;
- kgdb_init();
- }
- BREAKPOINT();
+ struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
+ handle_exception(regs);
}
/* Initialise the KGDB data structures and serial configuration */
@@ -1395,24 +1005,16 @@ int kgdb_init(void)
kgdb_in_gdb_mode = 0;
if (kgdb_serial_setup() != 0) {
- KGDB_PRINTK("serial setup error\n");
+ printk(KERN_NOTICE "KGDB: serial setup error\n");
return -1;
}
/* Init ptr to exception handler */
- kgdb_debug_hook = kgdb_handle_exception;
+ kgdb_debug_hook = handle_exception;
kgdb_bus_err_hook = kgdb_handle_bus_error;
/* Enter kgdb now if requested, or just report init done */
- if (kgdb_halt) {
- kgdb_in_gdb_mode = 1;
- put_debug_char('+');
- breakpoint();
- }
- else
- {
- KGDB_PRINTK("stub is initialized.\n");
- }
+ printk(KERN_NOTICE "KGDB: stub is initialized.\n");
return 0;
}
@@ -1437,7 +1039,7 @@ static void kgdb_msg_write(const char *s, unsigned count)
/* Calculate how many this time */
wcount = (count > MAXOUT) ? MAXOUT : count;
-
+
/* Pack in hex chars */
for (i = 0; i < wcount; i++)
bufptr = pack_hex_byte(bufptr, s[i]);
@@ -1467,3 +1069,25 @@ void kgdb_console_write(struct console *co, const char *s, unsigned count)
kgdb_msg_write(s, count);
}
#endif
+
+#ifdef CONFIG_KGDB_SYSRQ
+static void sysrq_handle_gdb(int key, struct tty_struct *tty)
+{
+ printk("Entering GDB stub\n");
+ breakpoint();
+}
+
+static struct sysrq_key_op sysrq_gdb_op = {
+ .handler = sysrq_handle_gdb,
+ .help_msg = "Gdb",
+ .action_msg = "GDB",
+};
+
+static int gdb_register_sysrq(void)
+{
+ printk("Registering GDB sysrq handler\n");
+ register_sysrq_key('g', &sysrq_gdb_op);
+ return 0;
+}
+module_init(gdb_register_sysrq);
+#endif
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index 08587cd..790ed69 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -59,13 +59,13 @@ static void kexec_info(struct kimage *image)
printk(" segment[%d]: 0x%08x - 0x%08x (0x%08x)\n",
i,
(unsigned int)image->segment[i].mem,
- (unsigned int)image->segment[i].mem + image->segment[i].memsz,
+ (unsigned int)image->segment[i].mem +
+ image->segment[i].memsz,
(unsigned int)image->segment[i].memsz);
- }
+ }
printk(" start : 0x%08x\n\n", (unsigned int)image->start);
}
-
/*
* Do not allocate memory (or fail in any way) in machine_kexec().
* We are past the point of no return, committed to rebooting now.
@@ -101,6 +101,27 @@ NORET_TYPE void machine_kexec(struct kimage *image)
/* now call it */
rnk = (relocate_new_kernel_t) reboot_code_buffer;
- (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg);
+ (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg);
}
+/* crashkernel=size@addr specifies the location to reserve for
+ * a crash kernel. By reserving this memory we guarantee
+ * that linux never sets it up as a DMA target.
+ * Useful for holding code to do something appropriate
+ * after a kernel panic.
+ */
+static int __init parse_crashkernel(char *arg)
+{
+ unsigned long size, base;
+ size = memparse(arg, &arg);
+ if (*arg == '@') {
+ base = memparse(arg+1, &arg);
+ /* FIXME: Do I want a sanity check
+ * to validate the memory range?
+ */
+ crashk_res.start = base;
+ crashk_res.end = base + size - 1;
+ }
+ return 0;
+}
+early_param("crashkernel", parse_crashkernel);
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index e760736..329b3f3 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -7,7 +7,7 @@
*
* SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
* Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC
- * Copyright (C) 2002 - 2006 Paul Mundt
+ * Copyright (C) 2002 - 2007 Paul Mundt
*/
#include <linux/module.h>
#include <linux/mm.h>
@@ -15,6 +15,7 @@
#include <linux/pm.h>
#include <linux/kallsyms.h>
#include <linux/kexec.h>
+#include <asm/kdebug.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/ubc.h>
@@ -299,7 +300,8 @@ static void ubc_set_tracing(int asid, unsigned long pc)
ctrl_outl(0, UBC_BAMRA);
if (current_cpu_data.type == CPU_SH7729 ||
- current_cpu_data.type == CPU_SH7710) {
+ current_cpu_data.type == CPU_SH7710 ||
+ current_cpu_data.type == CPU_SH7712) {
ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR);
} else {
@@ -495,6 +497,10 @@ asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5,
/* Rewind */
regs->pc -= 2;
+ if (notify_die(DIE_TRAP, regs, regs->tra & 0xff,
+ SIGTRAP) == NOTIFY_STOP)
+ return;
+
force_sig(SIGTRAP, current);
}
@@ -510,6 +516,10 @@ asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5,
/* Rewind */
regs->pc -= 2;
+ if (notify_die(DIE_TRAP, regs, TRAPA_BUG_OPCODE & 0xff,
+ SIGTRAP) == NOTIFY_STOP)
+ return;
+
#ifdef CONFIG_BUG
if (__kernel_text_address(instruction_pointer(regs))) {
u16 insn = *(u16 *)instruction_pointer(regs);
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index 855f724..3fb5fc0 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -12,7 +12,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 98802ab..477d2a8 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -4,7 +4,7 @@
* This file handles the architecture-dependent parts of initialization
*
* Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2002 - 2006 Paul Mundt
+ * Copyright (C) 2002 - 2007 Paul Mundt
*/
#include <linux/screen_info.h>
#include <linux/ioport.h>
@@ -15,21 +15,22 @@
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/utsname.h>
+#include <linux/nodemask.h>
#include <linux/cpu.h>
#include <linux/pfn.h>
#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/kexec.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/sections.h>
#include <asm/irq.h>
#include <asm/setup.h>
#include <asm/clock.h>
+#include <asm/mmu_context.h>
-#ifdef CONFIG_SH_KGDB
-#include <asm/kgdb.h>
-static int kgdb_parse_options(char *options);
-#endif
extern void * __rd_start, * __rd_end;
+
/*
* Machine setup..
*/
@@ -205,53 +206,33 @@ static int __init sh_mv_setup(char **cmdline_p)
return 0;
}
-void __init setup_arch(char **cmdline_p)
+/*
+ * Register fully available low RAM pages with the bootmem allocator.
+ */
+static void __init register_bootmem_low_pages(void)
{
- unsigned long bootmap_size;
- unsigned long start_pfn, max_pfn, max_low_pfn;
-
-#ifdef CONFIG_CMDLINE_BOOL
- strcpy(COMMAND_LINE, CONFIG_CMDLINE);
-#endif
-
- ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
-
-#ifdef CONFIG_BLK_DEV_RAM
- rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
- rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
- rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
-#endif
-
- if (!MOUNT_ROOT_RDONLY)
- root_mountflags &= ~MS_RDONLY;
- init_mm.start_code = (unsigned long) _text;
- init_mm.end_code = (unsigned long) _etext;
- init_mm.end_data = (unsigned long) _edata;
- init_mm.brk = (unsigned long) _end;
-
- code_resource.start = (unsigned long)virt_to_phys(_text);
- code_resource.end = (unsigned long)virt_to_phys(_etext)-1;
- data_resource.start = (unsigned long)virt_to_phys(_etext);
- data_resource.end = (unsigned long)virt_to_phys(_edata)-1;
-
- sh_mv_setup(cmdline_p);
-
+ unsigned long curr_pfn, last_pfn, pages;
/*
- * Find the highest page frame number we have available
+ * We are rounding up the start address of usable memory:
*/
- max_pfn = PFN_DOWN(__pa(memory_end));
+ curr_pfn = PFN_UP(__MEMORY_START);
/*
- * Determine low and high memory ranges:
+ * ... and at the end of the usable range downwards:
*/
- max_low_pfn = max_pfn;
+ last_pfn = PFN_DOWN(__pa(memory_end));
- /*
- * Partially used pages are not usable - thus
- * we are rounding upwards:
- */
- start_pfn = PFN_UP(__pa(_end));
+ if (last_pfn > max_low_pfn)
+ last_pfn = max_low_pfn;
+
+ pages = last_pfn - curr_pfn;
+ free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
+}
+
+void __init setup_bootmem_allocator(unsigned long start_pfn)
+{
+ unsigned long bootmap_size;
/*
* Find a proper area for the bootmem bitmap. After this
@@ -259,31 +240,11 @@ void __init setup_arch(char **cmdline_p)
* is intact) must be done via bootmem_alloc().
*/
bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
- __MEMORY_START>>PAGE_SHIFT,
- max_low_pfn);
- /*
- * Register fully available low RAM pages with the bootmem allocator.
- */
- {
- unsigned long curr_pfn, last_pfn, pages;
-
- /*
- * We are rounding up the start address of usable memory:
- */
- curr_pfn = PFN_UP(__MEMORY_START);
- /*
- * ... and at the end of the usable range downwards:
- */
- last_pfn = PFN_DOWN(__pa(memory_end));
+ min_low_pfn, max_low_pfn);
- if (last_pfn > max_low_pfn)
- last_pfn = max_low_pfn;
-
- pages = last_pfn - curr_pfn;
- free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn),
- PFN_PHYS(pages));
- }
+ register_bootmem_low_pages();
+ node_set_online(0);
/*
* Reserve the kernel text and
@@ -292,14 +253,14 @@ void __init setup_arch(char **cmdline_p)
* case of us accidentally initializing the bootmem allocator with
* an invalid RAM area.
*/
- reserve_bootmem_node(NODE_DATA(0), __MEMORY_START+PAGE_SIZE,
+ reserve_bootmem(__MEMORY_START+PAGE_SIZE,
(PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START);
/*
* reserve physical page 0 - it's a special BIOS page on many boxes,
* enabling clean reboots, SMP operation, laptop functions.
*/
- reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE);
+ reserve_bootmem(__MEMORY_START, PAGE_SIZE);
#ifdef CONFIG_BLK_DEV_INITRD
ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
@@ -313,8 +274,8 @@ void __init setup_arch(char **cmdline_p)
if (LOADER_TYPE && INITRD_START) {
if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
- reserve_bootmem_node(NODE_DATA(0), INITRD_START +
- __MEMORY_START, INITRD_SIZE);
+ reserve_bootmem(INITRD_START + __MEMORY_START,
+ INITRD_SIZE);
initrd_start = INITRD_START + PAGE_OFFSET +
__MEMORY_START;
initrd_end = initrd_start + INITRD_SIZE;
@@ -327,6 +288,76 @@ void __init setup_arch(char **cmdline_p)
}
}
#endif
+#ifdef CONFIG_KEXEC
+ if (crashk_res.start != crashk_res.end)
+ reserve_bootmem(crashk_res.start,
+ crashk_res.end - crashk_res.start + 1);
+#endif
+}
+
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+static void __init setup_memory(void)
+{
+ unsigned long start_pfn;
+
+ /*
+ * Partially used pages are not usable - thus
+ * we are rounding upwards:
+ */
+ start_pfn = PFN_UP(__pa(_end));
+ setup_bootmem_allocator(start_pfn);
+}
+#else
+extern void __init setup_memory(void);
+#endif
+
+void __init setup_arch(char **cmdline_p)
+{
+ enable_mmu();
+
+#ifdef CONFIG_CMDLINE_BOOL
+ strcpy(COMMAND_LINE, CONFIG_CMDLINE);
+#endif
+
+ ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
+
+#ifdef CONFIG_BLK_DEV_RAM
+ rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
+ rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
+ rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
+#endif
+
+ if (!MOUNT_ROOT_RDONLY)
+ root_mountflags &= ~MS_RDONLY;
+ init_mm.start_code = (unsigned long) _text;
+ init_mm.end_code = (unsigned long) _etext;
+ init_mm.end_data = (unsigned long) _edata;
+ init_mm.brk = (unsigned long) _end;
+
+ code_resource.start = virt_to_phys(_text);
+ code_resource.end = virt_to_phys(_etext)-1;
+ data_resource.start = virt_to_phys(_etext);
+ data_resource.end = virt_to_phys(_edata)-1;
+
+ parse_early_param();
+
+ sh_mv_setup(cmdline_p);
+
+ /*
+ * Find the highest page frame number we have available
+ */
+ max_pfn = PFN_DOWN(__pa(memory_end));
+
+ /*
+ * Determine low and high memory ranges:
+ */
+ max_low_pfn = max_pfn;
+ min_low_pfn = __MEMORY_START >> PAGE_SHIFT;
+
+ nodes_clear(node_online_map);
+ setup_memory();
+ paging_init();
+ sparse_init();
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
@@ -335,8 +366,6 @@ void __init setup_arch(char **cmdline_p)
/* Perform the machine specific initialisation */
if (likely(sh_mv.mv_setup))
sh_mv.mv_setup(cmdline_p);
-
- paging_init();
}
struct sh_machine_vector* __init get_mv_byname(const char* name)
@@ -380,6 +409,7 @@ static const char *cpu_name[] = {
[CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
[CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708",
[CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710",
+ [CPU_SH7712] = "SH7712",
[CPU_SH7729] = "SH7729", [CPU_SH7750] = "SH7750",
[CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R",
[CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R",
@@ -477,7 +507,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
c->loops_per_jiffy/(500000/HZ),
(c->loops_per_jiffy/(5000/HZ)) % 100);
- return show_clocks(m);
+ return 0;
}
static void *c_start(struct seq_file *m, loff_t *pos)
@@ -499,92 +529,3 @@ struct seq_operations cpuinfo_op = {
.show = show_cpuinfo,
};
#endif /* CONFIG_PROC_FS */
-
-#ifdef CONFIG_SH_KGDB
-/*
- * Parse command-line kgdb options. By default KGDB is enabled,
- * entered on error (or other action) using default serial info.
- * The command-line option can include a serial port specification
- * and an action to override default or configured behavior.
- */
-struct kgdb_sermap kgdb_sci_sermap =
-{ "ttySC", 5, kgdb_sci_setup, NULL };
-
-struct kgdb_sermap *kgdb_serlist = &kgdb_sci_sermap;
-struct kgdb_sermap *kgdb_porttype = &kgdb_sci_sermap;
-
-void kgdb_register_sermap(struct kgdb_sermap *map)
-{
- struct kgdb_sermap *last;
-
- for (last = kgdb_serlist; last->next; last = last->next)
- ;
- last->next = map;
- if (!map->namelen) {
- map->namelen = strlen(map->name);
- }
-}
-
-static int __init kgdb_parse_options(char *options)
-{
- char c;
- int baud;
-
- /* Check for port spec (or use default) */
-
- /* Determine port type and instance */
- if (!memcmp(options, "tty", 3)) {
- struct kgdb_sermap *map = kgdb_serlist;
-
- while (map && memcmp(options, map->name, map->namelen))
- map = map->next;
-
- if (!map) {
- KGDB_PRINTK("unknown port spec in %s\n", options);
- return -1;
- }
-
- kgdb_porttype = map;
- kgdb_serial_setup = map->setup_fn;
- kgdb_portnum = options[map->namelen] - '0';
- options += map->namelen + 1;
-
- options = (*options == ',') ? options+1 : options;
-
- /* Read optional parameters (baud/parity/bits) */
- baud = simple_strtoul(options, &options, 10);
- if (baud != 0) {
- kgdb_baud = baud;
-
- c = toupper(*options);
- if (c == 'E' || c == 'O' || c == 'N') {
- kgdb_parity = c;
- options++;
- }
-
- c = *options;
- if (c == '7' || c == '8') {
- kgdb_bits = c;
- options++;
- }
- options = (*options == ',') ? options+1 : options;
- }
- }
-
- /* Check for action specification */
- if (!memcmp(options, "halt", 4)) {
- kgdb_halt = 1;
- options += 4;
- } else if (!memcmp(options, "disabled", 8)) {
- kgdb_enabled = 0;
- options += 8;
- }
-
- if (*options) {
- KGDB_PRINTK("ignored unknown options: %s\n", options);
- return 0;
- }
- return 1;
-}
-__setup("kgdb=", kgdb_parse_options);
-#endif /* CONFIG_SH_KGDB */
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index 6e0d10f..fa91641 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -5,7 +5,6 @@
#include <linux/sched.h>
#include <linux/in6.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/pci.h>
#include <linux/irq.h>
@@ -65,7 +64,6 @@ EXPORT_SYMBOL(__div64_32);
/* These symbols are generated by the compiler itself */
DECLARE_EXPORT(__udivsi3);
-DECLARE_EXPORT(__udivdi3);
DECLARE_EXPORT(__sdivsi3);
DECLARE_EXPORT(__ashrdi3);
DECLARE_EXPORT(__ashldi3);
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 9f39ef1..eb0191c 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -11,7 +11,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c
index 0d5268a..4bdd2f8 100644
--- a/arch/sh/kernel/stacktrace.c
+++ b/arch/sh/kernel/stacktrace.c
@@ -19,14 +19,7 @@
*/
void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
{
- unsigned long *sp;
-
- if (!task)
- task = current;
- if (task == current)
- sp = (unsigned long *)current_stack_pointer;
- else
- sp = (unsigned long *)task->thread.sp;
+ unsigned long *sp = (unsigned long *)current_stack_pointer;
while (!kstack_end(sp)) {
unsigned long addr = *sp++;
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index e18f183..76b1bc7 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -12,7 +12,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c
index a574b93..82de689 100644
--- a/arch/sh/kernel/timers/timer-cmt.c
+++ b/arch/sh/kernel/timers/timer-cmt.c
@@ -115,7 +115,7 @@ static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id)
static struct irqaction cmt_irq = {
.name = "timer",
.handler = cmt_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.mask = CPU_MASK_NONE,
};
diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c
index fffcd1c..b7499a2 100644
--- a/arch/sh/kernel/timers/timer-mtu2.c
+++ b/arch/sh/kernel/timers/timer-mtu2.c
@@ -110,7 +110,7 @@ static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id)
static struct irqaction mtu2_irq = {
.name = "timer",
.handler = mtu2_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.mask = CPU_MASK_NONE,
};
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c
index e060e71..d9e3151 100644
--- a/arch/sh/kernel/timers/timer-tmu.c
+++ b/arch/sh/kernel/timers/timer-tmu.c
@@ -99,7 +99,7 @@ static irqreturn_t tmu_timer_interrupt(int irq, void *dummy)
static struct irqaction tmu_irq = {
.name = "timer",
.handler = tmu_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.mask = CPU_MASK_NONE,
};
@@ -148,7 +148,9 @@ static int tmu_timer_init(void)
/* Start TMU0 */
tmu_timer_stop();
-#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760)
+#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && \
+ !defined(CONFIG_CPU_SUBTYPE_SH7760) && \
+ !defined(CONFIG_CPU_SUBTYPE_SH7785)
ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
#endif
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index e9f168f..7b40f0f 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -5,7 +5,7 @@
* SuperH version: Copyright (C) 1999 Niibe Yutaka
* Copyright (C) 2000 Philipp Rumpf
* Copyright (C) 2000 David Howells
- * Copyright (C) 2002 - 2006 Paul Mundt
+ * Copyright (C) 2002 - 2007 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -18,10 +18,12 @@
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/io.h>
+#include <linux/bug.h>
#include <linux/debug_locks.h>
#include <linux/limits.h>
#include <asm/system.h>
#include <asm/uaccess.h>
+#include <asm/kdebug.h>
#ifdef CONFIG_SH_KGDB
#include <asm/kgdb.h>
@@ -74,7 +76,21 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
}
}
-DEFINE_SPINLOCK(die_lock);
+ATOMIC_NOTIFIER_HEAD(shdie_chain);
+
+int register_die_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&shdie_chain, nb);
+}
+EXPORT_SYMBOL(register_die_notifier);
+
+int unregister_die_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&shdie_chain, nb);
+}
+EXPORT_SYMBOL(unregister_die_notifier);
+
+static DEFINE_SPINLOCK(die_lock);
void die(const char * str, struct pt_regs * regs, long err)
{
@@ -130,40 +146,6 @@ static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
return -EFAULT;
}
-#ifdef CONFIG_BUG
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-static inline void do_bug_verbose(struct pt_regs *regs)
-{
- struct bug_frame f;
- long len;
-
- if (__copy_from_user(&f, (const void __user *)regs->pc,
- sizeof(struct bug_frame)))
- return;
-
- len = __strnlen_user(f.file, PATH_MAX) - 1;
- if (unlikely(len < 0 || len >= PATH_MAX))
- f.file = "<bad filename>";
- len = __strnlen_user(f.func, PATH_MAX) - 1;
- if (unlikely(len < 0 || len >= PATH_MAX))
- f.func = "<bad function>";
-
- printk(KERN_ALERT "kernel BUG in %s() at %s:%d!\n",
- f.func, f.file, f.line);
-}
-#else
-static inline void do_bug_verbose(struct pt_regs *regs)
-{
-}
-#endif /* CONFIG_DEBUG_BUGVERBOSE */
-
-void handle_BUG(struct pt_regs *regs)
-{
- do_bug_verbose(regs);
- die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
-}
-#endif /* CONFIG_BUG */
-
/*
* handle an instruction that does an unaligned memory access by emulating the
* desired behaviour
@@ -888,6 +870,25 @@ void __init trap_init(void)
per_cpu_trap_init();
}
+#ifdef CONFIG_BUG
+void handle_BUG(struct pt_regs *regs)
+{
+ enum bug_trap_type tt;
+ tt = report_bug(regs->pc);
+ if (tt == BUG_TRAP_TYPE_WARN) {
+ regs->pc += 2;
+ return;
+ }
+
+ die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
+}
+
+int is_valid_bugaddr(unsigned long addr)
+{
+ return addr >= PAGE_OFFSET;
+}
+#endif
+
void show_trace(struct task_struct *tsk, unsigned long *sp,
struct pt_regs *regs)
{
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 2f606d0..d83143c 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -34,9 +34,11 @@ SECTIONS
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
+ _etext = .; /* End of text section */
+
RODATA
- _etext = .; /* End of text section */
+ BUG_TABLE
.data : { /* Data */
*(.data)
@@ -53,6 +55,10 @@ SECTIONS
. = ALIGN(PAGE_SIZE);
.data.page_aligned : { *(.data.page_aligned) }
+ __nosave_begin = .;
+ .data_nosave : { *(.data.nosave) }
+ . = ALIGN(PAGE_SIZE);
+ __nosave_end = .;
. = ALIGN(PAGE_SIZE);
__per_cpu_start = .;
@@ -110,43 +116,10 @@ SECTIONS
* it's a module.
*/
/DISCARD/ : {
- *(.exit.text)
- *(.exit.data)
*(.exitcall.exit)
}
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging section are relative to the beginning
- of the section so we begin .debug at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
- /* These must appear regardless of . */
+ STABS_DEBUG
+
+ DWARF_DEBUG
}
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index 0b9cca5..e23dd1a 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -3,11 +3,9 @@
#
lib-y = delay.o memset.o memmove.o memchr.o \
- checksum.o strlen.o div64.o udivdi3.o \
- div64-generic.o
+ checksum.o strlen.o div64.o div64-generic.o
memcpy-y := memcpy.o
memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o
lib-y += $(memcpy-y)
-
diff --git a/arch/sh/lib/udivdi3.c b/arch/sh/lib/udivdi3.c
deleted file mode 100644
index 68f038b..0000000
--- a/arch/sh/lib/udivdi3.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Simple __udivdi3 function which doesn't use FPU.
- */
-
-#include <linux/types.h>
-
-extern u64 __xdiv64_32(u64 n, u32 d);
-extern void panic(const char * fmt, ...);
-
-u64 __udivdi3(u64 n, u64 d)
-{
- if (d & ~0xffffffff)
- panic("Need true 64-bit/64-bit division");
- return __xdiv64_32(n, (u32)d);
-}
-
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 6b0d28a..12f3d39 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -67,6 +67,7 @@ config CPU_SUBTYPE_SH7300
config CPU_SUBTYPE_SH7705
bool "Support SH7705 processor"
select CPU_SH3
+ select CPU_HAS_IPR_IRQ
select CPU_HAS_PINT_IRQ
config CPU_SUBTYPE_SH7706
@@ -101,9 +102,17 @@ config CPU_SUBTYPE_SH7709
config CPU_SUBTYPE_SH7710
bool "Support SH7710 processor"
select CPU_SH3
+ select CPU_HAS_IPR_IRQ
help
Select SH7710 if you have a SH3-DSP SH7710 CPU.
+config CPU_SUBTYPE_SH7712
+ bool "Support SH7712 processor"
+ select CPU_SH3
+ select CPU_HAS_IPR_IRQ
+ help
+ Select SH7712 if you have a SH3-DSP SH7712 CPU.
+
comment "SH-4 Processor Support"
config CPU_SUBTYPE_SH7750
@@ -283,6 +292,17 @@ config VSYSCALL
For systems with an MMU that can afford to give up a page,
(the default value) say Y.
+config NODES_SHIFT
+ int
+ default "1"
+ depends on NEED_MULTIPLE_NODES
+
+config ARCH_FLATMEM_ENABLE
+ def_bool y
+
+config ARCH_POPULATES_NODE_MAP
+ def_bool y
+
choice
prompt "Kernel page size"
default PAGE_SIZE_4KB
diff --git a/arch/sh/mm/fault-nommu.c b/arch/sh/mm/fault-nommu.c
index 34d4e0c..923cb45 100644
--- a/arch/sh/mm/fault-nommu.c
+++ b/arch/sh/mm/fault-nommu.c
@@ -19,7 +19,6 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <asm/system.h>
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index fa5d7f0..0ecc117 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -2,7 +2,7 @@
* Page fault handler for SH with an MMU.
*
* Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2003 Paul Mundt
+ * Copyright (C) 2003 - 2007 Paul Mundt
*
* Based on linux/arch/i386/mm/fault.c:
* Copyright (C) 1995 Linus Torvalds
@@ -15,12 +15,42 @@
#include <linux/mm.h>
#include <linux/hardirq.h>
#include <linux/kprobes.h>
+#include <asm/kdebug.h>
#include <asm/system.h>
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>
#include <asm/kgdb.h>
-extern void die(const char *,struct pt_regs *,long);
+#ifdef CONFIG_KPROBES
+ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
+
+/* Hook to register for page fault notifications */
+int register_page_fault_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
+}
+
+int unregister_page_fault_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
+}
+
+static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
+ int trap, int sig)
+{
+ struct die_args args = {
+ .regs = regs,
+ .trapnr = trap,
+ };
+ return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
+}
+#else
+static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
+ int trap, int sig)
+{
+ return NOTIFY_DONE;
+}
+#endif
/*
* This routine handles page faults. It determines the address,
@@ -39,6 +69,11 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
siginfo_t info;
trace_hardirqs_on();
+
+ if (notify_page_fault(DIE_PAGE_FAULT, regs,
+ writeaccess, SIGSEGV) == NOTIFY_STOP)
+ return;
+
local_irq_enable();
#ifdef CONFIG_SH_KGDB
diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c
index cf2c2ee..ae8c321 100644
--- a/arch/sh/mm/hugetlbpage.c
+++ b/arch/sh/mm/hugetlbpage.c
@@ -13,7 +13,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index ae957a9..4d03098 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -1,37 +1,20 @@
-/* $Id: init.c,v 1.19 2004/02/21 04:42:16 kkojima Exp $
- *
- * linux/arch/sh/mm/init.c
+/*
+ * linux/arch/sh/mm/init.c
*
* Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2002, 2004 Paul Mundt
+ * Copyright (C) 2002 - 2007 Paul Mundt
*
* Based on linux/arch/i386/mm/init.c:
* Copyright (C) 1995 Linus Torvalds
*/
-
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/ptrace.h>
-#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/swap.h>
-#include <linux/smp.h>
#include <linux/init.h>
-#include <linux/highmem.h>
#include <linux/bootmem.h>
-#include <linux/pagemap.h>
#include <linux/proc_fs.h>
-#include <asm/processor.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
+#include <linux/percpu.h>
+#include <linux/io.h>
#include <asm/mmu_context.h>
-#include <asm/io.h>
#include <asm/tlb.h>
#include <asm/cacheflush.h>
#include <asm/cache.h>
@@ -39,37 +22,51 @@
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
pgd_t swapper_pg_dir[PTRS_PER_PGD];
-#ifdef CONFIG_MMU
-/* It'd be good if these lines were in the standard header file. */
-#define START_PFN (NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT)
-#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn)
-#endif
-
void (*copy_page)(void *from, void *to);
void (*clear_page)(void *to);
void show_mem(void)
{
- int i, total = 0, reserved = 0;
- int shared = 0, cached = 0;
+ int total = 0, reserved = 0, free = 0;
+ int shared = 0, cached = 0, slab = 0;
+ pg_data_t *pgdat;
printk("Mem-info:\n");
show_free_areas();
- printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
- i = max_mapnr;
- while (i-- > 0) {
- total++;
- if (PageReserved(mem_map+i))
- reserved++;
- else if (PageSwapCache(mem_map+i))
- cached++;
- else if (page_count(mem_map+i))
- shared += page_count(mem_map+i) - 1;
+
+ for_each_online_pgdat(pgdat) {
+ struct page *page, *end;
+ unsigned long flags;
+
+ pgdat_resize_lock(pgdat, &flags);
+ page = pgdat->node_mem_map;
+ end = page + pgdat->node_spanned_pages;
+
+ do {
+ total++;
+ if (PageReserved(page))
+ reserved++;
+ else if (PageSwapCache(page))
+ cached++;
+ else if (PageSlab(page))
+ slab++;
+ else if (!page_count(page))
+ free++;
+ else
+ shared += page_count(page) - 1;
+ page++;
+ } while (page < end);
+
+ pgdat_resize_unlock(pgdat, &flags);
}
- printk("%d pages of RAM\n",total);
- printk("%d reserved pages\n",reserved);
- printk("%d pages shared\n",shared);
- printk("%d pages swap cached\n",cached);
+
+ printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+ printk("%d pages of RAM\n", total);
+ printk("%d free pages\n", free);
+ printk("%d reserved pages\n", reserved);
+ printk("%d slab pages\n", slab);
+ printk("%d pages shared\n", shared);
+ printk("%d pages swap cached\n", cached);
}
#ifdef CONFIG_MMU
@@ -147,52 +144,38 @@ extern char __init_begin, __init_end;
*/
void __init paging_init(void)
{
- unsigned long zones_size[MAX_NR_ZONES] = { 0, };
+ int nid;
- /*
- * Setup some defaults for the zone sizes.. these should be safe
- * regardless of distcontiguous memory or MMU settings.
- */
- zones_size[ZONE_NORMAL] = __MEMORY_SIZE >> PAGE_SHIFT;
-#ifdef CONFIG_HIGHMEM
- zones_size[ZONE_HIGHMEM] = 0 >> PAGE_SHIFT;
-#endif
-
-#ifdef CONFIG_MMU
- /*
- * If we have an MMU, and want to be using it .. we need to adjust
- * the zone sizes accordingly, in addition to turning it on.
- */
- {
- /* We don't need to map the kernel through the TLB, as
- * it is permanatly mapped using P1. So clear the
- * entire pgd. */
- memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir));
-
- /* Turn on the MMU */
- enable_mmu();
- zones_size[ZONE_NORMAL] = MAX_LOW_PFN - START_PFN;
- }
+ /* We don't need to map the kernel through the TLB, as
+ * it is permanatly mapped using P1. So clear the
+ * entire pgd. */
+ memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir));
/* Set an initial value for the MMU.TTB so we don't have to
* check for a null value. */
set_TTB(swapper_pg_dir);
-#elif defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4)
- /*
- * If we don't have CONFIG_MMU set and the processor in question
- * still has an MMU, care needs to be taken to make sure it doesn't
- * stay on.. Since the boot loader could have potentially already
- * turned it on, and we clearly don't want it, we simply turn it off.
- *
- * We don't need to do anything special for the zone sizes, since the
- * default values that were already configured up above should be
- * satisfactory.
- */
- disable_mmu();
-#endif
- NODE_DATA(0)->node_mem_map = NULL;
- free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0);
+ for_each_online_node(nid) {
+ pg_data_t *pgdat = NODE_DATA(nid);
+ unsigned long max_zone_pfns[MAX_NR_ZONES];
+ unsigned long low, start_pfn;
+
+ memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+
+ start_pfn = pgdat->bdata->node_boot_start >> PAGE_SHIFT;
+ low = pgdat->bdata->node_low_pfn;
+
+ max_zone_pfns[ZONE_NORMAL] = low;
+ add_active_range(nid, start_pfn, low);
+
+ printk("Node %u: start_pfn = 0x%lx, low = 0x%lx\n",
+ nid, start_pfn, low);
+
+ free_area_init_nodes(max_zone_pfns);
+
+ printk("Node %u: mem_map starts at %p\n",
+ pgdat->node_id, pgdat->node_mem_map);
+ }
}
static struct kcore_list kcore_mem, kcore_vmalloc;
@@ -200,18 +183,33 @@ static struct kcore_list kcore_mem, kcore_vmalloc;
void __init mem_init(void)
{
int codesize, reservedpages, datasize, initsize;
- int tmp;
- extern unsigned long memory_start;
+ int nid;
-#ifdef CONFIG_MMU
- high_memory = (void *)__va(MAX_LOW_PFN * PAGE_SIZE);
-#else
- extern unsigned long memory_end;
+ reservedpages = 0;
- high_memory = (void *)(memory_end & PAGE_MASK);
-#endif
+ for_each_online_node(nid) {
+ pg_data_t *pgdat = NODE_DATA(nid);
+ unsigned long node_pages = 0;
+ void *node_high_memory;
+ int i;
+
+ num_physpages += pgdat->node_present_pages;
+
+ if (pgdat->node_spanned_pages)
+ node_pages = free_all_bootmem_node(pgdat);
+
+ totalram_pages += node_pages;
- max_mapnr = num_physpages = MAP_NR(high_memory) - MAP_NR(memory_start);
+ for (i = 0; i < node_pages; i++)
+ if (PageReserved(pgdat->node_mem_map + i))
+ reservedpages++;
+
+ node_high_memory = (void *)((pgdat->node_start_pfn +
+ pgdat->node_spanned_pages) <<
+ PAGE_SHIFT);
+ if (node_high_memory > high_memory)
+ high_memory = node_high_memory;
+ }
/* clear the zero-page */
memset(empty_zero_page, 0, PAGE_SIZE);
@@ -229,16 +227,6 @@ void __init mem_init(void)
clear_page = clear_page_nommu;
#endif
- /* this will put all low memory onto the freelists */
- totalram_pages += free_all_bootmem_node(NODE_DATA(0));
- reservedpages = 0;
- for (tmp = 0; tmp < num_physpages; tmp++)
- /*
- * Only count reserved RAM pages
- */
- if (PageReserved(mem_map+tmp))
- reservedpages++;
-
codesize = (unsigned long) &_etext - (unsigned long) &_text;
datasize = (unsigned long) &_edata - (unsigned long) &_etext;
initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
@@ -250,7 +238,7 @@ void __init mem_init(void)
printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
"%dk reserved, %dk data, %dk init)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
- max_mapnr << (PAGE_SHIFT-10),
+ totalram_pages << (PAGE_SHIFT-10),
codesize >> 10,
reservedpages << (PAGE_SHIFT-10),
datasize >> 10,
@@ -289,4 +277,3 @@ void free_initrd_mem(unsigned long start, unsigned long end)
printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
}
#endif
-
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index d0d45e2..02aae06 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -311,9 +311,9 @@ static int __init pmb_init(void)
BUG_ON(unlikely(nr_entries >= NR_PMB_ENTRIES));
- pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry),
- 0, 0, pmb_cache_ctor, pmb_cache_dtor);
- BUG_ON(!pmb_cache);
+ pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry), 0,
+ SLAB_PANIC, pmb_cache_ctor,
+ pmb_cache_dtor);
jump_to_P2();
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index 4fe0f94..554f801 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -9,6 +9,7 @@ SE SH_SOLUTION_ENGINE
7751SE SH_7751_SOLUTION_ENGINE
7300SE SH_7300_SOLUTION_ENGINE
7343SE SH_7343_SOLUTION_ENGINE
+7780SE SH_7780_SOLUTION_ENGINE
73180SE SH_73180_SOLUTION_ENGINE
7751SYSTEMH SH_7751_SYSTEMH
HP6XX SH_HP6XX
@@ -26,6 +27,7 @@ SH03 SH_SH03
LANDISK SH_LANDISK
R7780RP SH_R7780RP
R7780MP SH_R7780MP
+R7785RP SH_R7785RP
TITAN SH_TITAN
SHMIN SH_SHMIN
7710VOIPGW SH_7710VOIPGW
diff --git a/arch/sh64/kernel/early_printk.c b/arch/sh64/kernel/early_printk.c
index 8c8a76e..4f91311 100644
--- a/arch/sh64/kernel/early_printk.c
+++ b/arch/sh64/kernel/early_printk.c
@@ -79,7 +79,7 @@ static struct console sh_console = {
.name = "scifcon",
.write = sh_console_write,
.setup = sh_console_setup,
- .flags = CON_PRINTBUFFER,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
.index = -1,
};
@@ -97,9 +97,3 @@ void __init enable_early_printk(void)
register_console(&sh_console);
}
-
-void disable_early_printk(void)
-{
- unregister_console(&sh_console);
-}
-
diff --git a/arch/sh64/kernel/irq.c b/arch/sh64/kernel/irq.c
index e7e07f8..f68b4f6 100644
--- a/arch/sh64/kernel/irq.c
+++ b/arch/sh64/kernel/irq.c
@@ -26,7 +26,6 @@
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/seq_file.h>
#include <linux/bitops.h>
diff --git a/arch/sh64/kernel/pci_sh5.c b/arch/sh64/kernel/pci_sh5.c
index 9dae689..49862e1 100644
--- a/arch/sh64/kernel/pci_sh5.c
+++ b/arch/sh64/kernel/pci_sh5.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/rwsem.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/errno.h>
diff --git a/arch/sh64/kernel/sh_ksyms.c b/arch/sh64/kernel/sh_ksyms.c
index 7aa4b4f..461ea3d 100644
--- a/arch/sh64/kernel/sh_ksyms.c
+++ b/arch/sh64/kernel/sh_ksyms.c
@@ -17,7 +17,6 @@
#include <linux/sched.h>
#include <linux/in6.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/screen_info.h>
#include <asm/semaphore.h>
diff --git a/arch/sh64/kernel/signal.c b/arch/sh64/kernel/signal.c
index 1666d3e..b76bdfa 100644
--- a/arch/sh64/kernel/signal.c
+++ b/arch/sh64/kernel/signal.c
@@ -16,7 +16,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/sh64/kernel/sys_sh64.c b/arch/sh64/kernel/sys_sh64.c
index ad0fa4e..19126da 100644
--- a/arch/sh64/kernel/sys_sh64.c
+++ b/arch/sh64/kernel/sys_sh64.c
@@ -20,7 +20,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
diff --git a/arch/sh64/kernel/traps.c b/arch/sh64/kernel/traps.c
index c346d7e..9d0d58f 100644
--- a/arch/sh64/kernel/traps.c
+++ b/arch/sh64/kernel/traps.c
@@ -23,7 +23,6 @@
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
diff --git a/arch/sh64/kernel/unwind.c b/arch/sh64/kernel/unwind.c
index f934f97..1214c78 100644
--- a/arch/sh64/kernel/unwind.c
+++ b/arch/sh64/kernel/unwind.c
@@ -46,15 +46,15 @@ static int lookup_prev_stack_frame(unsigned long fp, unsigned long pc,
struct pt_regs *regs)
{
const char *sym;
- char *modname, namebuf[128];
- unsigned long offset, size;
+ char namebuf[128];
+ unsigned long offset;
unsigned long prologue = 0;
unsigned long fp_displacement = 0;
unsigned long fp_prev = 0;
unsigned long offset_r14 = 0, offset_r18 = 0;
int i, found_prologue_end = 0;
- sym = kallsyms_lookup(pc, &size, &offset, &modname, namebuf);
+ sym = kallsyms_lookup(pc, NULL, &offset, NULL, namebuf);
if (!sym)
return -EINVAL;
diff --git a/arch/sh64/mm/fault.c b/arch/sh64/mm/fault.c
index 4f72ab3..4dd8ee8 100644
--- a/arch/sh64/mm/fault.c
+++ b/arch/sh64/mm/fault.c
@@ -22,7 +22,6 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <asm/system.h>
diff --git a/arch/sh64/mm/hugetlbpage.c b/arch/sh64/mm/hugetlbpage.c
index 4b455f6..fa66daa 100644
--- a/arch/sh64/mm/hugetlbpage.c
+++ b/arch/sh64/mm/hugetlbpage.c
@@ -13,7 +13,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
diff --git a/arch/sh64/mm/tlbmiss.c b/arch/sh64/mm/tlbmiss.c
index c861595..d4c5334 100644
--- a/arch/sh64/mm/tlbmiss.c
+++ b/arch/sh64/mm/tlbmiss.c
@@ -32,7 +32,6 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <asm/system.h>
diff --git a/arch/sparc/kernel/head.S b/arch/sparc/kernel/head.S
index 9a219e8..97da13c 100644
--- a/arch/sparc/kernel/head.S
+++ b/arch/sparc/kernel/head.S
@@ -19,7 +19,7 @@
#include <asm/ptrace.h>
#include <asm/psr.h>
#include <asm/page.h>
-#include <asm/kdebug.h>
+#include <linux/kdebug.h>
#include <asm/winmacro.h>
#include <asm/thread_info.h> /* TI_UWINMASK */
#include <asm/errno.h>
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index 5b4841d..bdbefa8 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -24,7 +24,6 @@
#include <linux/random.h>
#include <linux/init.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/threads.h>
#include <linux/spinlock.h>
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index fc874e6..2940d2c 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -23,7 +23,6 @@
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/reboot.h>
#include <linux/delay.h>
#include <linux/pm.h>
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index eccd8e8..64c0ed9 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -31,6 +31,7 @@
#include <linux/spinlock.h>
#include <linux/root_dev.h>
#include <linux/cpu.h>
+#include <linux/kdebug.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -40,7 +41,6 @@
#include <asm/pgtable.h>
#include <asm/traps.h>
#include <asm/vaddrs.h>
-#include <asm/kdebug.h>
#include <asm/mbus.h>
#include <asm/idprom.h>
#include <asm/machines.h>
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index c9301b9..9994cac 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -17,7 +17,6 @@
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/binfmts.h> /* do_coredum */
#include <linux/bitops.h>
diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c
index 6b5f26b..4d9ad590 100644
--- a/arch/sparc/kernel/smp.c
+++ b/arch/sparc/kernel/smp.c
@@ -11,7 +11,6 @@
#include <linux/sched.h>
#include <linux/threads.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/init.h>
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index 0e27e22..116d6a2 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -17,7 +17,6 @@
#include <linux/random.h>
#include <linux/init.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/seq_file.h>
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index c69de5d..098c94f 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -12,7 +12,6 @@
#include <linux/sched.h>
#include <linux/threads.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/init.h>
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index e2d9c01..63ed19b 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -9,7 +9,6 @@
#include <linux/sched.h>
#include <linux/threads.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/init.h>
@@ -405,7 +404,7 @@ void __init smp4m_blackbox_current(unsigned *addr)
addr[0] = 0x81580000 | rd; /* rd %tbr, reg */
addr[2] = 0x8130200a | rd | rs1; /* srl reg, 0xa, reg */
- addr[4] = 0x8008200c | rd | rs1; /* and reg, 3, reg */
+ addr[4] = 0x8008200c | rd | rs1; /* and reg, 0xc, reg */
}
void __init sun4m_init_smp(void)
diff --git a/arch/sparc/kernel/sunos_ioctl.c b/arch/sparc/kernel/sunos_ioctl.c
index 32e8274..e613cc6 100644
--- a/arch/sparc/kernel/sunos_ioctl.c
+++ b/arch/sparc/kernel/sunos_ioctl.c
@@ -21,7 +21,6 @@
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/file.h>
diff --git a/arch/sparc/kernel/sys_solaris.c b/arch/sparc/kernel/sys_solaris.c
index 01b07bb..2226a59 100644
--- a/arch/sparc/kernel/sys_solaris.c
+++ b/arch/sparc/kernel/sys_solaris.c
@@ -12,7 +12,6 @@
#include <linux/ptrace.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/module.h>
asmlinkage int
diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c
index 527687a..dc9ffea 100644
--- a/arch/sparc/kernel/traps.c
+++ b/arch/sparc/kernel/traps.c
@@ -15,6 +15,7 @@
#include <linux/signal.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
+#include <linux/kdebug.h>
#include <asm/delay.h>
#include <asm/system.h>
@@ -22,7 +23,6 @@
#include <asm/oplib.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/kdebug.h>
#include <asm/unistd.h>
#include <asm/traps.h>
diff --git a/arch/sparc/lib/bitext.c b/arch/sparc/lib/bitext.c
index 2e168d1..764b3eb 100644
--- a/arch/sparc/lib/bitext.c
+++ b/arch/sparc/lib/bitext.c
@@ -9,7 +9,6 @@
* fragmentation.
*/
-#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/bitops.h>
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index 9eeed33..c348336 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -18,9 +18,9 @@
#include <linux/signal.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/kdebug.h>
#include <asm/system.h>
#include <asm/page.h>
@@ -30,7 +30,6 @@
#include <asm/oplib.h>
#include <asm/smp.h>
#include <asm/traps.h>
-#include <asm/kdebug.h>
#include <asm/uaccess.h>
extern int prom_node_root;
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 0df7121..e5eaa80 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -18,13 +18,13 @@
#include <linux/bootmem.h>
#include <linux/fs.h>
#include <linux/seq_file.h>
+#include <linux/kdebug.h>
#include <asm/bitext.h>
#include <asm/page.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/io.h>
-#include <asm/kdebug.h>
#include <asm/vaddrs.h>
#include <asm/traps.h>
#include <asm/smp.h>
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index be9e10b..ad8d6b2 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -34,6 +34,10 @@ config MMU
bool
default y
+config QUICKLIST
+ bool
+ default y
+
config STACKTRACE_SUPPORT
bool
default y
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 120c9c3..37c2d36 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,15 +1,16 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21-rc4
-# Sat Mar 17 14:18:44 2007
+# Linux kernel version: 2.6.21
+# Sun May 6 22:46:54 2007
#
CONFIG_SPARC=y
CONFIG_SPARC64=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_64BIT=y
CONFIG_MMU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_TIME_INTERPOLATION=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -108,6 +109,9 @@ CONFIG_GENERIC_HARDIRQS=y
#
# General machine setup
#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
# CONFIG_SMP is not set
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=m
@@ -140,8 +144,7 @@ CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
CONFIG_HAVE_MEMORY_PRESENT=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_STATIC=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
CONFIG_ZONE_DMA_FLAG=0
@@ -151,6 +154,7 @@ CONFIG_SUN_AUXIO=y
CONFIG_SUN_IO=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
+CONFIG_ARCH_SUPPORTS_MSI=y
CONFIG_PCI_MSI=y
# CONFIG_PCI_DEBUG is not set
CONFIG_SUN_OPENPROMFS=m
@@ -178,7 +182,6 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -219,6 +222,7 @@ CONFIG_IPV6=m
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
@@ -292,6 +296,14 @@ CONFIG_NET_TCPPROBE=m
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
#
@@ -312,10 +324,6 @@ CONFIG_FW_LOADER=y
# Connector - unified userspace <-> kernelspace linker
#
CONFIG_CONNECTOR=m
-
-#
-# Memory Technology Devices (MTD)
-#
# CONFIG_MTD is not set
#
@@ -383,7 +391,6 @@ CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_BLK_DEV_OPTI621 is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
CONFIG_IDEDMA_ONLYDISK=y
# CONFIG_BLK_DEV_AEC62XX is not set
CONFIG_BLK_DEV_ALI15X3=y
@@ -413,7 +420,6 @@ CONFIG_BLK_DEV_ALI15X3=y
# CONFIG_IDE_ARM is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
# CONFIG_BLK_DEV_HD is not set
#
@@ -443,6 +449,7 @@ CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_LOGGING is not set
# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
#
# SCSI Transports
@@ -485,6 +492,7 @@ CONFIG_ISCSI_TCP=m
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_ESP_CORE is not set
# CONFIG_SCSI_SUNESP is not set
# CONFIG_SCSI_SRP is not set
@@ -628,9 +636,10 @@ CONFIG_BNX2=m
# CONFIG_TR is not set
#
-# Wireless LAN (non-hamradio)
+# Wireless LAN
#
-# CONFIG_NET_RADIO is not set
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
#
# Wan interfaces
@@ -695,6 +704,12 @@ CONFIG_KEYBOARD_LKKBD=m
# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
CONFIG_MOUSE_SERIAL=y
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_INPUT_JOYSTICK is not set
@@ -702,6 +717,7 @@ CONFIG_MOUSE_SERIAL=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_SPARCSPKR=y
# CONFIG_INPUT_UINPUT is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Hardware I/O ports
@@ -763,11 +779,8 @@ CONFIG_RTC=y
# TPM devices
#
# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
# CONFIG_I2C_CHARDEV is not set
#
@@ -791,17 +804,17 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PASEMI is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
-# CONFIG_I2C_PCA_ISA is not set
#
# Miscellaneous I2C Chip support
@@ -912,7 +925,7 @@ CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
#
-# Frambuffer hardware drivers
+# Frame buffer hardware drivers
#
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
@@ -937,6 +950,8 @@ CONFIG_FB_RADEON_I2C=y
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_XVR500 is not set
+# CONFIG_FB_XVR2500 is not set
# CONFIG_FB_PCI is not set
# CONFIG_FB_VIRTUAL is not set
@@ -1094,6 +1109,14 @@ CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+
+#
# USB support
#
CONFIG_USB_ARCH_HAS_HCD=y
@@ -1106,6 +1129,7 @@ CONFIG_USB=y
# Miscellaneous USB options
#
CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
@@ -1156,10 +1180,6 @@ CONFIG_USB_STORAGE=m
#
# USB Input Devices
#
-CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-CONFIG_USB_HIDDEV=y
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
# CONFIG_USB_ACECAD is not set
@@ -1524,6 +1544,7 @@ CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_LRW=m
+# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_BLOWFISH=m
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index eff0c01..6bf6fb6 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -17,7 +17,7 @@ obj-y := process.o setup.o cpu.o idprom.o \
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \
pci_psycho.o pci_sabre.o pci_schizo.o \
- pci_sun4v.o pci_sun4v_asm.o
+ pci_sun4v.o pci_sun4v_asm.o pci_fire.o
obj-$(CONFIG_SMP) += smp.o trampoline.o
obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o
obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
diff --git a/arch/sparc64/kernel/central.c b/arch/sparc64/kernel/central.c
index c65b2f9..8230099 100644
--- a/arch/sparc64/kernel/central.c
+++ b/arch/sparc64/kernel/central.c
@@ -98,7 +98,7 @@ void apply_central_ranges(struct linux_central *central,
central->num_central_ranges);
}
-void * __init central_alloc_bootmem(unsigned long size)
+static void * __init central_alloc_bootmem(unsigned long size)
{
void *ret;
@@ -116,7 +116,7 @@ static unsigned long prom_reg_to_paddr(struct linux_prom_registers *r)
return ret | (unsigned long) r->phys_addr;
}
-static void probe_other_fhcs(void)
+static void __init probe_other_fhcs(void)
{
struct device_node *dp;
const struct linux_prom64_registers *fpregs;
@@ -298,7 +298,7 @@ static void init_all_fhc_hw(void)
}
-void central_probe(void)
+void __init central_probe(void)
{
struct linux_prom_registers fpregs[6];
const struct linux_prom_registers *pr;
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 6241e3d..3edc18e 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -279,7 +279,7 @@ static void sun4u_irq_enable(unsigned int virt_irq)
struct irq_handler_data *data = get_irq_chip_data(virt_irq);
if (likely(data)) {
- unsigned long cpuid, imap;
+ unsigned long cpuid, imap, val;
unsigned int tid;
cpuid = irq_choose_cpu(virt_irq);
@@ -287,7 +287,11 @@ static void sun4u_irq_enable(unsigned int virt_irq)
tid = sun4u_compute_tid(imap, cpuid);
- upa_writel(tid | IMAP_VALID, imap);
+ val = upa_readq(imap);
+ val &= ~(IMAP_TID_UPA | IMAP_TID_JBUS |
+ IMAP_AID_SAFARI | IMAP_NID_SAFARI);
+ val |= tid | IMAP_VALID;
+ upa_writeq(val, imap);
}
}
@@ -297,10 +301,10 @@ static void sun4u_irq_disable(unsigned int virt_irq)
if (likely(data)) {
unsigned long imap = data->imap;
- u32 tmp = upa_readl(imap);
+ u32 tmp = upa_readq(imap);
tmp &= ~IMAP_VALID;
- upa_writel(tmp, imap);
+ upa_writeq(tmp, imap);
}
}
@@ -309,7 +313,7 @@ static void sun4u_irq_end(unsigned int virt_irq)
struct irq_handler_data *data = get_irq_chip_data(virt_irq);
if (likely(data))
- upa_writel(ICLR_IDLE, data->iclr);
+ upa_writeq(ICLR_IDLE, data->iclr);
}
static void sun4v_irq_enable(unsigned int virt_irq)
@@ -465,7 +469,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
BUG_ON(tlb_type == hypervisor);
- ino = (upa_readl(imap) & (IMAP_IGN | IMAP_INO)) + inofixup;
+ ino = (upa_readq(imap) & (IMAP_IGN | IMAP_INO)) + inofixup;
bucket = &ivector_table[ino];
if (!bucket->virt_irq) {
bucket->virt_irq = virt_irq_alloc(__irq(bucket));
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index ae221f0..a44fe47 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -6,7 +6,7 @@
#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <linux/module.h>
-#include <asm/kdebug.h>
+#include <linux/kdebug.h>
#include <asm/signal.h>
#include <asm/cacheflush.h>
#include <asm/uaccess.h>
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 9a54954..966861b 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -14,7 +14,6 @@
#include <linux/sched.h>
#include <linux/capability.h>
#include <linux/errno.h>
-#include <linux/smp_lock.h>
#include <linux/msi.h>
#include <linux/irq.h>
#include <linux/init.h>
@@ -190,6 +189,7 @@ extern void schizo_init(struct device_node *, const char *);
extern void schizo_plus_init(struct device_node *, const char *);
extern void tomatillo_init(struct device_node *, const char *);
extern void sun4v_pci_init(struct device_node *, const char *);
+extern void fire_pci_init(struct device_node *, const char *);
static struct {
char *model_name;
@@ -207,6 +207,7 @@ static struct {
{ "SUNW,tomatillo", tomatillo_init },
{ "pci108e,a801", tomatillo_init },
{ "SUNW,sun4v-pci", sun4v_pci_init },
+ { "pciex108e,80f0", fire_pci_init },
};
#define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \
sizeof(pci_controller_table[0]))
@@ -436,6 +437,13 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
printk(" class: 0x%x device name: %s\n",
dev->class, pci_name(dev));
+ /* I have seen IDE devices which will not respond to
+ * the bmdma simplex check reads if bus mastering is
+ * disabled.
+ */
+ if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)
+ pci_set_master(dev);
+
dev->current_state = 4; /* unknown power state */
dev->error_state = pci_channel_io_normal;
@@ -468,7 +476,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
return dev;
}
-static void __init apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p)
+static void __devinit apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p)
{
u32 idx, first, last;
@@ -497,9 +505,9 @@ static void __init pci_resource_adjust(struct resource *res,
/* Cook up fake bus resources for SUNW,simba PCI bridges which lack
* a proper 'ranges' property.
*/
-static void __init apb_fake_ranges(struct pci_dev *dev,
- struct pci_bus *bus,
- struct pci_pbm_info *pbm)
+static void __devinit apb_fake_ranges(struct pci_dev *dev,
+ struct pci_bus *bus,
+ struct pci_pbm_info *pbm)
{
struct resource *res;
u32 first, last;
@@ -522,15 +530,15 @@ static void __init apb_fake_ranges(struct pci_dev *dev,
pci_resource_adjust(res, &pbm->mem_space);
}
-static void __init pci_of_scan_bus(struct pci_pbm_info *pbm,
- struct device_node *node,
- struct pci_bus *bus);
+static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm,
+ struct device_node *node,
+ struct pci_bus *bus);
#define GET_64BIT(prop, i) ((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1])
-void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
- struct device_node *node,
- struct pci_dev *dev)
+static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm,
+ struct device_node *node,
+ struct pci_dev *dev)
{
struct pci_bus *bus;
const u32 *busrange, *ranges;
@@ -629,9 +637,9 @@ simba_cont:
pci_of_scan_bus(pbm, node, bus);
}
-static void __init pci_of_scan_bus(struct pci_pbm_info *pbm,
- struct device_node *node,
- struct pci_bus *bus)
+static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm,
+ struct device_node *node,
+ struct pci_bus *bus)
{
struct device_node *child;
const u32 *reg;
@@ -733,7 +741,7 @@ int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev,
return PCIBIOS_SUCCESSFUL;
}
-struct pci_bus * __init pci_scan_one_pbm(struct pci_pbm_info *pbm)
+struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm)
{
struct pci_controller_info *p = pbm->parent;
struct device_node *node = pbm->prom_node;
diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c
new file mode 100644
index 0000000..0fe6266
--- /dev/null
+++ b/arch/sparc64/kernel/pci_fire.c
@@ -0,0 +1,418 @@
+/* pci_fire.c: Sun4u platform PCI-E controller support.
+ *
+ * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include <asm/pbm.h>
+#include <asm/oplib.h>
+#include <asm/prom.h>
+
+#include "pci_impl.h"
+
+#define fire_read(__reg) \
+({ u64 __ret; \
+ __asm__ __volatile__("ldxa [%1] %2, %0" \
+ : "=r" (__ret) \
+ : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \
+ : "memory"); \
+ __ret; \
+})
+#define fire_write(__reg, __val) \
+ __asm__ __volatile__("stxa %0, [%1] %2" \
+ : /* no outputs */ \
+ : "r" (__val), "r" (__reg), \
+ "i" (ASI_PHYS_BYPASS_EC_E) \
+ : "memory")
+
+/* Fire config space address format is nearly identical to
+ * that of SCHIZO and PSYCHO, except that in order to accomodate
+ * PCI-E extended config space the encoding can handle 12 bits
+ * of register address:
+ *
+ * 32 28 27 20 19 15 14 12 11 2 1 0
+ * -------------------------------------------------
+ * |0 0 0 0 0| bus | device | function | reg | 0 0 |
+ * -------------------------------------------------
+ */
+#define FIRE_CONFIG_BASE(PBM) ((PBM)->config_space)
+#define FIRE_CONFIG_ENCODE(BUS, DEVFN, REG) \
+ (((unsigned long)(BUS) << 20) | \
+ ((unsigned long)(DEVFN) << 12) | \
+ ((unsigned long)(REG)))
+
+static void *fire_pci_config_mkaddr(struct pci_pbm_info *pbm,
+ unsigned char bus,
+ unsigned int devfn,
+ int where)
+{
+ if (!pbm)
+ return NULL;
+ return (void *)
+ (FIRE_CONFIG_BASE(pbm) |
+ FIRE_CONFIG_ENCODE(bus, devfn, where));
+}
+
+/* FIRE PCI configuration space accessors. */
+
+static int fire_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
+ int where, int size, u32 *value)
+{
+ struct pci_pbm_info *pbm = bus_dev->sysdata;
+ unsigned char bus = bus_dev->number;
+ u32 *addr;
+ u16 tmp16;
+ u8 tmp8;
+
+ if (bus_dev == pbm->pci_bus && devfn == 0x00)
+ return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
+ size, value);
+ switch (size) {
+ case 1:
+ *value = 0xff;
+ break;
+ case 2:
+ *value = 0xffff;
+ break;
+ case 4:
+ *value = 0xffffffff;
+ break;
+ }
+
+ addr = fire_pci_config_mkaddr(pbm, bus, devfn, where);
+ if (!addr)
+ return PCIBIOS_SUCCESSFUL;
+
+ switch (size) {
+ case 1:
+ pci_config_read8((u8 *)addr, &tmp8);
+ *value = tmp8;
+ break;
+
+ case 2:
+ if (where & 0x01) {
+ printk("pci_read_config_word: misaligned reg [%x]\n",
+ where);
+ return PCIBIOS_SUCCESSFUL;
+ }
+ pci_config_read16((u16 *)addr, &tmp16);
+ *value = tmp16;
+ break;
+
+ case 4:
+ if (where & 0x03) {
+ printk("pci_read_config_dword: misaligned reg [%x]\n",
+ where);
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ pci_config_read32(addr, value);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int fire_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
+ int where, int size, u32 value)
+{
+ struct pci_pbm_info *pbm = bus_dev->sysdata;
+ unsigned char bus = bus_dev->number;
+ u32 *addr;
+
+ if (bus_dev == pbm->pci_bus && devfn == 0x00)
+ return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
+ size, value);
+ addr = fire_pci_config_mkaddr(pbm, bus, devfn, where);
+ if (!addr)
+ return PCIBIOS_SUCCESSFUL;
+
+ switch (size) {
+ case 1:
+ pci_config_write8((u8 *)addr, value);
+ break;
+
+ case 2:
+ if (where & 0x01) {
+ printk("pci_write_config_word: misaligned reg [%x]\n",
+ where);
+ return PCIBIOS_SUCCESSFUL;
+ }
+ pci_config_write16((u16 *)addr, value);
+ break;
+
+ case 4:
+ if (where & 0x03) {
+ printk("pci_write_config_dword: misaligned reg [%x]\n",
+ where);
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ pci_config_write32(addr, value);
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_fire_ops = {
+ .read = fire_read_pci_cfg,
+ .write = fire_write_pci_cfg,
+};
+
+static void pbm_scan_bus(struct pci_controller_info *p,
+ struct pci_pbm_info *pbm)
+{
+ pbm->pci_bus = pci_scan_one_pbm(pbm);
+}
+
+static void pci_fire_scan_bus(struct pci_controller_info *p)
+{
+ struct device_node *dp;
+
+ if ((dp = p->pbm_A.prom_node) != NULL)
+ pbm_scan_bus(p, &p->pbm_A);
+
+ if ((dp = p->pbm_B.prom_node) != NULL)
+ pbm_scan_bus(p, &p->pbm_B);
+
+ /* XXX register error interrupt handlers XXX */
+}
+
+#define FIRE_IOMMU_CONTROL 0x40000UL
+#define FIRE_IOMMU_TSBBASE 0x40008UL
+#define FIRE_IOMMU_FLUSH 0x40100UL
+#define FIRE_IOMMU_FLUSHINV 0x40100UL
+
+static void pci_fire_pbm_iommu_init(struct pci_pbm_info *pbm)
+{
+ struct iommu *iommu = pbm->iommu;
+ u32 vdma[2], dma_mask;
+ u64 control;
+ int tsbsize;
+
+ /* No virtual-dma property on these guys, use largest size. */
+ vdma[0] = 0xc0000000; /* base */
+ vdma[1] = 0x40000000; /* size */
+ dma_mask = 0xffffffff;
+ tsbsize = 128;
+
+ /* Register addresses. */
+ iommu->iommu_control = pbm->pbm_regs + FIRE_IOMMU_CONTROL;
+ iommu->iommu_tsbbase = pbm->pbm_regs + FIRE_IOMMU_TSBBASE;
+ iommu->iommu_flush = pbm->pbm_regs + FIRE_IOMMU_FLUSH;
+ iommu->iommu_flushinv = pbm->pbm_regs + FIRE_IOMMU_FLUSHINV;
+
+ /* We use the main control/status register of FIRE as the write
+ * completion register.
+ */
+ iommu->write_complete_reg = pbm->controller_regs + 0x410000UL;
+
+ /*
+ * Invalidate TLB Entries.
+ */
+ fire_write(iommu->iommu_flushinv, ~(u64)0);
+
+ pci_iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask);
+
+ fire_write(iommu->iommu_tsbbase, __pa(iommu->page_table) | 0x7UL);
+
+ control = fire_read(iommu->iommu_control);
+ control |= (0x00000400 /* TSB cache snoop enable */ |
+ 0x00000300 /* Cache mode */ |
+ 0x00000002 /* Bypass enable */ |
+ 0x00000001 /* Translation enable */);
+ fire_write(iommu->iommu_control, control);
+}
+
+/* Based at pbm->controller_regs */
+#define FIRE_PARITY_CONTROL 0x470010UL
+#define FIRE_PARITY_ENAB 0x8000000000000000UL
+#define FIRE_FATAL_RESET_CTL 0x471028UL
+#define FIRE_FATAL_RESET_SPARE 0x0000000004000000UL
+#define FIRE_FATAL_RESET_MB 0x0000000002000000UL
+#define FIRE_FATAL_RESET_CPE 0x0000000000008000UL
+#define FIRE_FATAL_RESET_APE 0x0000000000004000UL
+#define FIRE_FATAL_RESET_PIO 0x0000000000000040UL
+#define FIRE_FATAL_RESET_JW 0x0000000000000004UL
+#define FIRE_FATAL_RESET_JI 0x0000000000000002UL
+#define FIRE_FATAL_RESET_JR 0x0000000000000001UL
+#define FIRE_CORE_INTR_ENABLE 0x471800UL
+
+/* Based at pbm->pbm_regs */
+#define FIRE_TLU_CTRL 0x80000UL
+#define FIRE_TLU_CTRL_TIM 0x00000000da000000UL
+#define FIRE_TLU_CTRL_QDET 0x0000000000000100UL
+#define FIRE_TLU_CTRL_CFG 0x0000000000000001UL
+#define FIRE_TLU_DEV_CTRL 0x90008UL
+#define FIRE_TLU_LINK_CTRL 0x90020UL
+#define FIRE_TLU_LINK_CTRL_CLK 0x0000000000000040UL
+#define FIRE_LPU_RESET 0xe2008UL
+#define FIRE_LPU_LLCFG 0xe2200UL
+#define FIRE_LPU_LLCFG_VC0 0x0000000000000100UL
+#define FIRE_LPU_FCTRL_UCTRL 0xe2240UL
+#define FIRE_LPU_FCTRL_UCTRL_N 0x0000000000000002UL
+#define FIRE_LPU_FCTRL_UCTRL_P 0x0000000000000001UL
+#define FIRE_LPU_TXL_FIFOP 0xe2430UL
+#define FIRE_LPU_LTSSM_CFG2 0xe2788UL
+#define FIRE_LPU_LTSSM_CFG3 0xe2790UL
+#define FIRE_LPU_LTSSM_CFG4 0xe2798UL
+#define FIRE_LPU_LTSSM_CFG5 0xe27a0UL
+#define FIRE_DMC_IENAB 0x31800UL
+#define FIRE_DMC_DBG_SEL_A 0x53000UL
+#define FIRE_DMC_DBG_SEL_B 0x53008UL
+#define FIRE_PEC_IENAB 0x51800UL
+
+static void pci_fire_hw_init(struct pci_pbm_info *pbm)
+{
+ u64 val;
+
+ fire_write(pbm->controller_regs + FIRE_PARITY_CONTROL,
+ FIRE_PARITY_ENAB);
+
+ fire_write(pbm->controller_regs + FIRE_FATAL_RESET_CTL,
+ (FIRE_FATAL_RESET_SPARE |
+ FIRE_FATAL_RESET_MB |
+ FIRE_FATAL_RESET_CPE |
+ FIRE_FATAL_RESET_APE |
+ FIRE_FATAL_RESET_PIO |
+ FIRE_FATAL_RESET_JW |
+ FIRE_FATAL_RESET_JI |
+ FIRE_FATAL_RESET_JR));
+
+ fire_write(pbm->controller_regs + FIRE_CORE_INTR_ENABLE, ~(u64)0);
+
+ val = fire_read(pbm->pbm_regs + FIRE_TLU_CTRL);
+ val |= (FIRE_TLU_CTRL_TIM |
+ FIRE_TLU_CTRL_QDET |
+ FIRE_TLU_CTRL_CFG);
+ fire_write(pbm->pbm_regs + FIRE_TLU_CTRL, val);
+ fire_write(pbm->pbm_regs + FIRE_TLU_DEV_CTRL, 0);
+ fire_write(pbm->pbm_regs + FIRE_TLU_LINK_CTRL,
+ FIRE_TLU_LINK_CTRL_CLK);
+
+ fire_write(pbm->pbm_regs + FIRE_LPU_RESET, 0);
+ fire_write(pbm->pbm_regs + FIRE_LPU_LLCFG,
+ FIRE_LPU_LLCFG_VC0);
+ fire_write(pbm->pbm_regs + FIRE_LPU_FCTRL_UCTRL,
+ (FIRE_LPU_FCTRL_UCTRL_N |
+ FIRE_LPU_FCTRL_UCTRL_P));
+ fire_write(pbm->pbm_regs + FIRE_LPU_TXL_FIFOP,
+ ((0xffff << 16) | (0x0000 << 0)));
+ fire_write(pbm->pbm_regs + FIRE_LPU_LTSSM_CFG2, 3000000);
+ fire_write(pbm->pbm_regs + FIRE_LPU_LTSSM_CFG3, 500000);
+ fire_write(pbm->pbm_regs + FIRE_LPU_LTSSM_CFG4,
+ (2 << 16) | (140 << 8));
+ fire_write(pbm->pbm_regs + FIRE_LPU_LTSSM_CFG5, 0);
+
+ fire_write(pbm->pbm_regs + FIRE_DMC_IENAB, ~(u64)0);
+ fire_write(pbm->pbm_regs + FIRE_DMC_DBG_SEL_A, 0);
+ fire_write(pbm->pbm_regs + FIRE_DMC_DBG_SEL_B, 0);
+
+ fire_write(pbm->pbm_regs + FIRE_PEC_IENAB, ~(u64)0);
+}
+
+static void pci_fire_pbm_init(struct pci_controller_info *p,
+ struct device_node *dp, u32 portid)
+{
+ const struct linux_prom64_registers *regs;
+ struct pci_pbm_info *pbm;
+ const u32 *ino_bitmap;
+ const unsigned int *busrange;
+
+ if ((portid & 1) == 0)
+ pbm = &p->pbm_A;
+ else
+ pbm = &p->pbm_B;
+
+ pbm->portid = portid;
+ pbm->parent = p;
+ pbm->prom_node = dp;
+ pbm->name = dp->full_name;
+
+ regs = of_get_property(dp, "reg", NULL);
+ pbm->pbm_regs = regs[0].phys_addr;
+ pbm->controller_regs = regs[1].phys_addr - 0x410000UL;
+
+ printk("%s: SUN4U PCIE Bus Module\n", pbm->name);
+
+ pci_determine_mem_io_space(pbm);
+
+ ino_bitmap = of_get_property(dp, "ino-bitmap", NULL);
+ pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) |
+ ((u64)ino_bitmap[0] << 0UL));
+
+ busrange = of_get_property(dp, "bus-range", NULL);
+ pbm->pci_first_busno = busrange[0];
+ pbm->pci_last_busno = busrange[1];
+
+ pci_fire_hw_init(pbm);
+ pci_fire_pbm_iommu_init(pbm);
+}
+
+static inline int portid_compare(u32 x, u32 y)
+{
+ if (x == (y ^ 1))
+ return 1;
+ return 0;
+}
+
+void fire_pci_init(struct device_node *dp, const char *model_name)
+{
+ struct pci_controller_info *p;
+ u32 portid = of_getintprop_default(dp, "portid", 0xff);
+ struct iommu *iommu;
+
+ for (p = pci_controller_root; p; p = p->next) {
+ struct pci_pbm_info *pbm;
+
+ if (p->pbm_A.prom_node && p->pbm_B.prom_node)
+ continue;
+
+ pbm = (p->pbm_A.prom_node ?
+ &p->pbm_A :
+ &p->pbm_B);
+
+ if (portid_compare(pbm->portid, portid)) {
+ pci_fire_pbm_init(p, dp, portid);
+ return;
+ }
+ }
+
+ p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC);
+ if (!p)
+ goto fatal_memory_error;
+
+ iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC);
+ if (!iommu)
+ goto fatal_memory_error;
+
+ p->pbm_A.iommu = iommu;
+
+ iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC);
+ if (!iommu)
+ goto fatal_memory_error;
+
+ p->pbm_B.iommu = iommu;
+
+ p->next = pci_controller_root;
+ pci_controller_root = p;
+
+ p->index = pci_num_controllers++;
+
+ p->scan_bus = pci_fire_scan_bus;
+ /* XXX MSI support XXX */
+ p->pci_ops = &pci_fire_ops;
+
+ /* Like PSYCHO and SCHIZO we have a 2GB aligned area
+ * for memory space.
+ */
+ pci_memspace_mask = 0x7fffffffUL;
+
+ pci_fire_pbm_init(p, dp, portid);
+ return;
+
+fatal_memory_error:
+ prom_printf("PCI_FIRE: Fatal memory allocation error.\n");
+ prom_halt();
+}
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index 6671277..9e405cb 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -37,17 +37,21 @@
/* Must be invoked under the IOMMU lock. */
static void __iommu_flushall(struct iommu *iommu)
{
- unsigned long tag;
- int entry;
+ if (iommu->iommu_flushinv) {
+ pci_iommu_write(iommu->iommu_flushinv, ~(u64)0);
+ } else {
+ unsigned long tag;
+ int entry;
- tag = iommu->iommu_flush + (0xa580UL - 0x0210UL);
- for (entry = 0; entry < 16; entry++) {
- pci_iommu_write(tag, 0);
- tag += 8;
- }
+ tag = iommu->iommu_flush + (0xa580UL - 0x0210UL);
+ for (entry = 0; entry < 16; entry++) {
+ pci_iommu_write(tag, 0);
+ tag += 8;
+ }
- /* Ensure completion of previous PIO writes. */
- (void) pci_iommu_read(iommu->write_complete_reg);
+ /* Ensure completion of previous PIO writes. */
+ (void) pci_iommu_read(iommu->write_complete_reg);
+ }
}
#define IOPTE_CONSISTENT(CTX) \
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index a114151..8e3c6e4 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -19,7 +19,6 @@
#include <linux/kallsyms.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index 5e1fcd0..c54d4d8 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -386,11 +386,9 @@ static unsigned int psycho_irq_build(struct device_node *dp,
/* Now build the IRQ bucket. */
imap = controller_regs + imap_off;
- imap += 4;
iclr_off = psycho_iclr_offset(ino);
iclr = controller_regs + iclr_off;
- iclr += 4;
if ((ino & 0x20) == 0)
inofixup = ino & 0x03;
@@ -398,7 +396,7 @@ static unsigned int psycho_irq_build(struct device_node *dp,
return build_irq(inofixup, iclr, imap);
}
-static void psycho_irq_trans_init(struct device_node *dp)
+static void __init psycho_irq_trans_init(struct device_node *dp)
{
const struct linux_prom64_registers *regs;
@@ -613,11 +611,9 @@ static unsigned int sabre_irq_build(struct device_node *dp,
/* Now build the IRQ bucket. */
imap = controller_regs + imap_off;
- imap += 4;
iclr_off = sabre_iclr_offset(ino);
iclr = controller_regs + iclr_off;
- iclr += 4;
if ((ino & 0x20) == 0)
inofixup = ino & 0x03;
@@ -640,7 +636,7 @@ static unsigned int sabre_irq_build(struct device_node *dp,
return virt_irq;
}
-static void sabre_irq_trans_init(struct device_node *dp)
+static void __init sabre_irq_trans_init(struct device_node *dp)
{
const struct linux_prom64_registers *regs;
struct sabre_irq_data *irq_data;
@@ -679,13 +675,14 @@ static unsigned long schizo_iclr_offset(unsigned long ino)
static unsigned long schizo_ino_to_iclr(unsigned long pbm_regs,
unsigned int ino)
{
- return pbm_regs + schizo_iclr_offset(ino) + 4;
+
+ return pbm_regs + schizo_iclr_offset(ino);
}
static unsigned long schizo_ino_to_imap(unsigned long pbm_regs,
unsigned int ino)
{
- return pbm_regs + schizo_imap_offset(ino) + 4;
+ return pbm_regs + schizo_imap_offset(ino);
}
#define schizo_read(__reg) \
@@ -796,7 +793,8 @@ static unsigned int schizo_irq_build(struct device_node *dp,
return virt_irq;
}
-static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo)
+static void __init __schizo_irq_trans_init(struct device_node *dp,
+ int is_tomatillo)
{
const struct linux_prom64_registers *regs;
struct schizo_irq_data *irq_data;
@@ -818,12 +816,12 @@ static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo)
irq_data->chip_version = of_getintprop_default(dp, "version#", 0);
}
-static void schizo_irq_trans_init(struct device_node *dp)
+static void __init schizo_irq_trans_init(struct device_node *dp)
{
__schizo_irq_trans_init(dp, 0);
}
-static void tomatillo_irq_trans_init(struct device_node *dp)
+static void __init tomatillo_irq_trans_init(struct device_node *dp)
{
__schizo_irq_trans_init(dp, 1);
}
@@ -837,7 +835,7 @@ static unsigned int pci_sun4v_irq_build(struct device_node *dp,
return sun4v_build_irq(devhandle, devino);
}
-static void pci_sun4v_irq_trans_init(struct device_node *dp)
+static void __init pci_sun4v_irq_trans_init(struct device_node *dp)
{
const struct linux_prom64_registers *regs;
@@ -848,6 +846,85 @@ static void pci_sun4v_irq_trans_init(struct device_node *dp)
dp->irq_trans->data = (void *) (unsigned long)
((regs->phys_addr >> 32UL) & 0x0fffffff);
}
+
+struct fire_irq_data {
+ unsigned long pbm_regs;
+ u32 portid;
+};
+
+#define FIRE_IMAP_BASE 0x001000
+#define FIRE_ICLR_BASE 0x001400
+
+static unsigned long fire_imap_offset(unsigned long ino)
+{
+ return FIRE_IMAP_BASE + (ino * 8UL);
+}
+
+static unsigned long fire_iclr_offset(unsigned long ino)
+{
+ return FIRE_ICLR_BASE + (ino * 8UL);
+}
+
+static unsigned long fire_ino_to_iclr(unsigned long pbm_regs,
+ unsigned int ino)
+{
+ return pbm_regs + fire_iclr_offset(ino);
+}
+
+static unsigned long fire_ino_to_imap(unsigned long pbm_regs,
+ unsigned int ino)
+{
+ return pbm_regs + fire_imap_offset(ino);
+}
+
+static unsigned int fire_irq_build(struct device_node *dp,
+ unsigned int ino,
+ void *_data)
+{
+ struct fire_irq_data *irq_data = _data;
+ unsigned long pbm_regs = irq_data->pbm_regs;
+ unsigned long imap, iclr;
+ unsigned long int_ctrlr;
+
+ ino &= 0x3f;
+
+ /* Now build the IRQ bucket. */
+ imap = fire_ino_to_imap(pbm_regs, ino);
+ iclr = fire_ino_to_iclr(pbm_regs, ino);
+
+ /* Set the interrupt controller number. */
+ int_ctrlr = 1 << 6;
+ upa_writeq(int_ctrlr, imap);
+
+ /* The interrupt map registers do not have an INO field
+ * like other chips do. They return zero in the INO
+ * field, and the interrupt controller number is controlled
+ * in bits 6 thru 9. So in order for build_irq() to get
+ * the INO right we pass it in as part of the fixup
+ * which will get added to the map register zero value
+ * read by build_irq().
+ */
+ ino |= (irq_data->portid << 6);
+ ino -= int_ctrlr;
+ return build_irq(ino, iclr, imap);
+}
+
+static void __init fire_irq_trans_init(struct device_node *dp)
+{
+ const struct linux_prom64_registers *regs;
+ struct fire_irq_data *irq_data;
+
+ dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
+ dp->irq_trans->irq_build = fire_irq_build;
+
+ irq_data = prom_early_alloc(sizeof(struct fire_irq_data));
+
+ regs = of_get_property(dp, "reg", NULL);
+ dp->irq_trans->data = irq_data;
+
+ irq_data->pbm_regs = regs[0].phys_addr;
+ irq_data->portid = of_getintprop_default(dp, "portid", 0);
+}
#endif /* CONFIG_PCI */
#ifdef CONFIG_SBUS
@@ -995,7 +1072,7 @@ static unsigned int sbus_of_build_irq(struct device_node *dp,
return build_irq(sbus_level, iclr, imap);
}
-static void sbus_irq_trans_init(struct device_node *dp)
+static void __init sbus_irq_trans_init(struct device_node *dp)
{
const struct linux_prom64_registers *regs;
@@ -1042,7 +1119,7 @@ static unsigned int central_build_irq(struct device_node *dp,
return build_irq(0, iclr, imap);
}
-static void central_irq_trans_init(struct device_node *dp)
+static void __init central_irq_trans_init(struct device_node *dp)
{
dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
dp->irq_trans->irq_build = central_build_irq;
@@ -1056,7 +1133,7 @@ struct irq_trans {
};
#ifdef CONFIG_PCI
-static struct irq_trans pci_irq_trans_table[] = {
+static struct irq_trans __initdata pci_irq_trans_table[] = {
{ "SUNW,sabre", sabre_irq_trans_init },
{ "pci108e,a000", sabre_irq_trans_init },
{ "pci108e,a001", sabre_irq_trans_init },
@@ -1069,6 +1146,7 @@ static struct irq_trans pci_irq_trans_table[] = {
{ "SUNW,tomatillo", tomatillo_irq_trans_init },
{ "pci108e,a801", tomatillo_irq_trans_init },
{ "SUNW,sun4v-pci", pci_sun4v_irq_trans_init },
+ { "pciex108e,80f0", fire_irq_trans_init },
};
#endif
@@ -1081,7 +1159,7 @@ static unsigned int sun4v_vdev_irq_build(struct device_node *dp,
return sun4v_build_irq(devhandle, devino);
}
-static void sun4v_vdev_irq_trans_init(struct device_node *dp)
+static void __init sun4v_vdev_irq_trans_init(struct device_node *dp)
{
const struct linux_prom64_registers *regs;
@@ -1093,7 +1171,7 @@ static void sun4v_vdev_irq_trans_init(struct device_node *dp)
((regs->phys_addr >> 32UL) & 0x0fffffff);
}
-static void irq_trans_init(struct device_node *dp)
+static void __init irq_trans_init(struct device_node *dp)
{
#ifdef CONFIG_PCI
const char *model;
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 96d56a8..203e873 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -20,7 +20,6 @@
#include <linux/unistd.h>
#include <linux/mm.h>
#include <linux/tty.h>
-#include <linux/smp_lock.h>
#include <linux/binfmts.h>
#include <linux/bitops.h>
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index c45f21b..8c1c121 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -17,7 +17,6 @@
#include <linux/unistd.h>
#include <linux/mm.h>
#include <linux/tty.h>
-#include <linux/smp_lock.h>
#include <linux/binfmts.h>
#include <linux/compat.h>
#include <linux/bitops.h>
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 1fac215..8087d67 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -10,7 +10,6 @@
#include <linux/pagemap.h>
#include <linux/threads.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/delay.h>
diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c
index c4d15f2..47f92a5 100644
--- a/arch/sparc64/kernel/stacktrace.c
+++ b/arch/sparc64/kernel/stacktrace.c
@@ -3,22 +3,16 @@
#include <linux/thread_info.h>
#include <asm/ptrace.h>
-void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+void save_stack_trace(struct stack_trace *trace)
{
unsigned long ksp, fp, thread_base;
- struct thread_info *tp;
+ struct thread_info *tp = task_thread_info(current);
- if (!task)
- task = current;
- tp = task_thread_info(task);
- if (task == current) {
- flushw_all();
- __asm__ __volatile__(
- "mov %%fp, %0"
- : "=r" (ksp)
- );
- } else
- ksp = tp->ksp;
+ flushw_all();
+ __asm__ __volatile__(
+ "mov %%fp, %0"
+ : "=r" (ksp)
+ );
fp = ksp + STACK_BIAS;
thread_base = (unsigned long) tp;
diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c
index a05e43d..75d2bad 100644
--- a/arch/sparc64/kernel/sunos_ioctl32.c
+++ b/arch/sparc64/kernel/sunos_ioctl32.c
@@ -22,7 +22,6 @@
#include <linux/file.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/compat.h>
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index a53d4ab..d108eeb 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -19,7 +19,6 @@
#include <linux/mman.h>
#include <linux/utsname.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/syscalls.h>
#include <linux/ipc.h>
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 7876a02..692e46a 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -775,15 +775,25 @@ asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv,
asmlinkage long sys32_utimes(char __user *filename,
struct compat_timeval __user *tvs)
{
- struct timeval ktvs[2];
+ struct timespec tv[2];
if (tvs) {
+ struct timeval ktvs[2];
if (get_tv32(&ktvs[0], tvs) ||
get_tv32(&ktvs[1], 1+tvs))
return -EFAULT;
+
+ if (ktvs[0].tv_usec < 0 || ktvs[0].tv_usec >= 1000000 ||
+ ktvs[1].tv_usec < 0 || ktvs[1].tv_usec >= 1000000)
+ return -EINVAL;
+
+ tv[0].tv_sec = ktvs[0].tv_sec;
+ tv[0].tv_nsec = 1000 * ktvs[0].tv_usec;
+ tv[1].tv_sec = ktvs[1].tv_sec;
+ tv[1].tv_nsec = 1000 * ktvs[1].tv_usec;
}
- return do_utimes(AT_FDCWD, filename, (tvs ? &ktvs[0] : NULL));
+ return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL);
}
/* These are here just in case some old sparc32 binary calls it. */
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index ad67784..dc652f2 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -15,9 +15,9 @@
#include <linux/kallsyms.h>
#include <linux/signal.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/init.h>
+#include <linux/kdebug.h>
#include <asm/delay.h>
#include <asm/system.h>
@@ -36,26 +36,12 @@
#include <asm/psrcompat.h>
#include <asm/processor.h>
#include <asm/timer.h>
-#include <asm/kdebug.h>
#include <asm/head.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
#include <asm/prom.h>
-ATOMIC_NOTIFIER_HEAD(sparc64die_chain);
-
-int register_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_register(&sparc64die_chain, nb);
-}
-EXPORT_SYMBOL(register_die_notifier);
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&sparc64die_chain, nb);
-}
-EXPORT_SYMBOL(unregister_die_notifier);
/* When an irrecoverable trap occurs at tl > 0, the trap entry
* code logs the trap state registers at every level in the trap
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
index bc18d48..953be81 100644
--- a/arch/sparc64/kernel/unaligned.c
+++ b/arch/sparc64/kernel/unaligned.c
@@ -18,7 +18,6 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/bitops.h>
#include <linux/kallsyms.h>
#include <asm/fpumacro.h>
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index 55ae802..c32e309 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -15,11 +15,11 @@
#include <linux/signal.h>
#include <linux/mm.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>
+#include <linux/kdebug.h>
#include <asm/page.h>
#include <asm/pgtable.h>
@@ -29,7 +29,6 @@
#include <asm/asi.h>
#include <asm/lsu.h>
#include <asm/sections.h>
-#include <asm/kdebug.h>
#include <asm/mmu_context.h>
#ifdef CONFIG_KPROBES
diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c
index 00677b5..eaba9b7 100644
--- a/arch/sparc64/mm/hugetlbpage.c
+++ b/arch/sparc64/mm/hugetlbpage.c
@@ -10,7 +10,6 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
@@ -175,6 +174,12 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
if (len > task_size)
return -ENOMEM;
+ if (flags & MAP_FIXED) {
+ if (prepare_hugepage_range(addr, len, pgoff))
+ return -EINVAL;
+ return addr;
+ }
+
if (addr) {
addr = ALIGN(addr, HPAGE_SIZE);
vma = find_vma(mm, addr);
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index cafadcb..d7004ea 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -164,30 +164,6 @@ unsigned long sparc64_kern_sec_context __read_mostly;
int bigkernel = 0;
-struct kmem_cache *pgtable_cache __read_mostly;
-
-static void zero_ctor(void *addr, struct kmem_cache *cache, unsigned long flags)
-{
- clear_page(addr);
-}
-
-extern void tsb_cache_init(void);
-
-void pgtable_cache_init(void)
-{
- pgtable_cache = kmem_cache_create("pgtable_cache",
- PAGE_SIZE, PAGE_SIZE,
- SLAB_HWCACHE_ALIGN |
- SLAB_MUST_HWCACHE_ALIGN,
- zero_ctor,
- NULL);
- if (!pgtable_cache) {
- prom_printf("Could not create pgtable_cache\n");
- prom_halt();
- }
- tsb_cache_init();
-}
-
#ifdef CONFIG_DEBUG_DCFLUSH
atomic_t dcpage_flushes = ATOMIC_INIT(0);
#ifdef CONFIG_SMP
diff --git a/arch/sparc64/mm/tsb.c b/arch/sparc64/mm/tsb.c
index 236d02f..8eb8a7c 100644
--- a/arch/sparc64/mm/tsb.c
+++ b/arch/sparc64/mm/tsb.c
@@ -252,7 +252,7 @@ static const char *tsb_cache_names[8] = {
"tsb_1MB",
};
-void __init tsb_cache_init(void)
+void __init pgtable_cache_init(void)
{
unsigned long i;
@@ -262,8 +262,7 @@ void __init tsb_cache_init(void)
tsb_caches[i] = kmem_cache_create(name,
size, size,
- SLAB_HWCACHE_ALIGN |
- SLAB_MUST_HWCACHE_ALIGN,
+ 0,
NULL, NULL);
if (!tsb_caches[i]) {
prom_printf("Could not create %s cache\n", name);
diff --git a/arch/sparc64/solaris/ipc.c b/arch/sparc64/solaris/ipc.c
index 8cef5fd..a531a2c 100644
--- a/arch/sparc64/solaris/ipc.c
+++ b/arch/sparc64/solaris/ipc.c
@@ -6,7 +6,6 @@
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/smp_lock.h>
#include <linux/wait.h>
#include <linux/mm.h>
#include <linux/shm.h>
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index 542c808..3b67de7 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -6,7 +6,6 @@
#include <linux/module.h>
#include <linux/types.h>
-#include <linux/smp_lock.h>
#include <linux/utsname.h>
#include <linux/limits.h>
#include <linux/mm.h>
diff --git a/arch/sparc64/solaris/signal.c b/arch/sparc64/solaris/signal.c
index 7fa2634..de10c97 100644
--- a/arch/sparc64/solaris/signal.c
+++ b/arch/sparc64/solaris/signal.c
@@ -5,7 +5,6 @@
*/
#include <linux/types.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
diff --git a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c
index d3a66ea..cc69847 100644
--- a/arch/sparc64/solaris/socket.c
+++ b/arch/sparc64/solaris/socket.c
@@ -8,7 +8,6 @@
*/
#include <linux/types.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/socket.h>
diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
index c286444..e94f6e5 100644
--- a/arch/sparc64/solaris/socksys.c
+++ b/arch/sparc64/solaris/socksys.c
@@ -17,7 +17,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/ioctl.h>
#include <linux/fs.h>
#include <linux/file.h>
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 9fdfad6..3aa3516 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -12,7 +12,6 @@
#include <linux/tty_flip.h>
#include <asm/irq.h>
#include "chan_kern.h"
-#include "user_util.h"
#include "kern.h"
#include "irq_user.h"
#include "sigio.h"
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 0cad354..13f0bf8 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -14,7 +14,6 @@
#include <sys/ioctl.h>
#include <sys/socket.h>
#include "kern_util.h"
-#include "user_util.h"
#include "chan_user.h"
#include "user.h"
#include "os.h"
@@ -158,7 +157,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
*/
err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0);
if(err < 0){
- printk("fork of winch_thread failed - errno = %d\n", errno);
+ printk("fork of winch_thread failed - errno = %d\n", -err);
goto out_close;
}
@@ -204,14 +203,3 @@ void register_winch(int fd, struct tty_struct *tty)
}
}
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
index c6a3084..1545384 100644
--- a/arch/um/drivers/cow_sys.h
+++ b/arch/um/drivers/cow_sys.h
@@ -2,14 +2,13 @@
#define __COW_SYS_H__
#include "kern_util.h"
-#include "user_util.h"
#include "os.h"
#include "user.h"
#include "um_malloc.h"
static inline void *cow_malloc(int size)
{
- return(um_kmalloc(size));
+ return um_kmalloc(size);
}
static inline void cow_free(void *ptr)
@@ -21,29 +20,22 @@ static inline void cow_free(void *ptr)
static inline char *cow_strdup(char *str)
{
- return(uml_strdup(str));
+ return uml_strdup(str);
}
static inline int cow_seek_file(int fd, __u64 offset)
{
- return(os_seek_file(fd, offset));
+ return os_seek_file(fd, offset);
}
static inline int cow_file_size(char *file, unsigned long long *size_out)
{
- return(os_file_size(file, size_out));
+ return os_file_size(file, size_out);
}
static inline int cow_write_file(int fd, void *buf, int size)
{
- return(os_write_file(fd, buf, size));
+ return os_write_file(fd, buf, size);
}
#endif
-
-/*
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index 021b82c..b869e38 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -14,7 +14,6 @@
#include "net_user.h"
#include "daemon.h"
#include "kern_util.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
#include "um_malloc.h"
@@ -39,11 +38,11 @@ static struct sockaddr_un *new_addr(void *name, int len)
sun = um_kmalloc(sizeof(struct sockaddr_un));
if(sun == NULL){
printk("new_addr: allocation of sockaddr_un failed\n");
- return(NULL);
+ return NULL;
}
sun->sun_family = AF_UNIX;
memcpy(sun->sun_path, name, len);
- return(sun);
+ return sun;
}
static int connect_to_switch(struct daemon_data *pri)
@@ -112,7 +111,7 @@ static int connect_to_switch(struct daemon_data *pri)
}
pri->data_addr = sun;
- return(fd);
+ return fd;
out_free:
kfree(sun);
@@ -120,10 +119,10 @@ static int connect_to_switch(struct daemon_data *pri)
os_close_file(fd);
out:
os_close_file(pri->control);
- return(err);
+ return err;
}
-static void daemon_user_init(void *data, void *dev)
+static int daemon_user_init(void *data, void *dev)
{
struct daemon_data *pri = data;
struct timeval tv;
@@ -146,13 +145,16 @@ static void daemon_user_init(void *data, void *dev)
if(pri->fd < 0){
kfree(pri->local_addr);
pri->local_addr = NULL;
+ return pri->fd;
}
+
+ return 0;
}
static int daemon_open(void *data)
{
struct daemon_data *pri = data;
- return(pri->fd);
+ return pri->fd;
}
static void daemon_remove(void *data)
@@ -176,12 +178,12 @@ int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
{
struct sockaddr_un *data_addr = pri->data_addr;
- return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
+ return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
}
static int daemon_set_mtu(int mtu, void *data)
{
- return(mtu);
+ return mtu;
}
const struct net_user_info daemon_user_info = {
@@ -194,14 +196,3 @@ const struct net_user_info daemon_user_info = {
.delete_address = NULL,
.max_packet = MAX_PACKET - ETH_HEADER_OTHER
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index 218aa0e..7f083ec 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -9,7 +9,6 @@
#include <termios.h>
#include <errno.h>
#include "user.h"
-#include "user_util.h"
#include "chan_user.h"
#include "os.h"
#include "um_malloc.h"
diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
index c495ecf..5eeecf89 100644
--- a/arch/um/drivers/harddog_user.c
+++ b/arch/um/drivers/harddog_user.c
@@ -6,7 +6,6 @@
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
-#include "user_util.h"
#include "user.h"
#include "mconsole.h"
#include "os.h"
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index f75d7b0..ced9910 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -13,7 +13,6 @@
#include "irq_user.h"
#include "line.h"
#include "kern.h"
-#include "user_util.h"
#include "kern_util.h"
#include "os.h"
#include "irq_kern.h"
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index b827e82..d319db1 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -20,7 +20,6 @@
#include "net_user.h"
#include "mcast.h"
#include "kern_util.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
#include "um_malloc.h"
@@ -34,20 +33,21 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port)
sin = um_kmalloc(sizeof(struct sockaddr_in));
if(sin == NULL){
printk("new_addr: allocation of sockaddr_in failed\n");
- return(NULL);
+ return NULL;
}
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = in_aton(addr);
sin->sin_port = htons(port);
- return(sin);
+ return sin;
}
-static void mcast_user_init(void *data, void *dev)
+static int mcast_user_init(void *data, void *dev)
{
struct mcast_data *pri = data;
pri->mcast_addr = new_addr(pri->addr, pri->port);
pri->dev = dev;
+ return 0;
}
static void mcast_remove(void *data)
@@ -107,8 +107,8 @@ static int mcast_open(void *data)
err = -errno;
printk("mcast_open : data bind failed, errno = %d\n", errno);
goto out_close;
- }
-
+ }
+
/* subscribe to the multicast group */
mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
mreq.imr_interface.s_addr = 0;
@@ -153,12 +153,12 @@ int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
{
struct sockaddr_in *data_addr = pri->mcast_addr;
- return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)));
+ return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
}
static int mcast_set_mtu(int mtu, void *data)
{
- return(mtu);
+ return mtu;
}
const struct net_user_info mcast_user_info = {
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 65ad293..542c9ef 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -25,7 +25,6 @@
#include "linux/console.h"
#include "asm/irq.h"
#include "asm/uaccess.h"
-#include "user_util.h"
#include "kern_util.h"
#include "kern.h"
#include "mconsole.h"
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index f02634f..62e5ad6 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -17,7 +17,6 @@
#include "sysdep/ptrace.h"
#include "mconsole.h"
#include "os.h"
-#include "user_util.h"
static struct mconsole_command commands[] = {
/* With uts namespaces, uts information becomes process-specific, so
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index df3516e..e41a08f0 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -15,7 +15,6 @@
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
#include "mem_user.h"
-#include "user_util.h"
/* These are set in mmapper_init, which is called at boot time */
static unsigned long mmapper_size;
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 8593037..72773dd 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -21,7 +21,6 @@
#include "linux/ethtool.h"
#include "linux/platform_device.h"
#include "asm/uaccess.h"
-#include "user_util.h"
#include "kern_util.h"
#include "net_kern.h"
#include "net_user.h"
@@ -284,7 +283,7 @@ void uml_net_user_timer_expire(unsigned long _conn)
#endif
}
-static void setup_etheraddr(char *str, unsigned char *addr)
+static void setup_etheraddr(char *str, unsigned char *addr, char *name)
{
char *end;
int i;
@@ -303,15 +302,34 @@ static void setup_etheraddr(char *str, unsigned char *addr)
}
str = end + 1;
}
- if(addr[0] & 1){
+ if (is_multicast_ether_addr(addr)) {
printk(KERN_ERR
- "Attempt to assign a broadcast ethernet address to a "
+ "Attempt to assign a multicast ethernet address to a "
"device disallowed\n");
goto random;
}
+ if (!is_valid_ether_addr(addr)) {
+ printk(KERN_ERR
+ "Attempt to assign an invalid ethernet address to a "
+ "device disallowed\n");
+ goto random;
+ }
+ if (!is_local_ether_addr(addr)) {
+ printk(KERN_WARNING
+ "Warning: attempt to assign a globally valid ethernet "
+ "address to a device\n");
+ printk(KERN_WARNING "You should better enable the 2nd "
+ "rightmost bit in the first byte of the MAC,\n");
+ printk(KERN_WARNING "i.e. %02x:%02x:%02x:%02x:%02x:%02x\n",
+ addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4],
+ addr[5]);
+ goto random;
+ }
return;
random:
+ printk(KERN_INFO
+ "Choosing a random ethernet address for device %s\n", name);
random_ether_addr(addr);
}
@@ -325,31 +343,53 @@ static struct platform_driver uml_net_driver = {
};
static int driver_registered;
-static int eth_configure(int n, void *init, char *mac,
- struct transport *transport)
+static void net_device_release(struct device *dev)
+{
+ struct uml_net *device = dev->driver_data;
+ struct net_device *netdev = device->dev;
+ struct uml_net_private *lp = netdev->priv;
+
+ if(lp->remove != NULL)
+ (*lp->remove)(&lp->user);
+ list_del(&device->list);
+ kfree(device);
+ free_netdev(netdev);
+}
+
+static void eth_configure(int n, void *init, char *mac,
+ struct transport *transport)
{
struct uml_net *device;
struct net_device *dev;
struct uml_net_private *lp;
- int save, err, size;
+ int err, size;
- size = transport->private_size + sizeof(struct uml_net_private) +
- sizeof(((struct uml_net_private *) 0)->user);
+ size = transport->private_size + sizeof(struct uml_net_private);
device = kzalloc(sizeof(*device), GFP_KERNEL);
if (device == NULL) {
- printk(KERN_ERR "eth_configure failed to allocate uml_net\n");
- return(1);
+ printk(KERN_ERR "eth_configure failed to allocate struct "
+ "uml_net\n");
+ return;
+ }
+
+ dev = alloc_etherdev(size);
+ if (dev == NULL) {
+ printk(KERN_ERR "eth_configure: failed to allocate struct "
+ "net_device for eth%d\n", n);
+ goto out_free_device;
}
INIT_LIST_HEAD(&device->list);
device->index = n;
- spin_lock(&devices_lock);
- list_add(&device->list, &devices);
- spin_unlock(&devices_lock);
+ /* If this name ends up conflicting with an existing registered
+ * netdevice, that is OK, register_netdev{,ice}() will notice this
+ * and fail.
+ */
+ snprintf(dev->name, sizeof(dev->name), "eth%d", n);
- setup_etheraddr(mac, device->mac);
+ setup_etheraddr(mac, device->mac, dev->name);
printk(KERN_INFO "Netdevice %d ", n);
printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
@@ -357,11 +397,6 @@ static int eth_configure(int n, void *init, char *mac,
device->mac[2], device->mac[3],
device->mac[4], device->mac[5]);
printk(": ");
- dev = alloc_etherdev(size);
- if (dev == NULL) {
- printk(KERN_ERR "eth_configure: failed to allocate device\n");
- return 1;
- }
lp = dev->priv;
/* This points to the transport private data. It's still clear, but we
@@ -376,47 +411,20 @@ static int eth_configure(int n, void *init, char *mac,
}
device->pdev.id = n;
device->pdev.name = DRIVER_NAME;
- platform_device_register(&device->pdev);
+ device->pdev.dev.release = net_device_release;
+ device->pdev.dev.driver_data = device;
+ if(platform_device_register(&device->pdev))
+ goto out_free_netdev;
SET_NETDEV_DEV(dev,&device->pdev.dev);
- /* If this name ends up conflicting with an existing registered
- * netdevice, that is OK, register_netdev{,ice}() will notice this
- * and fail.
- */
- snprintf(dev->name, sizeof(dev->name), "eth%d", n);
device->dev = dev;
+ /*
+ * These just fill in a data structure, so there's no failure
+ * to be worried about.
+ */
(*transport->kern->init)(dev, init);
- dev->mtu = transport->user->max_packet;
- dev->open = uml_net_open;
- dev->hard_start_xmit = uml_net_start_xmit;
- dev->stop = uml_net_close;
- dev->get_stats = uml_net_get_stats;
- dev->set_multicast_list = uml_net_set_multicast_list;
- dev->tx_timeout = uml_net_tx_timeout;
- dev->set_mac_address = uml_net_set_mac;
- dev->change_mtu = uml_net_change_mtu;
- dev->ethtool_ops = &uml_net_ethtool_ops;
- dev->watchdog_timeo = (HZ >> 1);
- dev->irq = UM_ETH_IRQ;
-
- rtnl_lock();
- err = register_netdevice(dev);
- rtnl_unlock();
- if (err) {
- device->dev = NULL;
- /* XXX: should we call ->remove() here? */
- free_netdev(dev);
- return 1;
- }
-
- /* lp.user is the first four bytes of the transport data, which
- * has already been initialized. This structure assignment will
- * overwrite that, so we make sure that .user gets overwritten with
- * what it already has.
- */
- save = lp->user[0];
*lp = ((struct uml_net_private)
{ .list = LIST_HEAD_INIT(lp->list),
.dev = dev,
@@ -430,20 +438,53 @@ static int eth_configure(int n, void *init, char *mac,
.write = transport->kern->write,
.add_address = transport->user->add_address,
.delete_address = transport->user->delete_address,
- .set_mtu = transport->user->set_mtu,
- .user = { save } });
+ .set_mtu = transport->user->set_mtu });
init_timer(&lp->tl);
spin_lock_init(&lp->lock);
lp->tl.function = uml_net_user_timer_expire;
memcpy(lp->mac, device->mac, sizeof(lp->mac));
- if (transport->user->init)
- (*transport->user->init)(&lp->user, dev);
+ if ((transport->user->init != NULL) &&
+ ((*transport->user->init)(&lp->user, dev) != 0))
+ goto out_unregister;
set_ether_mac(dev, device->mac);
+ dev->mtu = transport->user->max_packet;
+ dev->open = uml_net_open;
+ dev->hard_start_xmit = uml_net_start_xmit;
+ dev->stop = uml_net_close;
+ dev->get_stats = uml_net_get_stats;
+ dev->set_multicast_list = uml_net_set_multicast_list;
+ dev->tx_timeout = uml_net_tx_timeout;
+ dev->set_mac_address = uml_net_set_mac;
+ dev->change_mtu = uml_net_change_mtu;
+ dev->ethtool_ops = &uml_net_ethtool_ops;
+ dev->watchdog_timeo = (HZ >> 1);
+ dev->irq = UM_ETH_IRQ;
- return 0;
+ rtnl_lock();
+ err = register_netdevice(dev);
+ rtnl_unlock();
+ if (err)
+ goto out_undo_user_init;
+
+ spin_lock(&devices_lock);
+ list_add(&device->list, &devices);
+ spin_unlock(&devices_lock);
+
+ return;
+
+out_undo_user_init:
+ if (transport->user->remove != NULL)
+ (*transport->user->remove)(&lp->user);
+out_unregister:
+ platform_device_unregister(&device->pdev);
+ return; /* platform_device_unregister frees dev and device */
+out_free_netdev:
+ free_netdev(dev);
+out_free_device:
+ kfree(device);
}
static struct uml_net *find_device(int n)
@@ -666,13 +707,9 @@ static int net_remove(int n, char **error_out)
lp = dev->priv;
if(lp->fd > 0)
return -EBUSY;
- if(lp->remove != NULL) (*lp->remove)(&lp->user);
unregister_netdev(dev);
platform_device_unregister(&device->pdev);
- list_del(&device->list);
- kfree(device);
- free_netdev(dev);
return 0;
}
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 0ffd7ac..3503cff 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -14,11 +14,11 @@
#include <sys/wait.h>
#include <sys/time.h>
#include "user.h"
-#include "user_util.h"
#include "kern_util.h"
#include "net_user.h"
#include "os.h"
#include "um_malloc.h"
+#include "kern_constants.h"
int tap_open_common(void *dev, char *gate_addr)
{
@@ -216,7 +216,7 @@ static void change(char *dev, char *what, unsigned char *addr,
sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1],
netmask[2], netmask[3]);
- output_len = page_size();
+ output_len = UM_KERN_PAGE_SIZE;
output = um_kmalloc(output_len);
if(output == NULL)
printk("change : failed to allocate output buffer\n");
diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
index 9488493..c329931 100644
--- a/arch/um/drivers/pcap_kern.c
+++ b/arch/um/drivers/pcap_kern.c
@@ -29,21 +29,25 @@ void pcap_init(struct net_device *dev, void *data)
ppri->promisc = init->promisc;
ppri->optimize = init->optimize;
ppri->filter = init->filter;
+
+ printk("pcap backend, host interface %s\n", ppri->host_if);
}
-static int pcap_read(int fd, struct sk_buff **skb,
+static int pcap_read(int fd, struct sk_buff **skb,
struct uml_net_private *lp)
{
*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
- if(*skb == NULL) return(-ENOMEM);
- return(pcap_user_read(fd, skb_mac_header(*skb),
+ if(*skb == NULL)
+ return -ENOMEM;
+
+ return pcap_user_read(fd, skb_mac_header(*skb),
(*skb)->dev->mtu + ETH_HEADER_OTHER,
- (struct pcap_data *) &lp->user));
+ (struct pcap_data *) &lp->user);
}
static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
{
- return(-EPERM);
+ return -EPERM;
}
static const struct net_kern_info pcap_kern_info = {
@@ -65,12 +69,12 @@ int pcap_setup(char *str, char **mac_out, void *data)
.optimize = 0,
.filter = NULL });
- remain = split_if_spec(str, &host_if, &init->filter,
- &options[0], &options[1], NULL);
+ remain = split_if_spec(str, &host_if, &init->filter,
+ &options[0], &options[1], mac_out, NULL);
if(remain != NULL){
printk(KERN_ERR "pcap_setup - Extra garbage on "
"specification : '%s'\n", remain);
- return(0);
+ return 0;
}
if(host_if != NULL)
@@ -87,10 +91,13 @@ int pcap_setup(char *str, char **mac_out, void *data)
init->optimize = 1;
else if(!strcmp(options[i], "nooptimize"))
init->optimize = 0;
- else printk("pcap_setup : bad option - '%s'\n", options[i]);
+ else {
+ printk("pcap_setup : bad option - '%s'\n", options[i]);
+ return 0;
+ }
}
- return(1);
+ return 1;
}
static struct transport pcap_transport = {
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
index 11921a7..483aa15 100644
--- a/arch/um/drivers/pcap_user.c
+++ b/arch/um/drivers/pcap_user.c
@@ -13,12 +13,13 @@
#include "pcap_user.h"
#include "user.h"
#include "um_malloc.h"
+#include "kern_constants.h"
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
#define PCAP_FD(p) (*(int *)(p))
-static void pcap_user_init(void *data, void *dev)
+static int pcap_user_init(void *data, void *dev)
{
struct pcap_data *pri = data;
pcap_t *p;
@@ -26,13 +27,14 @@ static void pcap_user_init(void *data, void *dev)
p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors);
if(p == NULL){
- printk("pcap_user_init : pcap_open_live failed - '%s'\n",
- errors);
- return;
+ printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - "
+ "'%s'\n", errors);
+ return -EINVAL;
}
pri->dev = dev;
pri->pcap = p;
+ return 0;
}
static int pcap_open(void *data)
@@ -42,39 +44,39 @@ static int pcap_open(void *data)
int err;
if(pri->pcap == NULL)
- return(-ENODEV);
+ return -ENODEV;
if(pri->filter != NULL){
err = dev_netmask(pri->dev, &netmask);
if(err < 0){
- printk("pcap_open : dev_netmask failed\n");
- return(-EIO);
+ printk(UM_KERN_ERR "pcap_open : dev_netmask failed\n");
+ return -EIO;
}
pri->compiled = um_kmalloc(sizeof(struct bpf_program));
if(pri->compiled == NULL){
- printk("pcap_open : kmalloc failed\n");
- return(-ENOMEM);
+ printk(UM_KERN_ERR "pcap_open : kmalloc failed\n");
+ return -ENOMEM;
}
-
+
err = pcap_compile(pri->pcap,
(struct bpf_program *) pri->compiled,
pri->filter, pri->optimize, netmask);
if(err < 0){
- printk("pcap_open : pcap_compile failed - '%s'\n",
- pcap_geterr(pri->pcap));
- return(-EIO);
+ printk(UM_KERN_ERR "pcap_open : pcap_compile failed - "
+ "'%s'\n", pcap_geterr(pri->pcap));
+ return -EIO;
}
err = pcap_setfilter(pri->pcap, pri->compiled);
if(err < 0){
- printk("pcap_open : pcap_setfilter failed - '%s'\n",
- pcap_geterr(pri->pcap));
- return(-EIO);
+ printk(UM_KERN_ERR "pcap_open : pcap_setfilter "
+ "failed - '%s'\n", pcap_geterr(pri->pcap));
+ return -EIO;
}
}
-
- return(PCAP_FD(pri->pcap));
+
+ return PCAP_FD(pri->pcap);
}
static void pcap_remove(void *data)
@@ -84,7 +86,8 @@ static void pcap_remove(void *data)
if(pri->compiled != NULL)
pcap_freecode(pri->compiled);
- pcap_close(pri->pcap);
+ if(pri->pcap != NULL)
+ pcap_close(pri->pcap);
}
struct pcap_handler_data {
@@ -113,12 +116,13 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
if(n < 0){
- printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap));
- return(-EIO);
+ printk(UM_KERN_ERR "pcap_dispatch failed - %s\n",
+ pcap_geterr(pri->pcap));
+ return -EIO;
}
else if(n == 0)
- return(0);
- return(hdata.len);
+ return 0;
+ return hdata.len;
}
const struct net_user_info pcap_user_info = {
@@ -131,14 +135,3 @@ const struct net_user_info pcap_user_info = {
.delete_address = NULL,
.max_packet = MAX_PACKET - ETH_HEADER_OTHER
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index 8050802..3f6357d 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -13,7 +13,6 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "chan_user.h"
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index 829a5ec..df4976c 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -4,13 +4,13 @@
*/
#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <termios.h>
#include "chan_user.h"
#include "user.h"
-#include "user_util.h"
#include "kern_util.h"
#include "os.h"
#include "um_malloc.h"
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index 7eddacc..78f0e51 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -8,7 +8,6 @@
#include <sys/termios.h>
#include <sys/wait.h>
#include <sys/signal.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "net_user.h"
@@ -16,12 +15,14 @@
#include "slip_common.h"
#include "os.h"
#include "um_malloc.h"
+#include "kern_constants.h"
-void slip_user_init(void *data, void *dev)
+static int slip_user_init(void *data, void *dev)
{
struct slip_data *pri = data;
pri->dev = dev;
+ return 0;
}
static int set_up_tty(int fd)
@@ -89,7 +90,7 @@ static int slip_tramp(char **argv, int fd)
goto out_close;
pid = err;
- output_len = page_size();
+ output_len = UM_KERN_PAGE_SIZE;
output = um_kmalloc(output_len);
if(output == NULL){
printk("slip_tramp : failed to allocate output buffer\n");
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index ce5e85d..39f889f 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -7,7 +7,6 @@
#include <errno.h>
#include <sys/wait.h>
#include <sys/signal.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "net_user.h"
@@ -15,11 +14,12 @@
#include "slip_common.h"
#include "os.h"
-void slirp_user_init(void *data, void *dev)
+static int slirp_user_init(void *data, void *dev)
{
struct slirp_data *pri = data;
pri->dev = dev;
+ return 0;
}
struct slirp_pre_exec_data {
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index 4b382a6..fd09ad9 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -15,7 +15,6 @@
#include "line.h"
#include "ssl.h"
#include "chan_kern.h"
-#include "user_util.h"
#include "kern_util.h"
#include "kern.h"
#include "init.h"
@@ -192,12 +191,12 @@ static int ssl_init(void)
ssl_driver = register_lines(&driver, &ssl_ops, serial_lines,
ARRAY_SIZE(serial_lines));
- lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts);
-
new_title = add_xterm_umid(opts.xterm_title);
if (new_title != NULL)
opts.xterm_title = new_title;
+ lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts);
+
ssl_init_done = 1;
register_console(&ssl_cons);
return 0;
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 76d1f1c..2bb4193 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -22,7 +22,6 @@
#include "stdio_console.h"
#include "line.h"
#include "chan_kern.h"
-#include "user_util.h"
#include "kern_util.h"
#include "irq_user.h"
#include "mconsole_kern.h"
@@ -167,12 +166,12 @@ int stdio_init(void)
return -1;
printk(KERN_INFO "Initialized stdio console driver\n");
- lines_init(vts, ARRAY_SIZE(vts), &opts);
-
new_title = add_xterm_umid(opts.xterm_title);
if(new_title != NULL)
opts.xterm_title = new_title;
+ lines_init(vts, ARRAY_SIZE(vts), &opts);
+
con_init_done = 1;
register_console(&stdiocons);
return 0;
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index d95d643..c07d0d5 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -8,7 +8,6 @@
#include <errno.h>
#include <unistd.h>
#include "chan_user.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
#include "um_malloc.h"
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 8bd9204..70509dd 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -39,7 +39,6 @@
#include "asm/irq.h"
#include "asm/types.h"
#include "asm/tlbflush.h"
-#include "user_util.h"
#include "mem_user.h"
#include "kern_util.h"
#include "kern.h"
@@ -90,7 +89,7 @@ static inline int ubd_test_bit(__u64 bit, unsigned char *data)
bits = sizeof(data[0]) * 8;
n = bit / bits;
off = bit % bits;
- return((data[n] & (1 << off)) != 0);
+ return (data[n] & (1 << off)) != 0;
}
static inline void ubd_set_bit(__u64 bit, unsigned char *data)
@@ -147,10 +146,13 @@ struct cow {
unsigned long *bitmap;
unsigned long bitmap_len;
int bitmap_offset;
- int data_offset;
+ int data_offset;
};
+#define MAX_SG 64
+
struct ubd {
+ struct list_head restart;
/* name (and fd, below) of the file opened for writing, either the
* backing or the cow file. */
char *file;
@@ -165,15 +167,17 @@ struct ubd {
struct platform_device pdev;
struct request_queue *queue;
spinlock_t lock;
- int active;
+ struct scatterlist sg[MAX_SG];
+ struct request *request;
+ int start_sg, end_sg;
};
#define DEFAULT_COW { \
.file = NULL, \
- .fd = -1, \
- .bitmap = NULL, \
+ .fd = -1, \
+ .bitmap = NULL, \
.bitmap_offset = 0, \
- .data_offset = 0, \
+ .data_offset = 0, \
}
#define DEFAULT_UBD { \
@@ -183,11 +187,13 @@ struct ubd {
.size = -1, \
.boot_openflags = OPEN_FLAGS, \
.openflags = OPEN_FLAGS, \
- .no_cow = 0, \
+ .no_cow = 0, \
.shared = 0, \
- .cow = DEFAULT_COW, \
+ .cow = DEFAULT_COW, \
.lock = SPIN_LOCK_UNLOCKED, \
- .active = 0, \
+ .request = NULL, \
+ .start_sg = 0, \
+ .end_sg = 0, \
}
/* Protected by ubd_lock */
@@ -243,7 +249,7 @@ static void make_ide_entries(char *dev_name)
static int fake_ide_setup(char *str)
{
fake_ide = 1;
- return(1);
+ return 1;
}
__setup("fake_ide", fake_ide_setup);
@@ -261,7 +267,7 @@ static int parse_unit(char **ptr)
if(isdigit(*str)) {
n = simple_strtoul(str, &end, 0);
if(end == str)
- return(-1);
+ return -1;
*ptr = end;
}
else if (('a' <= *str) && (*str <= 'z')) {
@@ -269,7 +275,7 @@ static int parse_unit(char **ptr)
str++;
*ptr = str;
}
- return(n);
+ return n;
}
/* If *index_out == -1 at exit, the passed option was a general one;
@@ -436,7 +442,7 @@ static int udb_setup(char *str)
{
printk("udb%s specified on command line is almost certainly a ubd -> "
"udb TYPO\n", str);
- return(1);
+ return 1;
}
__setup("udb", udb_setup);
@@ -467,66 +473,75 @@ static void do_ubd_request(request_queue_t * q);
/* Only changed by ubd_init, which is an initcall. */
int thread_fd = -1;
-/* call ubd_finish if you need to serialize */
-static void __ubd_finish(struct request *req, int error)
+static void ubd_end_request(struct request *req, int bytes, int uptodate)
{
- int nsect;
-
- if(error){
- end_request(req, 0);
- return;
+ if (!end_that_request_first(req, uptodate, bytes >> 9)) {
+ struct ubd *dev = req->rq_disk->private_data;
+ unsigned long flags;
+
+ add_disk_randomness(req->rq_disk);
+ spin_lock_irqsave(&dev->lock, flags);
+ end_that_request_last(req, uptodate);
+ spin_unlock_irqrestore(&dev->lock, flags);
}
- nsect = req->current_nr_sectors;
- req->sector += nsect;
- req->buffer += nsect << 9;
- req->errors = 0;
- req->nr_sectors -= nsect;
- req->current_nr_sectors = 0;
- end_request(req, 1);
}
/* Callable only from interrupt context - otherwise you need to do
* spin_lock_irq()/spin_lock_irqsave() */
-static inline void ubd_finish(struct request *req, int error)
+static inline void ubd_finish(struct request *req, int bytes)
{
- struct ubd *dev = req->rq_disk->private_data;
-
- spin_lock(&dev->lock);
- __ubd_finish(req, error);
- spin_unlock(&dev->lock);
+ if(bytes < 0){
+ ubd_end_request(req, 0, 0);
+ return;
+ }
+ ubd_end_request(req, bytes, 1);
}
+static LIST_HEAD(restart);
+
/* XXX - move this inside ubd_intr. */
/* Called without dev->lock held, and only in interrupt context. */
static void ubd_handler(void)
{
- struct io_thread_req req;
+ struct io_thread_req *req;
struct request *rq;
- struct ubd *dev;
+ struct ubd *ubd;
+ struct list_head *list, *next_ele;
+ unsigned long flags;
int n;
- n = os_read_file(thread_fd, &req, sizeof(req));
- if(n != sizeof(req)){
- printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
- "err = %d\n", os_getpid(), -n);
- return;
- }
-
- rq = req.req;
- dev = rq->rq_disk->private_data;
- dev->active = 0;
+ while(1){
+ n = os_read_file(thread_fd, &req,
+ sizeof(struct io_thread_req *));
+ if(n != sizeof(req)){
+ if(n == -EAGAIN)
+ break;
+ printk(KERN_ERR "spurious interrupt in ubd_handler, "
+ "err = %d\n", -n);
+ return;
+ }
- ubd_finish(rq, req.error);
+ rq = req->req;
+ rq->nr_sectors -= req->length >> 9;
+ if(rq->nr_sectors == 0)
+ ubd_finish(rq, rq->hard_nr_sectors << 9);
+ kfree(req);
+ }
reactivate_fd(thread_fd, UBD_IRQ);
- spin_lock(&dev->lock);
- do_ubd_request(dev->queue);
- spin_unlock(&dev->lock);
+
+ list_for_each_safe(list, next_ele, &restart){
+ ubd = container_of(list, struct ubd, restart);
+ list_del_init(&ubd->restart);
+ spin_lock_irqsave(&ubd->lock, flags);
+ do_ubd_request(ubd->queue);
+ spin_unlock_irqrestore(&ubd->lock, flags);
+ }
}
static irqreturn_t ubd_intr(int irq, void *dev)
{
ubd_handler();
- return(IRQ_HANDLED);
+ return IRQ_HANDLED;
}
/* Only changed by ubd_init, which is an initcall. */
@@ -545,7 +560,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
char *file;
file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file;
- return(os_file_size(file, size_out));
+ return os_file_size(file, size_out);
}
static void ubd_close_dev(struct ubd *ubd_dev)
@@ -617,10 +632,18 @@ static int ubd_open_dev(struct ubd *ubd_dev)
if(err < 0) goto error;
ubd_dev->cow.fd = err;
}
- return(0);
+ return 0;
error:
os_close_file(ubd_dev->fd);
- return(err);
+ return err;
+}
+
+static void ubd_device_release(struct device *dev)
+{
+ struct ubd *ubd_dev = dev->driver_data;
+
+ blk_cleanup_queue(ubd_dev->queue);
+ *ubd_dev = ((struct ubd) DEFAULT_UBD);
}
static int ubd_disk_register(int major, u64 size, int unit,
@@ -630,7 +653,7 @@ static int ubd_disk_register(int major, u64 size, int unit,
disk = alloc_disk(1 << UBD_SHIFT);
if(disk == NULL)
- return(-ENOMEM);
+ return -ENOMEM;
disk->major = major;
disk->first_minor = unit << UBD_SHIFT;
@@ -645,6 +668,8 @@ static int ubd_disk_register(int major, u64 size, int unit,
if (major == MAJOR_NR) {
ubd_devs[unit].pdev.id = unit;
ubd_devs[unit].pdev.name = DRIVER_NAME;
+ ubd_devs[unit].pdev.dev.release = ubd_device_release;
+ ubd_devs[unit].pdev.dev.driver_data = &ubd_devs[unit];
platform_device_register(&ubd_devs[unit].pdev);
disk->driverfs_dev = &ubd_devs[unit].pdev.dev;
}
@@ -675,6 +700,8 @@ static int ubd_add(int n, char **error_out)
ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
+ INIT_LIST_HEAD(&ubd_dev->restart);
+
err = -ENOMEM;
ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock);
if (ubd_dev->queue == NULL) {
@@ -683,6 +710,7 @@ static int ubd_add(int n, char **error_out)
}
ubd_dev->queue->queuedata = ubd_dev;
+ blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG);
err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]);
if(err){
*error_out = "Failed to register device";
@@ -730,14 +758,14 @@ static int ubd_config(char *str, char **error_out)
goto err_free;
}
- mutex_lock(&ubd_lock);
+ mutex_lock(&ubd_lock);
ret = ubd_add(n, error_out);
if (ret)
ubd_devs[n].file = NULL;
- mutex_unlock(&ubd_lock);
+ mutex_unlock(&ubd_lock);
out:
- return ret;
+ return ret;
err_free:
kfree(str);
@@ -752,7 +780,7 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out)
n = parse_unit(&name);
if((n >= MAX_DEV) || (n < 0)){
*error_out = "ubd_get_config : device number out of range";
- return(-1);
+ return -1;
}
ubd_dev = &ubd_devs[n];
@@ -773,29 +801,27 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out)
out:
mutex_unlock(&ubd_lock);
- return(len);
+ return len;
}
static int ubd_id(char **str, int *start_out, int *end_out)
{
- int n;
+ int n;
n = parse_unit(str);
- *start_out = 0;
- *end_out = MAX_DEV - 1;
- return n;
+ *start_out = 0;
+ *end_out = MAX_DEV - 1;
+ return n;
}
static int ubd_remove(int n, char **error_out)
{
+ struct gendisk *disk = ubd_gendisk[n];
struct ubd *ubd_dev;
int err = -ENODEV;
mutex_lock(&ubd_lock);
- if(ubd_gendisk[n] == NULL)
- goto out;
-
ubd_dev = &ubd_devs[n];
if(ubd_dev->file == NULL)
@@ -806,9 +832,11 @@ static int ubd_remove(int n, char **error_out)
if(ubd_dev->count > 0)
goto out;
- del_gendisk(ubd_gendisk[n]);
- put_disk(ubd_gendisk[n]);
ubd_gendisk[n] = NULL;
+ if(disk != NULL){
+ del_gendisk(disk);
+ put_disk(disk);
+ }
if(fake_gendisk[n] != NULL){
del_gendisk(fake_gendisk[n]);
@@ -816,10 +844,8 @@ static int ubd_remove(int n, char **error_out)
fake_gendisk[n] = NULL;
}
- blk_cleanup_queue(ubd_dev->queue);
- platform_device_unregister(&ubd_dev->pdev);
- *ubd_dev = ((struct ubd) DEFAULT_UBD);
err = 0;
+ platform_device_unregister(&ubd_dev->pdev);
out:
mutex_unlock(&ubd_lock);
return err;
@@ -832,7 +858,7 @@ static struct mc_device ubd_mc = {
.list = LIST_HEAD_INIT(ubd_mc.list),
.name = "ubd",
.config = ubd_config,
- .get_config = ubd_get_config,
+ .get_config = ubd_get_config,
.id = ubd_id,
.remove = ubd_remove,
};
@@ -854,7 +880,7 @@ static int __init ubd0_init(void)
ubd_dev->file = "root_fs";
mutex_unlock(&ubd_lock);
- return(0);
+ return 0;
}
__initcall(ubd0_init);
@@ -882,14 +908,14 @@ static int __init ubd_init(void)
return -1;
}
platform_driver_register(&ubd_driver);
- mutex_lock(&ubd_lock);
+ mutex_lock(&ubd_lock);
for (i = 0; i < MAX_DEV; i++){
err = ubd_add(i, &error);
if(err)
printk(KERN_ERR "Failed to initialize ubd device %d :"
"%s\n", i, error);
}
- mutex_unlock(&ubd_lock);
+ mutex_unlock(&ubd_lock);
return 0;
}
@@ -913,7 +939,7 @@ static int __init ubd_driver_init(void){
"ubd : Failed to start I/O thread (errno = %d) - "
"falling back to synchronous I/O\n", -io_pid);
io_pid = -1;
- return(0);
+ return 0;
}
err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
IRQF_DISABLED, "ubd", ubd_devs);
@@ -948,7 +974,7 @@ static int ubd_open(struct inode *inode, struct file *filp)
err = -EROFS;
}*/
out:
- return(err);
+ return err;
}
static int ubd_release(struct inode * inode, struct file * file)
@@ -958,7 +984,7 @@ static int ubd_release(struct inode * inode, struct file * file)
if(--ubd_dev->count == 0)
ubd_close_dev(ubd_dev);
- return(0);
+ return 0;
}
static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
@@ -1014,7 +1040,7 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
ubd_set_bit(i, (unsigned char *)
&req->sector_mask);
- }
+ }
}
else cowify_bitmap(req->offset, req->length, &req->sector_mask,
&req->cow_offset, bitmap, bitmap_offset,
@@ -1022,26 +1048,16 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
}
/* Called with dev->lock held */
-static int prepare_request(struct request *req, struct io_thread_req *io_req)
+static void prepare_request(struct request *req, struct io_thread_req *io_req,
+ unsigned long long offset, int page_offset,
+ int len, struct page *page)
{
struct gendisk *disk = req->rq_disk;
struct ubd *ubd_dev = disk->private_data;
- __u64 offset;
- int len;
-
- /* This should be impossible now */
- if((rq_data_dir(req) == WRITE) && !ubd_dev->openflags.w){
- printk("Write attempted on readonly ubd device %s\n",
- disk->disk_name);
- end_request(req, 0);
- return(1);
- }
-
- offset = ((__u64) req->sector) << 9;
- len = req->current_nr_sectors << 9;
io_req->req = req;
- io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : ubd_dev->fd;
+ io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd :
+ ubd_dev->fd;
io_req->fds[1] = ubd_dev->fd;
io_req->cow_offset = -1;
io_req->offset = offset;
@@ -1052,45 +1068,66 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
io_req->offsets[0] = 0;
io_req->offsets[1] = ubd_dev->cow.data_offset;
- io_req->buffer = req->buffer;
+ io_req->buffer = page_address(page) + page_offset;
io_req->sectorsize = 1 << 9;
if(ubd_dev->cow.file != NULL)
- cowify_req(io_req, ubd_dev->cow.bitmap, ubd_dev->cow.bitmap_offset,
- ubd_dev->cow.bitmap_len);
+ cowify_req(io_req, ubd_dev->cow.bitmap,
+ ubd_dev->cow.bitmap_offset, ubd_dev->cow.bitmap_len);
- return(0);
}
/* Called with dev->lock held */
static void do_ubd_request(request_queue_t *q)
{
- struct io_thread_req io_req;
+ struct io_thread_req *io_req;
struct request *req;
- int err, n;
-
- if(thread_fd == -1){
- while((req = elv_next_request(q)) != NULL){
- err = prepare_request(req, &io_req);
- if(!err){
- do_io(&io_req);
- __ubd_finish(req, io_req.error);
- }
- }
- }
- else {
+ int n;
+
+ while(1){
struct ubd *dev = q->queuedata;
- if(dev->active || (req = elv_next_request(q)) == NULL)
- return;
- err = prepare_request(req, &io_req);
- if(!err){
- dev->active = 1;
- n = os_write_file(thread_fd, (char *) &io_req,
- sizeof(io_req));
- if(n != sizeof(io_req))
- printk("write to io thread failed, "
- "errno = %d\n", -n);
+ if(dev->end_sg == 0){
+ struct request *req = elv_next_request(q);
+ if(req == NULL)
+ return;
+
+ dev->request = req;
+ blkdev_dequeue_request(req);
+ dev->start_sg = 0;
+ dev->end_sg = blk_rq_map_sg(q, req, dev->sg);
}
+
+ req = dev->request;
+ while(dev->start_sg < dev->end_sg){
+ struct scatterlist *sg = &dev->sg[dev->start_sg];
+
+ io_req = kmalloc(sizeof(struct io_thread_req),
+ GFP_ATOMIC);
+ if(io_req == NULL){
+ if(list_empty(&dev->restart))
+ list_add(&dev->restart, &restart);
+ return;
+ }
+ prepare_request(req, io_req,
+ (unsigned long long) req->sector << 9,
+ sg->offset, sg->length, sg->page);
+
+ n = os_write_file(thread_fd, &io_req,
+ sizeof(struct io_thread_req *));
+ if(n != sizeof(struct io_thread_req *)){
+ if(n != -EAGAIN)
+ printk("write to io thread failed, "
+ "errno = %d\n", -n);
+ else if(list_empty(&dev->restart))
+ list_add(&dev->restart, &restart);
+ return;
+ }
+
+ req->sector += sg->length >> 9;
+ dev->start_sg++;
+ }
+ dev->end_sg = 0;
+ dev->request = NULL;
}
}
@@ -1120,21 +1157,21 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
ubd_id.cyls = ubd_dev->size / (128 * 32 * 512);
if(copy_to_user((char __user *) arg, (char *) &ubd_id,
sizeof(ubd_id)))
- return(-EFAULT);
- return(0);
+ return -EFAULT;
+ return 0;
case CDROMVOLREAD:
if(copy_from_user(&volume, (char __user *) arg, sizeof(volume)))
- return(-EFAULT);
+ return -EFAULT;
volume.channel0 = 255;
volume.channel1 = 255;
volume.channel2 = 255;
volume.channel3 = 255;
if(copy_to_user((char __user *) arg, &volume, sizeof(volume)))
- return(-EFAULT);
- return(0);
+ return -EFAULT;
+ return 0;
}
- return(-EINVAL);
+ return -EINVAL;
}
static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow)
@@ -1176,29 +1213,29 @@ static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
if(err < 0){
printk("Failed to get modification time of backing file "
"\"%s\", err = %d\n", file, -err);
- return(err);
+ return err;
}
err = os_file_size(file, &actual);
if(err < 0){
printk("Failed to get size of backing file \"%s\", "
"err = %d\n", file, -err);
- return(err);
+ return err;
}
- if(actual != size){
+ if(actual != size){
/*__u64 can be a long on AMD64 and with %lu GCC complains; so
* the typecast.*/
printk("Size mismatch (%llu vs %llu) of COW header vs backing "
"file\n", (unsigned long long) size, actual);
- return(-EINVAL);
+ return -EINVAL;
}
if(modtime != mtime){
printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
"file\n", mtime, modtime);
- return(-EINVAL);
+ return -EINVAL;
}
- return(0);
+ return 0;
}
int read_cow_bitmap(int fd, void *buf, int offset, int len)
@@ -1207,13 +1244,13 @@ int read_cow_bitmap(int fd, void *buf, int offset, int len)
err = os_seek_file(fd, offset);
if(err < 0)
- return(err);
+ return err;
err = os_read_file(fd, buf, len);
if(err < 0)
- return(err);
+ return err;
- return(0);
+ return 0;
}
int open_ubd_file(char *file, struct openflags *openflags, int shared,
@@ -1231,14 +1268,14 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
if (fd < 0) {
if ((fd == -ENOENT) && (create_cow_out != NULL))
*create_cow_out = 1;
- if (!openflags->w ||
- ((fd != -EROFS) && (fd != -EACCES)))
+ if (!openflags->w ||
+ ((fd != -EROFS) && (fd != -EACCES)))
return fd;
openflags->w = 0;
fd = os_open_file(file, *openflags, mode);
if (fd < 0)
return fd;
- }
+ }
if(shared)
printk("Not locking \"%s\" on the host\n", file);
@@ -1252,7 +1289,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
/* Successful return case! */
if(backing_file_out == NULL)
- return(fd);
+ return fd;
err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
&size, &sectorsize, &align, bitmap_offset_out);
@@ -1262,7 +1299,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
goto out_close;
}
if(err)
- return(fd);
+ return fd;
asked_switch = path_requires_switch(*backing_file_out, backing_file, file);
@@ -1285,7 +1322,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared,
cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
bitmap_len_out, data_offset_out);
- return fd;
+ return fd;
out_close:
os_close_file(fd);
return err;
@@ -1310,10 +1347,10 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
bitmap_offset_out, bitmap_len_out,
data_offset_out);
if(!err)
- return(fd);
+ return fd;
os_close_file(fd);
out:
- return(err);
+ return err;
}
static int update_bitmap(struct io_thread_req *req)
@@ -1321,23 +1358,23 @@ static int update_bitmap(struct io_thread_req *req)
int n;
if(req->cow_offset == -1)
- return(0);
+ return 0;
n = os_seek_file(req->fds[1], req->cow_offset);
if(n < 0){
printk("do_io - bitmap lseek failed : err = %d\n", -n);
- return(1);
+ return 1;
}
n = os_write_file(req->fds[1], &req->bitmap_words,
- sizeof(req->bitmap_words));
+ sizeof(req->bitmap_words));
if(n != sizeof(req->bitmap_words)){
printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
req->fds[1]);
- return(1);
+ return 1;
}
- return(0);
+ return 0;
}
void do_io(struct io_thread_req *req)
@@ -1409,13 +1446,14 @@ static int io_count = 0;
int io_thread(void *arg)
{
- struct io_thread_req req;
+ struct io_thread_req *req;
int n;
ignore_sigwinch_sig();
while(1){
- n = os_read_file(kernel_fd, &req, sizeof(req));
- if(n != sizeof(req)){
+ n = os_read_file(kernel_fd, &req,
+ sizeof(struct io_thread_req *));
+ if(n != sizeof(struct io_thread_req *)){
if(n < 0)
printk("io_thread - read failed, fd = %d, "
"err = %d\n", kernel_fd, -n);
@@ -1426,9 +1464,10 @@ int io_thread(void *arg)
continue;
}
io_count++;
- do_io(&req);
- n = os_write_file(kernel_fd, &req, sizeof(req));
- if(n != sizeof(req))
+ do_io(req);
+ n = os_write_file(kernel_fd, &req,
+ sizeof(struct io_thread_req *));
+ if(n != sizeof(struct io_thread_req *))
printk("io_thread - write failed, fd = %d, err = %d\n",
kernel_fd, -n);
}
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
index b94d2bc4f..4707b3f 100644
--- a/arch/um/drivers/ubd_user.c
+++ b/arch/um/drivers/ubd_user.c
@@ -16,7 +16,6 @@
#include <sys/mman.h>
#include <sys/param.h>
#include "asm/types.h"
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "ubd_user.h"
@@ -47,8 +46,8 @@ int start_io_thread(unsigned long sp, int *fd_out)
pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
NULL);
if(pid < 0){
- printk("start_io_thread - clone failed : errno = %d\n", errno);
err = -errno;
+ printk("start_io_thread - clone failed : errno = %d\n", errno);
goto out_close;
}
@@ -60,16 +59,5 @@ int start_io_thread(unsigned long sp, int *fd_out)
kernel_fd = -1;
*fd_out = -1;
out:
- return(err);
+ return err;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 850221d..571c2b3 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -14,7 +14,6 @@
#include <sys/socket.h>
#include "kern_util.h"
#include "chan_user.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
#include "xterm.h"
diff --git a/arch/um/include/arch.h b/arch/um/include/arch.h
new file mode 100644
index 0000000..10ad52d
--- /dev/null
+++ b/arch/um/include/arch.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __ARCH_H__
+#define __ARCH_H__
+
+#include "sysdep/ptrace.h"
+
+extern void arch_check_bugs(void);
+extern int arch_fixup(unsigned long address, union uml_pt_regs *regs);
+extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
+
+#endif
diff --git a/arch/um/include/as-layout.h b/arch/um/include/as-layout.h
new file mode 100644
index 0000000..fccf187
--- /dev/null
+++ b/arch/um/include/as-layout.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __START_H__
+#define __START_H__
+
+#include "sysdep/ptrace.h"
+
+struct cpu_task {
+ int pid;
+ void *task;
+};
+
+extern struct cpu_task cpu_tasks[];
+
+extern unsigned long low_physmem;
+extern unsigned long high_physmem;
+extern unsigned long uml_physmem;
+extern unsigned long uml_reserved;
+extern unsigned long end_vm;
+extern unsigned long start_vm;
+extern unsigned long long highmem;
+
+extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
+extern unsigned long _unprotected_end;
+extern unsigned long brk_start;
+
+extern int linux_main(int argc, char **argv);
+extern void set_cmdline(char *cmd);
+
+extern void (*sig_info[])(int, union uml_pt_regs *);
+
+#endif
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
index 461175f..5593a80 100644
--- a/arch/um/include/common-offsets.h
+++ b/arch/um/include/common-offsets.h
@@ -24,5 +24,7 @@ DEFINE(UM_ELF_CLASS, ELF_CLASS);
DEFINE(UM_ELFCLASS32, ELFCLASS32);
DEFINE(UM_ELFCLASS64, ELFCLASS64);
+DEFINE(UM_NR_CPUS, NR_CPUS);
+
/* For crypto assembler code. */
DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 173af02..50a4969 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -8,6 +8,7 @@
#include "sysdep/ptrace.h"
#include "sysdep/faultinfo.h"
+#include "uml-config.h"
typedef void (*kern_hndl)(int, union uml_pt_regs *);
@@ -23,7 +24,6 @@ struct kern_handlers {
extern const struct kern_handlers handlinfo_kern;
extern int ncpus;
-extern char *linux_prog;
extern char *gdb_init;
extern int kmalloc_ok;
extern int jail;
@@ -34,7 +34,9 @@ extern int nsyscalls;
UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1)
extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg);
+#ifdef UML_CONFIG_MODE_TT
extern unsigned long stack_sp(unsigned long page);
+#endif
extern int kernel_thread_proc(void *data);
extern void syscall_segv(int sig);
extern int current_pid(void);
@@ -42,7 +44,7 @@ extern unsigned long alloc_stack(int order, int atomic);
extern int do_signal(void);
extern int is_stack_fault(unsigned long sp);
extern unsigned long segv(struct faultinfo fi, unsigned long ip,
- int is_user, void *sc);
+ int is_user, union uml_pt_regs *regs);
extern int handle_page_fault(unsigned long address, unsigned long ip,
int is_write, int is_user, int *code_out);
extern void syscall_ready(void);
@@ -50,7 +52,6 @@ extern void set_tracing(void *t, int tracing);
extern int is_tracing(void *task);
extern int segv_syscall(void);
extern void kern_finish_exec(void *task, int new_pid, unsigned long stack);
-extern int page_size(void);
extern unsigned long page_mask(void);
extern int need_finish_fork(void);
extern void free_stack(unsigned long stack, int order);
@@ -58,7 +59,6 @@ extern void add_input_request(int op, void (*proc)(int), void *arg);
extern char *current_cmd(void);
extern void timer_handler(int sig, union uml_pt_regs *regs);
extern int set_signals(int enable);
-extern void force_sigbus(void);
extern int pid_to_processor_id(int pid);
extern void deliver_signals(void *t);
extern int next_trap_index(int max);
@@ -70,7 +70,6 @@ extern void *syscall_sp(void *t);
extern void syscall_trace(union uml_pt_regs *regs, int entryexit);
extern int hz(void);
extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
-extern int external_pid(void *t);
extern void interrupt_end(void);
extern void initial_thread_cb(void (*proc)(void *), void *arg);
extern int debugger_signal(int status, int pid);
@@ -81,7 +80,6 @@ extern int init_parent_proxy(int pid);
extern int singlestepping(void *t);
extern void check_stack_overflow(void *ptr);
extern void relay_signal(int sig, union uml_pt_regs *regs);
-extern void not_implemented(void);
extern int user_context(unsigned long sp);
extern void timer_irq(union uml_pt_regs *regs);
extern void unprotect_stack(unsigned long stack);
@@ -93,7 +91,6 @@ extern char *uml_strdup(char *string);
extern void unprotect_kernel_mem(void);
extern void protect_kernel_mem(void);
extern void uml_cleanup(void);
-extern void set_current(void *t);
extern void lock_signalled_task(void *t);
extern void IPI_handler(int cpu);
extern int jail_setup(char *line, int *add);
@@ -118,4 +115,6 @@ extern void time_init_kern(void);
extern int __cant_sleep(void);
extern void sigio_handler(int sig, union uml_pt_regs *regs);
+extern void copy_sc(union uml_pt_regs *regs, void *from);
+
#endif
diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h
index 125ab42..9237056 100644
--- a/arch/um/include/net_kern.h
+++ b/arch/um/include/net_kern.h
@@ -40,7 +40,7 @@ struct uml_net_private {
void (*add_address)(unsigned char *, unsigned char *, void *);
void (*delete_address)(unsigned char *, unsigned char *, void *);
int (*set_mtu)(int mtu, void *);
- int user[1];
+ char user[0];
};
struct net_kern_info {
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index 19f207c..cfe7c50 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -14,7 +14,7 @@
#define UML_NET_VERSION (4)
struct net_user_info {
- void (*init)(void *, void *);
+ int (*init)(void *, void *);
int (*open)(void *);
void (*close)(int, void *);
void (*remove)(void *);
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 5c74da4..688d181 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -16,6 +16,8 @@
#include "sysdep/tls.h"
#include "sysdep/archsetjmp.h"
+#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
+
#define OS_TYPE_FILE 1
#define OS_TYPE_DIR 2
#define OS_TYPE_SYMLINK 3
@@ -273,8 +275,9 @@ extern void stack_protections(unsigned long address);
extern void task_protections(unsigned long address);
extern int raw(int fd);
extern void setup_machinename(char *machine_out);
-extern void setup_hostinfo(void);
+extern void setup_hostinfo(char *buf, int len);
extern int setjmp_wrapper(void (*proc)(void *, void *), ...);
+extern void os_dump_core(void);
/* time.c */
#define BILLION (1000 * 1000 * 1000)
@@ -297,13 +300,12 @@ extern long syscall_stub_data(struct mm_id * mm_idp,
unsigned long *data, int data_count,
void **addr, void **stub_addr);
extern int map(struct mm_id * mm_idp, unsigned long virt,
- unsigned long len, int r, int w, int x, int phys_fd,
+ unsigned long len, int prot, int phys_fd,
unsigned long long offset, int done, void **data);
-extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len,
+extern int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
int done, void **data);
extern int protect(struct mm_id * mm_idp, unsigned long addr,
- unsigned long len, int r, int w, int x, int done,
- void **data);
+ unsigned long len, unsigned int prot, int done, void **data);
/* skas/process.c */
extern int is_skas_winch(int pid, int fd, void *data);
@@ -339,8 +341,11 @@ extern void maybe_sigio_broken(int fd, int read);
/* skas/trap */
extern void sig_handler_common_skas(int sig, void *sc_ptr);
-extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
+/* sys-x86_64/prctl.c */
extern int os_arch_prctl(int pid, int code, unsigned long *addr);
+/* tty.c */
+int get_pty(void);
+
#endif
diff --git a/arch/um/include/skas/mode_kern_skas.h b/arch/um/include/skas/mode_kern_skas.h
index 9cd9c6e..8ee6285 100644
--- a/arch/um/include/skas/mode_kern_skas.h
+++ b/arch/um/include/skas/mode_kern_skas.h
@@ -33,6 +33,8 @@ extern unsigned long set_task_sizes_skas(unsigned long *task_size_out);
extern int start_uml_skas(void);
extern int external_pid_skas(struct task_struct *task);
extern int thread_pid_skas(struct task_struct *task);
+extern void flush_tlb_page_skas(struct vm_area_struct *vma,
+ unsigned long address);
#define kmem_end_skas (host_task_size - 1024 * 1024)
diff --git a/arch/um/include/tlb.h b/arch/um/include/tlb.h
index 8efc1e0..bcd1a4a 100644
--- a/arch/um/include/tlb.h
+++ b/arch/um/include/tlb.h
@@ -14,9 +14,7 @@ struct host_vm_op {
struct {
unsigned long addr;
unsigned long len;
- unsigned int r:1;
- unsigned int w:1;
- unsigned int x:1;
+ unsigned int prot;
int fd;
__u64 offset;
} mmap;
@@ -27,9 +25,7 @@ struct host_vm_op {
struct {
unsigned long addr;
unsigned long len;
- unsigned int r:1;
- unsigned int w:1;
- unsigned int x:1;
+ unsigned int prot;
} mprotect;
} u;
};
diff --git a/arch/um/include/tt/uaccess-tt.h b/arch/um/include/tt/uaccess-tt.h
index b19645f..13a64f6 100644
--- a/arch/um/include/tt/uaccess-tt.h
+++ b/arch/um/include/tt/uaccess-tt.h
@@ -27,8 +27,6 @@ extern unsigned long uml_physmem;
#define access_ok_tt(type, addr, size) \
(is_stack(addr, size))
-extern unsigned long get_fault_addr(void);
-
extern int __do_copy_from_user(void *to, const void *from, int n,
void **fault_addr, void **fault_catcher);
extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
diff --git a/arch/um/include/um_malloc.h b/arch/um/include/um_malloc.h
index 0363a9b..e6d7c5a 100644
--- a/arch/um/include/um_malloc.h
+++ b/arch/um/include/um_malloc.h
@@ -11,7 +11,6 @@ extern void *um_kmalloc_atomic(int size);
extern void kfree(const void *ptr);
extern void *um_vmalloc(int size);
-extern void *um_vmalloc_atomic(int size);
extern void vfree(void *ptr);
#endif /* __UM_MALLOC_H__ */
diff --git a/arch/um/include/user.h b/arch/um/include/user.h
index acadce3..d380e6d 100644
--- a/arch/um/include/user.h
+++ b/arch/um/include/user.h
@@ -6,6 +6,19 @@
#ifndef __USER_H__
#define __USER_H__
+/*
+ * The usual definition - copied here because the kernel provides its own,
+ * fancier, type-safe, definition. Using that one would require
+ * copying too much infrastructure for my taste, so userspace files
+ * get less checking than kernel files.
+ */
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+/*
+ * This will provide the size_t definition in both kernel and userspace builds
+ */
+#include <linux/types.h>
+
extern void panic(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
extern int printk(const char *fmt, ...)
@@ -13,19 +26,7 @@ extern int printk(const char *fmt, ...)
extern void schedule(void);
extern int in_aton(char *str);
extern int open_gdb_chan(void);
-/* These use size_t, however unsigned long is correct on both i386 and x86_64. */
-extern unsigned long strlcpy(char *, const char *, unsigned long);
-extern unsigned long strlcat(char *, const char *, unsigned long);
+extern size_t strlcpy(char *, const char *, size_t);
+extern size_t strlcat(char *, const char *, size_t);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
deleted file mode 100644
index 023575f..0000000
--- a/arch/um/include/user_util.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __USER_UTIL_H__
-#define __USER_UTIL_H__
-
-#include "sysdep/ptrace.h"
-
-/* Copied from kernel.h */
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
-
-extern int mode_tt;
-
-extern int grantpt(int __fd);
-extern int unlockpt(int __fd);
-extern char *ptsname(int __fd);
-
-struct cpu_task {
- int pid;
- void *task;
-};
-
-extern struct cpu_task cpu_tasks[];
-
-extern void (*sig_info[])(int, union uml_pt_regs *);
-
-extern unsigned long low_physmem;
-extern unsigned long high_physmem;
-extern unsigned long uml_physmem;
-extern unsigned long uml_reserved;
-extern unsigned long end_vm;
-extern unsigned long start_vm;
-extern unsigned long long highmem;
-
-extern char host_info[];
-
-extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
-extern unsigned long _unprotected_end;
-extern unsigned long brk_start;
-
-extern int pty_output_sigio;
-extern int pty_close_sigio;
-
-extern void *add_signal_handler(int sig, void (*handler)(int));
-extern int linux_main(int argc, char **argv);
-extern void set_cmdline(char *cmd);
-extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
-extern int get_pty(void);
-extern int switcheroo(int fd, int prot, void *from, void *to, int size);
-extern void do_exec(int old_pid, int new_pid);
-extern void tracer_panic(char *msg, ...)
- __attribute__ ((format (printf, 1, 2)));
-extern int detach(int pid, int sig);
-extern int attach(int pid);
-extern void kill_child_dead(int pid);
-extern int cont(int pid);
-extern void check_sigio(void);
-extern void arch_check_bugs(void);
-extern int cpu_feature(char *what, char *buf, int len);
-extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
-extern int arch_fixup(unsigned long address, void *sc_ptr);
-extern void arch_init_thread(void);
-extern int raw(int fd);
-
-#endif
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index 1211664..356e50f 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -10,8 +10,8 @@
#include "asm/pgtable.h"
#include "asm/tlbflush.h"
#include "asm/uaccess.h"
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
#include "mem_user.h"
#include "kern.h"
#include "irq_user.h"
diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
index 8cde431..cda91aa 100644
--- a/arch/um/kernel/init_task.c
+++ b/arch/um/kernel/init_task.c
@@ -10,7 +10,6 @@
#include "linux/mqueue.h"
#include "asm/uaccess.h"
#include "asm/pgtable.h"
-#include "user_util.h"
#include "mem_user.h"
#include "os.h"
diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c
index 82ecf90..16dc43e 100644
--- a/arch/um/kernel/initrd.c
+++ b/arch/um/kernel/initrd.c
@@ -7,7 +7,6 @@
#include "linux/bootmem.h"
#include "linux/initrd.h"
#include "asm/types.h"
-#include "user_util.h"
#include "kern_util.h"
#include "initrd.h"
#include "init.h"
@@ -22,12 +21,20 @@ static int __init read_initrd(void)
long long size;
int err;
- if(initrd == NULL) return 0;
+ if(initrd == NULL)
+ return 0;
+
err = os_file_size(initrd, &size);
- if(err) return 0;
+ if(err)
+ return 0;
+
area = alloc_bootmem(size);
- if(area == NULL) return 0;
- if(load_initrd(initrd, area, size) == -1) return 0;
+ if(area == NULL)
+ return 0;
+
+ if(load_initrd(initrd, area, size) == -1)
+ return 0;
+
initrd_start = (unsigned long) area;
initrd_end = initrd_start + size;
return 0;
@@ -54,25 +61,15 @@ int load_initrd(char *filename, void *buf, int size)
fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
if(fd < 0){
printk("Opening '%s' failed - err = %d\n", filename, -fd);
- return(-1);
+ return -1;
}
n = os_read_file(fd, buf, size);
if(n != size){
printk("Read of %d bytes from '%s' failed, err = %d\n", size,
filename, -n);
- return(-1);
+ return -1;
}
os_close_file(fd);
- return(0);
+ return 0;
}
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index dbf2f5b..8f2ed36 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -25,7 +25,6 @@
#include "asm/system.h"
#include "asm/errno.h"
#include "asm/uaccess.h"
-#include "user_util.h"
#include "kern_util.h"
#include "irq_user.h"
#include "irq_kern.h"
@@ -79,6 +78,14 @@ skip:
return 0;
}
+/*
+ * This list is accessed under irq_lock, except in sigio_handler,
+ * where it is safe from being modified. IRQ handlers won't change it -
+ * if an IRQ source has vanished, it will be freed by free_irqs just
+ * before returning from sigio_handler. That will process a separate
+ * list of irqs to free, with its own locking, coming back here to
+ * remove list elements, taking the irq_lock to do so.
+ */
static struct irq_fd *active_fds = NULL;
static struct irq_fd **last_irq_ptr = &active_fds;
@@ -244,6 +251,7 @@ void free_irq_by_fd(int fd)
free_irq_by_cb(same_fd, &fd);
}
+/* Must be called with irq_lock held */
static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
{
struct irq_fd *irq;
@@ -309,6 +317,12 @@ void deactivate_fd(int fd, int irqnum)
ignore_sigio_fd(fd);
}
+/*
+ * Called just before shutdown in order to provide a clean exec
+ * environment in case the system is rebooting. No locking because
+ * that would cause a pointless shutdown hang if something hadn't
+ * released the lock.
+ */
int deactivate_all_fds(void)
{
struct irq_fd *irq;
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 0e00cf9..7b3e53f 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -16,7 +16,7 @@
#include "asm/page.h"
#include "asm/tlbflush.h"
#include "kern_util.h"
-#include "user_util.h"
+#include "as-layout.h"
#include "mem_user.h"
#include "os.h"
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index df7d662..72ff856 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -13,8 +13,8 @@
#include "asm/page.h"
#include "asm/fixmap.h"
#include "asm/pgalloc.h"
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
#include "kern.h"
#include "mem_user.h"
#include "uml_uaccess.h"
@@ -216,7 +216,7 @@ static void __init fixaddr_user_init( void)
#endif
}
-void paging_init(void)
+void __init paging_init(void)
{
unsigned long zones_size[MAX_NR_ZONES], vaddr;
int i;
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 638f3b5..3ba6e4c 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -13,7 +13,7 @@
#include "asm/types.h"
#include "asm/pgtable.h"
#include "kern_util.h"
-#include "user_util.h"
+#include "as-layout.h"
#include "mode_kern.h"
#include "mem.h"
#include "mem_user.h"
@@ -21,229 +21,8 @@
#include "kern.h"
#include "init.h"
-struct phys_desc {
- struct rb_node rb;
- int fd;
- __u64 offset;
- void *virt;
- unsigned long phys;
- struct list_head list;
-};
-
-static struct rb_root phys_mappings = RB_ROOT;
-
-static struct rb_node **find_rb(void *virt)
-{
- struct rb_node **n = &phys_mappings.rb_node;
- struct phys_desc *d;
-
- while(*n != NULL){
- d = rb_entry(*n, struct phys_desc, rb);
- if(d->virt == virt)
- return n;
-
- if(d->virt > virt)
- n = &(*n)->rb_left;
- else
- n = &(*n)->rb_right;
- }
-
- return n;
-}
-
-static struct phys_desc *find_phys_mapping(void *virt)
-{
- struct rb_node **n = find_rb(virt);
-
- if(*n == NULL)
- return NULL;
-
- return rb_entry(*n, struct phys_desc, rb);
-}
-
-static void insert_phys_mapping(struct phys_desc *desc)
-{
- struct rb_node **n = find_rb(desc->virt);
-
- if(*n != NULL)
- panic("Physical remapping for %p already present",
- desc->virt);
-
- rb_link_node(&desc->rb, rb_parent(*n), n);
- rb_insert_color(&desc->rb, &phys_mappings);
-}
-
-LIST_HEAD(descriptor_mappings);
-
-struct desc_mapping {
- int fd;
- struct list_head list;
- struct list_head pages;
-};
-
-static struct desc_mapping *find_mapping(int fd)
-{
- struct desc_mapping *desc;
- struct list_head *ele;
-
- list_for_each(ele, &descriptor_mappings){
- desc = list_entry(ele, struct desc_mapping, list);
- if(desc->fd == fd)
- return desc;
- }
-
- return NULL;
-}
-
-static struct desc_mapping *descriptor_mapping(int fd)
-{
- struct desc_mapping *desc;
-
- desc = find_mapping(fd);
- if(desc != NULL)
- return desc;
-
- desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
- if(desc == NULL)
- return NULL;
-
- *desc = ((struct desc_mapping)
- { .fd = fd,
- .list = LIST_HEAD_INIT(desc->list),
- .pages = LIST_HEAD_INIT(desc->pages) });
- list_add(&desc->list, &descriptor_mappings);
-
- return desc;
-}
-
-int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
-{
- struct desc_mapping *fd_maps;
- struct phys_desc *desc;
- unsigned long phys;
- int err;
-
- fd_maps = descriptor_mapping(fd);
- if(fd_maps == NULL)
- return -ENOMEM;
-
- phys = __pa(virt);
- desc = find_phys_mapping(virt);
- if(desc != NULL)
- panic("Address 0x%p is already substituted\n", virt);
-
- err = -ENOMEM;
- desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
- if(desc == NULL)
- goto out;
-
- *desc = ((struct phys_desc)
- { .fd = fd,
- .offset = offset,
- .virt = virt,
- .phys = __pa(virt),
- .list = LIST_HEAD_INIT(desc->list) });
- insert_phys_mapping(desc);
-
- list_add(&desc->list, &fd_maps->pages);
-
- virt = (void *) ((unsigned long) virt & PAGE_MASK);
- err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
- if(!err)
- goto out;
-
- rb_erase(&desc->rb, &phys_mappings);
- kfree(desc);
- out:
- return err;
-}
-
static int physmem_fd = -1;
-static void remove_mapping(struct phys_desc *desc)
-{
- void *virt = desc->virt;
- int err;
-
- rb_erase(&desc->rb, &phys_mappings);
- list_del(&desc->list);
- kfree(desc);
-
- err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
- if(err)
- panic("Failed to unmap block device page from physical memory, "
- "errno = %d", -err);
-}
-
-int physmem_remove_mapping(void *virt)
-{
- struct phys_desc *desc;
-
- virt = (void *) ((unsigned long) virt & PAGE_MASK);
- desc = find_phys_mapping(virt);
- if(desc == NULL)
- return 0;
-
- remove_mapping(desc);
- return 1;
-}
-
-void physmem_forget_descriptor(int fd)
-{
- struct desc_mapping *desc;
- struct phys_desc *page;
- struct list_head *ele, *next;
- __u64 offset;
- void *addr;
- int err;
-
- desc = find_mapping(fd);
- if(desc == NULL)
- return;
-
- list_for_each_safe(ele, next, &desc->pages){
- page = list_entry(ele, struct phys_desc, list);
- offset = page->offset;
- addr = page->virt;
- remove_mapping(page);
- err = os_seek_file(fd, offset);
- if(err)
- panic("physmem_forget_descriptor - failed to seek "
- "to %lld in fd %d, error = %d\n",
- offset, fd, -err);
- err = os_read_file(fd, addr, PAGE_SIZE);
- if(err < 0)
- panic("physmem_forget_descriptor - failed to read "
- "from fd %d to 0x%p, error = %d\n",
- fd, addr, -err);
- }
-
- list_del(&desc->list);
- kfree(desc);
-}
-
-EXPORT_SYMBOL(physmem_forget_descriptor);
-EXPORT_SYMBOL(physmem_remove_mapping);
-EXPORT_SYMBOL(physmem_subst_mapping);
-
-void arch_free_page(struct page *page, int order)
-{
- void *virt;
- int i;
-
- for(i = 0; i < (1 << order); i++){
- virt = __va(page_to_phys(page + i));
- physmem_remove_mapping(virt);
- }
-}
-
-int is_remapped(void *virt)
-{
- struct phys_desc *desc = find_phys_mapping(virt);
-
- return desc != NULL;
-}
-
/* Changed during early boot */
unsigned long high_physmem;
@@ -350,14 +129,9 @@ void setup_physmem(unsigned long start, unsigned long reserve_end,
int phys_mapping(unsigned long phys, __u64 *offset_out)
{
- struct phys_desc *desc = find_phys_mapping(__va(phys & PAGE_MASK));
int fd = -1;
- if(desc != NULL){
- fd = desc->fd;
- *offset_out = desc->offset;
- }
- else if(phys < physmem_size){
+ if(phys < physmem_size){
fd = physmem_fd;
*offset_out = phys;
}
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 348b272..8d2c549 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -32,8 +32,8 @@
#include "asm/tlbflush.h"
#include "asm/uaccess.h"
#include "asm/user.h"
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
#include "kern.h"
#include "signal_kern.h"
#include "init.h"
@@ -54,11 +54,9 @@
*/
struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
-int external_pid(void *t)
+static inline int external_pid(struct task_struct *task)
{
- struct task_struct *task = t ? t : current;
-
- return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
+ return CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task);
}
int pid_to_processor_id(int pid)
@@ -66,9 +64,10 @@ int pid_to_processor_id(int pid)
int i;
for(i = 0; i < ncpus; i++){
- if(cpu_tasks[i].pid == pid) return(i);
+ if(cpu_tasks[i].pid == pid)
+ return i;
}
- return(-1);
+ return -1;
}
void free_stack(unsigned long stack, int order)
@@ -85,9 +84,9 @@ unsigned long alloc_stack(int order, int atomic)
flags = GFP_ATOMIC;
page = __get_free_pages(flags, order);
if(page == 0)
- return(0);
+ return 0;
stack_protections(page);
- return(page);
+ return page;
}
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
@@ -98,15 +97,11 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
current->thread.request.u.thread.arg = arg;
pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0,
&current->thread.regs, 0, NULL, NULL);
- if(pid < 0)
- panic("do_fork failed in kernel_thread, errno = %d", pid);
- return(pid);
+ return pid;
}
-void set_current(void *t)
+static inline void set_current(struct task_struct *task)
{
- struct task_struct *task = t;
-
cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task)
{ external_pid(task), task });
}
@@ -128,14 +123,16 @@ void *_switch_to(void *prev, void *next, void *last)
prev= current;
} while(current->thread.saved_task);
- return(current->thread.prev_sched);
+ return current->thread.prev_sched;
}
void interrupt_end(void)
{
- if(need_resched()) schedule();
- if(test_tsk_thread_flag(current, TIF_SIGPENDING)) do_signal();
+ if(need_resched())
+ schedule();
+ if(test_tsk_thread_flag(current, TIF_SIGPENDING))
+ do_signal();
}
void release_thread(struct task_struct *task)
@@ -150,7 +147,7 @@ void exit_thread(void)
void *get_current(void)
{
- return(current);
+ return current;
}
int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
@@ -188,15 +185,12 @@ void initial_thread_cb(void (*proc)(void *), void *arg)
kmalloc_ok = save_kmalloc_ok;
}
+#ifdef CONFIG_MODE_TT
unsigned long stack_sp(unsigned long page)
{
- return(page + PAGE_SIZE - sizeof(void *));
-}
-
-int current_pid(void)
-{
- return(current->pid);
+ return page + PAGE_SIZE - sizeof(void *);
}
+#endif
void default_idle(void)
{
@@ -221,11 +215,6 @@ void cpu_idle(void)
CHOOSE_MODE(init_idle_tt(), init_idle_skas());
}
-int page_size(void)
-{
- return(PAGE_SIZE);
-}
-
void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
pte_t *pte_out)
{
@@ -236,68 +225,43 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
pte_t ptent;
if(task->mm == NULL)
- return(ERR_PTR(-EINVAL));
+ return ERR_PTR(-EINVAL);
pgd = pgd_offset(task->mm, addr);
if(!pgd_present(*pgd))
- return(ERR_PTR(-EINVAL));
+ return ERR_PTR(-EINVAL);
pud = pud_offset(pgd, addr);
if(!pud_present(*pud))
- return(ERR_PTR(-EINVAL));
+ return ERR_PTR(-EINVAL);
pmd = pmd_offset(pud, addr);
if(!pmd_present(*pmd))
- return(ERR_PTR(-EINVAL));
+ return ERR_PTR(-EINVAL);
pte = pte_offset_kernel(pmd, addr);
ptent = *pte;
if(!pte_present(ptent))
- return(ERR_PTR(-EINVAL));
+ return ERR_PTR(-EINVAL);
if(pte_out != NULL)
*pte_out = ptent;
- return((void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK));
+ return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK);
}
char *current_cmd(void)
{
#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
- return("(Unknown)");
+ return "(Unknown)";
#else
void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
#endif
}
-void force_sigbus(void)
-{
- printk(KERN_ERR "Killing pid %d because of a lack of memory\n",
- current->pid);
- lock_kernel();
- sigaddset(&current->pending.signal, SIGBUS);
- recalc_sigpending();
- current->flags |= PF_SIGNALED;
- do_exit(SIGBUS | 0x80);
-}
-
void dump_thread(struct pt_regs *regs, struct user *u)
{
}
-void enable_hlt(void)
-{
- panic("enable_hlt");
-}
-
-EXPORT_SYMBOL(enable_hlt);
-
-void disable_hlt(void)
-{
- panic("disable_hlt");
-}
-
-EXPORT_SYMBOL(disable_hlt);
-
void *um_kmalloc(int size)
{
return kmalloc(size, GFP_KERNEL);
@@ -313,36 +277,17 @@ void *um_vmalloc(int size)
return vmalloc(size);
}
-void *um_vmalloc_atomic(int size)
-{
- return __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, PAGE_KERNEL);
-}
-
int __cant_sleep(void) {
return in_atomic() || irqs_disabled() || in_interrupt();
/* Is in_interrupt() really needed? */
}
-unsigned long get_fault_addr(void)
-{
- return((unsigned long) current->thread.fault_addr);
-}
-
-EXPORT_SYMBOL(get_fault_addr);
-
-void not_implemented(void)
-{
- printk(KERN_DEBUG "Something isn't implemented in here\n");
-}
-
-EXPORT_SYMBOL(not_implemented);
-
int user_context(unsigned long sp)
{
unsigned long stack;
stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
- return(stack != (unsigned long) current_thread);
+ return stack != (unsigned long) current_thread;
}
extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
@@ -363,22 +308,22 @@ char *uml_strdup(char *string)
int copy_to_user_proc(void __user *to, void *from, int size)
{
- return(copy_to_user(to, from, size));
+ return copy_to_user(to, from, size);
}
int copy_from_user_proc(void *to, void __user *from, int size)
{
- return(copy_from_user(to, from, size));
+ return copy_from_user(to, from, size);
}
int clear_user_proc(void __user *buf, int size)
{
- return(clear_user(buf, size));
+ return clear_user(buf, size);
}
int strlen_user_proc(char __user *str)
{
- return(strlen_user(str));
+ return strlen_user(str);
}
int smp_sigio_handler(void)
@@ -387,14 +332,14 @@ int smp_sigio_handler(void)
int cpu = current_thread->cpu;
IPI_handler(cpu);
if(cpu != 0)
- return(1);
+ return 1;
#endif
- return(0);
+ return 0;
}
int cpu(void)
{
- return(current_thread->cpu);
+ return current_thread->cpu;
}
static atomic_t using_sysemu = ATOMIC_INIT(0);
@@ -443,7 +388,7 @@ int __init make_proc_sysemu(void)
if (ent == NULL)
{
printk(KERN_WARNING "Failed to register /proc/sysemu\n");
- return(0);
+ return 0;
}
ent->read_proc = proc_read_sysemu;
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index f602623..7e4305a 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -6,7 +6,6 @@
#include "linux/module.h"
#include "linux/sched.h"
#include "asm/smp.h"
-#include "user_util.h"
#include "kern_util.h"
#include "kern.h"
#include "os.h"
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c
index 3c798cd..c4020c3 100644
--- a/arch/um/kernel/signal.c
+++ b/arch/um/kernel/signal.c
@@ -17,7 +17,6 @@
#include "asm/signal.h"
#include "asm/uaccess.h"
#include "asm/unistd.h"
-#include "user_util.h"
#include "asm/ucontext.h"
#include "kern_util.h"
#include "signal_kern.h"
diff --git a/arch/um/kernel/skas/exec.c b/arch/um/kernel/skas/exec.c
index 54b7959..580eb64 100644
--- a/arch/um/kernel/skas/exec.c
+++ b/arch/um/kernel/skas/exec.c
@@ -17,7 +17,17 @@
void flush_thread_skas(void)
{
- force_flush_all();
+ void *data = NULL;
+ unsigned long end = proc_mm ? task_size : CONFIG_STUB_START;
+ int ret;
+
+ ret = unmap(&current->mm->context.skas.id, 0, end, 1, &data);
+ if(ret){
+ printk("flush_thread_skas - clearing address space failed, "
+ "err = %d\n", ret);
+ force_sig(SIGKILL, current);
+ }
+
switch_mm_skas(&current->mm->context.skas.id);
}
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index ae4fa71..ef36fac 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -13,9 +13,9 @@
#include "asm/uaccess.h"
#include "asm/atomic.h"
#include "kern_util.h"
+#include "as-layout.h"
#include "skas.h"
#include "os.h"
-#include "user_util.h"
#include "tlb.h"
#include "kern.h"
#include "mode.h"
diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c
index 27eb29c..c0f0693 100644
--- a/arch/um/kernel/skas/tlb.c
+++ b/arch/um/kernel/skas/tlb.c
@@ -10,7 +10,6 @@
#include "asm/page.h"
#include "asm/pgtable.h"
#include "asm/mmu.h"
-#include "user_util.h"
#include "mem_user.h"
#include "mem.h"
#include "skas.h"
@@ -28,19 +27,17 @@ static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last,
switch(op->type){
case MMAP:
ret = map(&mmu->skas.id, op->u.mmap.addr,
- op->u.mmap.len, op->u.mmap.r, op->u.mmap.w,
- op->u.mmap.x, op->u.mmap.fd,
- op->u.mmap.offset, finished, flush);
+ op->u.mmap.len, op->u.mmap.prot,
+ op->u.mmap.fd, op->u.mmap.offset, finished,
+ flush);
break;
case MUNMAP:
- ret = unmap(&mmu->skas.id,
- (void *) op->u.munmap.addr,
+ ret = unmap(&mmu->skas.id, op->u.munmap.addr,
op->u.munmap.len, finished, flush);
break;
case MPROTECT:
ret = protect(&mmu->skas.id, op->u.mprotect.addr,
- op->u.mprotect.len, op->u.mprotect.r,
- op->u.mprotect.w, op->u.mprotect.x,
+ op->u.mprotect.len, op->u.mprotect.prot,
finished, flush);
break;
default:
@@ -92,6 +89,76 @@ void flush_tlb_mm_skas(struct mm_struct *mm)
void force_flush_all_skas(void)
{
- unsigned long end = proc_mm ? task_size : CONFIG_STUB_START;
- fix_range(current->mm, 0, end, 1);
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma = mm->mmap;
+
+ while(vma != NULL) {
+ fix_range(mm, vma->vm_start, vma->vm_end, 1);
+ vma = vma->vm_next;
+ }
+}
+
+void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ struct mm_struct *mm = vma->vm_mm;
+ void *flush = NULL;
+ int r, w, x, prot, err = 0;
+ struct mm_id *mm_id;
+
+ pgd = pgd_offset(mm, address);
+ if(!pgd_present(*pgd))
+ goto kill;
+
+ pud = pud_offset(pgd, address);
+ if(!pud_present(*pud))
+ goto kill;
+
+ pmd = pmd_offset(pud, address);
+ if(!pmd_present(*pmd))
+ goto kill;
+
+ pte = pte_offset_kernel(pmd, address);
+
+ r = pte_read(*pte);
+ w = pte_write(*pte);
+ x = pte_exec(*pte);
+ if (!pte_young(*pte)) {
+ r = 0;
+ w = 0;
+ } else if (!pte_dirty(*pte)) {
+ w = 0;
+ }
+
+ mm_id = &mm->context.skas.id;
+ prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
+ (x ? UM_PROT_EXEC : 0));
+ if(pte_newpage(*pte)){
+ if(pte_present(*pte)){
+ unsigned long long offset;
+ int fd;
+
+ fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset);
+ err = map(mm_id, address, PAGE_SIZE, prot, fd, offset,
+ 1, &flush);
+ }
+ else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush);
+ }
+ else if(pte_newprot(*pte))
+ err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush);
+
+ if(err)
+ goto kill;
+
+ *pte = pte_mkuptodate(*pte);
+
+ return;
+
+kill:
+ printk("Failed to flush page for address 0x%lx\n", address);
+ force_sig(SIGKILL, current);
}
+
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
index 759b070..e6a7778 100644
--- a/arch/um/kernel/smp.c
+++ b/arch/um/kernel/smp.c
@@ -21,7 +21,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
#include "asm/smp.h"
#include "asm/processor.h"
#include "asm/spinlock.h"
-#include "user_util.h"
#include "kern_util.h"
#include "kern.h"
#include "irq_user.h"
@@ -90,7 +89,7 @@ static int idle_proc(void *cpup)
cpu_set(cpu, cpu_online_map);
default_idle();
- return(0);
+ return 0;
}
static struct task_struct *idle_thread(int cpu)
@@ -98,8 +97,8 @@ static struct task_struct *idle_thread(int cpu)
struct task_struct *new_task;
unsigned char c;
- current->thread.request.u.thread.proc = idle_proc;
- current->thread.request.u.thread.arg = (void *) cpu;
+ current->thread.request.u.thread.proc = idle_proc;
+ current->thread.request.u.thread.arg = (void *) cpu;
new_task = fork_idle(cpu);
if(IS_ERR(new_task))
panic("copy_process failed in idle_thread, error = %ld",
@@ -110,9 +109,9 @@ static struct task_struct *idle_thread(int cpu)
.task = new_task } );
idle_threads[cpu] = new_task;
CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c,
- sizeof(c)),
+ sizeof(c)),
({ panic("skas mode doesn't support SMP"); }));
- return(new_task);
+ return new_task;
}
void smp_prepare_cpus(unsigned int maxcpus)
@@ -163,13 +162,13 @@ int __cpu_up(unsigned int cpu)
cpu_set(cpu, smp_commenced_mask);
while (!cpu_isset(cpu, cpu_online_map))
mb();
- return(0);
+ return 0;
}
int setup_profiling_timer(unsigned int multiplier)
{
printk(KERN_INFO "setup_profiling_timer\n");
- return(0);
+ return 0;
}
void smp_call_function_slave(int cpu);
@@ -205,7 +204,7 @@ void IPI_handler(int cpu)
int hard_smp_processor_id(void)
{
- return(pid_to_processor_id(os_getpid()));
+ return pid_to_processor_id(os_getpid());
}
static DEFINE_SPINLOCK(call_lock);
@@ -254,14 +253,3 @@ int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic,
}
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index 2828c52..237c4ea 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -18,7 +18,6 @@
#include "asm/mman.h"
#include "asm/uaccess.h"
#include "kern_util.h"
-#include "user_util.h"
#include "sysdep/syscalls.h"
#include "mode_kern.h"
#include "choose-mode.h"
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index f9e02b3..9326357 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -10,7 +10,6 @@
#include "asm/page.h"
#include "asm/processor.h"
#include "sysrq.h"
-#include "user_util.h"
/* Catch non-i386 SUBARCH's. */
#if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT)
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index b1f8b07..259c49d 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -18,7 +18,6 @@
#include "asm/param.h"
#include "asm/current.h"
#include "kern_util.h"
-#include "user_util.h"
#include "mode.h"
#include "os.h"
@@ -35,8 +34,8 @@ unsigned long long sched_clock(void)
return (unsigned long long)jiffies_64 * (1000000000 / HZ);
}
-static unsigned long long prev_nsecs[NR_CPUS];
#ifdef CONFIG_UML_REAL_TIME_CLOCK
+static unsigned long long prev_nsecs[NR_CPUS];
static long long delta[NR_CPUS]; /* Deviation per interval */
#endif
@@ -95,7 +94,12 @@ irqreturn_t um_timer(int irq, void *dev)
do_timer(1);
+#ifdef CONFIG_UML_REAL_TIME_CLOCK
nsecs = get_time();
+#else
+ nsecs = (unsigned long long) xtime.tv_sec * BILLION + xtime.tv_nsec +
+ BILLION / HZ;
+#endif
xtime.tv_sec = nsecs / NSEC_PER_SEC;
xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC;
@@ -128,13 +132,18 @@ void time_init(void)
nsecs = os_nsecs();
set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
-nsecs % BILLION);
+ set_normalized_timespec(&xtime, nsecs / BILLION, nsecs % BILLION);
late_time_init = register_timer;
}
void do_gettimeofday(struct timeval *tv)
{
+#ifdef CONFIG_UML_REAL_TIME_CLOCK
unsigned long long nsecs = get_time();
-
+#else
+ unsigned long long nsecs = (unsigned long long) xtime.tv_sec * BILLION +
+ xtime.tv_nsec;
+#endif
tv->tv_sec = nsecs / NSEC_PER_SEC;
/* Careful about calculations here - this was originally done as
* (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC
@@ -168,6 +177,8 @@ int do_settimeofday(struct timespec *tv)
void timer_handler(int sig, union uml_pt_regs *regs)
{
+ if(current_thread->cpu == 0)
+ timer_irq(regs);
local_irq_disable();
irq_enter();
update_process_times(CHOOSE_MODE(
@@ -175,6 +186,4 @@ void timer_handler(int sig, union uml_pt_regs *regs)
(regs)->skas.is_user));
irq_exit();
local_irq_enable();
- if(current_thread->cpu == 0)
- timer_irq(regs);
}
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index 54a5ff2..8a8d528 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -6,17 +6,18 @@
#include "linux/mm.h"
#include "asm/page.h"
#include "asm/pgalloc.h"
+#include "asm/pgtable.h"
#include "asm/tlbflush.h"
#include "choose-mode.h"
#include "mode_kern.h"
-#include "user_util.h"
+#include "as-layout.h"
#include "tlb.h"
#include "mem.h"
#include "mem_user.h"
#include "os.h"
static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
- int r, int w, int x, struct host_vm_op *ops, int *index,
+ unsigned int prot, struct host_vm_op *ops, int *index,
int last_filled, union mm_context *mmu, void **flush,
int (*do_ops)(union mm_context *, struct host_vm_op *,
int, int, void **))
@@ -30,8 +31,7 @@ static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
last = &ops[*index];
if((last->type == MMAP) &&
(last->u.mmap.addr + last->u.mmap.len == virt) &&
- (last->u.mmap.r == r) && (last->u.mmap.w == w) &&
- (last->u.mmap.x == x) && (last->u.mmap.fd == fd) &&
+ (last->u.mmap.prot == prot) && (last->u.mmap.fd == fd) &&
(last->u.mmap.offset + last->u.mmap.len == offset)){
last->u.mmap.len += len;
return 0;
@@ -47,9 +47,7 @@ static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
.u = { .mmap = {
.addr = virt,
.len = len,
- .r = r,
- .w = w,
- .x = x,
+ .prot = prot,
.fd = fd,
.offset = offset }
} });
@@ -86,8 +84,8 @@ static int add_munmap(unsigned long addr, unsigned long len,
return ret;
}
-static int add_mprotect(unsigned long addr, unsigned long len, int r, int w,
- int x, struct host_vm_op *ops, int *index,
+static int add_mprotect(unsigned long addr, unsigned long len,
+ unsigned int prot, struct host_vm_op *ops, int *index,
int last_filled, union mm_context *mmu, void **flush,
int (*do_ops)(union mm_context *, struct host_vm_op *,
int, int, void **))
@@ -99,8 +97,7 @@ static int add_mprotect(unsigned long addr, unsigned long len, int r, int w,
last = &ops[*index];
if((last->type == MPROTECT) &&
(last->u.mprotect.addr + last->u.mprotect.len == addr) &&
- (last->u.mprotect.r == r) && (last->u.mprotect.w == w) &&
- (last->u.mprotect.x == x)){
+ (last->u.mprotect.prot == prot)){
last->u.mprotect.len += len;
return 0;
}
@@ -115,114 +112,145 @@ static int add_mprotect(unsigned long addr, unsigned long len, int r, int w,
.u = { .mprotect = {
.addr = addr,
.len = len,
- .r = r,
- .w = w,
- .x = x } } });
+ .prot = prot } } });
return ret;
}
#define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1))
+static inline int update_pte_range(pmd_t *pmd, unsigned long addr,
+ unsigned long end, struct host_vm_op *ops,
+ int last_op, int *op_index, int force,
+ union mm_context *mmu, void **flush,
+ int (*do_ops)(union mm_context *,
+ struct host_vm_op *, int, int,
+ void **))
+{
+ pte_t *pte;
+ int r, w, x, prot, ret = 0;
+
+ pte = pte_offset_kernel(pmd, addr);
+ do {
+ r = pte_read(*pte);
+ w = pte_write(*pte);
+ x = pte_exec(*pte);
+ if (!pte_young(*pte)) {
+ r = 0;
+ w = 0;
+ } else if (!pte_dirty(*pte)) {
+ w = 0;
+ }
+ prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
+ (x ? UM_PROT_EXEC : 0));
+ if(force || pte_newpage(*pte)){
+ if(pte_present(*pte))
+ ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK,
+ PAGE_SIZE, prot, ops, op_index,
+ last_op, mmu, flush, do_ops);
+ else ret = add_munmap(addr, PAGE_SIZE, ops, op_index,
+ last_op, mmu, flush, do_ops);
+ }
+ else if(pte_newprot(*pte))
+ ret = add_mprotect(addr, PAGE_SIZE, prot, ops, op_index,
+ last_op, mmu, flush, do_ops);
+ *pte = pte_mkuptodate(*pte);
+ } while (pte++, addr += PAGE_SIZE, ((addr != end) && !ret));
+ return ret;
+}
+
+static inline int update_pmd_range(pud_t *pud, unsigned long addr,
+ unsigned long end, struct host_vm_op *ops,
+ int last_op, int *op_index, int force,
+ union mm_context *mmu, void **flush,
+ int (*do_ops)(union mm_context *,
+ struct host_vm_op *, int, int,
+ void **))
+{
+ pmd_t *pmd;
+ unsigned long next;
+ int ret = 0;
+
+ pmd = pmd_offset(pud, addr);
+ do {
+ next = pmd_addr_end(addr, end);
+ if(!pmd_present(*pmd)){
+ if(force || pmd_newpage(*pmd)){
+ ret = add_munmap(addr, next - addr, ops,
+ op_index, last_op, mmu,
+ flush, do_ops);
+ pmd_mkuptodate(*pmd);
+ }
+ }
+ else ret = update_pte_range(pmd, addr, next, ops, last_op,
+ op_index, force, mmu, flush,
+ do_ops);
+ } while (pmd++, addr = next, ((addr != end) && !ret));
+ return ret;
+}
+
+static inline int update_pud_range(pgd_t *pgd, unsigned long addr,
+ unsigned long end, struct host_vm_op *ops,
+ int last_op, int *op_index, int force,
+ union mm_context *mmu, void **flush,
+ int (*do_ops)(union mm_context *,
+ struct host_vm_op *, int, int,
+ void **))
+{
+ pud_t *pud;
+ unsigned long next;
+ int ret = 0;
+
+ pud = pud_offset(pgd, addr);
+ do {
+ next = pud_addr_end(addr, end);
+ if(!pud_present(*pud)){
+ if(force || pud_newpage(*pud)){
+ ret = add_munmap(addr, next - addr, ops,
+ op_index, last_op, mmu,
+ flush, do_ops);
+ pud_mkuptodate(*pud);
+ }
+ }
+ else ret = update_pmd_range(pud, addr, next, ops, last_op,
+ op_index, force, mmu, flush,
+ do_ops);
+ } while (pud++, addr = next, ((addr != end) && !ret));
+ return ret;
+}
+
void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
unsigned long end_addr, int force,
int (*do_ops)(union mm_context *, struct host_vm_op *,
int, int, void **))
{
- pgd_t *npgd;
- pud_t *npud;
- pmd_t *npmd;
- pte_t *npte;
+ pgd_t *pgd;
union mm_context *mmu = &mm->context;
- unsigned long addr, end;
- int r, w, x;
struct host_vm_op ops[1];
+ unsigned long addr = start_addr, next;
+ int ret = 0, last_op = ARRAY_SIZE(ops) - 1, op_index = -1;
void *flush = NULL;
- int op_index = -1, last_op = ARRAY_SIZE(ops) - 1;
- int ret = 0;
-
- if(mm == NULL)
- return;
ops[0].type = NONE;
- for(addr = start_addr; addr < end_addr && !ret;){
- npgd = pgd_offset(mm, addr);
- if(!pgd_present(*npgd)){
- end = ADD_ROUND(addr, PGDIR_SIZE);
- if(end > end_addr)
- end = end_addr;
- if(force || pgd_newpage(*npgd)){
- ret = add_munmap(addr, end - addr, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
- pgd_mkuptodate(*npgd);
- }
- addr = end;
- continue;
- }
-
- npud = pud_offset(npgd, addr);
- if(!pud_present(*npud)){
- end = ADD_ROUND(addr, PUD_SIZE);
- if(end > end_addr)
- end = end_addr;
- if(force || pud_newpage(*npud)){
- ret = add_munmap(addr, end - addr, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
- pud_mkuptodate(*npud);
- }
- addr = end;
- continue;
- }
-
- npmd = pmd_offset(npud, addr);
- if(!pmd_present(*npmd)){
- end = ADD_ROUND(addr, PMD_SIZE);
- if(end > end_addr)
- end = end_addr;
- if(force || pmd_newpage(*npmd)){
- ret = add_munmap(addr, end - addr, ops,
+ pgd = pgd_offset(mm, addr);
+ do {
+ next = pgd_addr_end(addr, end_addr);
+ if(!pgd_present(*pgd)){
+ if (force || pgd_newpage(*pgd)){
+ ret = add_munmap(addr, next - addr, ops,
&op_index, last_op, mmu,
&flush, do_ops);
- pmd_mkuptodate(*npmd);
+ pgd_mkuptodate(*pgd);
}
- addr = end;
- continue;
- }
-
- npte = pte_offset_kernel(npmd, addr);
- r = pte_read(*npte);
- w = pte_write(*npte);
- x = pte_exec(*npte);
- if (!pte_young(*npte)) {
- r = 0;
- w = 0;
- } else if (!pte_dirty(*npte)) {
- w = 0;
- }
- if(force || pte_newpage(*npte)){
- if(pte_present(*npte))
- ret = add_mmap(addr,
- pte_val(*npte) & PAGE_MASK,
- PAGE_SIZE, r, w, x, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
- else ret = add_munmap(addr, PAGE_SIZE, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
}
- else if(pte_newprot(*npte))
- ret = add_mprotect(addr, PAGE_SIZE, r, w, x, ops,
- &op_index, last_op, mmu,
- &flush, do_ops);
+ else ret = update_pud_range(pgd, addr, next, ops, last_op,
+ &op_index, force, mmu, &flush,
+ do_ops);
+ } while (pgd++, addr = next, ((addr != end_addr) && !ret));
- *npte = pte_mkuptodate(*npte);
- addr += PAGE_SIZE;
- }
if(!ret)
ret = (*do_ops)(mmu, ops, op_index, 1, &flush);
-/* This is not an else because ret is modified above */
+ /* This is not an else because ret is modified above */
if(ret) {
printk("fix_range_common: failed, killing current process\n");
force_sig(SIGKILL, current);
@@ -343,12 +371,6 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr)
return(pte_offset_map(pmd, addr));
}
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
-{
- address &= PAGE_MASK;
- flush_tlb_range(vma, address, address + PAGE_SIZE);
-}
-
void flush_tlb_all(void)
{
flush_tlb_mm(current->mm);
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 26f15c4..abab90c 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -18,8 +18,9 @@
#include "asm/current.h"
#include "asm/irq.h"
#include "sysdep/sigcontext.h"
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
+#include "arch.h"
#include "kern.h"
#include "chan_kern.h"
#include "mconsole_kern.h"
@@ -71,8 +72,8 @@ good_area:
goto out;
/* Don't require VM_READ|VM_EXEC for write faults! */
- if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC)))
- goto out;
+ if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC)))
+ goto out;
do {
survive:
@@ -156,20 +157,23 @@ static void segv_handler(int sig, union uml_pt_regs *regs)
* the info in the regs. A pointer to the info then would
* give us bad data!
*/
-unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
+unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
+ union uml_pt_regs *regs)
{
struct siginfo si;
void *catcher;
int err;
- int is_write = FAULT_WRITE(fi);
- unsigned long address = FAULT_ADDRESS(fi);
+ int is_write = FAULT_WRITE(fi);
+ unsigned long address = FAULT_ADDRESS(fi);
- if(!is_user && (address >= start_vm) && (address < end_vm)){
- flush_tlb_kernel_vm();
- return(0);
- }
- else if(current->mm == NULL)
- panic("Segfault with no mm");
+ if(!is_user && (address >= start_vm) && (address < end_vm)){
+ flush_tlb_kernel_vm();
+ return 0;
+ }
+ else if(current->mm == NULL) {
+ show_regs(container_of(regs, struct pt_regs, regs));
+ panic("Segfault with no mm");
+ }
if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi))
err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
@@ -182,26 +186,28 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
catcher = current->thread.fault_catcher;
if(!err)
- return(0);
+ return 0;
else if(catcher != NULL){
current->thread.fault_addr = (void *) address;
do_longjmp(catcher, 1);
}
else if(current->thread.fault_addr != NULL)
panic("fault_addr set but no fault catcher");
- else if(!is_user && arch_fixup(ip, sc))
- return(0);
+ else if(!is_user && arch_fixup(ip, regs))
+ return 0;
- if(!is_user)
+ if(!is_user) {
+ show_regs(container_of(regs, struct pt_regs, regs));
panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
address, ip);
+ }
if (err == -EACCES) {
si.si_signo = SIGBUS;
si.si_errno = 0;
si.si_code = BUS_ADRERR;
si.si_addr = (void __user *)address;
- current->thread.arch.faultinfo = fi;
+ current->thread.arch.faultinfo = fi;
force_sig_info(SIGBUS, &si, current);
} else if (err == -ENOMEM) {
printk("VM: killing process %s\n", current->comm);
@@ -210,10 +216,10 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
BUG_ON(err != -EFAULT);
si.si_signo = SIGSEGV;
si.si_addr = (void __user *) address;
- current->thread.arch.faultinfo = fi;
+ current->thread.arch.faultinfo = fi;
force_sig_info(SIGSEGV, &si, current);
}
- return(0);
+ return 0;
}
void relay_signal(int sig, union uml_pt_regs *regs)
@@ -223,12 +229,12 @@ void relay_signal(int sig, union uml_pt_regs *regs)
if(!UPT_IS_USER(regs)){
if(sig == SIGBUS)
- printk("Bus error - the /dev/shm or /tmp mount likely "
- "just ran out of space\n");
+ printk("Bus error - the host /dev/shm or /tmp mount "
+ "likely just ran out of space\n");
panic("Kernel mode signal %d", sig);
}
- current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
+ current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
force_sig(sig, current);
}
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
index ad66df1..98e2174 100644
--- a/arch/um/kernel/tt/exec_kern.c
+++ b/arch/um/kernel/tt/exec_kern.c
@@ -10,7 +10,6 @@
#include "asm/uaccess.h"
#include "asm/pgalloc.h"
#include "asm/tlbflush.h"
-#include "user_util.h"
#include "kern_util.h"
#include "irq_user.h"
#include "mem_user.h"
diff --git a/arch/um/kernel/tt/exec_user.c b/arch/um/kernel/tt/exec_user.c
index a92c02f..7b5f218 100644
--- a/arch/um/kernel/tt/exec_user.c
+++ b/arch/um/kernel/tt/exec_user.c
@@ -10,7 +10,6 @@
#include <errno.h>
#include <sys/wait.h>
#include <signal.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "ptrace_user.h"
diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c
index 8eba8f7..030e465 100644
--- a/arch/um/kernel/tt/gdb.c
+++ b/arch/um/kernel/tt/gdb.c
@@ -17,7 +17,6 @@
#include "user.h"
#include "debug.h"
#include "kern_util.h"
-#include "user_util.h"
#include "tt.h"
#include "sysdep/thread.h"
#include "os.h"
@@ -115,6 +114,8 @@ struct gdb_data {
int err;
};
+extern char *linux_prog;
+
static void config_gdb_cb(void *arg)
{
struct gdb_data *data = arg;
diff --git a/arch/um/kernel/tt/include/mode_kern-tt.h b/arch/um/kernel/tt/include/mode_kern-tt.h
deleted file mode 100644
index 2a35b15..0000000
--- a/arch/um/kernel/tt/include/mode_kern-tt.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __TT_MODE_KERN_H__
-#define __TT_MODE_KERN_H__
-
-#include "linux/sched.h"
-#include "asm/page.h"
-#include "asm/ptrace.h"
-#include "asm/uaccess.h"
-
-extern void switch_to_tt(void *prev, void *next);
-extern void flush_thread_tt(void);
-extern void start_thread_tt(struct pt_regs *regs, unsigned long eip,
- unsigned long esp);
-extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
- unsigned long stack_top, struct task_struct *p,
- struct pt_regs *regs);
-extern void release_thread_tt(struct task_struct *task);
-extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
-extern void init_idle_tt(void);
-extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end);
-extern void flush_tlb_kernel_vm_tt(void);
-extern void __flush_tlb_one_tt(unsigned long addr);
-extern void flush_tlb_range_tt(struct vm_area_struct *vma,
- unsigned long start, unsigned long end);
-extern void flush_tlb_mm_tt(struct mm_struct *mm);
-extern void force_flush_all_tt(void);
-extern long execute_syscall_tt(void *r);
-extern void before_mem_tt(unsigned long brk_start);
-extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
- unsigned long *task_size_out);
-extern int start_uml_tt(void);
-extern int external_pid_tt(struct task_struct *task);
-extern int thread_pid_tt(struct task_struct *task);
-
-#define kmem_end_tt (host_task_size - ABOVE_KMEM)
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c
index 4d1929d..d0c3c49 100644
--- a/arch/um/kernel/tt/mem.c
+++ b/arch/um/kernel/tt/mem.c
@@ -8,7 +8,6 @@
#include "asm/uaccess.h"
#include "mem_user.h"
#include "kern_util.h"
-#include "user_util.h"
#include "kern.h"
#include "tt.h"
diff --git a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c
index 03e5898..9774f63 100644
--- a/arch/um/kernel/tt/mem_user.c
+++ b/arch/um/kernel/tt/mem_user.c
@@ -11,7 +11,6 @@
#include <sys/mman.h>
#include "tt.h"
#include "mem_user.h"
-#include "user_util.h"
#include "os.h"
void remap_data(void *segment_start, void *segment_end, int w)
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index 1e86f0b..c631303 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -14,7 +14,6 @@
#include "asm/tlbflush.h"
#include "irq_user.h"
#include "kern_util.h"
-#include "user_util.h"
#include "os.h"
#include "kern.h"
#include "sigcontext.h"
@@ -65,7 +64,8 @@ void switch_to_tt(void *prev, void *next)
if(from->thread.mode.tt.switch_pipe[0] == -1)
os_kill_process(os_getpid(), 0);
- err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
+ err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c,
+ sizeof(c));
if(err != sizeof(c))
panic("read of switch_pipe failed, errno = %d", -err);
diff --git a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c
index 58800c5..420c23f 100644
--- a/arch/um/kernel/tt/ptproxy/proxy.c
+++ b/arch/um/kernel/tt/ptproxy/proxy.c
@@ -26,7 +26,6 @@ Jeff Dike (jdike@karaya.com) : Modified for integration into uml
#include "sysdep.h"
#include "wait.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
#include "tempfile.h"
@@ -339,11 +338,12 @@ int start_debugger(char *prog, int startup, int stop, int *fd_out)
"err = %d\n", -fd);
exit(1);
}
- os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
+ os_write_file(fd, gdb_init_string,
+ sizeof(gdb_init_string) - 1);
if(startup){
if(stop){
os_write_file(fd, "b start_kernel\n",
- strlen("b start_kernel\n"));
+ strlen("b start_kernel\n"));
}
os_write_file(fd, "c\n", strlen("c\n"));
}
diff --git a/arch/um/kernel/tt/ptproxy/ptrace.c b/arch/um/kernel/tt/ptproxy/ptrace.c
index 0377442..4b4f617 100644
--- a/arch/um/kernel/tt/ptproxy/ptrace.c
+++ b/arch/um/kernel/tt/ptproxy/ptrace.c
@@ -16,7 +16,6 @@ Jeff Dike (jdike@karaya.com) : Modified for integration into uml
#include "ptproxy.h"
#include "debug.h"
-#include "user_util.h"
#include "kern_util.h"
#include "ptrace_user.h"
#include "tt.h"
diff --git a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c
index 99f1783..e0e1ab0 100644
--- a/arch/um/kernel/tt/ptproxy/sysdep.c
+++ b/arch/um/kernel/tt/ptproxy/sysdep.c
@@ -13,7 +13,6 @@ terms and conditions.
#include <sys/types.h>
#include <linux/unistd.h>
#include "ptrace_user.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
diff --git a/arch/um/kernel/tt/ptproxy/wait.c b/arch/um/kernel/tt/ptproxy/wait.c
index 12f6319..bdd4af4 100644
--- a/arch/um/kernel/tt/ptproxy/wait.c
+++ b/arch/um/kernel/tt/ptproxy/wait.c
@@ -13,7 +13,6 @@ terms and conditions.
#include "ptproxy.h"
#include "sysdep.h"
#include "wait.h"
-#include "user_util.h"
#include "ptrace_user.h"
#include "sysdep/ptrace.h"
#include "sysdep/sigcontext.h"
diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c
index 902987b..f52b47a 100644
--- a/arch/um/kernel/tt/syscall_user.c
+++ b/arch/um/kernel/tt/syscall_user.c
@@ -11,7 +11,6 @@
#include "sigcontext.h"
#include "ptrace_user.h"
#include "task.h"
-#include "user_util.h"
#include "kern_util.h"
#include "syscall.h"
#include "tt.h"
diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
index ae6217c..7caa24f 100644
--- a/arch/um/kernel/tt/tlb.c
+++ b/arch/um/kernel/tt/tlb.c
@@ -12,7 +12,6 @@
#include "asm/pgtable.h"
#include "asm/uaccess.h"
#include "asm/tlbflush.h"
-#include "user_util.h"
#include "mem_user.h"
#include "os.h"
#include "tlb.h"
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
index b919535..c235883 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -19,7 +19,6 @@
#include "sigcontext.h"
#include "sysdep/sigcontext.h"
#include "os.h"
-#include "user_util.h"
#include "mem_user.h"
#include "process.h"
#include "kern_util.h"
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
index b5d9d64..3032eb5 100644
--- a/arch/um/kernel/tt/trap_user.c
+++ b/arch/um/kernel/tt/trap_user.c
@@ -8,7 +8,6 @@
#include <signal.h>
#include "sysdep/ptrace.h"
#include "sysdep/sigcontext.h"
-#include "user_util.h"
#include "kern_util.h"
#include "task.h"
#include "tt.h"
diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
index ed1abcf..0e5c82c 100644
--- a/arch/um/kernel/tt/uaccess_user.c
+++ b/arch/um/kernel/tt/uaccess_user.c
@@ -5,7 +5,6 @@
*/
#include <string.h>
-#include "user_util.h"
#include "uml_uaccess.h"
#include "task.h"
#include "kern_util.h"
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 89c6dba..1cf954a 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -17,6 +17,7 @@
#include "linux/seq_file.h"
#include "linux/delay.h"
#include "linux/module.h"
+#include "linux/utsname.h"
#include "asm/page.h"
#include "asm/pgtable.h"
#include "asm/ptrace.h"
@@ -25,8 +26,9 @@
#include "asm/setup.h"
#include "ubd_user.h"
#include "asm/current.h"
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
+#include "arch.h"
#include "kern.h"
#include "mem_user.h"
#include "mem.h"
@@ -42,7 +44,7 @@
#define DEFAULT_COMMAND_LINE "root=98:0"
-/* Changed in linux_main and setup_arch, which run before SMP is started */
+/* Changed in add_arg and setup_arch, which run before SMP is started */
static char __initdata command_line[COMMAND_LINE_SIZE] = { 0 };
static void __init add_arg(char *arg)
@@ -56,17 +58,25 @@ static void __init add_arg(char *arg)
strcat(command_line, arg);
}
-struct cpuinfo_um boot_cpu_data = {
+/*
+ * These fields are initialized at boot time and not changed.
+ * XXX This structure is used only in the non-SMP case. Maybe this
+ * should be moved to smp.c.
+ */
+struct cpuinfo_um boot_cpu_data = {
.loops_per_jiffy = 0,
.ipi_pipe = { -1, -1 }
};
unsigned long thread_saved_pc(struct task_struct *task)
{
- return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
- task)));
+ return os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
+ task));
}
+/* Changed in setup_arch, which is called in early boot */
+static char host_info[(__NEW_UTS_LEN + 1) * 5];
+
static int show_cpuinfo(struct seq_file *m, void *v)
{
int index = 0;
@@ -86,7 +96,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
loops_per_jiffy/(500000/HZ),
(loops_per_jiffy/(5000/HZ)) % 100);
- return(0);
+ return 0;
}
static void *c_start(struct seq_file *m, loff_t *pos)
@@ -114,14 +124,12 @@ const struct seq_operations cpuinfo_op = {
/* Set in linux_main */
unsigned long host_task_size;
unsigned long task_size;
-
-unsigned long uml_start;
-
-/* Set in early boot */
unsigned long uml_physmem;
-unsigned long uml_reserved;
+unsigned long uml_reserved; /* Also modified in mem_init */
unsigned long start_vm;
unsigned long end_vm;
+
+/* Set in uml_ncpus_setup */
int ncpus = 1;
#ifdef CONFIG_CMDLINE_ON_HOST
@@ -135,6 +143,8 @@ static char *argv1_end = NULL;
/* Set in early boot */
static int have_root __initdata = 0;
+
+/* Set in uml_mem_setup and modified in linux_main */
long long physmem_size = 32 * 1024 * 1024;
void set_cmdline(char *cmd)
@@ -212,12 +222,12 @@ __uml_setup("debug", no_skas_debug_setup,
#ifdef CONFIG_SMP
static int __init uml_ncpus_setup(char *line, int *add)
{
- if (!sscanf(line, "%d", &ncpus)) {
- printf("Couldn't parse [%s]\n", line);
- return -1;
- }
+ if (!sscanf(line, "%d", &ncpus)) {
+ printf("Couldn't parse [%s]\n", line);
+ return -1;
+ }
- return 0;
+ return 0;
}
__uml_setup("ncpus=", uml_ncpus_setup,
@@ -234,7 +244,7 @@ static int force_tt = 0;
static int __init mode_tt_setup(char *line, int *add)
{
force_tt = 1;
- return(0);
+ return 0;
}
#else
@@ -245,7 +255,7 @@ static int __init mode_tt_setup(char *line, int *add)
static int __init mode_tt_setup(char *line, int *add)
{
printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
- return(0);
+ return 0;
}
#else
@@ -256,7 +266,7 @@ static int __init mode_tt_setup(char *line, int *add)
static int __init mode_tt_setup(char *line, int *add)
{
printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
- return(0);
+ return 0;
}
#endif
@@ -274,16 +284,15 @@ int mode_tt = DEFAULT_TT;
static int __init Usage(char *line, int *add)
{
- const char **p;
+ const char **p;
printf(usage_string, init_utsname()->release);
- p = &__uml_help_start;
- while (p < &__uml_help_end) {
- printf("%s", *p);
- p++;
- }
+ p = &__uml_help_start;
+ while (p < &__uml_help_end) {
+ printf("%s", *p);
+ p++;
+ }
exit(0);
-
return 0;
}
@@ -374,13 +383,12 @@ int __init linux_main(int argc, char **argv)
printf("UML running in %s mode\n", mode);
- uml_start = (unsigned long) &__binary_start;
host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt,
set_task_sizes_skas, &task_size);
/*
- * Setting up handlers to 'sig_info' struct
- */
+ * Setting up handlers to 'sig_info' struct
+ */
os_fill_handlinfo(handlinfo_kern);
brk_start = (unsigned long) sbrk(0);
@@ -396,7 +404,7 @@ int __init linux_main(int argc, char **argv)
physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
}
- uml_physmem = uml_start & PAGE_MASK;
+ uml_physmem = (unsigned long) &__binary_start & PAGE_MASK;
/* Reserve up to 4M after the current brk */
uml_reserved = ROUND_4M(brk_start) + (1 << 22);
@@ -407,7 +415,7 @@ int __init linux_main(int argc, char **argv)
argv1_begin = argv[1];
argv1_end = &argv[1][strlen(argv[1])];
#endif
-
+
highmem = 0;
iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
@@ -449,12 +457,12 @@ int __init linux_main(int argc, char **argv)
printf("Kernel virtual memory size shrunk to %lu bytes\n",
virtmem_size);
- uml_postsetup();
+ uml_postsetup();
task_protections((unsigned long) &init_thread_info);
os_flush_stdout();
- return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
+ return CHOOSE_MODE(start_uml_tt(), start_uml_skas());
}
extern int uml_exitcode;
@@ -466,8 +474,8 @@ static int panic_exit(struct notifier_block *self, unsigned long unused1,
show_regs(&(current->thread.regs));
bust_spinlocks(0);
uml_exitcode = 1;
- machine_halt();
- return(0);
+ os_dump_core();
+ return 0;
}
static struct notifier_block panic_exit_notifier = {
@@ -482,14 +490,14 @@ void __init setup_arch(char **cmdline_p)
&panic_exit_notifier);
paging_init();
strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
- *cmdline_p = command_line;
- setup_hostinfo();
+ *cmdline_p = command_line;
+ setup_hostinfo(host_info, sizeof host_info);
}
void __init check_bugs(void)
{
arch_check_bugs();
- os_check_bugs();
+ os_check_bugs();
}
void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index 6ff1274..9bf944f 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -132,10 +132,10 @@ static int aio_thread(void *arg)
{ .data = (void *) (long) event.data,
.err = event.res });
reply_fd = ((struct aio_context *) reply.data)->reply_fd;
- err = os_write_file(reply_fd, &reply, sizeof(reply));
+ err = write(reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply))
printk("aio_thread - write failed, fd = %d, "
- "err = %d\n", reply_fd, -err);
+ "err = %d\n", reply_fd, errno);
}
}
return 0;
@@ -146,38 +146,31 @@ static int aio_thread(void *arg)
static int do_not_aio(struct aio_thread_req *req)
{
char c;
- int err;
+ unsigned long long actual;
+ int n;
+
+ actual = lseek64(req->io_fd, req->offset, SEEK_SET);
+ if(actual != req->offset)
+ return -errno;
switch(req->type){
case AIO_READ:
- err = os_seek_file(req->io_fd, req->offset);
- if(err)
- goto out;
-
- err = os_read_file(req->io_fd, req->buf, req->len);
+ n = read(req->io_fd, req->buf, req->len);
break;
case AIO_WRITE:
- err = os_seek_file(req->io_fd, req->offset);
- if(err)
- goto out;
-
- err = os_write_file(req->io_fd, req->buf, req->len);
+ n = write(req->io_fd, req->buf, req->len);
break;
case AIO_MMAP:
- err = os_seek_file(req->io_fd, req->offset);
- if(err)
- goto out;
-
- err = os_read_file(req->io_fd, &c, sizeof(c));
+ n = read(req->io_fd, &c, sizeof(c));
break;
default:
printk("do_not_aio - bad request type : %d\n", req->type);
- err = -EINVAL;
- break;
+ return -EINVAL;
}
-out:
- return err;
+ if(n < 0)
+ return -errno;
+ return 0;
}
/* These are initialized in initcalls and not changed */
@@ -193,12 +186,12 @@ static int not_aio_thread(void *arg)
signal(SIGWINCH, SIG_IGN);
while(1){
- err = os_read_file(aio_req_fd_r, &req, sizeof(req));
+ err = read(aio_req_fd_r, &req, sizeof(req));
if(err != sizeof(req)){
if(err < 0)
printk("not_aio_thread - read failed, "
"fd = %d, err = %d\n", aio_req_fd_r,
- -err);
+ errno);
else {
printk("not_aio_thread - short read, fd = %d, "
"length = %d\n", aio_req_fd_r, err);
@@ -207,11 +200,11 @@ static int not_aio_thread(void *arg)
}
err = do_not_aio(&req);
reply = ((struct aio_thread_reply) { .data = req.aio,
- .err = err });
- err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply));
+ .err = err });
+ err = write(req.aio->reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply))
printk("not_aio_thread - write failed, fd = %d, "
- "err = %d\n", req.aio->reply_fd, -err);
+ "err = %d\n", req.aio->reply_fd, errno);
}
return 0;
@@ -228,6 +221,11 @@ static int init_aio_24(void)
aio_req_fd_w = fds[0];
aio_req_fd_r = fds[1];
+
+ err = os_set_fd_block(aio_req_fd_w, 0);
+ if(err)
+ goto out_close_pipe;
+
err = run_helper_thread(not_aio_thread, NULL,
CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
if(err < 0)
@@ -285,10 +283,12 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
if(err){
reply = ((struct aio_thread_reply) { .data = aio,
.err = err });
- err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
- if(err != sizeof(reply))
+ err = write(aio->reply_fd, &reply, sizeof(reply));
+ if(err != sizeof(reply)){
+ err = -errno;
printk("submit_aio_26 - write failed, "
"fd = %d, err = %d\n", aio->reply_fd, -err);
+ }
else err = 0;
}
@@ -383,9 +383,10 @@ static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
};
int err;
- err = os_write_file(aio_req_fd_w, &req, sizeof(req));
+ err = write(aio_req_fd_w, &req, sizeof(req));
if(err == sizeof(req))
err = 0;
+ else err = -errno;
return err;
}
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 863981b..acba301 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
* James Leu (jleu@mindspring.net).
* Copyright (C) 2001 by various other people who didn't put their name here.
* Licensed under the GPL.
@@ -16,19 +16,20 @@
#include <net/if.h>
#include "user.h"
#include "kern_util.h"
-#include "user_util.h"
#include "net_user.h"
#include "etap.h"
#include "os.h"
#include "um_malloc.h"
+#include "kern_constants.h"
#define MAX_PACKET ETH_MAX_PACKET
-void etap_user_init(void *data, void *dev)
+static int etap_user_init(void *data, void *dev)
{
struct ethertap_data *pri = data;
pri->dev = dev;
+ return 0;
}
struct addr_change {
@@ -47,13 +48,16 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
change.what = op;
memcpy(change.addr, addr, sizeof(change.addr));
memcpy(change.netmask, netmask, sizeof(change.netmask));
- n = os_write_file(fd, &change, sizeof(change));
- if(n != sizeof(change))
- printk("etap_change - request failed, err = %d\n", -n);
- output = um_kmalloc(page_size());
+ CATCH_EINTR(n = write(fd, &change, sizeof(change)));
+ if(n != sizeof(change)){
+ printk("etap_change - request failed, err = %d\n", errno);
+ return;
+ }
+
+ output = um_kmalloc(UM_KERN_PAGE_SIZE);
if(output == NULL)
printk("etap_change : Failed to allocate output buffer\n");
- read_output(fd, output, page_size());
+ read_output(fd, output, UM_KERN_PAGE_SIZE);
if(output != NULL){
printk("%s", output);
kfree(output);
@@ -115,13 +119,15 @@ static int etap_tramp(char *dev, char *gate, int control_me,
pe_data.data_me = data_me;
pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
- if(pid < 0) err = pid;
+ if(pid < 0)
+ err = pid;
os_close_file(data_remote);
os_close_file(control_remote);
- n = os_read_file(control_me, &c, sizeof(c));
+ CATCH_EINTR(n = read(control_me, &c, sizeof(c)));
if(n != sizeof(c)){
- printk("etap_tramp : read of status failed, err = %d\n", -n);
- return(-EINVAL);
+ err = -errno;
+ printk("etap_tramp : read of status failed, err = %d\n", -err);
+ return err;
}
if(c != 1){
printk("etap_tramp : uml_net failed\n");
@@ -132,7 +138,7 @@ static int etap_tramp(char *dev, char *gate, int control_me,
else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
printk("uml_net didn't exit with status 1\n");
}
- return(err);
+ return err;
}
static int etap_open(void *data)
@@ -142,23 +148,24 @@ static int etap_open(void *data)
int data_fds[2], control_fds[2], err, output_len;
err = tap_open_common(pri->dev, pri->gate_addr);
- if(err) return(err);
+ if(err)
+ return err;
err = os_pipe(data_fds, 0, 0);
if(err < 0){
printk("data os_pipe failed - err = %d\n", -err);
- return(err);
+ return err;
}
err = os_pipe(control_fds, 1, 0);
if(err < 0){
printk("control os_pipe failed - err = %d\n", -err);
- return(err);
+ return err;
}
-
+
err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
control_fds[1], data_fds[0], data_fds[1]);
- output_len = page_size();
+ output_len = UM_KERN_PAGE_SIZE;
output = um_kmalloc(output_len);
read_output(control_fds[0], output, output_len);
@@ -171,13 +178,13 @@ static int etap_open(void *data)
if(err < 0){
printk("etap_tramp failed - err = %d\n", -err);
- return(err);
+ return err;
}
pri->data_fd = data_fds[0];
pri->control_fd = control_fds[0];
iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
- return(data_fds[0]);
+ return data_fds[0];
}
static void etap_close(int fd, void *data)
@@ -195,7 +202,7 @@ static void etap_close(int fd, void *data)
static int etap_set_mtu(int mtu, void *data)
{
- return(mtu);
+ return mtu;
}
static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
@@ -204,7 +211,8 @@ static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
struct ethertap_data *pri = data;
tap_check_ips(pri->gate_addr, addr);
- if(pri->control_fd == -1) return;
+ if(pri->control_fd == -1)
+ return;
etap_open_addr(addr, netmask, &pri->control_fd);
}
@@ -213,7 +221,8 @@ static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
{
struct ethertap_data *pri = data;
- if(pri->control_fd == -1) return;
+ if(pri->control_fd == -1)
+ return;
etap_close_addr(addr, netmask, &pri->control_fd);
}
@@ -227,14 +236,3 @@ const struct net_user_info ethertap_user_info = {
.delete_address = etap_del_addr,
.max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index e846b23..11a9779 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -18,17 +18,17 @@
#include "net_user.h"
#include "tuntap.h"
#include "kern_util.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
#define MAX_PACKET ETH_MAX_PACKET
-void tuntap_user_init(void *data, void *dev)
+static int tuntap_user_init(void *data, void *dev)
{
struct tuntap_data *pri = data;
pri->dev = dev;
+ return 0;
}
static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
@@ -37,7 +37,8 @@ static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
struct tuntap_data *pri = data;
tap_check_ips(pri->gate_addr, addr);
- if((pri->fd == -1) || pri->fixed_config) return;
+ if((pri->fd == -1) || pri->fixed_config)
+ return;
open_addr(addr, netmask, pri->dev_name);
}
@@ -46,7 +47,8 @@ static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
{
struct tuntap_data *pri = data;
- if((pri->fd == -1) || pri->fixed_config) return;
+ if((pri->fd == -1) || pri->fixed_config)
+ return;
close_addr(addr, netmask, pri->dev_name);
}
@@ -58,7 +60,7 @@ struct tuntap_pre_exec_data {
static void tuntap_pre_exec(void *arg)
{
struct tuntap_pre_exec_data *data = arg;
-
+
dup2(data->stdout, 1);
os_close_file(data->close_me);
}
@@ -83,7 +85,8 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
pid = run_helper(tuntap_pre_exec, &data, argv, NULL);
- if(pid < 0) return(-pid);
+ if(pid < 0)
+ return -pid;
os_close_file(remote);
@@ -114,16 +117,16 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
cmsg = CMSG_FIRSTHDR(&msg);
if(cmsg == NULL){
printk("tuntap_open_tramp : didn't receive a message\n");
- return(-EINVAL);
+ return -EINVAL;
}
if((cmsg->cmsg_level != SOL_SOCKET) ||
(cmsg->cmsg_type != SCM_RIGHTS)){
printk("tuntap_open_tramp : didn't receive a descriptor\n");
- return(-EINVAL);
+ return -EINVAL;
}
*fd_out = ((int *) CMSG_DATA(cmsg))[0];
os_set_exec_close(*fd_out, 1);
- return(0);
+ return 0;
}
static int tuntap_open(void *data)
@@ -135,7 +138,7 @@ static int tuntap_open(void *data)
err = tap_open_common(pri->dev, pri->gate_addr);
if(err < 0)
- return(err);
+ return err;
if(pri->fixed_config){
pri->fd = os_open_file("/dev/net/tun",
@@ -143,7 +146,7 @@ static int tuntap_open(void *data)
if(pri->fd < 0){
printk("Failed to open /dev/net/tun, err = %d\n",
-pri->fd);
- return(pri->fd);
+ return pri->fd;
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
@@ -160,7 +163,7 @@ static int tuntap_open(void *data)
if(err < 0){
printk("tuntap_open : os_pipe failed - err = %d\n",
-err);
- return(err);
+ return err;
}
buffer = get_output_buffer(&len);
@@ -175,7 +178,7 @@ static int tuntap_open(void *data)
printk("%s", output);
free_output_buffer(buffer);
printk("tuntap_open_tramp failed - err = %d\n", -err);
- return(err);
+ return err;
}
pri->dev_name = uml_strdup(buffer);
@@ -187,7 +190,7 @@ static int tuntap_open(void *data)
iter_addresses(pri->dev, open_addr, pri->dev_name);
}
- return(pri->fd);
+ return pri->fd;
}
static void tuntap_close(int fd, void *data)
@@ -202,7 +205,7 @@ static void tuntap_close(int fd, void *data)
static int tuntap_set_mtu(int mtu, void *data)
{
- return(mtu);
+ return mtu;
}
const struct net_user_info tuntap_user_info = {
@@ -215,14 +218,3 @@ const struct net_user_info tuntap_user_info = {
.delete_address = tuntap_del_addr,
.max_packet = MAX_PACKET
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 371b433..6f92f73 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -18,7 +18,6 @@
#include "os.h"
#include "user.h"
#include "kern_util.h"
-#include "user_util.h"
static void copy_stat(struct uml_stat *dst, struct stat64 *src)
{
@@ -291,54 +290,22 @@ int os_seek_file(int fd, __u64 offset)
return 0;
}
-static int fault_buffer(void *start, int len,
- int (*copy_proc)(void *addr, void *buf, int len))
-{
- int page = getpagesize(), i;
- char c;
-
- for(i = 0; i < len; i += page){
- if((*copy_proc)(start + i, &c, sizeof(c)))
- return -EFAULT;
- }
- if((len % page) != 0){
- if((*copy_proc)(start + len - 1, &c, sizeof(c)))
- return -EFAULT;
- }
- return 0;
-}
-
-static int file_io(int fd, void *buf, int len,
- int (*io_proc)(int fd, void *buf, int len),
- int (*copy_user_proc)(void *addr, void *buf, int len))
+int os_read_file(int fd, void *buf, int len)
{
- int n, err;
-
- do {
- n = (*io_proc)(fd, buf, len);
- if((n < 0) && (errno == EFAULT)){
- err = fault_buffer(buf, len, copy_user_proc);
- if(err)
- return err;
- n = (*io_proc)(fd, buf, len);
- }
- } while((n < 0) && (errno == EINTR));
+ int n = read(fd, buf, len);
if(n < 0)
return -errno;
return n;
}
-int os_read_file(int fd, void *buf, int len)
-{
- return file_io(fd, buf, len, (int (*)(int, void *, int)) read,
- copy_from_user_proc);
-}
-
int os_write_file(int fd, const void *buf, int len)
{
- return file_io(fd, (void *) buf, len,
- (int (*)(int, void *, int)) write, copy_to_user_proc);
+ int n = write(fd, (void *) buf, len);
+
+ if(n < 0)
+ return -errno;
+ return n;
}
int os_file_size(char *file, unsigned long long *size_out)
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index c7ad630..97bed16 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -13,9 +13,9 @@
#include <sys/wait.h>
#include "user.h"
#include "kern_util.h"
-#include "user_util.h"
#include "os.h"
#include "um_malloc.h"
+#include "kern_constants.h"
struct helper_data {
void (*pre_exec)(void*);
@@ -25,28 +25,18 @@ struct helper_data {
char *buf;
};
-/* Debugging aid, changed only from gdb */
-int helper_pause = 0;
-
-static void helper_hup(int sig)
-{
-}
-
static int helper_child(void *arg)
{
struct helper_data *data = arg;
char **argv = data->argv;
int errval;
- if (helper_pause){
- signal(SIGHUP, helper_hup);
- pause();
- }
if (data->pre_exec != NULL)
(*data->pre_exec)(data->pre_data);
errval = execvp_noalloc(data->buf, argv[0], argv);
- printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval);
- os_write_file(data->fd, &errval, sizeof(errval));
+ printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0],
+ -errval);
+ write(data->fd, &errval, sizeof(errval));
kill(os_getpid(), SIGKILL);
return 0;
}
@@ -81,7 +71,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
goto out_close;
}
- sp = stack + page_size() - sizeof(void *);
+ sp = stack + UM_KERN_PAGE_SIZE - sizeof(void *);
data.pre_exec = pre_exec;
data.pre_data = pre_data;
data.argv = argv;
@@ -98,13 +88,16 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
close(fds[1]);
fds[1] = -1;
- /* Read the errno value from the child, if the exec failed, or get 0 if
- * the exec succeeded because the pipe fd was set as close-on-exec. */
- n = os_read_file(fds[0], &ret, sizeof(ret));
+ /*
+ * Read the errno value from the child, if the exec failed, or get 0 if
+ * the exec succeeded because the pipe fd was set as close-on-exec.
+ */
+ n = read(fds[0], &ret, sizeof(ret));
if (n == 0) {
ret = pid;
} else {
if (n < 0) {
+ n = -errno;
printk("run_helper : read on pipe failed, ret = %d\n",
-n);
ret = n;
@@ -135,7 +128,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
if (stack == 0)
return -ENOMEM;
- sp = stack + (page_size() << stack_order) - sizeof(void *);
+ sp = stack + (UM_KERN_PAGE_SIZE << stack_order) - sizeof(void *);
pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
if (pid < 0) {
err = -errno;
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index d1b61d4..a633fa8 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -11,7 +11,6 @@
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/time.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "process.h"
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 685feaa..ea9a236 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -13,8 +13,8 @@
#include <sys/mman.h>
#include <sys/user.h>
#include <asm/page.h>
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
#include "mem_user.h"
#include "irq_user.h"
#include "user.h"
@@ -25,12 +25,7 @@
#include "os.h"
#include "um_malloc.h"
-/* Set in set_stklim, which is called from main and __wrap_malloc.
- * __wrap_malloc only calls it if main hasn't started.
- */
-unsigned long stacksizelim;
-
-/* Set in main */
+/* Set in main, unchanged thereafter */
char *linux_prog;
#define PGD_BOUND (4 * 1024 * 1024)
@@ -52,7 +47,6 @@ static void set_stklim(void)
exit(1);
}
}
- stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1);
}
static __init void do_uml_initcalls(void)
@@ -126,7 +120,7 @@ extern int uml_exitcode;
extern void scan_elf_aux( char **envp);
-int main(int argc, char **argv, char **envp)
+int __init main(int argc, char **argv, char **envp)
{
char **new_argv;
int ret, i, err;
@@ -224,7 +218,7 @@ int main(int argc, char **argv, char **envp)
ret = 1;
}
printf("\n");
- return(uml_exitcode);
+ return uml_exitcode;
}
#define CAN_KMALLOC() \
@@ -237,7 +231,7 @@ void *__wrap_malloc(int size)
void *ret;
if(!CAN_KMALLOC())
- return(__real_malloc(size));
+ return __real_malloc(size);
else if(size <= PAGE_SIZE) /* finding contiguos pages can be hard*/
ret = um_kmalloc(size);
else ret = um_vmalloc(size);
@@ -248,16 +242,17 @@ void *__wrap_malloc(int size)
if(ret == NULL)
errno = ENOMEM;
- return(ret);
+ return ret;
}
void *__wrap_calloc(int n, int size)
{
void *ptr = __wrap_malloc(n * size);
- if(ptr == NULL) return(NULL);
+ if(ptr == NULL)
+ return NULL;
memset(ptr, 0, n * size);
- return(ptr);
+ return ptr;
}
extern void __real_free(void *);
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index f1ea169..c6378c6 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -11,7 +11,6 @@
#include <sys/statfs.h>
#include "kern_util.h"
#include "user.h"
-#include "user_util.h"
#include "mem_user.h"
#include "init.h"
#include "os.h"
@@ -165,7 +164,8 @@ found:
* (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger).
* So it isn't 'static' yet.
*/
-int make_tempfile(const char *template, char **out_tempname, int do_unlink)
+int __init make_tempfile(const char *template, char **out_tempname,
+ int do_unlink)
{
char *tempname;
int fd;
@@ -206,7 +206,7 @@ out:
* This proc is used in start_up.c
* So it isn't 'static'.
*/
-int create_tmp_file(unsigned long long len)
+int __init create_tmp_file(unsigned long long len)
{
int fd, err;
char zero;
@@ -232,17 +232,16 @@ int create_tmp_file(unsigned long long len)
zero = 0;
- err = os_write_file(fd, &zero, 1);
+ err = write(fd, &zero, 1);
if(err != 1){
- errno = -err;
- perror("os_write_file");
+ perror("write");
exit(1);
}
return fd;
}
-int create_mem_file(unsigned long long len)
+int __init create_mem_file(unsigned long long len)
{
int err, fd;
@@ -257,7 +256,7 @@ int create_mem_file(unsigned long long len)
}
-void check_tmpexec(void)
+void __init check_tmpexec(void)
{
void *addr;
int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 76bdd67..92a7b59 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -14,7 +14,6 @@
#include "ptrace_user.h"
#include "os.h"
#include "user.h"
-#include "user_util.h"
#include "process.h"
#include "irq_user.h"
#include "kern_util.h"
@@ -22,6 +21,7 @@
#include "skas_ptrace.h"
#include "kern_constants.h"
#include "uml-config.h"
+#include "init.h"
#define ARBITRARY_ADDR -1
#define FAILURE_PID -1
@@ -40,14 +40,14 @@ unsigned long os_process_pc(int pid)
if(fd < 0){
printk("os_process_pc - couldn't open '%s', err = %d\n",
proc_stat, -fd);
- return(ARBITRARY_ADDR);
+ return ARBITRARY_ADDR;
}
- err = os_read_file(fd, buf, sizeof(buf));
+ CATCH_EINTR(err = read(fd, buf, sizeof(buf)));
if(err < 0){
printk("os_process_pc - couldn't read '%s', err = %d\n",
- proc_stat, -err);
+ proc_stat, errno);
os_close_file(fd);
- return(ARBITRARY_ADDR);
+ return ARBITRARY_ADDR;
}
os_close_file(fd);
pc = ARBITRARY_ADDR;
@@ -56,7 +56,7 @@ unsigned long os_process_pc(int pid)
"%*d %*d %*d %*d %*d %lu", &pc) != 1){
printk("os_process_pc - couldn't find pc in '%s'\n", buf);
}
- return(pc);
+ return pc;
}
int os_process_parent(int pid)
@@ -65,21 +65,22 @@ int os_process_parent(int pid)
char data[256];
int parent, n, fd;
- if(pid == -1) return(-1);
+ if(pid == -1)
+ return -1;
snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
if(fd < 0){
printk("Couldn't open '%s', err = %d\n", stat, -fd);
- return(FAILURE_PID);
+ return FAILURE_PID;
}
- n = os_read_file(fd, data, sizeof(data));
+ CATCH_EINTR(n = read(fd, data, sizeof(data)));
os_close_file(fd);
if(n < 0){
- printk("Couldn't read '%s', err = %d\n", stat, -n);
- return(FAILURE_PID);
+ printk("Couldn't read '%s', err = %d\n", stat, errno);
+ return FAILURE_PID;
}
parent = FAILURE_PID;
@@ -87,7 +88,7 @@ int os_process_parent(int pid)
if(n != 1)
printk("Failed to scan '%s'\n", data);
- return(parent);
+ return parent;
}
void os_stop_process(int pid)
@@ -145,7 +146,7 @@ void os_usr1_process(int pid)
int os_getpid(void)
{
- return(syscall(__NR_getpid));
+ return syscall(__NR_getpid);
}
int os_getpgrp(void)
@@ -165,8 +166,8 @@ int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
fd, off);
if(loc == MAP_FAILED)
- return(-errno);
- return(0);
+ return -errno;
+ return 0;
}
int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
@@ -175,8 +176,8 @@ int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
(x ? PROT_EXEC : 0));
if(mprotect(addr, len, prot) < 0)
- return(-errno);
- return(0);
+ return -errno;
+ return 0;
}
int os_unmap_memory(void *addr, int len)
@@ -185,15 +186,15 @@ int os_unmap_memory(void *addr, int len)
err = munmap(addr, len);
if(err < 0)
- return(-errno);
- return(0);
+ return -errno;
+ return 0;
}
#ifndef MADV_REMOVE
#define MADV_REMOVE KERNEL_MADV_REMOVE
#endif
-int os_drop_memory(void *addr, int length)
+int __init os_drop_memory(void *addr, int length)
{
int err;
@@ -203,7 +204,7 @@ int os_drop_memory(void *addr, int length)
return err;
}
-int can_drop_memory(void)
+int __init can_drop_memory(void)
{
void *addr;
int fd, ok = 0;
@@ -244,7 +245,7 @@ void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
if(sig_stack != NULL){
pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER);
- set_sigstack(sig_stack, pages * page_size());
+ set_sigstack(sig_stack, pages * UM_KERN_PAGE_SIZE);
flags = SA_ONSTACK;
}
if(usr1_handler){
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index 3fc43b3..8d4e0c6 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -8,6 +8,7 @@
#include <termios.h>
#include <pty.h>
#include <signal.h>
+#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sched.h>
@@ -16,10 +17,10 @@
#include "init.h"
#include "user.h"
#include "kern_util.h"
-#include "user_util.h"
#include "sigio.h"
#include "os.h"
#include "um_malloc.h"
+#include "init.h"
/* Protected by sigio_lock(), also used by sigio_cleanup, which is an
* exitcall.
@@ -68,11 +69,12 @@ static int write_sigio_thread(void *unused)
p = &fds->poll[i];
if(p->revents == 0) continue;
if(p->fd == sigio_private[1]){
- n = os_read_file(sigio_private[1], &c, sizeof(c));
+ CATCH_EINTR(n = read(sigio_private[1], &c,
+ sizeof(c)));
if(n != sizeof(c))
printk("write_sigio_thread : "
"read on socket failed, "
- "err = %d\n", -n);
+ "err = %d\n", errno);
tmp = current_poll;
current_poll = next_poll;
next_poll = tmp;
@@ -85,10 +87,10 @@ static int write_sigio_thread(void *unused)
(fds->used - i) * sizeof(*fds->poll));
}
- n = os_write_file(respond_fd, &c, sizeof(c));
+ CATCH_EINTR(n = write(respond_fd, &c, sizeof(c)));
if(n != sizeof(c))
printk("write_sigio_thread : write on socket "
- "failed, err = %d\n", -n);
+ "failed, err = %d\n", errno);
}
}
@@ -126,15 +128,15 @@ static void update_thread(void)
char c;
flags = set_signals(0);
- n = os_write_file(sigio_private[0], &c, sizeof(c));
+ n = write(sigio_private[0], &c, sizeof(c));
if(n != sizeof(c)){
- printk("update_thread : write failed, err = %d\n", -n);
+ printk("update_thread : write failed, err = %d\n", errno);
goto fail;
}
- n = os_read_file(sigio_private[0], &c, sizeof(c));
+ CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c)));
if(n != sizeof(c)){
- printk("update_thread : read failed, err = %d\n", -n);
+ printk("update_thread : read failed, err = %d\n", errno);
goto fail;
}
@@ -320,6 +322,10 @@ out_close1:
close(l_write_sigio_fds[1]);
}
+/* Changed during early boot */
+static int pty_output_sigio = 0;
+static int pty_close_sigio = 0;
+
void maybe_sigio_broken(int fd, int read)
{
int err;
@@ -357,3 +363,143 @@ static void sigio_cleanup(void)
}
__uml_exitcall(sigio_cleanup);
+
+/* Used as a flag during SIGIO testing early in boot */
+static volatile int got_sigio = 0;
+
+static void __init handler(int sig)
+{
+ got_sigio = 1;
+}
+
+struct openpty_arg {
+ int master;
+ int slave;
+ int err;
+};
+
+static void openpty_cb(void *arg)
+{
+ struct openpty_arg *info = arg;
+
+ info->err = 0;
+ if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
+ info->err = -errno;
+}
+
+static int async_pty(int master, int slave)
+{
+ int flags;
+
+ flags = fcntl(master, F_GETFL);
+ if(flags < 0)
+ return -errno;
+
+ if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
+ (fcntl(master, F_SETOWN, os_getpid()) < 0))
+ return -errno;
+
+ if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
+ return -errno;
+
+ return(0);
+}
+
+static void __init check_one_sigio(void (*proc)(int, int))
+{
+ struct sigaction old, new;
+ struct openpty_arg pty = { .master = -1, .slave = -1 };
+ int master, slave, err;
+
+ initial_thread_cb(openpty_cb, &pty);
+ if(pty.err){
+ printk("openpty failed, errno = %d\n", -pty.err);
+ return;
+ }
+
+ master = pty.master;
+ slave = pty.slave;
+
+ if((master == -1) || (slave == -1)){
+ printk("openpty failed to allocate a pty\n");
+ return;
+ }
+
+ /* Not now, but complain so we now where we failed. */
+ err = raw(master);
+ if (err < 0)
+ panic("check_sigio : __raw failed, errno = %d\n", -err);
+
+ err = async_pty(master, slave);
+ if(err < 0)
+ panic("tty_fds : sigio_async failed, err = %d\n", -err);
+
+ if(sigaction(SIGIO, NULL, &old) < 0)
+ panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
+ new = old;
+ new.sa_handler = handler;
+ if(sigaction(SIGIO, &new, NULL) < 0)
+ panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
+
+ got_sigio = 0;
+ (*proc)(master, slave);
+
+ close(master);
+ close(slave);
+
+ if(sigaction(SIGIO, &old, NULL) < 0)
+ panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
+}
+
+static void tty_output(int master, int slave)
+{
+ int n;
+ char buf[512];
+
+ printk("Checking that host ptys support output SIGIO...");
+
+ memset(buf, 0, sizeof(buf));
+
+ while(write(master, buf, sizeof(buf)) > 0) ;
+ if(errno != EAGAIN)
+ panic("tty_output : write failed, errno = %d\n", errno);
+ while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
+
+ if(got_sigio){
+ printk("Yes\n");
+ pty_output_sigio = 1;
+ }
+ else if(n == -EAGAIN)
+ printk("No, enabling workaround\n");
+ else panic("tty_output : read failed, err = %d\n", n);
+}
+
+static void tty_close(int master, int slave)
+{
+ printk("Checking that host ptys support SIGIO on close...");
+
+ close(slave);
+ if(got_sigio){
+ printk("Yes\n");
+ pty_close_sigio = 1;
+ }
+ else printk("No, enabling workaround\n");
+}
+
+void __init check_sigio(void)
+{
+ if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
+ (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
+ printk("No pseudo-terminals available - skipping pty SIGIO "
+ "check\n");
+ return;
+ }
+ check_one_sigio(tty_output);
+ check_one_sigio(tty_close);
+}
+
+/* Here because it only does the SIGIO testing for now */
+void __init os_check_bugs(void)
+{
+ check_sigio();
+}
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 2667686..48d4934 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -11,7 +11,6 @@
#include <stdarg.h>
#include <string.h>
#include <sys/mman.h>
-#include "user_util.h"
#include "user.h"
#include "signal_kern.h"
#include "sysdep/sigcontext.h"
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index 9383e87..8e490ff 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -6,6 +6,7 @@
#include <signal.h>
#include <errno.h>
#include <string.h>
+#include <unistd.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <asm/page.h>
@@ -17,17 +18,17 @@
#include "os.h"
#include "proc_mm.h"
#include "ptrace_user.h"
-#include "user_util.h"
#include "kern_util.h"
#include "task.h"
#include "registers.h"
#include "uml-config.h"
#include "sysdep/ptrace.h"
#include "sysdep/stub.h"
+#include "init.h"
extern unsigned long batch_syscall_stub, __syscall_stub_start;
-extern void wait_stub_done(int pid, int sig, char * fname);
+extern void wait_stub_done(int pid);
static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
unsigned long *stack)
@@ -39,6 +40,19 @@ static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
return stack;
}
+static unsigned long syscall_regs[MAX_REG_NR];
+
+static int __init init_syscall_regs(void)
+{
+ get_safe_registers(syscall_regs, NULL);
+ syscall_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
+ ((unsigned long) &batch_syscall_stub -
+ (unsigned long) &__syscall_stub_start);
+ return 0;
+}
+
+__initcall(init_syscall_regs);
+
extern int proc_mm;
int single_count = 0;
@@ -47,12 +61,11 @@ int multi_op_count = 0;
static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
{
- unsigned long regs[MAX_REG_NR];
int n, i;
long ret, offset;
unsigned long * data;
unsigned long * syscall;
- int pid = mm_idp->u.pid;
+ int err, pid = mm_idp->u.pid;
if(proc_mm)
#warning Need to look up userspace_pid by cpu
@@ -60,21 +73,21 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
multi_count++;
- get_safe_registers(regs, NULL);
- regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
- ((unsigned long) &batch_syscall_stub -
- (unsigned long) &__syscall_stub_start);
-
- n = ptrace_setregs(pid, regs);
+ n = ptrace_setregs(pid, syscall_regs);
if(n < 0){
printk("Registers - \n");
for(i = 0; i < MAX_REG_NR; i++)
- printk("\t%d\t0x%lx\n", i, regs[i]);
+ printk("\t%d\t0x%lx\n", i, syscall_regs[i]);
panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
-n);
}
- wait_stub_done(pid, 0, "do_syscall_stub");
+ err = ptrace(PTRACE_CONT, pid, 0, 0);
+ if(err)
+ panic("Failed to continue stub, pid = %d, errno = %d\n", pid,
+ errno);
+
+ wait_stub_done(pid);
/* When the stub stops, we find the following values on the
* beginning of the stack:
@@ -176,14 +189,10 @@ long syscall_stub_data(struct mm_id * mm_idp,
return 0;
}
-int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
- int r, int w, int x, int phys_fd, unsigned long long offset,
- int done, void **data)
+int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
+ int phys_fd, unsigned long long offset, int done, void **data)
{
- int prot, ret;
-
- prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
- (x ? PROT_EXEC : 0);
+ int ret;
if(proc_mm){
struct proc_mm_op map;
@@ -200,9 +209,11 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
.fd = phys_fd,
.offset= offset
} } } );
- ret = os_write_file(fd, &map, sizeof(map));
- if(ret != sizeof(map))
+ CATCH_EINTR(ret = write(fd, &map, sizeof(map)));
+ if(ret != sizeof(map)){
+ ret = -errno;
printk("map : /proc/mm map failed, err = %d\n", -ret);
+ }
else ret = 0;
}
else {
@@ -217,8 +228,8 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
return ret;
}
-int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
- void **data)
+int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
+ int done, void **data)
{
int ret;
@@ -232,9 +243,11 @@ int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
{ .addr =
(unsigned long) addr,
.len = len } } } );
- ret = os_write_file(fd, &unmap, sizeof(unmap));
- if(ret != sizeof(unmap))
+ CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap)));
+ if(ret != sizeof(unmap)){
+ ret = -errno;
printk("unmap - proc_mm write returned %d\n", ret);
+ }
else ret = 0;
}
else {
@@ -249,13 +262,11 @@ int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
}
int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
- int r, int w, int x, int done, void **data)
+ unsigned int prot, int done, void **data)
{
struct proc_mm_op protect;
- int prot, ret;
+ int ret;
- prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
- (x ? PROT_EXEC : 0);
if(proc_mm){
int fd = mm_idp->u.mm_fd;
@@ -267,9 +278,11 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
.len = len,
.prot = prot } } } );
- ret = os_write_file(fd, &protect, sizeof(protect));
- if(ret != sizeof(protect))
+ CATCH_EINTR(ret = write(fd, &protect, sizeof(protect)));
+ if(ret != sizeof(protect)){
+ ret = -errno;
printk("protect failed, err = %d", -ret);
+ }
else ret = 0;
}
else {
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 0564422..5c088a5 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -18,7 +18,6 @@
#include <asm/types.h>
#include "user.h"
#include "sysdep/ptrace.h"
-#include "user_util.h"
#include "kern_util.h"
#include "skas.h"
#include "stub-data.h"
@@ -34,6 +33,8 @@
#include "uml-config.h"
#include "process.h"
#include "longjmp.h"
+#include "kern_constants.h"
+#include "as-layout.h"
int is_skas_winch(int pid, int fd, void *data)
{
@@ -44,45 +45,58 @@ int is_skas_winch(int pid, int fd, void *data)
return(1);
}
-void wait_stub_done(int pid, int sig, char * fname)
+static int ptrace_dump_regs(int pid)
{
- int n, status, err;
+ unsigned long regs[MAX_REG_NR];
+ int i;
+
+ if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
+ return -errno;
+ else {
+ printk("Stub registers -\n");
+ for(i = 0; i < ARRAY_SIZE(regs); i++)
+ printk("\t%d - %lx\n", i, regs[i]);
+ }
+
+ return 0;
+}
- do {
- if ( sig != -1 ) {
- err = ptrace(PTRACE_CONT, pid, 0, sig);
- if(err)
- panic("%s : continue failed, errno = %d\n",
- fname, errno);
- }
- sig = 0;
+/*
+ * Signals that are OK to receive in the stub - we'll just continue it.
+ * SIGWINCH will happen when UML is inside a detached screen.
+ */
+#define STUB_SIG_MASK ((1 << SIGVTALRM) | (1 << SIGWINCH))
+
+/* Signals that the stub will finish with - anything else is an error */
+#define STUB_DONE_MASK ((1 << SIGUSR1) | (1 << SIGTRAP))
+
+void wait_stub_done(int pid)
+{
+ int n, status, err;
+ while(1){
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
- } while((n >= 0) && WIFSTOPPED(status) &&
- ((WSTOPSIG(status) == SIGVTALRM) ||
- /* running UML inside a detached screen can cause
- * SIGWINCHes
- */
- (WSTOPSIG(status) == SIGWINCH)));
-
- if((n < 0) || !WIFSTOPPED(status) ||
- (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
- unsigned long regs[MAX_REG_NR];
-
- if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
- printk("Failed to get registers from stub, "
- "errno = %d\n", errno);
- else {
- int i;
-
- printk("Stub registers -\n");
- for(i = 0; i < ARRAY_SIZE(regs); i++)
- printk("\t%d - %lx\n", i, regs[i]);
- }
- panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
- "pid = %d, n = %d, errno = %d, status = 0x%x\n",
- fname, pid, n, errno, status);
+ if((n < 0) || !WIFSTOPPED(status))
+ goto bad_wait;
+
+ if(((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0)
+ break;
+
+ err = ptrace(PTRACE_CONT, pid, 0, 0);
+ if(err)
+ panic("wait_stub_done : continue failed, errno = %d\n",
+ errno);
}
+
+ if(((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0)
+ return;
+
+bad_wait:
+ err = ptrace_dump_regs(pid);
+ if(err)
+ printk("Failed to get registers from stub, errno = %d\n", -err);
+ panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, "
+ "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status);
}
extern unsigned long current_stub_stack(void);
@@ -104,7 +118,11 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
sizeof(struct ptrace_faultinfo));
}
else {
- wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo");
+ err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
+ if(err)
+ panic("Failed to continue stub, pid = %d, errno = %d\n",
+ pid, errno);
+ wait_stub_done(pid);
/* faultinfo is prepared by the stub-segv-handler at start of
* the stub stack page. We just have to copy it.
@@ -142,9 +160,14 @@ static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu
CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
if((err < 0) || !WIFSTOPPED(status) ||
- (WSTOPSIG(status) != SIGTRAP + 0x80))
+ (WSTOPSIG(status) != SIGTRAP + 0x80)){
+ err = ptrace_dump_regs(pid);
+ if(err)
+ printk("Failed to get registers from process, "
+ "errno = %d\n", -err);
panic("handle_trap - failed to wait at end of syscall, "
"errno = %d, status = %d\n", errno, status);
+ }
}
handle_syscall(regs);
@@ -172,7 +195,7 @@ static int userspace_tramp(void *stack)
int fd;
__u64 offset;
fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
- addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(),
+ addr = mmap64((void *) UML_CONFIG_STUB_CODE, UM_KERN_PAGE_SIZE,
PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
if(addr == MAP_FAILED){
printk("mapping mmap stub failed, errno = %d\n",
@@ -182,8 +205,8 @@ static int userspace_tramp(void *stack)
if(stack != NULL){
fd = phys_mapping(to_phys(stack), &offset);
- addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(),
- PROT_READ | PROT_WRITE,
+ addr = mmap((void *) UML_CONFIG_STUB_DATA,
+ UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_SHARED, fd, offset);
if(addr == MAP_FAILED){
printk("mapping segfault stack failed, "
@@ -199,7 +222,7 @@ static int userspace_tramp(void *stack)
(unsigned long) stub_segv_handler -
(unsigned long) &__syscall_stub_start;
- set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size());
+ set_sigstack((void *) UML_CONFIG_STUB_DATA, UM_KERN_PAGE_SIZE);
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGIO);
sigaddset(&sa.sa_mask, SIGWINCH);
@@ -291,10 +314,13 @@ void userspace(union uml_pt_regs *regs)
UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
if(WIFSTOPPED(status)){
- switch(WSTOPSIG(status)){
+ int sig = WSTOPSIG(status);
+ switch(sig){
case SIGSEGV:
- if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo)
- user_signal(SIGSEGV, regs, pid);
+ if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo){
+ get_skas_faultinfo(pid, &regs->skas.faultinfo);
+ (*sig_info[SIGSEGV])(SIGSEGV, regs);
+ }
else handle_segv(pid, regs);
break;
case SIGTRAP + 0x80:
@@ -309,11 +335,13 @@ void userspace(union uml_pt_regs *regs)
case SIGBUS:
case SIGFPE:
case SIGWINCH:
- user_signal(WSTOPSIG(status), regs, pid);
+ block_signals();
+ (*sig_info[sig])(sig, regs);
+ unblock_signals();
break;
default:
printk("userspace - child stopped with signal "
- "%d\n", WSTOPSIG(status));
+ "%d\n", sig);
}
pid = userspace_pid[0];
interrupt_end();
@@ -325,11 +353,29 @@ void userspace(union uml_pt_regs *regs)
}
}
+static unsigned long thread_regs[MAX_REG_NR];
+static unsigned long thread_fp_regs[HOST_FP_SIZE];
+
+static int __init init_thread_regs(void)
+{
+ get_safe_registers(thread_regs, thread_fp_regs);
+ /* Set parent's instruction pointer to start of clone-stub */
+ thread_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
+ (unsigned long) stub_clone_handler -
+ (unsigned long) &__syscall_stub_start;
+ thread_regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
+ sizeof(void *);
+#ifdef __SIGNAL_FRAMESIZE
+ thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
+#endif
+ return 0;
+}
+
+__initcall(init_thread_regs);
+
int copy_context_skas0(unsigned long new_stack, int pid)
{
int err;
- unsigned long regs[MAX_REG_NR];
- unsigned long fp_regs[HOST_FP_SIZE];
unsigned long current_stack = current_stub_stack();
struct stub_data *data = (struct stub_data *) current_stack;
struct stub_data *child_data = (struct stub_data *) new_stack;
@@ -344,23 +390,12 @@ int copy_context_skas0(unsigned long new_stack, int pid)
.timer = ((struct itimerval)
{ { 0, 1000000 / hz() },
{ 0, 1000000 / hz() }})});
- get_safe_registers(regs, fp_regs);
-
- /* Set parent's instruction pointer to start of clone-stub */
- regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
- (unsigned long) stub_clone_handler -
- (unsigned long) &__syscall_stub_start;
- regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
- sizeof(void *);
-#ifdef __SIGNAL_FRAMESIZE
- regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
-#endif
- err = ptrace_setregs(pid, regs);
+ err = ptrace_setregs(pid, thread_regs);
if(err < 0)
panic("copy_context_skas0 : PTRACE_SETREGS failed, "
"pid = %d, errno = %d\n", pid, -err);
- err = ptrace_setfpregs(pid, fp_regs);
+ err = ptrace_setfpregs(pid, thread_fp_regs);
if(err < 0)
panic("copy_context_skas0 : PTRACE_SETFPREGS failed, "
"pid = %d, errno = %d\n", pid, -err);
@@ -371,7 +406,11 @@ int copy_context_skas0(unsigned long new_stack, int pid)
/* Wait, until parent has finished its work: read child's pid from
* parent's stack, and check, if bad result.
*/
- wait_stub_done(pid, 0, "copy_context_skas0");
+ err = ptrace(PTRACE_CONT, pid, 0, 0);
+ if(err)
+ panic("Failed to continue new process, pid = %d, "
+ "errno = %d\n", pid, errno);
+ wait_stub_done(pid);
pid = data->err;
if(pid < 0)
@@ -381,7 +420,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
/* Wait, until child has finished too: read child's result from
* child's stack and check it.
*/
- wait_stub_done(pid, -1, "copy_context_skas0");
+ wait_stub_done(pid);
if (child_data->err != UML_CONFIG_STUB_DATA)
panic("copy_context_skas0 - stub-child reports error %ld\n",
child_data->err);
@@ -396,7 +435,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
/*
* This is used only, if stub pages are needed, while proc_mm is
- * availabl. Opening /proc/mm creates a new mm_context, which lacks
+ * available. Opening /proc/mm creates a new mm_context, which lacks
* the stub-pages. Thus, we map them using /proc/mm-fd
*/
void map_stub_pages(int fd, unsigned long code,
@@ -418,12 +457,13 @@ void map_stub_pages(int fd, unsigned long code,
.fd = code_fd,
.offset = code_offset
} } });
- n = os_write_file(fd, &mmop, sizeof(mmop));
+ CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
if(n != sizeof(mmop)){
+ n = errno;
printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n",
code, code_fd, (unsigned long long) code_offset);
panic("map_stub_pages : /proc/mm map for code failed, "
- "err = %d\n", -n);
+ "err = %d\n", n);
}
if ( stack ) {
@@ -440,10 +480,10 @@ void map_stub_pages(int fd, unsigned long code,
.fd = map_fd,
.offset = map_offset
} } });
- n = os_write_file(fd, &mmop, sizeof(mmop));
+ CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
if(n != sizeof(mmop))
panic("map_stub_pages : /proc/mm map for data failed, "
- "err = %d\n", -n);
+ "err = %d\n", errno);
}
}
@@ -480,7 +520,15 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
SIGVTALRM, -1);
- n = UML_SETJMP(&initial_jmpbuf);
+ /*
+ * Can't use UML_SETJMP or UML_LONGJMP here because they save
+ * and restore signals, with the possible side-effect of
+ * trying to handle any signals which came when they were
+ * blocked, which can't be done on this stack.
+ * Signals must be blocked when jumping back here and restored
+ * after returning to the jumper.
+ */
+ n = setjmp(initial_jmpbuf);
switch(n){
case INIT_JMP_NEW_THREAD:
(*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler;
@@ -490,7 +538,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
break;
case INIT_JMP_CALLBACK:
(*cb_proc)(cb_arg);
- UML_LONGJMP(cb_back, 1);
+ longjmp(*cb_back, 1);
break;
case INIT_JMP_HALT:
kmalloc_ok = 0;
@@ -501,7 +549,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
default:
panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
}
- UML_LONGJMP(switch_buf, 1);
+ longjmp(*switch_buf, 1);
}
void initial_thread_cb_skas(void (*proc)(void *), void *arg)
diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c
index 9ad5fbec..3b600c2 100644
--- a/arch/um/os-Linux/skas/trap.c
+++ b/arch/um/os-Linux/skas/trap.c
@@ -5,8 +5,8 @@
#include <signal.h>
#include <errno.h>
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
#include "task.h"
#include "sigcontext.h"
#include "skas.h"
@@ -15,29 +15,39 @@
#include "sysdep/ptrace_user.h"
#include "os.h"
+static union uml_pt_regs ksig_regs[UM_NR_CPUS];
+
void sig_handler_common_skas(int sig, void *sc_ptr)
{
struct sigcontext *sc = sc_ptr;
- struct skas_regs *r;
+ union uml_pt_regs *r;
void (*handler)(int, union uml_pt_regs *);
- int save_errno = errno;
- int save_user;
+ int save_user, save_errno = errno;
/* This is done because to allow SIGSEGV to be delivered inside a SEGV
* handler. This can happen in copy_user, and if SEGV is disabled,
* the process will die.
* XXX Figure out why this is better than SA_NODEFER
*/
- if(sig == SIGSEGV)
+ if(sig == SIGSEGV) {
change_sig(SIGSEGV, 1);
+ /* For segfaults, we want the data from the
+ * sigcontext. In this case, we don't want to mangle
+ * the process registers, so use a static set of
+ * registers. For other signals, the process
+ * registers are OK.
+ */
+ r = &ksig_regs[cpu()];
+ copy_sc(r, sc_ptr);
+ }
+ else r = TASK_REGS(get_current());
- r = &TASK_REGS(get_current())->skas;
- save_user = r->is_user;
- r->is_user = 0;
+ save_user = r->skas.is_user;
+ r->skas.is_user = 0;
if ( sig == SIGFPE || sig == SIGSEGV ||
sig == SIGBUS || sig == SIGILL ||
sig == SIGTRAP ) {
- GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
+ GET_FAULTINFO_FROM_SC(r->skas.faultinfo, sc);
}
change_sig(SIGUSR1, 1);
@@ -49,25 +59,8 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
sig != SIGVTALRM && sig != SIGALRM)
unblock_signals();
- handler(sig, (union uml_pt_regs *) r);
+ handler(sig, r);
errno = save_errno;
- r->is_user = save_user;
-}
-
-extern int ptrace_faultinfo;
-
-void user_signal(int sig, union uml_pt_regs *regs, int pid)
-{
- void (*handler)(int, union uml_pt_regs *);
- int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
- (sig == SIGILL) || (sig == SIGTRAP));
-
- if (segv)
- get_skas_faultinfo(pid, &regs->skas.faultinfo);
-
- handler = sig_info[sig];
- handler(sig, (union uml_pt_regs *) regs);
-
- unblock_signals();
+ r->skas.is_user = save_user;
}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 5178eba..79471f8 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -17,10 +17,10 @@
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/mman.h>
+#include <sys/resource.h>
#include <asm/unistd.h>
#include <asm/page.h>
#include <sys/types.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "signal_kern.h"
@@ -329,8 +329,32 @@ static void __init check_ptrace(void)
extern void check_tmpexec(void);
-void os_early_checks(void)
+static void __init check_coredump_limit(void)
{
+ struct rlimit lim;
+ int err = getrlimit(RLIMIT_CORE, &lim);
+
+ if(err){
+ perror("Getting core dump limit");
+ return;
+ }
+
+ printf("Core dump limits :\n\tsoft - ");
+ if(lim.rlim_cur == RLIM_INFINITY)
+ printf("NONE\n");
+ else printf("%lu\n", lim.rlim_cur);
+
+ printf("\thard - ");
+ if(lim.rlim_max == RLIM_INFINITY)
+ printf("NONE\n");
+ else printf("%lu\n", lim.rlim_max);
+}
+
+void __init os_early_checks(void)
+{
+ /* Print out the core dump limits early */
+ check_coredump_limit();
+
check_ptrace();
/* Need to check this early because mmapping happens before the
@@ -528,148 +552,3 @@ int __init parse_iomem(char *str, int *add)
out:
return 1;
}
-
-
-/* Changed during early boot */
-int pty_output_sigio = 0;
-int pty_close_sigio = 0;
-
-/* Used as a flag during SIGIO testing early in boot */
-static volatile int got_sigio = 0;
-
-static void __init handler(int sig)
-{
- got_sigio = 1;
-}
-
-struct openpty_arg {
- int master;
- int slave;
- int err;
-};
-
-static void openpty_cb(void *arg)
-{
- struct openpty_arg *info = arg;
-
- info->err = 0;
- if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
- info->err = -errno;
-}
-
-static int async_pty(int master, int slave)
-{
- int flags;
-
- flags = fcntl(master, F_GETFL);
- if(flags < 0)
- return -errno;
-
- if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
- (fcntl(master, F_SETOWN, os_getpid()) < 0))
- return -errno;
-
- if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
- return -errno;
-
- return(0);
-}
-
-static void __init check_one_sigio(void (*proc)(int, int))
-{
- struct sigaction old, new;
- struct openpty_arg pty = { .master = -1, .slave = -1 };
- int master, slave, err;
-
- initial_thread_cb(openpty_cb, &pty);
- if(pty.err){
- printk("openpty failed, errno = %d\n", -pty.err);
- return;
- }
-
- master = pty.master;
- slave = pty.slave;
-
- if((master == -1) || (slave == -1)){
- printk("openpty failed to allocate a pty\n");
- return;
- }
-
- /* Not now, but complain so we now where we failed. */
- err = raw(master);
- if (err < 0)
- panic("check_sigio : __raw failed, errno = %d\n", -err);
-
- err = async_pty(master, slave);
- if(err < 0)
- panic("tty_fds : sigio_async failed, err = %d\n", -err);
-
- if(sigaction(SIGIO, NULL, &old) < 0)
- panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
- new = old;
- new.sa_handler = handler;
- if(sigaction(SIGIO, &new, NULL) < 0)
- panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
-
- got_sigio = 0;
- (*proc)(master, slave);
-
- close(master);
- close(slave);
-
- if(sigaction(SIGIO, &old, NULL) < 0)
- panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
-}
-
-static void tty_output(int master, int slave)
-{
- int n;
- char buf[512];
-
- printk("Checking that host ptys support output SIGIO...");
-
- memset(buf, 0, sizeof(buf));
-
- while(os_write_file(master, buf, sizeof(buf)) > 0) ;
- if(errno != EAGAIN)
- panic("check_sigio : write failed, errno = %d\n", errno);
- while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
-
- if(got_sigio){
- printk("Yes\n");
- pty_output_sigio = 1;
- }
- else if(n == -EAGAIN) printk("No, enabling workaround\n");
- else panic("check_sigio : read failed, err = %d\n", n);
-}
-
-static void tty_close(int master, int slave)
-{
- printk("Checking that host ptys support SIGIO on close...");
-
- close(slave);
- if(got_sigio){
- printk("Yes\n");
- pty_close_sigio = 1;
- }
- else printk("No, enabling workaround\n");
-}
-
-void __init check_sigio(void)
-{
- if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
- (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
- printk("No pseudo-terminals available - skipping pty SIGIO "
- "check\n");
- return;
- }
- check_one_sigio(tty_output);
- check_one_sigio(tty_close);
-}
-
-void os_check_bugs(void)
-{
- check_ptrace();
- check_sigio();
-}
-
diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c
index 2565320..32ed41e 100644
--- a/arch/um/os-Linux/sys-i386/tls.c
+++ b/arch/um/os-Linux/sys-i386/tls.c
@@ -5,7 +5,7 @@
#include <unistd.h>
#include "sysdep/tls.h"
-#include "user_util.h"
+#include "user.h"
/* Checks whether host supports TLS, and sets *tls_min according to the value
* valid on the host.
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 2115b8b..5de169b 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -10,7 +10,6 @@
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "process.h"
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
index d221214..295da65 100644
--- a/arch/um/os-Linux/trap.c
+++ b/arch/um/os-Linux/trap.c
@@ -6,7 +6,6 @@
#include <stdlib.h>
#include <signal.h>
#include "kern_util.h"
-#include "user_util.h"
#include "os.h"
#include "mode.h"
#include "longjmp.h"
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
index 3dc3a02..bcf9359 100644
--- a/arch/um/os-Linux/tt.c
+++ b/arch/um/os-Linux/tt.c
@@ -18,7 +18,6 @@
#include <asm/ptrace.h>
#include <asm/unistd.h>
#include <asm/page.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "signal_kern.h"
@@ -32,6 +31,7 @@
#include "choose-mode.h"
#include "mode.h"
#include "tempfile.h"
+#include "kern_constants.h"
int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
int must_succeed)
@@ -143,7 +143,7 @@ int outer_tramp(void *arg)
int sig = sigkill;
t = arg;
- t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2,
+ t->pid = clone(t->tramp, (void *) t->temp_stack + UM_KERN_PAGE_SIZE/2,
t->flags, t->tramp_data);
if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
kill(os_getpid(), sig);
diff --git a/arch/um/os-Linux/tty_log.c b/arch/um/os-Linux/tty_log.c
index c6ba56c..d11a55b 100644
--- a/arch/um/os-Linux/tty_log.c
+++ b/arch/um/os-Linux/tty_log.c
@@ -53,9 +53,9 @@ int open_tty_log(void *tty, void *current_tty)
.direction = 0,
.sec = tv.tv_sec,
.usec = tv.tv_usec } );
- os_write_file(tty_log_fd, &data, sizeof(data));
- os_write_file(tty_log_fd, &current_tty, data.len);
- return(tty_log_fd);
+ write(tty_log_fd, &data, sizeof(data));
+ write(tty_log_fd, &current_tty, data.len);
+ return tty_log_fd;
}
sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
@@ -67,7 +67,7 @@ int open_tty_log(void *tty, void *current_tty)
printk("open_tty_log : couldn't open '%s', errno = %d\n",
buf, -fd);
}
- return(fd);
+ return fd;
}
void close_tty_log(int fd, void *tty)
@@ -83,7 +83,7 @@ void close_tty_log(int fd, void *tty)
.direction = 0,
.sec = tv.tv_sec,
.usec = tv.tv_usec } );
- os_write_file(tty_log_fd, &data, sizeof(data));
+ write(tty_log_fd, &data, sizeof(data));
return;
}
os_close_file(fd);
@@ -98,21 +98,21 @@ static int log_chunk(int fd, const char *buf, int len)
try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
missed = copy_from_user_proc(chunk, (char *) buf, try);
try -= missed;
- n = os_write_file(fd, chunk, try);
+ n = write(fd, chunk, try);
if(n != try) {
if(n < 0)
- return(n);
- return(-EIO);
+ return -errno;
+ return -EIO;
}
if(missed != 0)
- return(-EFAULT);
+ return -EFAULT;
len -= try;
total += try;
buf += try;
}
- return(total);
+ return total;
}
int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
@@ -130,10 +130,10 @@ int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
.direction = direction,
.sec = tv.tv_sec,
.usec = tv.tv_usec } );
- os_write_file(tty_log_fd, &data, sizeof(data));
+ write(tty_log_fd, &data, sizeof(data));
}
- return(log_chunk(fd, buf, len));
+ return log_chunk(fd, buf, len);
}
void log_exec(char **argv, void *tty)
@@ -161,7 +161,7 @@ void log_exec(char **argv, void *tty)
.direction = 0,
.sec = tv.tv_sec,
.usec = tv.tv_usec } );
- os_write_file(tty_log_fd, &data, sizeof(data));
+ write(tty_log_fd, &data, sizeof(data));
for(ptr = argv; ; ptr++){
if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
@@ -179,7 +179,7 @@ extern void register_tty_logger(int (*opener)(void *, void *),
static int register_logger(void)
{
register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
- return(0);
+ return 0;
}
__uml_initcall(register_logger);
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index 56b8a50..c307a89 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -21,7 +21,6 @@
#include <sched.h>
#include <termios.h>
#include <string.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "mem_user.h"
@@ -30,28 +29,29 @@
#include "uml-config.h"
#include "os.h"
#include "longjmp.h"
+#include "kern_constants.h"
void stack_protections(unsigned long address)
{
int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
- if(mprotect((void *) address, page_size(), prot) < 0)
+ if(mprotect((void *) address, UM_KERN_PAGE_SIZE, prot) < 0)
panic("protecting stack failed, errno = %d", errno);
}
void task_protections(unsigned long address)
{
- unsigned long guard = address + page_size();
- unsigned long stack = guard + page_size();
+ unsigned long guard = address + UM_KERN_PAGE_SIZE;
+ unsigned long stack = guard + UM_KERN_PAGE_SIZE;
int prot = 0, pages;
#ifdef notdef
- if(mprotect((void *) stack, page_size(), prot) < 0)
+ if(mprotect((void *) stack, UM_KERN_PAGE_SIZE, prot) < 0)
panic("protecting guard page failed, errno = %d", errno);
#endif
pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
prot = PROT_READ | PROT_WRITE | PROT_EXEC;
- if(mprotect((void *) stack, pages * page_size(), prot) < 0)
+ if(mprotect((void *) stack, pages * UM_KERN_PAGE_SIZE, prot) < 0)
panic("protecting stack failed, errno = %d", errno);
}
@@ -96,15 +96,13 @@ void setup_machinename(char *machine_out)
strcpy(machine_out, host.machine);
}
-char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1];
-
-void setup_hostinfo(void)
+void setup_hostinfo(char *buf, int len)
{
struct utsname host;
uname(&host);
- sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename,
- host.release, host.version, host.machine);
+ snprintf(buf, len, "%s %s %s %s %s", host.sysname, host.nodename,
+ host.release, host.version, host.machine);
}
int setjmp_wrapper(void (*proc)(void *, void *), ...)
@@ -121,3 +119,9 @@ int setjmp_wrapper(void (*proc)(void *, void *), ...)
va_end(args);
return n;
}
+
+void os_dump_core(void)
+{
+ signal(SIGSEGV, SIG_DFL);
+ abort();
+}
diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c
index f1bcd39..0393e44 100644
--- a/arch/um/sys-i386/bugs.c
+++ b/arch/um/sys-i386/bugs.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
@@ -13,7 +13,6 @@
#include "sysdep/ptrace.h"
#include "task.h"
#include "os.h"
-#include "user_util.h"
#define MAXTOKEN 64
@@ -32,21 +31,21 @@ static char token(int fd, char *buf, int len, char stop)
n = os_read_file(fd, ptr, sizeof(*ptr));
c = *ptr++;
if(n != sizeof(*ptr)){
- if(n == 0) return(0);
+ if(n == 0)
+ return 0;
printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
if(n < 0)
- return(n);
- else
- return(-EIO);
+ return n;
+ else return -EIO;
}
} while((c != '\n') && (c != stop) && (ptr < end));
if(ptr == end){
printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
- return(-1);
+ return -1;
}
*(ptr - 1) = '\0';
- return(c);
+ return c;
}
static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
@@ -58,48 +57,25 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
while(1){
c = token(fd, scratch, len - 1, ':');
if(c <= 0)
- return(0);
+ return 0;
else if(c != ':'){
printk("Failed to find ':' in /proc/cpuinfo\n");
- return(0);
+ return 0;
}
if(!strncmp(scratch, key, strlen(key)))
- return(1);
+ return 1;
do {
n = os_read_file(fd, &c, sizeof(c));
if(n != sizeof(c)){
printk("Failed to find newline in "
"/proc/cpuinfo, err = %d\n", -n);
- return(0);
+ return 0;
}
} while(c != '\n');
}
- return(0);
-}
-
-int cpu_feature(char *what, char *buf, int len)
-{
- int fd, ret = 0;
-
- fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
- if(fd < 0){
- printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
- return(0);
- }
-
- if(!find_cpuinfo_line(fd, what, buf, len)){
- printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
- goto out_close;
- }
-
- token(fd, buf, len, '\n');
- ret = 1;
-
- out_close:
- os_close_file(fd);
- return(ret);
+ return 0;
}
static int check_cpu_flag(char *feature, int *have_it)
@@ -119,7 +95,8 @@ static int check_cpu_flag(char *feature, int *have_it)
goto out;
c = token(fd, buf, len - 1, ' ');
- if(c < 0) goto out;
+ if(c < 0)
+ goto out;
else if(c != ' '){
printk("Failed to find ' ' in /proc/cpuinfo\n");
goto out;
@@ -127,7 +104,8 @@ static int check_cpu_flag(char *feature, int *have_it)
while(1){
c = token(fd, buf, len - 1, ' ');
- if(c < 0) goto out;
+ if(c < 0)
+ goto out;
else if(c == '\n') break;
if(!strcmp(buf, feature)){
@@ -136,8 +114,10 @@ static int check_cpu_flag(char *feature, int *have_it)
}
}
out:
- if(*have_it == 0) printk("No\n");
- else if(*have_it == 1) printk("Yes\n");
+ if(*have_it == 0)
+ printk("No\n");
+ else if(*have_it == 1)
+ printk("Yes\n");
os_close_file(fd);
return 1;
}
@@ -189,12 +169,13 @@ int arch_handle_signal(int sig, union uml_pt_regs *regs)
/* This is testing for a cmov (0x0f 0x4x) instruction causing a
* SIGILL in init.
*/
- if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0);
+ if((sig != SIGILL) || (TASK_PID(get_current()) != 1))
+ return 0;
if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2))
panic("SIGILL in init, could not read instructions!\n");
if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40))
- return(0);
+ return 0;
if(host_has_cmov == 0)
panic("SIGILL caused by cmov, which this processor doesn't "
@@ -208,16 +189,5 @@ int arch_handle_signal(int sig, union uml_pt_regs *regs)
"implements it, boot a filesystem compiled for older "
"processors");
else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
- return(0);
+ return 0;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-i386/fault.c b/arch/um/sys-i386/fault.c
index d0bbcdf..745b4fd 100644
--- a/arch/um/sys-i386/fault.c
+++ b/arch/um/sys-i386/fault.c
@@ -3,9 +3,7 @@
* Licensed under the GPL
*/
-#include <signal.h>
#include "sysdep/ptrace.h"
-#include "sysdep/sigcontext.h"
/* These two are from asm-um/uaccess.h and linux/module.h, check them. */
struct exception_table_entry
@@ -17,26 +15,14 @@ struct exception_table_entry
const struct exception_table_entry *search_exception_tables(unsigned long add);
/* Compare this to arch/i386/mm/extable.c:fixup_exception() */
-int arch_fixup(unsigned long address, void *sc_ptr)
+int arch_fixup(unsigned long address, union uml_pt_regs *regs)
{
- struct sigcontext *sc = sc_ptr;
const struct exception_table_entry *fixup;
fixup = search_exception_tables(address);
if(fixup != 0){
- sc->eip = fixup->fixup;
+ UPT_IP(regs) = fixup->fixup;
return(1);
}
return(0);
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c
index 01212c8..40ff0c8 100644
--- a/arch/um/sys-i386/ptrace_user.c
+++ b/arch/um/sys-i386/ptrace_user.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
@@ -15,7 +15,6 @@
#include "user.h"
#include "os.h"
#include "uml-config.h"
-#include "user_util.h"
int ptrace_getregs(long pid, unsigned long *regs_out)
{
@@ -45,7 +44,8 @@ int ptrace_setfpregs(long pid, unsigned long *regs)
return 0;
}
-/* All the below stuff is of interest for TT mode only */
+#ifdef UML_CONFIG_MODE_TT
+
static void write_debugregs(int pid, unsigned long *regs)
{
struct user *dummy;
@@ -128,13 +128,4 @@ void update_debugregs(int seq)
}
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+#endif
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 3f6acd6..1cbf95f 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -18,6 +18,28 @@
#include "skas.h"
+void copy_sc(union uml_pt_regs *regs, void *from)
+{
+ struct sigcontext *sc = from;
+
+ REGS_GS(regs->skas.regs) = sc->gs;
+ REGS_FS(regs->skas.regs) = sc->fs;
+ REGS_ES(regs->skas.regs) = sc->es;
+ REGS_DS(regs->skas.regs) = sc->ds;
+ REGS_EDI(regs->skas.regs) = sc->edi;
+ REGS_ESI(regs->skas.regs) = sc->esi;
+ REGS_EBP(regs->skas.regs) = sc->ebp;
+ REGS_SP(regs->skas.regs) = sc->esp;
+ REGS_EBX(regs->skas.regs) = sc->ebx;
+ REGS_EDX(regs->skas.regs) = sc->edx;
+ REGS_ECX(regs->skas.regs) = sc->ecx;
+ REGS_EAX(regs->skas.regs) = sc->eax;
+ REGS_IP(regs->skas.regs) = sc->eip;
+ REGS_CS(regs->skas.regs) = sc->cs;
+ REGS_EFLAGS(regs->skas.regs) = sc->eflags;
+ REGS_SS(regs->skas.regs) = sc->ss;
+}
+
static int copy_sc_from_user_skas(struct pt_regs *regs,
struct sigcontext __user *from)
{
@@ -28,33 +50,18 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
err = copy_from_user(&sc, from, sizeof(sc));
err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs));
if(err)
- return(err);
-
- REGS_GS(regs->regs.skas.regs) = sc.gs;
- REGS_FS(regs->regs.skas.regs) = sc.fs;
- REGS_ES(regs->regs.skas.regs) = sc.es;
- REGS_DS(regs->regs.skas.regs) = sc.ds;
- REGS_EDI(regs->regs.skas.regs) = sc.edi;
- REGS_ESI(regs->regs.skas.regs) = sc.esi;
- REGS_EBP(regs->regs.skas.regs) = sc.ebp;
- REGS_SP(regs->regs.skas.regs) = sc.esp;
- REGS_EBX(regs->regs.skas.regs) = sc.ebx;
- REGS_EDX(regs->regs.skas.regs) = sc.edx;
- REGS_ECX(regs->regs.skas.regs) = sc.ecx;
- REGS_EAX(regs->regs.skas.regs) = sc.eax;
- REGS_IP(regs->regs.skas.regs) = sc.eip;
- REGS_CS(regs->regs.skas.regs) = sc.cs;
- REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags;
- REGS_SS(regs->regs.skas.regs) = sc.ss;
+ return err;
+
+ copy_sc(&regs->regs, &sc);
err = restore_fp_registers(userspace_pid[0], fpregs);
- if(err < 0){
+ if(err < 0) {
printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, "
- "errno = %d\n", err);
- return(1);
+ "errno = %d\n", -err);
+ return err;
}
- return(0);
+ return 0;
}
int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *to_fp,
@@ -90,16 +97,16 @@ int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *t
if(err < 0){
printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, "
"errno = %d\n", err);
- return(1);
+ return 1;
}
to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1));
sc.fpstate = to_fp;
if(err)
- return(err);
+ return err;
- return(copy_to_user(to, &sc, sizeof(sc)) ||
- copy_to_user(to_fp, fpregs, sizeof(fpregs)));
+ return copy_to_user(to, &sc, sizeof(sc)) ||
+ copy_to_user(to_fp, fpregs, sizeof(fpregs));
}
#endif
@@ -129,7 +136,7 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from,
to->fpstate = to_fp;
if(to_fp != NULL)
err |= copy_from_user(to_fp, from_fp, fpsize);
- return(err);
+ return err;
}
int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp,
@@ -164,15 +171,15 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from)
ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from,
sizeof(struct _fpstate)),
copy_sc_from_user_skas(to, from));
- return(ret);
+ return ret;
}
static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp,
struct pt_regs *from, unsigned long sp)
{
- return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
+ return CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
sizeof(*fp), sp),
- copy_sc_to_user_skas(to, fp, from, sp)));
+ copy_sc_to_user_skas(to, fp, from, sp));
}
static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp,
@@ -185,7 +192,7 @@ static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __u
err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs, sp);
err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
- return(err);
+ return err;
}
struct sigframe
@@ -359,7 +366,7 @@ long sys_sigreturn(struct pt_regs regs)
/* Avoid ERESTART handling */
PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
- return(PT_REGS_SYSCALL_RET(&current->thread.regs));
+ return PT_REGS_SYSCALL_RET(&current->thread.regs);
segfault:
force_sig(SIGSEGV, current);
@@ -389,20 +396,9 @@ long sys_rt_sigreturn(struct pt_regs regs)
/* Avoid ERESTART handling */
PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
- return(PT_REGS_SYSCALL_RET(&current->thread.regs));
+ return PT_REGS_SYSCALL_RET(&current->thread.regs);
segfault:
force_sig(SIGSEGV, current);
return 0;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c
index 643dab5..fea8e5e 100644
--- a/arch/um/sys-i386/tls.c
+++ b/arch/um/sys-i386/tls.c
@@ -23,9 +23,13 @@
#include "skas.h"
#endif
-/* If needed we can detect when it's uninitialized. */
+/*
+ * If needed we can detect when it's uninitialized.
+ *
+ * These are initialized in an initcall and unchanged thereafter.
+ */
static int host_supports_tls = -1;
-int host_gdt_entry_tls_min = -1;
+int host_gdt_entry_tls_min;
#ifdef CONFIG_MODE_SKAS
int do_set_thread_area_skas(struct user_desc *info)
@@ -361,7 +365,8 @@ out:
/* XXX: This part is probably common to i386 and x86-64. Don't create a common
* file for now, do that when implementing x86-64 support.*/
-static int __init __setup_host_supports_tls(void) {
+static int __init __setup_host_supports_tls(void)
+{
check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min);
if (host_supports_tls) {
printk(KERN_INFO "Host TLS support detected\n");
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
index 447306b..29118cf 100644
--- a/arch/um/sys-i386/user-offsets.c
+++ b/arch/um/sys-i386/user-offsets.c
@@ -1,9 +1,10 @@
#include <stdio.h>
+#include <stddef.h>
#include <signal.h>
+#include <sys/poll.h>
+#include <sys/mman.h>
#include <asm/ptrace.h>
#include <asm/user.h>
-#include <stddef.h>
-#include <sys/poll.h>
#define DEFINE(sym, val) \
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -47,7 +48,6 @@ void foo(void)
OFFSET(HOST_SC_FP_ST, _fpstate, _st);
OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env);
- DEFINE(HOST_FRAME_SIZE, FRAME_SIZE);
DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_i387_struct));
DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fxsr_struct));
@@ -73,4 +73,8 @@ void foo(void)
DEFINE(UM_POLLIN, POLLIN);
DEFINE(UM_POLLPRI, POLLPRI);
DEFINE(UM_POLLOUT, POLLOUT);
+
+ DEFINE(UM_PROT_READ, PROT_READ);
+ DEFINE(UM_PROT_WRITE, PROT_WRITE);
+ DEFINE(UM_PROT_EXEC, PROT_EXEC);
}
diff --git a/arch/um/sys-ppc/sigcontext.c b/arch/um/sys-ppc/sigcontext.c
index 5d430fc..4bdc15c 100644
--- a/arch/um/sys-ppc/sigcontext.c
+++ b/arch/um/sys-ppc/sigcontext.c
@@ -1,7 +1,6 @@
#include "asm/ptrace.h"
#include "asm/sigcontext.h"
#include "sysdep/ptrace.h"
-#include "user_util.h"
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c
index fdce7ea..0954788 100644
--- a/arch/um/sys-x86_64/bugs.c
+++ b/arch/um/sys-x86_64/bugs.c
@@ -4,12 +4,7 @@
* Licensed under the GPL
*/
-#include "linux/sched.h"
-#include "linux/errno.h"
-#include "asm/system.h"
-#include "asm/pda.h"
#include "sysdep/ptrace.h"
-#include "os.h"
void arch_init_thread(void)
{
@@ -21,102 +16,5 @@ void arch_check_bugs(void)
int arch_handle_signal(int sig, union uml_pt_regs *regs)
{
- return(0);
+ return 0;
}
-
-#define MAXTOKEN 64
-
-/* Set during early boot */
-int host_has_cmov = 1;
-int host_has_xmm = 0;
-
-static char token(int fd, char *buf, int len, char stop)
-{
- int n;
- char *ptr, *end, c;
-
- ptr = buf;
- end = &buf[len];
- do {
- n = os_read_file(fd, ptr, sizeof(*ptr));
- c = *ptr++;
- if(n != sizeof(*ptr)){
- if(n == 0) return(0);
- printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
- if(n < 0)
- return(n);
- else
- return(-EIO);
- }
- } while((c != '\n') && (c != stop) && (ptr < end));
-
- if(ptr == end){
- printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
- return(-1);
- }
- *(ptr - 1) = '\0';
- return(c);
-}
-
-static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
-{
- int n;
- char c;
-
- scratch[len - 1] = '\0';
- while(1){
- c = token(fd, scratch, len - 1, ':');
- if(c <= 0)
- return(0);
- else if(c != ':'){
- printk("Failed to find ':' in /proc/cpuinfo\n");
- return(0);
- }
-
- if(!strncmp(scratch, key, strlen(key)))
- return(1);
-
- do {
- n = os_read_file(fd, &c, sizeof(c));
- if(n != sizeof(c)){
- printk("Failed to find newline in "
- "/proc/cpuinfo, err = %d\n", -n);
- return(0);
- }
- } while(c != '\n');
- }
- return(0);
-}
-
-int cpu_feature(char *what, char *buf, int len)
-{
- int fd, ret = 0;
-
- fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
- if(fd < 0){
- printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
- return(0);
- }
-
- if(!find_cpuinfo_line(fd, what, buf, len)){
- printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
- goto out_close;
- }
-
- token(fd, buf, len, '\n');
- ret = 1;
-
- out_close:
- os_close_file(fd);
- return(ret);
-}
-
-/* Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-x86_64/fault.c b/arch/um/sys-x86_64/fault.c
index cee1513..4636b14 100644
--- a/arch/um/sys-x86_64/fault.c
+++ b/arch/um/sys-x86_64/fault.c
@@ -4,20 +4,24 @@
* Licensed under the GPL
*/
-#include "user.h"
+#include "sysdep/ptrace.h"
-int arch_fixup(unsigned long address, void *sc_ptr)
+/* These two are from asm-um/uaccess.h and linux/module.h, check them. */
+struct exception_table_entry
{
- /* XXX search_exception_tables() */
+ unsigned long insn;
+ unsigned long fixup;
+};
+
+const struct exception_table_entry *search_exception_tables(unsigned long add);
+int arch_fixup(unsigned long address, union uml_pt_regs *regs)
+{
+ const struct exception_table_entry *fixup;
+
+ fixup = search_exception_tables(address);
+ if(fixup != 0){
+ UPT_IP(regs) = fixup->fixup;
+ return(1);
+ }
return(0);
}
-
-/* Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index af2f017..fe8ec04 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -20,6 +20,36 @@
#include "skas.h"
+void copy_sc(union uml_pt_regs *regs, void *from)
+{
+ struct sigcontext *sc = from;
+
+#define GETREG(regs, regno, sc, regname) \
+ (regs)->skas.regs[(regno) / sizeof(unsigned long)] = (sc)->regname
+
+ GETREG(regs, R8, sc, r8);
+ GETREG(regs, R9, sc, r9);
+ GETREG(regs, R10, sc, r10);
+ GETREG(regs, R11, sc, r11);
+ GETREG(regs, R12, sc, r12);
+ GETREG(regs, R13, sc, r13);
+ GETREG(regs, R14, sc, r14);
+ GETREG(regs, R15, sc, r15);
+ GETREG(regs, RDI, sc, rdi);
+ GETREG(regs, RSI, sc, rsi);
+ GETREG(regs, RBP, sc, rbp);
+ GETREG(regs, RBX, sc, rbx);
+ GETREG(regs, RDX, sc, rdx);
+ GETREG(regs, RAX, sc, rax);
+ GETREG(regs, RCX, sc, rcx);
+ GETREG(regs, RSP, sc, rsp);
+ GETREG(regs, RIP, sc, rip);
+ GETREG(regs, EFLAGS, sc, eflags);
+ GETREG(regs, CS, sc, cs);
+
+#undef GETREG
+}
+
static int copy_sc_from_user_skas(struct pt_regs *regs,
struct sigcontext __user *from)
{
@@ -51,7 +81,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
#undef GETREG
- return(err);
+ return err;
}
int copy_sc_to_user_skas(struct sigcontext __user *to,
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index 899cebb..0d5fd76 100644
--- a/arch/um/sys-x86_64/user-offsets.c
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -2,6 +2,7 @@
#include <stddef.h>
#include <signal.h>
#include <sys/poll.h>
+#include <sys/mman.h>
#define __FRAME_OFFSETS
#include <asm/ptrace.h>
#include <asm/types.h>
@@ -57,7 +58,6 @@ void foo(void)
OFFSET(HOST_SC_SS, sigcontext, ss);
#endif
- DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE);
DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long));
DEFINE(HOST_XFP_SIZE, 0);
DEFINE_LONGS(HOST_RBX, RBX);
@@ -94,4 +94,8 @@ void foo(void)
DEFINE(UM_POLLIN, POLLIN);
DEFINE(UM_POLLPRI, POLLPRI);
DEFINE(UM_POLLOUT, POLLOUT);
+
+ DEFINE(UM_PROT_READ, PROT_READ);
+ DEFINE(UM_PROT_WRITE, PROT_WRITE);
+ DEFINE(UM_PROT_EXEC, PROT_EXEC);
}
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
index 50ccc7f..5f54c12 100644
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -37,6 +37,10 @@ config GENERIC_IRQ_PROBE
bool
default y
+config GENERIC_TIME
+ bool
+ default y
+
config TIME_LOW_RES
bool
default y
diff --git a/arch/v850/kernel/process.c b/arch/v850/kernel/process.c
index c4f844c..e4a4b8e 100644
--- a/arch/v850/kernel/process.c
+++ b/arch/v850/kernel/process.c
@@ -16,7 +16,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
diff --git a/arch/v850/kernel/ptrace.c b/arch/v850/kernel/ptrace.c
index 67e0575..a9b0934 100644
--- a/arch/v850/kernel/ptrace.c
+++ b/arch/v850/kernel/ptrace.c
@@ -21,7 +21,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/ptrace.h>
#include <linux/signal.h>
diff --git a/arch/v850/kernel/signal.c b/arch/v850/kernel/signal.c
index 17c2d43..bf166e7 100644
--- a/arch/v850/kernel/signal.c
+++ b/arch/v850/kernel/signal.c
@@ -17,7 +17,6 @@
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/v850/kernel/syscalls.c b/arch/v850/kernel/syscalls.c
index d2b1fb1..f9f00cc 100644
--- a/arch/v850/kernel/syscalls.c
+++ b/arch/v850/kernel/syscalls.c
@@ -18,7 +18,6 @@
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/sem.h>
#include <linux/msg.h>
diff --git a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c
index 486e3a4..f0905b0 100644
--- a/arch/v850/kernel/time.c
+++ b/arch/v850/kernel/time.c
@@ -90,81 +90,6 @@ static irqreturn_t timer_interrupt (int irq, void *dummy, struct pt_regs *regs)
return IRQ_HANDLED;
}
-/*
- * This version of gettimeofday has near microsecond resolution.
- */
-void do_gettimeofday (struct timeval *tv)
-{
-#if 0 /* DAVIDM later if possible */
- extern volatile unsigned long lost_ticks;
- unsigned long lost;
-#endif
- unsigned long flags;
- unsigned long usec, sec;
- unsigned long seq;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
-
-#if 0
- usec = mach_gettimeoffset ? mach_gettimeoffset () : 0;
-#else
- usec = 0;
-#endif
-#if 0 /* DAVIDM later if possible */
- lost = lost_ticks;
- if (lost)
- usec += lost * (1000000/HZ);
-#endif
- sec = xtime.tv_sec;
- usec += xtime.tv_nsec / 1000;
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq (&xtime_lock);
-
- /* This is revolting. We need to set the xtime.tv_nsec
- * correctly. However, the value in this location is
- * is value at the last tick.
- * Discover what correction gettimeofday
- * would have done, and then undo it!
- */
-#if 0
- tv->tv_nsec -= mach_gettimeoffset() * 1000;
-#endif
-
- while (tv->tv_nsec < 0) {
- tv->tv_nsec += NSEC_PER_SEC;
- tv->tv_sec--;
- }
-
- xtime.tv_sec = tv->tv_sec;
- xtime.tv_nsec = tv->tv_nsec;
-
- ntp_clear();
-
- write_sequnlock_irq (&xtime_lock);
- clock_was_set();
- return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
static int timer_dev_id;
static struct irqaction timer_irqaction = {
timer_interrupt,
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
index 359eacc..6ea19c2 100644
--- a/arch/x86_64/ia32/ia32_signal.c
+++ b/arch/x86_64/ia32/ia32_signal.c
@@ -11,7 +11,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index c48087d..f210683 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -710,9 +710,10 @@ ia32_sys_call_table:
.quad compat_sys_get_robust_list
.quad sys_splice
.quad sys_sync_file_range
- .quad sys_tee
+ .quad sys_tee /* 315 */
.quad compat_sys_vmsplice
.quad compat_sys_move_pages
.quad sys_getcpu
.quad sys_epoll_pwait
+ .quad compat_sys_utimensat /* 320 */
ia32_syscall_end:
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index 4d94c51..de1de8a 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_IOMMU) += pci-gart.o aperture.o
obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary.o tce.o
obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
+obj-$(CONFIG_SERIAL_8250) += legacy_serial.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o
obj-$(CONFIG_X86_VSMP) += vsmp.o
@@ -49,6 +50,7 @@ CFLAGS_vsyscall.o := $(PROFILING) -g0
therm_throt-y += ../../i386/kernel/cpu/mcheck/therm_throt.o
bootflag-y += ../../i386/kernel/bootflag.o
+legacy_serial-y += ../../i386/kernel/legacy_serial.o
cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o
topology-y += ../../i386/kernel/topology.o
microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index d198f7d..1b0e07b 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -19,7 +19,6 @@
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/mc146818rtc.h>
#include <linux/kernel_stat.h>
diff --git a/arch/x86_64/kernel/crash.c b/arch/x86_64/kernel/crash.c
index 95a7a2c..13432a1 100644
--- a/arch/x86_64/kernel/crash.c
+++ b/arch/x86_64/kernel/crash.c
@@ -17,13 +17,13 @@
#include <linux/delay.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
+#include <linux/kdebug.h>
#include <asm/processor.h>
#include <asm/hardirq.h>
#include <asm/nmi.h>
#include <asm/hw_irq.h>
#include <asm/mach_apic.h>
-#include <asm/kdebug.h>
/* This keeps a track of which one is crashing cpu. */
static int crashing_cpu;
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index be89654..13c6c37 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -17,6 +17,8 @@
#include <linux/kexec.h>
#include <linux/module.h>
#include <linux/mm.h>
+#include <linux/suspend.h>
+#include <linux/pfn.h>
#include <asm/pgtable.h>
#include <asm/page.h>
@@ -256,22 +258,6 @@ void __init e820_reserve_resources(void)
}
}
-/* Mark pages corresponding to given address range as nosave */
-static void __init
-e820_mark_nosave_range(unsigned long start, unsigned long end)
-{
- unsigned long pfn, max_pfn;
-
- if (start >= end)
- return;
-
- printk("Nosave address range: %016lx - %016lx\n", start, end);
- max_pfn = end >> PAGE_SHIFT;
- for (pfn = start >> PAGE_SHIFT; pfn < max_pfn; pfn++)
- if (pfn_valid(pfn))
- SetPageNosave(pfn_to_page(pfn));
-}
-
/*
* Find the ranges of physical addresses that do not correspond to
* e820 RAM areas and mark the corresponding pages as nosave for software
@@ -290,13 +276,13 @@ void __init e820_mark_nosave_regions(void)
struct e820entry *ei = &e820.map[i];
if (paddr < ei->addr)
- e820_mark_nosave_range(paddr,
- round_up(ei->addr, PAGE_SIZE));
+ register_nosave_region(PFN_DOWN(paddr),
+ PFN_UP(ei->addr));
paddr = round_down(ei->addr + ei->size, PAGE_SIZE);
if (ei->type != E820_RAM)
- e820_mark_nosave_range(round_up(ei->addr, PAGE_SIZE),
- paddr);
+ register_nosave_region(PFN_UP(ei->addr),
+ PFN_DOWN(paddr));
if (paddr >= (end_pfn << PAGE_SHIFT))
break;
diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c
index 92213d2..56eaa25 100644
--- a/arch/x86_64/kernel/early_printk.c
+++ b/arch/x86_64/kernel/early_printk.c
@@ -243,22 +243,12 @@ static int __init setup_early_printk(char *buf)
early_console = &simnow_console;
keep_early = 1;
}
+
+ if (keep_early)
+ early_console->flags &= ~CON_BOOT;
+ else
+ early_console->flags |= CON_BOOT;
register_console(early_console);
return 0;
}
-
early_param("earlyprintk", setup_early_printk);
-
-void __init disable_early_printk(void)
-{
- if (!early_console_initialized || !early_console)
- return;
- if (!keep_early) {
- printk("disabling early console\n");
- unregister_console(early_console);
- early_console_initialized = 0;
- } else {
- printk("keeping early console\n");
- }
-}
-
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
index 4894266..4b32665 100644
--- a/arch/x86_64/kernel/i8259.c
+++ b/arch/x86_64/kernel/i8259.c
@@ -7,7 +7,6 @@
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/sysdev.h>
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 2a2df14..4d58258 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -25,7 +25,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/pci.h>
#include <linux/mc146818rtc.h>
#include <linux/acpi.h>
diff --git a/arch/x86_64/kernel/ioport.c b/arch/x86_64/kernel/ioport.c
index 387d347..653efa3 100644
--- a/arch/x86_64/kernel/ioport.c
+++ b/arch/x86_64/kernel/ioport.c
@@ -12,7 +12,6 @@
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/slab.h>
#include <linux/thread_info.h>
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index 209c8c0..d4a0d0a 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -37,10 +37,10 @@
#include <linux/slab.h>
#include <linux/preempt.h>
#include <linux/module.h>
+#include <linux/kdebug.h>
#include <asm/cacheflush.h>
#include <asm/pgtable.h>
-#include <asm/kdebug.h>
#include <asm/uaccess.h>
void jprobe_return_end(void);
@@ -266,23 +266,14 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
}
/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
unsigned long *sara = (unsigned long *)regs->rsp;
- struct kretprobe_instance *ri;
- if ((ri = get_free_rp_inst(rp)) != NULL) {
- ri->rp = rp;
- ri->task = current;
- ri->ret_addr = (kprobe_opcode_t *) *sara;
-
- /* Replace the return addr with trampoline addr */
- *sara = (unsigned long) &kretprobe_trampoline;
- add_rp_inst(ri);
- } else {
- rp->nmissed++;
- }
+ ri->ret_addr = (kprobe_opcode_t *) *sara;
+ /* Replace the return addr with trampoline addr */
+ *sara = (unsigned long) &kretprobe_trampoline;
}
int __kprobes kprobe_handler(struct pt_regs *regs)
@@ -447,7 +438,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
break;
}
- BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
+ kretprobe_assert(ri, orig_ret_address, trampoline_address);
regs->rip = orig_ret_address;
reset_current_kprobe();
@@ -752,3 +743,11 @@ int __init arch_init_kprobes(void)
{
return register_kprobe(&trampoline_p);
}
+
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+ if (p->addr == (kprobe_opcode_t *)&kretprobe_trampoline)
+ return 1;
+
+ return 0;
+}
diff --git a/arch/x86_64/kernel/ldt.c b/arch/x86_64/kernel/ldt.c
index d7e5d0c..bc9ffd5 100644
--- a/arch/x86_64/kernel/ldt.c
+++ b/arch/x86_64/kernel/ldt.c
@@ -13,7 +13,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c
index a8bb33c..c3a5547 100644
--- a/arch/x86_64/kernel/machine_kexec.c
+++ b/arch/x86_64/kernel/machine_kexec.c
@@ -189,21 +189,21 @@ NORET_TYPE void machine_kexec(struct kimage *image)
control_page = page_address(image->control_code_page) + PAGE_SIZE;
memcpy(control_page, relocate_kernel, PAGE_SIZE);
- page_list[PA_CONTROL_PAGE] = __pa(control_page);
+ page_list[PA_CONTROL_PAGE] = virt_to_phys(control_page);
page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
- page_list[PA_PGD] = __pa_symbol(&kexec_pgd);
+ page_list[PA_PGD] = virt_to_phys(&kexec_pgd);
page_list[VA_PGD] = (unsigned long)kexec_pgd;
- page_list[PA_PUD_0] = __pa_symbol(&kexec_pud0);
+ page_list[PA_PUD_0] = virt_to_phys(&kexec_pud0);
page_list[VA_PUD_0] = (unsigned long)kexec_pud0;
- page_list[PA_PMD_0] = __pa_symbol(&kexec_pmd0);
+ page_list[PA_PMD_0] = virt_to_phys(&kexec_pmd0);
page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
- page_list[PA_PTE_0] = __pa_symbol(&kexec_pte0);
+ page_list[PA_PTE_0] = virt_to_phys(&kexec_pte0);
page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
- page_list[PA_PUD_1] = __pa_symbol(&kexec_pud1);
+ page_list[PA_PUD_1] = virt_to_phys(&kexec_pud1);
page_list[VA_PUD_1] = (unsigned long)kexec_pud1;
- page_list[PA_PMD_1] = __pa_symbol(&kexec_pmd1);
+ page_list[PA_PMD_1] = virt_to_phys(&kexec_pmd1);
page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
- page_list[PA_PTE_1] = __pa_symbol(&kexec_pte1);
+ page_list[PA_PTE_1] = virt_to_phys(&kexec_pte1);
page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
page_list[PA_TABLE_PAGE] =
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index fa26726..4421696 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -20,10 +20,10 @@
#include <linux/percpu.h>
#include <linux/ctype.h>
#include <linux/kmod.h>
+#include <linux/kdebug.h>
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/mce.h>
-#include <asm/kdebug.h>
#include <asm/uaccess.h>
#include <asm/smp.h>
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index d0dc489..61ae57e 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -17,7 +17,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
-#include <linux/smp_lock.h>
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
#include <linux/acpi.h>
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index 6cd2b30..931c64b 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -21,11 +21,11 @@
#include <linux/sysctl.h>
#include <linux/kprobes.h>
#include <linux/cpumask.h>
+#include <linux/kdebug.h>
#include <asm/smp.h>
#include <asm/nmi.h>
#include <asm/proto.h>
-#include <asm/kdebug.h>
#include <asm/mce.h>
int unknown_nmi_panic;
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 0a762e1..373ef66 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -22,13 +22,13 @@
#include <linux/topology.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
+#include <linux/kdebug.h>
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/mtrr.h>
#include <asm/pgtable.h>
#include <asm/proto.h>
#include <asm/cacheflush.h>
-#include <asm/kdebug.h>
#include <asm/swiotlb.h>
#include <asm/dma.h>
#include <asm/k8.h>
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 4f21765..5909039 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -36,6 +36,7 @@
#include <linux/random.h>
#include <linux/notifier.h>
#include <linux/kprobes.h>
+#include <linux/kdebug.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -46,7 +47,6 @@
#include <asm/mmu_context.h>
#include <asm/pda.h>
#include <asm/prctl.h>
-#include <asm/kdebug.h>
#include <asm/desc.h>
#include <asm/proto.h>
#include <asm/ia32.h>
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index 4326a69..9409117 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -11,7 +11,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
diff --git a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c
index 2d67698..c116b54 100644
--- a/arch/x86_64/kernel/reboot.c
+++ b/arch/x86_64/kernel/reboot.c
@@ -7,8 +7,8 @@
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/pm.h>
+#include <linux/kdebug.h>
#include <asm/io.h>
-#include <asm/kdebug.h>
#include <asm/delay.h>
#include <asm/hw_irq.h>
#include <asm/system.h>
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index db30b5b..db51577 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -245,12 +245,11 @@ void __init setup_arch(char **cmdline_p)
init_mm.end_code = (unsigned long) &_etext;
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end;
- init_mm.pgd = __va(__pa_symbol(&init_level4_pgt));
- code_resource.start = __pa_symbol(&_text);
- code_resource.end = __pa_symbol(&_etext)-1;
- data_resource.start = __pa_symbol(&_etext);
- data_resource.end = __pa_symbol(&_edata)-1;
+ code_resource.start = virt_to_phys(&_text);
+ code_resource.end = virt_to_phys(&_etext)-1;
+ data_resource.start = virt_to_phys(&_etext);
+ data_resource.end = virt_to_phys(&_edata)-1;
early_identify_cpu(&boot_cpu_data);
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
index c819625..290f5d8 100644
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -12,7 +12,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
index 22abae4..2ff4685 100644
--- a/arch/x86_64/kernel/smp.c
+++ b/arch/x86_64/kernel/smp.c
@@ -14,7 +14,6 @@
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/smp.h>
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
@@ -76,7 +75,7 @@ static inline void leave_mm(int cpu)
if (read_pda(mmu_state) == TLBSTATE_OK)
BUG();
cpu_clear(cpu, read_pda(active_mm)->cpu_vm_mask);
- load_cr3(init_mm.pgd);
+ load_cr3(swapper_pg_dir);
}
/*
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 4d9dacf..32f5078 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -42,18 +42,17 @@
#include <linux/mm.h>
#include <linux/kernel_stat.h>
-#include <linux/smp_lock.h>
#include <linux/bootmem.h>
#include <linux/thread_info.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
#include <linux/smp.h>
+#include <linux/kdebug.h>
#include <asm/mtrr.h>
#include <asm/pgalloc.h>
#include <asm/desc.h>
-#include <asm/kdebug.h>
#include <asm/tlbflush.h>
#include <asm/proto.h>
#include <asm/nmi.h>
diff --git a/arch/x86_64/kernel/stacktrace.c b/arch/x86_64/kernel/stacktrace.c
index 65ac2c6..cb91091 100644
--- a/arch/x86_64/kernel/stacktrace.c
+++ b/arch/x86_64/kernel/stacktrace.c
@@ -21,8 +21,7 @@ save_stack_warning_symbol(void *data, char *msg, unsigned long symbol)
static int save_stack_stack(void *data, char *name)
{
- struct stack_trace *trace = (struct stack_trace *)data;
- return trace->all_contexts ? 0 : -1;
+ return -1;
}
static void save_stack_address(void *data, unsigned long addr)
@@ -46,11 +45,10 @@ static struct stacktrace_ops save_stack_ops = {
/*
* Save stack-backtrace addresses into a stack_trace buffer.
*/
-void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+void save_stack_trace(struct stack_trace *trace)
{
- dump_trace(task, NULL, NULL, &save_stack_ops, trace);
+ dump_trace(current, NULL, NULL, &save_stack_ops, trace);
if (trace->nr_entries < trace->max_entries)
trace->entries[trace->nr_entries++] = ULONG_MAX;
}
EXPORT_SYMBOL(save_stack_trace);
-
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c
index 76bf7c2..d067d9a 100644
--- a/arch/x86_64/kernel/sys_x86_64.c
+++ b/arch/x86_64/kernel/sys_x86_64.c
@@ -7,7 +7,6 @@
#include <linux/syscalls.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
@@ -93,6 +92,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long start_addr;
unsigned long begin, end;
+ if (flags & MAP_FIXED)
+ return addr;
+
find_start_end(flags, &begin, &end);
if (len > end)
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 0652e17..4a0895b 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -363,7 +363,10 @@ void stop_timer_interrupt(void)
}
static struct irqaction irq0 = {
- timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_IRQPOLL,
+ .mask = CPU_MASK_NONE,
+ .name = "timer"
};
void __init time_init(void)
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index d76fc32..8c2ac41 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -32,6 +32,7 @@
#include <linux/unwind.h>
#include <linux/uaccess.h>
#include <linux/bug.h>
+#include <linux/kdebug.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -39,7 +40,6 @@
#include <asm/debugreg.h>
#include <asm/desc.h>
#include <asm/i387.h>
-#include <asm/kdebug.h>
#include <asm/processor.h>
#include <asm/unwind.h>
#include <asm/smp.h>
@@ -71,22 +71,6 @@ asmlinkage void alignment_check(void);
asmlinkage void machine_check(void);
asmlinkage void spurious_interrupt_bug(void);
-ATOMIC_NOTIFIER_HEAD(die_chain);
-EXPORT_SYMBOL(die_chain);
-
-int register_die_notifier(struct notifier_block *nb)
-{
- vmalloc_sync_all();
- return atomic_notifier_chain_register(&die_chain, nb);
-}
-EXPORT_SYMBOL(register_die_notifier); /* used modular by kdb */
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&die_chain, nb);
-}
-EXPORT_SYMBOL(unregister_die_notifier); /* used modular by kdb */
-
static inline void conditional_sti(struct pt_regs *regs)
{
if (regs->eflags & X86_EFLAGS_IF)
@@ -792,6 +776,8 @@ asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs)
*/
if (nmi_watchdog_tick(regs,reason))
return;
+ if (notify_die(DIE_NMI_POST, "nmi_post", regs, reason, 2, 0)
+ == NOTIFY_STOP)
if (!do_nmi_callback(regs,cpu))
unknown_nmi_error(reason, regs);
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index de99dba..bfb62a1 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -15,22 +15,22 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/vt_kern.h> /* For unblank_screen() */
#include <linux/compiler.h>
+#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/uaccess.h>
+#include <linux/kdebug.h>
#include <asm/system.h>
#include <asm/pgalloc.h>
#include <asm/smp.h>
#include <asm/tlbflush.h>
#include <asm/proto.h>
-#include <asm/kdebug.h>
#include <asm-generic/sections.h>
/* Page fault error code bits */
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index 282b0a8..1336da8 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -172,7 +172,7 @@ __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
set_pte_phys(address, phys, prot);
}
-unsigned long __initdata table_start, table_end;
+unsigned long __meminitdata table_start, table_end;
static __meminit void *alloc_low_page(unsigned long *phys)
{
@@ -204,7 +204,7 @@ static __meminit void unmap_low_page(void *adr)
}
/* Must run before zap_low_mappings */
-__init void *early_ioremap(unsigned long addr, unsigned long size)
+__meminit void *early_ioremap(unsigned long addr, unsigned long size)
{
unsigned long vaddr;
pmd_t *pmd, *last_pmd;
@@ -233,7 +233,7 @@ __init void *early_ioremap(unsigned long addr, unsigned long size)
}
/* To avoid virtual aliases later */
-__init void early_iounmap(void *addr, unsigned long size)
+__meminit void early_iounmap(void *addr, unsigned long size)
{
unsigned long vaddr;
pmd_t *pmd;
@@ -572,13 +572,13 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
for (addr = begin; addr < end; addr += PAGE_SIZE) {
- struct page *page = pfn_to_page(addr >> PAGE_SHIFT);
- ClearPageReserved(page);
- init_page_count(page);
- memset(page_address(page), POISON_FREE_INITMEM, PAGE_SIZE);
+ ClearPageReserved(virt_to_page(addr));
+ init_page_count(virt_to_page(addr));
+ memset((void *)(addr & ~(PAGE_SIZE-1)),
+ POISON_FREE_INITMEM, PAGE_SIZE);
if (addr >= __START_KERNEL_map)
change_page_attr_addr(addr, 1, __pgprot(0));
- __free_page(page);
+ free_page(addr);
totalram_pages++;
}
if (addr > __START_KERNEL_map)
@@ -588,26 +588,31 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
void free_initmem(void)
{
free_init_pages("unused kernel memory",
- __pa_symbol(&__init_begin),
- __pa_symbol(&__init_end));
+ (unsigned long)(&__init_begin),
+ (unsigned long)(&__init_end));
}
#ifdef CONFIG_DEBUG_RODATA
void mark_rodata_ro(void)
{
- unsigned long start = PFN_ALIGN(__va(__pa_symbol(&_stext))), size;
+ unsigned long start = (unsigned long)_stext, end;
#ifdef CONFIG_HOTPLUG_CPU
/* It must still be possible to apply SMP alternatives. */
if (num_possible_cpus() > 1)
- start = PFN_ALIGN(__va(__pa_symbol(&_etext)));
+ start = (unsigned long)_etext;
#endif
- size = (unsigned long)__va(__pa_symbol(&__end_rodata)) - start;
- change_page_attr_addr(start, size >> PAGE_SHIFT, PAGE_KERNEL_RO);
+ end = (unsigned long)__end_rodata;
+ start = (start + PAGE_SIZE - 1) & PAGE_MASK;
+ end &= PAGE_MASK;
+ if (end <= start)
+ return;
+
+ change_page_attr_addr(start, (end - start) >> PAGE_SHIFT, PAGE_KERNEL_RO);
printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
- size >> 10);
+ (end - start) >> 10);
/*
* change_page_attr_addr() requires a global_flush_tlb() call after it.
@@ -622,7 +627,7 @@ void mark_rodata_ro(void)
#ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end)
{
- free_init_pages("initrd memory", __pa(start), __pa(end));
+ free_init_pages("initrd memory", start, end);
}
#endif
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
index c6e5e8d..6cac90a 100644
--- a/arch/x86_64/mm/ioremap.c
+++ b/arch/x86_64/mm/ioremap.c
@@ -13,12 +13,21 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/io.h>
+
#include <asm/pgalloc.h>
#include <asm/fixmap.h>
#include <asm/tlbflush.h>
#include <asm/cacheflush.h>
#include <asm/proto.h>
+unsigned long __phys_addr(unsigned long x)
+{
+ if (x >= __START_KERNEL_map)
+ return x - __START_KERNEL_map + phys_base;
+ return x - PAGE_OFFSET;
+}
+EXPORT_SYMBOL(__phys_addr);
+
#define ISA_START_ADDRESS 0xa0000
#define ISA_END_ADDRESS 0x100000
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
index bf4aa8d..d653d0b 100644
--- a/arch/x86_64/mm/pageattr.c
+++ b/arch/x86_64/mm/pageattr.c
@@ -51,6 +51,7 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot,
SetPagePrivate(base);
page_private(base) = 0;
+ address = __pa(address);
addr = address & LARGE_PAGE_MASK;
pbase = (pte_t *)page_address(base);
for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
@@ -100,12 +101,13 @@ static inline void save_page(struct page *fpage)
* No more special protections in this 2/4MB area - revert to a
* large page again.
*/
-static void revert_page(unsigned long address, unsigned long pfn, pgprot_t ref_prot)
+static void revert_page(unsigned long address, pgprot_t ref_prot)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t large_pte;
+ unsigned long pfn;
pgd = pgd_offset_k(address);
BUG_ON(pgd_none(*pgd));
@@ -113,6 +115,7 @@ static void revert_page(unsigned long address, unsigned long pfn, pgprot_t ref_p
BUG_ON(pud_none(*pud));
pmd = pmd_offset(pud, address);
BUG_ON(pmd_val(*pmd) & _PAGE_PSE);
+ pfn = (__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT;
large_pte = pfn_pte(pfn, ref_prot);
large_pte = pte_mkhuge(large_pte);
set_pte((pte_t *)pmd, large_pte);
@@ -138,8 +141,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
*/
struct page *split;
ref_prot2 = pte_pgprot(pte_clrhuge(*kpte));
- split = split_large_page(pfn << PAGE_SHIFT, prot,
- ref_prot2);
+ split = split_large_page(address, prot, ref_prot2);
if (!split)
return -ENOMEM;
set_pte(kpte, mk_pte(split, ref_prot2));
@@ -158,7 +160,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
if (page_private(kpte_page) == 0) {
save_page(kpte_page);
- revert_page(address, pfn, ref_prot);
+ revert_page(address, ref_prot);
}
return 0;
}
@@ -178,7 +180,6 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
*/
int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot)
{
- unsigned long phys_base_pfn = __pa_symbol(__START_KERNEL_map) >> PAGE_SHIFT;
int err = 0, kernel_map = 0;
int i;
@@ -199,11 +200,10 @@ int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot)
}
/* Handle kernel mapping too which aliases part of the
* lowmem */
- if ((pfn >= phys_base_pfn) &&
- ((pfn - phys_base_pfn) < (KERNEL_TEXT_SIZE >> PAGE_SHIFT))) {
+ if (__pa(address) < KERNEL_TEXT_SIZE) {
unsigned long addr2;
pgprot_t prot2;
- addr2 = __START_KERNEL_map + ((pfn - phys_base_pfn) << PAGE_SHIFT);
+ addr2 = __START_KERNEL_map + __pa(address);
/* Make sure the kernel mappings stay executable */
prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot)));
err = __change_page_attr(addr2, pfn, prot2,
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 795bd5a..ce758ba 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 8b6d3d0..14104ff 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -19,7 +19,6 @@
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/security.h>
#include <linux/signal.h>
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index c6d9880..5810767 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -17,7 +17,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c
index ab05bff..4bfe333 100644
--- a/arch/xtensa/platform-iss/network.c
+++ b/arch/xtensa/platform-iss/network.c
@@ -251,7 +251,7 @@ static int tuntap_open(struct iss_net_private *lp)
memset(&ifr, 0, sizeof ifr);
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
- strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name - 1);
+ strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name);
if ((err = simc_ioctl(fd, TUNSETIFF, (void*) &ifr)) < 0) {
printk("Failed to set interface, returned %d "
diff --git a/block/as-iosched.c b/block/as-iosched.c
index ef12627..640aa83 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -569,7 +569,7 @@ static void as_update_iohist(struct as_data *ad, struct as_io_context *aic,
static int as_close_req(struct as_data *ad, struct as_io_context *aic,
struct request *rq)
{
- unsigned long delay; /* milliseconds */
+ unsigned long delay; /* jiffies */
sector_t last = ad->last_sector[ad->batch_data_dir];
sector_t next = rq->sector;
sector_t delta; /* acceptable close offset (in sectors) */
@@ -578,11 +578,11 @@ static int as_close_req(struct as_data *ad, struct as_io_context *aic,
if (ad->antic_status == ANTIC_OFF || !ad->ioc_finished)
delay = 0;
else
- delay = ((jiffies - ad->antic_start) * 1000) / HZ;
+ delay = jiffies - ad->antic_start;
if (delay == 0)
delta = 8192;
- else if (delay <= 20 && delay <= ad->antic_expire)
+ else if (delay <= (20 * HZ / 1000) && delay <= ad->antic_expire)
delta = 8192 << delay;
else
return 1;
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 64df3fa..baef5fc 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -2090,13 +2090,11 @@ static void cfq_slab_kill(void)
static int __init cfq_slab_setup(void)
{
- cfq_pool = kmem_cache_create("cfq_pool", sizeof(struct cfq_queue), 0, 0,
- NULL, NULL);
+ cfq_pool = KMEM_CACHE(cfq_queue, 0);
if (!cfq_pool)
goto fail;
- cfq_ioc_pool = kmem_cache_create("cfq_ioc_pool",
- sizeof(struct cfq_io_context), 0, 0, NULL, NULL);
+ cfq_ioc_pool = KMEM_CACHE(cfq_io_context, 0);
if (!cfq_ioc_pool)
goto fail;
diff --git a/block/ioctl.c b/block/ioctl.c
index e06dbe9..f7e3e8a 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -80,7 +80,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
}
/* all seems OK */
fsync_bdev(bdevp);
- invalidate_bdev(bdevp, 0);
+ invalidate_bdev(bdevp);
mutex_lock_nested(&bdev->bd_mutex, 1);
delete_partition(disk, part);
@@ -236,7 +236,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
lock_kernel();
fsync_bdev(bdev);
- invalidate_bdev(bdev, 0);
+ invalidate_bdev(bdev);
unlock_kernel();
return 0;
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 5873861..d99d402 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -2558,6 +2558,7 @@ int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf,
bio->bi_rw |= (1 << BIO_RW);
blk_rq_bio_prep(q, rq, bio);
+ blk_queue_bounce(q, &rq->bio);
rq->buffer = rq->data = NULL;
return 0;
}
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 4334c20..41427a4 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -245,6 +245,35 @@ arch_initcall(init_acpi_device_notify);
#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
+#ifdef CONFIG_PM
+static u32 rtc_handler(void *context)
+{
+ acpi_clear_event(ACPI_EVENT_RTC);
+ acpi_disable_event(ACPI_EVENT_RTC, 0);
+ return ACPI_INTERRUPT_HANDLED;
+}
+
+static inline void rtc_wake_setup(void)
+{
+ acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
+}
+
+static void rtc_wake_on(struct device *dev)
+{
+ acpi_clear_event(ACPI_EVENT_RTC);
+ acpi_enable_event(ACPI_EVENT_RTC, 0);
+}
+
+static void rtc_wake_off(struct device *dev)
+{
+ acpi_disable_event(ACPI_EVENT_RTC, 0);
+}
+#else
+#define rtc_wake_setup() do{}while(0)
+#define rtc_wake_on NULL
+#define rtc_wake_off NULL
+#endif
+
/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
* its device node and pass extra config data. This helps its driver use
* capabilities that the now-obsolete mc146818 didn't have, and informs it
@@ -283,11 +312,24 @@ static int __init acpi_rtc_init(void)
struct device *dev = get_rtc_dev();
if (dev) {
+ rtc_wake_setup();
+ rtc_info.wake_on = rtc_wake_on;
+ rtc_info.wake_off = rtc_wake_off;
+
+ /* workaround bug in some ACPI tables */
+ if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
+ DBG("bogus FADT month_alarm\n");
+ acpi_gbl_FADT.month_alarm = 0;
+ }
+
rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
rtc_info.rtc_century = acpi_gbl_FADT.century;
- /* NOTE: acpi_gbl_FADT->rtcs4 is NOT currently useful */
+ /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */
+ if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
+ printk(PREFIX "RTC can wake from S4\n");
+
dev->platform_data = &rtc_info;
@@ -296,7 +338,7 @@ static int __init acpi_rtc_init(void)
put_device(dev);
} else
- pr_debug("ACPI: RTC unavailable?\n");
+ DBG("RTC unavailable?\n");
return 0;
}
/* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 8fcd6a1..4dd0dab 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -228,7 +228,7 @@ int __init acpi_numa_init(void)
return 0;
}
-int acpi_get_pxm(acpi_handle h)
+int __meminit acpi_get_pxm(acpi_handle h)
{
unsigned long pxm;
acpi_status status;
@@ -246,7 +246,7 @@ int acpi_get_pxm(acpi_handle h)
}
EXPORT_SYMBOL(acpi_get_pxm);
-int acpi_get_node(acpi_handle *handle)
+int __meminit acpi_get_node(acpi_handle *handle)
{
int pxm, node = -1;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 971eca4..c2bed56 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -30,7 +30,6 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/pci.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/kmod.h>
#include <linux/delay.h>
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index d80dd84..6b3b8a5 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -302,7 +302,7 @@ static void acpi_device_shutdown(struct device *dev)
return ;
}
-static struct bus_type acpi_bus_type = {
+struct bus_type acpi_bus_type = {
.name = "acpi",
.suspend = acpi_device_suspend,
.resume = acpi_device_resume,
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index 2d912b7..5a76e5b 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -60,7 +60,7 @@ acpi_system_write_sleep(struct file *file,
state = simple_strtoul(str, NULL, 0);
#ifdef CONFIG_SOFTWARE_SUSPEND
if (state == 4) {
- error = software_suspend();
+ error = pm_suspend(PM_SUSPEND_DISK);
goto Done;
}
#endif
@@ -70,6 +70,14 @@ acpi_system_write_sleep(struct file *file,
}
#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
+#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
+/* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */
+#else
+#define HAVE_ACPI_LEGACY_ALARM
+#endif
+
+#ifdef HAVE_ACPI_LEGACY_ALARM
+
static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
{
u32 sec, min, hr;
@@ -341,6 +349,8 @@ acpi_system_write_alarm(struct file *file,
end:
return_VALUE(result ? result : count);
}
+#endif /* HAVE_ACPI_LEGACY_ALARM */
+
extern struct list_head acpi_wakeup_device_list;
extern spinlock_t acpi_device_lock;
@@ -464,6 +474,7 @@ static const struct file_operations acpi_system_sleep_fops = {
};
#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
+#ifdef HAVE_ACPI_LEGACY_ALARM
static const struct file_operations acpi_system_alarm_fops = {
.open = acpi_system_alarm_open_fs,
.read = seq_read,
@@ -479,8 +490,9 @@ static u32 rtc_handler(void *context)
return ACPI_INTERRUPT_HANDLED;
}
+#endif /* HAVE_ACPI_LEGACY_ALARM */
-static int acpi_sleep_proc_init(void)
+static int __init acpi_sleep_proc_init(void)
{
struct proc_dir_entry *entry = NULL;
@@ -496,6 +508,7 @@ static int acpi_sleep_proc_init(void)
entry->proc_fops = &acpi_system_sleep_fops;
#endif
+#ifdef HAVE_ACPI_LEGACY_ALARM
/* 'alarm' [R/W] */
entry =
create_proc_entry("alarm", S_IFREG | S_IRUGO | S_IWUSR,
@@ -503,6 +516,9 @@ static int acpi_sleep_proc_init(void)
if (entry)
entry->proc_fops = &acpi_system_alarm_fops;
+ acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
+#endif /* HAVE_ACPI_LEGACY_ALARM */
+
/* 'wakeup device' [R/W] */
entry =
create_proc_entry("wakeup", S_IFREG | S_IRUGO | S_IWUSR,
@@ -510,7 +526,6 @@ static int acpi_sleep_proc_init(void)
if (entry)
entry->proc_fops = &acpi_system_wakeup_device_fops;
- acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
return 0;
}
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 365c306..45dbdc1 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -550,13 +550,21 @@ config PATA_WINBOND_VLB
config PATA_PLATFORM
tristate "Generic platform device PATA support"
- depends on EMBEDDED
+ depends on EMBEDDED || ARCH_RPC
help
This option enables support for generic directly connected ATA
devices commonly found on embedded systems.
If unsure, say N.
+config PATA_ICSIDE
+ tristate "Acorn ICS PATA support"
+ depends on ARM && ARCH_ACORN
+ help
+ On Acorn systems, say Y here if you wish to use the ICS PATA
+ interface card. This is not required for ICS partition support.
+ If you are unsure, say N to this.
+
config PATA_IXP4XX_CF
tristate "IXP4XX Compact Flash support"
depends on ARCH_IXP4XX
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index b7055e3..6f42a0e 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o
obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o
obj-$(CONFIG_PATA_SCC) += pata_scc.o
obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o
+obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o
# Should be last but one libata driver
obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
# Should be last libata driver
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 34c5534..d961789 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -874,7 +874,8 @@ static int ahci_clo(struct ata_port *ap)
return 0;
}
-static int ahci_softreset(struct ata_port *ap, unsigned int *class)
+static int ahci_softreset(struct ata_port *ap, unsigned int *class,
+ unsigned long deadline)
{
struct ahci_port_priv *pp = ap->private_data;
void __iomem *port_mmio = ahci_port_base(ap);
@@ -959,15 +960,13 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
*/
msleep(150);
- *class = ATA_DEV_NONE;
- if (ata_port_online(ap)) {
- if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
- rc = -EIO;
- reason = "device not ready";
- goto fail;
- }
- *class = ahci_dev_classify(ap);
+ rc = ata_wait_ready(ap, deadline);
+ /* link occupied, -ENODEV too is an error */
+ if (rc) {
+ reason = "device not ready";
+ goto fail;
}
+ *class = ahci_dev_classify(ap);
DPRINTK("EXIT, class=%u\n", *class);
return 0;
@@ -979,7 +978,8 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
return rc;
}
-static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
+static int ahci_hardreset(struct ata_port *ap, unsigned int *class,
+ unsigned long deadline)
{
struct ahci_port_priv *pp = ap->private_data;
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
@@ -995,7 +995,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
tf.command = 0x80;
ata_tf_to_fis(&tf, d2h_fis, 0);
- rc = sata_std_hardreset(ap, class);
+ rc = sata_std_hardreset(ap, class, deadline);
ahci_start_engine(ap);
@@ -1008,7 +1008,8 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
return rc;
}
-static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
+static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,
+ unsigned long deadline)
{
int rc;
@@ -1016,7 +1017,8 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
ahci_stop_engine(ap);
- rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context));
+ rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context),
+ deadline);
/* vt8251 needs SError cleared for the port to operate */
ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR));
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 55d306a..4a795fd 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -625,17 +625,18 @@ static int ich_pata_cable_detect(struct ata_port *ap)
/**
* piix_pata_prereset - prereset for PATA host controller
* @ap: Target port
+ * @deadline: deadline jiffies for the operation
*
* LOCKING:
* None (inherited from caller).
*/
-static int piix_pata_prereset(struct ata_port *ap)
+static int piix_pata_prereset(struct ata_port *ap, unsigned long deadline)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
+ return ata_std_prereset(ap, deadline);
}
static void piix_pata_error_handler(struct ata_port *ap)
@@ -644,7 +645,6 @@ static void piix_pata_error_handler(struct ata_port *ap)
ata_std_postreset);
}
-
static void piix_sata_error_handler(struct ata_port *ap)
{
ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index ca67484..a795088 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2979,23 +2979,71 @@ int ata_busy_sleep(struct ata_port *ap,
return 0;
}
-static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
+/**
+ * ata_wait_ready - sleep until BSY clears, or timeout
+ * @ap: port containing status register to be polled
+ * @deadline: deadline jiffies for the operation
+ *
+ * Sleep until ATA Status register bit BSY clears, or timeout
+ * occurs.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ata_wait_ready(struct ata_port *ap, unsigned long deadline)
+{
+ unsigned long start = jiffies;
+ int warned = 0;
+
+ while (1) {
+ u8 status = ata_chk_status(ap);
+ unsigned long now = jiffies;
+
+ if (!(status & ATA_BUSY))
+ return 0;
+ if (status == 0xff)
+ return -ENODEV;
+ if (time_after(now, deadline))
+ return -EBUSY;
+
+ if (!warned && time_after(now, start + 5 * HZ) &&
+ (deadline - now > 3 * HZ)) {
+ ata_port_printk(ap, KERN_WARNING,
+ "port is slow to respond, please be patient "
+ "(Status 0x%x)\n", status);
+ warned = 1;
+ }
+
+ msleep(50);
+ }
+}
+
+static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
+ unsigned long deadline)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int dev0 = devmask & (1 << 0);
unsigned int dev1 = devmask & (1 << 1);
- unsigned long timeout;
+ int rc, ret = 0;
/* if device 0 was found in ata_devchk, wait for its
* BSY bit to clear
*/
- if (dev0)
- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+ if (dev0) {
+ rc = ata_wait_ready(ap, deadline);
+ if (rc) {
+ if (rc != -ENODEV)
+ return rc;
+ ret = rc;
+ }
+ }
/* if device 1 was found in ata_devchk, wait for
* register access, then wait for BSY to clear
*/
- timeout = jiffies + ATA_TMOUT_BOOT;
while (dev1) {
u8 nsect, lbal;
@@ -3004,14 +3052,18 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
lbal = ioread8(ioaddr->lbal_addr);
if ((nsect == 1) && (lbal == 1))
break;
- if (time_after(jiffies, timeout)) {
- dev1 = 0;
- break;
- }
+ if (time_after(jiffies, deadline))
+ return -EBUSY;
msleep(50); /* give drive a breather */
}
- if (dev1)
- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+ if (dev1) {
+ rc = ata_wait_ready(ap, deadline);
+ if (rc) {
+ if (rc != -ENODEV)
+ return rc;
+ ret = rc;
+ }
+ }
/* is all this really necessary? */
ap->ops->dev_select(ap, 0);
@@ -3019,10 +3071,12 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
ap->ops->dev_select(ap, 1);
if (dev0)
ap->ops->dev_select(ap, 0);
+
+ return ret;
}
-static unsigned int ata_bus_softreset(struct ata_port *ap,
- unsigned int devmask)
+static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
+ unsigned long deadline)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
@@ -3052,11 +3106,9 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
* pulldown resistor.
*/
if (ata_check_status(ap) == 0xFF)
- return 0;
-
- ata_bus_post_reset(ap, devmask);
+ return -ENODEV;
- return 0;
+ return ata_bus_post_reset(ap, devmask, deadline);
}
/**
@@ -3085,6 +3137,7 @@ void ata_bus_reset(struct ata_port *ap)
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
u8 err;
unsigned int dev0, dev1 = 0, devmask = 0;
+ int rc;
DPRINTK("ENTER, host %u, port %u\n", ap->print_id, ap->port_no);
@@ -3106,9 +3159,11 @@ void ata_bus_reset(struct ata_port *ap)
ap->ops->dev_select(ap, 0);
/* issue bus reset */
- if (ap->flags & ATA_FLAG_SRST)
- if (ata_bus_softreset(ap, devmask))
+ if (ap->flags & ATA_FLAG_SRST) {
+ rc = ata_bus_softreset(ap, devmask, jiffies + 40 * HZ);
+ if (rc && rc != -ENODEV)
goto err_out;
+ }
/*
* determine by signature whether we have ATA or ATAPI devices
@@ -3150,29 +3205,37 @@ err_out:
* sata_phy_debounce - debounce SATA phy status
* @ap: ATA port to debounce SATA phy status for
* @params: timing parameters { interval, duratinon, timeout } in msec
+ * @deadline: deadline jiffies for the operation
*
* Make sure SStatus of @ap reaches stable state, determined by
* holding the same value where DET is not 1 for @duration polled
* every @interval, before @timeout. Timeout constraints the
- * beginning of the stable state. Because, after hot unplugging,
- * DET gets stuck at 1 on some controllers, this functions waits
+ * beginning of the stable state. Because DET gets stuck at 1 on
+ * some controllers after hot unplugging, this functions waits
* until timeout then returns 0 if DET is stable at 1.
*
+ * @timeout is further limited by @deadline. The sooner of the
+ * two is used.
+ *
* LOCKING:
* Kernel thread context (may sleep)
*
* RETURNS:
* 0 on success, -errno on failure.
*/
-int sata_phy_debounce(struct ata_port *ap, const unsigned long *params)
+int sata_phy_debounce(struct ata_port *ap, const unsigned long *params,
+ unsigned long deadline)
{
unsigned long interval_msec = params[0];
- unsigned long duration = params[1] * HZ / 1000;
- unsigned long timeout = jiffies + params[2] * HZ / 1000;
- unsigned long last_jiffies;
+ unsigned long duration = msecs_to_jiffies(params[1]);
+ unsigned long last_jiffies, t;
u32 last, cur;
int rc;
+ t = jiffies + msecs_to_jiffies(params[2]);
+ if (time_before(t, deadline))
+ deadline = t;
+
if ((rc = sata_scr_read(ap, SCR_STATUS, &cur)))
return rc;
cur &= 0xf;
@@ -3188,7 +3251,7 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params)
/* DET stable? */
if (cur == last) {
- if (cur == 1 && time_before(jiffies, timeout))
+ if (cur == 1 && time_before(jiffies, deadline))
continue;
if (time_after(jiffies, last_jiffies + duration))
return 0;
@@ -3199,8 +3262,8 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params)
last = cur;
last_jiffies = jiffies;
- /* check timeout */
- if (time_after(jiffies, timeout))
+ /* check deadline */
+ if (time_after(jiffies, deadline))
return -EBUSY;
}
}
@@ -3209,6 +3272,7 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params)
* sata_phy_resume - resume SATA phy
* @ap: ATA port to resume SATA phy for
* @params: timing parameters { interval, duratinon, timeout } in msec
+ * @deadline: deadline jiffies for the operation
*
* Resume SATA phy of @ap and debounce it.
*
@@ -3218,7 +3282,8 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params)
* RETURNS:
* 0 on success, -errno on failure.
*/
-int sata_phy_resume(struct ata_port *ap, const unsigned long *params)
+int sata_phy_resume(struct ata_port *ap, const unsigned long *params,
+ unsigned long deadline)
{
u32 scontrol;
int rc;
@@ -3236,43 +3301,19 @@ int sata_phy_resume(struct ata_port *ap, const unsigned long *params)
*/
msleep(200);
- return sata_phy_debounce(ap, params);
-}
-
-static void ata_wait_spinup(struct ata_port *ap)
-{
- struct ata_eh_context *ehc = &ap->eh_context;
- unsigned long end, secs;
- int rc;
-
- /* first, debounce phy if SATA */
- if (ap->cbl == ATA_CBL_SATA) {
- rc = sata_phy_debounce(ap, sata_deb_timing_hotplug);
-
- /* if debounced successfully and offline, no need to wait */
- if ((rc == 0 || rc == -EOPNOTSUPP) && ata_port_offline(ap))
- return;
- }
-
- /* okay, let's give the drive time to spin up */
- end = ehc->i.hotplug_timestamp + ATA_SPINUP_WAIT * HZ / 1000;
- secs = ((end - jiffies) + HZ - 1) / HZ;
-
- if (time_after(jiffies, end))
- return;
-
- if (secs > 5)
- ata_port_printk(ap, KERN_INFO, "waiting for device to spin up "
- "(%lu secs)\n", secs);
-
- schedule_timeout_uninterruptible(end - jiffies);
+ return sata_phy_debounce(ap, params, deadline);
}
/**
* ata_std_prereset - prepare for reset
* @ap: ATA port to be reset
+ * @deadline: deadline jiffies for the operation
*
- * @ap is about to be reset. Initialize it.
+ * @ap is about to be reset. Initialize it. Failure from
+ * prereset makes libata abort whole reset sequence and give up
+ * that port, so prereset should be best-effort. It does its
+ * best to prepare for reset sequence but if things go wrong, it
+ * should just whine, not fail.
*
* LOCKING:
* Kernel thread context (may sleep)
@@ -3280,41 +3321,41 @@ static void ata_wait_spinup(struct ata_port *ap)
* RETURNS:
* 0 on success, -errno otherwise.
*/
-int ata_std_prereset(struct ata_port *ap)
+int ata_std_prereset(struct ata_port *ap, unsigned long deadline)
{
struct ata_eh_context *ehc = &ap->eh_context;
const unsigned long *timing = sata_ehc_deb_timing(ehc);
int rc;
- /* handle link resume & hotplug spinup */
+ /* handle link resume */
if ((ehc->i.flags & ATA_EHI_RESUME_LINK) &&
(ap->flags & ATA_FLAG_HRST_TO_RESUME))
ehc->i.action |= ATA_EH_HARDRESET;
- if ((ehc->i.flags & ATA_EHI_HOTPLUGGED) &&
- (ap->flags & ATA_FLAG_SKIP_D2H_BSY))
- ata_wait_spinup(ap);
-
/* if we're about to do hardreset, nothing more to do */
if (ehc->i.action & ATA_EH_HARDRESET)
return 0;
/* if SATA, resume phy */
if (ap->cbl == ATA_CBL_SATA) {
- rc = sata_phy_resume(ap, timing);
- if (rc && rc != -EOPNOTSUPP) {
- /* phy resume failed */
+ rc = sata_phy_resume(ap, timing, deadline);
+ /* whine about phy resume failure but proceed */
+ if (rc && rc != -EOPNOTSUPP)
ata_port_printk(ap, KERN_WARNING, "failed to resume "
"link for reset (errno=%d)\n", rc);
- return rc;
- }
}
/* Wait for !BSY if the controller can wait for the first D2H
* Reg FIS and we don't know that no device is attached.
*/
- if (!(ap->flags & ATA_FLAG_SKIP_D2H_BSY) && !ata_port_offline(ap))
- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+ if (!(ap->flags & ATA_FLAG_SKIP_D2H_BSY) && !ata_port_offline(ap)) {
+ rc = ata_wait_ready(ap, deadline);
+ if (rc) {
+ ata_port_printk(ap, KERN_WARNING, "device not ready "
+ "(errno=%d), forcing hardreset\n", rc);
+ ehc->i.action |= ATA_EH_HARDRESET;
+ }
+ }
return 0;
}
@@ -3323,6 +3364,7 @@ int ata_std_prereset(struct ata_port *ap)
* ata_std_softreset - reset host port via ATA SRST
* @ap: port to reset
* @classes: resulting classes of attached devices
+ * @deadline: deadline jiffies for the operation
*
* Reset host port using ATA SRST.
*
@@ -3332,10 +3374,12 @@ int ata_std_prereset(struct ata_port *ap)
* RETURNS:
* 0 on success, -errno otherwise.
*/
-int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
+int ata_std_softreset(struct ata_port *ap, unsigned int *classes,
+ unsigned long deadline)
{
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
- unsigned int devmask = 0, err_mask;
+ unsigned int devmask = 0;
+ int rc;
u8 err;
DPRINTK("ENTER\n");
@@ -3356,11 +3400,11 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
/* issue bus reset */
DPRINTK("about to softreset, devmask=%x\n", devmask);
- err_mask = ata_bus_softreset(ap, devmask);
- if (err_mask) {
- ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n",
- err_mask);
- return -EIO;
+ rc = ata_bus_softreset(ap, devmask, deadline);
+ /* if link is occupied, -ENODEV too is an error */
+ if (rc && (rc != -ENODEV || sata_scr_valid(ap))) {
+ ata_port_printk(ap, KERN_ERR, "SRST failed (errno=%d)\n", rc);
+ return rc;
}
/* determine by signature whether we have ATA or ATAPI devices */
@@ -3377,6 +3421,7 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
* sata_port_hardreset - reset port via SATA phy reset
* @ap: port to reset
* @timing: timing parameters { interval, duratinon, timeout } in msec
+ * @deadline: deadline jiffies for the operation
*
* SATA phy-reset host port using DET bits of SControl register.
*
@@ -3386,7 +3431,8 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
* RETURNS:
* 0 on success, -errno otherwise.
*/
-int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing)
+int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing,
+ unsigned long deadline)
{
u32 scontrol;
int rc;
@@ -3425,7 +3471,7 @@ int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing)
msleep(1);
/* bring phy back */
- rc = sata_phy_resume(ap, timing);
+ rc = sata_phy_resume(ap, timing, deadline);
out:
DPRINTK("EXIT, rc=%d\n", rc);
return rc;
@@ -3435,6 +3481,7 @@ int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing)
* sata_std_hardreset - reset host port via SATA phy reset
* @ap: port to reset
* @class: resulting class of attached device
+ * @deadline: deadline jiffies for the operation
*
* SATA phy-reset host port using DET bits of SControl register,
* wait for !BSY and classify the attached device.
@@ -3445,7 +3492,8 @@ int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing)
* RETURNS:
* 0 on success, -errno otherwise.
*/
-int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
+int sata_std_hardreset(struct ata_port *ap, unsigned int *class,
+ unsigned long deadline)
{
const unsigned long *timing = sata_ehc_deb_timing(&ap->eh_context);
int rc;
@@ -3453,7 +3501,7 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
DPRINTK("ENTER\n");
/* do hardreset */
- rc = sata_port_hardreset(ap, timing);
+ rc = sata_port_hardreset(ap, timing, deadline);
if (rc) {
ata_port_printk(ap, KERN_ERR,
"COMRESET failed (errno=%d)\n", rc);
@@ -3470,10 +3518,12 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
/* wait a while before checking status, see SRST for more info */
msleep(150);
- if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
+ rc = ata_wait_ready(ap, deadline);
+ /* link occupied, -ENODEV too is an error */
+ if (rc) {
ata_port_printk(ap, KERN_ERR,
- "COMRESET failed (device not ready)\n");
- return -EIO;
+ "COMRESET failed (errno=%d)\n", rc);
+ return rc;
}
ap->ops->dev_select(ap, 0); /* probably unnecessary */
@@ -6793,6 +6843,7 @@ EXPORT_SYMBOL_GPL(ata_port_disable);
EXPORT_SYMBOL_GPL(ata_ratelimit);
EXPORT_SYMBOL_GPL(ata_wait_register);
EXPORT_SYMBOL_GPL(ata_busy_sleep);
+EXPORT_SYMBOL_GPL(ata_wait_ready);
EXPORT_SYMBOL_GPL(ata_port_queue_task);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 2bff9ad..8256655 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -50,6 +50,28 @@ enum {
ATA_EH_SPDN_FALLBACK_TO_PIO = (1 << 2),
};
+/* Waiting in ->prereset can never be reliable. It's sometimes nice
+ * to wait there but it can't be depended upon; otherwise, we wouldn't
+ * be resetting. Just give it enough time for most drives to spin up.
+ */
+enum {
+ ATA_EH_PRERESET_TIMEOUT = 10 * HZ,
+};
+
+/* The following table determines how we sequence resets. Each entry
+ * represents timeout for that try. The first try can be soft or
+ * hardreset. All others are hardreset if available. In most cases
+ * the first reset w/ 10sec timeout should succeed. Following entries
+ * are mostly for error handling, hotplug and retarded devices.
+ */
+static const unsigned long ata_eh_reset_timeouts[] = {
+ 10 * HZ, /* most drives spin up by 10sec */
+ 10 * HZ, /* > 99% working drives spin up before 20sec */
+ 35 * HZ, /* give > 30 secs of idleness for retarded devices */
+ 5 * HZ, /* and sweet one last chance */
+ /* > 1 min has elapsed, give up */
+};
+
static void __ata_port_freeze(struct ata_port *ap);
static void ata_eh_finish(struct ata_port *ap);
#ifdef CONFIG_PM
@@ -1558,14 +1580,14 @@ static void ata_eh_report(struct ata_port *ap)
}
static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
- unsigned int *classes)
+ unsigned int *classes, unsigned long deadline)
{
int i, rc;
for (i = 0; i < ATA_MAX_DEVICES; i++)
classes[i] = ATA_DEV_UNKNOWN;
- rc = reset(ap, classes);
+ rc = reset(ap, classes, deadline);
if (rc)
return rc;
@@ -1603,8 +1625,9 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
{
struct ata_eh_context *ehc = &ap->eh_context;
unsigned int *classes = ehc->classes;
- int tries = ATA_EH_RESET_TRIES;
int verbose = !(ehc->i.flags & ATA_EHI_QUIET);
+ int try = 0;
+ unsigned long deadline;
unsigned int action;
ata_reset_fn_t reset;
int i, did_followup_srst, rc;
@@ -1624,7 +1647,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
ehc->i.action |= ATA_EH_HARDRESET;
if (prereset) {
- rc = prereset(ap);
+ rc = prereset(ap, jiffies + ATA_EH_PRERESET_TIMEOUT);
if (rc) {
if (rc == -ENOENT) {
ata_port_printk(ap, KERN_DEBUG,
@@ -1665,6 +1688,8 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
}
retry:
+ deadline = jiffies + ata_eh_reset_timeouts[try++];
+
/* shut up during boot probing */
if (verbose)
ata_port_printk(ap, KERN_INFO, "%s resetting port\n",
@@ -1676,7 +1701,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
else
ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
- rc = ata_do_reset(ap, reset, classes);
+ rc = ata_do_reset(ap, reset, classes, deadline);
did_followup_srst = 0;
if (reset == hardreset &&
@@ -1693,7 +1718,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
}
ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK);
- rc = ata_do_reset(ap, reset, classes);
+ rc = ata_do_reset(ap, reset, classes, deadline);
if (rc == 0 && classify &&
classes[0] == ATA_DEV_UNKNOWN) {
@@ -1703,22 +1728,21 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
}
}
- if (rc && --tries) {
- const char *type;
+ if (rc && try < ARRAY_SIZE(ata_eh_reset_timeouts)) {
+ unsigned long now = jiffies;
- if (reset == softreset) {
- if (did_followup_srst)
- type = "follow-up soft";
- else
- type = "soft";
- } else
- type = "hard";
+ if (time_before(now, deadline)) {
+ unsigned long delta = deadline - jiffies;
- ata_port_printk(ap, KERN_WARNING,
- "%sreset failed, retrying in 5 secs\n", type);
- ssleep(5);
+ ata_port_printk(ap, KERN_WARNING, "reset failed "
+ "(errno=%d), retrying in %u secs\n",
+ rc, (jiffies_to_msecs(delta) + 999) / 1000);
+
+ schedule_timeout_uninterruptible(delta);
+ }
- if (reset == hardreset)
+ if (reset == hardreset &&
+ try == ARRAY_SIZE(ata_eh_reset_timeouts) - 1)
sata_down_spd_limit(ap);
if (hardreset)
reset = hardreset;
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 536ee89..67c7e87 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -121,12 +121,13 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse
/**
* amd_probe_init - perform reset handling
* @ap: ATA port
+ * @deadline: deadline jiffies for the operation
*
* Reset sequence checking enable bits to see which ports are
* active.
*/
-static int amd_pre_reset(struct ata_port *ap)
+static int amd_pre_reset(struct ata_port *ap, unsigned long deadline)
{
static const struct pci_bits amd_enable_bits[] = {
{ 0x40, 1, 0x02, 0x02 },
@@ -138,8 +139,7 @@ static int amd_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
-
+ return ata_std_prereset(ap, deadline);
}
static void amd_error_handler(struct ata_port *ap)
@@ -227,7 +227,8 @@ static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev)
* space for us.
*/
-static int nv_pre_reset(struct ata_port *ap) {
+static int nv_pre_reset(struct ata_port *ap, unsigned long deadline)
+{
static const struct pci_bits nv_enable_bits[] = {
{ 0x50, 1, 0x02, 0x02 },
{ 0x50, 1, 0x01, 0x01 }
@@ -238,7 +239,7 @@ static int nv_pre_reset(struct ata_port *ap) {
if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
+ return ata_std_prereset(ap, deadline);
}
static void nv_error_handler(struct ata_port *ap)
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 00e9ec3..ef51940 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -39,7 +39,7 @@
static int clock = 0;
-static int artop6210_pre_reset(struct ata_port *ap)
+static int artop6210_pre_reset(struct ata_port *ap, unsigned long deadline)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
const struct pci_bits artop_enable_bits[] = {
@@ -49,7 +49,8 @@ static int artop6210_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
+
+ return ata_std_prereset(ap, deadline);
}
/**
@@ -70,12 +71,13 @@ static void artop6210_error_handler(struct ata_port *ap)
/**
* artop6260_pre_reset - check for 40/80 pin
* @ap: Port
+ * @deadline: deadline jiffies for the operation
*
* The ARTOP hardware reports the cable detect bits in register 0x49.
* Nothing complicated needed here.
*/
-static int artop6260_pre_reset(struct ata_port *ap)
+static int artop6260_pre_reset(struct ata_port *ap, unsigned long deadline)
{
static const struct pci_bits artop_enable_bits[] = {
{ 0x4AU, 1U, 0x02UL, 0x02UL }, /* port 0 */
@@ -87,7 +89,8 @@ static int artop6260_pre_reset(struct ata_port *ap)
/* Odd numbered device ids are the units with enable bits (the -R cards) */
if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
+
+ return ata_std_prereset(ap, deadline);
}
/**
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 39c871a..2151538 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -33,7 +33,7 @@ enum {
ATIIXP_IDE_UDMA_MODE = 0x56
};
-static int atiixp_pre_reset(struct ata_port *ap)
+static int atiixp_pre_reset(struct ata_port *ap, unsigned long deadline)
{
static const struct pci_bits atiixp_enable_bits[] = {
{ 0x48, 1, 0x01, 0x00 },
@@ -44,7 +44,7 @@ static int atiixp_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
+ return ata_std_prereset(ap, deadline);
}
static void atiixp_error_handler(struct ata_port *ap)
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index 08cccc9..22006ae 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -72,6 +72,7 @@
/**
* cs5535_cable_detect - detect cable type
* @ap: Port to detect on
+ * @deadline: deadline jiffies for the operation
*
* Perform cable detection for ATA66 capable cable. Return a libata
* cable type.
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index a321685..d0f52e0 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -27,12 +27,13 @@
/**
* efar_pre_reset - Enable bits
* @ap: Port
+ * @deadline: deadline jiffies for the operation
*
* Perform cable detection for the EFAR ATA interface. This is
* different to the PIIX arrangement
*/
-static int efar_pre_reset(struct ata_port *ap)
+static int efar_pre_reset(struct ata_port *ap, unsigned long deadline)
{
static const struct pci_bits efar_enable_bits[] = {
{ 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */
@@ -43,7 +44,7 @@ static int efar_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
+ return ata_std_prereset(ap, deadline);
}
/**
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index 93cfa6d..e64e05e 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -220,7 +220,7 @@ static int hpt36x_cable_detect(struct ata_port *ap)
return ATA_CBL_PATA80;
}
-static int hpt36x_pre_reset(struct ata_port *ap)
+static int hpt36x_pre_reset(struct ata_port *ap, unsigned long deadline)
{
static const struct pci_bits hpt36x_enable_bits[] = {
{ 0x50, 1, 0x04, 0x04 },
@@ -231,7 +231,7 @@ static int hpt36x_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &hpt36x_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
+ return ata_std_prereset(ap, deadline);
}
/**
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 41d83129..1614e8c 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -307,11 +307,12 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)
/**
* hpt37x_pre_reset - reset the hpt37x bus
* @ap: ATA port to reset
+ * @deadline: deadline jiffies for the operation
*
* Perform the initial reset handling for the 370/372 and 374 func 0
*/
-static int hpt37x_pre_reset(struct ata_port *ap)
+static int hpt37x_pre_reset(struct ata_port *ap, unsigned long deadline)
{
u8 scr2, ata66;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
@@ -338,7 +339,7 @@ static int hpt37x_pre_reset(struct ata_port *ap)
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(100);
- return ata_std_prereset(ap);
+ return ata_std_prereset(ap, deadline);
}
/**
@@ -353,7 +354,7 @@ static void hpt37x_error_handler(struct ata_port *ap)
ata_bmdma_drive_eh(ap, hpt37x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
}
-static int hpt374_pre_reset(struct ata_port *ap)
+static int hpt374_pre_reset(struct ata_port *ap, unsigned long deadline)
{
static const struct pci_bits hpt37x_enable_bits[] = {
{ 0x50, 1, 0x04, 0x04 },
@@ -388,7 +389,7 @@ static int hpt374_pre_reset(struct ata_port *ap)
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(100);
- return ata_std_prereset(ap);
+ return ata_std_prereset(ap, deadline);
}
/**
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index 6a34521..ea1037d 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -148,13 +148,14 @@ static int hpt3x2n_cable_detect(struct ata_port *ap)
* Reset the hardware and state machine,
*/
-static int hpt3xn_pre_reset(struct ata_port *ap)
+static int hpt3xn_pre_reset(struct ata_port *ap, unsigned long deadline)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
/* Reset the state machine */
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(100);
- return ata_std_prereset(ap);
+
+ return ata_std_prereset(ap, deadline);
}
/**
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
new file mode 100644
index 0000000..dbc8ee2
--- /dev/null
+++ b/drivers/ata/pata_icside.c
@@ -0,0 +1,686 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <scsi/scsi_host.h>
+#include <linux/ata.h>
+#include <linux/libata.h>
+
+#include <asm/dma.h>
+#include <asm/ecard.h>
+
+#define DRV_NAME "pata_icside"
+
+#define ICS_IDENT_OFFSET 0x2280
+
+#define ICS_ARCIN_V5_INTRSTAT 0x0000
+#define ICS_ARCIN_V5_INTROFFSET 0x0004
+
+#define ICS_ARCIN_V6_INTROFFSET_1 0x2200
+#define ICS_ARCIN_V6_INTRSTAT_1 0x2290
+#define ICS_ARCIN_V6_INTROFFSET_2 0x3200
+#define ICS_ARCIN_V6_INTRSTAT_2 0x3290
+
+struct portinfo {
+ unsigned int dataoffset;
+ unsigned int ctrloffset;
+ unsigned int stepping;
+};
+
+static const struct portinfo pata_icside_portinfo_v5 = {
+ .dataoffset = 0x2800,
+ .ctrloffset = 0x2b80,
+ .stepping = 6,
+};
+
+static const struct portinfo pata_icside_portinfo_v6_1 = {
+ .dataoffset = 0x2000,
+ .ctrloffset = 0x2380,
+ .stepping = 6,
+};
+
+static const struct portinfo pata_icside_portinfo_v6_2 = {
+ .dataoffset = 0x3000,
+ .ctrloffset = 0x3380,
+ .stepping = 6,
+};
+
+#define PATA_ICSIDE_MAX_SG 128
+
+struct pata_icside_state {
+ void __iomem *irq_port;
+ void __iomem *ioc_base;
+ unsigned int type;
+ unsigned int dma;
+ struct {
+ u8 port_sel;
+ u8 disabled;
+ unsigned int speed[ATA_MAX_DEVICES];
+ } port[2];
+ struct scatterlist sg[PATA_ICSIDE_MAX_SG];
+};
+
+#define ICS_TYPE_A3IN 0
+#define ICS_TYPE_A3USER 1
+#define ICS_TYPE_V6 3
+#define ICS_TYPE_V5 15
+#define ICS_TYPE_NOTYPE ((unsigned int)-1)
+
+/* ---------------- Version 5 PCB Support Functions --------------------- */
+/* Prototype: pata_icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
+ * Purpose : enable interrupts from card
+ */
+static void pata_icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
+{
+ struct pata_icside_state *state = ec->irq_data;
+
+ writeb(0, state->irq_port + ICS_ARCIN_V5_INTROFFSET);
+}
+
+/* Prototype: pata_icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
+ * Purpose : disable interrupts from card
+ */
+static void pata_icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
+{
+ struct pata_icside_state *state = ec->irq_data;
+
+ readb(state->irq_port + ICS_ARCIN_V5_INTROFFSET);
+}
+
+static const expansioncard_ops_t pata_icside_ops_arcin_v5 = {
+ .irqenable = pata_icside_irqenable_arcin_v5,
+ .irqdisable = pata_icside_irqdisable_arcin_v5,
+};
+
+
+/* ---------------- Version 6 PCB Support Functions --------------------- */
+/* Prototype: pata_icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
+ * Purpose : enable interrupts from card
+ */
+static void pata_icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
+{
+ struct pata_icside_state *state = ec->irq_data;
+ void __iomem *base = state->irq_port;
+
+ if (!state->port[0].disabled)
+ writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
+ if (!state->port[1].disabled)
+ writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
+}
+
+/* Prototype: pata_icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
+ * Purpose : disable interrupts from card
+ */
+static void pata_icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
+{
+ struct pata_icside_state *state = ec->irq_data;
+
+ readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
+ readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
+}
+
+/* Prototype: pata_icside_irqprobe(struct expansion_card *ec)
+ * Purpose : detect an active interrupt from card
+ */
+static int pata_icside_irqpending_arcin_v6(struct expansion_card *ec)
+{
+ struct pata_icside_state *state = ec->irq_data;
+
+ return readb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 ||
+ readb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_2) & 1;
+}
+
+static const expansioncard_ops_t pata_icside_ops_arcin_v6 = {
+ .irqenable = pata_icside_irqenable_arcin_v6,
+ .irqdisable = pata_icside_irqdisable_arcin_v6,
+ .irqpending = pata_icside_irqpending_arcin_v6,
+};
+
+
+/*
+ * SG-DMA support.
+ *
+ * Similar to the BM-DMA, but we use the RiscPCs IOMD DMA controllers.
+ * There is only one DMA controller per card, which means that only
+ * one drive can be accessed at one time. NOTE! We do not enforce that
+ * here, but we rely on the main IDE driver spotting that both
+ * interfaces use the same IRQ, which should guarantee this.
+ */
+
+/*
+ * Configure the IOMD to give the appropriate timings for the transfer
+ * mode being requested. We take the advice of the ATA standards, and
+ * calculate the cycle time based on the transfer mode, and the EIDE
+ * MW DMA specs that the drive provides in the IDENTIFY command.
+ *
+ * We have the following IOMD DMA modes to choose from:
+ *
+ * Type Active Recovery Cycle
+ * A 250 (250) 312 (550) 562 (800)
+ * B 187 (200) 250 (550) 437 (750)
+ * C 125 (125) 125 (375) 250 (500)
+ * D 62 (50) 125 (375) 187 (425)
+ *
+ * (figures in brackets are actual measured timings on DIOR/DIOW)
+ *
+ * However, we also need to take care of the read/write active and
+ * recovery timings:
+ *
+ * Read Write
+ * Mode Active -- Recovery -- Cycle IOMD type
+ * MW0 215 50 215 480 A
+ * MW1 80 50 50 150 C
+ * MW2 70 25 25 120 C
+ */
+static void pata_icside_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+ struct pata_icside_state *state = ap->host->private_data;
+ struct ata_timing t;
+ unsigned int cycle;
+ char iomd_type;
+
+ /*
+ * DMA is based on a 16MHz clock
+ */
+ if (ata_timing_compute(adev, adev->dma_mode, &t, 1000, 1))
+ return;
+
+ /*
+ * Choose the IOMD cycle timing which ensure that the interface
+ * satisfies the measured active, recovery and cycle times.
+ */
+ if (t.active <= 50 && t.recover <= 375 && t.cycle <= 425)
+ iomd_type = 'D', cycle = 187;
+ else if (t.active <= 125 && t.recover <= 375 && t.cycle <= 500)
+ iomd_type = 'C', cycle = 250;
+ else if (t.active <= 200 && t.recover <= 550 && t.cycle <= 750)
+ iomd_type = 'B', cycle = 437;
+ else
+ iomd_type = 'A', cycle = 562;
+
+ ata_dev_printk(adev, KERN_INFO, "timings: act %dns rec %dns cyc %dns (%c)\n",
+ t.active, t.recover, t.cycle, iomd_type);
+
+ state->port[ap->port_no].speed[adev->devno] = cycle;
+}
+
+static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct pata_icside_state *state = ap->host->private_data;
+ struct scatterlist *sg, *rsg = state->sg;
+ unsigned int write = qc->tf.flags & ATA_TFLAG_WRITE;
+
+ /*
+ * We are simplex; BUG if we try to fiddle with DMA
+ * while it's active.
+ */
+ BUG_ON(dma_channel_active(state->dma));
+
+ /*
+ * Copy ATAs scattered sg list into a contiguous array of sg
+ */
+ ata_for_each_sg(sg, qc) {
+ memcpy(rsg, sg, sizeof(*sg));
+ rsg++;
+ }
+
+ /*
+ * Route the DMA signals to the correct interface
+ */
+ writeb(state->port[ap->port_no].port_sel, state->ioc_base);
+
+ set_dma_speed(state->dma, state->port[ap->port_no].speed[qc->dev->devno]);
+ set_dma_sg(state->dma, state->sg, rsg - state->sg);
+ set_dma_mode(state->dma, write ? DMA_MODE_WRITE : DMA_MODE_READ);
+
+ /* issue r/w command */
+ ap->ops->exec_command(ap, &qc->tf);
+}
+
+static void pata_icside_bmdma_start(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct pata_icside_state *state = ap->host->private_data;
+
+ BUG_ON(dma_channel_active(state->dma));
+ enable_dma(state->dma);
+}
+
+static void pata_icside_bmdma_stop(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct pata_icside_state *state = ap->host->private_data;
+
+ disable_dma(state->dma);
+
+ /* see ata_bmdma_stop */
+ ata_altstatus(ap);
+}
+
+static u8 pata_icside_bmdma_status(struct ata_port *ap)
+{
+ struct pata_icside_state *state = ap->host->private_data;
+ void __iomem *irq_port;
+
+ irq_port = state->irq_port + (ap->port_no ? ICS_ARCIN_V6_INTRSTAT_2 :
+ ICS_ARCIN_V6_INTRSTAT_1);
+
+ return readb(irq_port) & 1 ? ATA_DMA_INTR : 0;
+}
+
+static int icside_dma_init(struct ata_probe_ent *ae, struct expansion_card *ec)
+{
+ struct pata_icside_state *state = ae->private_data;
+ int i;
+
+ for (i = 0; i < ATA_MAX_DEVICES; i++) {
+ state->port[0].speed[i] = 480;
+ state->port[1].speed[i] = 480;
+ }
+
+ if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) {
+ state->dma = ec->dma;
+ ae->mwdma_mask = 0x07; /* MW0..2 */
+ }
+
+ return 0;
+}
+
+
+static int pata_icside_port_start(struct ata_port *ap)
+{
+ /* No PRD to alloc */
+ return ata_pad_alloc(ap, ap->dev);
+}
+
+static struct scsi_host_template pata_icside_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = PATA_ICSIDE_MAX_SG,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ~0, /* no dma boundaries */
+ .slave_configure = ata_scsi_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
+};
+
+/* wish this was exported from libata-core */
+static void ata_dummy_noret(struct ata_port *port)
+{
+}
+
+/*
+ * We need to shut down unused ports to prevent spurious interrupts.
+ * FIXME: the libata core doesn't call this function for PATA interfaces.
+ */
+static void pata_icside_port_disable(struct ata_port *ap)
+{
+ struct pata_icside_state *state = ap->host->private_data;
+
+ ata_port_printk(ap, KERN_ERR, "disabling icside port\n");
+
+ ata_port_disable(ap);
+
+ state->port[ap->port_no].disabled = 1;
+
+ if (state->type == ICS_TYPE_V6) {
+ /*
+ * Disable interrupts from this port, otherwise we
+ * receive spurious interrupts from the floating
+ * interrupt line.
+ */
+ void __iomem *irq_port = state->irq_port +
+ (ap->port_no ? ICS_ARCIN_V6_INTROFFSET_2 : ICS_ARCIN_V6_INTROFFSET_1);
+ readb(irq_port);
+ }
+}
+
+static u8 pata_icside_irq_ack(struct ata_port *ap, unsigned int chk_drq)
+{
+ unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
+ u8 status;
+
+ status = ata_busy_wait(ap, bits, 1000);
+ if (status & bits)
+ if (ata_msg_err(ap))
+ printk(KERN_ERR "abnormal status 0x%X\n", status);
+
+ if (ata_msg_intr(ap))
+ printk(KERN_INFO "%s: irq ack: drv_stat 0x%X\n",
+ __FUNCTION__, status);
+
+ return status;
+}
+
+static struct ata_port_operations pata_icside_port_ops = {
+ .port_disable = pata_icside_port_disable,
+
+ .set_dmamode = pata_icside_set_dmamode,
+
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .exec_command = ata_exec_command,
+ .check_status = ata_check_status,
+ .dev_select = ata_std_dev_select,
+
+ .bmdma_setup = pata_icside_bmdma_setup,
+ .bmdma_start = pata_icside_bmdma_start,
+
+ .data_xfer = ata_data_xfer_noirq,
+
+ /* no need to build any PRD tables for DMA */
+ .qc_prep = ata_noop_qc_prep,
+ .qc_issue = ata_qc_issue_prot,
+
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+ .error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = pata_icside_bmdma_stop,
+
+ .irq_handler = ata_interrupt,
+ .irq_clear = ata_dummy_noret,
+ .irq_on = ata_irq_on,
+ .irq_ack = pata_icside_irq_ack,
+
+ .port_start = pata_icside_port_start,
+
+ .bmdma_stop = pata_icside_bmdma_stop,
+ .bmdma_status = pata_icside_bmdma_status,
+};
+
+static void
+pata_icside_add_port(struct ata_probe_ent *ae, void __iomem *base,
+ const struct portinfo *info)
+{
+ struct ata_ioports *ioaddr = &ae->port[ae->n_ports++];
+ void __iomem *cmd = base + info->dataoffset;
+
+ ioaddr->cmd_addr = cmd;
+ ioaddr->data_addr = cmd + (ATA_REG_DATA << info->stepping);
+ ioaddr->error_addr = cmd + (ATA_REG_ERR << info->stepping);
+ ioaddr->feature_addr = cmd + (ATA_REG_FEATURE << info->stepping);
+ ioaddr->nsect_addr = cmd + (ATA_REG_NSECT << info->stepping);
+ ioaddr->lbal_addr = cmd + (ATA_REG_LBAL << info->stepping);
+ ioaddr->lbam_addr = cmd + (ATA_REG_LBAM << info->stepping);
+ ioaddr->lbah_addr = cmd + (ATA_REG_LBAH << info->stepping);
+ ioaddr->device_addr = cmd + (ATA_REG_DEVICE << info->stepping);
+ ioaddr->status_addr = cmd + (ATA_REG_STATUS << info->stepping);
+ ioaddr->command_addr = cmd + (ATA_REG_CMD << info->stepping);
+
+ ioaddr->ctl_addr = base + info->ctrloffset;
+ ioaddr->altstatus_addr = ioaddr->ctl_addr;
+}
+
+static int __init
+pata_icside_register_v5(struct ata_probe_ent *ae, struct expansion_card *ec)
+{
+ struct pata_icside_state *state = ae->private_data;
+ void __iomem *base;
+
+ base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
+ ecard_resource_len(ec, ECARD_RES_MEMC));
+ if (!base)
+ return -ENOMEM;
+
+ state->irq_port = base;
+
+ ec->irqaddr = base + ICS_ARCIN_V5_INTRSTAT;
+ ec->irqmask = 1;
+ ec->irq_data = state;
+ ec->ops = &pata_icside_ops_arcin_v5;
+
+ /*
+ * Be on the safe side - disable interrupts
+ */
+ ec->ops->irqdisable(ec, ec->irq);
+
+ pata_icside_add_port(ae, base, &pata_icside_portinfo_v5);
+
+ return 0;
+}
+
+static int __init
+pata_icside_register_v6(struct ata_probe_ent *ae, struct expansion_card *ec)
+{
+ struct pata_icside_state *state = ae->private_data;
+ void __iomem *ioc_base, *easi_base;
+ unsigned int sel = 0;
+ int ret;
+
+ ioc_base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST),
+ ecard_resource_len(ec, ECARD_RES_IOCFAST));
+ if (!ioc_base) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ easi_base = ioc_base;
+
+ if (ecard_resource_flags(ec, ECARD_RES_EASI)) {
+ easi_base = ioremap(ecard_resource_start(ec, ECARD_RES_EASI),
+ ecard_resource_len(ec, ECARD_RES_EASI));
+ if (!easi_base) {
+ ret = -ENOMEM;
+ goto unmap_slot;
+ }
+
+ /*
+ * Enable access to the EASI region.
+ */
+ sel = 1 << 5;
+ }
+
+ writeb(sel, ioc_base);
+
+ ec->irq_data = state;
+ ec->ops = &pata_icside_ops_arcin_v6;
+
+ state->irq_port = easi_base;
+ state->ioc_base = ioc_base;
+ state->port[0].port_sel = sel;
+ state->port[1].port_sel = sel | 1;
+
+ /*
+ * Be on the safe side - disable interrupts
+ */
+ ec->ops->irqdisable(ec, ec->irq);
+
+ /*
+ * Find and register the interfaces.
+ */
+ pata_icside_add_port(ae, easi_base, &pata_icside_portinfo_v6_1);
+ pata_icside_add_port(ae, easi_base, &pata_icside_portinfo_v6_2);
+
+ /*
+ * FIXME: work around libata's aversion to calling port_disable.
+ * This permanently disables interrupts on port 0 - bad luck if
+ * you have a drive on that port.
+ */
+ state->port[0].disabled = 1;
+
+ return icside_dma_init(ae, ec);
+
+ unmap_slot:
+ iounmap(ioc_base);
+ out:
+ return ret;
+}
+
+static int __devinit
+pata_icside_probe(struct expansion_card *ec, const struct ecard_id *id)
+{
+ struct pata_icside_state *state;
+ struct ata_probe_ent ae;
+ void __iomem *idmem;
+ int ret;
+
+ ret = ecard_request_resources(ec);
+ if (ret)
+ goto out;
+
+ state = kzalloc(sizeof(struct pata_icside_state), GFP_KERNEL);
+ if (!state) {
+ ret = -ENOMEM;
+ goto release;
+ }
+
+ state->type = ICS_TYPE_NOTYPE;
+ state->dma = NO_DMA;
+
+ idmem = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST),
+ ecard_resource_len(ec, ECARD_RES_IOCFAST));
+ if (idmem) {
+ unsigned int type;
+
+ type = readb(idmem + ICS_IDENT_OFFSET) & 1;
+ type |= (readb(idmem + ICS_IDENT_OFFSET + 4) & 1) << 1;
+ type |= (readb(idmem + ICS_IDENT_OFFSET + 8) & 1) << 2;
+ type |= (readb(idmem + ICS_IDENT_OFFSET + 12) & 1) << 3;
+ iounmap(idmem);
+
+ state->type = type;
+ }
+
+ memset(&ae, 0, sizeof(ae));
+ INIT_LIST_HEAD(&ae.node);
+ ae.dev = &ec->dev;
+ ae.port_ops = &pata_icside_port_ops;
+ ae.sht = &pata_icside_sht;
+ ae.pio_mask = 0x1f;
+ ae.irq = ec->irq;
+ ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
+ ae._host_flags = ATA_HOST_SIMPLEX;
+ ae.private_data = state;
+
+ switch (state->type) {
+ case ICS_TYPE_A3IN:
+ dev_warn(&ec->dev, "A3IN unsupported\n");
+ ret = -ENODEV;
+ break;
+
+ case ICS_TYPE_A3USER:
+ dev_warn(&ec->dev, "A3USER unsupported\n");
+ ret = -ENODEV;
+ break;
+
+ case ICS_TYPE_V5:
+ ret = pata_icside_register_v5(&ae, ec);
+ break;
+
+ case ICS_TYPE_V6:
+ ret = pata_icside_register_v6(&ae, ec);
+ break;
+
+ default:
+ dev_warn(&ec->dev, "unknown interface type\n");
+ ret = -ENODEV;
+ break;
+ }
+
+ if (ret == 0)
+ ret = ata_device_add(&ae) == 0 ? -ENODEV : 0;
+
+ if (ret == 0)
+ goto out;
+
+ kfree(state);
+ release:
+ ecard_release_resources(ec);
+ out:
+ return ret;
+}
+
+static void pata_icside_shutdown(struct expansion_card *ec)
+{
+ struct ata_host *host = ecard_get_drvdata(ec);
+ unsigned long flags;
+
+ /*
+ * Disable interrupts from this card. We need to do
+ * this before disabling EASI since we may be accessing
+ * this register via that region.
+ */
+ local_irq_save(flags);
+ if (ec->ops)
+ ec->ops->irqdisable(ec, ec->irq);
+ local_irq_restore(flags);
+
+ /*
+ * Reset the ROM pointer so that we can read the ROM
+ * after a soft reboot. This also disables access to
+ * the IDE taskfile via the EASI region.
+ */
+ if (host) {
+ struct pata_icside_state *state = host->private_data;
+ if (state->ioc_base)
+ writeb(0, state->ioc_base);
+ }
+}
+
+static void __devexit pata_icside_remove(struct expansion_card *ec)
+{
+ struct ata_host *host = ecard_get_drvdata(ec);
+ struct pata_icside_state *state = host->private_data;
+
+ ata_host_detach(host);
+
+ pata_icside_shutdown(ec);
+
+ /*
+ * don't NULL out the drvdata - devres/libata wants it
+ * to free the ata_host structure.
+ */
+ ec->ops = NULL;
+ ec->irq_data = NULL;
+
+ if (state->dma != NO_DMA)
+ free_dma(state->dma);
+ if (state->ioc_base)
+ iounmap(state->ioc_base);
+ if (state->ioc_base != state->irq_port)
+ iounmap(state->irq_port);
+
+ kfree(state);
+ ecard_release_resources(ec);
+}
+
+static const struct ecard_id pata_icside_ids[] = {
+ { MANU_ICS, PROD_ICS_IDE },
+ { MANU_ICS2, PROD_ICS2_IDE },
+ { 0xffff, 0xffff }
+};
+
+static struct ecard_driver pata_icside_driver = {
+ .probe = pata_icside_probe,
+ .remove = __devexit_p(pata_icside_remove),
+ .shutdown = pata_icside_shutdown,
+ .id_table = pata_icside_ids,
+ .drv = {
+ .name = DRV_NAME,
+ },
+};
+
+static int __init pata_icside_init(void)
+{
+ return ecard_register_driver(&pata_icside_driver);
+}
+
+static void __exit pata_icside_exit(void)
+{
+ ecard_remove_driver(&pata_icside_driver);
+}
+
+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ICS PATA driver");
+
+module_init(pata_icside_init);
+module_exit(pata_icside_exit);
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c
index 011306e..17bf9f3 100644
--- a/drivers/ata/pata_it8213.c
+++ b/drivers/ata/pata_it8213.c
@@ -24,12 +24,13 @@
/**
* it8213_pre_reset - check for 40/80 pin
* @ap: Port
+ * @deadline: deadline jiffies for the operation
*
* Filter out ports by the enable bits before doing the normal reset
* and probe.
*/
-static int it8213_pre_reset(struct ata_port *ap)
+static int it8213_pre_reset(struct ata_port *ap, unsigned long deadline)
{
static const struct pci_bits it8213_enable_bits[] = {
{ 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */
@@ -37,7 +38,8 @@ static int it8213_pre_reset(struct ata_port *ap)
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
if (!pci_test_config_bits(pdev, &it8213_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
+
+ return ata_std_prereset(ap, deadline);
}
/**
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 43763c9..1daf78a 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -30,16 +30,17 @@ typedef enum {
/**
* jmicron_pre_reset - check for 40/80 pin
* @ap: Port
+ * @deadline: deadline jiffies for the operation
*
* Perform the PATA port setup we need.
-
+ *
* On the Jmicron 361/363 there is a single PATA port that can be mapped
* either as primary or secondary (or neither). We don't do any policy
* and setup here. We assume that has been done by init_one and the
* BIOS.
*/
-static int jmicron_pre_reset(struct ata_port *ap)
+static int jmicron_pre_reset(struct ata_port *ap, unsigned long deadline)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u32 control;
@@ -102,7 +103,7 @@ static int jmicron_pre_reset(struct ata_port *ap)
ap->cbl = ATA_CBL_SATA;
break;
}
- return ata_std_prereset(ap);
+ return ata_std_prereset(ap, deadline);
}
/**
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index d9b94a1..837b7fe 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -25,11 +25,12 @@
/**
* marvell_pre_reset - check for 40/80 pin
* @ap: Port
+ * @deadline: deadline jiffies for the operation
*
* Perform the PATA port setup we need.
*/
-static int marvell_pre_reset(struct ata_port *ap)
+static int marvell_pre_reset(struct ata_port *ap, unsigned long deadline)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u32 devices;
@@ -52,7 +53,8 @@ static int marvell_pre_reset(struct ata_port *ap)
if ((pdev->device == 0x6145) && (ap->port_no == 0) &&
(!(devices & 0x10))) /* PATA enable ? */
return -ENOENT;
- return ata_std_prereset(ap);
+
+ return ata_std_prereset(ap, deadline);
}
static int marvell_cable_detect(struct ata_port *ap)
@@ -67,6 +69,7 @@ static int marvell_cable_detect(struct ata_port *ap)
case 1: /* Legacy SATA port */
return ATA_CBL_SATA;
}
+
BUG();
return 0; /* Our BUG macro needs the right markup */
}
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index 987c5fa..3bfbd49 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -46,14 +46,15 @@ enum {
SECONDARY = (1 << 14)
};
-static int mpiix_pre_reset(struct ata_port *ap)
+static int mpiix_pre_reset(struct ata_port *ap, unsigned long deadline)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
static const struct pci_bits mpiix_enable_bits = { 0x6D, 1, 0x80, 0x80 };
if (!pci_test_config_bits(pdev, &mpiix_enable_bits))
return -ENOENT;
- return ata_std_prereset(ap);
+
+ return ata_std_prereset(ap, deadline);
}
/**
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index 078aeda..ebc58a9 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -33,11 +33,12 @@
/**
* ns87410_pre_reset - probe begin
* @ap: ATA port
+ * @deadline: deadline jiffies for the operation
*
* Check enabled ports
*/
-static int ns87410_pre_reset(struct ata_port *ap)
+static int ns87410_pre_reset(struct ata_port *ap, unsigned long deadline)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
static const struct pci_bits ns87410_enable_bits[] = {
@@ -47,7 +48,8 @@ static int ns87410_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &ns87410_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
+
+ return ata_std_prereset(ap, deadline);
}
/**
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index dea4690..4d75d32 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -30,11 +30,12 @@
/**
* oldpiix_pre_reset - probe begin
* @ap: ATA port
+ * @deadline: deadline jiffies for the operation
*
* Set up cable type and use generic probe init
*/
-static int oldpiix_pre_reset(struct ata_port *ap)
+static int oldpiix_pre_reset(struct ata_port *ap, unsigned long deadline)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
static const struct pci_bits oldpiix_enable_bits[] = {
@@ -44,7 +45,8 @@ static int oldpiix_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
+
+ return ata_std_prereset(ap, deadline);
}
/**
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index 13b63e2..0af8a2c 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -47,11 +47,12 @@ enum {
/**
* opti_pre_reset - probe begin
* @ap: ATA port
+ * @deadline: deadline jiffies for the operation
*
* Set up cable type and use generic probe init
*/
-static int opti_pre_reset(struct ata_port *ap)
+static int opti_pre_reset(struct ata_port *ap, unsigned long deadline)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
static const struct pci_bits opti_enable_bits[] = {
@@ -61,7 +62,8 @@ static int opti_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &opti_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
+
+ return ata_std_prereset(ap, deadline);
}
/**
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index b70e04c..2843e48 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -48,11 +48,12 @@ static int pci_clock; /* 0 = 33 1 = 25 */
/**
* optidma_pre_reset - probe begin
* @ap: ATA port
+ * @deadline: deadline jiffies for the operation
*
* Set up cable type and use generic probe init
*/
-static int optidma_pre_reset(struct ata_port *ap)
+static int optidma_pre_reset(struct ata_port *ap, unsigned long deadline)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
static const struct pci_bits optidma_enable_bits = {
@@ -62,7 +63,7 @@ static int optidma_pre_reset(struct ata_port *ap)
if (ap->port_no && !pci_test_config_bits(pdev, &optidma_enable_bits))
return -ENOENT;
- return ata_std_prereset(ap);
+ return ata_std_prereset(ap, deadline);
}
/**
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index a61cbc1..0d2cc49 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -301,6 +301,7 @@ static inline int pdc2027x_port_enabled(struct ata_port *ap)
/**
* pdc2027x_prereset - prereset for PATA host controller
* @ap: Target port
+ * @deadline: deadline jiffies for the operation
*
* Probeinit including cable detection.
*
@@ -308,12 +309,12 @@ static inline int pdc2027x_port_enabled(struct ata_port *ap)
* None (inherited from caller).
*/
-static int pdc2027x_prereset(struct ata_port *ap)
+static int pdc2027x_prereset(struct ata_port *ap, unsigned long deadline)
{
/* Check whether port enabled */
if (!pdc2027x_port_enabled(ap))
return -ENOENT;
- return ata_std_prereset(ap);
+ return ata_std_prereset(ap, deadline);
}
/**
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index 3956ef2..b6e0203 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -139,12 +139,14 @@ static struct sv_cable_table cable_detect[] = {
/**
* serverworks_cable_detect - cable detection
* @ap: ATA port
+ * @deadline: deadline jiffies for the operation
*
* Perform cable detection according to the device and subvendor
* identifications
*/
-static int serverworks_cable_detect(struct ata_port *ap) {
+static int serverworks_cable_detect(struct ata_port *ap)
+{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
struct sv_cable_table *cb = cable_detect;
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 6770820..a5886f0 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -94,11 +94,13 @@ static int sil680_cable_detect(struct ata_port *ap) {
/**
* sil680_bus_reset - reset the SIL680 bus
* @ap: ATA port to reset
+ * @deadline: deadline jiffies for the operation
*
* Perform the SIL680 housekeeping when doing an ATA bus reset
*/
-static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes)
+static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes,
+ unsigned long deadline)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
unsigned long addr = sil680_selreg(ap, 0);
@@ -108,7 +110,7 @@ static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes)
pci_write_config_byte(pdev, addr, reset | 0x03);
udelay(25);
pci_write_config_byte(pdev, addr, reset);
- return ata_std_softreset(ap, classes);
+ return ata_std_softreset(ap, classes, deadline);
}
static void sil680_error_handler(struct ata_port *ap)
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index a3fbcee..f5838cc 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -88,6 +88,7 @@ static int sis_port_base(struct ata_device *adev)
/**
* sis_133_cable_detect - check for 40/80 pin
* @ap: Port
+ * @deadline: deadline jiffies for the operation
*
* Perform cable detection for the later UDMA133 capable
* SiS chipset.
@@ -108,6 +109,7 @@ static int sis_133_cable_detect(struct ata_port *ap)
/**
* sis_66_cable_detect - check for 40/80 pin
* @ap: Port
+ * @deadline: deadline jiffies for the operation
*
* Perform cable detection on the UDMA66, UDMA100 and early UDMA133
* SiS IDE controllers.
@@ -130,11 +132,12 @@ static int sis_66_cable_detect(struct ata_port *ap)
/**
* sis_pre_reset - probe begin
* @ap: ATA port
+ * @deadline: deadline jiffies for the operation
*
* Set up cable type and use generic probe init
*/
-static int sis_pre_reset(struct ata_port *ap)
+static int sis_pre_reset(struct ata_port *ap, unsigned long deadline)
{
static const struct pci_bits sis_enable_bits[] = {
{ 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */
@@ -145,7 +148,8 @@ static int sis_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
+
+ return ata_std_prereset(ap, deadline);
}
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index da9e22b..9aeffdb 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -44,11 +44,12 @@ enum {
/**
* sl82c105_pre_reset - probe begin
* @ap: ATA port
+ * @deadline: deadline jiffies for the operation
*
* Set up cable type and use generic probe init
*/
-static int sl82c105_pre_reset(struct ata_port *ap)
+static int sl82c105_pre_reset(struct ata_port *ap, unsigned long deadline)
{
static const struct pci_bits sl82c105_enable_bits[] = {
{ 0x40, 1, 0x01, 0x01 },
@@ -58,7 +59,7 @@ static int sl82c105_pre_reset(struct ata_port *ap)
if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
+ return ata_std_prereset(ap, deadline);
}
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index e618ffd..349887b 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -48,11 +48,12 @@
/**
* triflex_prereset - probe begin
* @ap: ATA port
+ * @deadline: deadline jiffies for the operation
*
* Set up cable type and use generic probe init
*/
-static int triflex_prereset(struct ata_port *ap)
+static int triflex_prereset(struct ata_port *ap, unsigned long deadline)
{
static const struct pci_bits triflex_enable_bits[] = {
{ 0x80, 1, 0x01, 0x01 },
@@ -63,7 +64,8 @@ static int triflex_prereset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(ap);
+
+ return ata_std_prereset(ap, deadline);
}
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 96b7179..362beb2 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -154,7 +154,7 @@ static int via_cable_detect(struct ata_port *ap) {
return ATA_CBL_PATA40;
}
-static int via_pre_reset(struct ata_port *ap)
+static int via_pre_reset(struct ata_port *ap, unsigned long deadline)
{
const struct via_isa_bridge *config = ap->host->private_data;
@@ -167,7 +167,8 @@ static int via_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &via_enable_bits[ap->port_no]))
return -ENOENT;
}
- return ata_std_prereset(ap);
+
+ return ata_std_prereset(ap, deadline);
}
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index f099a1d..b3b62e9 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -420,7 +420,8 @@ static void inic_thaw(struct ata_port *ap)
* SRST and SControl hardreset don't give valid signature on this
* controller. Only controller specific hardreset mechanism works.
*/
-static int inic_hardreset(struct ata_port *ap, unsigned int *class)
+static int inic_hardreset(struct ata_port *ap, unsigned int *class,
+ unsigned long deadline)
{
void __iomem *port_base = inic_port_base(ap);
void __iomem *idma_ctl = port_base + PORT_IDMA_CTL;
@@ -437,7 +438,7 @@ static int inic_hardreset(struct ata_port *ap, unsigned int *class)
msleep(1);
writew(val & ~IDMA_CTL_RST_ATA, idma_ctl);
- rc = sata_phy_resume(ap, timing);
+ rc = sata_phy_resume(ap, timing, deadline);
if (rc) {
ata_port_printk(ap, KERN_WARNING, "failed to resume "
"link after reset (errno=%d)\n", rc);
@@ -451,10 +452,12 @@ static int inic_hardreset(struct ata_port *ap, unsigned int *class)
/* wait a while before checking status */
msleep(150);
- if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
- ata_port_printk(ap, KERN_WARNING,
- "device busy after hardreset\n");
- return -EIO;
+ rc = ata_wait_ready(ap, deadline);
+ /* link occupied, -ENODEV too is an error */
+ if (rc) {
+ ata_port_printk(ap, KERN_WARNING, "device not ready "
+ "after hardreset (errno=%d)\n", rc);
+ return rc;
}
ata_tf_read(ap, &tf);
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 0216974..e2e795e 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1405,7 +1405,8 @@ static void nv_ck804_thaw(struct ata_port *ap)
writeb(mask, mmio_base + NV_INT_ENABLE_CK804);
}
-static int nv_hardreset(struct ata_port *ap, unsigned int *class)
+static int nv_hardreset(struct ata_port *ap, unsigned int *class,
+ unsigned long deadline)
{
unsigned int dummy;
@@ -1413,7 +1414,7 @@ static int nv_hardreset(struct ata_port *ap, unsigned int *class)
* some controllers. Don't classify on hardreset. For more
* info, see http://bugme.osdl.org/show_bug.cgi?id=3352
*/
- return sata_std_hardreset(ap, &dummy);
+ return sata_std_hardreset(ap, &dummy, deadline);
}
static void nv_error_handler(struct ata_port *ap)
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index e6223ba..b97ee9f 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -534,7 +534,8 @@ static int sil24_init_port(struct ata_port *ap)
return 0;
}
-static int sil24_softreset(struct ata_port *ap, unsigned int *class)
+static int sil24_softreset(struct ata_port *ap, unsigned int *class,
+ unsigned long deadline)
{
void __iomem *port = ap->ioaddr.cmd_addr;
struct sil24_port_priv *pp = ap->private_data;
@@ -566,7 +567,7 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class)
mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT;
irq_stat = ata_wait_register(port + PORT_IRQ_STAT, mask, 0x0,
- 100, ATA_TMOUT_BOOT / HZ * 1000);
+ 100, jiffies_to_msecs(deadline - jiffies));
writel(irq_stat, port + PORT_IRQ_STAT); /* clear IRQs */
irq_stat >>= PORT_IRQ_RAW_SHIFT;
@@ -594,7 +595,8 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class)
return -EIO;
}
-static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
+static int sil24_hardreset(struct ata_port *ap, unsigned int *class,
+ unsigned long deadline)
{
void __iomem *port = ap->ioaddr.cmd_addr;
const char *reason;
@@ -615,7 +617,7 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
/* SStatus oscillates between zero and valid status after
* DEV_RST, debounce it.
*/
- rc = sata_phy_debounce(ap, sata_deb_timing_long);
+ rc = sata_phy_debounce(ap, sata_deb_timing_long, deadline);
if (rc) {
reason = "PHY debouncing failed";
goto err;
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index cc07aac..1724673 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -288,7 +288,7 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start,
/* Match it to a port node */
index = (ap == ap->host->ports[0]) ? 0 : 1;
for (np = np->child; np != NULL; np = np->sibling) {
- const u32 *reg = get_property(np, "reg", NULL);
+ const u32 *reg = of_get_property(np, "reg", NULL);
if (!reg)
continue;
if (index == *reg)
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 1d855f5..305ab7c 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -268,6 +268,7 @@ static void svia_noop_freeze(struct ata_port *ap)
/**
* vt6420_prereset - prereset for vt6420
* @ap: target ATA port
+ * @deadline: deadline jiffies for the operation
*
* SCR registers on vt6420 are pieces of shit and may hang the
* whole machine completely if accessed with the wrong timing.
@@ -284,7 +285,7 @@ static void svia_noop_freeze(struct ata_port *ap)
* RETURNS:
* 0 on success, -errno otherwise.
*/
-static int vt6420_prereset(struct ata_port *ap)
+static int vt6420_prereset(struct ata_port *ap, unsigned long deadline)
{
struct ata_eh_context *ehc = &ap->eh_context;
unsigned long timeout = jiffies + (HZ * 5);
@@ -329,7 +330,7 @@ static int vt6420_prereset(struct ata_port *ap)
skip_scr:
/* wait for !BSY */
- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+ ata_wait_ready(ap, deadline);
return 0;
}
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index e9eb738..b39ea3f 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -2,10 +2,10 @@
obj-y := core.o sys.o bus.o dd.o \
driver.o class.o platform.o \
- cpu.o firmware.o init.o map.o dmapool.o \
- dma-mapping.o devres.o \
+ cpu.o firmware.o init.o map.o devres.o \
attribute_container.o transport_class.o
obj-y += power/
+obj-$(CONFIG_HAS_DMA) += dma-mapping.o dmapool.o
obj-$(CONFIG_ISA) += isa.o
obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 17b5ece..eb84d9d 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -160,6 +160,11 @@ static void platform_device_release(struct device *dev)
*
* Create a platform device object which can have other objects attached
* to it, and which will have attached objects freed when it is released.
+ *
+ * This device will be marked as not supporting hotpluggable drivers; no
+ * device add/remove uevents will be generated. In the unusual case that
+ * the device isn't being dynamically allocated as a legacy "probe the
+ * hardware" driver, infrastructure code should reverse this marking.
*/
struct platform_device *platform_device_alloc(const char *name, unsigned int id)
{
@@ -172,6 +177,12 @@ struct platform_device *platform_device_alloc(const char *name, unsigned int id)
pa->pdev.id = id;
device_initialize(&pa->pdev.dev);
pa->pdev.dev.release = platform_device_release;
+
+ /* prevent hotplug "modprobe $(MODALIAS)" from causing trouble in
+ * legacy probe-the-hardware drivers, which don't properly split
+ * out device enumeration logic from drivers.
+ */
+ pa->pdev.dev.uevent_suppress = 1;
}
return pa ? &pa->pdev : NULL;
@@ -351,6 +362,13 @@ EXPORT_SYMBOL_GPL(platform_device_unregister);
* memory allocated for the device allows drivers using such devices
* to be unloaded iwithout waiting for the last reference to the device
* to be dropped.
+ *
+ * This interface is primarily intended for use with legacy drivers
+ * which probe hardware directly. Because such drivers create sysfs
+ * device nodes themselves, rather than letting system infrastructure
+ * handle such device enumeration tasks, they don't fully conform to
+ * the Linux driver model. In particular, when such drivers are built
+ * as modules, they can't be "hotplugged".
*/
struct platform_device *platform_device_register_simple(char *name, unsigned int id,
struct resource *res, unsigned int num)
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
index e2e0432..1d9d9b4 100644
--- a/drivers/block/acsi_slm.c
+++ b/drivers/block/acsi_slm.c
@@ -65,7 +65,6 @@ not be guaranteed. There are several ways to assure this:
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <asm/pgtable.h>
#include <asm/system.h>
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 5d65621..27a1390 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1480,7 +1480,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
break;
case FDFMTEND:
floppy_off(drive);
- invalidate_bdev(inode->i_bdev, 0);
+ invalidate_bdev(inode->i_bdev);
break;
case FDGETPRM:
memset((void *)&getprm, 0, sizeof (getprm));
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 65a725c..370dfe1 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -45,6 +45,10 @@
#include <linux/blkdev.h>
#include <linux/genhd.h>
#include <linux/completion.h>
+#include <scsi/scsi.h>
+#include <scsi/sg.h>
+#include <scsi/scsi_ioctl.h>
+#include <linux/cdrom.h>
#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
#define DRIVER_NAME "HP CISS Driver (v 3.6.14)"
@@ -1152,6 +1156,30 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
kfree(ioc);
return status;
}
+
+ /* scsi_cmd_ioctl handles these, below, though some are not */
+ /* very meaningful for cciss. SG_IO is the main one people want. */
+
+ case SG_GET_VERSION_NUM:
+ case SG_SET_TIMEOUT:
+ case SG_GET_TIMEOUT:
+ case SG_GET_RESERVED_SIZE:
+ case SG_SET_RESERVED_SIZE:
+ case SG_EMULATED_HOST:
+ case SG_IO:
+ case SCSI_IOCTL_SEND_COMMAND:
+ return scsi_cmd_ioctl(filep, disk, cmd, argp);
+
+ /* scsi_cmd_ioctl would normally handle these, below, but */
+ /* they aren't a good fit for cciss, as CD-ROMs are */
+ /* not supported, and we don't have any bus/target/lun */
+ /* which we present to the kernel. */
+
+ case CDROM_SEND_PACKET:
+ case CDROMCLOSETRAY:
+ case CDROMEJECT:
+ case SCSI_IOCTL_GET_IDLUN:
+ case SCSI_IOCTL_GET_BUS_NUMBER:
default:
return -ENOTTY;
}
@@ -1234,7 +1262,7 @@ static void cciss_softirq_done(struct request *rq)
pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir);
}
- complete_buffers(rq->bio, rq->errors);
+ complete_buffers(rq->bio, (rq->errors == 0));
if (blk_fs_request(rq)) {
const int rw = rq_data_dir(rq);
@@ -1248,7 +1276,7 @@ static void cciss_softirq_done(struct request *rq)
add_disk_randomness(rq->rq_disk);
spin_lock_irqsave(&h->lock, flags);
- end_that_request_last(rq, rq->errors);
+ end_that_request_last(rq, (rq->errors == 0));
cmd_free(h, cmd, 1);
cciss_check_queues(h);
spin_unlock_irqrestore(&h->lock, flags);
@@ -2336,6 +2364,44 @@ static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c)
start_io(h);
}
+static inline int evaluate_target_status(CommandList_struct *cmd)
+{
+ unsigned char sense_key;
+ int error_count = 1;
+
+ if (cmd->err_info->ScsiStatus != 0x02) { /* not check condition? */
+ if (!blk_pc_request(cmd->rq))
+ printk(KERN_WARNING "cciss: cmd %p "
+ "has SCSI Status 0x%x\n",
+ cmd, cmd->err_info->ScsiStatus);
+ return error_count;
+ }
+
+ /* check the sense key */
+ sense_key = 0xf & cmd->err_info->SenseInfo[2];
+ /* no status or recovered error */
+ if ((sense_key == 0x0) || (sense_key == 0x1))
+ error_count = 0;
+
+ if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */
+ if (error_count != 0)
+ printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION"
+ " sense key = 0x%x\n", cmd, sense_key);
+ return error_count;
+ }
+
+ /* SG_IO or similar, copy sense data back */
+ if (cmd->rq->sense) {
+ if (cmd->rq->sense_len > cmd->err_info->SenseLen)
+ cmd->rq->sense_len = cmd->err_info->SenseLen;
+ memcpy(cmd->rq->sense, cmd->err_info->SenseInfo,
+ cmd->rq->sense_len);
+ } else
+ cmd->rq->sense_len = 0;
+
+ return error_count;
+}
+
/* checks the status of the job and calls complete buffers to mark all
* buffers for the completed job. Note that this function does not need
* to hold the hba/queue lock.
@@ -2343,109 +2409,99 @@ static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c)
static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
int timeout)
{
- int status = 1;
int retry_cmd = 0;
+ struct request *rq = cmd->rq;
+
+ rq->errors = 0;
if (timeout)
- status = 0;
+ rq->errors = 1;
- if (cmd->err_info->CommandStatus != 0) { /* an error has occurred */
- switch (cmd->err_info->CommandStatus) {
- unsigned char sense_key;
- case CMD_TARGET_STATUS:
- status = 0;
+ if (cmd->err_info->CommandStatus == 0) /* no error has occurred */
+ goto after_error_processing;
- if (cmd->err_info->ScsiStatus == 0x02) {
- printk(KERN_WARNING "cciss: cmd %p "
- "has CHECK CONDITION "
- " byte 2 = 0x%x\n", cmd,
- cmd->err_info->SenseInfo[2]
- );
- /* check the sense key */
- sense_key = 0xf & cmd->err_info->SenseInfo[2];
- /* no status or recovered error */
- if ((sense_key == 0x0) || (sense_key == 0x1)) {
- status = 1;
- }
- } else {
- printk(KERN_WARNING "cciss: cmd %p "
- "has SCSI Status 0x%x\n",
- cmd, cmd->err_info->ScsiStatus);
- }
- break;
- case CMD_DATA_UNDERRUN:
+ switch (cmd->err_info->CommandStatus) {
+ case CMD_TARGET_STATUS:
+ rq->errors = evaluate_target_status(cmd);
+ break;
+ case CMD_DATA_UNDERRUN:
+ if (blk_fs_request(cmd->rq)) {
printk(KERN_WARNING "cciss: cmd %p has"
" completed with data underrun "
"reported\n", cmd);
- break;
- case CMD_DATA_OVERRUN:
+ cmd->rq->data_len = cmd->err_info->ResidualCnt;
+ }
+ break;
+ case CMD_DATA_OVERRUN:
+ if (blk_fs_request(cmd->rq))
printk(KERN_WARNING "cciss: cmd %p has"
" completed with data overrun "
"reported\n", cmd);
- break;
- case CMD_INVALID:
- printk(KERN_WARNING "cciss: cmd %p is "
- "reported invalid\n", cmd);
- status = 0;
- break;
- case CMD_PROTOCOL_ERR:
- printk(KERN_WARNING "cciss: cmd %p has "
- "protocol error \n", cmd);
- status = 0;
- break;
- case CMD_HARDWARE_ERR:
- printk(KERN_WARNING "cciss: cmd %p had "
- " hardware error\n", cmd);
- status = 0;
- break;
- case CMD_CONNECTION_LOST:
- printk(KERN_WARNING "cciss: cmd %p had "
- "connection lost\n", cmd);
- status = 0;
- break;
- case CMD_ABORTED:
- printk(KERN_WARNING "cciss: cmd %p was "
- "aborted\n", cmd);
- status = 0;
- break;
- case CMD_ABORT_FAILED:
- printk(KERN_WARNING "cciss: cmd %p reports "
- "abort failed\n", cmd);
- status = 0;
- break;
- case CMD_UNSOLICITED_ABORT:
- printk(KERN_WARNING "cciss%d: unsolicited "
- "abort %p\n", h->ctlr, cmd);
- if (cmd->retry_count < MAX_CMD_RETRIES) {
- retry_cmd = 1;
- printk(KERN_WARNING
- "cciss%d: retrying %p\n", h->ctlr, cmd);
- cmd->retry_count++;
- } else
- printk(KERN_WARNING
- "cciss%d: %p retried too "
- "many times\n", h->ctlr, cmd);
- status = 0;
- break;
- case CMD_TIMEOUT:
- printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd);
- status = 0;
- break;
- default:
- printk(KERN_WARNING "cciss: cmd %p returned "
- "unknown status %x\n", cmd,
- cmd->err_info->CommandStatus);
- status = 0;
- }
+ break;
+ case CMD_INVALID:
+ printk(KERN_WARNING "cciss: cmd %p is "
+ "reported invalid\n", cmd);
+ rq->errors = 1;
+ break;
+ case CMD_PROTOCOL_ERR:
+ printk(KERN_WARNING "cciss: cmd %p has "
+ "protocol error \n", cmd);
+ rq->errors = 1;
+ break;
+ case CMD_HARDWARE_ERR:
+ printk(KERN_WARNING "cciss: cmd %p had "
+ " hardware error\n", cmd);
+ rq->errors = 1;
+ break;
+ case CMD_CONNECTION_LOST:
+ printk(KERN_WARNING "cciss: cmd %p had "
+ "connection lost\n", cmd);
+ rq->errors = 1;
+ break;
+ case CMD_ABORTED:
+ printk(KERN_WARNING "cciss: cmd %p was "
+ "aborted\n", cmd);
+ rq->errors = 1;
+ break;
+ case CMD_ABORT_FAILED:
+ printk(KERN_WARNING "cciss: cmd %p reports "
+ "abort failed\n", cmd);
+ rq->errors = 1;
+ break;
+ case CMD_UNSOLICITED_ABORT:
+ printk(KERN_WARNING "cciss%d: unsolicited "
+ "abort %p\n", h->ctlr, cmd);
+ if (cmd->retry_count < MAX_CMD_RETRIES) {
+ retry_cmd = 1;
+ printk(KERN_WARNING
+ "cciss%d: retrying %p\n", h->ctlr, cmd);
+ cmd->retry_count++;
+ } else
+ printk(KERN_WARNING
+ "cciss%d: %p retried too "
+ "many times\n", h->ctlr, cmd);
+ rq->errors = 1;
+ break;
+ case CMD_TIMEOUT:
+ printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd);
+ rq->errors = 1;
+ break;
+ default:
+ printk(KERN_WARNING "cciss: cmd %p returned "
+ "unknown status %x\n", cmd,
+ cmd->err_info->CommandStatus);
+ rq->errors = 1;
}
+
+after_error_processing:
+
/* We need to return this command */
if (retry_cmd) {
resend_cciss_cmd(h, cmd);
return;
}
-
+ cmd->rq->data_len = 0;
cmd->rq->completion_data = cmd;
- cmd->rq->errors = status;
blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE);
blk_complete_request(cmd->rq);
}
@@ -2539,32 +2595,40 @@ static void do_cciss_request(request_queue_t *q)
#endif /* CCISS_DEBUG */
c->Header.SGList = c->Header.SGTotal = seg;
- if(h->cciss_read == CCISS_READ_10) {
- c->Request.CDB[1] = 0;
- c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB
- c->Request.CDB[3] = (start_blk >> 16) & 0xff;
- c->Request.CDB[4] = (start_blk >> 8) & 0xff;
- c->Request.CDB[5] = start_blk & 0xff;
- c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB
- c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff;
- c->Request.CDB[8] = creq->nr_sectors & 0xff;
- c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
+ if (likely(blk_fs_request(creq))) {
+ if(h->cciss_read == CCISS_READ_10) {
+ c->Request.CDB[1] = 0;
+ c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB
+ c->Request.CDB[3] = (start_blk >> 16) & 0xff;
+ c->Request.CDB[4] = (start_blk >> 8) & 0xff;
+ c->Request.CDB[5] = start_blk & 0xff;
+ c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB
+ c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff;
+ c->Request.CDB[8] = creq->nr_sectors & 0xff;
+ c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
+ } else {
+ c->Request.CDBLen = 16;
+ c->Request.CDB[1]= 0;
+ c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB
+ c->Request.CDB[3]= (start_blk >> 48) & 0xff;
+ c->Request.CDB[4]= (start_blk >> 40) & 0xff;
+ c->Request.CDB[5]= (start_blk >> 32) & 0xff;
+ c->Request.CDB[6]= (start_blk >> 24) & 0xff;
+ c->Request.CDB[7]= (start_blk >> 16) & 0xff;
+ c->Request.CDB[8]= (start_blk >> 8) & 0xff;
+ c->Request.CDB[9]= start_blk & 0xff;
+ c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff;
+ c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff;
+ c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff;
+ c->Request.CDB[13]= creq->nr_sectors & 0xff;
+ c->Request.CDB[14] = c->Request.CDB[15] = 0;
+ }
+ } else if (blk_pc_request(creq)) {
+ c->Request.CDBLen = creq->cmd_len;
+ memcpy(c->Request.CDB, creq->cmd, BLK_MAX_CDB);
} else {
- c->Request.CDBLen = 16;
- c->Request.CDB[1]= 0;
- c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB
- c->Request.CDB[3]= (start_blk >> 48) & 0xff;
- c->Request.CDB[4]= (start_blk >> 40) & 0xff;
- c->Request.CDB[5]= (start_blk >> 32) & 0xff;
- c->Request.CDB[6]= (start_blk >> 24) & 0xff;
- c->Request.CDB[7]= (start_blk >> 16) & 0xff;
- c->Request.CDB[8]= (start_blk >> 8) & 0xff;
- c->Request.CDB[9]= start_blk & 0xff;
- c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff;
- c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff;
- c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff;
- c->Request.CDB[13]= creq->nr_sectors & 0xff;
- c->Request.CDB[14] = c->Request.CDB[15] = 0;
+ printk(KERN_WARNING "cciss%d: bad request type %d\n", h->ctlr, creq->cmd_type);
+ BUG();
}
spin_lock_irq(q->queue_lock);
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index bb15051..90961a8 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -35,7 +35,6 @@
#include <asm/atomic.h>
-#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 5231ed7..3587cb4 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4334,7 +4334,10 @@ static int __init floppy_init(void)
if (err)
goto out_flush_work;
- device_create_file(&floppy_device[drive].dev,&dev_attr_cmos);
+ err = device_create_file(&floppy_device[drive].dev,&dev_attr_cmos);
+ if (err)
+ goto out_unreg_platform_dev;
+
/* to be cleaned up... */
disks[drive]->private_data = (void *)(long)drive;
disks[drive]->queue = floppy_queue;
@@ -4345,6 +4348,8 @@ static int __init floppy_init(void)
return 0;
+out_unreg_platform_dev:
+ platform_device_unregister(&floppy_device[drive]);
out_flush_work:
flush_scheduled_work();
if (usage_count)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 6b5b642..af6d727 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -77,9 +77,8 @@
#include <asm/uaccess.h>
-static int max_loop = 8;
-static struct loop_device *loop_dev;
-static struct gendisk **disks;
+static LIST_HEAD(loop_devices);
+static DEFINE_MUTEX(loop_devices_mutex);
/*
* Transfer functions
@@ -183,7 +182,7 @@ figure_loop_size(struct loop_device *lo)
if (unlikely((loff_t)x != size))
return -EFBIG;
- set_capacity(disks[lo->lo_number], x);
+ set_capacity(lo->lo_disk, x);
return 0;
}
@@ -812,7 +811,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
lo->lo_queue->queuedata = lo;
lo->lo_queue->unplug_fn = loop_unplug;
- set_capacity(disks[lo->lo_number], size);
+ set_capacity(lo->lo_disk, size);
bd_set_size(bdev, size << 9);
set_blocksize(bdev, lo_blocksize);
@@ -832,8 +831,8 @@ out_clr:
lo->lo_device = NULL;
lo->lo_backing_file = NULL;
lo->lo_flags = 0;
- set_capacity(disks[lo->lo_number], 0);
- invalidate_bdev(bdev, 0);
+ set_capacity(lo->lo_disk, 0);
+ invalidate_bdev(bdev);
bd_set_size(bdev, 0);
mapping_set_gfp_mask(mapping, lo->old_gfp_mask);
lo->lo_state = Lo_unbound;
@@ -917,8 +916,8 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
memset(lo->lo_file_name, 0, LO_NAME_SIZE);
- invalidate_bdev(bdev, 0);
- set_capacity(disks[lo->lo_number], 0);
+ invalidate_bdev(bdev);
+ set_capacity(lo->lo_disk, 0);
bd_set_size(bdev, 0);
mapping_set_gfp_mask(filp->f_mapping, gfp);
lo->lo_state = Lo_unbound;
@@ -1322,6 +1321,18 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
}
#endif
+static struct loop_device *loop_find_dev(int number)
+{
+ struct loop_device *lo;
+
+ list_for_each_entry(lo, &loop_devices, lo_list) {
+ if (lo->lo_number == number)
+ return lo;
+ }
+ return NULL;
+}
+
+static struct loop_device *loop_init_one(int i);
static int lo_open(struct inode *inode, struct file *file)
{
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
@@ -1330,6 +1341,11 @@ static int lo_open(struct inode *inode, struct file *file)
lo->lo_refcnt++;
mutex_unlock(&lo->lo_ctl_mutex);
+ mutex_lock(&loop_devices_mutex);
+ if (!loop_find_dev(lo->lo_number + 1))
+ loop_init_one(lo->lo_number + 1);
+ mutex_unlock(&loop_devices_mutex);
+
return 0;
}
@@ -1357,8 +1373,9 @@ static struct block_device_operations lo_fops = {
/*
* And now the modules code and kernel interface.
*/
+static int max_loop;
module_param(max_loop, int, 0);
-MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-256)");
+MODULE_PARM_DESC(max_loop, "obsolete, loop device is created on-demand");
MODULE_LICENSE("GPL");
MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
@@ -1383,7 +1400,7 @@ int loop_unregister_transfer(int number)
xfer_funcs[n] = NULL;
- for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
+ list_for_each_entry(lo, &loop_devices, lo_list) {
mutex_lock(&lo->lo_ctl_mutex);
if (lo->lo_encryption == xfer)
@@ -1398,91 +1415,110 @@ int loop_unregister_transfer(int number)
EXPORT_SYMBOL(loop_register_transfer);
EXPORT_SYMBOL(loop_unregister_transfer);
-static int __init loop_init(void)
+static struct loop_device *loop_init_one(int i)
+{
+ struct loop_device *lo;
+ struct gendisk *disk;
+
+ lo = kzalloc(sizeof(*lo), GFP_KERNEL);
+ if (!lo)
+ goto out;
+
+ lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
+ if (!lo->lo_queue)
+ goto out_free_dev;
+
+ disk = lo->lo_disk = alloc_disk(1);
+ if (!disk)
+ goto out_free_queue;
+
+ mutex_init(&lo->lo_ctl_mutex);
+ lo->lo_number = i;
+ lo->lo_thread = NULL;
+ init_waitqueue_head(&lo->lo_event);
+ spin_lock_init(&lo->lo_lock);
+ disk->major = LOOP_MAJOR;
+ disk->first_minor = i;
+ disk->fops = &lo_fops;
+ disk->private_data = lo;
+ disk->queue = lo->lo_queue;
+ sprintf(disk->disk_name, "loop%d", i);
+ add_disk(disk);
+ list_add_tail(&lo->lo_list, &loop_devices);
+ return lo;
+
+out_free_queue:
+ blk_cleanup_queue(lo->lo_queue);
+out_free_dev:
+ kfree(lo);
+out:
+ return ERR_PTR(-ENOMEM);
+}
+
+static void loop_del_one(struct loop_device *lo)
{
- int i;
+ del_gendisk(lo->lo_disk);
+ blk_cleanup_queue(lo->lo_queue);
+ put_disk(lo->lo_disk);
+ list_del(&lo->lo_list);
+ kfree(lo);
+}
- if (max_loop < 1 || max_loop > 256) {
- printk(KERN_WARNING "loop: invalid max_loop (must be between"
- " 1 and 256), using default (8)\n");
- max_loop = 8;
- }
+static struct kobject *loop_probe(dev_t dev, int *part, void *data)
+{
+ unsigned int number = dev & MINORMASK;
+ struct loop_device *lo;
+
+ mutex_lock(&loop_devices_mutex);
+ lo = loop_find_dev(number);
+ if (lo == NULL)
+ lo = loop_init_one(number);
+ mutex_unlock(&loop_devices_mutex);
+
+ *part = 0;
+ if (IS_ERR(lo))
+ return (void *)lo;
+ else
+ return &lo->lo_disk->kobj;
+}
+
+static int __init loop_init(void)
+{
+ struct loop_device *lo;
if (register_blkdev(LOOP_MAJOR, "loop"))
return -EIO;
+ blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS,
+ THIS_MODULE, loop_probe, NULL, NULL);
- loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL);
- if (!loop_dev)
- goto out_mem1;
- memset(loop_dev, 0, max_loop * sizeof(struct loop_device));
+ lo = loop_init_one(0);
+ if (IS_ERR(lo))
+ goto out;
- disks = kmalloc(max_loop * sizeof(struct gendisk *), GFP_KERNEL);
- if (!disks)
- goto out_mem2;
+ if (max_loop) {
+ printk(KERN_INFO "loop: the max_loop option is obsolete "
+ "and will be removed in March 2008\n");
- for (i = 0; i < max_loop; i++) {
- disks[i] = alloc_disk(1);
- if (!disks[i])
- goto out_mem3;
}
-
- for (i = 0; i < max_loop; i++) {
- struct loop_device *lo = &loop_dev[i];
- struct gendisk *disk = disks[i];
-
- memset(lo, 0, sizeof(*lo));
- lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
- if (!lo->lo_queue)
- goto out_mem4;
- mutex_init(&lo->lo_ctl_mutex);
- lo->lo_number = i;
- lo->lo_thread = NULL;
- init_waitqueue_head(&lo->lo_event);
- spin_lock_init(&lo->lo_lock);
- disk->major = LOOP_MAJOR;
- disk->first_minor = i;
- disk->fops = &lo_fops;
- sprintf(disk->disk_name, "loop%d", i);
- disk->private_data = lo;
- disk->queue = lo->lo_queue;
- }
-
- /* We cannot fail after we call this, so another loop!*/
- for (i = 0; i < max_loop; i++)
- add_disk(disks[i]);
- printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop);
+ printk(KERN_INFO "loop: module loaded\n");
return 0;
-out_mem4:
- while (i--)
- blk_cleanup_queue(loop_dev[i].lo_queue);
- i = max_loop;
-out_mem3:
- while (i--)
- put_disk(disks[i]);
- kfree(disks);
-out_mem2:
- kfree(loop_dev);
-out_mem1:
+out:
unregister_blkdev(LOOP_MAJOR, "loop");
printk(KERN_ERR "loop: ran out of memory\n");
return -ENOMEM;
}
-static void loop_exit(void)
+static void __exit loop_exit(void)
{
- int i;
+ struct loop_device *lo, *next;
- for (i = 0; i < max_loop; i++) {
- del_gendisk(disks[i]);
- blk_cleanup_queue(loop_dev[i].lo_queue);
- put_disk(disks[i]);
- }
+ list_for_each_entry_safe(lo, next, &loop_devices, lo_list)
+ loop_del_one(lo);
+
+ blk_unregister_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS);
if (unregister_blkdev(LOOP_MAJOR, "loop"))
printk(KERN_WARNING "loop: cannot unregister blkdev\n");
-
- kfree(disks);
- kfree(loop_dev);
}
module_init(loop_init);
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 485aa87..43d4ebc 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -403,7 +403,7 @@ static void __exit rd_cleanup(void)
struct block_device *bdev = rd_bdev[i];
rd_bdev[i] = NULL;
if (bdev) {
- invalidate_bdev(bdev, 1);
+ invalidate_bdev(bdev);
blkdev_put(bdev);
}
del_gendisk(rd_disks[i]);
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 5872036..6f5d620 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -44,7 +44,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/pci.h>
#include <linux/slab.h>
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 406af57..b0238b4 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -114,10 +114,16 @@ static struct usb_device_id blacklist_ids[] = {
{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 },
+ /* Broadcom BCM2045 */
+ { USB_DEVICE(0x0a5c, 0x2101), .driver_info = HCI_WRONG_SCO_MTU },
+
/* IBM/Lenovo ThinkPad with Broadcom chip */
{ USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU },
{ USB_DEVICE(0x0a5c, 0x2110), .driver_info = HCI_WRONG_SCO_MTU },
+ /* Targus ACB10US */
+ { USB_DEVICE(0x0a5c, 0x2100), .driver_info = HCI_RESET },
+
/* ANYCOM Bluetooth USB-200 and USB-250 */
{ USB_DEVICE(0x0a5c, 0x2111), .driver_info = HCI_RESET },
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index b36f44d..3625a05 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -2384,7 +2384,7 @@ static int cdrom_ioctl_reset(struct cdrom_device_info *cdi,
return -EACCES;
if (!CDROM_CAN(CDC_RESET))
return -ENOSYS;
- invalidate_bdev(bdev, 0);
+ invalidate_bdev(bdev);
return cdi->ops->reset(cdi);
}
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index d0c978f..1e32fb8 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -127,7 +127,7 @@ config ROCKETPORT
config CYCLADES
tristate "Cyclades async mux support"
- depends on SERIAL_NONSTANDARD
+ depends on SERIAL_NONSTANDARD && (PCI || ISA)
---help---
This driver supports Cyclades Z and Y multiserial boards.
You would need something like this to connect more than two modems to
@@ -905,8 +905,8 @@ config SONYPI
To compile this driver as a module, choose M here: the
module will be called sonypi.
-config TANBAC_TB0219
- tristate "TANBAC TB0219 base board support"
+config GPIO_TB0219
+ tristate "TANBAC TB0219 GPIO support"
depends on TANBAC_TB022X
select GPIO_VR41XX
@@ -1071,5 +1071,11 @@ config TELCLOCK
/sys/devices/platform/telco_clock, with a number of files for
controlling the behavior of this hardware.
+config DEVPORT
+ bool
+ depends on !M68K
+ depends on ISA || PCI
+ default y
+
endmenu
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index ae8567c..2f56ecc 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -91,7 +91,7 @@ obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o
obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o
obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o
obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
-obj-$(CONFIG_TANBAC_TB0219) += tb0219.o
+obj-$(CONFIG_GPIO_TB0219) += tb0219.o
obj-$(CONFIG_TELCLOCK) += tlclk.o
obj-$(CONFIG_WATCHDOG) += watchdog/
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index 91b0621..42c0a60 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -613,7 +613,7 @@ static int __devinit agp_uninorth_probe(struct pci_dev *pdev,
uninorth_node = of_find_node_by_name(NULL, "u3");
}
if (uninorth_node) {
- const int *revprop = get_property(uninorth_node,
+ const int *revprop = of_get_property(uninorth_node,
"device-rev", NULL);
if (revprop != NULL)
uninorth_rev = *revprop & 0x3f;
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 0e2b72f..4eaceab 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -1574,7 +1574,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
if (timeout && time_after(jiffies, orig_jiffies + timeout))
break;
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
#endif
@@ -1700,7 +1700,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
#endif
schedule();
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&info->open_wait, &wait);
if (extra_count)
state->count++;
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c
index c70d52a..ed53f54 100644
--- a/drivers/char/briq_panel.c
+++ b/drivers/char/briq_panel.c
@@ -206,7 +206,7 @@ static int __init briq_panel_init(void)
const char *machine;
int i;
- machine = get_property(root, "model", NULL);
+ machine = of_get_property(root, "model", NULL);
if (!machine || strncmp(machine, "TotalImpact,BRIQ-1", 18) != 0) {
of_node_put(root);
return -ENODEV;
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c
index b99b756..fd40b95 100644
--- a/drivers/char/consolemap.c
+++ b/drivers/char/consolemap.c
@@ -626,10 +626,10 @@ conv_uni_to_pc(struct vc_data *conp, long ucs)
/* Only 16-bit codes supported at this time */
if (ucs > 0xffff)
- ucs = 0xfffd; /* U+FFFD: REPLACEMENT CHARACTER */
- else if (ucs < 0x20 || ucs >= 0xfffe)
+ return -4; /* Not found */
+ else if (ucs < 0x20)
return -1; /* Not a printable character */
- else if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f))
+ else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f))
return -2; /* Zero-width space */
/*
* UNI_DIRECT_BASE indicates the start of the region in the User Zone
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c
index c02d9e9..fe6d240 100644
--- a/drivers/char/cs5535_gpio.c
+++ b/drivers/char/cs5535_gpio.c
@@ -44,6 +44,7 @@ static struct pci_device_id divil_pci[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
{ } /* NULL entry */
};
+MODULE_DEVICE_TABLE(pci, divil_pci);
static struct cdev cs5535_gpio_cdev;
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 16dc5d1..c72ee97 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -10,15 +10,14 @@
*
* Initially written by Randolph Bentson <bentson@grieg.seaslug.org>.
* Modified and maintained by Marcio Saito <marcio@cyclades.com>.
- * Currently maintained by Cyclades team <async@cyclades.com>.
*
- * For Technical support and installation problems, please send e-mail
- * to support@cyclades.com.
+ * Copyright (C) 2007 Jiri Slaby <jirislaby@gmail.com>
*
* Much of the design and some of the code came from serial.c
* which was copyright (C) 1991, 1992 Linus Torvalds. It was
* extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92,
* and then fixed as suggested by Michael K. Johnson 12/12/92.
+ * Converted to pci probing and cleaned up by Jiri Slaby.
*
* This version supports shared IRQ's (only for PCI boards).
*
@@ -591,7 +590,7 @@
*
*/
-#define CY_VERSION "2.4"
+#define CY_VERSION "2.5"
/* If you need to install more boards than NR_CARDS, change the constant
in the definition below. No other change is necessary to support up to
@@ -624,12 +623,6 @@
#undef CY_ENABLE_MONITORING
#undef CY_PCI_DEBUG
-#if 0
-#define PAUSE __asm__("nop")
-#else
-#define PAUSE do {} while (0)
-#endif
-
/*
* Include section
*/
@@ -659,17 +652,6 @@
#include <asm/irq.h>
#include <asm/uaccess.h>
-#define CY_LOCK(info,flags) \
- do { \
- spin_lock_irqsave(&cy_card[info->card].card_lock, flags); \
- } while (0)
-
-#define CY_UNLOCK(info,flags) \
- do { \
- spin_unlock_irqrestore(&cy_card[info->card].card_lock, flags); \
- } while (0)
-
-#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/pci.h>
@@ -682,13 +664,13 @@ static void cy_send_xchar(struct tty_struct *tty, char ch);
#define IS_CYC_Z(card) ((card).num_chips == -1)
#define Z_FPGA_CHECK(card) \
- ((cy_readl(&((struct RUNTIME_9060 __iomem *) \
+ ((readl(&((struct RUNTIME_9060 __iomem *) \
((card).ctl_addr))->init_ctrl) & (1<<17)) != 0)
-#define ISZLOADED(card) (((ZO_V1==cy_readl(&((struct RUNTIME_9060 __iomem *) \
+#define ISZLOADED(card) (((ZO_V1==readl(&((struct RUNTIME_9060 __iomem *) \
((card).ctl_addr))->mail_box_0)) || \
Z_FPGA_CHECK(card)) && \
- (ZFIRM_ID==cy_readl(&((struct FIRM_ID __iomem *) \
+ (ZFIRM_ID==readl(&((struct FIRM_ID __iomem *) \
((card).base_addr+ID_ADDRESS))->signature)))
#ifndef SERIAL_XMIT_SIZE
@@ -725,8 +707,8 @@ static unsigned int cy_isa_addresses[] = {
#define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses)
#ifdef MODULE
-static long maddr[NR_CARDS] = { 0, };
-static int irq[NR_CARDS] = { 0, };
+static long maddr[NR_CARDS];
+static int irq[NR_CARDS];
module_param_array(maddr, long, NULL, 0);
module_param_array(irq, int, NULL, 0);
@@ -739,11 +721,6 @@ module_param_array(irq, int, NULL, 0);
*/
static struct cyclades_card cy_card[NR_CARDS];
-/* This is the per-channel data structure containing pointers, flags
- and variables for the port. This driver supports a maximum of NR_PORTS.
-*/
-static struct cyclades_port cy_port[NR_PORTS];
-
static int cy_next_channel; /* next minor available */
/*
@@ -825,9 +802,6 @@ static int cy_chip_offset[] = { 0x0000,
/* PCI related definitions */
-static unsigned short cy_pci_nboard;
-static unsigned short cy_isa_nboard;
-static unsigned short cy_nboard;
#ifdef CONFIG_PCI
static struct pci_device_id cy_pci_dev_id[] __devinitdata = {
{ PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, /* PCI < 1Mb */
@@ -845,7 +819,7 @@ MODULE_DEVICE_TABLE(pci, cy_pci_dev_id);
static void cy_start(struct tty_struct *);
static void set_line_char(struct cyclades_port *);
-static int cyz_issue_cmd(struct cyclades_card *, uclong, ucchar, uclong);
+static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32);
#ifdef CONFIG_ISA
static unsigned detect_isa_irq(void __iomem *);
#endif /* CONFIG_ISA */
@@ -858,7 +832,6 @@ static void cyz_poll(unsigned long);
/* The Cyclades-Z polling cycle is defined by this variable */
static long cyz_polling_cycle = CZ_DEF_POLL;
-static int cyz_timeron = 0;
static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0);
#else /* CONFIG_CYZ_INTR */
@@ -871,21 +844,14 @@ static inline int serial_paranoia_check(struct cyclades_port *info,
{
#ifdef SERIAL_PARANOIA_CHECK
if (!info) {
- printk("cyc Warning: null cyclades_port for (%s) in %s\n",
- name, routine);
- return 1;
- }
-
- if ((long)info < (long)(&cy_port[0]) ||
- (long)(&cy_port[NR_PORTS]) < (long)info) {
- printk("cyc Warning: cyclades_port out of range for (%s) in "
- "%s\n", name, routine);
+ printk(KERN_WARNING "cyc Warning: null cyclades_port for (%s) "
+ "in %s\n", name, routine);
return 1;
}
if (info->magic != CYCLADES_MAGIC) {
- printk("cyc Warning: bad magic number for serial struct (%s) "
- "in %s\n", name, routine);
+ printk(KERN_WARNING "cyc Warning: bad magic number for serial "
+ "struct (%s) in %s\n", name, routine);
return 1;
}
#endif
@@ -943,22 +909,16 @@ do_softint(struct work_struct *work)
if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event))
wake_up_interruptible(&info->open_wait);
#ifdef CONFIG_CYZ_INTR
- if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event)) {
- if (cyz_rx_full_timer[info->line].function == NULL) {
- cyz_rx_full_timer[info->line].expires = jiffies + 1;
- cyz_rx_full_timer[info->line].function = cyz_rx_restart;
- cyz_rx_full_timer[info->line].data =
- (unsigned long)info;
- add_timer(&cyz_rx_full_timer[info->line]);
- }
- }
+ if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event) &&
+ !timer_pending(&cyz_rx_full_timer[info->line]))
+ mod_timer(&cyz_rx_full_timer[info->line], jiffies + 1);
#endif
if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event))
wake_up_interruptible(&info->delta_msr_wait);
tty_wakeup(tty);
#ifdef Z_WAKE
if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event))
- wake_up_interruptible(&info->shutdown_wait);
+ complete(&info->shutdown_wait);
#endif
} /* do_softint */
@@ -975,11 +935,11 @@ do_softint(struct work_struct *work)
*/
static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index)
{
- volatile int i;
+ unsigned int i;
/* Check to see that the previous command has completed */
for (i = 0; i < 100; i++) {
- if (cy_readb(base_addr + (CyCCR << index)) == 0) {
+ if (readb(base_addr + (CyCCR << index)) == 0) {
break;
}
udelay(10L);
@@ -1022,7 +982,7 @@ static unsigned detect_isa_irq(void __iomem * address)
cy_writeb(address + (CyCAR << index), 0);
cy_writeb(address + (CySRER << index),
- cy_readb(address + (CySRER << index)) | CyTxRdy);
+ readb(address + (CySRER << index)) | CyTxRdy);
local_irq_restore(flags);
/* Wait ... */
@@ -1032,11 +992,11 @@ static unsigned detect_isa_irq(void __iomem * address)
irq = probe_irq_off(irqs);
/* Clean up */
- save_xir = (u_char) cy_readb(address + (CyTIR << index));
- save_car = cy_readb(address + (CyCAR << index));
+ save_xir = (u_char) readb(address + (CyTIR << index));
+ save_car = readb(address + (CyCAR << index));
cy_writeb(address + (CyCAR << index), (save_xir & 0x3));
cy_writeb(address + (CySRER << index),
- cy_readb(address + (CySRER << index)) & ~CyTxRdy);
+ readb(address + (CySRER << index)) & ~CyTxRdy);
cy_writeb(address + (CyTIR << index), (save_xir & 0x3f));
cy_writeb(address + (CyCAR << index), (save_car));
cy_writeb(address + (Cy_ClrIntr << index), 0);
@@ -1051,45 +1011,43 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
{
struct cyclades_port *info;
struct tty_struct *tty;
- volatile int char_count;
- int i, j, len, mdm_change, mdm_status, outch;
+ int char_count;
+ int j, len, mdm_change, mdm_status, outch;
int save_xir, channel, save_car;
char data;
if (status & CySRReceive) { /* reception interrupt */
#ifdef CY_DEBUG_INTERRUPTS
- printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip);
+ printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
#endif
/* determine the channel & change to that context */
spin_lock(&cinfo->card_lock);
- save_xir = (u_char) cy_readb(base_addr + (CyRIR << index));
+ save_xir = (u_char) readb(base_addr + (CyRIR << index));
channel = (u_short) (save_xir & CyIRChannel);
- i = channel + chip * 4 + cinfo->first_line;
- info = &cy_port[i];
- info->last_active = jiffies;
- save_car = cy_readb(base_addr + (CyCAR << index));
+ info = &cinfo->ports[channel + chip * 4];
+ save_car = readb(base_addr + (CyCAR << index));
cy_writeb(base_addr + (CyCAR << index), save_xir);
/* if there is nowhere to put the data, discard it */
- if (info->tty == 0) {
- j = (cy_readb(base_addr + (CyRIVR << index)) &
+ if (info->tty == NULL) {
+ j = (readb(base_addr + (CyRIVR << index)) &
CyIVRMask);
if (j == CyIVRRxEx) { /* exception */
- data = cy_readb(base_addr + (CyRDSR << index));
+ data = readb(base_addr + (CyRDSR << index));
} else { /* normal character reception */
- char_count = cy_readb(base_addr +
+ char_count = readb(base_addr +
(CyRDCR << index));
while (char_count--) {
- data = cy_readb(base_addr +
+ data = readb(base_addr +
(CyRDSR << index));
}
}
} else { /* there is an open port for this data */
tty = info->tty;
- j = (cy_readb(base_addr + (CyRIVR << index)) &
+ j = (readb(base_addr + (CyRIVR << index)) &
CyIVRMask);
if (j == CyIVRRxEx) { /* exception */
- data = cy_readb(base_addr + (CyRDSR << index));
+ data = readb(base_addr + (CyRDSR << index));
/* For statistics only */
if (data & CyBREAK)
@@ -1110,7 +1068,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
if (data & CyBREAK) {
tty_insert_flip_char(
tty,
- cy_readb(
+ readb(
base_addr +
(CyRDSR <<
index)),
@@ -1123,7 +1081,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
} else if (data & CyFRAME) {
tty_insert_flip_char(
tty,
- cy_readb(
+ readb(
base_addr +
(CyRDSR <<
index)),
@@ -1135,7 +1093,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
/* Pieces of seven... */
tty_insert_flip_char(
tty,
- cy_readb(
+ readb(
base_addr +
(CyRDSR <<
index)),
@@ -1154,7 +1112,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
*/
tty_insert_flip_char(
tty,
- cy_readb(
+ readb(
base_addr +
(CyRDSR <<
index)),
@@ -1186,7 +1144,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
}
} else { /* normal character reception */
/* load # chars available from the chip */
- char_count = cy_readb(base_addr +
+ char_count = readb(base_addr +
(CyRDCR << index));
#ifdef CY_ENABLE_MONITORING
@@ -1198,7 +1156,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
#endif
len = tty_buffer_request_room(tty, char_count);
while (len--) {
- data = cy_readb(base_addr +
+ data = readb(base_addr +
(CyRDSR << index));
tty_insert_flip_char(tty, data,
TTY_NORMAL);
@@ -1223,29 +1181,27 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
is empty, we know we can always stuff a dozen
characters. */
#ifdef CY_DEBUG_INTERRUPTS
- printk("cyy_interrupt: xmit intr, chip %d\n\r", chip);
+ printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip);
#endif
/* determine the channel & change to that context */
spin_lock(&cinfo->card_lock);
- save_xir = (u_char) cy_readb(base_addr + (CyTIR << index));
+ save_xir = (u_char) readb(base_addr + (CyTIR << index));
channel = (u_short) (save_xir & CyIRChannel);
- i = channel + chip * 4 + cinfo->first_line;
- save_car = cy_readb(base_addr + (CyCAR << index));
+ save_car = readb(base_addr + (CyCAR << index));
cy_writeb(base_addr + (CyCAR << index), save_xir);
/* validate the port# (as configured and open) */
- if ((i < 0) || (NR_PORTS <= i)) {
+ if (channel + chip * 4 >= cinfo->nports) {
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index)) &
+ readb(base_addr + (CySRER << index)) &
~CyTxRdy);
goto txend;
}
- info = &cy_port[i];
- info->last_active = jiffies;
- if (info->tty == 0) {
+ info = &cinfo->ports[channel + chip * 4];
+ if (info->tty == NULL) {
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index)) &
+ readb(base_addr + (CySRER << index)) &
~CyTxRdy);
goto txdone;
}
@@ -1278,29 +1234,29 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
while (char_count-- > 0) {
if (!info->xmit_cnt) {
- if (cy_readb(base_addr + (CySRER << index)) &
+ if (readb(base_addr + (CySRER << index)) &
CyTxMpty) {
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr +
+ readb(base_addr +
(CySRER << index)) &
~CyTxMpty);
} else {
cy_writeb(base_addr + (CySRER << index),
- (cy_readb(base_addr +
+ (readb(base_addr +
(CySRER << index)) &
~CyTxRdy) | CyTxMpty);
}
goto txdone;
}
- if (info->xmit_buf == 0) {
+ if (info->xmit_buf == NULL) {
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index))&
+ readb(base_addr + (CySRER << index)) &
~CyTxRdy);
goto txdone;
}
if (info->tty->stopped || info->tty->hw_stopped) {
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index))&
+ readb(base_addr + (CySRER << index)) &
~CyTxRdy);
goto txdone;
}
@@ -1333,7 +1289,6 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
0);
info->icount.tx++;
char_count--;
- } else {
}
}
}
@@ -1353,19 +1308,16 @@ txend:
/* determine the channel & change to that context */
spin_lock(&cinfo->card_lock);
- save_xir = (u_char) cy_readb(base_addr + (CyMIR << index));
+ save_xir = (u_char) readb(base_addr + (CyMIR << index));
channel = (u_short) (save_xir & CyIRChannel);
- info = &cy_port[channel + chip * 4 + cinfo->first_line];
- info->last_active = jiffies;
- save_car = cy_readb(base_addr + (CyCAR << index));
+ info = &cinfo->ports[channel + chip * 4];
+ save_car = readb(base_addr + (CyCAR << index));
cy_writeb(base_addr + (CyCAR << index), save_xir);
- mdm_change = cy_readb(base_addr + (CyMISR << index));
- mdm_status = cy_readb(base_addr + (CyMSVR1 << index));
+ mdm_change = readb(base_addr + (CyMISR << index));
+ mdm_status = readb(base_addr + (CyMSVR1 << index));
- if (info->tty == 0) { /* no place for data, ignore it */
- ;
- } else {
+ if (info->tty) {
if (mdm_change & CyANY_DELTA) {
/* For statistics only */
if (mdm_change & CyDCD)
@@ -1398,7 +1350,7 @@ txend:
info->tty->hw_stopped = 0;
cy_writeb(base_addr +
(CySRER << index),
- cy_readb(base_addr +
+ readb(base_addr +
(CySRER <<
index))|
CyTxRdy);
@@ -1412,17 +1364,17 @@ txend:
info->tty->hw_stopped = 1;
cy_writeb(base_addr +
(CySRER << index),
- cy_readb(base_addr +
+ readb(base_addr +
(CySRER <<
index)) &
~CyTxRdy);
}
}
}
- if (mdm_change & CyDSR) {
+/* if (mdm_change & CyDSR) {
}
if (mdm_change & CyRI) {
- }
+ }*/
}
/* end of service */
cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f));
@@ -1438,16 +1390,16 @@ txend:
static irqreturn_t cyy_interrupt(int irq, void *dev_id)
{
int status;
- struct cyclades_card *cinfo;
+ struct cyclades_card *cinfo = dev_id;
void __iomem *base_addr, *card_base_addr;
int chip;
int index;
int too_many;
int had_work;
- if ((cinfo = (struct cyclades_card *)dev_id) == 0) {
+ if (unlikely(cinfo == NULL)) {
#ifdef CY_DEBUG_INTERRUPTS
- printk("cyy_interrupt: spurious interrupt %d\n\r", irq);
+ printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n",irq);
#endif
return IRQ_NONE; /* spurious interrupt */
}
@@ -1455,6 +1407,10 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
card_base_addr = cinfo->base_addr;
index = cinfo->bus_index;
+ /* card was not initialized yet (e.g. DEBUG_SHIRQ) */
+ if (unlikely(card_base_addr == NULL))
+ return IRQ_HANDLED;
+
/* This loop checks all chips in the card. Make a note whenever
_any_ chip had some work to do, as this is considered an
indication that there will be more to do. Only when no chip
@@ -1466,7 +1422,7 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
base_addr = cinfo->base_addr +
(cy_chip_offset[chip] << index);
too_many = 0;
- while ((status = cy_readb(base_addr +
+ while ((status = readb(base_addr +
(CySVRR << index))) != 0x00) {
had_work++;
/* The purpose of the following test is to ensure that
@@ -1498,7 +1454,7 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
static int
cyz_fetch_msg(struct cyclades_card *cinfo,
- uclong * channel, ucchar * cmd, uclong * param)
+ __u32 * channel, __u8 * cmd, __u32 * param)
{
struct FIRM_ID __iomem *firm_id;
struct ZFW_CTRL __iomem *zfw_ctrl;
@@ -1509,16 +1465,15 @@ cyz_fetch_msg(struct cyclades_card *cinfo,
if (!ISZLOADED(*cinfo)) {
return -1;
}
- zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) &
- 0xfffff);
+ zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
- loc_doorbell = cy_readl(&((struct RUNTIME_9060 __iomem *)
+ loc_doorbell = readl(&((struct RUNTIME_9060 __iomem *)
(cinfo->ctl_addr))->loc_doorbell);
if (loc_doorbell) {
*cmd = (char)(0xff & loc_doorbell);
- *channel = cy_readl(&board_ctrl->fwcmd_channel);
- *param = (uclong) cy_readl(&board_ctrl->fwcmd_param);
+ *channel = readl(&board_ctrl->fwcmd_channel);
+ *param = (__u32) readl(&board_ctrl->fwcmd_param);
cy_writel(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->
loc_doorbell, 0xffffffff);
return 1;
@@ -1528,28 +1483,27 @@ cyz_fetch_msg(struct cyclades_card *cinfo,
static int
cyz_issue_cmd(struct cyclades_card *cinfo,
- uclong channel, ucchar cmd, uclong param)
+ __u32 channel, __u8 cmd, __u32 param)
{
struct FIRM_ID __iomem *firm_id;
struct ZFW_CTRL __iomem *zfw_ctrl;
struct BOARD_CTRL __iomem *board_ctrl;
- unsigned long __iomem *pci_doorbell;
+ __u32 __iomem *pci_doorbell;
int index;
firm_id = cinfo->base_addr + ID_ADDRESS;
if (!ISZLOADED(*cinfo)) {
return -1;
}
- zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) &
- 0xfffff);
+ zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
index = 0;
pci_doorbell =
&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell;
- while ((cy_readl(pci_doorbell) & 0xff) != 0) {
+ while ((readl(pci_doorbell) & 0xff) != 0) {
if (index++ == 1000) {
- return (int)(cy_readl(pci_doorbell) & 0xff);
+ return (int)(readl(pci_doorbell) & 0xff);
}
udelay(50L);
}
@@ -1561,34 +1515,30 @@ cyz_issue_cmd(struct cyclades_card *cinfo,
} /* cyz_issue_cmd */
static void
-cyz_handle_rx(struct cyclades_port *info,
- volatile struct CH_CTRL __iomem * ch_ctrl,
- volatile struct BUF_CTRL __iomem * buf_ctrl)
+cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
+ struct BUF_CTRL __iomem *buf_ctrl)
{
- struct cyclades_card *cinfo = &cy_card[info->card];
+ struct cyclades_card *cinfo = info->card;
struct tty_struct *tty = info->tty;
- volatile int char_count;
+ int char_count;
int len;
#ifdef BLOCKMOVE
- int small_count;
+ unsigned char *buf;
#else
char data;
#endif
- volatile uclong rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr;
+ __u32 rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr;
- rx_get = new_rx_get = cy_readl(&buf_ctrl->rx_get);
- rx_put = cy_readl(&buf_ctrl->rx_put);
- rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
- rx_bufaddr = cy_readl(&buf_ctrl->rx_bufaddr);
+ rx_get = new_rx_get = readl(&buf_ctrl->rx_get);
+ rx_put = readl(&buf_ctrl->rx_put);
+ rx_bufsize = readl(&buf_ctrl->rx_bufsize);
+ rx_bufaddr = readl(&buf_ctrl->rx_bufaddr);
if (rx_put >= rx_get)
char_count = rx_put - rx_get;
else
char_count = rx_put - rx_get + rx_bufsize;
if (char_count) {
- info->last_active = jiffies;
- info->jiffies[1] = jiffies;
-
#ifdef CY_ENABLE_MONITORING
info->mon.int_count++;
info->mon.char_count += char_count;
@@ -1596,7 +1546,7 @@ cyz_handle_rx(struct cyclades_port *info,
info->mon.char_max = char_count;
info->mon.char_last = char_count;
#endif
- if (tty == 0) {
+ if (tty == NULL) {
/* flush received characters */
new_rx_get = (new_rx_get + char_count) &
(rx_bufsize - 1);
@@ -1606,30 +1556,28 @@ cyz_handle_rx(struct cyclades_port *info,
/* we'd like to use memcpy(t, f, n) and memset(s, c, count)
for performance, but because of buffer boundaries, there
may be several steps to the operation */
- while (0 < (small_count = min_t(unsigned int,
- rx_bufsize - new_rx_get,
- min_t(unsigned int, TTY_FLIPBUF_SIZE -
- tty->flip.count, char_count)))){
- memcpy_fromio(tty->flip.char_buf_ptr,
- (char *)(cinfo->base_addr + rx_bufaddr +
- new_rx_get),
- small_count);
+ while (1) {
+ len = tty_prepare_flip_string(tty, &buf,
+ char_count);
+ if (!len)
+ break;
- tty->flip.char_buf_ptr += small_count;
- memset(tty->flip.flag_buf_ptr, TTY_NORMAL,
- small_count);
- tty->flip.flag_buf_ptr += small_count;
- new_rx_get = (new_rx_get + small_count) &
+ len = min_t(unsigned int, min(len, char_count),
+ rx_bufsize - new_rx_get);
+
+ memcpy_fromio(buf, cinfo->base_addr +
+ rx_bufaddr + new_rx_get, len);
+
+ new_rx_get = (new_rx_get + len) &
(rx_bufsize - 1);
- char_count -= small_count;
- info->icount.rx += small_count;
- info->idle_stats.recv_bytes += small_count;
- tty->flip.count += small_count;
+ char_count -= len;
+ info->icount.rx += len;
+ info->idle_stats.recv_bytes += len;
}
#else
len = tty_buffer_request_room(tty, char_count);
while (len--) {
- data = cy_readb(cinfo->base_addr + rx_bufaddr +
+ data = readb(cinfo->base_addr + rx_bufaddr +
new_rx_get);
new_rx_get = (new_rx_get + 1)& (rx_bufsize - 1);
tty_insert_flip_char(tty, data, TTY_NORMAL);
@@ -1640,13 +1588,12 @@ cyz_handle_rx(struct cyclades_port *info,
#ifdef CONFIG_CYZ_INTR
/* Recalculate the number of chars in the RX buffer and issue
a cmd in case it's higher than the RX high water mark */
- rx_put = cy_readl(&buf_ctrl->rx_put);
+ rx_put = readl(&buf_ctrl->rx_put);
if (rx_put >= rx_get)
char_count = rx_put - rx_get;
else
char_count = rx_put - rx_get + rx_bufsize;
- if (char_count >= (int)cy_readl(&buf_ctrl->
- rx_threshold)) {
+ if (char_count >= (int)readl(&buf_ctrl->rx_threshold)) {
cy_sched_event(info, Cy_EVENT_Z_RX_FULL);
}
#endif
@@ -1659,26 +1606,25 @@ cyz_handle_rx(struct cyclades_port *info,
}
static void
-cyz_handle_tx(struct cyclades_port *info,
- volatile struct CH_CTRL __iomem * ch_ctrl,
- volatile struct BUF_CTRL __iomem * buf_ctrl)
+cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
+ struct BUF_CTRL __iomem *buf_ctrl)
{
- struct cyclades_card *cinfo = &cy_card[info->card];
+ struct cyclades_card *cinfo = info->card;
struct tty_struct *tty = info->tty;
char data;
- volatile int char_count;
+ int char_count;
#ifdef BLOCKMOVE
int small_count;
#endif
- volatile uclong tx_put, tx_get, tx_bufsize, tx_bufaddr;
+ __u32 tx_put, tx_get, tx_bufsize, tx_bufaddr;
if (info->xmit_cnt <= 0) /* Nothing to transmit */
return;
- tx_get = cy_readl(&buf_ctrl->tx_get);
- tx_put = cy_readl(&buf_ctrl->tx_put);
- tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
- tx_bufaddr = cy_readl(&buf_ctrl->tx_bufaddr);
+ tx_get = readl(&buf_ctrl->tx_get);
+ tx_put = readl(&buf_ctrl->tx_put);
+ tx_bufsize = readl(&buf_ctrl->tx_bufsize);
+ tx_bufaddr = readl(&buf_ctrl->tx_bufaddr);
if (tx_put >= tx_get)
char_count = tx_get - tx_put - 1 + tx_bufsize;
else
@@ -1686,9 +1632,8 @@ cyz_handle_tx(struct cyclades_port *info,
if (char_count) {
- if (tty == 0) {
+ if (tty == NULL)
goto ztxdone;
- }
if (info->x_char) { /* send special char */
data = info->x_char;
@@ -1698,8 +1643,6 @@ cyz_handle_tx(struct cyclades_port *info,
info->x_char = 0;
char_count--;
info->icount.tx++;
- info->last_active = jiffies;
- info->jiffies[2] = jiffies;
}
#ifdef BLOCKMOVE
while (0 < (small_count = min_t(unsigned int,
@@ -1719,8 +1662,6 @@ cyz_handle_tx(struct cyclades_port *info,
info->xmit_cnt -= small_count;
info->xmit_tail = (info->xmit_tail + small_count) &
(SERIAL_XMIT_SIZE - 1);
- info->last_active = jiffies;
- info->jiffies[2] = jiffies;
}
#else
while (info->xmit_cnt && char_count) {
@@ -1733,8 +1674,6 @@ cyz_handle_tx(struct cyclades_port *info,
tx_put = (tx_put + 1) & (tx_bufsize - 1);
char_count--;
info->icount.tx++;
- info->last_active = jiffies;
- info->jiffies[2] = jiffies;
}
#endif
ztxdone:
@@ -1750,33 +1689,32 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
{
struct tty_struct *tty;
struct cyclades_port *info;
- static volatile struct FIRM_ID __iomem *firm_id;
- static volatile struct ZFW_CTRL __iomem *zfw_ctrl;
- static volatile struct BOARD_CTRL __iomem *board_ctrl;
- static volatile struct CH_CTRL __iomem *ch_ctrl;
- static volatile struct BUF_CTRL __iomem *buf_ctrl;
- uclong channel;
- ucchar cmd;
- uclong param;
- uclong hw_ver, fw_ver;
+ static struct FIRM_ID __iomem *firm_id;
+ static struct ZFW_CTRL __iomem *zfw_ctrl;
+ static struct BOARD_CTRL __iomem *board_ctrl;
+ static struct CH_CTRL __iomem *ch_ctrl;
+ static struct BUF_CTRL __iomem *buf_ctrl;
+ __u32 channel;
+ __u8 cmd;
+ __u32 param;
+ __u32 hw_ver, fw_ver;
int special_count;
int delta_count;
firm_id = cinfo->base_addr + ID_ADDRESS;
- zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) &
- 0xfffff);
+ zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
- fw_ver = cy_readl(&board_ctrl->fw_version);
- hw_ver = cy_readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->
+ fw_ver = readl(&board_ctrl->fw_version);
+ hw_ver = readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->
mail_box_0);
while (cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
special_count = 0;
delta_count = 0;
- info = &cy_port[channel + cinfo->first_line];
- if ((tty = info->tty) == 0) {
+ info = &cinfo->ports[channel];
+ if ((tty = info->tty) == NULL)
continue;
- }
+
ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
@@ -1801,7 +1739,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
delta_count++;
if (info->flags & ASYNC_CHECK_CD) {
if ((fw_ver > 241 ? ((u_long) param) :
- cy_readl(&ch_ctrl->rs_status)) &
+ readl(&ch_ctrl->rs_status)) &
C_RS_DCD) {
cy_sched_event(info,
Cy_EVENT_OPEN_WAKEUP);
@@ -1833,8 +1771,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
case C_CM_INTBACK2:
/* Reception Interrupt */
#ifdef CY_DEBUG_INTERRUPTS
- printk("cyz_interrupt: rcvd intr, card %d, "
- "port %ld\n\r", info->card, channel);
+ printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, "
+ "port %ld\n", info->card, channel);
#endif
cyz_handle_rx(info, ch_ctrl, buf_ctrl);
break;
@@ -1843,8 +1781,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
case C_CM_INTBACK:
/* Transmission Interrupt */
#ifdef CY_DEBUG_INTERRUPTS
- printk("cyz_interrupt: xmit intr, card %d, "
- "port %ld\n\r", info->card, channel);
+ printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, "
+ "port %ld\n", info->card, channel);
#endif
cyz_handle_tx(info, ch_ctrl, buf_ctrl);
break;
@@ -1865,18 +1803,19 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
#ifdef CONFIG_CYZ_INTR
static irqreturn_t cyz_interrupt(int irq, void *dev_id)
{
- struct cyclades_card *cinfo;
+ struct cyclades_card *cinfo = dev_id;
- if ((cinfo = (struct cyclades_card *)dev_id) == 0) {
+ if (unlikely(cinfo == NULL)) {
#ifdef CY_DEBUG_INTERRUPTS
- printk("cyz_interrupt: spurious interrupt %d\n\r", irq);
+ printk(KERN_DEBUG "cyz_interrupt: spurious interrupt %d\n",irq);
#endif
return IRQ_NONE; /* spurious interrupt */
}
- if (!ISZLOADED(*cinfo)) {
+ if (unlikely(!ISZLOADED(*cinfo))) {
#ifdef CY_DEBUG_INTERRUPTS
- printk("cyz_interrupt: board not yet loaded (IRQ%d).\n\r", irq);
+ printk(KERN_DEBUG "cyz_interrupt: board not yet loaded "
+ "(IRQ%d).\n", irq);
#endif
return IRQ_NONE;
}
@@ -1890,19 +1829,18 @@ static irqreturn_t cyz_interrupt(int irq, void *dev_id)
static void cyz_rx_restart(unsigned long arg)
{
struct cyclades_port *info = (struct cyclades_port *)arg;
+ struct cyclades_card *card = info->card;
int retval;
- int card = info->card;
- uclong channel = (info->line) - (cy_card[card].first_line);
+ __u32 channel = info->line - card->first_line;
unsigned long flags;
- CY_LOCK(info, flags);
- retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK2, 0L);
+ spin_lock_irqsave(&card->card_lock, flags);
+ retval = cyz_issue_cmd(card, channel, C_CM_INTBACK2, 0L);
if (retval != 0) {
- printk("cyc:cyz_rx_restart retval on ttyC%d was %x\n",
+ printk(KERN_ERR "cyc:cyz_rx_restart retval on ttyC%d was %x\n",
info->line, retval);
}
- cyz_rx_full_timer[info->line].function = NULL;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
#else /* CONFIG_CYZ_INTR */
@@ -1912,14 +1850,14 @@ static void cyz_poll(unsigned long arg)
struct cyclades_card *cinfo;
struct cyclades_port *info;
struct tty_struct *tty;
- static volatile struct FIRM_ID *firm_id;
- static volatile struct ZFW_CTRL *zfw_ctrl;
- static volatile struct BOARD_CTRL *board_ctrl;
- static volatile struct CH_CTRL *ch_ctrl;
- static volatile struct BUF_CTRL *buf_ctrl;
+ static struct FIRM_ID *firm_id;
+ static struct ZFW_CTRL *zfw_ctrl;
+ static struct BOARD_CTRL *board_ctrl;
+ static struct CH_CTRL *ch_ctrl;
+ static struct BUF_CTRL *buf_ctrl;
+ unsigned long expires = jiffies + HZ;
int card, port;
- cyz_timerlist.expires = jiffies + (HZ);
for (card = 0; card < NR_CARDS; card++) {
cinfo = &cy_card[card];
@@ -1930,12 +1868,12 @@ static void cyz_poll(unsigned long arg)
firm_id = cinfo->base_addr + ID_ADDRESS;
zfw_ctrl = cinfo->base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &(zfw_ctrl->board_ctrl);
/* Skip first polling cycle to avoid racing conditions with the FW */
if (!cinfo->intr_enabled) {
- cinfo->nports = (int)cy_readl(&board_ctrl->n_channel);
+ cinfo->nports = (int)readl(&board_ctrl->n_channel);
cinfo->intr_enabled = 1;
continue;
}
@@ -1943,7 +1881,7 @@ static void cyz_poll(unsigned long arg)
cyz_handle_cmd(cinfo);
for (port = 0; port < cinfo->nports; port++) {
- info = &cy_port[port + cinfo->first_line];
+ info = &cinfo->ports[port];
tty = info->tty;
ch_ctrl = &(zfw_ctrl->ch_ctrl[port]);
buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
@@ -1953,9 +1891,9 @@ static void cyz_poll(unsigned long arg)
cyz_handle_tx(info, ch_ctrl, buf_ctrl);
}
/* poll every 'cyz_polling_cycle' period */
- cyz_timerlist.expires = jiffies + cyz_polling_cycle;
+ expires = jiffies + cyz_polling_cycle;
}
- add_timer(&cyz_timerlist);
+ mod_timer(&cyz_timerlist, expires);
} /* cyz_poll */
#endif /* CONFIG_CYZ_INTR */
@@ -1968,20 +1906,21 @@ static void cyz_poll(unsigned long arg)
*/
static int startup(struct cyclades_port *info)
{
+ struct cyclades_card *card;
unsigned long flags;
int retval = 0;
void __iomem *base_addr;
- int card, chip, channel, index;
+ int chip, channel, index;
unsigned long page;
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
+ channel = info->line - card->first_line;
page = get_zeroed_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
if (info->flags & ASYNC_INITIALIZED) {
free_page(page);
@@ -2001,24 +1940,22 @@ static int startup(struct cyclades_port *info)
else
info->xmit_buf = (unsigned char *)page;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
set_line_char(info);
- if (!IS_CYC_Z(cy_card[card])) {
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr = cy_card[card].base_addr +
- (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
#ifdef CY_DEBUG_OPEN
- printk("cyc startup card %d, chip %d, channel %d, "
- "base_addr %lx\n",
- card, chip, channel, (long)base_addr);
- /**/
+ printk(KERN_DEBUG "cyc startup card %d, chip %d, channel %d, "
+ "base_addr %p\n",
+ card, chip, channel, base_addr);
#endif
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
@@ -2034,14 +1971,14 @@ static int startup(struct cyclades_port *info)
cy_writeb(base_addr + (CyMSVR2 << index), CyDTR);
#ifdef CY_DEBUG_DTR
- printk("cyc:startup raising DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr + (CyMSVR1 << index)),
- cy_readb(base_addr + (CyMSVR2 << index)));
+ printk(KERN_DEBUG "cyc:startup raising DTR\n");
+ printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
+ readb(base_addr + (CyMSVR1 << index)),
+ readb(base_addr + (CyMSVR2 << index)));
#endif
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index)) | CyRxData);
+ readb(base_addr + (CySRER << index)) | CyRxData);
info->flags |= ASYNC_INITIALIZED;
if (info->tty) {
@@ -2054,7 +1991,7 @@ static int startup(struct cyclades_port *info)
info->idle_stats.recv_idle =
info->idle_stats.xmit_idle = jiffies;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} else {
struct FIRM_ID __iomem *firm_id;
@@ -2063,24 +2000,23 @@ static int startup(struct cyclades_port *info)
struct CH_CTRL __iomem *ch_ctrl;
int retval;
- base_addr = cy_card[card].base_addr;
+ base_addr = card->base_addr;
firm_id = base_addr + ID_ADDRESS;
- if (!ISZLOADED(cy_card[card])) {
+ if (!ISZLOADED(*card)) {
return -ENODEV;
}
- zfw_ctrl = cy_card[card].base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ zfw_ctrl = card->base_addr +
+ (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
#ifdef CY_DEBUG_OPEN
- printk("cyc startup Z card %d, channel %d, base_addr %lx\n",
- card, channel, (long)base_addr);
- /**/
+ printk(KERN_DEBUG "cyc startup Z card %d, channel %d, "
+ "base_addr %p\n", card, channel, base_addr);
#endif
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE);
#ifdef Z_WAKE
@@ -2102,33 +2038,31 @@ static int startup(struct cyclades_port *info)
#endif /* CONFIG_CYZ_INTR */
#endif /* Z_WAKE */
- retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L);
+ retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L);
if (retval != 0) {
- printk("cyc:startup(1) retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc:startup(1) retval on ttyC%d was "
+ "%x\n", info->line, retval);
}
/* Flush RX buffers before raising DTR and RTS */
- retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_RX,
- 0L);
+ retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_RX, 0L);
if (retval != 0) {
- printk("cyc:startup(2) retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc:startup(2) retval on ttyC%d was "
+ "%x\n", info->line, retval);
}
/* set timeout !!! */
/* set RTS and DTR !!! */
cy_writel(&ch_ctrl[channel].rs_control,
- cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS |
+ readl(&ch_ctrl[channel].rs_control) | C_RS_RTS |
C_RS_DTR);
- retval = cyz_issue_cmd(&cy_card[info->card], channel,
- C_CM_IOCTLM, 0L);
+ retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
if (retval != 0) {
- printk("cyc:startup(3) retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc:startup(3) retval on ttyC%d was "
+ "%x\n", info->line, retval);
}
#ifdef CY_DEBUG_DTR
- printk("cyc:startup raising Z DTR\n");
+ printk(KERN_DEBUG "cyc:startup raising Z DTR\n");
#endif
/* enable send, recv, modem !!! */
@@ -2144,51 +2078,50 @@ static int startup(struct cyclades_port *info)
info->idle_stats.recv_idle =
info->idle_stats.xmit_idle = jiffies;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
#ifdef CY_DEBUG_OPEN
- printk(" cyc startup done\n");
+ printk(KERN_DEBUG "cyc startup done\n");
#endif
return 0;
errout:
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
return retval;
} /* startup */
static void start_xmit(struct cyclades_port *info)
{
+ struct cyclades_card *card;
unsigned long flags;
void __iomem *base_addr;
- int card, chip, channel, index;
+ int chip, channel, index;
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr = cy_card[card].base_addr +
- (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index), channel);
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index)) | CyTxRdy);
- CY_UNLOCK(info, flags);
+ readb(base_addr + (CySRER << index)) | CyTxRdy);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} else {
#ifdef CONFIG_CYZ_INTR
int retval;
- CY_LOCK(info, flags);
- retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK,
- 0L);
+ spin_lock_irqsave(&card->card_lock, flags);
+ retval = cyz_issue_cmd(card, channel, C_CM_INTBACK, 0L);
if (retval != 0) {
- printk("cyc:start_xmit retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc:start_xmit retval on ttyC%d was "
+ "%x\n", info->line, retval);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
#else /* CONFIG_CYZ_INTR */
/* Don't have to do anything at this time */
#endif /* CONFIG_CYZ_INTR */
@@ -2201,30 +2134,30 @@ static void start_xmit(struct cyclades_port *info)
*/
static void shutdown(struct cyclades_port *info)
{
+ struct cyclades_card *card;
unsigned long flags;
void __iomem *base_addr;
- int card, chip, channel, index;
+ int chip, channel, index;
if (!(info->flags & ASYNC_INITIALIZED)) {
return;
}
card = info->card;
- channel = info->line - cy_card[card].first_line;
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr = cy_card[card].base_addr +
- (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
#ifdef CY_DEBUG_OPEN
- printk("cyc shutdown Y card %d, chip %d, channel %d, "
- "base_addr %lx\n",
- card, chip, channel, (long)base_addr);
+ printk(KERN_DEBUG "cyc shutdown Y card %d, chip %d, "
+ "channel %d, base_addr %p\n",
+ card, chip, channel, base_addr);
#endif
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
/* Clear delta_msr_wait queue to avoid mem leaks. */
wake_up_interruptible(&info->delta_msr_wait);
@@ -2240,10 +2173,10 @@ static void shutdown(struct cyclades_port *info)
cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS);
cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR);
#ifdef CY_DEBUG_DTR
- printk("cyc shutdown dropping DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr + (CyMSVR1 << index)),
- cy_readb(base_addr + (CyMSVR2 << index)));
+ printk(KERN_DEBUG "cyc shutdown dropping DTR\n");
+ printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
+ readb(base_addr + (CyMSVR1 << index)),
+ readb(base_addr + (CyMSVR2 << index)));
#endif
}
cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index);
@@ -2254,7 +2187,7 @@ static void shutdown(struct cyclades_port *info)
set_bit(TTY_IO_ERROR, &info->tty->flags);
}
info->flags &= ~ASYNC_INITIALIZED;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} else {
struct FIRM_ID __iomem *firm_id;
struct ZFW_CTRL __iomem *zfw_ctrl;
@@ -2262,23 +2195,23 @@ static void shutdown(struct cyclades_port *info)
struct CH_CTRL __iomem *ch_ctrl;
int retval;
- base_addr = cy_card[card].base_addr;
+ base_addr = card->base_addr;
#ifdef CY_DEBUG_OPEN
- printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n",
- card, channel, (long)base_addr);
+ printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, "
+ "base_addr %p\n", card, channel, base_addr);
#endif
firm_id = base_addr + ID_ADDRESS;
- if (!ISZLOADED(cy_card[card])) {
+ if (!ISZLOADED(*card)) {
return;
}
- zfw_ctrl = cy_card[card].base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ zfw_ctrl = card->base_addr +
+ (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
if (info->xmit_buf) {
unsigned char *temp;
@@ -2289,16 +2222,16 @@ static void shutdown(struct cyclades_port *info)
if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
cy_writel(&ch_ctrl[channel].rs_control,
- (uclong)(cy_readl(&ch_ctrl[channel].rs_control)&
+ (__u32)(readl(&ch_ctrl[channel].rs_control) &
~(C_RS_RTS | C_RS_DTR)));
- retval = cyz_issue_cmd(&cy_card[info->card], channel,
+ retval = cyz_issue_cmd(info->card, channel,
C_CM_IOCTLM, 0L);
if (retval != 0) {
- printk("cyc:shutdown retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR"cyc:shutdown retval on ttyC%d "
+ "was %x\n", info->line, retval);
}
#ifdef CY_DEBUG_DTR
- printk("cyc:shutdown dropping Z DTR\n");
+ printk(KERN_DEBUG "cyc:shutdown dropping Z DTR\n");
#endif
}
@@ -2307,11 +2240,11 @@ static void shutdown(struct cyclades_port *info)
}
info->flags &= ~ASYNC_INITIALIZED;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
#ifdef CY_DEBUG_OPEN
- printk(" cyc shutdown done\n");
+ printk(KERN_DEBUG "cyc shutdown done\n");
#endif
} /* shutdown */
@@ -2332,7 +2265,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
int retval;
void __iomem *base_addr;
- cinfo = &cy_card[info->card];
+ cinfo = info->card;
channel = info->line - cinfo->first_line;
/*
@@ -2340,9 +2273,8 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
* until it's done, and then try again.
*/
if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
- if (info->flags & ASYNC_CLOSING) {
- interruptible_sleep_on(&info->close_wait);
- }
+ wait_event_interruptible(info->close_wait,
+ !(info->flags & ASYNC_CLOSING));
return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
}
@@ -2365,17 +2297,16 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
retval = 0;
add_wait_queue(&info->open_wait, &wait);
#ifdef CY_DEBUG_OPEN
- printk("cyc block_til_ready before block: ttyC%d, count = %d\n",
- info->line, info->count);
- /**/
+ printk(KERN_DEBUG "cyc block_til_ready before block: ttyC%d, "
+ "count = %d\n", info->line, info->count);
#endif
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&cinfo->card_lock, flags);
if (!tty_hung_up_p(filp))
info->count--;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&cinfo->card_lock, flags);
#ifdef CY_DEBUG_COUNT
- printk("cyc block_til_ready: (%d): decrementing count to %d\n",
- current->pid, info->count);
+ printk(KERN_DEBUG "cyc block_til_ready: (%d): decrementing count to "
+ "%d\n", current->pid, info->count);
#endif
info->blocked_open++;
@@ -2386,7 +2317,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
while (1) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&cinfo->card_lock, flags);
if ((tty->termios->c_cflag & CBAUD)) {
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
@@ -2395,15 +2326,14 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
cy_writeb(base_addr + (CyMSVR2 << index),
CyDTR);
#ifdef CY_DEBUG_DTR
- printk("cyc:block_til_ready raising DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr +
- (CyMSVR1 << index)),
- cy_readb(base_addr +
- (CyMSVR2 << index)));
+ printk(KERN_DEBUG "cyc:block_til_ready raising "
+ "DTR\n");
+ printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
+ readb(base_addr + (CyMSVR1 << index)),
+ readb(base_addr + (CyMSVR2 << index)));
#endif
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&cinfo->card_lock, flags);
set_current_state(TASK_INTERRUPTIBLE);
if (tty_hung_up_p(filp) ||
@@ -2413,26 +2343,25 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
break;
}
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&cinfo->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
- (cy_readb(base_addr +
+ (readb(base_addr +
(CyMSVR1 << index)) & CyDCD))) {
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&cinfo->card_lock, flags);
break;
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&cinfo->card_lock, flags);
if (signal_pending(current)) {
retval = -ERESTARTSYS;
break;
}
#ifdef CY_DEBUG_OPEN
- printk("cyc block_til_ready blocking: ttyC%d, "
- "count = %d\n",
- info->line, info->count);
- /**/
+ printk(KERN_DEBUG "cyc block_til_ready blocking: "
+ "ttyC%d, count = %d\n",
+ info->line, info->count);
#endif
schedule();
}
@@ -2446,31 +2375,30 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
base_addr = cinfo->base_addr;
firm_id = base_addr + ID_ADDRESS;
if (!ISZLOADED(*cinfo)) {
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&info->open_wait, &wait);
return -EINVAL;
}
- zfw_ctrl = base_addr + (cy_readl(&firm_id->zfwctrl_addr) &
- 0xfffff);
+ zfw_ctrl = base_addr + (readl(&firm_id->zfwctrl_addr)& 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
while (1) {
if ((tty->termios->c_cflag & CBAUD)) {
cy_writel(&ch_ctrl[channel].rs_control,
- cy_readl(&ch_ctrl[channel].
- rs_control) | (C_RS_RTS |
- C_RS_DTR));
- retval = cyz_issue_cmd(&cy_card[info->card],
- channel, C_CM_IOCTLM, 0L);
+ readl(&ch_ctrl[channel].rs_control) |
+ C_RS_RTS | C_RS_DTR);
+ retval = cyz_issue_cmd(cinfo,
+ channel, C_CM_IOCTLM, 0L);
if (retval != 0) {
- printk("cyc:block_til_ready retval on "
- "ttyC%d was %x\n",
+ printk(KERN_ERR "cyc:block_til_ready "
+ "retval on ttyC%d was %x\n",
info->line, retval);
}
#ifdef CY_DEBUG_DTR
- printk("cyc:block_til_ready raising Z DTR\n");
+ printk(KERN_DEBUG "cyc:block_til_ready raising "
+ "Z DTR\n");
#endif
}
@@ -2482,7 +2410,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
break;
}
if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
- (cy_readl(&ch_ctrl[channel].rs_status) &
+ (readl(&ch_ctrl[channel].rs_status) &
C_RS_DCD))) {
break;
}
@@ -2491,28 +2419,26 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
break;
}
#ifdef CY_DEBUG_OPEN
- printk("cyc block_til_ready blocking: ttyC%d, "
- "count = %d\n",
- info->line, info->count);
- /**/
+ printk(KERN_DEBUG "cyc block_til_ready blocking: "
+ "ttyC%d, count = %d\n",
+ info->line, info->count);
#endif
schedule();
}
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&info->open_wait, &wait);
if (!tty_hung_up_p(filp)) {
info->count++;
#ifdef CY_DEBUG_COUNT
- printk("cyc:block_til_ready (%d): incrementing count to %d\n",
- current->pid, info->count);
+ printk(KERN_DEBUG "cyc:block_til_ready (%d): incrementing "
+ "count to %d\n", current->pid, info->count);
#endif
}
info->blocked_open--;
#ifdef CY_DEBUG_OPEN
- printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n",
- info->line, info->count);
- /**/
+ printk(KERN_DEBUG "cyc:block_til_ready after blocking: ttyC%d, "
+ "count = %d\n", info->line, info->count);
#endif
if (retval)
return retval;
@@ -2527,13 +2453,20 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
static int cy_open(struct tty_struct *tty, struct file *filp)
{
struct cyclades_port *info;
+ unsigned int i;
int retval, line;
line = tty->index;
if ((line < 0) || (NR_PORTS <= line)) {
return -ENODEV;
}
- info = &cy_port[line];
+ for (i = 0; i < NR_CARDS; i++)
+ if (line < cy_card[i].first_line + cy_card[i].nports &&
+ line >= cy_card[i].first_line)
+ break;
+ if (i >= NR_CARDS)
+ return -ENODEV;
+ info = &cy_card[i].ports[line - cy_card[i].first_line];
if (info->line < 0) {
return -ENODEV;
}
@@ -2542,23 +2475,23 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
treat it as absent from the system. This
will make the user pay attention.
*/
- if (IS_CYC_Z(cy_card[info->card])) {
- struct cyclades_card *cinfo = &cy_card[info->card];
+ if (IS_CYC_Z(*info->card)) {
+ struct cyclades_card *cinfo = info->card;
struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS;
if (!ISZLOADED(*cinfo)) {
- if (((ZE_V1 == cy_readl(
- &((struct RUNTIME_9060 __iomem *)
+ if (((ZE_V1 == readl(&((struct RUNTIME_9060 __iomem *)
(cinfo->ctl_addr))->mail_box_0)) &&
Z_FPGA_CHECK(*cinfo)) &&
- (ZFIRM_HLT == cy_readl(
+ (ZFIRM_HLT == readl(
&firm_id->signature))) {
- printk("cyc:Cyclades-Z Error: you need an "
- "external power supply for this number "
- "of ports.\n\rFirmware halted.\r\n");
+ printk(KERN_ERR "cyc:Cyclades-Z Error: you "
+ "need an external power supply for "
+ "this number of ports.\nFirmware "
+ "halted.\n");
} else {
- printk("cyc:Cyclades-Z firmware not yet "
- "loaded\n");
+ printk(KERN_ERR "cyc:Cyclades-Z firmware not "
+ "yet loaded\n");
}
return -ENODEV;
}
@@ -2572,24 +2505,23 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
struct BOARD_CTRL __iomem *board_ctrl;
zfw_ctrl = cinfo->base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) &
- 0xfffff);
+ (readl(&firm_id->zfwctrl_addr) &
+ 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
/* Enable interrupts on the PLX chip */
cy_writew(cinfo->ctl_addr + 0x68,
- cy_readw(cinfo->ctl_addr +
- 0x68) | 0x0900);
+ readw(cinfo->ctl_addr + 0x68) | 0x0900);
/* Enable interrupts on the FW */
retval = cyz_issue_cmd(cinfo, 0,
C_CM_IRQ_ENBL, 0L);
if (retval != 0) {
- printk("cyc:IRQ enable retval was %x\n",
- retval);
+ printk(KERN_ERR "cyc:IRQ enable retval "
+ "was %x\n", retval);
}
cinfo->nports =
- (int)cy_readl(&board_ctrl->n_channel);
+ (int)readl(&board_ctrl->n_channel);
cinfo->intr_enabled = 1;
}
}
@@ -2599,7 +2531,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
return -ENODEV;
}
#ifdef CY_DEBUG_OTHER
- printk("cyc:cy_open ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line);
#endif
tty->driver_data = info;
info->tty = tty;
@@ -2607,12 +2539,12 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
return -ENODEV;
}
#ifdef CY_DEBUG_OPEN
- printk("cyc:cy_open ttyC%d, count = %d\n", info->line, info->count);
- /**/
+ printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line,
+ info->count);
#endif
info->count++;
#ifdef CY_DEBUG_COUNT
- printk("cyc:cy_open (%d): incrementing count to %d\n",
+ printk(KERN_DEBUG "cyc:cy_open (%d): incrementing count to %d\n",
current->pid, info->count);
#endif
@@ -2620,8 +2552,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
* If the port is the middle of closing, bail out now
*/
if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
- if (info->flags & ASYNC_CLOSING)
- interruptible_sleep_on(&info->close_wait);
+ wait_event_interruptible(info->close_wait,
+ !(info->flags & ASYNC_CLOSING));
return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
}
@@ -2636,8 +2568,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
retval = block_til_ready(tty, filp, info);
if (retval) {
#ifdef CY_DEBUG_OPEN
- printk("cyc:cy_open returning after block_til_ready with %d\n",
- retval);
+ printk(KERN_DEBUG "cyc:cy_open returning after block_til_ready "
+ "with %d\n", retval);
#endif
return retval;
}
@@ -2645,8 +2577,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
info->throttle = 0;
#ifdef CY_DEBUG_OPEN
- printk(" cyc:cy_open done\n");
- /**/
+ printk(KERN_DEBUG "cyc:cy_open done\n");
#endif
return 0;
} /* cy_open */
@@ -2656,9 +2587,10 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
*/
static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_card *card;
+ struct cyclades_port *info = tty->driver_data;
void __iomem *base_addr;
- int card, chip, channel, index;
+ int chip, channel, index;
unsigned long orig_jiffies;
int char_time;
@@ -2697,20 +2629,19 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
if (!timeout || timeout > 2 * info->timeout)
timeout = 2 * info->timeout;
#ifdef CY_DEBUG_WAIT_UNTIL_SENT
- printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time);
- printk("jiff=%lu...", jiffies);
+ printk(KERN_DEBUG "In cy_wait_until_sent(%d) check=%d, jiff=%lu...",
+ timeout, char_time, jiffies);
#endif
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = (info->line) - (card->first_line);
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
- while (cy_readb(base_addr + (CySRER << index)) & CyTxRdy) {
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
+ while (readb(base_addr + (CySRER << index)) & CyTxRdy) {
#ifdef CY_DEBUG_WAIT_UNTIL_SENT
- printk("Not clean (jiff=%lu)...", jiffies);
+ printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies);
#endif
if (msleep_interruptible(jiffies_to_msecs(char_time)))
break;
@@ -2718,13 +2649,11 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
timeout))
break;
}
- } else {
- /* Nothing to do! */
}
/* Run one more char cycle */
msleep_interruptible(jiffies_to_msecs(char_time * 5));
#ifdef CY_DEBUG_WAIT_UNTIL_SENT
- printk("Clean (jiff=%lu)...done\n", jiffies);
+ printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies);
#endif
}
@@ -2733,25 +2662,29 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
*/
static void cy_close(struct tty_struct *tty, struct file *filp)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
unsigned long flags;
#ifdef CY_DEBUG_OTHER
- printk("cyc:cy_close ttyC%d\n", info->line);
+ printk(KERN_DEBUG "cyc:cy_close ttyC%d\n", info->line);
#endif
if (!info || serial_paranoia_check(info, tty->name, "cy_close")) {
return;
}
- CY_LOCK(info, flags);
+ card = info->card;
+
+ spin_lock_irqsave(&card->card_lock, flags);
/* If the TTY is being hung up, nothing to do */
if (tty_hung_up_p(filp)) {
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
return;
}
#ifdef CY_DEBUG_OPEN
- printk("cyc:cy_close ttyC%d, count = %d\n", info->line, info->count);
+ printk(KERN_DEBUG "cyc:cy_close ttyC%d, count = %d\n", info->line,
+ info->count);
#endif
if ((tty->count == 1) && (info->count != 1)) {
/*
@@ -2761,22 +2694,22 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
* one, we've got real problems, since it means the
* serial port won't be shutdown.
*/
- printk("cyc:cy_close: bad serial port count; tty->count is 1, "
- "info->count is %d\n", info->count);
+ printk(KERN_ERR "cyc:cy_close: bad serial port count; "
+ "tty->count is 1, info->count is %d\n", info->count);
info->count = 1;
}
#ifdef CY_DEBUG_COUNT
- printk("cyc:cy_close at (%d): decrementing count to %d\n",
+ printk(KERN_DEBUG "cyc:cy_close at (%d): decrementing count to %d\n",
current->pid, info->count - 1);
#endif
if (--info->count < 0) {
#ifdef CY_DEBUG_COUNT
- printk("cyc:cyc_close setting count to 0\n");
+ printk(KERN_DEBUG "cyc:cyc_close setting count to 0\n");
#endif
info->count = 0;
}
if (info->count) {
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
return;
}
info->flags |= ASYNC_CLOSING;
@@ -2786,81 +2719,80 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
* the line discipline to only process XON/XOFF characters.
*/
tty->closing = 1;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
if (info->closing_wait != CY_CLOSING_WAIT_NONE) {
tty_wait_until_sent(tty, info->closing_wait);
}
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
- if (!IS_CYC_Z(cy_card[info->card])) {
- int channel = info->line - cy_card[info->card].first_line;
- int index = cy_card[info->card].bus_index;
- void __iomem *base_addr = cy_card[info->card].base_addr +
+ if (!IS_CYC_Z(*card)) {
+ int channel = info->line - card->first_line;
+ int index = card->bus_index;
+ void __iomem *base_addr = card->base_addr +
(cy_chip_offset[channel >> 2] << index);
/* Stop accepting input */
channel &= 0x03;
cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index)) & ~CyRxData);
+ readb(base_addr + (CySRER << index)) & ~CyRxData);
if (info->flags & ASYNC_INITIALIZED) {
/* Waiting for on-board buffers to be empty before closing
the port */
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
cy_wait_until_sent(tty, info->timeout);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
}
} else {
#ifdef Z_WAKE
/* Waiting for on-board buffers to be empty before closing the port */
- void __iomem *base_addr = cy_card[info->card].base_addr;
+ void __iomem *base_addr = card->base_addr;
struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS;
struct ZFW_CTRL __iomem *zfw_ctrl =
- base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl;
- int channel = info->line - cy_card[info->card].first_line;
+ int channel = info->line - card->first_line;
int retval;
- if (cy_readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) {
- retval = cyz_issue_cmd(&cy_card[info->card], channel,
- C_CM_IOCTLW, 0L);
+ if (readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) {
+ retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L);
if (retval != 0) {
- printk("cyc:cy_close retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_DEBUG "cyc:cy_close retval on "
+ "ttyC%d was %x\n", info->line, retval);
}
- CY_UNLOCK(info, flags);
- interruptible_sleep_on(&info->shutdown_wait);
- CY_LOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
+ wait_for_completion_interruptible(&info->shutdown_wait);
+ spin_lock_irqsave(&card->card_lock, flags);
}
#endif
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
shutdown(info);
if (tty->driver->flush_buffer)
tty->driver->flush_buffer(tty);
tty_ldisc_flush(tty);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
tty->closing = 0;
info->event = 0;
info->tty = NULL;
if (info->blocked_open) {
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
if (info->close_delay) {
msleep_interruptible(jiffies_to_msecs
(info->close_delay));
}
wake_up_interruptible(&info->open_wait);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
}
info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
wake_up_interruptible(&info->close_wait);
#ifdef CY_DEBUG_OTHER
- printk(" cyc:cy_close done\n");
+ printk(KERN_DEBUG "cyc:cy_close done\n");
#endif
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} /* cy_close */
/* This routine gets called when tty_write has put something into
@@ -2878,12 +2810,12 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
*/
static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
unsigned long flags;
int c, ret = 0;
#ifdef CY_DEBUG_IO
- printk("cyc:cy_write ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_write ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_write")) {
@@ -2893,7 +2825,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
if (!info->xmit_buf)
return 0;
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&info->card->card_lock, flags);
while (1) {
c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1),
(int)(SERIAL_XMIT_SIZE - info->xmit_head)));
@@ -2909,7 +2841,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
count -= c;
ret += c;
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&info->card->card_lock, flags);
info->idle_stats.xmit_bytes += ret;
info->idle_stats.xmit_idle = jiffies;
@@ -2929,11 +2861,11 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
*/
static void cy_put_char(struct tty_struct *tty, unsigned char ch)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
unsigned long flags;
#ifdef CY_DEBUG_IO
- printk("cyc:cy_put_char ttyC%d\n", info->line);
+ printk(KERN_DEBUG "cyc:cy_put_char ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_put_char"))
@@ -2942,9 +2874,9 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch)
if (!info->xmit_buf)
return;
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&info->card->card_lock, flags);
if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) {
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&info->card->card_lock, flags);
return;
}
@@ -2953,7 +2885,7 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch)
info->xmit_cnt++;
info->idle_stats.xmit_bytes++;
info->idle_stats.xmit_idle = jiffies;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&info->card->card_lock, flags);
} /* cy_put_char */
/*
@@ -2962,10 +2894,10 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch)
*/
static void cy_flush_chars(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
#ifdef CY_DEBUG_IO
- printk("cyc:cy_flush_chars ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_flush_chars ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_flush_chars"))
@@ -2986,11 +2918,11 @@ static void cy_flush_chars(struct tty_struct *tty)
*/
static int cy_write_room(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
int ret;
#ifdef CY_DEBUG_IO
- printk("cyc:cy_write_room ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_write_room ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_write_room"))
@@ -3003,46 +2935,49 @@ static int cy_write_room(struct tty_struct *tty)
static int cy_chars_in_buffer(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- int card, channel;
+ struct cyclades_card *card;
+ struct cyclades_port *info = tty->driver_data;
+ int channel;
if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
return 0;
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
+ channel = (info->line) - (card->first_line);
#ifdef Z_EXT_CHARS_IN_BUFFER
if (!IS_CYC_Z(cy_card[card])) {
#endif /* Z_EXT_CHARS_IN_BUFFER */
#ifdef CY_DEBUG_IO
- printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt); /* */
+ printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
+ info->line, info->xmit_cnt);
#endif
return info->xmit_cnt;
#ifdef Z_EXT_CHARS_IN_BUFFER
} else {
- static volatile struct FIRM_ID *firm_id;
- static volatile struct ZFW_CTRL *zfw_ctrl;
- static volatile struct CH_CTRL *ch_ctrl;
- static volatile struct BUF_CTRL *buf_ctrl;
+ static struct FIRM_ID *firm_id;
+ static struct ZFW_CTRL *zfw_ctrl;
+ static struct CH_CTRL *ch_ctrl;
+ static struct BUF_CTRL *buf_ctrl;
int char_count;
- volatile uclong tx_put, tx_get, tx_bufsize;
+ __u32 tx_put, tx_get, tx_bufsize;
- firm_id = cy_card[card].base_addr + ID_ADDRESS;
- zfw_ctrl = cy_card[card].base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ firm_id = card->base_addr + ID_ADDRESS;
+ zfw_ctrl = card->base_addr +
+ (readl(&firm_id->zfwctrl_addr) & 0xfffff);
ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
- tx_get = cy_readl(&buf_ctrl->tx_get);
- tx_put = cy_readl(&buf_ctrl->tx_put);
- tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize);
+ tx_get = readl(&buf_ctrl->tx_get);
+ tx_put = readl(&buf_ctrl->tx_put);
+ tx_bufsize = readl(&buf_ctrl->tx_bufsize);
if (tx_put >= tx_get)
char_count = tx_put - tx_get;
else
char_count = tx_put - tx_get + tx_bufsize;
#ifdef CY_DEBUG_IO
- printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt + char_count); /* */
+ printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
+ info->line, info->xmit_cnt + char_count);
#endif
return info->xmit_cnt + char_count;
}
@@ -3055,10 +2990,10 @@ static int cy_chars_in_buffer(struct tty_struct *tty)
* ------------------------------------------------------------
*/
-static void cyy_baud_calc(struct cyclades_port *info, uclong baud)
+static void cyy_baud_calc(struct cyclades_port *info, __u32 baud)
{
int co, co_val, bpr;
- uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 :
+ __u32 cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 :
25000000);
if (baud == 0) {
@@ -3086,9 +3021,10 @@ static void cyy_baud_calc(struct cyclades_port *info, uclong baud)
*/
static void set_line_char(struct cyclades_port *info)
{
+ struct cyclades_card *card;
unsigned long flags;
void __iomem *base_addr;
- int card, chip, channel, index;
+ int chip, channel, index;
unsigned cflag, iflag;
unsigned short chip_number;
int baud, baud_rate = 0;
@@ -3118,12 +3054,12 @@ static void set_line_char(struct cyclades_port *info)
}
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
+ channel = info->line - card->first_line;
chip_number = channel / 4;
- if (!IS_CYC_Z(cy_card[card])) {
+ if (!IS_CYC_Z(*card)) {
- index = cy_card[card].bus_index;
+ index = card->bus_index;
/* baud rate */
baud = tty_get_baud_rate(info->tty);
@@ -3241,10 +3177,9 @@ static void set_line_char(struct cyclades_port *info)
chip = channel >> 2;
channel &= 0x03;
- base_addr = cy_card[card].base_addr +
- (cy_chip_offset[chip] << index);
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
/* tx and rx baud rate */
@@ -3276,8 +3211,7 @@ static void set_line_char(struct cyclades_port *info)
if (C_CLOCAL(info->tty)) {
/* without modem intr */
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr +
- (CySRER << index)) | CyMdmCh);
+ readb(base_addr + (CySRER << index)) | CyMdmCh);
/* act on 1->0 modem transitions */
if ((cflag & CRTSCTS) && info->rflow) {
cy_writeb(base_addr + (CyMCOR1 << index),
@@ -3291,7 +3225,7 @@ static void set_line_char(struct cyclades_port *info)
} else {
/* without modem intr */
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr +
+ readb(base_addr +
(CySRER << index)) | CyMdmCh);
/* act on 1->0 modem transitions */
if ((cflag & CRTSCTS) && info->rflow) {
@@ -3316,10 +3250,10 @@ static void set_line_char(struct cyclades_port *info)
~CyDTR);
}
#ifdef CY_DEBUG_DTR
- printk("cyc:set_line_char dropping DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr + (CyMSVR1 << index)),
- cy_readb(base_addr + (CyMSVR2 << index)));
+ printk(KERN_DEBUG "cyc:set_line_char dropping DTR\n");
+ printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
+ readb(base_addr + (CyMSVR1 << index)),
+ readb(base_addr + (CyMSVR2 << index)));
#endif
} else {
if (info->rtsdtr_inv) {
@@ -3330,17 +3264,17 @@ static void set_line_char(struct cyclades_port *info)
CyDTR);
}
#ifdef CY_DEBUG_DTR
- printk("cyc:set_line_char raising DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr + (CyMSVR1 << index)),
- cy_readb(base_addr + (CyMSVR2 << index)));
+ printk(KERN_DEBUG "cyc:set_line_char raising DTR\n");
+ printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
+ readb(base_addr + (CyMSVR1 << index)),
+ readb(base_addr + (CyMSVR2 << index)));
#endif
}
if (info->tty) {
clear_bit(TTY_IO_ERROR, &info->tty->flags);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} else {
struct FIRM_ID __iomem *firm_id;
@@ -3348,16 +3282,16 @@ static void set_line_char(struct cyclades_port *info)
struct BOARD_CTRL __iomem *board_ctrl;
struct CH_CTRL __iomem *ch_ctrl;
struct BUF_CTRL __iomem *buf_ctrl;
- uclong sw_flow;
+ __u32 sw_flow;
int retval;
- firm_id = cy_card[card].base_addr + ID_ADDRESS;
- if (!ISZLOADED(cy_card[card])) {
+ firm_id = card->base_addr + ID_ADDRESS;
+ if (!ISZLOADED(*card)) {
return;
}
- zfw_ctrl = cy_card[card].base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ zfw_ctrl = card->base_addr +
+ (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
@@ -3408,10 +3342,10 @@ static void set_line_char(struct cyclades_port *info)
}
if (cflag & CSTOPB) {
cy_writel(&ch_ctrl->comm_data_l,
- cy_readl(&ch_ctrl->comm_data_l) | C_DL_2STOP);
+ readl(&ch_ctrl->comm_data_l) | C_DL_2STOP);
} else {
cy_writel(&ch_ctrl->comm_data_l,
- cy_readl(&ch_ctrl->comm_data_l) | C_DL_1STOP);
+ readl(&ch_ctrl->comm_data_l) | C_DL_1STOP);
}
if (cflag & PARENB) {
if (cflag & PARODD) {
@@ -3426,12 +3360,10 @@ static void set_line_char(struct cyclades_port *info)
/* CTS flow control flag */
if (cflag & CRTSCTS) {
cy_writel(&ch_ctrl->hw_flow,
- cy_readl(&ch_ctrl->
- hw_flow) | C_RS_CTS | C_RS_RTS);
+ readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS);
} else {
- cy_writel(&ch_ctrl->hw_flow,
- cy_readl(&ch_ctrl->
- hw_flow) & ~(C_RS_CTS | C_RS_RTS));
+ cy_writel(&ch_ctrl->hw_flow, readl(&ch_ctrl->hw_flow) &
+ ~(C_RS_CTS | C_RS_RTS));
}
/* As the HW flow control is done in firmware, the driver
doesn't need to care about it */
@@ -3446,10 +3378,10 @@ static void set_line_char(struct cyclades_port *info)
}
cy_writel(&ch_ctrl->sw_flow, sw_flow);
- retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L);
+ retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L);
if (retval != 0) {
- printk("cyc:set_line_char retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc:set_line_char retval on ttyC%d "
+ "was %x\n", info->line, retval);
}
/* CD sensitivity */
@@ -3461,22 +3393,22 @@ static void set_line_char(struct cyclades_port *info)
if (baud == 0) { /* baud rate is zero, turn off line */
cy_writel(&ch_ctrl->rs_control,
- cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR);
+ readl(&ch_ctrl->rs_control) & ~C_RS_DTR);
#ifdef CY_DEBUG_DTR
- printk("cyc:set_line_char dropping Z DTR\n");
+ printk(KERN_DEBUG "cyc:set_line_char dropping Z DTR\n");
#endif
} else {
cy_writel(&ch_ctrl->rs_control,
- cy_readl(&ch_ctrl->rs_control) | C_RS_DTR);
+ readl(&ch_ctrl->rs_control) | C_RS_DTR);
#ifdef CY_DEBUG_DTR
- printk("cyc:set_line_char raising Z DTR\n");
+ printk(KERN_DEBUG "cyc:set_line_char raising Z DTR\n");
#endif
}
- retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTLM,0L);
+ retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM,0L);
if (retval != 0) {
- printk("cyc:set_line_char(2) retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc:set_line_char(2) retval on ttyC%d "
+ "was %x\n", info->line, retval);
}
if (info->tty) {
@@ -3490,14 +3422,15 @@ get_serial_info(struct cyclades_port *info,
struct serial_struct __user * retinfo)
{
struct serial_struct tmp;
- struct cyclades_card *cinfo = &cy_card[info->card];
+ struct cyclades_card *cinfo = info->card;
if (!retinfo)
return -EFAULT;
memset(&tmp, 0, sizeof(tmp));
tmp.type = info->type;
tmp.line = info->line;
- tmp.port = info->card * 0x100 + info->line - cinfo->first_line;
+ tmp.port = (info->card - cy_card) * 0x100 + info->line -
+ cinfo->first_line;
tmp.irq = cinfo->irq;
tmp.flags = info->flags;
tmp.close_delay = info->close_delay;
@@ -3566,25 +3499,25 @@ check_and_exit:
*/
static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value)
{
- int card, chip, channel, index;
+ struct cyclades_card *card;
+ int chip, channel, index;
unsigned char status;
unsigned int result;
unsigned long flags;
void __iomem *base_addr;
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = (info->line) - (card->first_line);
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
- status = cy_readb(base_addr + (CySRER << index)) &
+ spin_lock_irqsave(&card->card_lock, flags);
+ status = readb(base_addr + (CySRER << index)) &
(CyTxRdy | CyTxMpty);
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
result = (status ? 0 : TIOCSER_TEMT);
} else {
/* Not supported yet */
@@ -3595,8 +3528,9 @@ static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value)
static int cy_tiocmget(struct tty_struct *tty, struct file *file)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- int card, chip, channel, index;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
+ int chip, channel, index;
void __iomem *base_addr;
unsigned long flags;
unsigned char status;
@@ -3611,19 +3545,18 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file)
return -ENODEV;
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
- status = cy_readb(base_addr + (CyMSVR1 << index));
- status |= cy_readb(base_addr + (CyMSVR2 << index));
- CY_UNLOCK(info, flags);
+ status = readb(base_addr + (CyMSVR1 << index));
+ status |= readb(base_addr + (CyMSVR2 << index));
+ spin_unlock_irqrestore(&card->card_lock, flags);
if (info->rtsdtr_inv) {
result = ((status & CyRTS) ? TIOCM_DTR : 0) |
@@ -3637,19 +3570,14 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file)
((status & CyDSR) ? TIOCM_DSR : 0) |
((status & CyCTS) ? TIOCM_CTS : 0);
} else {
- base_addr = cy_card[card].base_addr;
-
- if (cy_card[card].num_chips != -1) {
- return -EINVAL;
- }
-
- firm_id = cy_card[card].base_addr + ID_ADDRESS;
- if (ISZLOADED(cy_card[card])) {
- zfw_ctrl = cy_card[card].base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ base_addr = card->base_addr;
+ firm_id = card->base_addr + ID_ADDRESS;
+ if (ISZLOADED(*card)) {
+ zfw_ctrl = card->base_addr +
+ (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
- lstatus = cy_readl(&ch_ctrl[channel].rs_status);
+ lstatus = readl(&ch_ctrl[channel].rs_status);
result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) |
((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) |
((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) |
@@ -3669,8 +3597,9 @@ static int
cy_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- int card, chip, channel, index;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
+ int chip, channel, index;
void __iomem *base_addr;
unsigned long flags;
struct FIRM_ID __iomem *firm_id;
@@ -3683,16 +3612,15 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
return -ENODEV;
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = (info->line) - (card->first_line);
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
if (set & TIOCM_RTS) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
if (info->rtsdtr_inv) {
@@ -3702,10 +3630,10 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
cy_writeb(base_addr + (CyMSVR1 << index),
CyRTS);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
if (clear & TIOCM_RTS) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
if (info->rtsdtr_inv) {
@@ -3715,10 +3643,10 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
cy_writeb(base_addr + (CyMSVR1 << index),
~CyRTS);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
if (set & TIOCM_DTR) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
if (info->rtsdtr_inv) {
@@ -3729,15 +3657,15 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
CyDTR);
}
#ifdef CY_DEBUG_DTR
- printk("cyc:set_modem_info raising DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr + (CyMSVR1 << index)),
- cy_readb(base_addr + (CyMSVR2 << index)));
+ printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n");
+ printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
+ readb(base_addr + (CyMSVR1 << index)),
+ readb(base_addr + (CyMSVR2 << index)));
#endif
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
if (clear & TIOCM_DTR) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
if (info->rtsdtr_inv) {
@@ -3749,68 +3677,69 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
}
#ifdef CY_DEBUG_DTR
- printk("cyc:set_modem_info dropping DTR\n");
- printk(" status: 0x%x, 0x%x\n",
- cy_readb(base_addr + (CyMSVR1 << index)),
- cy_readb(base_addr + (CyMSVR2 << index)));
+ printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n");
+ printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
+ readb(base_addr + (CyMSVR1 << index)),
+ readb(base_addr + (CyMSVR2 << index)));
#endif
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
} else {
- base_addr = cy_card[card].base_addr;
+ base_addr = card->base_addr;
- firm_id = cy_card[card].base_addr + ID_ADDRESS;
- if (ISZLOADED(cy_card[card])) {
- zfw_ctrl = cy_card[card].base_addr +
- (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
+ firm_id = card->base_addr + ID_ADDRESS;
+ if (ISZLOADED(*card)) {
+ zfw_ctrl = card->base_addr +
+ (readl(&firm_id->zfwctrl_addr) & 0xfffff);
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
if (set & TIOCM_RTS) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writel(&ch_ctrl[channel].rs_control,
- cy_readl(&ch_ctrl[channel].
- rs_control) | C_RS_RTS);
- CY_UNLOCK(info, flags);
+ readl(&ch_ctrl[channel].rs_control) |
+ C_RS_RTS);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
if (clear & TIOCM_RTS) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writel(&ch_ctrl[channel].rs_control,
- cy_readl(&ch_ctrl[channel].
- rs_control) & ~C_RS_RTS);
- CY_UNLOCK(info, flags);
+ readl(&ch_ctrl[channel].rs_control) &
+ ~C_RS_RTS);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
if (set & TIOCM_DTR) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writel(&ch_ctrl[channel].rs_control,
- cy_readl(&ch_ctrl[channel].
- rs_control) | C_RS_DTR);
+ readl(&ch_ctrl[channel].rs_control) |
+ C_RS_DTR);
#ifdef CY_DEBUG_DTR
- printk("cyc:set_modem_info raising Z DTR\n");
+ printk(KERN_DEBUG "cyc:set_modem_info raising "
+ "Z DTR\n");
#endif
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
if (clear & TIOCM_DTR) {
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writel(&ch_ctrl[channel].rs_control,
- cy_readl(&ch_ctrl[channel].
- rs_control) & ~C_RS_DTR);
+ readl(&ch_ctrl[channel].rs_control) &
+ ~C_RS_DTR);
#ifdef CY_DEBUG_DTR
- printk("cyc:set_modem_info clearing Z DTR\n");
+ printk(KERN_DEBUG "cyc:set_modem_info clearing "
+ "Z DTR\n");
#endif
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
} else {
return -ENODEV;
}
- CY_LOCK(info, flags);
- retval = cyz_issue_cmd(&cy_card[info->card],
- channel, C_CM_IOCTLM, 0L);
+ spin_lock_irqsave(&card->card_lock, flags);
+ retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
if (retval != 0) {
- printk("cyc:set_modem_info retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc:set_modem_info retval on ttyC%d "
+ "was %x\n", info->line, retval);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
return 0;
} /* cy_tiocmset */
@@ -3820,14 +3749,17 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
*/
static void cy_break(struct tty_struct *tty, int break_state)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
unsigned long flags;
if (serial_paranoia_check(info, tty->name, "cy_break"))
return;
- CY_LOCK(info, flags);
- if (!IS_CYC_Z(cy_card[info->card])) {
+ card = info->card;
+
+ spin_lock_irqsave(&card->card_lock, flags);
+ if (!IS_CYC_Z(*card)) {
/* Let the transmit ISR take care of this (since it
requires stuffing characters into the output stream).
*/
@@ -3835,18 +3767,18 @@ static void cy_break(struct tty_struct *tty, int break_state)
if (!info->breakon) {
info->breakon = 1;
if (!info->xmit_cnt) {
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
start_xmit(info);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
}
}
} else {
if (!info->breakoff) {
info->breakoff = 1;
if (!info->xmit_cnt) {
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
start_xmit(info);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
}
}
}
@@ -3854,24 +3786,25 @@ static void cy_break(struct tty_struct *tty, int break_state)
int retval;
if (break_state == -1) {
- retval = cyz_issue_cmd(&cy_card[info->card],
- info->line - cy_card[info->card].first_line,
+ retval = cyz_issue_cmd(card,
+ info->line - card->first_line,
C_CM_SET_BREAK, 0L);
if (retval != 0) {
- printk("cyc:cy_break (set) retval on ttyC%d "
- "was %x\n", info->line, retval);
+ printk(KERN_ERR "cyc:cy_break (set) retval on "
+ "ttyC%d was %x\n", info->line, retval);
}
} else {
- retval = cyz_issue_cmd(&cy_card[info->card],
- info->line - cy_card[info->card].first_line,
+ retval = cyz_issue_cmd(card,
+ info->line - card->first_line,
C_CM_CLR_BREAK, 0L);
if (retval != 0) {
- printk("cyc:cy_break (clr) retval on ttyC%d "
- "was %x\n", info->line, retval);
+ printk(KERN_DEBUG "cyc:cy_break (clr) retval "
+ "on ttyC%d was %x\n", info->line,
+ retval);
}
}
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} /* cy_break */
static int
@@ -3889,28 +3822,27 @@ get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon)
static int set_threshold(struct cyclades_port *info, unsigned long value)
{
+ struct cyclades_card *card;
void __iomem *base_addr;
- int card, channel, chip, index;
+ int channel, chip, index;
unsigned long flags;
card = info->card;
- channel = info->line - cy_card[card].first_line;
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
+ index = card->bus_index;
base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+ card->base_addr + (cy_chip_offset[chip] << index);
info->cor3 &= ~CyREC_FIFO;
info->cor3 |= value & CyREC_FIFO;
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCOR3 << index), info->cor3);
cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index);
- CY_UNLOCK(info, flags);
- } else {
- /* Nothing to do! */
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
return 0;
} /* set_threshold */
@@ -3918,25 +3850,23 @@ static int set_threshold(struct cyclades_port *info, unsigned long value)
static int
get_threshold(struct cyclades_port *info, unsigned long __user * value)
{
+ struct cyclades_card *card;
void __iomem *base_addr;
- int card, channel, chip, index;
+ int channel, chip, index;
unsigned long tmp;
card = info->card;
- channel = info->line - cy_card[card].first_line;
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
- tmp = cy_readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO;
+ tmp = readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO;
return put_user(tmp, value);
- } else {
- /* Nothing to do! */
- return 0;
}
+ return 0;
} /* get_threshold */
static int
@@ -3954,49 +3884,45 @@ get_default_threshold(struct cyclades_port *info, unsigned long __user * value)
static int set_timeout(struct cyclades_port *info, unsigned long value)
{
+ struct cyclades_card *card;
void __iomem *base_addr;
- int card, channel, chip, index;
+ int channel, chip, index;
unsigned long flags;
card = info->card;
- channel = info->line - cy_card[card].first_line;
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyRTPR << index), value & 0xff);
- CY_UNLOCK(info, flags);
- } else {
- /* Nothing to do! */
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
return 0;
} /* set_timeout */
static int get_timeout(struct cyclades_port *info, unsigned long __user * value)
{
+ struct cyclades_card *card;
void __iomem *base_addr;
- int card, channel, chip, index;
+ int channel, chip, index;
unsigned long tmp;
card = info->card;
- channel = info->line - cy_card[card].first_line;
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr =
- cy_card[card].base_addr + (cy_chip_offset[chip] << index);
+ index = card->bus_index;
+ base_addr = card->base_addr + (cy_chip_offset[chip] << index);
- tmp = cy_readb(base_addr + (CyRTPR << index));
+ tmp = readb(base_addr + (CyRTPR << index));
return put_user(tmp, value);
- } else {
- /* Nothing to do! */
- return 0;
}
+ return 0;
} /* get_timeout */
static int set_default_timeout(struct cyclades_port *info, unsigned long value)
@@ -4020,7 +3946,7 @@ static int
cy_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
struct cyclades_icount cprev, cnow; /* kernel counter temps */
struct serial_icounter_struct __user *p_cuser; /* user space */
int ret_val = 0;
@@ -4031,7 +3957,8 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
return -ENODEV;
#ifdef CY_DEBUG_OTHER
- printk("cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", info->line, cmd, arg); /* */
+ printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n",
+ info->line, cmd, arg);
#endif
switch (cmd) {
@@ -4076,14 +4003,6 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
case CYGETRTSDTR_INV:
ret_val = info->rtsdtr_inv;
break;
- case CYGETCARDINFO:
- if (copy_to_user(argp, &cy_card[info->card],
- sizeof(struct cyclades_card))) {
- ret_val = -EFAULT;
- break;
- }
- ret_val = 0;
- break;
case CYGETCD1400VER:
ret_val = info->chip_rev;
break;
@@ -4119,34 +4038,22 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
* Caller should use TIOCGICOUNT to see which one it was
*/
case TIOCMIWAIT:
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&info->card->card_lock, flags);
/* note the counters on entry */
- cprev = info->icount;
- CY_UNLOCK(info, flags);
- while (1) {
- interruptible_sleep_on(&info->delta_msr_wait);
- /* see if a signal did it */
- if (signal_pending(current)) {
- return -ERESTARTSYS;
- }
-
- CY_LOCK(info, flags);
+ cnow = info->icount;
+ spin_unlock_irqrestore(&info->card->card_lock, flags);
+ ret_val = wait_event_interruptible(info->delta_msr_wait, ({
+ cprev = cnow;
+ spin_lock_irqsave(&info->card->card_lock, flags);
cnow = info->icount; /* atomic copy */
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&info->card->card_lock, flags);
- if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
- cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
- return -EIO; /* no change => error */
- }
- if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
- ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
- ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
- ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
- return 0;
- }
- cprev = cnow;
- }
- /* NOTREACHED */
+ ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts));
+ }));
+ break;
/*
* Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
@@ -4155,9 +4062,9 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
* RI where only 0->1 is counted.
*/
case TIOCGICOUNT:
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&info->card->card_lock, flags);
cnow = info->icount;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&info->card->card_lock, flags);
p_cuser = argp;
ret_val = put_user(cnow.cts, &p_cuser->cts);
if (ret_val)
@@ -4199,7 +4106,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
}
#ifdef CY_DEBUG_OTHER
- printk(" cyc:cy_ioctl done\n");
+ printk(KERN_DEBUG "cyc:cy_ioctl done\n");
#endif
return ret_val;
@@ -4213,10 +4120,10 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
*/
static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
#ifdef CY_DEBUG_OTHER
- printk("cyc:cy_set_termios ttyC%d\n", info->line);
+ printk(KERN_DEBUG "cyc:cy_set_termios ttyC%d\n", info->line);
#endif
if (tty->termios->c_cflag == old_termios->c_cflag &&
@@ -4248,8 +4155,9 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
*/
static void cy_send_xchar(struct tty_struct *tty, char ch)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- int card, channel;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
+ int channel;
if (serial_paranoia_check(info, tty->name, "cy_send_xchar"))
return;
@@ -4260,15 +4168,13 @@ static void cy_send_xchar(struct tty_struct *tty, char ch)
cy_start(tty);
card = info->card;
- channel = info->line - cy_card[card].first_line;
+ channel = info->line - card->first_line;
- if (IS_CYC_Z(cy_card[card])) {
+ if (IS_CYC_Z(*card)) {
if (ch == STOP_CHAR(tty))
- cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXOFF,
- 0L);
+ cyz_issue_cmd(card, channel, C_CM_SENDXOFF, 0L);
else if (ch == START_CHAR(tty))
- cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXON,
- 0L);
+ cyz_issue_cmd(card, channel, C_CM_SENDXON, 0L);
}
}
@@ -4278,15 +4184,16 @@ static void cy_send_xchar(struct tty_struct *tty, char ch)
*/
static void cy_throttle(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
unsigned long flags;
void __iomem *base_addr;
- int card, chip, channel, index;
+ int chip, channel, index;
#ifdef CY_DEBUG_THROTTLE
char buf[64];
- printk("cyc:throttle %s: %d....ttyC%d\n", tty_name(tty, buf),
+ printk(KERN_DEBUG "cyc:throttle %s: %ld...ttyC%d\n", tty_name(tty, buf),
tty->ldisc.chars_in_buffer(tty), info->line);
#endif
@@ -4297,22 +4204,22 @@ static void cy_throttle(struct tty_struct *tty)
card = info->card;
if (I_IXOFF(tty)) {
- if (!IS_CYC_Z(cy_card[card]))
+ if (!IS_CYC_Z(*card))
cy_send_xchar(tty, STOP_CHAR(tty));
else
info->throttle = 1;
}
if (tty->termios->c_cflag & CRTSCTS) {
- channel = info->line - cy_card[card].first_line;
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr = cy_card[card].base_addr +
+ index = card->bus_index;
+ base_addr = card->base_addr +
(cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
if (info->rtsdtr_inv) {
@@ -4322,7 +4229,7 @@ static void cy_throttle(struct tty_struct *tty)
cy_writeb(base_addr + (CyMSVR1 << index),
~CyRTS);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} else {
info->throttle = 1;
}
@@ -4336,16 +4243,17 @@ static void cy_throttle(struct tty_struct *tty)
*/
static void cy_unthrottle(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
unsigned long flags;
void __iomem *base_addr;
- int card, chip, channel, index;
+ int chip, channel, index;
#ifdef CY_DEBUG_THROTTLE
char buf[64];
- printk("cyc:unthrottle %s: %d....ttyC%d\n", tty_name(tty, buf),
- tty->ldisc.chars_in_buffer(tty), info->line);
+ printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n",
+ tty_name(tty, buf), tty->ldisc.chars_in_buffer(tty),info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) {
@@ -4361,15 +4269,15 @@ static void cy_unthrottle(struct tty_struct *tty)
if (tty->termios->c_cflag & CRTSCTS) {
card = info->card;
- channel = info->line - cy_card[card].first_line;
- if (!IS_CYC_Z(cy_card[card])) {
+ channel = info->line - card->first_line;
+ if (!IS_CYC_Z(*card)) {
chip = channel >> 2;
channel &= 0x03;
- index = cy_card[card].bus_index;
- base_addr = cy_card[card].base_addr +
+ index = card->bus_index;
+ base_addr = card->base_addr +
(cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char) channel);
if (info->rtsdtr_inv) {
@@ -4379,7 +4287,7 @@ static void cy_unthrottle(struct tty_struct *tty)
cy_writeb(base_addr + (CyMSVR1 << index),
CyRTS);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
} else {
info->throttle = 0;
}
@@ -4392,102 +4300,96 @@ static void cy_unthrottle(struct tty_struct *tty)
static void cy_stop(struct tty_struct *tty)
{
struct cyclades_card *cinfo;
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
void __iomem *base_addr;
int chip, channel, index;
unsigned long flags;
#ifdef CY_DEBUG_OTHER
- printk("cyc:cy_stop ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_stop ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_stop"))
return;
- cinfo = &cy_card[info->card];
+ cinfo = info->card;
channel = info->line - cinfo->first_line;
if (!IS_CYC_Z(*cinfo)) {
index = cinfo->bus_index;
chip = channel >> 2;
channel &= 0x03;
- base_addr = cy_card[info->card].base_addr +
- (cy_chip_offset[chip] << index);
+ base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&cinfo->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index),
(u_char)(channel & 0x0003)); /* index channel */
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index)) & ~CyTxRdy);
- CY_UNLOCK(info, flags);
- } else {
- /* Nothing to do! */
+ readb(base_addr + (CySRER << index)) & ~CyTxRdy);
+ spin_unlock_irqrestore(&cinfo->card_lock, flags);
}
} /* cy_stop */
static void cy_start(struct tty_struct *tty)
{
struct cyclades_card *cinfo;
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
void __iomem *base_addr;
int chip, channel, index;
unsigned long flags;
#ifdef CY_DEBUG_OTHER
- printk("cyc:cy_start ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_start ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_start"))
return;
- cinfo = &cy_card[info->card];
+ cinfo = info->card;
channel = info->line - cinfo->first_line;
index = cinfo->bus_index;
if (!IS_CYC_Z(*cinfo)) {
chip = channel >> 2;
channel &= 0x03;
- base_addr = cy_card[info->card].base_addr +
- (cy_chip_offset[chip] << index);
+ base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&cinfo->card_lock, flags);
cy_writeb(base_addr + (CyCAR << index), (u_char) (channel & 0x0003)); /* index channel */
cy_writeb(base_addr + (CySRER << index),
- cy_readb(base_addr + (CySRER << index)) | CyTxRdy);
- CY_UNLOCK(info, flags);
- } else {
- /* Nothing to do! */
+ readb(base_addr + (CySRER << index)) | CyTxRdy);
+ spin_unlock_irqrestore(&cinfo->card_lock, flags);
}
} /* cy_start */
static void cy_flush_buffer(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- int card, channel, retval;
+ struct cyclades_port *info = tty->driver_data;
+ struct cyclades_card *card;
+ int channel, retval;
unsigned long flags;
#ifdef CY_DEBUG_IO
- printk("cyc:cy_flush_buffer ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
return;
card = info->card;
- channel = (info->line) - (cy_card[card].first_line);
+ channel = info->line - card->first_line;
- CY_LOCK(info, flags);
+ spin_lock_irqsave(&card->card_lock, flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
- if (IS_CYC_Z(cy_card[card])) { /* If it is a Z card, flush the on-board
+ if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board
buffers as well */
- CY_LOCK(info, flags);
- retval =
- cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_TX, 0L);
+ spin_lock_irqsave(&card->card_lock, flags);
+ retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L);
if (retval != 0) {
- printk("cyc: flush_buffer retval on ttyC%d was %x\n",
- info->line, retval);
+ printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d "
+ "was %x\n", info->line, retval);
}
- CY_UNLOCK(info, flags);
+ spin_unlock_irqrestore(&card->card_lock, flags);
}
tty_wakeup(tty);
} /* cy_flush_buffer */
@@ -4497,10 +4399,10 @@ static void cy_flush_buffer(struct tty_struct *tty)
*/
static void cy_hangup(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = tty->driver_data;
#ifdef CY_DEBUG_OTHER
- printk("cyc:cy_hangup ttyC%d\n", info->line); /* */
+ printk(KERN_DEBUG "cyc:cy_hangup ttyC%d\n", info->line);
#endif
if (serial_paranoia_check(info, tty->name, "cy_hangup"))
@@ -4511,7 +4413,8 @@ static void cy_hangup(struct tty_struct *tty)
info->event = 0;
info->count = 0;
#ifdef CY_DEBUG_COUNT
- printk("cyc:cy_hangup (%d): setting count to 0\n", current->pid);
+ printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n",
+ current->pid);
#endif
info->tty = NULL;
info->flags &= ~ASYNC_NORMAL_ACTIVE;
@@ -4526,10 +4429,107 @@ static void cy_hangup(struct tty_struct *tty)
* ---------------------------------------------------------------------
*/
+static int __devinit cy_init_card(struct cyclades_card *cinfo)
+{
+ struct cyclades_port *info;
+ u32 mailbox;
+ unsigned int nports;
+ unsigned short chip_number;
+ int index, port;
+
+ spin_lock_init(&cinfo->card_lock);
+
+ if (IS_CYC_Z(*cinfo)) { /* Cyclades-Z */
+ mailbox = readl(&((struct RUNTIME_9060 __iomem *)
+ cinfo->ctl_addr)->mail_box_0);
+ nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
+ cinfo->intr_enabled = 0;
+ cinfo->nports = 0; /* Will be correctly set later, after
+ Z FW is loaded */
+ } else {
+ index = cinfo->bus_index;
+ nports = cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips;
+ }
+
+ cinfo->ports = kzalloc(sizeof(*cinfo->ports) * nports, GFP_KERNEL);
+ if (cinfo->ports == NULL) {
+ printk(KERN_ERR "Cyclades: cannot allocate ports\n");
+ cinfo->nports = 0;
+ return -ENOMEM;
+ }
+
+ for (port = cinfo->first_line; port < cinfo->first_line + nports;
+ port++) {
+ info = &cinfo->ports[port - cinfo->first_line];
+ info->magic = CYCLADES_MAGIC;
+ info->card = cinfo;
+ info->line = port;
+ info->flags = STD_COM_FLAGS;
+ info->closing_wait = CLOSING_WAIT_DELAY;
+ info->close_delay = 5 * HZ / 10;
+
+ INIT_WORK(&info->tqueue, do_softint);
+ init_waitqueue_head(&info->open_wait);
+ init_waitqueue_head(&info->close_wait);
+ init_completion(&info->shutdown_wait);
+ init_waitqueue_head(&info->delta_msr_wait);
+
+ if (IS_CYC_Z(*cinfo)) {
+ info->type = PORT_STARTECH;
+ if (mailbox == ZO_V1)
+ info->xmit_fifo_size = CYZ_FIFO_SIZE;
+ else
+ info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE;
+#ifdef CONFIG_CYZ_INTR
+ setup_timer(&cyz_rx_full_timer[port],
+ cyz_rx_restart, (unsigned long)info);
+#endif
+ } else {
+ info->type = PORT_CIRRUS;
+ info->xmit_fifo_size = CyMAX_CHAR_FIFO;
+ info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS;
+ info->cor2 = CyETC;
+ info->cor3 = 0x08; /* _very_ small rcv threshold */
+
+ chip_number = (port - cinfo->first_line) / 4;
+ if ((info->chip_rev = readb(cinfo->base_addr +
+ (cy_chip_offset[chip_number] <<
+ index) + (CyGFRCR << index))) >=
+ CD1400_REV_J) {
+ /* It is a CD1400 rev. J or later */
+ info->tbpr = baud_bpr_60[13]; /* Tx BPR */
+ info->tco = baud_co_60[13]; /* Tx CO */
+ info->rbpr = baud_bpr_60[13]; /* Rx BPR */
+ info->rco = baud_co_60[13]; /* Rx CO */
+ info->rtsdtr_inv = 1;
+ } else {
+ info->tbpr = baud_bpr_25[13]; /* Tx BPR */
+ info->tco = baud_co_25[13]; /* Tx CO */
+ info->rbpr = baud_bpr_25[13]; /* Rx BPR */
+ info->rco = baud_co_25[13]; /* Rx CO */
+ info->rtsdtr_inv = 0;
+ }
+ info->read_status_mask = CyTIMEOUT | CySPECHAR |
+ CyBREAK | CyPARITY | CyFRAME | CyOVERRUN;
+ }
+
+ }
+
+#ifndef CONFIG_CYZ_INTR
+ if (IS_CYC_Z(*cinfo) && !timer_pending(&cyz_timerlist)) {
+ mod_timer(&cyz_timerlist, jiffies + 1);
+#ifdef CY_PCI_DEBUG
+ printk(KERN_DEBUG "Cyclades-Z polling initialized\n");
+#endif
+ }
+#endif
+ return 0;
+}
+
/* initialize chips on Cyclom-Y card -- return number of valid
chips (which is number of ports/4) */
-static unsigned short __init
-cyy_init_card(void __iomem * true_base_addr, int index)
+static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr,
+ int index)
{
unsigned int chip_number;
void __iomem *base_addr;
@@ -4544,7 +4544,7 @@ cyy_init_card(void __iomem * true_base_addr, int index)
base_addr =
true_base_addr + (cy_chip_offset[chip_number] << index);
mdelay(1);
- if (cy_readb(base_addr + (CyCCR << index)) != 0x00) {
+ if (readb(base_addr + (CyCCR << index)) != 0x00) {
/*************
printk(" chip #%d at %#6lx is never idle (CCR != 0)\n",
chip_number, (unsigned long)base_addr);
@@ -4561,7 +4561,7 @@ cyy_init_card(void __iomem * true_base_addr, int index)
chip 4 GFRCR register appears at chip 0, there is no chip 4
and this must be a Cyclom-16Y, not a Cyclom-32Ye.
*/
- if (chip_number == 4 && cy_readb(true_base_addr +
+ if (chip_number == 4 && readb(true_base_addr +
(cy_chip_offset[0] << index) +
(CyGFRCR << index)) == 0) {
return chip_number;
@@ -4570,7 +4570,7 @@ cyy_init_card(void __iomem * true_base_addr, int index)
cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET);
mdelay(1);
- if (cy_readb(base_addr + (CyGFRCR << index)) == 0x00) {
+ if (readb(base_addr + (CyGFRCR << index)) == 0x00) {
/*
printk(" chip #%d at %#6lx is not responding ",
chip_number, (unsigned long)base_addr);
@@ -4578,7 +4578,7 @@ cyy_init_card(void __iomem * true_base_addr, int index)
*/
return chip_number;
}
- if ((0xf0 & (cy_readb(base_addr + (CyGFRCR << index)))) !=
+ if ((0xf0 & (readb(base_addr + (CyGFRCR << index)))) !=
0x40) {
/*
printk(" chip #%d at %#6lx is not valid (GFRCR == "
@@ -4589,7 +4589,7 @@ cyy_init_card(void __iomem * true_base_addr, int index)
return chip_number;
}
cy_writeb(base_addr + (CyGCR << index), CyCH0_SERIAL);
- if (cy_readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) {
+ if (readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) {
/* It is a CD1400 rev. J or later */
/* Impossible to reach 5ms with this chip.
Changed to 2ms instead (f = 500 Hz). */
@@ -4602,7 +4602,7 @@ cyy_init_card(void __iomem * true_base_addr, int index)
/*
printk(" chip #%d at %#6lx is rev 0x%2x\n",
chip_number, (unsigned long)base_addr,
- cy_readb(base_addr+(CyGFRCR<<index)));
+ readb(base_addr+(CyGFRCR<<index)));
*/
}
return chip_number;
@@ -4647,9 +4647,15 @@ static int __init cy_detect_isa(void)
/* probe for CD1400... */
cy_isa_address = ioremap(isa_address, CyISA_Ywin);
+ if (cy_isa_address == NULL) {
+ printk(KERN_ERR "Cyclom-Y/ISA: can't remap base "
+ "address\n");
+ continue;
+ }
cy_isa_nchan = CyPORTS_PER_CHIP *
cyy_init_card(cy_isa_address, 0);
if (cy_isa_nchan == 0) {
+ iounmap(cy_isa_address);
continue;
}
#ifdef MODULE
@@ -4660,40 +4666,42 @@ static int __init cy_detect_isa(void)
/* find out the board's irq by probing */
cy_isa_irq = detect_isa_irq(cy_isa_address);
if (cy_isa_irq == 0) {
- printk("Cyclom-Y/ISA found at 0x%lx ",
+ printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but the "
+ "IRQ could not be detected.\n",
(unsigned long)cy_isa_address);
- printk("but the IRQ could not be detected.\n");
+ iounmap(cy_isa_address);
continue;
}
if ((cy_next_channel + cy_isa_nchan) > NR_PORTS) {
- printk("Cyclom-Y/ISA found at 0x%lx ",
+ printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no "
+ "more channels are available. Change NR_PORTS "
+ "in cyclades.c and recompile kernel.\n",
(unsigned long)cy_isa_address);
- printk("but no more channels are available.\n");
- printk("Change NR_PORTS in cyclades.c and recompile "
- "kernel.\n");
+ iounmap(cy_isa_address);
return nboard;
}
/* fill the next cy_card structure available */
for (j = 0; j < NR_CARDS; j++) {
- if (cy_card[j].base_addr == 0)
+ if (cy_card[j].base_addr == NULL)
break;
}
if (j == NR_CARDS) { /* no more cy_cards available */
- printk("Cyclom-Y/ISA found at 0x%lx ",
+ printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no "
+ "more cards can be used. Change NR_CARDS in "
+ "cyclades.c and recompile kernel.\n",
(unsigned long)cy_isa_address);
- printk("but no more cards can be used .\n");
- printk("Change NR_CARDS in cyclades.c and recompile "
- "kernel.\n");
+ iounmap(cy_isa_address);
return nboard;
}
/* allocate IRQ */
if (request_irq(cy_isa_irq, cyy_interrupt,
IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) {
- printk("Cyclom-Y/ISA found at 0x%lx ",
- (unsigned long)cy_isa_address);
- printk("but could not allocate IRQ#%d.\n", cy_isa_irq);
+ printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but "
+ "could not allocate IRQ#%d.\n",
+ (unsigned long)cy_isa_address, cy_isa_irq);
+ iounmap(cy_isa_address);
return nboard;
}
@@ -4704,15 +4712,23 @@ static int __init cy_detect_isa(void)
cy_card[j].bus_index = 0;
cy_card[j].first_line = cy_next_channel;
cy_card[j].num_chips = cy_isa_nchan / 4;
+ if (cy_init_card(&cy_card[j])) {
+ cy_card[j].base_addr = NULL;
+ free_irq(cy_isa_irq, &cy_card[j]);
+ iounmap(cy_isa_address);
+ continue;
+ }
nboard++;
- /* print message */
- printk("Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d, ",
+ printk(KERN_INFO "Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d found: "
+ "%d channels starting from port %d\n",
j + 1, (unsigned long)cy_isa_address,
(unsigned long)(cy_isa_address + (CyISA_Ywin - 1)),
- cy_isa_irq);
- printk("%d channels starting from port %d.\n",
- cy_isa_nchan, cy_next_channel);
+ cy_isa_irq, cy_isa_nchan, cy_next_channel);
+
+ for (j = cy_next_channel;
+ j < cy_next_channel + cy_isa_nchan; j++)
+ tty_register_device(cy_serial_driver, j, NULL);
cy_next_channel += cy_isa_nchan;
}
return nboard;
@@ -4721,510 +4737,310 @@ static int __init cy_detect_isa(void)
#endif /* CONFIG_ISA */
} /* cy_detect_isa */
-static void plx_init(void __iomem * addr, uclong initctl)
+#ifdef CONFIG_PCI
+static void __devinit plx_init(void __iomem * addr, __u32 initctl)
{
/* Reset PLX */
- cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000);
+ cy_writel(addr + initctl, readl(addr + initctl) | 0x40000000);
udelay(100L);
- cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000);
+ cy_writel(addr + initctl, readl(addr + initctl) & ~0x40000000);
/* Reload Config. Registers from EEPROM */
- cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000);
+ cy_writel(addr + initctl, readl(addr + initctl) | 0x20000000);
udelay(100L);
- cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000);
+ cy_writel(addr + initctl, readl(addr + initctl) & ~0x20000000);
}
-/*
- * ---------------------------------------------------------------------
- * cy_detect_pci() - Test PCI bus presence and Cyclom-Ye/PCI.
- * sets global variables and return the number of PCI boards found.
- * ---------------------------------------------------------------------
- */
-static int __init cy_detect_pci(void)
+static int __devinit cy_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
-#ifdef CONFIG_PCI
-
- struct pci_dev *pdev = NULL;
- unsigned char cyy_rev_id;
- unsigned char cy_pci_irq = 0;
- uclong cy_pci_phys0, cy_pci_phys2;
- void __iomem *cy_pci_addr0, *cy_pci_addr2;
- unsigned short i, j, cy_pci_nchan, plx_ver;
- unsigned short device_id, dev_index = 0;
- uclong mailbox;
- uclong ZeIndex = 0;
- void __iomem *Ze_addr0[NR_CARDS], *Ze_addr2[NR_CARDS];
- uclong Ze_phys0[NR_CARDS], Ze_phys2[NR_CARDS];
- unsigned char Ze_irq[NR_CARDS];
- struct pci_dev *Ze_pdev[NR_CARDS];
-
- for (i = 0; i < NR_CARDS; i++) {
- /* look for a Cyclades card by vendor and device id */
- while ((device_id = cy_pci_dev_id[dev_index].device) != 0) {
- if ((pdev = pci_get_device(PCI_VENDOR_ID_CYCLADES,
- device_id, pdev)) == NULL) {
- dev_index++; /* try next device id */
- } else {
- break; /* found a board */
- }
- }
-
- if (device_id == 0)
- break;
-
- if (pci_enable_device(pdev))
- continue;
-
- /* read PCI configuration area */
- cy_pci_irq = pdev->irq;
- cy_pci_phys0 = pci_resource_start(pdev, 0);
- cy_pci_phys2 = pci_resource_start(pdev, 2);
- pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id);
+ void __iomem *addr0 = NULL, *addr2 = NULL;
+ char *card_name = NULL;
+ u32 mailbox;
+ unsigned int device_id, nchan = 0, card_no, i;
+ unsigned char plx_ver;
+ int retval, irq;
+
+ retval = pci_enable_device(pdev);
+ if (retval) {
+ dev_err(&pdev->dev, "cannot enable device\n");
+ goto err;
+ }
- device_id &= ~PCI_DEVICE_ID_MASK;
+ /* read PCI configuration area */
+ irq = pdev->irq;
+ device_id = pdev->device & ~PCI_DEVICE_ID_MASK;
- if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
- device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
-#ifdef CY_PCI_DEBUG
- printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
- pdev->bus->number, pdev->devfn);
- printk("rev_id=%d) IRQ%d\n",
- cyy_rev_id, (int)cy_pci_irq);
- printk("Cyclom-Y/PCI:found winaddr=0x%lx "
- "ctladdr=0x%lx\n",
- (ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
+#if defined(__alpha__)
+ if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
+ dev_err(&pdev->dev, "Cyclom-Y/PCI not supported for low "
+ "addresses on Alpha systems.\n");
+ retval = -EIO;
+ goto err_dis;
+ }
#endif
+ if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) {
+ dev_err(&pdev->dev, "Cyclades-Z/PCI not supported for low "
+ "addresses\n");
+ retval = -EIO;
+ goto err_dis;
+ }
- if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
- printk(" Warning: PCI I/O bit incorrectly "
- "set. Ignoring it...\n");
- pdev->resource[2].flags &= ~IORESOURCE_IO;
- }
+ if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
+ dev_warn(&pdev->dev, "PCI I/O bit incorrectly set. Ignoring "
+ "it...\n");
+ pdev->resource[2].flags &= ~IORESOURCE_IO;
+ }
- /* Although we don't use this I/O region, we should
- request it from the kernel anyway, to avoid problems
- with other drivers accessing it. */
- if (pci_request_regions(pdev, "Cyclom-Y") != 0) {
- printk(KERN_ERR "cyclades: failed to reserve "
- "PCI resources\n");
- continue;
- }
-#if defined(__alpha__)
- if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
- printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
- pdev->bus->number, pdev->devfn);
- printk("rev_id=%d) IRQ%d\n",
- cyy_rev_id, (int)cy_pci_irq);
- printk("Cyclom-Y/PCI:found winaddr=0x%lx "
- "ctladdr=0x%lx\n",
- (ulong)cy_pci_phys2,
- (ulong)cy_pci_phys0);
- printk("Cyclom-Y/PCI not supported for low "
- "addresses in Alpha systems.\n");
- i--;
- continue;
- }
-#endif
- cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Yctl);
- cy_pci_addr2 = ioremap(cy_pci_phys2, CyPCI_Ywin);
+ retval = pci_request_regions(pdev, "cyclades");
+ if (retval) {
+ dev_err(&pdev->dev, "failed to reserve resources\n");
+ goto err_dis;
+ }
-#ifdef CY_PCI_DEBUG
- printk("Cyclom-Y/PCI: relocate winaddr=0x%lx "
- "ctladdr=0x%lx\n",
- (u_long)cy_pci_addr2, (u_long)cy_pci_addr0);
-#endif
- cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP *
- cyy_init_card(cy_pci_addr2, 1));
- if (cy_pci_nchan == 0) {
- printk("Cyclom-Y PCI host card with ");
- printk("no Serial-Modules at 0x%lx.\n",
- (ulong) cy_pci_phys2);
- i--;
- continue;
- }
- if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) {
- printk("Cyclom-Y/PCI found at 0x%lx ",
- (ulong) cy_pci_phys2);
- printk("but no channels are available.\n");
- printk("Change NR_PORTS in cyclades.c and "
- "recompile kernel.\n");
- return i;
- }
- /* fill the next cy_card structure available */
- for (j = 0; j < NR_CARDS; j++) {
- if (cy_card[j].base_addr == 0)
- break;
- }
- if (j == NR_CARDS) { /* no more cy_cards available */
- printk("Cyclom-Y/PCI found at 0x%lx ",
- (ulong) cy_pci_phys2);
- printk("but no more cards can be used.\n");
- printk("Change NR_CARDS in cyclades.c and "
- "recompile kernel.\n");
- return i;
- }
+ retval = -EIO;
+ if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
+ device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
+ card_name = "Cyclom-Y";
- /* allocate IRQ */
- if (request_irq(cy_pci_irq, cyy_interrupt,
- IRQF_SHARED, "Cyclom-Y", &cy_card[j])) {
- printk("Cyclom-Y/PCI found at 0x%lx ",
- (ulong) cy_pci_phys2);
- printk("but could not allocate IRQ%d.\n",
- cy_pci_irq);
- return i;
- }
+ addr0 = pci_iomap(pdev, 0, CyPCI_Yctl);
+ if (addr0 == NULL) {
+ dev_err(&pdev->dev, "can't remap ctl region\n");
+ goto err_reg;
+ }
+ addr2 = pci_iomap(pdev, 2, CyPCI_Ywin);
+ if (addr2 == NULL) {
+ dev_err(&pdev->dev, "can't remap base region\n");
+ goto err_unmap;
+ }
- /* set cy_card */
- cy_card[j].base_phys = (ulong) cy_pci_phys2;
- cy_card[j].ctl_phys = (ulong) cy_pci_phys0;
- cy_card[j].base_addr = cy_pci_addr2;
- cy_card[j].ctl_addr = cy_pci_addr0;
- cy_card[j].irq = (int)cy_pci_irq;
- cy_card[j].bus_index = 1;
- cy_card[j].first_line = cy_next_channel;
- cy_card[j].num_chips = cy_pci_nchan / 4;
- cy_card[j].pdev = pdev;
-
- /* enable interrupts in the PCI interface */
- plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f;
- switch (plx_ver) {
- case PLX_9050:
-
- cy_writeb(cy_pci_addr0 + 0x4c, 0x43);
- break;
+ nchan = CyPORTS_PER_CHIP * cyy_init_card(addr2, 1);
+ if (nchan == 0) {
+ dev_err(&pdev->dev, "Cyclom-Y PCI host card with no "
+ "Serial-Modules\n");
+ return -EIO;
+ }
+ } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) {
+ struct RUNTIME_9060 __iomem *ctl_addr;
- case PLX_9060:
- case PLX_9080:
- default: /* Old boards, use PLX_9060 */
-
- plx_init(cy_pci_addr0, 0x6c);
- /* For some yet unknown reason, once the PLX9060 reloads
- the EEPROM, the IRQ is lost and, thus, we have to
- re-write it to the PCI config. registers.
- This will remain here until we find a permanent
- fix. */
- pci_write_config_byte(pdev, PCI_INTERRUPT_LINE,
- cy_pci_irq);
-
- cy_writew(cy_pci_addr0 + 0x68,
- cy_readw(cy_pci_addr0 +
- 0x68) | 0x0900);
- break;
- }
+ ctl_addr = addr0 = pci_iomap(pdev, 0, CyPCI_Zctl);
+ if (addr0 == NULL) {
+ dev_err(&pdev->dev, "can't remap ctl region\n");
+ goto err_reg;
+ }
- /* print message */
- printk("Cyclom-Y/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
- j + 1, (ulong)cy_pci_phys2,
- (ulong) (cy_pci_phys2 + CyPCI_Ywin - 1),
- (int)cy_pci_irq);
- printk("%d channels starting from port %d.\n",
- cy_pci_nchan, cy_next_channel);
-
- cy_next_channel += cy_pci_nchan;
- } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) {
- /* print message */
- printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
- pdev->bus->number, pdev->devfn);
- printk("rev_id=%d) IRQ%d\n",
- cyy_rev_id, (int)cy_pci_irq);
- printk("Cyclades-Z/PCI: found winaddr=0x%lx "
- "ctladdr=0x%lx\n",
- (ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
- printk("Cyclades-Z/PCI not supported for low "
- "addresses\n");
- break;
- } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) {
-#ifdef CY_PCI_DEBUG
- printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
- pdev->bus->number, pdev->devfn);
- printk("rev_id=%d) IRQ%d\n",
- cyy_rev_id, (int)cy_pci_irq);
- printk("Cyclades-Z/PCI: found winaddr=0x%lx "
- "ctladdr=0x%lx\n",
- (ulong) cy_pci_phys2, (ulong) cy_pci_phys0);
-#endif
- cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Zctl);
-
- /* Disable interrupts on the PLX before resetting it */
- cy_writew(cy_pci_addr0 + 0x68,
- cy_readw(cy_pci_addr0 + 0x68) & ~0x0900);
-
- plx_init(cy_pci_addr0, 0x6c);
- /* For some yet unknown reason, once the PLX9060 reloads
- the EEPROM, the IRQ is lost and, thus, we have to
- re-write it to the PCI config. registers.
- This will remain here until we find a permanent
- fix. */
- pci_write_config_byte(pdev, PCI_INTERRUPT_LINE,
- cy_pci_irq);
-
- mailbox =
- (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *)
- cy_pci_addr0)->mail_box_0);
-
- if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
- printk(" Warning: PCI I/O bit incorrectly "
- "set. Ignoring it...\n");
- pdev->resource[2].flags &= ~IORESOURCE_IO;
- }
+ /* Disable interrupts on the PLX before resetting it */
+ cy_writew(addr0 + 0x68,
+ readw(addr0 + 0x68) & ~0x0900);
+
+ plx_init(addr0, 0x6c);
+ /* For some yet unknown reason, once the PLX9060 reloads
+ the EEPROM, the IRQ is lost and, thus, we have to
+ re-write it to the PCI config. registers.
+ This will remain here until we find a permanent
+ fix. */
+ pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq);
+
+ mailbox = (u32)readl(&ctl_addr->mail_box_0);
+
+ addr2 = pci_iomap(pdev, 2, mailbox == ZE_V1 ?
+ CyPCI_Ze_win : CyPCI_Zwin);
+ if (addr2 == NULL) {
+ dev_err(&pdev->dev, "can't remap base region\n");
+ goto err_unmap;
+ }
- /* Although we don't use this I/O region, we should
- request it from the kernel anyway, to avoid problems
- with other drivers accessing it. */
- if (pci_request_regions(pdev, "Cyclades-Z") != 0) {
- printk(KERN_ERR "cyclades: failed to reserve "
- "PCI resources\n");
- continue;
- }
+ if (mailbox == ZE_V1) {
+ card_name = "Cyclades-Ze";
- if (mailbox == ZE_V1) {
- cy_pci_addr2 = ioremap(cy_pci_phys2,
- CyPCI_Ze_win);
- if (ZeIndex == NR_CARDS) {
- printk("Cyclades-Ze/PCI found at "
- "0x%lx but no more cards can "
- "be used.\nChange NR_CARDS in "
- "cyclades.c and recompile "
- "kernel.\n",
- (ulong)cy_pci_phys2);
- } else {
- Ze_phys0[ZeIndex] = cy_pci_phys0;
- Ze_phys2[ZeIndex] = cy_pci_phys2;
- Ze_addr0[ZeIndex] = cy_pci_addr0;
- Ze_addr2[ZeIndex] = cy_pci_addr2;
- Ze_irq[ZeIndex] = cy_pci_irq;
- Ze_pdev[ZeIndex] = pdev;
- ZeIndex++;
- }
- i--;
- continue;
- } else {
- cy_pci_addr2 = ioremap(cy_pci_phys2,CyPCI_Zwin);
- }
+ readl(&ctl_addr->mail_box_0);
+ nchan = ZE_V1_NPORTS;
+ } else {
+ card_name = "Cyclades-8Zo";
#ifdef CY_PCI_DEBUG
- printk("Cyclades-Z/PCI: relocate winaddr=0x%lx "
- "ctladdr=0x%lx\n",
- (ulong) cy_pci_addr2, (ulong) cy_pci_addr0);
if (mailbox == ZO_V1) {
- cy_writel(&((struct RUNTIME_9060 *)
- (cy_pci_addr0))->loc_addr_base,
- WIN_CREG);
- PAUSE;
- printk("Cyclades-8Zo/PCI: FPGA id %lx, ver "
- "%lx\n", (ulong) (0xff &
- cy_readl(&((struct CUSTOM_REG *)
- (cy_pci_addr2))->fpga_id)),
- (ulong)(0xff &
- cy_readl(&((struct CUSTOM_REG *)
- (cy_pci_addr2))->
- fpga_version)));
- cy_writel(&((struct RUNTIME_9060 *)
- (cy_pci_addr0))->loc_addr_base,
- WIN_RAM);
+ cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
+ dev_info(&pdev->dev, "Cyclades-8Zo/PCI: FPGA "
+ "id %lx, ver %lx\n", (ulong)(0xff &
+ readl(&((struct CUSTOM_REG *)addr2)->
+ fpga_id)), (ulong)(0xff &
+ readl(&((struct CUSTOM_REG *)addr2)->
+ fpga_version)));
+ cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
} else {
- printk("Cyclades-Z/PCI: New Cyclades-Z board. "
- "FPGA not loaded\n");
+ dev_info(&pdev->dev, "Cyclades-Z/PCI: New "
+ "Cyclades-Z board. FPGA not loaded\n");
}
#endif
/* The following clears the firmware id word. This
ensures that the driver will not attempt to talk to
the board until it has been properly initialized.
*/
- PAUSE;
if ((mailbox == ZO_V1) || (mailbox == ZO_V2))
- cy_writel(cy_pci_addr2 + ID_ADDRESS, 0L);
+ cy_writel(addr2 + ID_ADDRESS, 0L);
/* This must be a Cyclades-8Zo/PCI. The extendable
version will have a different device_id and will
be allocated its maximum number of ports. */
- cy_pci_nchan = 8;
-
- if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) {
- printk("Cyclades-8Zo/PCI found at 0x%lx but"
- "no channels are available.\nChange "
- "NR_PORTS in cyclades.c and recompile "
- "kernel.\n", (ulong)cy_pci_phys2);
- return i;
- }
-
- /* fill the next cy_card structure available */
- for (j = 0; j < NR_CARDS; j++) {
- if (cy_card[j].base_addr == 0)
- break;
- }
- if (j == NR_CARDS) { /* no more cy_cards available */
- printk("Cyclades-8Zo/PCI found at 0x%lx but"
- "no more cards can be used.\nChange "
- "NR_CARDS in cyclades.c and recompile "
- "kernel.\n", (ulong)cy_pci_phys2);
- return i;
- }
-#ifdef CONFIG_CYZ_INTR
- /* allocate IRQ only if board has an IRQ */
- if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) {
- if (request_irq(cy_pci_irq, cyz_interrupt,
- IRQF_SHARED, "Cyclades-Z",
- &cy_card[j])) {
- printk("Cyclom-8Zo/PCI found at 0x%lx "
- "but could not allocate "
- "IRQ%d.\n", (ulong)cy_pci_phys2,
- cy_pci_irq);
- return i;
- }
- }
-#endif /* CONFIG_CYZ_INTR */
-
- /* set cy_card */
- cy_card[j].base_phys = cy_pci_phys2;
- cy_card[j].ctl_phys = cy_pci_phys0;
- cy_card[j].base_addr = cy_pci_addr2;
- cy_card[j].ctl_addr = cy_pci_addr0;
- cy_card[j].irq = (int)cy_pci_irq;
- cy_card[j].bus_index = 1;
- cy_card[j].first_line = cy_next_channel;
- cy_card[j].num_chips = -1;
- cy_card[j].pdev = pdev;
-
- /* print message */
-#ifdef CONFIG_CYZ_INTR
- /* don't report IRQ if board is no IRQ */
- if ((cy_pci_irq != 0) && (cy_pci_irq != 255))
- printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, "
- "IRQ%d, ", j + 1, (ulong)cy_pci_phys2,
- (ulong) (cy_pci_phys2 + CyPCI_Zwin - 1),
- (int)cy_pci_irq);
- else
-#endif /* CONFIG_CYZ_INTR */
- printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ",
- j + 1, (ulong)cy_pci_phys2,
- (ulong)(cy_pci_phys2 + CyPCI_Zwin - 1));
-
- printk("%d channels starting from port %d.\n",
- cy_pci_nchan, cy_next_channel);
- cy_next_channel += cy_pci_nchan;
+ nchan = 8;
}
}
- for (; ZeIndex != 0 && i < NR_CARDS; i++) {
- cy_pci_phys0 = Ze_phys0[0];
- cy_pci_phys2 = Ze_phys2[0];
- cy_pci_addr0 = Ze_addr0[0];
- cy_pci_addr2 = Ze_addr2[0];
- cy_pci_irq = Ze_irq[0];
- pdev = Ze_pdev[0];
- for (j = 0; j < ZeIndex - 1; j++) {
- Ze_phys0[j] = Ze_phys0[j + 1];
- Ze_phys2[j] = Ze_phys2[j + 1];
- Ze_addr0[j] = Ze_addr0[j + 1];
- Ze_addr2[j] = Ze_addr2[j + 1];
- Ze_irq[j] = Ze_irq[j + 1];
- Ze_pdev[j] = Ze_pdev[j + 1];
- }
- ZeIndex--;
- mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *)
- cy_pci_addr0)->mail_box_0);
-#ifdef CY_PCI_DEBUG
- printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
- (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
- printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not "
- "loaded\n");
-#endif
- PAUSE;
- /* This must be the new Cyclades-Ze/PCI. */
- cy_pci_nchan = ZE_V1_NPORTS;
-
- if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) {
- printk("Cyclades-Ze/PCI found at 0x%lx but no channels "
- "are available.\nChange NR_PORTS in cyclades.c "
- "and recompile kernel.\n",
- (ulong) cy_pci_phys2);
- return i;
- }
+ if ((cy_next_channel + nchan) > NR_PORTS) {
+ dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no "
+ "channels are available. Change NR_PORTS in "
+ "cyclades.c and recompile kernel.\n");
+ goto err_unmap;
+ }
+ /* fill the next cy_card structure available */
+ for (card_no = 0; card_no < NR_CARDS; card_no++) {
+ if (cy_card[card_no].base_addr == NULL)
+ break;
+ }
+ if (card_no == NR_CARDS) { /* no more cy_cards available */
+ dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no "
+ "more cards can be used. Change NR_CARDS in "
+ "cyclades.c and recompile kernel.\n");
+ goto err_unmap;
+ }
- /* fill the next cy_card structure available */
- for (j = 0; j < NR_CARDS; j++) {
- if (cy_card[j].base_addr == 0)
- break;
- }
- if (j == NR_CARDS) { /* no more cy_cards available */
- printk("Cyclades-Ze/PCI found at 0x%lx but no more "
- "cards can be used.\nChange NR_CARDS in "
- "cyclades.c and recompile kernel.\n",
- (ulong) cy_pci_phys2);
- return i;
+ if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
+ device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
+ /* allocate IRQ */
+ retval = request_irq(irq, cyy_interrupt,
+ IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]);
+ if (retval) {
+ dev_err(&pdev->dev, "could not allocate IRQ\n");
+ goto err_unmap;
}
+ cy_card[card_no].num_chips = nchan / 4;
+ } else {
#ifdef CONFIG_CYZ_INTR
/* allocate IRQ only if board has an IRQ */
- if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) {
- if (request_irq(cy_pci_irq, cyz_interrupt,
+ if (irq != 0 && irq != 255) {
+ retval = request_irq(irq, cyz_interrupt,
IRQF_SHARED, "Cyclades-Z",
- &cy_card[j])) {
- printk("Cyclom-Ze/PCI found at 0x%lx ",
- (ulong) cy_pci_phys2);
- printk("but could not allocate IRQ%d.\n",
- cy_pci_irq);
- return i;
+ &cy_card[card_no]);
+ if (retval) {
+ dev_err(&pdev->dev, "could not allocate IRQ\n");
+ goto err_unmap;
}
}
#endif /* CONFIG_CYZ_INTR */
+ cy_card[card_no].num_chips = -1;
+ }
- /* set cy_card */
- cy_card[j].base_phys = cy_pci_phys2;
- cy_card[j].ctl_phys = cy_pci_phys0;
- cy_card[j].base_addr = cy_pci_addr2;
- cy_card[j].ctl_addr = cy_pci_addr0;
- cy_card[j].irq = (int)cy_pci_irq;
- cy_card[j].bus_index = 1;
- cy_card[j].first_line = cy_next_channel;
- cy_card[j].num_chips = -1;
- cy_card[j].pdev = pdev;
+ /* set cy_card */
+ cy_card[card_no].base_addr = addr2;
+ cy_card[card_no].ctl_addr = addr0;
+ cy_card[card_no].irq = irq;
+ cy_card[card_no].bus_index = 1;
+ cy_card[card_no].first_line = cy_next_channel;
+ retval = cy_init_card(&cy_card[card_no]);
+ if (retval)
+ goto err_null;
- /* print message */
-#ifdef CONFIG_CYZ_INTR
- /* don't report IRQ if board is no IRQ */
- if ((cy_pci_irq != 0) && (cy_pci_irq != 255))
- printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
- j + 1, (ulong) cy_pci_phys2,
- (ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1),
- (int)cy_pci_irq);
- else
-#endif /* CONFIG_CYZ_INTR */
- printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ",
- j + 1, (ulong) cy_pci_phys2,
- (ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1));
+ pci_set_drvdata(pdev, &cy_card[card_no]);
- printk("%d channels starting from port %d.\n",
- cy_pci_nchan, cy_next_channel);
- cy_next_channel += cy_pci_nchan;
- }
- if (ZeIndex != 0) {
- printk("Cyclades-Ze/PCI found at 0x%x but no more cards can be "
- "used.\nChange NR_CARDS in cyclades.c and recompile "
- "kernel.\n", (unsigned int)Ze_phys2[0]);
+ if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
+ device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
+ /* enable interrupts in the PCI interface */
+ plx_ver = readb(addr2 + CyPLX_VER) & 0x0f;
+ switch (plx_ver) {
+ case PLX_9050:
+
+ cy_writeb(addr0 + 0x4c, 0x43);
+ break;
+
+ case PLX_9060:
+ case PLX_9080:
+ default: /* Old boards, use PLX_9060 */
+
+ plx_init(addr0, 0x6c);
+ /* For some yet unknown reason, once the PLX9060 reloads
+ the EEPROM, the IRQ is lost and, thus, we have to
+ re-write it to the PCI config. registers.
+ This will remain here until we find a permanent
+ fix. */
+ pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq);
+
+ cy_writew(addr0 + 0x68, readw(addr0 + 0x68) | 0x0900);
+ break;
+ }
}
- return i;
-#else
+
+ dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from "
+ "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel);
+ for (i = cy_next_channel; i < cy_next_channel + nchan; i++)
+ tty_register_device(cy_serial_driver, i, &pdev->dev);
+ cy_next_channel += nchan;
+
return 0;
-#endif /* ifdef CONFIG_PCI */
-} /* cy_detect_pci */
+err_null:
+ cy_card[card_no].base_addr = NULL;
+ free_irq(irq, &cy_card[card_no]);
+err_unmap:
+ pci_iounmap(pdev, addr0);
+ if (addr2)
+ pci_iounmap(pdev, addr2);
+err_reg:
+ pci_release_regions(pdev);
+err_dis:
+ pci_disable_device(pdev);
+err:
+ return retval;
+}
-/*
- * This routine prints out the appropriate serial driver version number
- * and identifies which options were configured into this driver.
- */
-static inline void show_version(void)
+static void __devexit cy_pci_remove(struct pci_dev *pdev)
{
- printk("Cyclades driver " CY_VERSION "\n");
- printk(" built %s %s\n", __DATE__, __TIME__);
-} /* show_version */
+ struct cyclades_card *cinfo = pci_get_drvdata(pdev);
+ unsigned int i;
+
+ /* non-Z with old PLX */
+ if (!IS_CYC_Z(*cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) ==
+ PLX_9050)
+ cy_writeb(cinfo->ctl_addr + 0x4c, 0);
+ else
+#ifndef CONFIG_CYZ_INTR
+ if (!IS_CYC_Z(*cinfo))
+#endif
+ cy_writew(cinfo->ctl_addr + 0x68,
+ readw(cinfo->ctl_addr + 0x68) & ~0x0900);
+
+ pci_iounmap(pdev, cinfo->base_addr);
+ if (cinfo->ctl_addr)
+ pci_iounmap(pdev, cinfo->ctl_addr);
+ if (cinfo->irq
+#ifndef CONFIG_CYZ_INTR
+ && !IS_CYC_Z(*cinfo)
+#endif /* CONFIG_CYZ_INTR */
+ )
+ free_irq(cinfo->irq, cinfo);
+ pci_release_regions(pdev);
+
+ cinfo->base_addr = NULL;
+ for (i = cinfo->first_line; i < cinfo->first_line +
+ cinfo->nports; i++)
+ tty_unregister_device(cy_serial_driver, i);
+ cinfo->nports = 0;
+ kfree(cinfo->ports);
+}
+
+static struct pci_driver cy_pci_driver = {
+ .name = "cyclades",
+ .id_table = cy_pci_dev_id,
+ .probe = cy_pci_probe,
+ .remove = __devexit_p(cy_pci_remove)
+};
+#endif
static int
cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
int *eof, void *data)
{
struct cyclades_port *info;
- int i;
+ unsigned int i, j;
int len = 0;
off_t begin = 0;
off_t pos = 0;
@@ -5238,33 +5054,34 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
len += size;
/* Output one line for each known port */
- for (i = 0; i < NR_PORTS && cy_port[i].line >= 0; i++) {
- info = &cy_port[i];
-
- if (info->count)
- size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu "
- "%8lu %9lu %6ld\n", info->line,
- (cur_jifs - info->idle_stats.in_use) / HZ,
- info->idle_stats.xmit_bytes,
- (cur_jifs - info->idle_stats.xmit_idle) / HZ,
- info->idle_stats.recv_bytes,
- (cur_jifs - info->idle_stats.recv_idle) / HZ,
- info->idle_stats.overruns,
- (long)info->tty->ldisc.num);
- else
- size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu "
- "%8lu %9lu %6ld\n",
- info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
- len += size;
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
+ for (i = 0; i < NR_CARDS; i++)
+ for (j = 0; j < cy_card[i].nports; j++) {
+ info = &cy_card[i].ports[j];
+
+ if (info->count)
+ size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
+ "%10lu %8lu %9lu %6ld\n", info->line,
+ (cur_jifs - info->idle_stats.in_use) /
+ HZ, info->idle_stats.xmit_bytes,
+ (cur_jifs - info->idle_stats.xmit_idle)/
+ HZ, info->idle_stats.recv_bytes,
+ (cur_jifs - info->idle_stats.recv_idle)/
+ HZ, info->idle_stats.overruns,
+ (long)info->tty->ldisc.num);
+ else
+ size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
+ "%10lu %8lu %9lu %6ld\n",
+ info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
+ len += size;
+ pos = begin + len;
+
+ if (pos < offset) {
+ len = 0;
+ begin = pos;
+ }
+ if (pos > offset + length)
+ goto done;
}
- if (pos > offset + length)
- goto done;
- }
*eof = 1;
done:
*start = buf + (offset - begin); /* Start of wanted data */
@@ -5319,18 +5136,15 @@ static const struct tty_operations cy_ops = {
static int __init cy_init(void)
{
- struct cyclades_port *info;
- struct cyclades_card *cinfo;
- int number_z_boards = 0;
- int board, port, i, index;
- unsigned long mailbox;
- unsigned short chip_number;
- int nports;
+ unsigned int nboards;
+ int retval = -ENOMEM;
cy_serial_driver = alloc_tty_driver(NR_PORTS);
if (!cy_serial_driver)
- return -ENOMEM;
- show_version();
+ goto err;
+
+ printk(KERN_INFO "Cyclades driver " CY_VERSION " (built %s %s)\n",
+ __DATE__, __TIME__);
/* Initialize the tty_driver structure */
@@ -5344,15 +5158,13 @@ static int __init cy_init(void)
cy_serial_driver->init_termios = tty_std_termios;
cy_serial_driver->init_termios.c_cflag =
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- cy_serial_driver->flags = TTY_DRIVER_REAL_RAW;
+ cy_serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
tty_set_operations(cy_serial_driver, &cy_ops);
- if (tty_register_driver(cy_serial_driver))
- panic("Couldn't register Cyclades serial driver\n");
-
- for (i = 0; i < NR_CARDS; i++) {
- /* base_addr=0 indicates board not found */
- cy_card[i].base_addr = NULL;
+ retval = tty_register_driver(cy_serial_driver);
+ if (retval) {
+ printk(KERN_ERR "Couldn't register Cyclades serial driver\n");
+ goto err_frtty;
}
/* the code below is responsible to find the boards. Each different
@@ -5363,223 +5175,68 @@ static int __init cy_init(void)
the cy_next_channel. */
/* look for isa boards */
- cy_isa_nboard = cy_detect_isa();
+ nboards = cy_detect_isa();
+#ifdef CONFIG_PCI
/* look for pci boards */
- cy_pci_nboard = cy_detect_pci();
-
- cy_nboard = cy_isa_nboard + cy_pci_nboard;
-
- /* invalidate remaining cy_card structures */
- for (i = 0; i < NR_CARDS; i++) {
- if (cy_card[i].base_addr == 0) {
- cy_card[i].first_line = -1;
- cy_card[i].ctl_addr = NULL;
- cy_card[i].irq = 0;
- cy_card[i].bus_index = 0;
- cy_card[i].first_line = 0;
- cy_card[i].num_chips = 0;
- }
- }
- /* invalidate remaining cy_port structures */
- for (i = cy_next_channel; i < NR_PORTS; i++) {
- cy_port[i].line = -1;
- cy_port[i].magic = -1;
- }
-
- /* initialize per-port data structures for each valid board found */
- for (board = 0; board < cy_nboard; board++) {
- cinfo = &cy_card[board];
- if (cinfo->num_chips == -1) { /* Cyclades-Z */
- number_z_boards++;
- mailbox = cy_readl(&((struct RUNTIME_9060 __iomem *)
- cy_card[board].ctl_addr)->
- mail_box_0);
- nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
- cinfo->intr_enabled = 0;
- cinfo->nports = 0; /* Will be correctly set later, after
- Z FW is loaded */
- spin_lock_init(&cinfo->card_lock);
- for (port = cinfo->first_line;
- port < cinfo->first_line + nports; port++) {
- info = &cy_port[port];
- info->magic = CYCLADES_MAGIC;
- info->type = PORT_STARTECH;
- info->card = board;
- info->line = port;
- info->chip_rev = 0;
- info->flags = STD_COM_FLAGS;
- info->tty = NULL;
- if (mailbox == ZO_V1)
- info->xmit_fifo_size = CYZ_FIFO_SIZE;
- else
- info->xmit_fifo_size =
- 4 * CYZ_FIFO_SIZE;
- info->cor1 = 0;
- info->cor2 = 0;
- info->cor3 = 0;
- info->cor4 = 0;
- info->cor5 = 0;
- info->tbpr = 0;
- info->tco = 0;
- info->rbpr = 0;
- info->rco = 0;
- info->custom_divisor = 0;
- info->close_delay = 5 * HZ / 10;
- info->closing_wait = CLOSING_WAIT_DELAY;
- info->icount.cts = info->icount.dsr =
- info->icount.rng = info->icount.dcd = 0;
- info->icount.rx = info->icount.tx = 0;
- info->icount.frame = info->icount.parity = 0;
- info->icount.overrun = info->icount.brk = 0;
- info->x_char = 0;
- info->event = 0;
- info->count = 0;
- info->blocked_open = 0;
- info->default_threshold = 0;
- info->default_timeout = 0;
- INIT_WORK(&info->tqueue, do_softint);
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
- init_waitqueue_head(&info->shutdown_wait);
- init_waitqueue_head(&info->delta_msr_wait);
- /* info->session */
- /* info->pgrp */
- info->read_status_mask = 0;
- /* info->timeout */
- /* Bentson's vars */
- info->jiffies[0] = 0;
- info->jiffies[1] = 0;
- info->jiffies[2] = 0;
- info->rflush_count = 0;
-#ifdef CONFIG_CYZ_INTR
- init_timer(&cyz_rx_full_timer[port]);
- cyz_rx_full_timer[port].function = NULL;
+ retval = pci_register_driver(&cy_pci_driver);
+ if (retval && !nboards)
+ goto err_unr;
#endif
- }
- continue;
- } else { /* Cyclom-Y of some kind */
- index = cinfo->bus_index;
- spin_lock_init(&cinfo->card_lock);
- cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips;
- for (port = cinfo->first_line;
- port < cinfo->first_line + cinfo->nports; port++) {
- info = &cy_port[port];
- info->magic = CYCLADES_MAGIC;
- info->type = PORT_CIRRUS;
- info->card = board;
- info->line = port;
- info->flags = STD_COM_FLAGS;
- info->tty = NULL;
- info->xmit_fifo_size = CyMAX_CHAR_FIFO;
- info->cor1 =
- CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS;
- info->cor2 = CyETC;
- info->cor3 = 0x08; /* _very_ small rcv threshold */
- info->cor4 = 0;
- info->cor5 = 0;
- info->custom_divisor = 0;
- info->close_delay = 5 * HZ / 10;
- info->closing_wait = CLOSING_WAIT_DELAY;
- info->icount.cts = info->icount.dsr =
- info->icount.rng = info->icount.dcd = 0;
- info->icount.rx = info->icount.tx = 0;
- info->icount.frame = info->icount.parity = 0;
- info->icount.overrun = info->icount.brk = 0;
- chip_number = (port - cinfo->first_line) / 4;
- if ((info->chip_rev =
- cy_readb(cinfo->base_addr +
- (cy_chip_offset[chip_number] <<
- index) + (CyGFRCR << index))) >=
- CD1400_REV_J) {
- /* It is a CD1400 rev. J or later */
- info->tbpr = baud_bpr_60[13]; /* Tx BPR */
- info->tco = baud_co_60[13]; /* Tx CO */
- info->rbpr = baud_bpr_60[13]; /* Rx BPR */
- info->rco = baud_co_60[13]; /* Rx CO */
- info->rflow = 0;
- info->rtsdtr_inv = 1;
- } else {
- info->tbpr = baud_bpr_25[13]; /* Tx BPR */
- info->tco = baud_co_25[13]; /* Tx CO */
- info->rbpr = baud_bpr_25[13]; /* Rx BPR */
- info->rco = baud_co_25[13]; /* Rx CO */
- info->rflow = 0;
- info->rtsdtr_inv = 0;
- }
- info->x_char = 0;
- info->event = 0;
- info->count = 0;
- info->blocked_open = 0;
- info->default_threshold = 0;
- info->default_timeout = 0;
- INIT_WORK(&info->tqueue, do_softint);
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
- init_waitqueue_head(&info->shutdown_wait);
- init_waitqueue_head(&info->delta_msr_wait);
- /* info->session */
- /* info->pgrp */
- info->read_status_mask =
- CyTIMEOUT | CySPECHAR | CyBREAK
- | CyPARITY | CyFRAME | CyOVERRUN;
- /* info->timeout */
- }
- }
- }
-
-#ifndef CONFIG_CYZ_INTR
- if (number_z_boards && !cyz_timeron) {
- cyz_timeron++;
- cyz_timerlist.expires = jiffies + 1;
- add_timer(&cyz_timerlist);
-#ifdef CY_PCI_DEBUG
- printk("Cyclades-Z polling initialized\n");
-#endif
- }
-#endif /* CONFIG_CYZ_INTR */
return 0;
-
+err_unr:
+ tty_unregister_driver(cy_serial_driver);
+err_frtty:
+ put_tty_driver(cy_serial_driver);
+err:
+ return retval;
} /* cy_init */
static void __exit cy_cleanup_module(void)
{
+ struct cyclades_card *card;
int i, e1;
#ifndef CONFIG_CYZ_INTR
- if (cyz_timeron){
- cyz_timeron = 0;
- del_timer(&cyz_timerlist);
- }
+ del_timer_sync(&cyz_timerlist);
#endif /* CONFIG_CYZ_INTR */
if ((e1 = tty_unregister_driver(cy_serial_driver)))
- printk("cyc: failed to unregister Cyclades serial driver(%d)\n",
- e1);
+ printk(KERN_ERR "failed to unregister Cyclades serial "
+ "driver(%d)\n", e1);
- put_tty_driver(cy_serial_driver);
+#ifdef CONFIG_PCI
+ pci_unregister_driver(&cy_pci_driver);
+#endif
for (i = 0; i < NR_CARDS; i++) {
- if (cy_card[i].base_addr) {
- iounmap(cy_card[i].base_addr);
- if (cy_card[i].ctl_addr)
- iounmap(cy_card[i].ctl_addr);
- if (cy_card[i].irq
+ card = &cy_card[i];
+ if (card->base_addr) {
+ /* clear interrupt */
+ cy_writeb(card->base_addr + Cy_ClrIntr, 0);
+ iounmap(card->base_addr);
+ if (card->ctl_addr)
+ iounmap(card->ctl_addr);
+ if (card->irq
#ifndef CONFIG_CYZ_INTR
- && cy_card[i].num_chips != -1 /* not a Z card */
+ && !IS_CYC_Z(*card)
#endif /* CONFIG_CYZ_INTR */
)
- free_irq(cy_card[i].irq, &cy_card[i]);
-#ifdef CONFIG_PCI
- if (cy_card[i].pdev)
- pci_release_regions(cy_card[i].pdev);
-#endif
+ free_irq(card->irq, card);
+ for (e1 = card->first_line;
+ e1 < card->first_line +
+ card->nports; e1++)
+ tty_unregister_device(cy_serial_driver, e1);
+ kfree(card->ports);
}
}
+
+ put_tty_driver(cy_serial_driver);
} /* cy_cleanup_module */
module_init(cy_init);
module_exit(cy_cleanup_module);
MODULE_LICENSE("GPL");
+MODULE_VERSION(CY_VERSION);
diff --git a/drivers/char/digi.h b/drivers/char/digi.h
deleted file mode 100644
index 19df0e8..0000000
--- a/drivers/char/digi.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Definitions for DigiBoard ditty(1) command. */
-
-#if !defined(TIOCMODG)
-#define TIOCMODG (('d'<<8) | 250) /* get modem ctrl state */
-#define TIOCMODS (('d'<<8) | 251) /* set modem ctrl state */
-#endif
-
-#if !defined(TIOCMSET)
-#define TIOCMSET (('d'<<8) | 252) /* set modem ctrl state */
-#define TIOCMGET (('d'<<8) | 253) /* set modem ctrl state */
-#endif
-
-#if !defined(TIOCMBIC)
-#define TIOCMBIC (('d'<<8) | 254) /* set modem ctrl state */
-#define TIOCMBIS (('d'<<8) | 255) /* set modem ctrl state */
-#endif
-
-#if !defined(TIOCSDTR)
-#define TIOCSDTR (('e'<<8) | 0) /* set DTR */
-#define TIOCCDTR (('e'<<8) | 1) /* clear DTR */
-#endif
-
-/************************************************************************
- * Ioctl command arguments for DIGI parameters.
- ************************************************************************/
-#define DIGI_GETA (('e'<<8) | 94) /* Read params */
-
-#define DIGI_SETA (('e'<<8) | 95) /* Set params */
-#define DIGI_SETAW (('e'<<8) | 96) /* Drain & set params */
-#define DIGI_SETAF (('e'<<8) | 97) /* Drain, flush & set params */
-
-#define DIGI_GETFLOW (('e'<<8) | 99) /* Get startc/stopc flow */
- /* control characters */
-#define DIGI_SETFLOW (('e'<<8) | 100) /* Set startc/stopc flow */
- /* control characters */
-#define DIGI_GETAFLOW (('e'<<8) | 101) /* Get Aux. startc/stopc */
- /* flow control chars */
-#define DIGI_SETAFLOW (('e'<<8) | 102) /* Set Aux. startc/stopc */
- /* flow control chars */
-
-struct digiflow_struct {
- unsigned char startc; /* flow cntl start char */
- unsigned char stopc; /* flow cntl stop char */
-};
-
-typedef struct digiflow_struct digiflow_t;
-
-
-/************************************************************************
- * Values for digi_flags
- ************************************************************************/
-#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */
-#define DIGI_FAST 0x0002 /* Fast baud rates */
-#define RTSPACE 0x0004 /* RTS input flow control */
-#define CTSPACE 0x0008 /* CTS output flow control */
-#define DSRPACE 0x0010 /* DSR output flow control */
-#define DCDPACE 0x0020 /* DCD output flow control */
-#define DTRPACE 0x0040 /* DTR input flow control */
-#define DIGI_FORCEDCD 0x0100 /* Force carrier */
-#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */
-#define DIGI_AIXON 0x0400 /* Aux flow control in fep */
-
-
-/************************************************************************
- * Structure used with ioctl commands for DIGI parameters.
- ************************************************************************/
-struct digi_struct {
- unsigned short digi_flags; /* Flags (see above) */
-};
-
-typedef struct digi_struct digi_t;
diff --git a/drivers/char/drm/README.drm b/drivers/char/drm/README.drm
index 6441e01..af74cd7 100644
--- a/drivers/char/drm/README.drm
+++ b/drivers/char/drm/README.drm
@@ -1,6 +1,6 @@
************************************************************
* For the very latest on DRI development, please see: *
-* http://dri.sourceforge.net/ *
+* http://dri.freedesktop.org/ *
************************************************************
The Direct Rendering Manager (drm) is a device-independent kernel-level
@@ -26,21 +26,19 @@ ways:
Documentation on the DRI is available from:
- http://precisioninsight.com/piinsights.html
+ http://dri.freedesktop.org/wiki/Documentation
+ http://sourceforge.net/project/showfiles.php?group_id=387
+ http://dri.sourceforge.net/doc/
For specific information about kernel-level support, see:
The Direct Rendering Manager, Kernel Support for the Direct Rendering
Infrastructure
- http://precisioninsight.com/dr/drm.html
+ http://dri.sourceforge.net/doc/drm_low_level.html
Hardware Locking for the Direct Rendering Infrastructure
- http://precisioninsight.com/dr/locking.html
+ http://dri.sourceforge.net/doc/hardware_locking_low_level.html
A Security Analysis of the Direct Rendering Infrastructure
- http://precisioninsight.com/dr/security.html
+ http://dri.sourceforge.net/doc/security_low_level.html
-************************************************************
-* For the very latest on DRI development, please see: *
-* http://dri.sourceforge.net/ *
-************************************************************
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index bd7be09..5b91bc0 100644
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -33,59 +33,44 @@
#include "drmP.h"
-#if PAGE_SIZE == 65536
-# define ATI_PCIGART_TABLE_ORDER 0
-# define ATI_PCIGART_TABLE_PAGES (1 << 0)
-#elif PAGE_SIZE == 16384
-# define ATI_PCIGART_TABLE_ORDER 1
-# define ATI_PCIGART_TABLE_PAGES (1 << 1)
-#elif PAGE_SIZE == 8192
-# define ATI_PCIGART_TABLE_ORDER 2
-# define ATI_PCIGART_TABLE_PAGES (1 << 2)
-#elif PAGE_SIZE == 4096
-# define ATI_PCIGART_TABLE_ORDER 3
-# define ATI_PCIGART_TABLE_PAGES (1 << 3)
-#else
-# error - PAGE_SIZE not 64K, 16K, 8K or 4K
-#endif
-
-# define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */
# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
-static void *drm_ati_alloc_pcigart_table(void)
+static void *drm_ati_alloc_pcigart_table(int order)
{
unsigned long address;
struct page *page;
int i;
- DRM_DEBUG("%s\n", __FUNCTION__);
+
+ DRM_DEBUG("%s: alloc %d order\n", __FUNCTION__, order);
address = __get_free_pages(GFP_KERNEL | __GFP_COMP,
- ATI_PCIGART_TABLE_ORDER);
+ order);
if (address == 0UL) {
return NULL;
}
page = virt_to_page(address);
- for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++)
+ for (i = 0; i < order; i++, page++)
SetPageReserved(page);
DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address);
return (void *)address;
}
-static void drm_ati_free_pcigart_table(void *address)
+static void drm_ati_free_pcigart_table(void *address, int order)
{
struct page *page;
int i;
+ int num_pages = 1 << order;
DRM_DEBUG("%s\n", __FUNCTION__);
page = virt_to_page((unsigned long)address);
- for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++)
+ for (i = 0; i < num_pages; i++, page++)
ClearPageReserved(page);
- free_pages((unsigned long)address, ATI_PCIGART_TABLE_ORDER);
+ free_pages((unsigned long)address, order);
}
int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
@@ -93,6 +78,8 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
drm_sg_mem_t *entry = dev->sg;
unsigned long pages;
int i;
+ int order;
+ int num_pages, max_pages;
/* we need to support large memory configurations */
if (!entry) {
@@ -100,15 +87,19 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
return 0;
}
+ order = drm_order((gart_info->table_size + (PAGE_SIZE-1)) / PAGE_SIZE);
+ num_pages = 1 << order;
+
if (gart_info->bus_addr) {
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
pci_unmap_single(dev->pdev, gart_info->bus_addr,
- ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
+ num_pages * PAGE_SIZE,
PCI_DMA_TODEVICE);
}
- pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
- ? entry->pages : ATI_MAX_PCIGART_PAGES;
+ max_pages = (gart_info->table_size / sizeof(u32));
+ pages = (entry->pages <= max_pages)
+ ? entry->pages : max_pages;
for (i = 0; i < pages; i++) {
if (!entry->busaddr[i])
@@ -123,13 +114,12 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN
&& gart_info->addr) {
- drm_ati_free_pcigart_table(gart_info->addr);
+ drm_ati_free_pcigart_table(gart_info->addr, order);
gart_info->addr = NULL;
}
return 1;
}
-
EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
@@ -139,6 +129,9 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
unsigned long pages;
u32 *pci_gart, page_base, bus_address = 0;
int i, j, ret = 0;
+ int order;
+ int max_pages;
+ int num_pages;
if (!entry) {
DRM_ERROR("no scatter/gather memory!\n");
@@ -148,7 +141,10 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");
- address = drm_ati_alloc_pcigart_table();
+ order = drm_order((gart_info->table_size +
+ (PAGE_SIZE-1)) / PAGE_SIZE);
+ num_pages = 1 << order;
+ address = drm_ati_alloc_pcigart_table(order);
if (!address) {
DRM_ERROR("cannot allocate PCI GART page!\n");
goto done;
@@ -160,11 +156,13 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
}
bus_address = pci_map_single(dev->pdev, address,
- ATI_PCIGART_TABLE_PAGES *
- PAGE_SIZE, PCI_DMA_TODEVICE);
+ num_pages * PAGE_SIZE,
+ PCI_DMA_TODEVICE);
if (bus_address == 0) {
DRM_ERROR("unable to map PCIGART pages!\n");
- drm_ati_free_pcigart_table(address);
+ order = drm_order((gart_info->table_size +
+ (PAGE_SIZE-1)) / PAGE_SIZE);
+ drm_ati_free_pcigart_table(address, order);
address = NULL;
goto done;
}
@@ -177,10 +175,11 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
pci_gart = (u32 *) address;
- pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
- ? entry->pages : ATI_MAX_PCIGART_PAGES;
+ max_pages = (gart_info->table_size / sizeof(u32));
+ pages = (entry->pages <= max_pages)
+ ? entry->pages : max_pages;
- memset(pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32));
+ memset(pci_gart, 0, max_pages * sizeof(u32));
for (i = 0; i < pages; i++) {
/* we need to support large memory configurations */
@@ -198,10 +197,18 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
page_base = (u32) entry->busaddr[i];
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
- if (gart_info->is_pcie)
+ switch(gart_info->gart_reg_if) {
+ case DRM_ATI_GART_IGP:
+ *pci_gart = cpu_to_le32((page_base) | 0xc);
+ break;
+ case DRM_ATI_GART_PCIE:
*pci_gart = cpu_to_le32((page_base >> 8) | 0xc);
- else
+ break;
+ default:
+ case DRM_ATI_GART_PCI:
*pci_gart = cpu_to_le32(page_base);
+ break;
+ }
pci_gart++;
page_base += ATI_PCIGART_PAGE_SIZE;
}
@@ -220,5 +227,4 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
gart_info->bus_addr = bus_address;
return ret;
}
-
EXPORT_SYMBOL(drm_ati_pcigart_init);
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
index 8db9041..0891984 100644
--- a/drivers/char/drm/drm.h
+++ b/drivers/char/drm/drm.h
@@ -654,11 +654,13 @@ typedef struct drm_set_version {
/**
* Device specific ioctls should only be in their respective headers
- * The device specific ioctl range is from 0x40 to 0x79.
+ * The device specific ioctl range is from 0x40 to 0x99.
+ * Generic IOCTLS restart at 0xA0.
*
* \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and
* drmCommandReadWrite().
*/
#define DRM_COMMAND_BASE 0x40
+#define DRM_COMMAND_END 0xA0
#endif
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 85d99e2..d494315 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -414,6 +414,10 @@ typedef struct drm_lock_data {
struct file *filp; /**< File descr of lock holder (0=kernel) */
wait_queue_head_t lock_queue; /**< Queue of blocked processes */
unsigned long lock_time; /**< Time of last lock in jiffies */
+ spinlock_t spinlock;
+ uint32_t kernel_waiters;
+ uint32_t user_waiters;
+ int idle_has_lock;
} drm_lock_data_t;
/**
@@ -515,12 +519,17 @@ typedef struct drm_vbl_sig {
#define DRM_ATI_GART_MAIN 1
#define DRM_ATI_GART_FB 2
+#define DRM_ATI_GART_PCI 1
+#define DRM_ATI_GART_PCIE 2
+#define DRM_ATI_GART_IGP 3
+
typedef struct ati_pcigart_info {
int gart_table_location;
- int is_pcie;
+ int gart_reg_if;
void *addr;
dma_addr_t bus_addr;
drm_local_map_t mapping;
+ int table_size;
} drm_ati_pcigart_info;
/*
@@ -590,6 +599,8 @@ struct drm_driver {
void (*reclaim_buffers) (struct drm_device * dev, struct file * filp);
void (*reclaim_buffers_locked) (struct drm_device *dev,
struct file *filp);
+ void (*reclaim_buffers_idlelocked) (struct drm_device *dev,
+ struct file * filp);
unsigned long (*get_map_ofs) (drm_map_t * map);
unsigned long (*get_reg_ofs) (struct drm_device * dev);
void (*set_version) (struct drm_device * dev, drm_set_version_t * sv);
@@ -764,7 +775,7 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev,
}
#ifdef __alpha__
-#define drm_get_pci_domain(dev) dev->hose->bus->number
+#define drm_get_pci_domain(dev) dev->hose->index
#else
#define drm_get_pci_domain(dev) 0
#endif
@@ -915,9 +926,18 @@ extern int drm_lock(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_unlock(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-extern int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context);
-extern int drm_lock_free(drm_device_t * dev,
- __volatile__ unsigned int *lock, unsigned int context);
+extern int drm_lock_take(drm_lock_data_t *lock_data, unsigned int context);
+extern int drm_lock_free(drm_lock_data_t *lock_data, unsigned int context);
+extern void drm_idlelock_take(drm_lock_data_t *lock_data);
+extern void drm_idlelock_release(drm_lock_data_t *lock_data);
+
+/*
+ * These are exported to drivers so that they can implement fencing using
+ * DMA quiscent + idle. DMA quiescent usually requires the hardware lock.
+ */
+
+extern int drm_i_have_hw_lock(struct file *filp);
+extern int drm_kernel_take_hw_lock(struct file *filp);
/* Buffer management support (drm_bufs.h) */
extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request);
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index a6828cc..c113458 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -57,7 +57,8 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
list_for_each(list, &dev->maplist->head) {
drm_map_list_t *entry = list_entry(list, drm_map_list_t, head);
if (entry->map && map->type == entry->map->type &&
- entry->map->offset == map->offset) {
+ ((entry->map->offset == map->offset) ||
+ (map->type == _DRM_SHM && map->flags==_DRM_CONTAINS_LOCK))) {
return entry;
}
}
@@ -180,8 +181,20 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
if (map->type == _DRM_REGISTERS)
map->handle = ioremap(map->offset, map->size);
break;
-
case _DRM_SHM:
+ list = drm_find_matching_map(dev, map);
+ if (list != NULL) {
+ if(list->map->size != map->size) {
+ DRM_DEBUG("Matching maps of type %d with "
+ "mismatched sizes, (%ld vs %ld)\n",
+ map->type, map->size, list->map->size);
+ list->map->size = map->size;
+ }
+
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ *maplist = list;
+ return 0;
+ }
map->handle = vmalloc_user(map->size);
DRM_DEBUG("%lu %d %p\n",
map->size, drm_order(map->size), map->handle);
@@ -200,15 +213,45 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
dev->sigdata.lock = dev->lock.hw_lock = map->handle; /* Pointer to lock */
}
break;
- case _DRM_AGP:
- if (drm_core_has_AGP(dev)) {
+ case _DRM_AGP: {
+ drm_agp_mem_t *entry;
+ int valid = 0;
+
+ if (!drm_core_has_AGP(dev)) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -EINVAL;
+ }
#ifdef __alpha__
- map->offset += dev->hose->mem_space->start;
+ map->offset += dev->hose->mem_space->start;
#endif
- map->offset += dev->agp->base;
- map->mtrr = dev->agp->agp_mtrr; /* for getmap */
+ /* Note: dev->agp->base may actually be 0 when the DRM
+ * is not in control of AGP space. But if user space is
+ * it should already have added the AGP base itself.
+ */
+ map->offset += dev->agp->base;
+ map->mtrr = dev->agp->agp_mtrr; /* for getmap */
+
+ /* This assumes the DRM is in total control of AGP space.
+ * It's not always the case as AGP can be in the control
+ * of user space (i.e. i810 driver). So this loop will get
+ * skipped and we double check that dev->agp->memory is
+ * actually set as well as being invalid before EPERM'ing
+ */
+ for (entry = dev->agp->memory; entry; entry = entry->next) {
+ if ((map->offset >= entry->bound) &&
+ (map->offset + map->size <= entry->bound + entry->pages * PAGE_SIZE)) {
+ valid = 1;
+ break;
+ }
}
+ if (dev->agp->memory && !valid) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -EPERM;
+ }
+ DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size);
+
break;
+ }
case _DRM_SCATTER_GATHER:
if (!dev->sg) {
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
@@ -267,7 +310,7 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
*maplist = list;
return 0;
-}
+ }
int drm_addmap(drm_device_t * dev, unsigned int offset,
unsigned int size, drm_map_type_t type,
@@ -519,6 +562,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
{
drm_device_dma_t *dma = dev->dma;
drm_buf_entry_t *entry;
+ drm_agp_mem_t *agp_entry;
drm_buf_t *buf;
unsigned long offset;
unsigned long agp_offset;
@@ -529,7 +573,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
int page_order;
int total;
int byte_count;
- int i;
+ int i, valid;
drm_buf_t **temp_buflist;
if (!dma)
@@ -560,6 +604,19 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
if (dev->queue_count)
return -EBUSY; /* Not while in use */
+ /* Make sure buffers are located in AGP memory that we own */
+ valid = 0;
+ for (agp_entry = dev->agp->memory; agp_entry; agp_entry = agp_entry->next) {
+ if ((agp_offset >= agp_entry->bound) &&
+ (agp_offset + total * count <= agp_entry->bound + agp_entry->pages * PAGE_SIZE)) {
+ valid = 1;
+ break;
+ }
+ }
+ if (dev->agp->memory && !valid) {
+ DRM_DEBUG("zone invalid\n");
+ return -EINVAL;
+ }
spin_lock(&dev->count_lock);
if (dev->buf_use) {
spin_unlock(&dev->count_lock);
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index f5b9b24..8e77b7e 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -15,8 +15,6 @@
* #define DRIVER_DESC "Matrox G200/G400"
* #define DRIVER_DATE "20001127"
*
- * #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( mga_ioctls )
- *
* #define drm_x mga_##x
* \endcode
*/
@@ -120,7 +118,7 @@ static drm_ioctl_desc_t drm_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] = {drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
};
-#define DRIVER_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
+#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
/**
* Take down the DRM device.
@@ -496,11 +494,14 @@ int drm_ioctl(struct inode *inode, struct file *filp,
(long)old_encode_dev(priv->head->device),
priv->authenticated);
- if (nr < DRIVER_IOCTL_COUNT)
- ioctl = &drm_ioctls[nr];
- else if ((nr >= DRM_COMMAND_BASE)
- && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
+ if ((nr >= DRM_CORE_IOCTL_COUNT) &&
+ ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
+ goto err_i1;
+ if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) &&
+ (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
+ else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE))
+ ioctl = &drm_ioctls[nr];
else
goto err_i1;
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index 898f47d..3b159ca 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -46,6 +46,7 @@ static int drm_setup(drm_device_t * dev)
drm_local_map_t *map;
int i;
int ret;
+ u32 sareapage;
if (dev->driver->firstopen) {
ret = dev->driver->firstopen(dev);
@@ -56,7 +57,8 @@ static int drm_setup(drm_device_t * dev)
dev->magicfree.next = NULL;
/* prebuild the SAREA */
- i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map);
+ sareapage = max_t(unsigned, SAREA_MAX, PAGE_SIZE);
+ i = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK, &map);
if (i != 0)
return i;
@@ -84,7 +86,7 @@ static int drm_setup(drm_device_t * dev)
INIT_LIST_HEAD(&dev->ctxlist->head);
dev->vmalist = NULL;
- dev->sigdata.lock = dev->lock.hw_lock = NULL;
+ dev->sigdata.lock = NULL;
init_waitqueue_head(&dev->lock.lock_queue);
dev->queue_count = 0;
dev->queue_reserved = 0;
@@ -354,58 +356,56 @@ int drm_release(struct inode *inode, struct file *filp)
current->pid, (long)old_encode_dev(priv->head->device),
dev->open_count);
- if (priv->lock_count && dev->lock.hw_lock &&
- _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
- dev->lock.filp == filp) {
- DRM_DEBUG("File %p released, freeing lock for context %d\n",
- filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-
- if (dev->driver->reclaim_buffers_locked)
+ if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) {
+ if (drm_i_have_hw_lock(filp)) {
dev->driver->reclaim_buffers_locked(dev, filp);
-
- drm_lock_free(dev, &dev->lock.hw_lock->lock,
- _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-
- /* FIXME: may require heavy-handed reset of
- hardware at this point, possibly
- processed via a callback to the X
- server. */
- } else if (dev->driver->reclaim_buffers_locked && priv->lock_count
- && dev->lock.hw_lock) {
- /* The lock is required to reclaim buffers */
- DECLARE_WAITQUEUE(entry, current);
-
- add_wait_queue(&dev->lock.lock_queue, &entry);
- for (;;) {
- __set_current_state(TASK_INTERRUPTIBLE);
- if (!dev->lock.hw_lock) {
- /* Device has been unregistered */
- retcode = -EINTR;
- break;
+ } else {
+ unsigned long _end=jiffies + 3*DRM_HZ;
+ int locked = 0;
+
+ drm_idlelock_take(&dev->lock);
+
+ /*
+ * Wait for a while.
+ */
+
+ do{
+ spin_lock(&dev->lock.spinlock);
+ locked = dev->lock.idle_has_lock;
+ spin_unlock(&dev->lock.spinlock);
+ if (locked)
+ break;
+ schedule();
+ } while (!time_after_eq(jiffies, _end));
+
+ if (!locked) {
+ DRM_ERROR("reclaim_buffers_locked() deadlock. Please rework this\n"
+ "\tdriver to use reclaim_buffers_idlelocked() instead.\n"
+ "\tI will go on reclaiming the buffers anyway.\n");
}
- if (drm_lock_take(&dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT)) {
- dev->lock.filp = filp;
- dev->lock.lock_time = jiffies;
- atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
- break; /* Got lock */
- }
- /* Contention */
- schedule();
- if (signal_pending(current)) {
- retcode = -ERESTARTSYS;
- break;
- }
- }
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(&dev->lock.lock_queue, &entry);
- if (!retcode) {
+
dev->driver->reclaim_buffers_locked(dev, filp);
- drm_lock_free(dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT);
+ drm_idlelock_release(&dev->lock);
}
}
+ if (dev->driver->reclaim_buffers_idlelocked && dev->lock.hw_lock) {
+
+ drm_idlelock_take(&dev->lock);
+ dev->driver->reclaim_buffers_idlelocked(dev, filp);
+ drm_idlelock_release(&dev->lock);
+
+ }
+
+ if (drm_i_have_hw_lock(filp)) {
+ DRM_DEBUG("File %p released, freeing lock for context %d\n",
+ filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+
+ drm_lock_free(&dev->lock,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+ }
+
+
if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) &&
!dev->driver->reclaim_buffers_locked) {
dev->driver->reclaim_buffers(dev, filp);
diff --git a/drivers/char/drm/drm_hashtab.c b/drivers/char/drm/drm_hashtab.c
index a0b2d68..31acb62 100644
--- a/drivers/char/drm/drm_hashtab.c
+++ b/drivers/char/drm/drm_hashtab.c
@@ -43,7 +43,16 @@ int drm_ht_create(drm_open_hash_t *ht, unsigned int order)
ht->size = 1 << order;
ht->order = order;
ht->fill = 0;
- ht->table = vmalloc(ht->size*sizeof(*ht->table));
+ ht->table = NULL;
+ ht->use_vmalloc = ((ht->size * sizeof(*ht->table)) > PAGE_SIZE);
+ if (!ht->use_vmalloc) {
+ ht->table = drm_calloc(ht->size, sizeof(*ht->table),
+ DRM_MEM_HASHTAB);
+ }
+ if (!ht->table) {
+ ht->use_vmalloc = 1;
+ ht->table = vmalloc(ht->size*sizeof(*ht->table));
+ }
if (!ht->table) {
DRM_ERROR("Out of memory for hash table\n");
return -ENOMEM;
@@ -183,7 +192,11 @@ int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item)
void drm_ht_remove(drm_open_hash_t *ht)
{
if (ht->table) {
- vfree(ht->table);
+ if (ht->use_vmalloc)
+ vfree(ht->table);
+ else
+ drm_free(ht->table, ht->size * sizeof(*ht->table),
+ DRM_MEM_HASHTAB);
ht->table = NULL;
}
}
diff --git a/drivers/char/drm/drm_hashtab.h b/drivers/char/drm/drm_hashtab.h
index 40afec0..613091c 100644
--- a/drivers/char/drm/drm_hashtab.h
+++ b/drivers/char/drm/drm_hashtab.h
@@ -47,6 +47,7 @@ typedef struct drm_open_hash{
unsigned int order;
unsigned int fill;
struct hlist_head *table;
+ int use_vmalloc;
} drm_open_hash_t;
diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c
index 9d00c51..2e75331 100644
--- a/drivers/char/drm/drm_irq.c
+++ b/drivers/char/drm/drm_irq.c
@@ -424,7 +424,7 @@ static void drm_locked_tasklet_func(unsigned long data)
spin_lock_irqsave(&dev->tasklet_lock, irqflags);
if (!dev->locked_tasklet_func ||
- !drm_lock_take(&dev->lock.hw_lock->lock,
+ !drm_lock_take(&dev->lock,
DRM_KERNEL_CONTEXT)) {
spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
return;
@@ -435,7 +435,7 @@ static void drm_locked_tasklet_func(unsigned long data)
dev->locked_tasklet_func(dev);
- drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ drm_lock_free(&dev->lock,
DRM_KERNEL_CONTEXT);
dev->locked_tasklet_func = NULL;
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
index e9993ba..befd1af 100644
--- a/drivers/char/drm/drm_lock.c
+++ b/drivers/char/drm/drm_lock.c
@@ -35,9 +35,6 @@
#include "drmP.h"
-static int drm_lock_transfer(drm_device_t * dev,
- __volatile__ unsigned int *lock,
- unsigned int context);
static int drm_notifier(void *priv);
/**
@@ -80,6 +77,9 @@ int drm_lock(struct inode *inode, struct file *filp,
return -EINVAL;
add_wait_queue(&dev->lock.lock_queue, &entry);
+ spin_lock(&dev->lock.spinlock);
+ dev->lock.user_waiters++;
+ spin_unlock(&dev->lock.spinlock);
for (;;) {
__set_current_state(TASK_INTERRUPTIBLE);
if (!dev->lock.hw_lock) {
@@ -87,7 +87,7 @@ int drm_lock(struct inode *inode, struct file *filp,
ret = -EINTR;
break;
}
- if (drm_lock_take(&dev->lock.hw_lock->lock, lock.context)) {
+ if (drm_lock_take(&dev->lock, lock.context)) {
dev->lock.filp = filp;
dev->lock.lock_time = jiffies;
atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
@@ -101,12 +101,14 @@ int drm_lock(struct inode *inode, struct file *filp,
break;
}
}
+ spin_lock(&dev->lock.spinlock);
+ dev->lock.user_waiters--;
+ spin_unlock(&dev->lock.spinlock);
__set_current_state(TASK_RUNNING);
remove_wait_queue(&dev->lock.lock_queue, &entry);
- DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
- if (ret)
- return ret;
+ DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
+ if (ret) return ret;
sigemptyset(&dev->sigmask);
sigaddset(&dev->sigmask, SIGSTOP);
@@ -127,14 +129,12 @@ int drm_lock(struct inode *inode, struct file *filp,
}
}
- /* dev->driver->kernel_context_switch isn't used by any of the x86
- * drivers but is used by the Sparc driver.
- */
if (dev->driver->kernel_context_switch &&
dev->last_context != lock.context) {
dev->driver->kernel_context_switch(dev, dev->last_context,
lock.context);
}
+
return 0;
}
@@ -184,12 +184,8 @@ int drm_unlock(struct inode *inode, struct file *filp,
if (dev->driver->kernel_context_switch_unlock)
dev->driver->kernel_context_switch_unlock(dev);
else {
- drm_lock_transfer(dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT);
-
- if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
- DRM_KERNEL_CONTEXT)) {
- DRM_ERROR("\n");
+ if (drm_lock_free(&dev->lock,lock.context)) {
+ /* FIXME: Should really bail out here. */
}
}
@@ -206,18 +202,26 @@ int drm_unlock(struct inode *inode, struct file *filp,
*
* Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction.
*/
-int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
+int drm_lock_take(drm_lock_data_t *lock_data,
+ unsigned int context)
{
unsigned int old, new, prev;
+ volatile unsigned int *lock = &lock_data->hw_lock->lock;
+ spin_lock(&lock_data->spinlock);
do {
old = *lock;
if (old & _DRM_LOCK_HELD)
new = old | _DRM_LOCK_CONT;
- else
- new = context | _DRM_LOCK_HELD;
+ else {
+ new = context | _DRM_LOCK_HELD |
+ ((lock_data->user_waiters + lock_data->kernel_waiters > 1) ?
+ _DRM_LOCK_CONT : 0);
+ }
prev = cmpxchg(lock, old, new);
} while (prev != old);
+ spin_unlock(&lock_data->spinlock);
+
if (_DRM_LOCKING_CONTEXT(old) == context) {
if (old & _DRM_LOCK_HELD) {
if (context != DRM_KERNEL_CONTEXT) {
@@ -227,7 +231,8 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
return 0;
}
}
- if (new == (context | _DRM_LOCK_HELD)) {
+
+ if ((_DRM_LOCKING_CONTEXT(new)) == context && (new & _DRM_LOCK_HELD)) {
/* Have lock */
return 1;
}
@@ -246,13 +251,13 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
* Resets the lock file pointer.
* Marks the lock as held by the given context, via the \p cmpxchg instruction.
*/
-static int drm_lock_transfer(drm_device_t * dev,
- __volatile__ unsigned int *lock,
+static int drm_lock_transfer(drm_lock_data_t *lock_data,
unsigned int context)
{
unsigned int old, new, prev;
+ volatile unsigned int *lock = &lock_data->hw_lock->lock;
- dev->lock.filp = NULL;
+ lock_data->filp = NULL;
do {
old = *lock;
new = context | _DRM_LOCK_HELD;
@@ -272,23 +277,32 @@ static int drm_lock_transfer(drm_device_t * dev,
* Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task
* waiting on the lock queue.
*/
-int drm_lock_free(drm_device_t * dev,
- __volatile__ unsigned int *lock, unsigned int context)
+int drm_lock_free(drm_lock_data_t *lock_data, unsigned int context)
{
unsigned int old, new, prev;
+ volatile unsigned int *lock = &lock_data->hw_lock->lock;
+
+ spin_lock(&lock_data->spinlock);
+ if (lock_data->kernel_waiters != 0) {
+ drm_lock_transfer(lock_data, 0);
+ lock_data->idle_has_lock = 1;
+ spin_unlock(&lock_data->spinlock);
+ return 1;
+ }
+ spin_unlock(&lock_data->spinlock);
- dev->lock.filp = NULL;
do {
old = *lock;
- new = 0;
+ new = _DRM_LOCKING_CONTEXT(old);
prev = cmpxchg(lock, old, new);
} while (prev != old);
+
if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
DRM_ERROR("%d freed heavyweight lock held by %d\n",
context, _DRM_LOCKING_CONTEXT(old));
return 1;
}
- wake_up_interruptible(&dev->lock.lock_queue);
+ wake_up_interruptible(&lock_data->lock_queue);
return 0;
}
@@ -322,3 +336,67 @@ static int drm_notifier(void *priv)
} while (prev != old);
return 0;
}
+
+/**
+ * This function returns immediately and takes the hw lock
+ * with the kernel context if it is free, otherwise it gets the highest priority when and if
+ * it is eventually released.
+ *
+ * This guarantees that the kernel will _eventually_ have the lock _unless_ it is held
+ * by a blocked process. (In the latter case an explicit wait for the hardware lock would cause
+ * a deadlock, which is why the "idlelock" was invented).
+ *
+ * This should be sufficient to wait for GPU idle without
+ * having to worry about starvation.
+ */
+
+void drm_idlelock_take(drm_lock_data_t *lock_data)
+{
+ int ret = 0;
+
+ spin_lock(&lock_data->spinlock);
+ lock_data->kernel_waiters++;
+ if (!lock_data->idle_has_lock) {
+
+ spin_unlock(&lock_data->spinlock);
+ ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT);
+ spin_lock(&lock_data->spinlock);
+
+ if (ret == 1)
+ lock_data->idle_has_lock = 1;
+ }
+ spin_unlock(&lock_data->spinlock);
+}
+EXPORT_SYMBOL(drm_idlelock_take);
+
+void drm_idlelock_release(drm_lock_data_t *lock_data)
+{
+ unsigned int old, prev;
+ volatile unsigned int *lock = &lock_data->hw_lock->lock;
+
+ spin_lock(&lock_data->spinlock);
+ if (--lock_data->kernel_waiters == 0) {
+ if (lock_data->idle_has_lock) {
+ do {
+ old = *lock;
+ prev = cmpxchg(lock, old, DRM_KERNEL_CONTEXT);
+ } while (prev != old);
+ wake_up_interruptible(&lock_data->lock_queue);
+ lock_data->idle_has_lock = 0;
+ }
+ }
+ spin_unlock(&lock_data->spinlock);
+}
+EXPORT_SYMBOL(drm_idlelock_release);
+
+
+int drm_i_have_hw_lock(struct file *filp)
+{
+ DRM_DEVICE;
+
+ return (priv->lock_count && dev->lock.hw_lock &&
+ _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
+ dev->lock.filp == filp);
+}
+
+EXPORT_SYMBOL(drm_i_have_hw_lock);
diff --git a/drivers/char/drm/drm_mm.c b/drivers/char/drm/drm_mm.c
index 9b46b85..2ec1d9f 100644
--- a/drivers/char/drm/drm_mm.c
+++ b/drivers/char/drm/drm_mm.c
@@ -274,7 +274,6 @@ int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size)
return drm_mm_create_tail_node(mm, start, size);
}
-EXPORT_SYMBOL(drm_mm_init);
void drm_mm_takedown(drm_mm_t * mm)
{
@@ -295,4 +294,3 @@ void drm_mm_takedown(drm_mm_t * mm)
drm_free(entry, sizeof(*entry), DRM_MEM_MM);
}
-EXPORT_SYMBOL(drm_mm_takedown);
diff --git a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h
index 2908b72..0fe7b44 100644
--- a/drivers/char/drm/drm_os_linux.h
+++ b/drivers/char/drm/drm_os_linux.h
@@ -70,9 +70,6 @@ static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size)
#endif
-/** Task queue handler arguments */
-#define DRM_TASKQUEUE_ARGS void *arg
-
/** For data going into the kernel through the ioctl argument */
#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \
if ( copy_from_user(&arg1, arg2, arg3) ) \
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index ad54b84..31cdde8 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -102,6 +102,7 @@
{0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \
{0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
+ {0x1002, 0x5955, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
{0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
@@ -230,10 +231,10 @@
{0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x3304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
- {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
+ {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
{0, 0, 0}
#define i810_PCI_IDS \
@@ -296,5 +297,6 @@
{0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+ {0x8086, 0x2a02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index 7fd0da7..b204498 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -72,7 +72,7 @@ static struct drm_proc_list {
#endif
};
-#define DRM_PROC_ENTRIES (sizeof(drm_proc_list)/sizeof(drm_proc_list[0]))
+#define DRM_PROC_ENTRIES ARRAY_SIZE(drm_proc_list)
/**
* Initialize the DRI proc filesystem for a device.
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 120d102..19408ad 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -62,6 +62,7 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
spin_lock_init(&dev->count_lock);
spin_lock_init(&dev->drw_lock);
spin_lock_init(&dev->tasklet_lock);
+ spin_lock_init(&dev->lock.spinlock);
init_timer(&dev->timer);
mutex_init(&dev->struct_mutex);
mutex_init(&dev->ctxlist_mutex);
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index 54a6328..35540cf 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -41,6 +41,30 @@
static void drm_vm_open(struct vm_area_struct *vma);
static void drm_vm_close(struct vm_area_struct *vma);
+static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
+{
+ pgprot_t tmp = vm_get_page_prot(vma->vm_flags);
+
+#if defined(__i386__) || defined(__x86_64__)
+ if (boot_cpu_data.x86 > 3 && map_type != _DRM_AGP) {
+ pgprot_val(tmp) |= _PAGE_PCD;
+ pgprot_val(tmp) &= ~_PAGE_PWT;
+ }
+#elif defined(__powerpc__)
+ pgprot_val(tmp) |= _PAGE_NO_CACHE;
+ if (map_type == _DRM_REGISTERS)
+ pgprot_val(tmp) |= _PAGE_GUARDED;
+#endif
+#if defined(__ia64__)
+ if (efi_range_is_wc(vma->vm_start, vma->vm_end -
+ vma->vm_start))
+ tmp = pgprot_writecombine(tmp);
+ else
+ tmp = pgprot_noncached(tmp);
+#endif
+ return tmp;
+}
+
/**
* \c nopage method for AGP virtual memory.
*
@@ -151,8 +175,7 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma,
offset = address - vma->vm_start;
i = (unsigned long)map->handle + offset;
- page = (map->type == _DRM_CONSISTENT) ?
- virt_to_page((void *)i) : vmalloc_to_page((void *)i);
+ page = vmalloc_to_page((void *)i);
if (!page)
return NOPAGE_SIGBUS;
get_page(page);
@@ -389,7 +412,7 @@ static struct vm_operations_struct drm_vm_sg_ops = {
* Create a new drm_vma_entry structure as the \p vma private data entry and
* add it to drm_device::vmalist.
*/
-static void drm_vm_open(struct vm_area_struct *vma)
+static void drm_vm_open_locked(struct vm_area_struct *vma)
{
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->head->dev;
@@ -401,15 +424,23 @@ static void drm_vm_open(struct vm_area_struct *vma)
vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
if (vma_entry) {
- mutex_lock(&dev->struct_mutex);
vma_entry->vma = vma;
vma_entry->next = dev->vmalist;
vma_entry->pid = current->pid;
dev->vmalist = vma_entry;
- mutex_unlock(&dev->struct_mutex);
}
}
+static void drm_vm_open(struct vm_area_struct *vma)
+{
+ drm_file_t *priv = vma->vm_file->private_data;
+ drm_device_t *dev = priv->head->dev;
+
+ mutex_lock(&dev->struct_mutex);
+ drm_vm_open_locked(vma);
+ mutex_unlock(&dev->struct_mutex);
+}
+
/**
* \c close method for all virtual memory types.
*
@@ -460,7 +491,6 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
drm_device_dma_t *dma;
unsigned long length = vma->vm_end - vma->vm_start;
- lock_kernel();
dev = priv->head->dev;
dma = dev->dma;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n",
@@ -468,10 +498,8 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
/* Length must match exact page count */
if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
- unlock_kernel();
return -EINVAL;
}
- unlock_kernel();
if (!capable(CAP_SYS_ADMIN) &&
(dma->flags & _DRM_DMA_USE_PCI_RO)) {
@@ -494,7 +522,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
vma->vm_flags |= VM_RESERVED; /* Don't swap */
vma->vm_file = filp; /* Needed for drm_vm_open() */
- drm_vm_open(vma);
+ drm_vm_open_locked(vma);
return 0;
}
@@ -529,7 +557,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs);
* according to the mapping type and remaps the pages. Finally sets the file
* pointer and calls vm_open().
*/
-int drm_mmap(struct file *filp, struct vm_area_struct *vma)
+static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
@@ -565,7 +593,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
return -EPERM;
/* Check for valid size. */
- if (map->size != vma->vm_end - vma->vm_start)
+ if (map->size < vma->vm_end - vma->vm_start)
return -EINVAL;
if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
@@ -600,37 +628,16 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
/* fall through to _DRM_FRAME_BUFFER... */
case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS:
-#if defined(__i386__) || defined(__x86_64__)
- if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
- pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
- pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
- }
-#elif defined(__powerpc__)
- pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
- if (map->type == _DRM_REGISTERS)
- pgprot_val(vma->vm_page_prot) |= _PAGE_GUARDED;
-#endif
- vma->vm_flags |= VM_IO; /* not in core dump */
-#if defined(__ia64__)
- if (efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start))
- vma->vm_page_prot =
- pgprot_writecombine(vma->vm_page_prot);
- else
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-#endif
offset = dev->driver->get_reg_ofs(dev);
+ vma->vm_flags |= VM_IO; /* not in core dump */
+ vma->vm_page_prot = drm_io_prot(map->type, vma);
#ifdef __sparc__
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+#endif
if (io_remap_pfn_range(vma, vma->vm_start,
(map->offset + offset) >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
-#else
- if (io_remap_pfn_range(vma, vma->vm_start,
- (map->offset + offset) >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot))
-#endif
return -EAGAIN;
DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
" offset = 0x%lx\n",
@@ -638,10 +645,15 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_start, vma->vm_end, map->offset + offset);
vma->vm_ops = &drm_vm_ops;
break;
- case _DRM_SHM:
case _DRM_CONSISTENT:
- /* Consistent memory is really like shared memory. It's only
- * allocate in a different way */
+ /* Consistent memory is really like shared memory. But
+ * it's allocated in a different way, so avoid nopage */
+ if (remap_pfn_range(vma, vma->vm_start,
+ page_to_pfn(virt_to_page(map->handle)),
+ vma->vm_end - vma->vm_start, vma->vm_page_prot))
+ return -EAGAIN;
+ /* fall through to _DRM_SHM */
+ case _DRM_SHM:
vma->vm_ops = &drm_vm_shm_ops;
vma->vm_private_data = (void *)map;
/* Don't let this area swap. Change when
@@ -659,8 +671,20 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_flags |= VM_RESERVED; /* Don't swap */
vma->vm_file = filp; /* Needed for drm_vm_open() */
- drm_vm_open(vma);
+ drm_vm_open_locked(vma);
return 0;
}
+int drm_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->head->dev;
+ int ret;
+
+ mutex_lock(&dev->struct_mutex);
+ ret = drm_mmap_locked(filp, vma);
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
EXPORT_SYMBOL(drm_mmap);
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index 9354ce3..1ba15d9 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -34,7 +34,8 @@
#define IS_I965G(dev) (dev->pci_device == 0x2972 || \
dev->pci_device == 0x2982 || \
dev->pci_device == 0x2992 || \
- dev->pci_device == 0x29A2)
+ dev->pci_device == 0x29A2 || \
+ dev->pci_device == 0x2A02)
/* Really want an OS-independent resettable timer. Would like to have
* this loop run for (eg) 3 sec, but have the timer reset every time
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c
index db5a604..1014602 100644
--- a/drivers/char/drm/r128_cce.c
+++ b/drivers/char/drm/r128_cce.c
@@ -560,9 +560,10 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init)
if (dev_priv->is_pci) {
#endif
dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN;
+ dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE;
dev_priv->gart_info.addr = NULL;
dev_priv->gart_info.bus_addr = 0;
- dev_priv->gart_info.is_pcie = 0;
+ dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
DRM_ERROR("failed to init PCI GART!\n");
dev->dev_private = (void *)dev_priv;
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
index f1efb49..9086835 100644
--- a/drivers/char/drm/r128_drv.h
+++ b/drivers/char/drm/r128_drv.h
@@ -383,6 +383,8 @@ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
#define R128_PERFORMANCE_BOXES 0
+#define R128_PCIGART_TABLE_SIZE 32768
+
#define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
#define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
#define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 5ed9656..68338389 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -830,6 +830,15 @@ static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
return RADEON_READ(RADEON_PCIE_DATA);
}
+static u32 RADEON_READ_IGPGART(drm_radeon_private_t *dev_priv, int addr)
+{
+ u32 ret;
+ RADEON_WRITE(RADEON_IGPGART_INDEX, addr & 0x7f);
+ ret = RADEON_READ(RADEON_IGPGART_DATA);
+ RADEON_WRITE(RADEON_IGPGART_INDEX, 0x7f);
+ return ret;
+}
+
#if RADEON_FIFO_DEBUG
static void radeon_status(drm_radeon_private_t * dev_priv)
{
@@ -1267,7 +1276,44 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
}
}
-/* Enable or disable PCI-E GART on the chip */
+/* Enable or disable IGP GART on the chip */
+static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
+{
+ u32 temp, tmp;
+
+ tmp = RADEON_READ(RADEON_AIC_CNTL);
+ if (on) {
+ DRM_DEBUG("programming igpgart %08X %08lX %08X\n",
+ dev_priv->gart_vm_start,
+ (long)dev_priv->gart_info.bus_addr,
+ dev_priv->gart_size);
+
+ RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_18, 0x1000);
+ RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, 0x1);
+ RADEON_WRITE_IGPGART(RADEON_IGPGART_CTRL, 0x42040800);
+ RADEON_WRITE_IGPGART(RADEON_IGPGART_BASE_ADDR,
+ dev_priv->gart_info.bus_addr);
+
+ temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_UNK_39);
+ RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_39, temp);
+
+ RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start);
+ dev_priv->gart_size = 32*1024*1024;
+ RADEON_WRITE(RADEON_MC_AGP_LOCATION,
+ (((dev_priv->gart_vm_start - 1 +
+ dev_priv->gart_size) & 0xffff0000) |
+ (dev_priv->gart_vm_start >> 16)));
+
+ temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_ENABLE);
+ RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, temp);
+
+ RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH);
+ RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x1);
+ RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH);
+ RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x0);
+ }
+}
+
static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
{
u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
@@ -1302,6 +1348,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
{
u32 tmp;
+ if (dev_priv->flags & RADEON_IS_IGPGART) {
+ radeon_set_igpgart(dev_priv, on);
+ return;
+ }
+
if (dev_priv->flags & RADEON_IS_PCIE) {
radeon_set_pciegart(dev_priv, on);
return;
@@ -1560,8 +1611,8 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
if (dev_priv->flags & RADEON_IS_AGP) {
base = dev->agp->base;
/* Check if valid */
- if ((base + dev_priv->gart_size) > dev_priv->fb_location &&
- base < (dev_priv->fb_location + dev_priv->fb_size)) {
+ if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location &&
+ base < (dev_priv->fb_location + dev_priv->fb_size - 1)) {
DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n",
dev->agp->base);
base = 0;
@@ -1571,8 +1622,8 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
/* If not or if AGP is at 0 (Macs), try to put it elsewhere */
if (base == 0) {
base = dev_priv->fb_location + dev_priv->fb_size;
- if (((base + dev_priv->gart_size) & 0xfffffffful)
- < base)
+ if (base < dev_priv->fb_location ||
+ ((base + dev_priv->gart_size) & 0xfffffffful) < base)
base = dev_priv->fb_location
- dev_priv->gart_size;
}
@@ -1620,20 +1671,22 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
#endif
{
/* if we have an offset set from userspace */
- if (dev_priv->pcigart_offset) {
+ if (dev_priv->pcigart_offset_set) {
dev_priv->gart_info.bus_addr =
dev_priv->pcigart_offset + dev_priv->fb_location;
dev_priv->gart_info.mapping.offset =
dev_priv->gart_info.bus_addr;
dev_priv->gart_info.mapping.size =
- RADEON_PCIGART_TABLE_SIZE;
+ dev_priv->gart_info.table_size;
drm_core_ioremap(&dev_priv->gart_info.mapping, dev);
dev_priv->gart_info.addr =
dev_priv->gart_info.mapping.handle;
- dev_priv->gart_info.is_pcie =
- !!(dev_priv->flags & RADEON_IS_PCIE);
+ if (dev_priv->flags & RADEON_IS_PCIE)
+ dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE;
+ else
+ dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
dev_priv->gart_info.gart_table_location =
DRM_ATI_GART_FB;
@@ -1641,6 +1694,10 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
dev_priv->gart_info.addr,
dev_priv->pcigart_offset);
} else {
+ if (dev_priv->flags & RADEON_IS_IGPGART)
+ dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP;
+ else
+ dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
dev_priv->gart_info.gart_table_location =
DRM_ATI_GART_MAIN;
dev_priv->gart_info.addr = NULL;
@@ -1714,7 +1771,7 @@ static int radeon_do_cleanup_cp(drm_device_t * dev)
if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB)
{
drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
- dev_priv->gart_info.addr = NULL;
+ dev_priv->gart_info.addr = 0;
}
}
/* only clear to the start of flags */
@@ -2222,6 +2279,8 @@ int radeon_driver_firstopen(struct drm_device *dev)
drm_local_map_t *map;
drm_radeon_private_t *dev_priv = dev->dev_private;
+ dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
+
ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
drm_get_resource_len(dev, 2), _DRM_REGISTERS,
_DRM_READ_ONLY, &dev_priv->mmio);
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
index 8d6350d..66c4b6f 100644
--- a/drivers/char/drm/radeon_drm.h
+++ b/drivers/char/drm/radeon_drm.h
@@ -707,6 +707,7 @@ typedef struct drm_radeon_setparam {
#define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */
#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */
#define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */
+#define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */
/* 1.14: Clients can allocate/free a surface
*/
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index 8b105f1..54f49ef 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -95,9 +95,11 @@
* 1.24- Add general-purpose packet for manipulating scratch registers (r300)
* 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL,
* new packet type)
+ * 1.26- Add support for variable size PCI(E) gart aperture
+ * 1.27- Add support for IGP GART
*/
#define DRIVER_MAJOR 1
-#define DRIVER_MINOR 25
+#define DRIVER_MINOR 27
#define DRIVER_PATCHLEVEL 0
/*
@@ -143,6 +145,7 @@ enum radeon_chip_flags {
RADEON_IS_PCIE = 0x00200000UL,
RADEON_NEW_MEMMAP = 0x00400000UL,
RADEON_IS_PCI = 0x00800000UL,
+ RADEON_IS_IGPGART = 0x01000000UL,
};
#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \
@@ -240,7 +243,6 @@ typedef struct drm_radeon_private {
int do_boxes;
int page_flipping;
- int current_page;
u32 color_fmt;
unsigned int front_offset;
@@ -280,6 +282,7 @@ typedef struct drm_radeon_private {
struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES];
unsigned long pcigart_offset;
+ unsigned int pcigart_offset_set;
drm_ati_pcigart_info gart_info;
u32 scratch_ages[5];
@@ -432,6 +435,15 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
#define RADEON_PCIE_TX_GART_END_LO 0x16
#define RADEON_PCIE_TX_GART_END_HI 0x17
+#define RADEON_IGPGART_INDEX 0x168
+#define RADEON_IGPGART_DATA 0x16c
+#define RADEON_IGPGART_UNK_18 0x18
+#define RADEON_IGPGART_CTRL 0x2b
+#define RADEON_IGPGART_BASE_ADDR 0x2c
+#define RADEON_IGPGART_FLUSH 0x2e
+#define RADEON_IGPGART_ENABLE 0x38
+#define RADEON_IGPGART_UNK_39 0x39
+
#define RADEON_MPP_TB_CONFIG 0x01c0
#define RADEON_MEM_CNTL 0x0140
#define RADEON_MEM_SDRAM_MODE_REG 0x0158
@@ -964,6 +976,14 @@ do { \
RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \
} while (0)
+#define RADEON_WRITE_IGPGART( addr, val ) \
+do { \
+ RADEON_WRITE( RADEON_IGPGART_INDEX, \
+ ((addr) & 0x7f) | (1 << 8)); \
+ RADEON_WRITE( RADEON_IGPGART_DATA, (val) ); \
+ RADEON_WRITE( RADEON_IGPGART_INDEX, 0x7f ); \
+} while (0)
+
#define RADEON_WRITE_PCIE( addr, val ) \
do { \
RADEON_WRITE8( RADEON_PCIE_INDEX, \
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 938eccb..98c5f1d 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -773,7 +773,7 @@ static void radeon_clear_box(drm_radeon_private_t * dev_priv,
RADEON_GMC_SRC_DATATYPE_COLOR |
RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS);
- if (dev_priv->page_flipping && dev_priv->current_page == 1) {
+ if (dev_priv->sarea_priv->pfCurrentPage == 1) {
OUT_RING(dev_priv->front_pitch_offset);
} else {
OUT_RING(dev_priv->back_pitch_offset);
@@ -861,7 +861,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev,
dev_priv->stats.clears++;
- if (dev_priv->page_flipping && dev_priv->current_page == 1) {
+ if (dev_priv->sarea_priv->pfCurrentPage == 1) {
unsigned int tmp = flags;
flags &= ~(RADEON_FRONT | RADEON_BACK);
@@ -1382,7 +1382,7 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev)
/* Make this work even if front & back are flipped:
*/
OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1));
- if (dev_priv->current_page == 0) {
+ if (dev_priv->sarea_priv->pfCurrentPage == 0) {
OUT_RING(dev_priv->back_pitch_offset);
OUT_RING(dev_priv->front_pitch_offset);
} else {
@@ -1416,12 +1416,12 @@ static void radeon_cp_dispatch_flip(drm_device_t * dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
drm_sarea_t *sarea = (drm_sarea_t *) dev_priv->sarea->handle;
- int offset = (dev_priv->current_page == 1)
+ int offset = (dev_priv->sarea_priv->pfCurrentPage == 1)
? dev_priv->front_offset : dev_priv->back_offset;
RING_LOCALS;
- DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
+ DRM_DEBUG("%s: pfCurrentPage=%d\n",
__FUNCTION__,
- dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage);
+ dev_priv->sarea_priv->pfCurrentPage);
/* Do some trivial performance monitoring...
*/
@@ -1449,8 +1449,8 @@ static void radeon_cp_dispatch_flip(drm_device_t * dev)
* performing the swapbuffer ioctl.
*/
dev_priv->sarea_priv->last_frame++;
- dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =
- 1 - dev_priv->current_page;
+ dev_priv->sarea_priv->pfCurrentPage =
+ 1 - dev_priv->sarea_priv->pfCurrentPage;
BEGIN_RING(2);
@@ -2152,24 +2152,10 @@ static int radeon_do_init_pageflip(drm_device_t * dev)
ADVANCE_RING();
dev_priv->page_flipping = 1;
- dev_priv->current_page = 0;
- dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
- return 0;
-}
-
-/* Called whenever a client dies, from drm_release.
- * NOTE: Lock isn't necessarily held when this is called!
- */
-static int radeon_do_cleanup_pageflip(drm_device_t * dev)
-{
- drm_radeon_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG("\n");
-
- if (dev_priv->current_page != 0)
- radeon_cp_dispatch_flip(dev);
+ if (dev_priv->sarea_priv->pfCurrentPage != 1)
+ dev_priv->sarea_priv->pfCurrentPage = 0;
- dev_priv->page_flipping = 0;
return 0;
}
@@ -3145,10 +3131,16 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS)
break;
case RADEON_SETPARAM_PCIGART_LOCATION:
dev_priv->pcigart_offset = sp.value;
+ dev_priv->pcigart_offset_set = 1;
break;
case RADEON_SETPARAM_NEW_MEMMAP:
dev_priv->new_memmap = sp.value;
break;
+ case RADEON_SETPARAM_PCIGART_TABLE_SIZE:
+ dev_priv->gart_info.table_size = sp.value;
+ if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE)
+ dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
+ break;
default:
DRM_DEBUG("Invalid parameter %d\n", sp.param);
return DRM_ERR(EINVAL);
@@ -3168,9 +3160,7 @@ void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp)
{
if (dev->dev_private) {
drm_radeon_private_t *dev_priv = dev->dev_private;
- if (dev_priv->page_flipping) {
- radeon_do_cleanup_pageflip(dev);
- }
+ dev_priv->page_flipping = 0;
radeon_mem_release(filp, dev_priv->gart_heap);
radeon_mem_release(filp, dev_priv->fb_heap);
radeon_surfaces_release(filp, dev_priv);
@@ -3179,6 +3169,14 @@ void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp)
void radeon_driver_lastclose(drm_device_t * dev)
{
+ if (dev->dev_private) {
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if (dev_priv->sarea_priv &&
+ dev_priv->sarea_priv->pfCurrentPage != 0)
+ radeon_cp_dispatch_flip(dev);
+ }
+
radeon_do_release(dev);
}
diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c
index 3d5b321..690e0af 100644
--- a/drivers/char/drm/sis_drv.c
+++ b/drivers/char/drm/sis_drv.c
@@ -71,7 +71,7 @@ static struct drm_driver driver = {
.context_dtor = NULL,
.dma_quiescent = sis_idle,
.reclaim_buffers = NULL,
- .reclaim_buffers_locked = sis_reclaim_buffers_locked,
+ .reclaim_buffers_idlelocked = sis_reclaim_buffers_locked,
.lastclose = sis_lastclose,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c
index c0539c6..13a9c5c 100644
--- a/drivers/char/drm/via_dma.c
+++ b/drivers/char/drm/via_dma.c
@@ -252,7 +252,7 @@ static int via_dma_init(DRM_IOCTL_ARGS)
break;
case VIA_DMA_INITIALIZED:
retcode = (dev_priv->ring.virtual_start != NULL) ?
- 0 : DRM_ERR(EFAULT);
+ 0 : DRM_ERR(EFAULT);
break;
default:
retcode = DRM_ERR(EINVAL);
@@ -432,56 +432,34 @@ static int via_hook_segment(drm_via_private_t * dev_priv,
{
int paused, count;
volatile uint32_t *paused_at = dev_priv->last_pause_ptr;
+ uint32_t reader,ptr;
+ paused = 0;
via_flush_write_combine();
- while (!*(via_get_dma(dev_priv) - 1)) ;
- *dev_priv->last_pause_ptr = pause_addr_lo;
+ (void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1);
+ *paused_at = pause_addr_lo;
via_flush_write_combine();
-
- /*
- * The below statement is inserted to really force the flush.
- * Not sure it is needed.
- */
-
- while (!*dev_priv->last_pause_ptr) ;
+ (void) *paused_at;
+ reader = *(dev_priv->hw_addr_ptr);
+ ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) +
+ dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1;
- while (!*dev_priv->last_pause_ptr) ;
- paused = 0;
- count = 20;
-
- while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--) ;
- if ((count <= 8) && (count >= 0)) {
- uint32_t rgtr, ptr;
- rgtr = *(dev_priv->hw_addr_ptr);
- ptr = ((volatile char *)dev_priv->last_pause_ptr -
- dev_priv->dma_ptr) + dev_priv->dma_offset +
- (uint32_t) dev_priv->agpAddr + 4 - CMDBUF_ALIGNMENT_SIZE;
- if (rgtr <= ptr) {
- DRM_ERROR
- ("Command regulator\npaused at count %d, address %x, "
- "while current pause address is %x.\n"
- "Please mail this message to "
- "<unichrome-devel@lists.sourceforge.net>\n", count,
- rgtr, ptr);
- }
+ if ((ptr - reader) <= dev_priv->dma_diff ) {
+ count = 10000000;
+ while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--);
}
if (paused && !no_pci_fire) {
- uint32_t rgtr, ptr;
- uint32_t ptr_low;
+ reader = *(dev_priv->hw_addr_ptr);
+ if ((ptr - reader) == dev_priv->dma_diff) {
- count = 1000000;
- while ((VIA_READ(VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY)
- && count--) ;
+ /*
+ * There is a concern that these writes may stall the PCI bus
+ * if the GPU is not idle. However, idling the GPU first
+ * doesn't make a difference.
+ */
- rgtr = *(dev_priv->hw_addr_ptr);
- ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) +
- dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
-
- ptr_low = (ptr > 3 * CMDBUF_ALIGNMENT_SIZE) ?
- ptr - 3 * CMDBUF_ALIGNMENT_SIZE : 0;
- if (rgtr <= ptr && rgtr >= ptr_low) {
VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
@@ -494,6 +472,9 @@ static int via_hook_segment(drm_via_private_t * dev_priv,
static int via_wait_idle(drm_via_private_t * dev_priv)
{
int count = 10000000;
+
+ while (!(VIA_READ(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && count--);
+
while (count-- && (VIA_READ(VIA_REG_STATUS) &
(VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY |
VIA_3D_ENG_BUSY))) ;
@@ -537,6 +518,9 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv)
uint32_t end_addr, end_addr_lo;
uint32_t command;
uint32_t agp_base;
+ uint32_t ptr;
+ uint32_t reader;
+ int count;
dev_priv->dma_low = 0;
@@ -554,7 +538,7 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv)
&pause_addr_hi, &pause_addr_lo, 1) - 1;
via_flush_write_combine();
- while (!*dev_priv->last_pause_ptr) ;
+ (void) *(volatile uint32_t *)dev_priv->last_pause_ptr;
VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
VIA_WRITE(VIA_REG_TRANSPACE, command);
@@ -566,6 +550,24 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv)
DRM_WRITEMEMORYBARRIER();
VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK);
VIA_READ(VIA_REG_TRANSPACE);
+
+ dev_priv->dma_diff = 0;
+
+ count = 10000000;
+ while (!(VIA_READ(0x41c) & 0x80000000) && count--);
+
+ reader = *(dev_priv->hw_addr_ptr);
+ ptr = ((volatile char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) +
+ dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
+
+ /*
+ * This is the difference between where we tell the
+ * command reader to pause and where it actually pauses.
+ * This differs between hw implementation so we need to
+ * detect it.
+ */
+
+ dev_priv->dma_diff = ptr - reader;
}
static void via_pad_cache(drm_via_private_t * dev_priv, int qwords)
@@ -592,7 +594,6 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
uint32_t pause_addr_lo, pause_addr_hi;
uint32_t jump_addr_lo, jump_addr_hi;
volatile uint32_t *last_pause_ptr;
- uint32_t dma_low_save1, dma_low_save2;
agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi,
@@ -619,31 +620,11 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
&pause_addr_lo, 0);
*last_pause_ptr = pause_addr_lo;
- dma_low_save1 = dev_priv->dma_low;
-
- /*
- * Now, set a trap that will pause the regulator if it tries to rerun the old
- * command buffer. (Which may happen if via_hook_segment detecs a command regulator pause
- * and reissues the jump command over PCI, while the regulator has already taken the jump
- * and actually paused at the current buffer end).
- * There appears to be no other way to detect this condition, since the hw_addr_pointer
- * does not seem to get updated immediately when a jump occurs.
- */
- last_pause_ptr =
- via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
- &pause_addr_lo, 0) - 1;
- via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
- &pause_addr_lo, 0);
- *last_pause_ptr = pause_addr_lo;
-
- dma_low_save2 = dev_priv->dma_low;
- dev_priv->dma_low = dma_low_save1;
- via_hook_segment(dev_priv, jump_addr_hi, jump_addr_lo, 0);
- dev_priv->dma_low = dma_low_save2;
- via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
+ via_hook_segment( dev_priv, jump_addr_hi, jump_addr_lo, 0);
}
+
static void via_cmdbuf_rewind(drm_via_private_t * dev_priv)
{
via_cmdbuf_jump(dev_priv);
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c
index bb9dde8..2d4957a 100644
--- a/drivers/char/drm/via_drv.c
+++ b/drivers/char/drm/via_drv.c
@@ -52,7 +52,8 @@ static struct drm_driver driver = {
.dma_quiescent = via_driver_dma_quiescent,
.dri_library_name = dri_library_name,
.reclaim_buffers = drm_core_reclaim_buffers,
- .reclaim_buffers_locked = via_reclaim_buffers_locked,
+ .reclaim_buffers_locked = NULL,
+ .reclaim_buffers_idlelocked = via_reclaim_buffers_locked,
.lastclose = via_lastclose,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h
index 8b8778d..b46ca8e 100644
--- a/drivers/char/drm/via_drv.h
+++ b/drivers/char/drm/via_drv.h
@@ -29,11 +29,11 @@
#define DRIVER_NAME "via"
#define DRIVER_DESC "VIA Unichrome / Pro"
-#define DRIVER_DATE "20061227"
+#define DRIVER_DATE "20070202"
#define DRIVER_MAJOR 2
#define DRIVER_MINOR 11
-#define DRIVER_PATCHLEVEL 0
+#define DRIVER_PATCHLEVEL 1
#include "via_verifier.h"
@@ -93,6 +93,7 @@ typedef struct drm_via_private {
unsigned long vram_offset;
unsigned long agp_offset;
drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES];
+ uint32_t dma_diff;
} drm_via_private_t;
enum via_family {
diff --git a/drivers/char/drm/via_mm.h b/drivers/char/drm/via_mm.h
deleted file mode 100644
index d57efda..0000000
--- a/drivers/char/drm/via_mm.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
- * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sub license,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#ifndef _via_drm_mm_h_
-#define _via_drm_mm_h_
-
-typedef struct {
- unsigned int context;
- unsigned int size;
- unsigned long offset;
- unsigned long free;
-} drm_via_mm_t;
-
-typedef struct {
- unsigned int size;
- unsigned long handle;
- void *virtual;
-} drm_via_dma_t;
-
-#endif
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index 3d7efc2..334ad5b 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -4,7 +4,6 @@
*/
#include <linux/module.h>
#include <linux/miscdevice.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/capability.h>
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index db984e4..9b8278e 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -32,7 +32,6 @@
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/device.h>
#include <asm/atarihw.h>
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index d8dbdb9..abde6dd 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -62,7 +62,6 @@
#include <linux/init.h> /* for __init, module_{init,exit} */
#include <linux/poll.h> /* for POLLIN, etc. */
#include <linux/dtlk.h> /* local header file for DoubleTalk values */
-#include <linux/smp_lock.h>
#ifdef TRACING
#define TRACE_TEXT(str) printk(str);
@@ -325,16 +324,22 @@ static int dtlk_release(struct inode *inode, struct file *file)
static int __init dtlk_init(void)
{
+ int err;
+
dtlk_port_lpc = 0;
dtlk_port_tts = 0;
dtlk_busy = 0;
dtlk_major = register_chrdev(0, "dtlk", &dtlk_fops);
- if (dtlk_major == 0) {
+ if (dtlk_major < 0) {
printk(KERN_ERR "DoubleTalk PC - cannot register device\n");
- return 0;
+ return dtlk_major;
+ }
+ err = dtlk_dev_probe();
+ if (err) {
+ unregister_chrdev(dtlk_major, "dtlk");
+ return err;
}
- if (dtlk_dev_probe() == 0)
- printk(", MAJOR %d\n", dtlk_major);
+ printk(", MAJOR %d\n", dtlk_major);
init_waitqueue_head(&dtlk_process_list);
diff --git a/drivers/char/ec3104_keyb.c b/drivers/char/ec3104_keyb.c
index 77f58ed..0200114 100644
--- a/drivers/char/ec3104_keyb.c
+++ b/drivers/char/ec3104_keyb.c
@@ -41,7 +41,6 @@
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/kbd_kern.h>
-#include <linux/smp_lock.h>
#include <linux/bitops.h>
#include <asm/keyboard.h>
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index de5be30..c6c56fb 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -949,7 +949,7 @@ static int block_til_ready(struct tty_struct *tty,
} /* End forever while */
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&ch->open_wait, &wait);
if (!tty_hung_up_p(filp))
ch->count++;
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c
index 23b25ad..49f914e 100644
--- a/drivers/char/genrtc.c
+++ b/drivers/char/genrtc.c
@@ -207,7 +207,7 @@ static ssize_t gen_rtc_read(struct file *file, char __user *buf,
sizeof(unsigned long);
}
out:
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&gen_rtc_wait, &wait);
return retval;
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index ae76a9f..f0e7263 100644
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -44,7 +44,6 @@
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/reboot.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 0f9ed7b..322bc5f 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -111,7 +111,7 @@ static int last_hvc = -1;
* lock held. If successful, this function increments the kobject reference
* count against the target hvc_struct so it should be released when finished.
*/
-struct hvc_struct *hvc_get_by_index(int index)
+static struct hvc_struct *hvc_get_by_index(int index)
{
struct hvc_struct *hp;
unsigned long flags;
@@ -150,7 +150,8 @@ static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
* hvc_console_setup() finds adapters.
*/
-void hvc_console_print(struct console *co, const char *b, unsigned count)
+static void hvc_console_print(struct console *co, const char *b,
+ unsigned count)
{
char c[N_OUTBUF] __ALIGNED__;
unsigned i = 0, n = 0;
@@ -208,7 +209,7 @@ static int __init hvc_console_setup(struct console *co, char *options)
return 0;
}
-struct console hvc_con_driver = {
+static struct console hvc_con_driver = {
.name = "hvc",
.write = hvc_console_print,
.device = hvc_console_device,
@@ -278,7 +279,6 @@ int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops)
return 0;
}
-EXPORT_SYMBOL(hvc_instantiate);
/* Wake the sleeping khvcd */
static void hvc_kick(void)
@@ -792,7 +792,6 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
return hp;
}
-EXPORT_SYMBOL(hvc_alloc);
int __devexit hvc_remove(struct hvc_struct *hp)
{
@@ -828,11 +827,10 @@ int __devexit hvc_remove(struct hvc_struct *hp)
tty_hangup(tty);
return 0;
}
-EXPORT_SYMBOL(hvc_remove);
/* Driver initialization. Follow console initialization. This is where the TTY
* interfaces start to become available. */
-int __init hvc_init(void)
+static int __init hvc_init(void)
{
struct tty_driver *drv;
diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c
index ec420fe..b37f1d5 100644
--- a/drivers/char/hvc_iseries.c
+++ b/drivers/char/hvc_iseries.c
@@ -579,7 +579,7 @@ static int hvc_find_vtys(void)
if (!vtermno)
continue;
- if (!device_is_compatible(vty, "IBM,iSeries-vty"))
+ if (!of_device_is_compatible(vty, "IBM,iSeries-vty"))
continue;
if (num_found == 0)
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
index 94a542e..79711aa 100644
--- a/drivers/char/hvc_vio.c
+++ b/drivers/char/hvc_vio.c
@@ -157,7 +157,7 @@ static int hvc_find_vtys(void)
if (!vtermno)
continue;
- if (device_is_compatible(vty, "hvterm1")) {
+ if (of_device_is_compatible(vty, "hvterm1")) {
hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops);
++num_found;
}
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c
index cc1046e..4ae9811 100644
--- a/drivers/char/hw_random/intel-rng.c
+++ b/drivers/char/hw_random/intel-rng.c
@@ -24,10 +24,11 @@
* warranty of any kind, whether express or implied.
*/
-#include <linux/module.h>
+#include <linux/hw_random.h>
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/pci.h>
-#include <linux/hw_random.h>
+#include <linux/stop_machine.h>
#include <asm/io.h>
@@ -217,30 +218,117 @@ static struct hwrng intel_rng = {
.data_read = intel_rng_data_read,
};
+struct intel_rng_hw {
+ struct pci_dev *dev;
+ void __iomem *mem;
+ u8 bios_cntl_off;
+ u8 bios_cntl_val;
+ u8 fwh_dec_en1_off;
+ u8 fwh_dec_en1_val;
+};
-#ifdef CONFIG_SMP
-static char __initdata waitflag;
+static int __init intel_rng_hw_init(void *_intel_rng_hw)
+{
+ struct intel_rng_hw *intel_rng_hw = _intel_rng_hw;
+ u8 mfc, dvc;
+
+ /* interrupts disabled in stop_machine_run call */
+
+ if (!(intel_rng_hw->fwh_dec_en1_val & FWH_F8_EN_MASK))
+ pci_write_config_byte(intel_rng_hw->dev,
+ intel_rng_hw->fwh_dec_en1_off,
+ intel_rng_hw->fwh_dec_en1_val |
+ FWH_F8_EN_MASK);
+ if (!(intel_rng_hw->bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK))
+ pci_write_config_byte(intel_rng_hw->dev,
+ intel_rng_hw->bios_cntl_off,
+ intel_rng_hw->bios_cntl_val |
+ BIOS_CNTL_WRITE_ENABLE_MASK);
+
+ writeb(INTEL_FWH_RESET_CMD, intel_rng_hw->mem);
+ writeb(INTEL_FWH_READ_ID_CMD, intel_rng_hw->mem);
+ mfc = readb(intel_rng_hw->mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS);
+ dvc = readb(intel_rng_hw->mem + INTEL_FWH_DEVICE_CODE_ADDRESS);
+ writeb(INTEL_FWH_RESET_CMD, intel_rng_hw->mem);
+
+ if (!(intel_rng_hw->bios_cntl_val &
+ (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
+ pci_write_config_byte(intel_rng_hw->dev,
+ intel_rng_hw->bios_cntl_off,
+ intel_rng_hw->bios_cntl_val);
+ if (!(intel_rng_hw->fwh_dec_en1_val & FWH_F8_EN_MASK))
+ pci_write_config_byte(intel_rng_hw->dev,
+ intel_rng_hw->fwh_dec_en1_off,
+ intel_rng_hw->fwh_dec_en1_val);
-static void __init intel_init_wait(void *unused)
+ if (mfc != INTEL_FWH_MANUFACTURER_CODE ||
+ (dvc != INTEL_FWH_DEVICE_CODE_8M &&
+ dvc != INTEL_FWH_DEVICE_CODE_4M)) {
+ printk(KERN_ERR PFX "FWH not detected\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int __init intel_init_hw_struct(struct intel_rng_hw *intel_rng_hw,
+ struct pci_dev *dev)
{
- while (waitflag)
- cpu_relax();
+ intel_rng_hw->bios_cntl_val = 0xff;
+ intel_rng_hw->fwh_dec_en1_val = 0xff;
+ intel_rng_hw->dev = dev;
+
+ /* Check for Intel 82802 */
+ if (dev->device < 0x2640) {
+ intel_rng_hw->fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD;
+ intel_rng_hw->bios_cntl_off = BIOS_CNTL_REG_OLD;
+ } else {
+ intel_rng_hw->fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW;
+ intel_rng_hw->bios_cntl_off = BIOS_CNTL_REG_NEW;
+ }
+
+ pci_read_config_byte(dev, intel_rng_hw->fwh_dec_en1_off,
+ &intel_rng_hw->fwh_dec_en1_val);
+ pci_read_config_byte(dev, intel_rng_hw->bios_cntl_off,
+ &intel_rng_hw->bios_cntl_val);
+
+ if ((intel_rng_hw->bios_cntl_val &
+ (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))
+ == BIOS_CNTL_LOCK_ENABLE_MASK) {
+ static __initdata /*const*/ char warning[] =
+ KERN_WARNING PFX "Firmware space is locked read-only. "
+ KERN_WARNING PFX "If you can't or\n don't want to "
+ KERN_WARNING PFX "disable this in firmware setup, and "
+ KERN_WARNING PFX "if\n you are certain that your "
+ KERN_WARNING PFX "system has a functional\n RNG, try"
+ KERN_WARNING PFX "using the 'no_fwh_detect' option.\n";
+
+ if (no_fwh_detect)
+ return -ENODEV;
+ printk(warning);
+ return -EBUSY;
+ }
+
+ intel_rng_hw->mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN);
+ if (intel_rng_hw->mem == NULL)
+ return -EBUSY;
+
+ return 0;
}
-#endif
+
static int __init mod_init(void)
{
int err = -ENODEV;
- unsigned i;
+ int i;
struct pci_dev *dev = NULL;
- void __iomem *mem;
- unsigned long flags;
- u8 bios_cntl_off, fwh_dec_en1_off;
- u8 bios_cntl_val = 0xff, fwh_dec_en1_val = 0xff;
- u8 hw_status, mfc, dvc;
+ void __iomem *mem = mem;
+ u8 hw_status;
+ struct intel_rng_hw *intel_rng_hw;
for (i = 0; !dev && pci_tbl[i].vendor; ++i)
- dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, NULL);
+ dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device,
+ NULL);
if (!dev)
goto out; /* Device not found. */
@@ -250,39 +338,18 @@ static int __init mod_init(void)
goto fwh_done;
}
- /* Check for Intel 82802 */
- if (dev->device < 0x2640) {
- fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD;
- bios_cntl_off = BIOS_CNTL_REG_OLD;
- } else {
- fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW;
- bios_cntl_off = BIOS_CNTL_REG_NEW;
- }
-
- pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val);
- pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val);
-
- if ((bios_cntl_val &
- (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))
- == BIOS_CNTL_LOCK_ENABLE_MASK) {
- static __initdata /*const*/ char warning[] =
- KERN_WARNING PFX "Firmware space is locked read-only. If you can't or\n"
- KERN_WARNING PFX "don't want to disable this in firmware setup, and if\n"
- KERN_WARNING PFX "you are certain that your system has a functional\n"
- KERN_WARNING PFX "RNG, try using the 'no_fwh_detect' option.\n";
-
+ intel_rng_hw = kmalloc(sizeof(*intel_rng_hw), GFP_KERNEL);
+ if (!intel_rng_hw) {
pci_dev_put(dev);
- if (no_fwh_detect)
- goto fwh_done;
- printk(warning);
- err = -EBUSY;
goto out;
}
- mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN);
- if (mem == NULL) {
+ err = intel_init_hw_struct(intel_rng_hw, dev);
+ if (err) {
pci_dev_put(dev);
- err = -EBUSY;
+ kfree(intel_rng_hw);
+ if (err == -ENODEV)
+ goto fwh_done;
goto out;
}
@@ -290,59 +357,18 @@ static int __init mod_init(void)
* Since the BIOS code/data is going to disappear from its normal
* location with the Read ID command, all activity on the system
* must be stopped until the state is back to normal.
+ *
+ * Use stop_machine_run because IPIs can be blocked by disabling
+ * interrupts.
*/
-#ifdef CONFIG_SMP
- set_mb(waitflag, 1);
- if (smp_call_function(intel_init_wait, NULL, 1, 0) != 0) {
- set_mb(waitflag, 0);
- pci_dev_put(dev);
- printk(KERN_ERR PFX "cannot run on all processors\n");
- err = -EAGAIN;
- goto err_unmap;
- }
-#endif
- local_irq_save(flags);
-
- if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
- pci_write_config_byte(dev,
- fwh_dec_en1_off,
- fwh_dec_en1_val | FWH_F8_EN_MASK);
- if (!(bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK))
- pci_write_config_byte(dev,
- bios_cntl_off,
- bios_cntl_val | BIOS_CNTL_WRITE_ENABLE_MASK);
-
- writeb(INTEL_FWH_RESET_CMD, mem);
- writeb(INTEL_FWH_READ_ID_CMD, mem);
- mfc = readb(mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS);
- dvc = readb(mem + INTEL_FWH_DEVICE_CODE_ADDRESS);
- writeb(INTEL_FWH_RESET_CMD, mem);
-
- if (!(bios_cntl_val &
- (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
- pci_write_config_byte(dev, bios_cntl_off, bios_cntl_val);
- if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
- pci_write_config_byte(dev, fwh_dec_en1_off, fwh_dec_en1_val);
-
- local_irq_restore(flags);
-#ifdef CONFIG_SMP
- /* Tell other CPUs to resume. */
- set_mb(waitflag, 0);
-#endif
-
- iounmap(mem);
+ err = stop_machine_run(intel_rng_hw_init, intel_rng_hw, NR_CPUS);
pci_dev_put(dev);
-
- if (mfc != INTEL_FWH_MANUFACTURER_CODE ||
- (dvc != INTEL_FWH_DEVICE_CODE_8M &&
- dvc != INTEL_FWH_DEVICE_CODE_4M)) {
- printk(KERN_ERR PFX "FWH not detected\n");
- err = -ENODEV;
+ iounmap(intel_rng_hw->mem);
+ kfree(intel_rng_hw);
+ if (err)
goto out;
- }
fwh_done:
-
err = -ENOMEM;
mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
if (!mem)
@@ -352,22 +378,21 @@ fwh_done:
/* Check for Random Number Generator */
err = -ENODEV;
hw_status = hwstatus_get(mem);
- if ((hw_status & INTEL_RNG_PRESENT) == 0)
- goto err_unmap;
+ if ((hw_status & INTEL_RNG_PRESENT) == 0) {
+ iounmap(mem);
+ goto out;
+ }
printk(KERN_INFO "Intel 82802 RNG detected\n");
err = hwrng_register(&intel_rng);
if (err) {
printk(KERN_ERR PFX "RNG registering failed (%d)\n",
err);
- goto err_unmap;
+ iounmap(mem);
}
out:
return err;
-err_unmap:
- iounmap(mem);
- goto out;
}
static void __exit mod_exit(void)
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 353d9f3..0289705 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -22,6 +22,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/dmi.h>
+#include <linux/capability.h>
#include <asm/uaccess.h>
#include <asm/io.h>
diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c
index a48da02..932264a 100644
--- a/drivers/char/ip27-rtc.c
+++ b/drivers/char/ip27-rtc.c
@@ -35,7 +35,6 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
#include <asm/m48t35.h>
#include <asm/sn/ioc3.h>
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index e221465..6c5d15d 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -9,6 +9,7 @@
* source@mvista.com
*
* Copyright 2002 MontaVista Software Inc.
+ * Copyright 2006 IBM Corp., Christian Krafft <krafft@de.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -64,6 +65,11 @@
#include <linux/string.h>
#include <linux/ctype.h>
+#ifdef CONFIG_PPC_OF
+#include <asm/of_device.h>
+#include <asm/of_platform.h>
+#endif
+
#define PFX "ipmi_si: "
/* Measure times between events in the driver. */
@@ -76,6 +82,12 @@
#define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a
short timeout */
+/* Bit for BMC global enables. */
+#define IPMI_BMC_RCV_MSG_INTR 0x01
+#define IPMI_BMC_EVT_MSG_INTR 0x02
+#define IPMI_BMC_EVT_MSG_BUFF 0x04
+#define IPMI_BMC_SYS_LOG 0x08
+
enum si_intf_state {
SI_NORMAL,
SI_GETTING_FLAGS,
@@ -84,7 +96,9 @@ enum si_intf_state {
SI_CLEARING_FLAGS_THEN_SET_IRQ,
SI_GETTING_MESSAGES,
SI_ENABLE_INTERRUPTS1,
- SI_ENABLE_INTERRUPTS2
+ SI_ENABLE_INTERRUPTS2,
+ SI_DISABLE_INTERRUPTS1,
+ SI_DISABLE_INTERRUPTS2
/* FIXME - add watchdog stuff. */
};
@@ -333,6 +347,17 @@ static void start_enable_irq(struct smi_info *smi_info)
smi_info->si_state = SI_ENABLE_INTERRUPTS1;
}
+static void start_disable_irq(struct smi_info *smi_info)
+{
+ unsigned char msg[2];
+
+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
+ msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
+
+ smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
+ smi_info->si_state = SI_DISABLE_INTERRUPTS1;
+}
+
static void start_clear_flags(struct smi_info *smi_info)
{
unsigned char msg[3];
@@ -353,7 +378,7 @@ static void start_clear_flags(struct smi_info *smi_info)
static inline void disable_si_irq(struct smi_info *smi_info)
{
if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
- disable_irq_nosync(smi_info->irq);
+ start_disable_irq(smi_info);
smi_info->interrupt_disabled = 1;
}
}
@@ -361,7 +386,7 @@ static inline void disable_si_irq(struct smi_info *smi_info)
static inline void enable_si_irq(struct smi_info *smi_info)
{
if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
- enable_irq(smi_info->irq);
+ start_enable_irq(smi_info);
smi_info->interrupt_disabled = 0;
}
}
@@ -583,7 +608,9 @@ static void handle_transaction_done(struct smi_info *smi_info)
} else {
msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
- msg[2] = msg[3] | 1; /* enable msg queue int */
+ msg[2] = (msg[3] |
+ IPMI_BMC_RCV_MSG_INTR |
+ IPMI_BMC_EVT_MSG_INTR);
smi_info->handlers->start_transaction(
smi_info->si_sm, msg, 3);
smi_info->si_state = SI_ENABLE_INTERRUPTS2;
@@ -605,6 +632,45 @@ static void handle_transaction_done(struct smi_info *smi_info)
smi_info->si_state = SI_NORMAL;
break;
}
+
+ case SI_DISABLE_INTERRUPTS1:
+ {
+ unsigned char msg[4];
+
+ /* We got the flags from the SMI, now handle them. */
+ smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
+ if (msg[2] != 0) {
+ printk(KERN_WARNING
+ "ipmi_si: Could not disable interrupts"
+ ", failed get.\n");
+ smi_info->si_state = SI_NORMAL;
+ } else {
+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
+ msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
+ msg[2] = (msg[3] &
+ ~(IPMI_BMC_RCV_MSG_INTR |
+ IPMI_BMC_EVT_MSG_INTR));
+ smi_info->handlers->start_transaction(
+ smi_info->si_sm, msg, 3);
+ smi_info->si_state = SI_DISABLE_INTERRUPTS2;
+ }
+ break;
+ }
+
+ case SI_DISABLE_INTERRUPTS2:
+ {
+ unsigned char msg[4];
+
+ /* We got the flags from the SMI, now handle them. */
+ smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
+ if (msg[2] != 0) {
+ printk(KERN_WARNING
+ "ipmi_si: Could not disable interrupts"
+ ", failed set.\n");
+ }
+ smi_info->si_state = SI_NORMAL;
+ break;
+ }
}
}
@@ -858,9 +924,6 @@ static void smi_timeout(unsigned long data)
struct timeval t;
#endif
- if (atomic_read(&smi_info->stop_operation))
- return;
-
spin_lock_irqsave(&(smi_info->si_lock), flags);
#ifdef DEBUG_TIMING
do_gettimeofday(&t);
@@ -916,15 +979,11 @@ static irqreturn_t si_irq_handler(int irq, void *data)
smi_info->interrupts++;
spin_unlock(&smi_info->count_lock);
- if (atomic_read(&smi_info->stop_operation))
- goto out;
-
#ifdef DEBUG_TIMING
do_gettimeofday(&t);
printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec);
#endif
smi_event_handler(smi_info, 0);
- out:
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
return IRQ_HANDLED;
}
@@ -1006,6 +1065,7 @@ static DEFINE_MUTEX(smi_infos_lock);
static int smi_num; /* Used to sequence the SMIs */
#define DEFAULT_REGSPACING 1
+#define DEFAULT_REGSIZE 1
static int si_trydefaults = 1;
static char *si_type[SI_MAX_PARMS];
@@ -1111,7 +1171,7 @@ static int std_irq_setup(struct smi_info *info)
if (info->si_type == SI_BT) {
rv = request_irq(info->irq,
si_bt_irq_handler,
- IRQF_DISABLED,
+ IRQF_SHARED | IRQF_DISABLED,
DEVICE_NAME,
info);
if (!rv)
@@ -1121,7 +1181,7 @@ static int std_irq_setup(struct smi_info *info)
} else
rv = request_irq(info->irq,
si_irq_handler,
- IRQF_DISABLED,
+ IRQF_SHARED | IRQF_DISABLED,
DEVICE_NAME,
info);
if (rv) {
@@ -1701,15 +1761,11 @@ static u32 ipmi_acpi_gpe(void *context)
smi_info->interrupts++;
spin_unlock(&smi_info->count_lock);
- if (atomic_read(&smi_info->stop_operation))
- goto out;
-
#ifdef DEBUG_TIMING
do_gettimeofday(&t);
printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec);
#endif
smi_event_handler(smi_info, 0);
- out:
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
return ACPI_INTERRUPT_HANDLED;
@@ -2133,12 +2189,15 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev,
info->irq_setup = std_irq_setup;
info->dev = &pdev->dev;
+ pci_set_drvdata(pdev, info);
return try_smi_init(info);
}
static void __devexit ipmi_pci_remove(struct pci_dev *pdev)
{
+ struct smi_info *info = pci_get_drvdata(pdev);
+ cleanup_one_si(info);
}
#ifdef CONFIG_PM
@@ -2172,6 +2231,99 @@ static struct pci_driver ipmi_pci_driver = {
#endif /* CONFIG_PCI */
+#ifdef CONFIG_PPC_OF
+static int __devinit ipmi_of_probe(struct of_device *dev,
+ const struct of_device_id *match)
+{
+ struct smi_info *info;
+ struct resource resource;
+ const int *regsize, *regspacing, *regshift;
+ struct device_node *np = dev->node;
+ int ret;
+ int proplen;
+
+ dev_info(&dev->dev, PFX "probing via device tree\n");
+
+ ret = of_address_to_resource(np, 0, &resource);
+ if (ret) {
+ dev_warn(&dev->dev, PFX "invalid address from OF\n");
+ return ret;
+ }
+
+ regsize = get_property(np, "reg-size", &proplen);
+ if (regsize && proplen != 4) {
+ dev_warn(&dev->dev, PFX "invalid regsize from OF\n");
+ return -EINVAL;
+ }
+
+ regspacing = get_property(np, "reg-spacing", &proplen);
+ if (regspacing && proplen != 4) {
+ dev_warn(&dev->dev, PFX "invalid regspacing from OF\n");
+ return -EINVAL;
+ }
+
+ regshift = get_property(np, "reg-shift", &proplen);
+ if (regshift && proplen != 4) {
+ dev_warn(&dev->dev, PFX "invalid regshift from OF\n");
+ return -EINVAL;
+ }
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+
+ if (!info) {
+ dev_err(&dev->dev,
+ PFX "could not allocate memory for OF probe\n");
+ return -ENOMEM;
+ }
+
+ info->si_type = (enum si_type) match->data;
+ info->addr_source = "device-tree";
+ info->io_setup = mem_setup;
+ info->irq_setup = std_irq_setup;
+
+ info->io.addr_type = IPMI_MEM_ADDR_SPACE;
+ info->io.addr_data = resource.start;
+
+ info->io.regsize = regsize ? *regsize : DEFAULT_REGSIZE;
+ info->io.regspacing = regspacing ? *regspacing : DEFAULT_REGSPACING;
+ info->io.regshift = regshift ? *regshift : 0;
+
+ info->irq = irq_of_parse_and_map(dev->node, 0);
+ info->dev = &dev->dev;
+
+ dev_dbg(&dev->dev, "addr 0x%lx regsize %ld spacing %ld irq %x\n",
+ info->io.addr_data, info->io.regsize, info->io.regspacing,
+ info->irq);
+
+ dev->dev.driver_data = (void*) info;
+
+ return try_smi_init(info);
+}
+
+static int __devexit ipmi_of_remove(struct of_device *dev)
+{
+ cleanup_one_si(dev->dev.driver_data);
+ return 0;
+}
+
+static struct of_device_id ipmi_match[] =
+{
+ { .type = "ipmi", .compatible = "ipmi-kcs", .data = (void *)(unsigned long) SI_KCS },
+ { .type = "ipmi", .compatible = "ipmi-smic", .data = (void *)(unsigned long) SI_SMIC },
+ { .type = "ipmi", .compatible = "ipmi-bt", .data = (void *)(unsigned long) SI_BT },
+ {},
+};
+
+static struct of_platform_driver ipmi_of_platform_driver =
+{
+ .name = "ipmi",
+ .match_table = ipmi_match,
+ .probe = ipmi_of_probe,
+ .remove = __devexit_p(ipmi_of_remove),
+};
+#endif /* CONFIG_PPC_OF */
+
+
static int try_get_dev_id(struct smi_info *smi_info)
{
unsigned char msg[2];
@@ -2801,6 +2953,10 @@ static __devinit int init_ipmi_si(void)
}
#endif
+#ifdef CONFIG_PPC_OF
+ of_register_platform_driver(&ipmi_of_platform_driver);
+#endif
+
if (si_trydefaults) {
mutex_lock(&smi_infos_lock);
if (list_empty(&smi_infos)) {
@@ -2838,28 +2994,33 @@ static void cleanup_one_si(struct smi_info *to_clean)
list_del(&to_clean->link);
- /* Tell the timer and interrupt handlers that we are shutting
- down. */
- spin_lock_irqsave(&(to_clean->si_lock), flags);
- spin_lock(&(to_clean->msg_lock));
-
+ /* Tell the driver that we are shutting down. */
atomic_inc(&to_clean->stop_operation);
- if (to_clean->irq_cleanup)
- to_clean->irq_cleanup(to_clean);
-
- spin_unlock(&(to_clean->msg_lock));
- spin_unlock_irqrestore(&(to_clean->si_lock), flags);
-
- /* Wait until we know that we are out of any interrupt
- handlers might have been running before we freed the
- interrupt. */
- synchronize_sched();
-
+ /* Make sure the timer and thread are stopped and will not run
+ again. */
wait_for_timer_and_thread(to_clean);
- /* Interrupts and timeouts are stopped, now make sure the
- interface is in a clean state. */
+ /* Timeouts are stopped, now make sure the interrupts are off
+ for the device. A little tricky with locks to make sure
+ there are no races. */
+ spin_lock_irqsave(&to_clean->si_lock, flags);
+ while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
+ spin_unlock_irqrestore(&to_clean->si_lock, flags);
+ poll(to_clean);
+ schedule_timeout_uninterruptible(1);
+ spin_lock_irqsave(&to_clean->si_lock, flags);
+ }
+ disable_si_irq(to_clean);
+ spin_unlock_irqrestore(&to_clean->si_lock, flags);
+ while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
+ poll(to_clean);
+ schedule_timeout_uninterruptible(1);
+ }
+
+ /* Clean up interrupts and make sure that everything is done. */
+ if (to_clean->irq_cleanup)
+ to_clean->irq_cleanup(to_clean);
while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
poll(to_clean);
schedule_timeout_uninterruptible(1);
@@ -2898,6 +3059,10 @@ static __exit void cleanup_ipmi_si(void)
pci_unregister_driver(&ipmi_pci_driver);
#endif
+#ifdef CONFIG_PPC_OF
+ of_unregister_platform_driver(&ipmi_of_platform_driver);
+#endif
+
mutex_lock(&smi_infos_lock);
list_for_each_entry_safe(e, tmp_e, &smi_infos, link)
cleanup_one_si(e);
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 6b634e8..147c120 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -39,6 +39,7 @@
#include <linux/miscdevice.h>
#include <linux/init.h>
#include <linux/completion.h>
+#include <linux/kdebug.h>
#include <linux/rwsem.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
@@ -49,9 +50,18 @@
#include <linux/poll.h>
#include <linux/string.h>
#include <linux/ctype.h>
+#include <linux/delay.h>
#include <asm/atomic.h>
-#ifdef CONFIG_X86_LOCAL_APIC
-#include <asm/apic.h>
+
+#ifdef CONFIG_X86
+/* This is ugly, but I've determined that x86 is the only architecture
+ that can reasonably support the IPMI NMI watchdog timeout at this
+ time. If another architecture adds this capability somehow, it
+ will have to be a somewhat different mechanism and I have no idea
+ how it will work. So in the unlikely event that another
+ architecture supports this, we can figure out a good generic
+ mechanism for it at that time. */
+#define HAVE_DIE_NMI_POST
#endif
#define PFX "IPMI Watchdog: "
@@ -317,6 +327,11 @@ static unsigned char ipmi_version_minor;
/* If a pretimeout occurs, this is used to allow only one panic to happen. */
static atomic_t preop_panic_excl = ATOMIC_INIT(-1);
+#ifdef HAVE_DIE_NMI_POST
+static int testing_nmi;
+static int nmi_handler_registered;
+#endif
+
static int ipmi_heartbeat(void);
static void panic_halt_ipmi_heartbeat(void);
@@ -358,6 +373,10 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg,
int hbnow = 0;
+ /* These can be cleared as we are setting the timeout. */
+ ipmi_start_timer_on_heartbeat = 0;
+ pretimeout_since_last_heartbeat = 0;
+
data[0] = 0;
WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS);
@@ -432,13 +451,12 @@ static int ipmi_set_timeout(int do_heartbeat)
wait_for_completion(&set_timeout_wait);
+ mutex_unlock(&set_timeout_lock);
+
if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB)
|| ((send_heartbeat_now)
&& (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY)))
- {
rv = ipmi_heartbeat();
- }
- mutex_unlock(&set_timeout_lock);
out:
return rv;
@@ -518,12 +536,10 @@ static int ipmi_heartbeat(void)
int rv;
struct ipmi_system_interface_addr addr;
- if (ipmi_ignore_heartbeat) {
+ if (ipmi_ignore_heartbeat)
return 0;
- }
if (ipmi_start_timer_on_heartbeat) {
- ipmi_start_timer_on_heartbeat = 0;
ipmi_watchdog_state = action_val;
return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
} else if (pretimeout_since_last_heartbeat) {
@@ -531,7 +547,6 @@ static int ipmi_heartbeat(void)
We don't want to set the action, though, we want to
leave that alone (thus it can't be combined with the
above operation. */
- pretimeout_since_last_heartbeat = 0;
return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
}
@@ -919,6 +934,45 @@ static void ipmi_register_watchdog(int ipmi_intf)
printk(KERN_CRIT PFX "Unable to register misc device\n");
}
+#ifdef HAVE_DIE_NMI_POST
+ if (nmi_handler_registered) {
+ int old_pretimeout = pretimeout;
+ int old_timeout = timeout;
+ int old_preop_val = preop_val;
+
+ /* Set the pretimeout to go off in a second and give
+ ourselves plenty of time to stop the timer. */
+ ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
+ preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */
+ pretimeout = 99;
+ timeout = 100;
+
+ testing_nmi = 1;
+
+ rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
+ if (rv) {
+ printk(KERN_WARNING PFX "Error starting timer to"
+ " test NMI: 0x%x. The NMI pretimeout will"
+ " likely not work\n", rv);
+ rv = 0;
+ goto out_restore;
+ }
+
+ msleep(1500);
+
+ if (testing_nmi != 2) {
+ printk(KERN_WARNING PFX "IPMI NMI didn't seem to"
+ " occur. The NMI pretimeout will"
+ " likely not work\n");
+ }
+ out_restore:
+ testing_nmi = 0;
+ preop_val = old_preop_val;
+ pretimeout = old_pretimeout;
+ timeout = old_timeout;
+ }
+#endif
+
out:
up_write(&register_sem);
@@ -928,6 +982,10 @@ static void ipmi_register_watchdog(int ipmi_intf)
ipmi_watchdog_state = action_val;
ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
printk(KERN_INFO PFX "Starting now!\n");
+ } else {
+ /* Stop the timer now. */
+ ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
+ ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
}
}
@@ -964,17 +1022,28 @@ static void ipmi_unregister_watchdog(int ipmi_intf)
up_write(&register_sem);
}
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI_POST
static int
-ipmi_nmi(void *dev_id, int cpu, int handled)
+ipmi_nmi(struct notifier_block *self, unsigned long val, void *data)
{
+ if (val != DIE_NMI_POST)
+ return NOTIFY_OK;
+
+ if (testing_nmi) {
+ testing_nmi = 2;
+ return NOTIFY_STOP;
+ }
+
/* If we are not expecting a timeout, ignore it. */
if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
- return NOTIFY_DONE;
+ return NOTIFY_OK;
+
+ if (preaction_val != WDOG_PRETIMEOUT_NMI)
+ return NOTIFY_OK;
/* If no one else handled the NMI, we assume it was the IPMI
watchdog. */
- if ((!handled) && (preop_val == WDOG_PREOP_PANIC)) {
+ if (preop_val == WDOG_PREOP_PANIC) {
/* On some machines, the heartbeat will give
an error and not work unless we re-enable
the timer. So do so. */
@@ -983,18 +1052,12 @@ ipmi_nmi(void *dev_id, int cpu, int handled)
panic(PFX "pre-timeout");
}
- return NOTIFY_DONE;
+ return NOTIFY_STOP;
}
-static struct nmi_handler ipmi_nmi_handler =
-{
- .link = LIST_HEAD_INIT(ipmi_nmi_handler.link),
- .dev_name = "ipmi_watchdog",
- .dev_id = NULL,
- .handler = ipmi_nmi,
- .priority = 0, /* Call us last. */
+static struct notifier_block ipmi_nmi_handler = {
+ .notifier_call = ipmi_nmi
};
-int nmi_handler_registered;
#endif
static int wdog_reboot_handler(struct notifier_block *this,
@@ -1111,7 +1174,7 @@ static int preaction_op(const char *inval, char *outval)
preaction_val = WDOG_PRETIMEOUT_NONE;
else if (strcmp(inval, "pre_smi") == 0)
preaction_val = WDOG_PRETIMEOUT_SMI;
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI_POST
else if (strcmp(inval, "pre_nmi") == 0)
preaction_val = WDOG_PRETIMEOUT_NMI;
#endif
@@ -1145,7 +1208,7 @@ static int preop_op(const char *inval, char *outval)
static void check_parms(void)
{
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI_POST
int do_nmi = 0;
int rv;
@@ -1158,20 +1221,9 @@ static void check_parms(void)
preop_op("preop_none", NULL);
do_nmi = 0;
}
-#ifdef CONFIG_X86_LOCAL_APIC
- if (nmi_watchdog == NMI_IO_APIC) {
- printk(KERN_WARNING PFX "nmi_watchdog is set to IO APIC"
- " mode (value is %d), that is incompatible"
- " with using NMI in the IPMI watchdog."
- " Disabling IPMI nmi pretimeout.\n",
- nmi_watchdog);
- preaction_val = WDOG_PRETIMEOUT_NONE;
- do_nmi = 0;
- }
-#endif
}
if (do_nmi && !nmi_handler_registered) {
- rv = request_nmi(&ipmi_nmi_handler);
+ rv = register_die_notifier(&ipmi_nmi_handler);
if (rv) {
printk(KERN_WARNING PFX
"Can't register nmi handler\n");
@@ -1179,7 +1231,7 @@ static void check_parms(void)
} else
nmi_handler_registered = 1;
} else if (!do_nmi && nmi_handler_registered) {
- release_nmi(&ipmi_nmi_handler);
+ unregister_die_notifier(&ipmi_nmi_handler);
nmi_handler_registered = 0;
}
#endif
@@ -1215,9 +1267,9 @@ static int __init ipmi_wdog_init(void)
rv = ipmi_smi_watcher_register(&smi_watcher);
if (rv) {
-#ifdef HAVE_NMI_HANDLER
- if (preaction_val == WDOG_PRETIMEOUT_NMI)
- release_nmi(&ipmi_nmi_handler);
+#ifdef HAVE_DIE_NMI_POST
+ if (nmi_handler_registered)
+ unregister_die_notifier(&ipmi_nmi_handler);
#endif
atomic_notifier_chain_unregister(&panic_notifier_list,
&wdog_panic_notifier);
@@ -1236,9 +1288,9 @@ static void __exit ipmi_wdog_exit(void)
ipmi_smi_watcher_unregister(&smi_watcher);
ipmi_unregister_watchdog(watchdog_ifnum);
-#ifdef HAVE_NMI_HANDLER
+#ifdef HAVE_DIE_NMI_POST
if (nmi_handler_registered)
- release_nmi(&ipmi_nmi_handler);
+ unregister_die_notifier(&ipmi_nmi_handler);
#endif
atomic_notifier_chain_unregister(&panic_notifier_list,
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 43ab9ed..761f777 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -137,11 +137,10 @@
#define InterruptTheCard(base) outw(0, (base) + 0xc)
#define ClearInterrupt(base) inw((base) + 0x0a)
+#define pr_dbg(str...) pr_debug("ISICOM: " str)
#ifdef DEBUG
-#define pr_dbg(str...) printk(KERN_DEBUG "ISICOM: " str)
#define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c))
#else
-#define pr_dbg(str...) do { } while (0)
#define isicom_paranoia_check(a, b, c) 0
#endif
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index c06e86a..1b09450 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -109,7 +109,7 @@ struct kbd_struct kbd_table[MAX_NR_CONSOLES];
static struct kbd_struct *kbd = kbd_table;
struct vt_spawn_console vt_spawn_con = {
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock),
.pid = NULL,
.sig = 0,
};
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index b51d08b..62051f8 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -118,7 +118,6 @@
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/delay.h>
@@ -139,9 +138,6 @@
/* if you have more than 8 printers, remember to increase LP_NO */
#define LP_NO 8
-/* ROUND_UP macro from fs/select.c */
-#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
-
static struct lp_struct lp_table[LP_NO];
static unsigned int lp_count = 0;
@@ -652,7 +648,7 @@ static int lp_ioctl(struct inode *inode, struct file *file,
(par_timeout.tv_usec < 0)) {
return -EINVAL;
}
- to_jiffies = ROUND_UP(par_timeout.tv_usec, 1000000/HZ);
+ to_jiffies = DIV_ROUND_UP(par_timeout.tv_usec, 1000000/HZ);
to_jiffies += par_timeout.tv_sec * (long) HZ;
if (to_jiffies <= 0) {
return -EINVAL;
@@ -803,7 +799,7 @@ static int lp_register(int nr, struct parport *port)
if (reset)
lp_reset(nr);
- class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL,
+ class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), port->dev,
"lp%d", nr);
printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name,
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 5f06696..cc9a9d0 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -18,7 +18,6 @@
#include <linux/raw.h>
#include <linux/tty.h>
#include <linux/capability.h>
-#include <linux/smp_lock.h>
#include <linux/ptrace.h>
#include <linux/device.h>
#include <linux/highmem.h>
@@ -552,7 +551,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf,
return virtr + wrote;
}
-#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
+#ifdef CONFIG_DEVPORT
static ssize_t read_port(struct file * file, char __user * buf,
size_t count, loff_t *ppos)
{
@@ -835,7 +834,7 @@ static const struct file_operations null_fops = {
.splice_write = splice_write_null,
};
-#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
+#ifdef CONFIG_DEVPORT
static const struct file_operations port_fops = {
.llseek = memory_lseek,
.read = read_port,
@@ -913,7 +912,7 @@ static int memory_open(struct inode * inode, struct file * filp)
case 3:
filp->f_op = &null_fops;
break;
-#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
+#ifdef CONFIG_DEVPORT
case 4:
filp->f_op = &port_fops;
break;
@@ -960,7 +959,7 @@ static const struct {
{1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
{2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
{3, "null", S_IRUGO | S_IWUGO, &null_fops},
-#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
+#ifdef CONFIG_DEVPORT
{4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
#endif
{5, "zero", S_IRUGO | S_IWUGO, &zero_fops},
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 7e975f6..4e6fb96 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -41,6 +41,7 @@
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/slab.h>
+#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
@@ -53,7 +54,7 @@
* Head entry for the doubly linked miscdevice list
*/
static LIST_HEAD(misc_list);
-static DECLARE_MUTEX(misc_sem);
+static DEFINE_MUTEX(misc_mtx);
/*
* Assigned numbers, used for dynamic minors
@@ -69,7 +70,7 @@ static void *misc_seq_start(struct seq_file *seq, loff_t *pos)
struct miscdevice *p;
loff_t off = 0;
- down(&misc_sem);
+ mutex_lock(&misc_mtx);
list_for_each_entry(p, &misc_list, list) {
if (*pos == off++)
return p;
@@ -89,7 +90,7 @@ static void *misc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static void misc_seq_stop(struct seq_file *seq, void *v)
{
- up(&misc_sem);
+ mutex_unlock(&misc_mtx);
}
static int misc_seq_show(struct seq_file *seq, void *v)
@@ -129,7 +130,7 @@ static int misc_open(struct inode * inode, struct file * file)
int err = -ENODEV;
const struct file_operations *old_fops, *new_fops = NULL;
- down(&misc_sem);
+ mutex_lock(&misc_mtx);
list_for_each_entry(c, &misc_list, list) {
if (c->minor == minor) {
@@ -139,9 +140,9 @@ static int misc_open(struct inode * inode, struct file * file)
}
if (!new_fops) {
- up(&misc_sem);
+ mutex_unlock(&misc_mtx);
request_module("char-major-%d-%d", MISC_MAJOR, minor);
- down(&misc_sem);
+ mutex_lock(&misc_mtx);
list_for_each_entry(c, &misc_list, list) {
if (c->minor == minor) {
@@ -165,7 +166,7 @@ static int misc_open(struct inode * inode, struct file * file)
}
fops_put(old_fops);
fail:
- up(&misc_sem);
+ mutex_unlock(&misc_mtx);
return err;
}
@@ -201,10 +202,10 @@ int misc_register(struct miscdevice * misc)
INIT_LIST_HEAD(&misc->list);
- down(&misc_sem);
+ mutex_lock(&misc_mtx);
list_for_each_entry(c, &misc_list, list) {
if (c->minor == misc->minor) {
- up(&misc_sem);
+ mutex_unlock(&misc_mtx);
return -EBUSY;
}
}
@@ -215,7 +216,7 @@ int misc_register(struct miscdevice * misc)
if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
break;
if (i<0) {
- up(&misc_sem);
+ mutex_unlock(&misc_mtx);
return -EBUSY;
}
misc->minor = i;
@@ -238,7 +239,7 @@ int misc_register(struct miscdevice * misc)
*/
list_add(&misc->list, &misc_list);
out:
- up(&misc_sem);
+ mutex_unlock(&misc_mtx);
return err;
}
@@ -259,13 +260,13 @@ int misc_deregister(struct miscdevice * misc)
if (list_empty(&misc->list))
return -EINVAL;
- down(&misc_sem);
+ mutex_lock(&misc_mtx);
list_del(&misc->list);
device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
if (i < DYNAMIC_MINORS && i>0) {
misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
}
- up(&misc_sem);
+ mutex_unlock(&misc_mtx);
return 0;
}
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 7dbaee8..e0d35c2 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -1582,7 +1582,7 @@ copy:
if(copy_from_user(&dltmp, argp, sizeof(struct dl_str)))
return -EFAULT;
- if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS)
+ if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS || dltmp.len < 0)
return -EINVAL;
switch(cmd)
@@ -2529,6 +2529,8 @@ static int moxaloadbios(int cardno, unsigned char __user *tmp, int len)
void __iomem *baseAddr;
int i;
+ if(len < 0 || len > sizeof(moxaBuff))
+ return -EINVAL;
if(copy_from_user(moxaBuff, tmp, len))
return -EFAULT;
baseAddr = moxa_boards[cardno].basemem;
@@ -2576,7 +2578,7 @@ static int moxaload320b(int cardno, unsigned char __user *tmp, int len)
void __iomem *baseAddr;
int i;
- if(len > sizeof(moxaBuff))
+ if(len < 0 || len > sizeof(moxaBuff))
return -EINVAL;
if(copy_from_user(moxaBuff, tmp, len))
return -EFAULT;
@@ -2596,6 +2598,8 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len)
void __iomem *baseAddr, *ofsAddr;
int retval, port, i;
+ if(len < 0 || len > sizeof(moxaBuff))
+ return -EINVAL;
if(copy_from_user(moxaBuff, tmp, len))
return -EFAULT;
baseAddr = moxa_boards[cardno].basemem;
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 80a0115..5953a45 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -54,7 +54,6 @@
#include <linux/gfp.h>
#include <linux/ioport.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/pci.h>
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c
index f7603b6..6cde448 100644
--- a/drivers/char/mxser_new.c
+++ b/drivers/char/mxser_new.c
@@ -37,7 +37,6 @@
#include <linux/gfp.h>
#include <linux/ioport.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/pci.h>
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 65f2d3a..14557a4 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -1088,13 +1088,13 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
/* block until there is a message: */
add_wait_queue(&pInfo->read_wait, &wait);
repeat:
- current->state = TASK_INTERRUPTIBLE;
+ __set_current_state(TASK_INTERRUPTIBLE);
pMsg = remove_msg(pInfo, pClient);
if (!pMsg && !signal_pending(current)) {
schedule();
goto repeat;
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&pInfo->read_wait, &wait);
}
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 4abd1ef..84ac64f 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -66,7 +66,6 @@
#include <linux/poll.h>
#include <linux/major.h>
#include <linux/ppdev.h>
-#include <linux/smp_lock.h>
#include <linux/device.h>
#include <asm/uaccess.h>
@@ -752,7 +751,7 @@ static const struct file_operations pp_fops = {
static void pp_attach(struct parport *port)
{
- device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number),
+ device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number),
"parport%d", port->number);
}
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 7014525..3494e3f 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -980,7 +980,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
}
schedule();
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&port->open_wait, &wait);
if (!tty_hung_up_p(filp))
port->count++;
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 76357c8..61a63da 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -65,10 +65,6 @@
/****** Kernel includes ******/
-#ifdef MODVERSIONS
-#include <config/modversions.h>
-#endif
-
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/major.h>
@@ -85,6 +81,7 @@
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
+#include <linux/mutex.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/wait.h>
@@ -93,7 +90,6 @@
#include <asm/atomic.h>
#include <linux/bitops.h>
#include <linux/spinlock.h>
-#include <asm/semaphore.h>
#include <linux/init.h>
/****** RocketPort includes ******/
@@ -702,7 +698,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
}
}
spin_lock_init(&info->slock);
- sema_init(&info->write_sem, 1);
+ mutex_init(&info->write_mtx);
rp_table[line] = info;
if (pci_dev)
tty_register_device(rocket_driver, line, &pci_dev->dev);
@@ -947,7 +943,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
#endif
schedule(); /* Don't hold spinlock here, will hang PC */
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&info->open_wait, &wait);
spin_lock_irqsave(&info->slock, flags);
@@ -1602,7 +1598,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
if (signal_pending(current))
break;
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
#endif
@@ -1661,8 +1657,11 @@ static void rp_put_char(struct tty_struct *tty, unsigned char ch)
if (rocket_paranoia_check(info, "rp_put_char"))
return;
- /* Grab the port write semaphore, locking out other processes that try to write to this port */
- down(&info->write_sem);
+ /*
+ * Grab the port write mutex, locking out other processes that try to
+ * write to this port
+ */
+ mutex_lock(&info->write_mtx);
#ifdef ROCKET_DEBUG_WRITE
printk(KERN_INFO "rp_put_char %c...", ch);
@@ -1684,12 +1683,12 @@ static void rp_put_char(struct tty_struct *tty, unsigned char ch)
info->xmit_fifo_room--;
}
spin_unlock_irqrestore(&info->slock, flags);
- up(&info->write_sem);
+ mutex_unlock(&info->write_mtx);
}
/*
* Exception handler - write routine, called when user app writes to the device.
- * A per port write semaphore is used to protect from another process writing to
+ * A per port write mutex is used to protect from another process writing to
* this port at the same time. This other process could be running on the other CPU
* or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out).
* Spinlocks protect the info xmit members.
@@ -1706,7 +1705,7 @@ static int rp_write(struct tty_struct *tty,
if (count <= 0 || rocket_paranoia_check(info, "rp_write"))
return 0;
- down_interruptible(&info->write_sem);
+ mutex_lock_interruptible(&info->write_mtx);
#ifdef ROCKET_DEBUG_WRITE
printk(KERN_INFO "rp_write %d chars...", count);
@@ -1777,7 +1776,7 @@ end:
wake_up_interruptible(&tty->poll_wait);
#endif
}
- up(&info->write_sem);
+ mutex_unlock(&info->write_mtx);
return retval;
}
@@ -1852,6 +1851,12 @@ static void rp_flush_buffer(struct tty_struct *tty)
#ifdef CONFIG_PCI
+static struct pci_device_id __devinitdata rocket_pci_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) },
+ { }
+};
+MODULE_DEVICE_TABLE(pci, rocket_pci_ids);
+
/*
* Called when a PCI card is found. Retrieves and stores model information,
* init's aiopic and serial port hardware.
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
index 3a8bcc8..89b4d7b 100644
--- a/drivers/char/rocket_int.h
+++ b/drivers/char/rocket_int.h
@@ -15,6 +15,8 @@
#define ROCKET_TYPE_MODEMIII 3
#define ROCKET_TYPE_PC104 4
+#include <linux/mutex.h>
+
#include <asm/io.h>
#include <asm/byteorder.h>
@@ -1171,7 +1173,7 @@ struct r_port {
struct wait_queue *close_wait;
#endif
spinlock_t slock;
- struct semaphore write_sem;
+ struct mutex write_mtx;
};
#define RPORT_MAGIC 0x525001
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index c7dac9b..20380a2 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -388,7 +388,7 @@ static ssize_t rtc_read(struct file *file, char __user *buf,
if (!retval)
retval = count;
out:
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&rtc_wait, &wait);
return retval;
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index 74cff83..a69f094 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -299,7 +299,7 @@ int paste_selection(struct tty_struct *tty)
pasted += count;
}
remove_wait_queue(&vc->paste_wait, &wait);
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
tty_ldisc_deref(ld);
return 0;
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index 5fd314a..c585b47 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -1892,7 +1892,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
#endif
schedule();
}
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&info->open_wait, &wait);
if (!tty_hung_up_p(filp)) {
info->count++;
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index ce4db6f..f02a079 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -4010,8 +4010,13 @@ static int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info)
for ( i=0; i<info->num_tx_holding_buffers; ++i) {
info->tx_holding_buffers[i].buffer =
kmalloc(info->max_frame_size, GFP_KERNEL);
- if ( info->tx_holding_buffers[i].buffer == NULL )
+ if (info->tx_holding_buffers[i].buffer == NULL) {
+ for (--i; i >= 0; i--) {
+ kfree(info->tx_holding_buffers[i].buffer);
+ info->tx_holding_buffers[i].buffer = NULL;
+ }
return -ENOMEM;
+ }
}
return 0;
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 0a367cd..2a7736b 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -3415,6 +3415,9 @@ static void device_init(int adapter_num, struct pci_dev *pdev)
}
}
}
+
+ for (i=0; i < port_count; ++i)
+ tty_register_device(serial_driver, port_array[i]->line, &(port_array[i]->pdev->dev));
}
static int __devinit init_one(struct pci_dev *dev,
@@ -3466,6 +3469,8 @@ static void slgt_cleanup(void)
printk("unload %s %s\n", driver_name, driver_version);
if (serial_driver) {
+ for (info=slgt_device_list ; info != NULL ; info=info->next_device)
+ tty_unregister_device(serial_driver, info->line);
if ((rc = tty_unregister_driver(serial_driver)))
DBGERR(("tty_unregister_driver error=%d\n", rc));
put_tty_driver(serial_driver);
@@ -3506,23 +3511,10 @@ static int __init slgt_init(void)
printk("%s %s\n", driver_name, driver_version);
- slgt_device_count = 0;
- if ((rc = pci_register_driver(&pci_driver)) < 0) {
- printk("%s pci_register_driver error=%d\n", driver_name, rc);
- return rc;
- }
- pci_registered = 1;
-
- if (!slgt_device_list) {
- printk("%s no devices found\n",driver_name);
- pci_unregister_driver(&pci_driver);
- return -ENODEV;
- }
-
serial_driver = alloc_tty_driver(MAX_DEVICES);
if (!serial_driver) {
- rc = -ENOMEM;
- goto error;
+ printk("%s can't allocate tty driver\n", driver_name);
+ return -ENOMEM;
}
/* Initialize the tty_driver structure */
@@ -3539,7 +3531,7 @@ static int __init slgt_init(void)
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
serial_driver->init_termios.c_ispeed = 9600;
serial_driver->init_termios.c_ospeed = 9600;
- serial_driver->flags = TTY_DRIVER_REAL_RAW;
+ serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
tty_set_operations(serial_driver, &ops);
if ((rc = tty_register_driver(serial_driver)) < 0) {
DBGERR(("%s can't register serial driver\n", driver_name));
@@ -3552,6 +3544,16 @@ static int __init slgt_init(void)
driver_name, driver_version,
serial_driver->major);
+ slgt_device_count = 0;
+ if ((rc = pci_register_driver(&pci_driver)) < 0) {
+ printk("%s pci_register_driver error=%d\n", driver_name, rc);
+ goto error;
+ }
+ pci_registered = 1;
+
+ if (!slgt_device_list)
+ printk("%s no devices found\n",driver_name);
+
return 0;
error:
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 1d8c4ae6..39cc318 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -24,7 +24,6 @@
#include <linux/sysrq.h>
#include <linux/kbd_kern.h>
#include <linux/quotaops.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/suspend.h>
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index 47fb20f..35b40b9 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -442,7 +442,7 @@ tipar_register(int nr, struct parport *port)
}
class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR,
- TIPAR_MINOR + nr), NULL, "par%d", nr);
+ TIPAR_MINOR + nr), port->dev, "par%d", nr);
/* Display informations */
pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq ==
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index e5a254a..9bb5429 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -24,7 +24,9 @@
*/
#include <linux/poll.h>
+#include <linux/mutex.h>
#include <linux/spinlock.h>
+
#include "tpm.h"
enum tpm_const {
@@ -328,10 +330,10 @@ static void timeout_work(struct work_struct *work)
{
struct tpm_chip *chip = container_of(work, struct tpm_chip, work);
- down(&chip->buffer_mutex);
+ mutex_lock(&chip->buffer_mutex);
atomic_set(&chip->data_pending, 0);
memset(chip->data_buffer, 0, TPM_BUFSIZE);
- up(&chip->buffer_mutex);
+ mutex_unlock(&chip->buffer_mutex);
}
/*
@@ -380,7 +382,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
return -E2BIG;
}
- down(&chip->tpm_mutex);
+ mutex_lock(&chip->tpm_mutex);
if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
dev_err(chip->dev,
@@ -419,7 +421,7 @@ out_recv:
dev_err(chip->dev,
"tpm_transmit: tpm_recv: error %zd\n", rc);
out:
- up(&chip->tpm_mutex);
+ mutex_unlock(&chip->tpm_mutex);
return rc;
}
@@ -942,12 +944,12 @@ int tpm_release(struct inode *inode, struct file *file)
{
struct tpm_chip *chip = file->private_data;
+ flush_scheduled_work();
spin_lock(&driver_lock);
file->private_data = NULL;
- chip->num_opens--;
del_singleshot_timer_sync(&chip->user_read_timer);
- flush_scheduled_work();
atomic_set(&chip->data_pending, 0);
+ chip->num_opens--;
put_device(chip->dev);
kfree(chip->data_buffer);
spin_unlock(&driver_lock);
@@ -966,14 +968,14 @@ ssize_t tpm_write(struct file *file, const char __user *buf,
while (atomic_read(&chip->data_pending) != 0)
msleep(TPM_TIMEOUT);
- down(&chip->buffer_mutex);
+ mutex_lock(&chip->buffer_mutex);
if (in_size > TPM_BUFSIZE)
in_size = TPM_BUFSIZE;
if (copy_from_user
(chip->data_buffer, (void __user *) buf, in_size)) {
- up(&chip->buffer_mutex);
+ mutex_unlock(&chip->buffer_mutex);
return -EFAULT;
}
@@ -981,7 +983,7 @@ ssize_t tpm_write(struct file *file, const char __user *buf,
out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
atomic_set(&chip->data_pending, out_size);
- up(&chip->buffer_mutex);
+ mutex_unlock(&chip->buffer_mutex);
/* Set a timeout by which the reader must come claim the result */
mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
@@ -1004,10 +1006,10 @@ ssize_t tpm_read(struct file *file, char __user *buf,
if (size < ret_size)
ret_size = size;
- down(&chip->buffer_mutex);
+ mutex_lock(&chip->buffer_mutex);
if (copy_to_user(buf, chip->data_buffer, ret_size))
ret_size = -EFAULT;
- up(&chip->buffer_mutex);
+ mutex_unlock(&chip->buffer_mutex);
}
return ret_size;
@@ -1097,11 +1099,16 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
/* Driver specific per-device data */
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL)
+ devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
+
+ if (chip == NULL || devname == NULL) {
+ kfree(chip);
+ kfree(devname);
return NULL;
+ }
- init_MUTEX(&chip->buffer_mutex);
- init_MUTEX(&chip->tpm_mutex);
+ mutex_init(&chip->buffer_mutex);
+ mutex_init(&chip->tpm_mutex);
INIT_LIST_HEAD(&chip->list);
INIT_WORK(&chip->work, timeout_work);
@@ -1124,7 +1131,6 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
set_bit(chip->dev_num, dev_mask);
- devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
chip->vendor.miscdev.name = devname;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 9f273f0..b2e2b00 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/fs.h>
+#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
@@ -94,11 +95,11 @@ struct tpm_chip {
/* Data passed to and from the tpm via the read/write calls */
u8 *data_buffer;
atomic_t data_pending;
- struct semaphore buffer_mutex;
+ struct mutex buffer_mutex;
struct timer_list user_read_timer; /* user needs to claim result */
struct work_struct work;
- struct semaphore tpm_mutex; /* tpm is processing */
+ struct mutex tpm_mutex; /* tpm is processing */
struct tpm_vendor_specific vendor;
diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h
index 3c85200..c912d86 100644
--- a/drivers/char/tpm/tpm_atmel.h
+++ b/drivers/char/tpm/tpm_atmel.h
@@ -47,12 +47,12 @@ static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
if (!dn)
return NULL;
- if (!device_is_compatible(dn, "AT97SC3201")) {
+ if (!of_device_is_compatible(dn, "AT97SC3201")) {
of_node_put(dn);
return NULL;
}
- reg = get_property(dn, "reg", &reglen);
+ reg = of_get_property(dn, "reg", &reglen);
naddrc = of_n_addr_cells(dn);
nsizec = of_n_size_cells(dn);
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index 1353b5a..967002a 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -30,12 +30,60 @@
#define TPM_MAX_TRIES 5000
#define TPM_INFINEON_DEV_VEN_VALUE 0x15D1
-/* These values will be filled after PnP-call */
-static int TPM_INF_DATA;
-static int TPM_INF_ADDR;
-static int TPM_INF_BASE;
-static int TPM_INF_ADDR_LEN;
-static int TPM_INF_PORT_LEN;
+#define TPM_INF_IO_PORT 0x0
+#define TPM_INF_IO_MEM 0x1
+
+#define TPM_INF_ADDR 0x0
+#define TPM_INF_DATA 0x1
+
+struct tpm_inf_dev {
+ int iotype;
+
+ void __iomem *mem_base; /* MMIO ioremap'd addr */
+ unsigned long map_base; /* phys MMIO base */
+ unsigned long map_size; /* MMIO region size */
+ unsigned int index_off; /* index register offset */
+
+ unsigned int data_regs; /* Data registers */
+ unsigned int data_size;
+
+ unsigned int config_port; /* IO Port config index reg */
+ unsigned int config_size;
+};
+
+static struct tpm_inf_dev tpm_dev;
+
+static inline void tpm_data_out(unsigned char data, unsigned char offset)
+{
+ if (tpm_dev.iotype == TPM_INF_IO_PORT)
+ outb(data, tpm_dev.data_regs + offset);
+ else
+ writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset);
+}
+
+static inline unsigned char tpm_data_in(unsigned char offset)
+{
+ if (tpm_dev.iotype == TPM_INF_IO_PORT)
+ return inb(tpm_dev.data_regs + offset);
+ else
+ return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset);
+}
+
+static inline void tpm_config_out(unsigned char data, unsigned char offset)
+{
+ if (tpm_dev.iotype == TPM_INF_IO_PORT)
+ outb(data, tpm_dev.config_port + offset);
+ else
+ writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset);
+}
+
+static inline unsigned char tpm_config_in(unsigned char offset)
+{
+ if (tpm_dev.iotype == TPM_INF_IO_PORT)
+ return inb(tpm_dev.config_port + offset);
+ else
+ return readb(tpm_dev.mem_base + tpm_dev.index_off + offset);
+}
/* TPM header definitions */
enum infineon_tpm_header {
@@ -105,7 +153,7 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
if (clear_wrfifo) {
for (i = 0; i < 4096; i++) {
- status = inb(chip->vendor.base + WRFIFO);
+ status = tpm_data_in(WRFIFO);
if (status == 0xff) {
if (check == 5)
break;
@@ -125,8 +173,8 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
*/
i = 0;
do {
- status = inb(chip->vendor.base + RDFIFO);
- status = inb(chip->vendor.base + STAT);
+ status = tpm_data_in(RDFIFO);
+ status = tpm_data_in(STAT);
i++;
if (i == TPM_MAX_TRIES)
return -EIO;
@@ -139,7 +187,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
int status;
int i;
for (i = 0; i < TPM_MAX_TRIES; i++) {
- status = inb(chip->vendor.base + STAT);
+ status = tpm_data_in(STAT);
/* check the status-register if wait_for_bit is set */
if (status & 1 << wait_for_bit)
break;
@@ -158,7 +206,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
{
wait(chip, STAT_XFE);
- outb(sendbyte, chip->vendor.base + WRFIFO);
+ tpm_data_out(sendbyte, WRFIFO);
}
/* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
@@ -205,7 +253,7 @@ recv_begin:
ret = wait(chip, STAT_RDA);
if (ret)
return -EIO;
- buf[i] = inb(chip->vendor.base + RDFIFO);
+ buf[i] = tpm_data_in(RDFIFO);
}
if (buf[0] != TPM_VL_VER) {
@@ -220,7 +268,7 @@ recv_begin:
for (i = 0; i < size; i++) {
wait(chip, STAT_RDA);
- buf[i] = inb(chip->vendor.base + RDFIFO);
+ buf[i] = tpm_data_in(RDFIFO);
}
if ((size == 0x6D00) && (buf[1] == 0x80)) {
@@ -269,7 +317,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
u8 count_high, count_low, count_4, count_3, count_2, count_1;
/* Disabling Reset, LP and IRQC */
- outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD);
+ tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
ret = empty_fifo(chip, 1);
if (ret) {
@@ -320,7 +368,7 @@ static void tpm_inf_cancel(struct tpm_chip *chip)
static u8 tpm_inf_status(struct tpm_chip *chip)
{
- return inb(chip->vendor.base + STAT);
+ return tpm_data_in(STAT);
}
static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
@@ -381,51 +429,88 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
/* read IO-ports through PnP */
if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
!(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
- TPM_INF_ADDR = pnp_port_start(dev, 0);
- TPM_INF_ADDR_LEN = pnp_port_len(dev, 0);
- TPM_INF_DATA = (TPM_INF_ADDR + 1);
- TPM_INF_BASE = pnp_port_start(dev, 1);
- TPM_INF_PORT_LEN = pnp_port_len(dev, 1);
- if ((TPM_INF_PORT_LEN < 4) || (TPM_INF_ADDR_LEN < 2)) {
+
+ tpm_dev.iotype = TPM_INF_IO_PORT;
+
+ tpm_dev.config_port = pnp_port_start(dev, 0);
+ tpm_dev.config_size = pnp_port_len(dev, 0);
+ tpm_dev.data_regs = pnp_port_start(dev, 1);
+ tpm_dev.data_size = pnp_port_len(dev, 1);
+ if ((tpm_dev.data_size < 4) || (tpm_dev.config_size < 2)) {
rc = -EINVAL;
goto err_last;
}
dev_info(&dev->dev, "Found %s with ID %s\n",
dev->name, dev_id->id);
- if (!((TPM_INF_BASE >> 8) & 0xff)) {
+ if (!((tpm_dev.data_regs >> 8) & 0xff)) {
rc = -EINVAL;
goto err_last;
}
/* publish my base address and request region */
- if (request_region
- (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
+ if (request_region(tpm_dev.data_regs, tpm_dev.data_size,
+ "tpm_infineon0") == NULL) {
rc = -EINVAL;
goto err_last;
}
- if (request_region
- (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) {
+ if (request_region(tpm_dev.config_port, tpm_dev.config_size,
+ "tpm_infineon0") == NULL) {
+ release_region(tpm_dev.data_regs, tpm_dev.data_size);
rc = -EINVAL;
goto err_last;
}
+ } else if (pnp_mem_valid(dev, 0) &&
+ !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
+
+ tpm_dev.iotype = TPM_INF_IO_MEM;
+
+ tpm_dev.map_base = pnp_mem_start(dev, 0);
+ tpm_dev.map_size = pnp_mem_len(dev, 0);
+
+ dev_info(&dev->dev, "Found %s with ID %s\n",
+ dev->name, dev_id->id);
+
+ /* publish my base address and request region */
+ if (request_mem_region(tpm_dev.map_base, tpm_dev.map_size,
+ "tpm_infineon0") == NULL) {
+ rc = -EINVAL;
+ goto err_last;
+ }
+
+ tpm_dev.mem_base = ioremap(tpm_dev.map_base, tpm_dev.map_size);
+ if (tpm_dev.mem_base == NULL) {
+ release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
+ rc = -EINVAL;
+ goto err_last;
+ }
+
+ /*
+ * The only known MMIO based Infineon TPM system provides
+ * a single large mem region with the device config
+ * registers at the default TPM_ADDR. The data registers
+ * seem like they could be placed anywhere within the MMIO
+ * region, but lets just put them at zero offset.
+ */
+ tpm_dev.index_off = TPM_ADDR;
+ tpm_dev.data_regs = 0x0;
} else {
rc = -EINVAL;
goto err_last;
}
/* query chip for its vendor, its version number a.s.o. */
- outb(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
- outb(IDVENL, TPM_INF_ADDR);
- vendorid[1] = inb(TPM_INF_DATA);
- outb(IDVENH, TPM_INF_ADDR);
- vendorid[0] = inb(TPM_INF_DATA);
- outb(IDPDL, TPM_INF_ADDR);
- productid[1] = inb(TPM_INF_DATA);
- outb(IDPDH, TPM_INF_ADDR);
- productid[0] = inb(TPM_INF_DATA);
- outb(CHIP_ID1, TPM_INF_ADDR);
- version[1] = inb(TPM_INF_DATA);
- outb(CHIP_ID2, TPM_INF_ADDR);
- version[0] = inb(TPM_INF_DATA);
+ tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
+ tpm_config_out(IDVENL, TPM_INF_ADDR);
+ vendorid[1] = tpm_config_in(TPM_INF_DATA);
+ tpm_config_out(IDVENH, TPM_INF_ADDR);
+ vendorid[0] = tpm_config_in(TPM_INF_DATA);
+ tpm_config_out(IDPDL, TPM_INF_ADDR);
+ productid[1] = tpm_config_in(TPM_INF_DATA);
+ tpm_config_out(IDPDH, TPM_INF_ADDR);
+ productid[0] = tpm_config_in(TPM_INF_DATA);
+ tpm_config_out(CHIP_ID1, TPM_INF_ADDR);
+ version[1] = tpm_config_in(TPM_INF_DATA);
+ tpm_config_out(CHIP_ID2, TPM_INF_ADDR);
+ version[0] = tpm_config_in(TPM_INF_DATA);
switch ((productid[0] << 8) | productid[1]) {
case 6:
@@ -442,51 +527,54 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
/* configure TPM with IO-ports */
- outb(IOLIMH, TPM_INF_ADDR);
- outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA);
- outb(IOLIML, TPM_INF_ADDR);
- outb((TPM_INF_BASE & 0xff), TPM_INF_DATA);
+ tpm_config_out(IOLIMH, TPM_INF_ADDR);
+ tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
+ tpm_config_out(IOLIML, TPM_INF_ADDR);
+ tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
/* control if IO-ports are set correctly */
- outb(IOLIMH, TPM_INF_ADDR);
- ioh = inb(TPM_INF_DATA);
- outb(IOLIML, TPM_INF_ADDR);
- iol = inb(TPM_INF_DATA);
+ tpm_config_out(IOLIMH, TPM_INF_ADDR);
+ ioh = tpm_config_in(TPM_INF_DATA);
+ tpm_config_out(IOLIML, TPM_INF_ADDR);
+ iol = tpm_config_in(TPM_INF_DATA);
- if ((ioh << 8 | iol) != TPM_INF_BASE) {
+ if ((ioh << 8 | iol) != tpm_dev.data_regs) {
dev_err(&dev->dev,
- "Could not set IO-ports to 0x%x\n",
- TPM_INF_BASE);
+ "Could not set IO-data registers to 0x%x\n",
+ tpm_dev.data_regs);
rc = -EIO;
goto err_release_region;
}
/* activate register */
- outb(TPM_DAR, TPM_INF_ADDR);
- outb(0x01, TPM_INF_DATA);
- outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
+ tpm_config_out(TPM_DAR, TPM_INF_ADDR);
+ tpm_config_out(0x01, TPM_INF_DATA);
+ tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
/* disable RESET, LP and IRQC */
- outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD);
+ tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
/* Finally, we're done, print some infos */
dev_info(&dev->dev, "TPM found: "
- "config base 0x%x, "
- "io base 0x%x, "
+ "config base 0x%lx, "
+ "data base 0x%lx, "
"chip version 0x%02x%02x, "
"vendor id 0x%x%x (Infineon), "
"product id 0x%02x%02x"
"%s\n",
- TPM_INF_ADDR,
- TPM_INF_BASE,
+ tpm_dev.iotype == TPM_INF_IO_PORT ?
+ tpm_dev.config_port :
+ tpm_dev.map_base + tpm_dev.index_off,
+ tpm_dev.iotype == TPM_INF_IO_PORT ?
+ tpm_dev.data_regs :
+ tpm_dev.map_base + tpm_dev.data_regs,
version[0], version[1],
vendorid[0], vendorid[1],
productid[0], productid[1], chipname);
- if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) {
+ if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf)))
goto err_release_region;
- }
- chip->vendor.base = TPM_INF_BASE;
+
return 0;
} else {
rc = -ENODEV;
@@ -494,8 +582,13 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
}
err_release_region:
- release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
- release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
+ if (tpm_dev.iotype == TPM_INF_IO_PORT) {
+ release_region(tpm_dev.data_regs, tpm_dev.data_size);
+ release_region(tpm_dev.config_port, tpm_dev.config_size);
+ } else {
+ iounmap(tpm_dev.mem_base);
+ release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
+ }
err_last:
return rc;
@@ -506,8 +599,14 @@ static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
struct tpm_chip *chip = pnp_get_drvdata(dev);
if (chip) {
- release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
- release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
+ if (tpm_dev.iotype == TPM_INF_IO_PORT) {
+ release_region(tpm_dev.data_regs, tpm_dev.data_size);
+ release_region(tpm_dev.config_port,
+ tpm_dev.config_size);
+ } else {
+ iounmap(tpm_dev.mem_base);
+ release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
+ }
tpm_remove_hardware(chip->dev);
}
}
@@ -539,5 +638,5 @@ module_exit(cleanup_inf);
MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
-MODULE_VERSION("1.8");
+MODULE_VERSION("1.9");
MODULE_LICENSE("GPL");
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 7a32df5..7710a6a 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -141,8 +141,6 @@ static DECLARE_MUTEX(allocated_ptys_lock);
static int ptmx_open(struct inode *, struct file *);
#endif
-extern void disable_early_printk(void);
-
static void initialize_tty_struct(struct tty_struct *tty);
static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
@@ -155,8 +153,8 @@ int tty_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg);
static int tty_fasync(int fd, struct file * filp, int on);
static void release_tty(struct tty_struct *tty, int idx);
-static struct pid *__proc_set_tty(struct task_struct *tsk,
- struct tty_struct *tty);
+static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
+static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
/**
* alloc_tty_struct - allocate a tty object
@@ -1534,10 +1532,9 @@ void disassociate_ctty(int on_exit)
}
spin_lock_irq(&current->sighand->siglock);
- tty_pgrp = current->signal->tty_old_pgrp;
+ put_pid(current->signal->tty_old_pgrp);
current->signal->tty_old_pgrp = NULL;
spin_unlock_irq(&current->sighand->siglock);
- put_pid(tty_pgrp);
mutex_lock(&tty_mutex);
/* It is possible that do_tty_hangup has free'd this tty */
@@ -1562,6 +1559,18 @@ void disassociate_ctty(int on_exit)
unlock_kernel();
}
+/**
+ *
+ * no_tty - Ensure the current process does not have a controlling tty
+ */
+void no_tty(void)
+{
+ struct task_struct *tsk = current;
+ if (tsk->signal->leader)
+ disassociate_ctty(0);
+ proc_clear_tty(tsk);
+}
+
/**
* stop_tty - propogate flow control
@@ -2508,7 +2517,6 @@ static int tty_open(struct inode * inode, struct file * filp)
int index;
dev_t device = inode->i_rdev;
unsigned short saved_flags = filp->f_flags;
- struct pid *old_pgrp;
nonseekable_open(inode, filp);
@@ -2602,17 +2610,15 @@ got_driver:
goto retry_open;
}
- old_pgrp = NULL;
mutex_lock(&tty_mutex);
spin_lock_irq(&current->sighand->siglock);
if (!noctty &&
current->signal->leader &&
!current->signal->tty &&
tty->session == NULL)
- old_pgrp = __proc_set_tty(current, tty);
+ __proc_set_tty(current, tty);
spin_unlock_irq(&current->sighand->siglock);
mutex_unlock(&tty_mutex);
- put_pid(old_pgrp);
return 0;
}
@@ -3287,9 +3293,7 @@ int tty_ioctl(struct inode * inode, struct file * file,
case TIOCNOTTY:
if (current->signal->tty != tty)
return -ENOTTY;
- if (current->signal->leader)
- disassociate_ctty(0);
- proc_clear_tty(current);
+ no_tty();
return 0;
case TIOCSCTTY:
return tiocsctty(tty, arg);
@@ -3720,11 +3724,10 @@ int tty_register_driver(struct tty_driver *driver)
if (driver->flags & TTY_DRIVER_INSTALLED)
return 0;
- if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
- p = kmalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL);
+ if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) {
+ p = kzalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL);
if (!p)
return -ENOMEM;
- memset(p, 0, driver->num * 3 * sizeof(void *));
}
if (!driver->major) {
@@ -3767,7 +3770,9 @@ int tty_register_driver(struct tty_driver *driver)
if (!driver->put_char)
driver->put_char = tty_default_put_char;
+ mutex_lock(&tty_mutex);
list_add(&driver->tty_drivers, &tty_drivers);
+ mutex_unlock(&tty_mutex);
if ( !(driver->flags & TTY_DRIVER_DYNAMIC_DEV) ) {
for(i = 0; i < driver->num; i++)
@@ -3793,8 +3798,9 @@ int tty_unregister_driver(struct tty_driver *driver)
unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
driver->num);
-
+ mutex_lock(&tty_mutex);
list_del(&driver->tty_drivers);
+ mutex_unlock(&tty_mutex);
/*
* Free the termios and termios_locked structures because
@@ -3837,11 +3843,9 @@ void proc_clear_tty(struct task_struct *p)
p->signal->tty = NULL;
spin_unlock_irq(&p->sighand->siglock);
}
-EXPORT_SYMBOL(proc_clear_tty);
-static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
+static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
{
- struct pid *old_pgrp;
if (tty) {
/* We should not have a session or pgrp to here but.... */
put_pid(tty->session);
@@ -3849,21 +3853,16 @@ static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tt
tty->session = get_pid(task_session(tsk));
tty->pgrp = get_pid(task_pgrp(tsk));
}
- old_pgrp = tsk->signal->tty_old_pgrp;
+ put_pid(tsk->signal->tty_old_pgrp);
tsk->signal->tty = tty;
tsk->signal->tty_old_pgrp = NULL;
- return old_pgrp;
}
-void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
+static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
{
- struct pid *old_pgrp;
-
spin_lock_irq(&tsk->sighand->siglock);
- old_pgrp = __proc_set_tty(tsk, tty);
+ __proc_set_tty(tsk, tty);
spin_unlock_irq(&tsk->sighand->siglock);
-
- put_pid(old_pgrp);
}
struct tty_struct *get_current_tty(void)
@@ -3898,9 +3897,6 @@ void __init console_init(void)
* set up the console device so that later boot sequences can
* inform about problems etc..
*/
-#ifdef CONFIG_EARLY_PRINTK
- disable_early_printk();
-#endif
call = __con_initcall_start;
while (call < __con_initcall_end) {
(*call)();
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 7919303..83aeedd 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -28,12 +28,13 @@
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/init.h>
+#include <linux/mutex.h>
#include <linux/vt_kern.h>
#include <linux/selection.h>
#include <linux/kbd_kern.h>
#include <linux/console.h>
-#include <linux/smp_lock.h>
#include <linux/device.h>
+
#include <asm/uaccess.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
@@ -70,11 +71,11 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
{
int size;
- down(&con_buf_sem);
+ mutex_lock(&con_buf_mtx);
size = vcs_size(file->f_path.dentry->d_inode);
switch (orig) {
default:
- up(&con_buf_sem);
+ mutex_unlock(&con_buf_mtx);
return -EINVAL;
case 2:
offset += size;
@@ -85,11 +86,11 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
break;
}
if (offset < 0 || offset > size) {
- up(&con_buf_sem);
+ mutex_unlock(&con_buf_mtx);
return -EINVAL;
}
file->f_pos = offset;
- up(&con_buf_sem);
+ mutex_unlock(&con_buf_mtx);
return file->f_pos;
}
@@ -106,7 +107,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
unsigned short *org = NULL;
ssize_t ret;
- down(&con_buf_sem);
+ mutex_lock(&con_buf_mtx);
pos = *ppos;
@@ -263,7 +264,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
ret = read;
unlock_out:
release_console_sem();
- up(&con_buf_sem);
+ mutex_unlock(&con_buf_mtx);
return ret;
}
@@ -280,7 +281,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
u16 *org0 = NULL, *org = NULL;
size_t ret;
- down(&con_buf_sem);
+ mutex_lock(&con_buf_mtx);
pos = *ppos;
@@ -450,7 +451,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
unlock_out:
release_console_sem();
- up(&con_buf_sem);
+ mutex_unlock(&con_buf_mtx);
return ret;
}
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 1bbb45b..bbd9fc4 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -86,6 +86,7 @@
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/init.h>
+#include <linux/mutex.h>
#include <linux/vt_kern.h>
#include <linux/selection.h>
#include <linux/tiocl.h>
@@ -157,6 +158,8 @@ static void blank_screen_t(unsigned long dummy);
static void set_palette(struct vc_data *vc);
static int printable; /* Is console ready for printing? */
+static int default_utf8;
+module_param(default_utf8, int, S_IRUGO | S_IWUSR);
/*
* ignore_poke: don't unblank the screen when things are typed. This is
@@ -348,10 +351,12 @@ void update_region(struct vc_data *vc, unsigned long start, int count)
/* Structure of attributes is hardware-dependent */
-static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse)
+static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
+ u8 _underline, u8 _reverse, u8 _italic)
{
if (vc->vc_sw->con_build_attr)
- return vc->vc_sw->con_build_attr(vc, _color, _intensity, _blink, _underline, _reverse);
+ return vc->vc_sw->con_build_attr(vc, _color, _intensity,
+ _blink, _underline, _reverse, _italic);
#ifndef VT_BUF_VRAM_ONLY
/*
@@ -368,10 +373,13 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8
u8 a = vc->vc_color;
if (!vc->vc_can_do_color)
return _intensity |
+ (_italic ? 2 : 0) |
(_underline ? 4 : 0) |
(_reverse ? 8 : 0) |
(_blink ? 0x80 : 0);
- if (_underline)
+ if (_italic)
+ a = (a & 0xF0) | vc->vc_itcolor;
+ else if (_underline)
a = (a & 0xf0) | vc->vc_ulcolor;
else if (_intensity == 0)
a = (a & 0xf0) | vc->vc_ulcolor;
@@ -392,8 +400,10 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8
static void update_attr(struct vc_data *vc)
{
- vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity, vc->vc_blink, vc->vc_underline, vc->vc_reverse ^ vc->vc_decscnm);
- vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm) << 8) | ' ';
+ vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity,
+ vc->vc_blink, vc->vc_underline,
+ vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
+ vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
}
/* Note: inverting the screen twice should revert to the original state */
@@ -934,6 +944,10 @@ int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
+module_param_array(default_red, int, NULL, S_IRUGO | S_IWUSR);
+module_param_array(default_grn, int, NULL, S_IRUGO | S_IWUSR);
+module_param_array(default_blu, int, NULL, S_IRUGO | S_IWUSR);
+
/*
* gotoxy() must verify all boundaries, because the arguments
* might also be negative. If the given position is out of
@@ -1132,6 +1146,7 @@ static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar posi
static void default_attr(struct vc_data *vc)
{
vc->vc_intensity = 1;
+ vc->vc_italic = 0;
vc->vc_underline = 0;
vc->vc_reverse = 0;
vc->vc_blink = 0;
@@ -1154,6 +1169,9 @@ static void csi_m(struct vc_data *vc)
case 2:
vc->vc_intensity = 0;
break;
+ case 3:
+ vc->vc_italic = 1;
+ break;
case 4:
vc->vc_underline = 1;
break;
@@ -1194,6 +1212,9 @@ static void csi_m(struct vc_data *vc)
case 22:
vc->vc_intensity = 1;
break;
+ case 23:
+ vc->vc_italic = 0;
+ break;
case 24:
vc->vc_underline = 0;
break;
@@ -1454,6 +1475,7 @@ static void save_cur(struct vc_data *vc)
vc->vc_saved_x = vc->vc_x;
vc->vc_saved_y = vc->vc_y;
vc->vc_s_intensity = vc->vc_intensity;
+ vc->vc_s_italic = vc->vc_italic;
vc->vc_s_underline = vc->vc_underline;
vc->vc_s_blink = vc->vc_blink;
vc->vc_s_reverse = vc->vc_reverse;
@@ -1468,6 +1490,7 @@ static void restore_cur(struct vc_data *vc)
{
gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y);
vc->vc_intensity = vc->vc_s_intensity;
+ vc->vc_italic = vc->vc_s_italic;
vc->vc_underline = vc->vc_s_underline;
vc->vc_blink = vc->vc_s_blink;
vc->vc_reverse = vc->vc_s_reverse;
@@ -1497,7 +1520,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
vc->vc_charset = 0;
vc->vc_need_wrap = 0;
vc->vc_report_mouse = 0;
- vc->vc_utf = 0;
+ vc->vc_utf = default_utf8;
vc->vc_utf_count = 0;
vc->vc_disp_ctrl = 0;
@@ -1930,7 +1953,47 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
* kernel memory allocation is available.
*/
char con_buf[CON_BUF_SIZE];
-DECLARE_MUTEX(con_buf_sem);
+DEFINE_MUTEX(con_buf_mtx);
+
+/* is_double_width() is based on the wcwidth() implementation by
+ * Markus Kuhn -- 2003-05-20 (Unicode 4.0)
+ * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
+ */
+struct interval {
+ uint32_t first;
+ uint32_t last;
+};
+
+static int bisearch(uint32_t ucs, const struct interval *table, int max)
+{
+ int min = 0;
+ int mid;
+
+ if (ucs < table[0].first || ucs > table[max].last)
+ return 0;
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (ucs > table[mid].last)
+ min = mid + 1;
+ else if (ucs < table[mid].first)
+ max = mid - 1;
+ else
+ return 1;
+ }
+ return 0;
+}
+
+static int is_double_width(uint32_t ucs)
+{
+ static const struct interval double_width[] = {
+ { 0x1100, 0x115F }, { 0x2329, 0x232A }, { 0x2E80, 0x303E },
+ { 0x3040, 0xA4CF }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFAFF },
+ { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 }, { 0xFFE0, 0xFFE6 },
+ { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD }
+ };
+ return bisearch(ucs, double_width,
+ sizeof(double_width) / sizeof(*double_width) - 1);
+}
/* acquires console_sem */
static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
@@ -1948,6 +2011,10 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
unsigned int currcons;
unsigned long draw_from = 0, draw_to = 0;
struct vc_data *vc;
+ unsigned char vc_attr;
+ uint8_t rescan;
+ uint8_t inverse;
+ uint8_t width;
u16 himask, charmask;
const unsigned char *orig_buf = NULL;
int orig_count;
@@ -1983,7 +2050,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
/* At this point 'buf' is guaranteed to be a kernel buffer
* and therefore no access to userspace (and therefore sleeping)
- * will be needed. The con_buf_sem serializes all tty based
+ * will be needed. The con_buf_mtx serializes all tty based
* console rendering and vcs write/read operations. We hold
* the console spinlock during the entire write.
*/
@@ -2010,53 +2077,86 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
buf++;
n++;
count--;
+ rescan = 0;
+ inverse = 0;
+ width = 1;
/* Do no translation at all in control states */
if (vc->vc_state != ESnormal) {
tc = c;
} else if (vc->vc_utf && !vc->vc_disp_ctrl) {
- /* Combine UTF-8 into Unicode */
- /* Malformed sequences as sequences of replacement glyphs */
+ /* Combine UTF-8 into Unicode in vc_utf_char.
+ * vc_utf_count is the number of continuation bytes still
+ * expected to arrive.
+ * vc_npar is the number of continuation bytes arrived so
+ * far
+ */
rescan_last_byte:
- if(c > 0x7f) {
+ if ((c & 0xc0) == 0x80) {
+ /* Continuation byte received */
+ static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff };
if (vc->vc_utf_count) {
- if ((c & 0xc0) == 0x80) {
- vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
- if (--vc->vc_utf_count) {
- vc->vc_npar++;
- continue;
- }
- tc = c = vc->vc_utf_char;
- } else
- goto replacement_glyph;
- } else {
- vc->vc_npar = 0;
- if ((c & 0xe0) == 0xc0) {
- vc->vc_utf_count = 1;
- vc->vc_utf_char = (c & 0x1f);
- } else if ((c & 0xf0) == 0xe0) {
- vc->vc_utf_count = 2;
- vc->vc_utf_char = (c & 0x0f);
- } else if ((c & 0xf8) == 0xf0) {
- vc->vc_utf_count = 3;
- vc->vc_utf_char = (c & 0x07);
- } else if ((c & 0xfc) == 0xf8) {
- vc->vc_utf_count = 4;
- vc->vc_utf_char = (c & 0x03);
- } else if ((c & 0xfe) == 0xfc) {
- vc->vc_utf_count = 5;
- vc->vc_utf_char = (c & 0x01);
- } else
- goto replacement_glyph;
+ vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
+ vc->vc_npar++;
+ if (--vc->vc_utf_count) {
+ /* Still need some bytes */
continue;
- }
+ }
+ /* Got a whole character */
+ c = vc->vc_utf_char;
+ /* Reject overlong sequences */
+ if (c <= utf8_length_changes[vc->vc_npar - 1] ||
+ c > utf8_length_changes[vc->vc_npar])
+ c = 0xfffd;
+ } else {
+ /* Unexpected continuation byte */
+ vc->vc_utf_count = 0;
+ c = 0xfffd;
+ }
} else {
- if (vc->vc_utf_count)
- goto replacement_glyph;
- tc = c;
+ /* Single ASCII byte or first byte of a sequence received */
+ if (vc->vc_utf_count) {
+ /* Continuation byte expected */
+ rescan = 1;
+ vc->vc_utf_count = 0;
+ c = 0xfffd;
+ } else if (c > 0x7f) {
+ /* First byte of a multibyte sequence received */
+ vc->vc_npar = 0;
+ if ((c & 0xe0) == 0xc0) {
+ vc->vc_utf_count = 1;
+ vc->vc_utf_char = (c & 0x1f);
+ } else if ((c & 0xf0) == 0xe0) {
+ vc->vc_utf_count = 2;
+ vc->vc_utf_char = (c & 0x0f);
+ } else if ((c & 0xf8) == 0xf0) {
+ vc->vc_utf_count = 3;
+ vc->vc_utf_char = (c & 0x07);
+ } else if ((c & 0xfc) == 0xf8) {
+ vc->vc_utf_count = 4;
+ vc->vc_utf_char = (c & 0x03);
+ } else if ((c & 0xfe) == 0xfc) {
+ vc->vc_utf_count = 5;
+ vc->vc_utf_char = (c & 0x01);
+ } else {
+ /* 254 and 255 are invalid */
+ c = 0xfffd;
+ }
+ if (vc->vc_utf_count) {
+ /* Still need some bytes */
+ continue;
+ }
+ }
+ /* Nothing to do if an ASCII byte was received */
}
+ /* End of UTF-8 decoding. */
+ /* c is the received character, or U+FFFD for invalid sequences. */
+ /* Replace invalid Unicode code points with U+FFFD too */
+ if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
+ c = 0xfffd;
+ tc = c;
} else { /* no utf or alternate charset mode */
- tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c];
+ tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c];
}
/* If the original code was a control character we
@@ -2076,56 +2176,80 @@ rescan_last_byte:
&& (c != 128+27);
if (vc->vc_state == ESnormal && ok) {
+ if (vc->vc_utf && !vc->vc_disp_ctrl) {
+ if (is_double_width(c))
+ width = 2;
+ }
/* Now try to find out how to display it */
tc = conv_uni_to_pc(vc, tc);
if (tc & ~charmask) {
- if ( tc == -4 ) {
- /* If we got -4 (not found) then see if we have
- defined a replacement character (U+FFFD) */
-replacement_glyph:
- tc = conv_uni_to_pc(vc, 0xfffd);
- if (!(tc & ~charmask))
- goto display_glyph;
- } else if ( tc != -3 )
- continue; /* nothing to display */
- /* no hash table or no replacement --
- * hope for the best */
- if ( c & ~charmask )
- tc = '?';
- else
- tc = c;
+ if (tc == -1 || tc == -2) {
+ continue; /* nothing to display */
+ }
+ /* Glyph not found */
+ if (!(vc->vc_utf && !vc->vc_disp_ctrl) && !(c & ~charmask)) {
+ /* In legacy mode use the glyph we get by a 1:1 mapping.
+ This would make absolutely no sense with Unicode in mind. */
+ tc = c;
+ } else {
+ /* Display U+FFFD. If it's not found, display an inverse question mark. */
+ tc = conv_uni_to_pc(vc, 0xfffd);
+ if (tc < 0) {
+ inverse = 1;
+ tc = conv_uni_to_pc(vc, '?');
+ if (tc < 0) tc = '?';
+ }
+ }
}
-display_glyph:
- if (vc->vc_need_wrap || vc->vc_decim)
- FLUSH
- if (vc->vc_need_wrap) {
- cr(vc);
- lf(vc);
- }
- if (vc->vc_decim)
- insert_char(vc, 1);
- scr_writew(himask ?
- ((vc->vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
- (vc->vc_attr << 8) + tc,
- (u16 *) vc->vc_pos);
- if (DO_UPDATE(vc) && draw_x < 0) {
- draw_x = vc->vc_x;
- draw_from = vc->vc_pos;
- }
- if (vc->vc_x == vc->vc_cols - 1) {
- vc->vc_need_wrap = vc->vc_decawm;
- draw_to = vc->vc_pos + 2;
+ if (!inverse) {
+ vc_attr = vc->vc_attr;
} else {
- vc->vc_x++;
- draw_to = (vc->vc_pos += 2);
+ /* invert vc_attr */
+ if (!vc->vc_can_do_color) {
+ vc_attr = (vc->vc_attr) ^ 0x08;
+ } else if (vc->vc_hi_font_mask == 0x100) {
+ vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) & 0x0e) << 4);
+ } else {
+ vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4);
+ }
}
- if (vc->vc_utf_count) {
- if (vc->vc_npar) {
- vc->vc_npar--;
- goto display_glyph;
+
+ while (1) {
+ if (vc->vc_need_wrap || vc->vc_decim)
+ FLUSH
+ if (vc->vc_need_wrap) {
+ cr(vc);
+ lf(vc);
+ }
+ if (vc->vc_decim)
+ insert_char(vc, 1);
+ scr_writew(himask ?
+ ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
+ (vc_attr << 8) + tc,
+ (u16 *) vc->vc_pos);
+ if (DO_UPDATE(vc) && draw_x < 0) {
+ draw_x = vc->vc_x;
+ draw_from = vc->vc_pos;
+ }
+ if (vc->vc_x == vc->vc_cols - 1) {
+ vc->vc_need_wrap = vc->vc_decawm;
+ draw_to = vc->vc_pos + 2;
+ } else {
+ vc->vc_x++;
+ draw_to = (vc->vc_pos += 2);
}
- vc->vc_utf_count = 0;
+
+ if (!--width) break;
+
+ tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
+ if (tc < 0) tc = ' ';
+ }
+
+ if (rescan) {
+ rescan = 0;
+ inverse = 0;
+ width = 1;
c = orig;
goto rescan_last_byte;
}
@@ -2581,6 +2705,11 @@ static void con_close(struct tty_struct *tty, struct file *filp)
mutex_unlock(&tty_mutex);
}
+static int default_italic_color = 2; // green (ASCII)
+static int default_underline_color = 3; // cyan (ASCII)
+module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR);
+module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR);
+
static void vc_init(struct vc_data *vc, unsigned int rows,
unsigned int cols, int do_clear)
{
@@ -2600,7 +2729,8 @@ static void vc_init(struct vc_data *vc, unsigned int rows,
vc->vc_palette[k++] = default_blu[j] ;
}
vc->vc_def_color = 0x07; /* white */
- vc->vc_ulcolor = 0x0f; /* bold white */
+ vc->vc_ulcolor = default_underline_color;
+ vc->vc_itcolor = default_italic_color;
vc->vc_halfcolor = 0x08; /* grey */
init_waitqueue_head(&vc->paste_wait);
reset_terminal(vc, do_clear);
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index c9f2dd6..c6f6f42 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -1061,7 +1061,7 @@ int vt_waitactive(int vt)
schedule();
}
remove_wait_queue(&vt_activate_queue, &wait);
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
return retval;
}
diff --git a/drivers/char/watchdog/omap_wdt.c b/drivers/char/watchdog/omap_wdt.c
index 84074a6..b36fa8d 100644
--- a/drivers/char/watchdog/omap_wdt.c
+++ b/drivers/char/watchdog/omap_wdt.c
@@ -34,7 +34,6 @@
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 8d053f5..8532bb7 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -470,7 +470,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
dbs_info->enable = 1;
ondemand_powersave_bias_init();
dbs_info->sample_type = DBS_NORMAL_SAMPLE;
- INIT_DELAYED_WORK(&dbs_info->work, do_dbs_timer);
+ INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work,
delay);
}
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c
index 161fe09..2800b3e 100644
--- a/drivers/edac/i82875p_edac.c
+++ b/drivers/edac/i82875p_edac.c
@@ -261,10 +261,6 @@ static void i82875p_check(struct mem_ctl_info *mci)
i82875p_process_error_info(mci, &info, 1);
}
-#ifdef CONFIG_PROC_FS
-extern int pci_proc_attach_device(struct pci_dev *);
-#endif
-
/* Return 0 on success or 1 on failure. */
static int i82875p_setup_overfl_dev(struct pci_dev *pdev,
struct pci_dev **ovrfl_pdev, void __iomem **ovrfl_window)
@@ -287,17 +283,12 @@ static int i82875p_setup_overfl_dev(struct pci_dev *pdev,
if (dev == NULL)
return 1;
+
+ pci_bus_add_device(dev);
}
*ovrfl_pdev = dev;
-#ifdef CONFIG_PROC_FS
- if ((dev->procent == NULL) && pci_proc_attach_device(dev)) {
- i82875p_printk(KERN_ERR, "%s(): Failed to attach overflow "
- "device\n", __func__);
- return 1;
- }
-#endif /* CONFIG_PROC_FS */
if (pci_enable_device(dev)) {
i82875p_printk(KERN_ERR, "%s(): Failed to enable overflow "
"device\n", __func__);
diff --git a/drivers/eisa/virtual_root.c b/drivers/eisa/virtual_root.c
index 9b4fcac..3074879 100644
--- a/drivers/eisa/virtual_root.c
+++ b/drivers/eisa/virtual_root.c
@@ -47,7 +47,7 @@ static void virtual_eisa_release (struct device *dev)
/* nothing really to do here */
}
-static int virtual_eisa_root_init (void)
+static int __init virtual_eisa_root_init (void)
{
int r;
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 62e21cc..6ec04e7 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <asm/unaligned.h>
#include <asm/byteorder.h>
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 6d105a1..3ba3a52 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -2,9 +2,7 @@
# Hardware monitoring chip drivers configuration
#
-menu "Hardware Monitoring support"
-
-config HWMON
+menuconfig HWMON
tristate "Hardware Monitoring support"
default y
help
@@ -23,13 +21,15 @@ config HWMON
This support can also be built as a module. If so, the module
will be called hwmon.
+if HWMON
+
config HWMON_VID
tristate
default n
config SENSORS_ABITUGURU
tristate "Abit uGuru"
- depends on HWMON && EXPERIMENTAL
+ depends on EXPERIMENTAL
help
If you say yes here you get support for the Abit uGuru chips
sensor part. The voltage and frequency control parts of the Abit
@@ -39,9 +39,19 @@ config SENSORS_ABITUGURU
This driver can also be built as a module. If so, the module
will be called abituguru.
+config SENSORS_AD7418
+ tristate "Analog Devices AD7416, AD7417 and AD7418"
+ depends on I2C && EXPERIMENTAL
+ help
+ If you say yes here you get support for the Analog Devices
+ AD7416, AD7417 and AD7418 temperature monitoring chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called ad7418.
+
config SENSORS_ADM1021
tristate "Analog Devices ADM1021 and compatibles"
- depends on HWMON && I2C
+ depends on I2C
help
If you say yes here you get support for Analog Devices ADM1021
and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A,
@@ -53,7 +63,7 @@ config SENSORS_ADM1021
config SENSORS_ADM1025
tristate "Analog Devices ADM1025 and compatibles"
- depends on HWMON && I2C
+ depends on I2C
select HWMON_VID
help
If you say yes here you get support for Analog Devices ADM1025
@@ -64,7 +74,7 @@ config SENSORS_ADM1025
config SENSORS_ADM1026
tristate "Analog Devices ADM1026 and compatibles"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
select HWMON_VID
help
If you say yes here you get support for Analog Devices ADM1026
@@ -75,7 +85,7 @@ config SENSORS_ADM1026
config SENSORS_ADM1029
tristate "Analog Devices ADM1029"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
help
If you say yes here you get support for Analog Devices ADM1029
sensor chip.
@@ -86,7 +96,7 @@ config SENSORS_ADM1029
config SENSORS_ADM1031
tristate "Analog Devices ADM1031 and compatibles"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
help
If you say yes here you get support for Analog Devices ADM1031
and ADM1030 sensor chips.
@@ -96,7 +106,7 @@ config SENSORS_ADM1031
config SENSORS_ADM9240
tristate "Analog Devices ADM9240 and compatibles"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
select HWMON_VID
help
If you say yes here you get support for Analog Devices ADM9240,
@@ -107,7 +117,7 @@ config SENSORS_ADM9240
config SENSORS_K8TEMP
tristate "AMD Athlon64/FX or Opteron temperature sensor"
- depends on HWMON && X86 && PCI && EXPERIMENTAL
+ depends on X86 && PCI && EXPERIMENTAL
help
If you say yes here you get support for the temperature
sensor(s) inside your CPU. Supported is whole AMD K8
@@ -119,7 +129,7 @@ config SENSORS_K8TEMP
config SENSORS_AMS
tristate "Apple Motion Sensor driver"
- depends on HWMON && PPC_PMAC && !PPC64 && INPUT && ((ADB_PMU && I2C = y) || (ADB_PMU && !I2C) || I2C) && EXPERIMENTAL
+ depends on PPC_PMAC && !PPC64 && INPUT && ((ADB_PMU && I2C = y) || (ADB_PMU && !I2C) || I2C) && EXPERIMENTAL
help
Support for the motion sensor included in PowerBooks. Includes
implementations for PMU and I2C.
@@ -144,7 +154,7 @@ config SENSORS_AMS_I2C
config SENSORS_ASB100
tristate "Asus ASB100 Bach"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
select HWMON_VID
help
If you say yes here you get support for the ASB100 Bach sensor
@@ -155,7 +165,7 @@ config SENSORS_ASB100
config SENSORS_ATXP1
tristate "Attansic ATXP1 VID controller"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
select HWMON_VID
help
If you say yes here you get support for the Attansic ATXP1 VID
@@ -169,7 +179,7 @@ config SENSORS_ATXP1
config SENSORS_DS1621
tristate "Dallas Semiconductor DS1621 and DS1625"
- depends on HWMON && I2C
+ depends on I2C
help
If you say yes here you get support for Dallas Semiconductor
DS1621 and DS1625 sensor chips.
@@ -179,7 +189,7 @@ config SENSORS_DS1621
config SENSORS_F71805F
tristate "Fintek F71805F/FG and F71872F/FG"
- depends on HWMON && EXPERIMENTAL
+ depends on EXPERIMENTAL
help
If you say yes here you get support for hardware monitoring
features of the Fintek F71805F/FG and F71872F/FG Super-I/O
@@ -190,7 +200,7 @@ config SENSORS_F71805F
config SENSORS_FSCHER
tristate "FSC Hermes"
- depends on HWMON && I2C
+ depends on I2C
help
If you say yes here you get support for Fujitsu Siemens
Computers Hermes sensor chips.
@@ -200,7 +210,7 @@ config SENSORS_FSCHER
config SENSORS_FSCPOS
tristate "FSC Poseidon"
- depends on HWMON && I2C
+ depends on I2C
help
If you say yes here you get support for Fujitsu Siemens
Computers Poseidon sensor chips.
@@ -210,7 +220,7 @@ config SENSORS_FSCPOS
config SENSORS_GL518SM
tristate "Genesys Logic GL518SM"
- depends on HWMON && I2C
+ depends on I2C
help
If you say yes here you get support for Genesys Logic GL518SM
sensor chips.
@@ -220,7 +230,7 @@ config SENSORS_GL518SM
config SENSORS_GL520SM
tristate "Genesys Logic GL520SM"
- depends on HWMON && I2C
+ depends on I2C
select HWMON_VID
help
If you say yes here you get support for Genesys Logic GL520SM
@@ -229,9 +239,17 @@ config SENSORS_GL520SM
This driver can also be built as a module. If so, the module
will be called gl520sm.
+config SENSORS_CORETEMP
+ tristate "Intel Core (2) Duo/Solo temperature sensor"
+ depends on X86 && EXPERIMENTAL
+ help
+ If you say yes here you get support for the temperature
+ sensor inside your CPU. Supported all are all known variants
+ of Intel Core family.
+
config SENSORS_IT87
tristate "ITE IT87xx and compatibles"
- depends on HWMON && I2C
+ depends on I2C
select I2C_ISA
select HWMON_VID
help
@@ -243,7 +261,7 @@ config SENSORS_IT87
config SENSORS_LM63
tristate "National Semiconductor LM63"
- depends on HWMON && I2C
+ depends on I2C
help
If you say yes here you get support for the National Semiconductor
LM63 remote diode digital temperature sensor with integrated fan
@@ -255,7 +273,7 @@ config SENSORS_LM63
config SENSORS_LM70
tristate "National Semiconductor LM70"
- depends on HWMON && SPI_MASTER && EXPERIMENTAL
+ depends on SPI_MASTER && EXPERIMENTAL
help
If you say yes here you get support for the National Semiconductor
LM70 digital temperature sensor chip.
@@ -265,7 +283,7 @@ config SENSORS_LM70
config SENSORS_LM75
tristate "National Semiconductor LM75 and compatibles"
- depends on HWMON && I2C
+ depends on I2C
help
If you say yes here you get support for National Semiconductor LM75
sensor chips and clones: Dallas Semiconductor DS75 and DS1775 (in
@@ -280,7 +298,7 @@ config SENSORS_LM75
config SENSORS_LM77
tristate "National Semiconductor LM77"
- depends on HWMON && I2C
+ depends on I2C
help
If you say yes here you get support for National Semiconductor LM77
sensor chips.
@@ -290,8 +308,7 @@ config SENSORS_LM77
config SENSORS_LM78
tristate "National Semiconductor LM78 and compatibles"
- depends on HWMON && I2C
- select I2C_ISA
+ depends on I2C
select HWMON_VID
help
If you say yes here you get support for National Semiconductor LM78,
@@ -302,7 +319,7 @@ config SENSORS_LM78
config SENSORS_LM80
tristate "National Semiconductor LM80"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
help
If you say yes here you get support for National Semiconductor
LM80 sensor chips.
@@ -312,7 +329,7 @@ config SENSORS_LM80
config SENSORS_LM83
tristate "National Semiconductor LM83 and compatibles"
- depends on HWMON && I2C
+ depends on I2C
help
If you say yes here you get support for National Semiconductor
LM82 and LM83 sensor chips.
@@ -322,7 +339,7 @@ config SENSORS_LM83
config SENSORS_LM85
tristate "National Semiconductor LM85 and compatibles"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
select HWMON_VID
help
If you say yes here you get support for National Semiconductor LM85
@@ -333,7 +350,7 @@ config SENSORS_LM85
config SENSORS_LM87
tristate "National Semiconductor LM87"
- depends on HWMON && I2C
+ depends on I2C
select HWMON_VID
help
If you say yes here you get support for National Semiconductor LM87
@@ -344,7 +361,7 @@ config SENSORS_LM87
config SENSORS_LM90
tristate "National Semiconductor LM90 and compatibles"
- depends on HWMON && I2C
+ depends on I2C
help
If you say yes here you get support for National Semiconductor LM90,
LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and
@@ -358,7 +375,7 @@ config SENSORS_LM90
config SENSORS_LM92
tristate "National Semiconductor LM92 and compatibles"
- depends on HWMON && I2C
+ depends on I2C
help
If you say yes here you get support for National Semiconductor LM92
and Maxim MAX6635 sensor chips.
@@ -368,16 +385,26 @@ config SENSORS_LM92
config SENSORS_MAX1619
tristate "Maxim MAX1619 sensor chip"
- depends on HWMON && I2C
+ depends on I2C
help
If you say yes here you get support for MAX1619 sensor chip.
This driver can also be built as a module. If so, the module
will be called max1619.
+config SENSORS_MAX6650
+ tristate "Maxim MAX6650 sensor chip"
+ depends on I2C && EXPERIMENTAL
+ help
+ If you say yes here you get support for the MAX6650 / MAX6651
+ sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called max6650.
+
config SENSORS_PC87360
tristate "National Semiconductor PC87360 family"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
select I2C_ISA
select HWMON_VID
help
@@ -392,7 +419,7 @@ config SENSORS_PC87360
config SENSORS_PC87427
tristate "National Semiconductor PC87427"
- depends on HWMON && EXPERIMENTAL
+ depends on EXPERIMENTAL
help
If you say yes here you get access to the hardware monitoring
functions of the National Semiconductor PC87427 Super-I/O chip.
@@ -405,7 +432,7 @@ config SENSORS_PC87427
config SENSORS_SIS5595
tristate "Silicon Integrated Systems Corp. SiS5595"
- depends on HWMON && I2C && PCI && EXPERIMENTAL
+ depends on I2C && PCI && EXPERIMENTAL
select I2C_ISA
help
If you say yes here you get support for the integrated sensors in
@@ -416,28 +443,28 @@ config SENSORS_SIS5595
config SENSORS_SMSC47M1
tristate "SMSC LPC47M10x and compatibles"
- depends on HWMON && I2C
- select I2C_ISA
help
If you say yes here you get support for the integrated fan
monitoring and control capabilities of the SMSC LPC47B27x,
LPC47M10x, LPC47M112, LPC47M13x, LPC47M14x, LPC47M15x,
- LPC47M192 and LPC47M997 chips.
+ LPC47M192, LPC47M292 and LPC47M997 chips.
- The temperature and voltage sensor features of the LPC47M192
- and LPC47M997 are supported by another driver, select also
- "SMSC LPC47M192 and compatibles" below for those.
+ The temperature and voltage sensor features of the LPC47M15x,
+ LPC47M192, LPC47M292 and LPC47M997 are supported by another
+ driver, select also "SMSC LPC47M192 and compatibles" below for
+ those.
This driver can also be built as a module. If so, the module
will be called smsc47m1.
config SENSORS_SMSC47M192
tristate "SMSC LPC47M192 and compatibles"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
select HWMON_VID
help
If you say yes here you get support for the temperature and
- voltage sensors of the SMSC LPC47M192 and LPC47M997 chips.
+ voltage sensors of the SMSC LPC47M192, LPC47M15x, LPC47M292
+ and LPC47M997 chips.
The fan monitoring and control capabilities of these chips
are supported by another driver, select
@@ -449,8 +476,7 @@ config SENSORS_SMSC47M192
config SENSORS_SMSC47B397
tristate "SMSC LPC47B397-NC"
- depends on HWMON && I2C && EXPERIMENTAL
- select I2C_ISA
+ depends on EXPERIMENTAL
help
If you say yes here you get support for the SMSC LPC47B397-NC
sensor chip.
@@ -460,7 +486,7 @@ config SENSORS_SMSC47B397
config SENSORS_VIA686A
tristate "VIA686A"
- depends on HWMON && I2C && PCI
+ depends on I2C && PCI
select I2C_ISA
help
If you say yes here you get support for the integrated sensors in
@@ -471,7 +497,7 @@ config SENSORS_VIA686A
config SENSORS_VT1211
tristate "VIA VT1211"
- depends on HWMON && EXPERIMENTAL
+ depends on EXPERIMENTAL
select HWMON_VID
help
If you say yes here then you get support for hardware monitoring
@@ -482,7 +508,7 @@ config SENSORS_VT1211
config SENSORS_VT8231
tristate "VIA VT8231"
- depends on HWMON && I2C && PCI && EXPERIMENTAL
+ depends on I2C && PCI && EXPERIMENTAL
select HWMON_VID
select I2C_ISA
help
@@ -494,8 +520,7 @@ config SENSORS_VT8231
config SENSORS_W83781D
tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F"
- depends on HWMON && I2C
- select I2C_ISA
+ depends on I2C
select HWMON_VID
help
If you say yes here you get support for the Winbond W8378x series
@@ -507,7 +532,7 @@ config SENSORS_W83781D
config SENSORS_W83791D
tristate "Winbond W83791D"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
select HWMON_VID
help
If you say yes here you get support for the Winbond W83791D chip.
@@ -517,7 +542,7 @@ config SENSORS_W83791D
config SENSORS_W83792D
tristate "Winbond W83792D"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
help
If you say yes here you get support for the Winbond W83792D chip.
@@ -526,7 +551,7 @@ config SENSORS_W83792D
config SENSORS_W83793
tristate "Winbond W83793"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
select HWMON_VID
help
If you say yes here you get support for the Winbond W83793
@@ -537,7 +562,7 @@ config SENSORS_W83793
config SENSORS_W83L785TS
tristate "Winbond W83L785TS-S"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
help
If you say yes here you get support for the Winbond W83L785TS-S
sensor chip, which is used on the Asus A7N8X, among other
@@ -548,8 +573,6 @@ config SENSORS_W83L785TS
config SENSORS_W83627HF
tristate "Winbond W83627HF, W83627THF, W83637HF, W83687THF, W83697HF"
- depends on HWMON && I2C
- select I2C_ISA
select HWMON_VID
help
If you say yes here you get support for the Winbond W836X7 series
@@ -561,7 +584,7 @@ config SENSORS_W83627HF
config SENSORS_W83627EHF
tristate "Winbond W83627EHF"
- depends on HWMON && I2C && EXPERIMENTAL
+ depends on I2C && EXPERIMENTAL
select I2C_ISA
help
If you say yes here you get preliminary support for the hardware
@@ -577,7 +600,7 @@ config SENSORS_W83627EHF
config SENSORS_HDAPS
tristate "IBM Hard Drive Active Protection System (hdaps)"
- depends on HWMON && INPUT && X86
+ depends on INPUT && X86
default n
help
This driver provides support for the IBM Hard Drive Active Protection
@@ -594,9 +617,32 @@ config SENSORS_HDAPS
Say Y here if you have an applicable laptop and want to experience
the awesome power of hdaps.
+config SENSORS_APPLESMC
+ tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
+ depends on HWMON && INPUT && X86
+ select NEW_LEDS
+ select LEDS_CLASS
+ default n
+ help
+ This driver provides support for the Apple System Management
+ Controller, which provides an accelerometer (Apple Sudden Motion
+ Sensor), light sensors, temperature sensors, keyboard backlight
+ control and fan control.
+
+ Only Intel-based Apple's computers are supported (MacBook Pro,
+ MacBook, MacMini).
+
+ Data from the different sensors, keyboard backlight control and fan
+ control are accessible via sysfs.
+
+ This driver also provides an absolute input class device, allowing
+ the laptop to act as a pinball machine-esque joystick.
+
+ Say Y here if you have an applicable laptop and want to experience
+ the awesome power of applesmc.
+
config HWMON_DEBUG_CHIP
bool "Hardware Monitoring Chip debugging messages"
- depends on HWMON
default n
help
Say Y here if you want the I2C chip drivers to produce a bunch of
@@ -604,4 +650,4 @@ config HWMON_DEBUG_CHIP
a problem with I2C support and want to see more of what is going
on.
-endmenu
+endif # HWMON
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 4165c27..cfaf338 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -14,14 +14,17 @@ obj-$(CONFIG_SENSORS_W83781D) += w83781d.o
obj-$(CONFIG_SENSORS_W83791D) += w83791d.o
obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o
+obj-$(CONFIG_SENSORS_AD7418) += ad7418.o
obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o
obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o
obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o
obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o
obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o
obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o
+obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
obj-$(CONFIG_SENSORS_AMS) += ams/
obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
+obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
obj-$(CONFIG_SENSORS_F71805F) += f71805f.o
obj-$(CONFIG_SENSORS_FSCHER) += fscher.o
@@ -43,6 +46,7 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o
obj-$(CONFIG_SENSORS_LM90) += lm90.o
obj-$(CONFIG_SENSORS_LM92) += lm92.o
obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
+obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c
new file mode 100644
index 0000000..cc8b624
--- /dev/null
+++ b/drivers/hwmon/ad7418.c
@@ -0,0 +1,373 @@
+/*
+ * An hwmon driver for the Analog Devices AD7416/17/18
+ * Copyright (C) 2006-07 Tower Technologies
+ *
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ *
+ * Based on lm75.c
+ * Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License,
+ * as published by the Free Software Foundation - version 2.
+ */
+
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+
+#include "lm75.h"
+
+#define DRV_VERSION "0.3"
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x28, I2C_CLIENT_END };
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_3(ad7416, ad7417, ad7418);
+
+/* AD7418 registers */
+#define AD7418_REG_TEMP_IN 0x00
+#define AD7418_REG_CONF 0x01
+#define AD7418_REG_TEMP_HYST 0x02
+#define AD7418_REG_TEMP_OS 0x03
+#define AD7418_REG_ADC 0x04
+#define AD7418_REG_CONF2 0x05
+
+#define AD7418_REG_ADC_CH(x) ((x) << 5)
+#define AD7418_CH_TEMP AD7418_REG_ADC_CH(0)
+
+static const u8 AD7418_REG_TEMP[] = { AD7418_REG_TEMP_IN,
+ AD7418_REG_TEMP_HYST,
+ AD7418_REG_TEMP_OS };
+
+struct ad7418_data {
+ struct i2c_client client;
+ struct class_device *class_dev;
+ struct attribute_group attrs;
+ enum chips type;
+ struct mutex lock;
+ int adc_max; /* number of ADC channels */
+ char valid;
+ unsigned long last_updated; /* In jiffies */
+ s16 temp[3]; /* Register values */
+ u16 in[4];
+};
+
+static int ad7418_attach_adapter(struct i2c_adapter *adapter);
+static int ad7418_detect(struct i2c_adapter *adapter, int address, int kind);
+static int ad7418_detach_client(struct i2c_client *client);
+
+static struct i2c_driver ad7418_driver = {
+ .driver = {
+ .name = "ad7418",
+ },
+ .attach_adapter = ad7418_attach_adapter,
+ .detach_client = ad7418_detach_client,
+};
+
+/* All registers are word-sized, except for the configuration registers.
+ * AD7418 uses a high-byte first convention. Do NOT use those functions to
+ * access the configuration registers CONF and CONF2, as they are byte-sized.
+ */
+static inline int ad7418_read(struct i2c_client *client, u8 reg)
+{
+ return swab16(i2c_smbus_read_word_data(client, reg));
+}
+
+static inline int ad7418_write(struct i2c_client *client, u8 reg, u16 value)
+{
+ return i2c_smbus_write_word_data(client, reg, swab16(value));
+}
+
+static void ad7418_init_client(struct i2c_client *client)
+{
+ struct ad7418_data *data = i2c_get_clientdata(client);
+
+ int reg = i2c_smbus_read_byte_data(client, AD7418_REG_CONF);
+ if (reg < 0) {
+ dev_err(&client->dev, "cannot read configuration register\n");
+ } else {
+ dev_info(&client->dev, "configuring for mode 1\n");
+ i2c_smbus_write_byte_data(client, AD7418_REG_CONF, reg & 0xfe);
+
+ if (data->type == ad7417 || data->type == ad7418)
+ i2c_smbus_write_byte_data(client,
+ AD7418_REG_CONF2, 0x00);
+ }
+}
+
+static struct ad7418_data *ad7418_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ad7418_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ u8 cfg;
+ int i, ch;
+
+ /* read config register and clear channel bits */
+ cfg = i2c_smbus_read_byte_data(client, AD7418_REG_CONF);
+ cfg &= 0x1F;
+
+ i2c_smbus_write_byte_data(client, AD7418_REG_CONF,
+ cfg | AD7418_CH_TEMP);
+ udelay(30);
+
+ for (i = 0; i < 3; i++) {
+ data->temp[i] = ad7418_read(client, AD7418_REG_TEMP[i]);
+ }
+
+ for (i = 0, ch = 4; i < data->adc_max; i++, ch--) {
+ i2c_smbus_write_byte_data(client,
+ AD7418_REG_CONF,
+ cfg | AD7418_REG_ADC_CH(ch));
+
+ udelay(15);
+ data->in[data->adc_max - 1 - i] =
+ ad7418_read(client, AD7418_REG_ADC);
+ }
+
+ /* restore old configuration value */
+ ad7418_write(client, AD7418_REG_CONF, cfg);
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->lock);
+
+ return data;
+}
+
+static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct ad7418_data *data = ad7418_update_device(dev);
+ return sprintf(buf, "%d\n",
+ LM75_TEMP_FROM_REG(data->temp[attr->index]));
+}
+
+static ssize_t show_adc(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct ad7418_data *data = ad7418_update_device(dev);
+
+ return sprintf(buf, "%d\n",
+ ((data->in[attr->index] >> 6) * 2500 + 512) / 1024);
+}
+
+static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ad7418_data *data = i2c_get_clientdata(client);
+ int temp = simple_strtol(buf, NULL, 10);
+
+ mutex_lock(&data->lock);
+ data->temp[attr->index] = LM75_TEMP_TO_REG(temp);
+ ad7418_write(client, AD7418_REG_TEMP[attr->index], data->temp[attr->index]);
+ mutex_unlock(&data->lock);
+ return count;
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
+ show_temp, set_temp, 1);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
+ show_temp, set_temp, 2);
+
+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_adc, NULL, 0);
+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_adc, NULL, 1);
+static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_adc, NULL, 2);
+static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_adc, NULL, 3);
+
+static int ad7418_attach_adapter(struct i2c_adapter *adapter)
+{
+ if (!(adapter->class & I2C_CLASS_HWMON))
+ return 0;
+ return i2c_probe(adapter, &addr_data, ad7418_detect);
+}
+
+static struct attribute *ad7416_attributes[] = {
+ &sensor_dev_attr_temp1_max.dev_attr.attr,
+ &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ NULL
+};
+
+static struct attribute *ad7417_attributes[] = {
+ &sensor_dev_attr_temp1_max.dev_attr.attr,
+ &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_in1_input.dev_attr.attr,
+ &sensor_dev_attr_in2_input.dev_attr.attr,
+ &sensor_dev_attr_in3_input.dev_attr.attr,
+ &sensor_dev_attr_in4_input.dev_attr.attr,
+ NULL
+};
+
+static struct attribute *ad7418_attributes[] = {
+ &sensor_dev_attr_temp1_max.dev_attr.attr,
+ &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_in1_input.dev_attr.attr,
+ NULL
+};
+
+static int ad7418_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+ struct i2c_client *client;
+ struct ad7418_data *data;
+ int err = 0;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+ I2C_FUNC_SMBUS_WORD_DATA))
+ goto exit;
+
+ if (!(data = kzalloc(sizeof(struct ad7418_data), GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ client = &data->client;
+ client->addr = address;
+ client->adapter = adapter;
+ client->driver = &ad7418_driver;
+
+ i2c_set_clientdata(client, data);
+
+ mutex_init(&data->lock);
+
+ /* AD7418 has a curious behaviour on registers 6 and 7. They
+ * both always read 0xC071 and are not documented on the datasheet.
+ * We use them to detect the chip.
+ */
+ if (kind <= 0) {
+ int reg, reg6, reg7;
+
+ /* the AD7416 lies within this address range, but I have
+ * no means to check.
+ */
+ if (address >= 0x48 && address <= 0x4f) {
+ /* XXX add tests for AD7416 here */
+ /* data->type = ad7416; */
+ }
+ /* here we might have AD7417 or AD7418 */
+ else if (address >= 0x28 && address <= 0x2f) {
+ reg6 = i2c_smbus_read_word_data(client, 0x06);
+ reg7 = i2c_smbus_read_word_data(client, 0x07);
+
+ if (address == 0x28 && reg6 == 0xC071 && reg7 == 0xC071)
+ data->type = ad7418;
+
+ /* XXX add tests for AD7417 here */
+
+
+ /* both AD7417 and AD7418 have bits 0-5 of
+ * the CONF2 register at 0
+ */
+ reg = i2c_smbus_read_byte_data(client,
+ AD7418_REG_CONF2);
+ if (reg & 0x3F)
+ data->type = any_chip; /* detection failed */
+ }
+ } else {
+ dev_dbg(&adapter->dev, "detection forced\n");
+ }
+
+ if (kind > 0)
+ data->type = kind;
+ else if (kind < 0 && data->type == any_chip) {
+ err = -ENODEV;
+ goto exit_free;
+ }
+
+ switch (data->type) {
+ case any_chip:
+ case ad7416:
+ data->adc_max = 0;
+ data->attrs.attrs = ad7416_attributes;
+ strlcpy(client->name, "ad7416", I2C_NAME_SIZE);
+ break;
+
+ case ad7417:
+ data->adc_max = 4;
+ data->attrs.attrs = ad7417_attributes;
+ strlcpy(client->name, "ad7417", I2C_NAME_SIZE);
+ break;
+
+ case ad7418:
+ data->adc_max = 1;
+ data->attrs.attrs = ad7418_attributes;
+ strlcpy(client->name, "ad7418", I2C_NAME_SIZE);
+ break;
+ }
+
+ if ((err = i2c_attach_client(client)))
+ goto exit_free;
+
+ dev_info(&client->dev, "%s chip found\n", client->name);
+
+ /* Initialize the AD7418 chip */
+ ad7418_init_client(client);
+
+ /* Register sysfs hooks */
+ if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs)))
+ goto exit_detach;
+
+ data->class_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->class_dev)) {
+ err = PTR_ERR(data->class_dev);
+ goto exit_remove;
+ }
+
+ return 0;
+
+exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &data->attrs);
+exit_detach:
+ i2c_detach_client(client);
+exit_free:
+ kfree(data);
+exit:
+ return err;
+}
+
+static int ad7418_detach_client(struct i2c_client *client)
+{
+ struct ad7418_data *data = i2c_get_clientdata(client);
+ hwmon_device_unregister(data->class_dev);
+ sysfs_remove_group(&client->dev.kobj, &data->attrs);
+ i2c_detach_client(client);
+ kfree(data);
+ return 0;
+}
+
+static int __init ad7418_init(void)
+{
+ return i2c_add_driver(&ad7418_driver);
+}
+
+static void __exit ad7418_exit(void)
+{
+ i2c_del_driver(&ad7418_driver);
+}
+
+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
+MODULE_DESCRIPTION("AD7416/17/18 driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+module_init(ad7418_init);
+module_exit(ad7418_exit);
diff --git a/drivers/hwmon/ams/ams-core.c b/drivers/hwmon/ams/ams-core.c
index f5ebad5..6db9737 100644
--- a/drivers/hwmon/ams/ams-core.c
+++ b/drivers/hwmon/ams/ams-core.c
@@ -144,7 +144,7 @@ int ams_sensor_attach(void)
const u32 *prop;
/* Get orientation */
- prop = get_property(ams_info.of_node, "orientation", NULL);
+ prop = of_get_property(ams_info.of_node, "orientation", NULL);
if (!prop)
return -ENODEV;
ams_info.orient1 = *prop;
@@ -208,20 +208,17 @@ int __init ams_init(void)
#ifdef CONFIG_SENSORS_AMS_I2C
np = of_find_node_by_name(NULL, "accelerometer");
- if (np && device_is_compatible(np, "AAPL,accelerometer_1"))
+ if (np && of_device_is_compatible(np, "AAPL,accelerometer_1"))
/* Found I2C motion sensor */
return ams_i2c_init(np);
#endif
#ifdef CONFIG_SENSORS_AMS_PMU
np = of_find_node_by_name(NULL, "sms");
- if (np && device_is_compatible(np, "sms"))
+ if (np && of_device_is_compatible(np, "sms"))
/* Found PMU motion sensor */
return ams_pmu_init(np);
#endif
-
- printk(KERN_ERR "ams: No motion sensor found.\n");
-
return -ENODEV;
}
diff --git a/drivers/hwmon/ams/ams-i2c.c b/drivers/hwmon/ams/ams-i2c.c
index 485d333..95776053 100644
--- a/drivers/hwmon/ams/ams-i2c.c
+++ b/drivers/hwmon/ams/ams-i2c.c
@@ -85,17 +85,17 @@ static int ams_i2c_write(u8 reg, u8 value)
static int ams_i2c_cmd(enum ams_i2c_cmd cmd)
{
s32 result;
- int remaining = HZ / 20;
+ int count = 3;
ams_i2c_write(AMS_COMMAND, cmd);
- mdelay(5);
+ msleep(5);
- while (remaining) {
+ while (count--) {
result = ams_i2c_read(AMS_COMMAND);
if (result == 0 || result & 0x80)
return 0;
- remaining = schedule_timeout(remaining);
+ schedule_timeout_uninterruptible(HZ / 20);
}
return -1;
@@ -276,7 +276,7 @@ int __init ams_i2c_init(struct device_node *np)
ams_info.bustype = BUS_I2C;
/* look for bus either using "reg" or by path */
- prop = get_property(ams_info.of_node, "reg", NULL);
+ prop = of_get_property(ams_info.of_node, "reg", NULL);
if (!prop) {
result = -ENODEV;
diff --git a/drivers/hwmon/ams/ams-pmu.c b/drivers/hwmon/ams/ams-pmu.c
index 1b01c21..9463e97 100644
--- a/drivers/hwmon/ams/ams-pmu.c
+++ b/drivers/hwmon/ams/ams-pmu.c
@@ -160,7 +160,7 @@ int __init ams_pmu_init(struct device_node *np)
ams_info.bustype = BUS_HOST;
/* Get PMU command, should be 0x4e, but we can never know */
- prop = get_property(ams_info.of_node, "reg", NULL);
+ prop = of_get_property(ams_info.of_node, "reg", NULL);
if (!prop) {
result = -ENODEV;
goto exit;
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
new file mode 100644
index 0000000..3215f9c
--- /dev/null
+++ b/drivers/hwmon/applesmc.c
@@ -0,0 +1,1339 @@
+/*
+ * drivers/hwmon/applesmc.c - driver for Apple's SMC (accelerometer, temperature
+ * sensors, fan control, keyboard backlight control) used in Intel-based Apple
+ * computers.
+ *
+ * Copyright (C) 2007 Nicolas Boichat <nicolas@boichat.ch>
+ *
+ * Based on hdaps.c driver:
+ * Copyright (C) 2005 Robert Love <rml@novell.com>
+ * Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com>
+ *
+ * Fan control based on smcFanControl:
+ * Copyright (C) 2006 Hendrik Holtmann <holtmann@mac.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License v2 as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/dmi.h>
+#include <linux/mutex.h>
+#include <linux/hwmon-sysfs.h>
+#include <asm/io.h>
+#include <linux/leds.h>
+#include <linux/hwmon.h>
+#include <linux/workqueue.h>
+
+/* data port used by Apple SMC */
+#define APPLESMC_DATA_PORT 0x300
+/* command/status port used by Apple SMC */
+#define APPLESMC_CMD_PORT 0x304
+
+#define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */
+
+#define APPLESMC_MAX_DATA_LENGTH 32
+
+#define APPLESMC_STATUS_MASK 0x0f
+#define APPLESMC_READ_CMD 0x10
+#define APPLESMC_WRITE_CMD 0x11
+#define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12
+#define APPLESMC_GET_KEY_TYPE_CMD 0x13
+
+#define KEY_COUNT_KEY "#KEY" /* r-o ui32 */
+
+#define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6 bytes) */
+#define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6 bytes) */
+#define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */
+
+#define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */
+
+#define MOTION_SENSOR_X_KEY "MO_X" /* r-o sp78 (2 bytes) */
+#define MOTION_SENSOR_Y_KEY "MO_Y" /* r-o sp78 (2 bytes) */
+#define MOTION_SENSOR_Z_KEY "MO_Z" /* r-o sp78 (2 bytes) */
+#define MOTION_SENSOR_KEY "MOCN" /* r/w ui16 */
+
+#define FANS_COUNT "FNum" /* r-o ui8 */
+#define FANS_MANUAL "FS! " /* r-w ui16 */
+#define FAN_ACTUAL_SPEED "F0Ac" /* r-o fpe2 (2 bytes) */
+#define FAN_MIN_SPEED "F0Mn" /* r-o fpe2 (2 bytes) */
+#define FAN_MAX_SPEED "F0Mx" /* r-o fpe2 (2 bytes) */
+#define FAN_SAFE_SPEED "F0Sf" /* r-o fpe2 (2 bytes) */
+#define FAN_TARGET_SPEED "F0Tg" /* r-w fpe2 (2 bytes) */
+#define FAN_POSITION "F0ID" /* r-o char[16] */
+
+/*
+ * Temperature sensors keys (sp78 - 2 bytes).
+ * First set for Macbook(Pro), second for Macmini.
+ */
+static const char* temperature_sensors_sets[][13] = {
+ { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
+ "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
+ { "TC0D", "TC0P", NULL }
+};
+
+/* List of keys used to read/write fan speeds */
+static const char* fan_speed_keys[] = {
+ FAN_ACTUAL_SPEED,
+ FAN_MIN_SPEED,
+ FAN_MAX_SPEED,
+ FAN_SAFE_SPEED,
+ FAN_TARGET_SPEED
+};
+
+#define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
+#define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
+
+#define APPLESMC_POLL_PERIOD (HZ/20) /* poll for input every 1/20s */
+#define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
+#define APPLESMC_INPUT_FLAT 4
+
+#define SENSOR_X 0
+#define SENSOR_Y 1
+#define SENSOR_Z 2
+
+/* Structure to be passed to DMI_MATCH function */
+struct dmi_match_data {
+/* Indicates whether this computer has an accelerometer. */
+ int accelerometer;
+/* Indicates whether this computer has light sensors and keyboard backlight. */
+ int light;
+/* Indicates which temperature sensors set to use. */
+ int temperature_set;
+};
+
+static const int debug;
+static struct platform_device *pdev;
+static s16 rest_x;
+static s16 rest_y;
+static struct timer_list applesmc_timer;
+static struct input_dev *applesmc_idev;
+static struct class_device *hwmon_class_dev;
+
+/* Indicates whether this computer has an accelerometer. */
+static unsigned int applesmc_accelerometer;
+
+/* Indicates whether this computer has light sensors and keyboard backlight. */
+static unsigned int applesmc_light;
+
+/* Indicates which temperature sensors set to use. */
+static unsigned int applesmc_temperature_set;
+
+static struct mutex applesmc_lock;
+
+/*
+ * Last index written to key_at_index sysfs file, and value to use for all other
+ * key_at_index_* sysfs files.
+ */
+static unsigned int key_at_index;
+
+static struct workqueue_struct *applesmc_led_wq;
+
+/*
+ * __wait_status - Wait up to 2ms for the status port to get a certain value
+ * (masked with 0x0f), returning zero if the value is obtained. Callers must
+ * hold applesmc_lock.
+ */
+static int __wait_status(u8 val)
+{
+ unsigned int i;
+
+ val = val & APPLESMC_STATUS_MASK;
+
+ for (i = 0; i < 200; i++) {
+ if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
+ if (debug)
+ printk(KERN_DEBUG
+ "Waited %d us for status %x\n",
+ i*10, val);
+ return 0;
+ }
+ udelay(10);
+ }
+
+ printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
+ val, inb(APPLESMC_CMD_PORT));
+
+ return -EIO;
+}
+
+/*
+ * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
+ * Returns zero on success or a negative error on failure. Callers must
+ * hold applesmc_lock.
+ */
+static int applesmc_read_key(const char* key, u8* buffer, u8 len)
+{
+ int i;
+
+ if (len > APPLESMC_MAX_DATA_LENGTH) {
+ printk(KERN_ERR "applesmc_read_key: cannot read more than "
+ "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
+ return -EINVAL;
+ }
+
+ outb(APPLESMC_READ_CMD, APPLESMC_CMD_PORT);
+ if (__wait_status(0x0c))
+ return -EIO;
+
+ for (i = 0; i < 4; i++) {
+ outb(key[i], APPLESMC_DATA_PORT);
+ if (__wait_status(0x04))
+ return -EIO;
+ }
+ if (debug)
+ printk(KERN_DEBUG "<%s", key);
+
+ outb(len, APPLESMC_DATA_PORT);
+ if (debug)
+ printk(KERN_DEBUG ">%x", len);
+
+ for (i = 0; i < len; i++) {
+ if (__wait_status(0x05))
+ return -EIO;
+ buffer[i] = inb(APPLESMC_DATA_PORT);
+ if (debug)
+ printk(KERN_DEBUG "<%x", buffer[i]);
+ }
+ if (debug)
+ printk(KERN_DEBUG "\n");
+
+ return 0;
+}
+
+/*
+ * applesmc_write_key - writes len bytes from buffer to a given key.
+ * Returns zero on success or a negative error on failure. Callers must
+ * hold applesmc_lock.
+ */
+static int applesmc_write_key(const char* key, u8* buffer, u8 len)
+{
+ int i;
+
+ if (len > APPLESMC_MAX_DATA_LENGTH) {
+ printk(KERN_ERR "applesmc_write_key: cannot write more than "
+ "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
+ return -EINVAL;
+ }
+
+ outb(APPLESMC_WRITE_CMD, APPLESMC_CMD_PORT);
+ if (__wait_status(0x0c))
+ return -EIO;
+
+ for (i = 0; i < 4; i++) {
+ outb(key[i], APPLESMC_DATA_PORT);
+ if (__wait_status(0x04))
+ return -EIO;
+ }
+
+ outb(len, APPLESMC_DATA_PORT);
+
+ for (i = 0; i < len; i++) {
+ if (__wait_status(0x04))
+ return -EIO;
+ outb(buffer[i], APPLESMC_DATA_PORT);
+ }
+
+ return 0;
+}
+
+/*
+ * applesmc_get_key_at_index - get key at index, and put the result in key
+ * (char[6]). Returns zero on success or a negative error on failure. Callers
+ * must hold applesmc_lock.
+ */
+static int applesmc_get_key_at_index(int index, char* key)
+{
+ int i;
+ u8 readkey[4];
+ readkey[0] = index >> 24;
+ readkey[1] = index >> 16;
+ readkey[2] = index >> 8;
+ readkey[3] = index;
+
+ outb(APPLESMC_GET_KEY_BY_INDEX_CMD, APPLESMC_CMD_PORT);
+ if (__wait_status(0x0c))
+ return -EIO;
+
+ for (i = 0; i < 4; i++) {
+ outb(readkey[i], APPLESMC_DATA_PORT);
+ if (__wait_status(0x04))
+ return -EIO;
+ }
+
+ outb(4, APPLESMC_DATA_PORT);
+
+ for (i = 0; i < 4; i++) {
+ if (__wait_status(0x05))
+ return -EIO;
+ key[i] = inb(APPLESMC_DATA_PORT);
+ }
+ key[4] = 0;
+
+ return 0;
+}
+
+/*
+ * applesmc_get_key_type - get key type, and put the result in type (char[6]).
+ * Returns zero on success or a negative error on failure. Callers must
+ * hold applesmc_lock.
+ */
+static int applesmc_get_key_type(char* key, char* type)
+{
+ int i;
+
+ outb(APPLESMC_GET_KEY_TYPE_CMD, APPLESMC_CMD_PORT);
+ if (__wait_status(0x0c))
+ return -EIO;
+
+ for (i = 0; i < 4; i++) {
+ outb(key[i], APPLESMC_DATA_PORT);
+ if (__wait_status(0x04))
+ return -EIO;
+ }
+
+ outb(5, APPLESMC_DATA_PORT);
+
+ for (i = 0; i < 6; i++) {
+ if (__wait_status(0x05))
+ return -EIO;
+ type[i] = inb(APPLESMC_DATA_PORT);
+ }
+ type[5] = 0;
+
+ return 0;
+}
+
+/*
+ * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
+ * hold applesmc_lock.
+ */
+static int applesmc_read_motion_sensor(int index, s16* value)
+{
+ u8 buffer[2];
+ int ret;
+
+ switch (index) {
+ case SENSOR_X:
+ ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
+ break;
+ case SENSOR_Y:
+ ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
+ break;
+ case SENSOR_Z:
+ ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ *value = ((s16)buffer[0] << 8) | buffer[1];
+
+ return ret;
+}
+
+/*
+ * applesmc_device_init - initialize the accelerometer. Returns zero on success
+ * and negative error code on failure. Can sleep.
+ */
+static int applesmc_device_init(void)
+{
+ int total, ret = -ENXIO;
+ u8 buffer[2];
+
+ if (!applesmc_accelerometer)
+ return 0;
+
+ mutex_lock(&applesmc_lock);
+
+ for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
+ if (debug)
+ printk(KERN_DEBUG "applesmc try %d\n", total);
+ if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
+ (buffer[0] != 0x00 || buffer[1] != 0x00)) {
+ if (total == INIT_TIMEOUT_MSECS) {
+ printk(KERN_DEBUG "applesmc: device has"
+ " already been initialized"
+ " (0x%02x, 0x%02x).\n",
+ buffer[0], buffer[1]);
+ } else {
+ printk(KERN_DEBUG "applesmc: device"
+ " successfully initialized"
+ " (0x%02x, 0x%02x).\n",
+ buffer[0], buffer[1]);
+ }
+ ret = 0;
+ goto out;
+ }
+ buffer[0] = 0xe0;
+ buffer[1] = 0x00;
+ applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
+ msleep(INIT_WAIT_MSECS);
+ }
+
+ printk(KERN_WARNING "applesmc: failed to init the device\n");
+
+out:
+ mutex_unlock(&applesmc_lock);
+ return ret;
+}
+
+/*
+ * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
+ * applesmc_lock.
+ */
+static int applesmc_get_fan_count(void)
+{
+ int ret;
+ u8 buffer[1];
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(FANS_COUNT, buffer, 1);
+
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return buffer[0];
+}
+
+/* Device model stuff */
+static int applesmc_probe(struct platform_device *dev)
+{
+ int ret;
+
+ ret = applesmc_device_init();
+ if (ret)
+ return ret;
+
+ printk(KERN_INFO "applesmc: device successfully initialized.\n");
+ return 0;
+}
+
+static int applesmc_resume(struct platform_device *dev)
+{
+ return applesmc_device_init();
+}
+
+static struct platform_driver applesmc_driver = {
+ .probe = applesmc_probe,
+ .resume = applesmc_resume,
+ .driver = {
+ .name = "applesmc",
+ .owner = THIS_MODULE,
+ },
+};
+
+/*
+ * applesmc_calibrate - Set our "resting" values. Callers must
+ * hold applesmc_lock.
+ */
+static void applesmc_calibrate(void)
+{
+ applesmc_read_motion_sensor(SENSOR_X, &rest_x);
+ applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
+ rest_x = -rest_x;
+}
+
+static int applesmc_idev_open(struct input_dev *dev)
+{
+ add_timer(&applesmc_timer);
+
+ return 0;
+}
+
+static void applesmc_idev_close(struct input_dev *dev)
+{
+ del_timer_sync(&applesmc_timer);
+}
+
+static void applesmc_idev_poll(unsigned long unused)
+{
+ s16 x, y;
+
+ /* Cannot sleep. Try nonblockingly. If we fail, try again later. */
+ if (!mutex_trylock(&applesmc_lock)) {
+ mod_timer(&applesmc_timer, jiffies + APPLESMC_POLL_PERIOD);
+ return;
+ }
+
+ if (applesmc_read_motion_sensor(SENSOR_X, &x))
+ goto out;
+ if (applesmc_read_motion_sensor(SENSOR_Y, &y))
+ goto out;
+
+ x = -x;
+ input_report_abs(applesmc_idev, ABS_X, x - rest_x);
+ input_report_abs(applesmc_idev, ABS_Y, y - rest_y);
+ input_sync(applesmc_idev);
+
+out:
+ mod_timer(&applesmc_timer, jiffies + APPLESMC_POLL_PERIOD);
+
+ mutex_unlock(&applesmc_lock);
+}
+
+/* Sysfs Files */
+
+static ssize_t applesmc_position_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret;
+ s16 x, y, z;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_motion_sensor(SENSOR_X, &x);
+ if (ret)
+ goto out;
+ ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
+ if (ret)
+ goto out;
+ ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
+ if (ret)
+ goto out;
+
+out:
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
+}
+
+static ssize_t applesmc_light_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ int ret;
+ u8 left = 0, right = 0;
+ u8 buffer[6];
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, 6);
+ left = buffer[2];
+ if (ret)
+ goto out;
+ ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, 6);
+ right = buffer[2];
+
+out:
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
+}
+
+/* Displays degree Celsius * 1000 */
+static ssize_t applesmc_show_temperature(struct device *dev,
+ struct device_attribute *devattr, char *sysfsbuf)
+{
+ int ret;
+ u8 buffer[2];
+ unsigned int temp;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ const char* key =
+ temperature_sensors_sets[applesmc_temperature_set][attr->index];
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(key, buffer, 2);
+ temp = buffer[0]*1000;
+ temp += (buffer[1] >> 6) * 250;
+
+ mutex_unlock(&applesmc_lock);
+
+ if (ret)
+ return ret;
+ else
+ return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
+}
+
+static ssize_t applesmc_show_fan_speed(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ int ret;
+ unsigned int speed = 0;
+ char newkey[5];
+ u8 buffer[2];
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+
+ newkey[0] = fan_speed_keys[sensor_attr->nr][0];
+ newkey[1] = '0' + sensor_attr->index;
+ newkey[2] = fan_speed_keys[sensor_attr->nr][2];
+ newkey[3] = fan_speed_keys[sensor_attr->nr][3];
+ newkey[4] = 0;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(newkey, buffer, 2);
+ speed = ((buffer[0] << 8 | buffer[1]) >> 2);
+
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
+}
+
+static ssize_t applesmc_store_fan_speed(struct device *dev,
+ struct device_attribute *attr,
+ const char *sysfsbuf, size_t count)
+{
+ int ret;
+ u32 speed;
+ char newkey[5];
+ u8 buffer[2];
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+
+ speed = simple_strtoul(sysfsbuf, NULL, 10);
+
+ if (speed > 0x4000) /* Bigger than a 14-bit value */
+ return -EINVAL;
+
+ newkey[0] = fan_speed_keys[sensor_attr->nr][0];
+ newkey[1] = '0' + sensor_attr->index;
+ newkey[2] = fan_speed_keys[sensor_attr->nr][2];
+ newkey[3] = fan_speed_keys[sensor_attr->nr][3];
+ newkey[4] = 0;
+
+ mutex_lock(&applesmc_lock);
+
+ buffer[0] = (speed >> 6) & 0xff;
+ buffer[1] = (speed << 2) & 0xff;
+ ret = applesmc_write_key(newkey, buffer, 2);
+
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return count;
+}
+
+static ssize_t applesmc_show_fan_manual(struct device *dev,
+ struct device_attribute *devattr, char *sysfsbuf)
+{
+ int ret;
+ u16 manual = 0;
+ u8 buffer[2];
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
+ manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
+
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
+}
+
+static ssize_t applesmc_store_fan_manual(struct device *dev,
+ struct device_attribute *devattr,
+ const char *sysfsbuf, size_t count)
+{
+ int ret;
+ u8 buffer[2];
+ u32 input;
+ u16 val;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+
+ input = simple_strtoul(sysfsbuf, NULL, 10);
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
+ val = (buffer[0] << 8 | buffer[1]);
+ if (ret)
+ goto out;
+
+ if (input)
+ val = val | (0x01 << attr->index);
+ else
+ val = val & ~(0x01 << attr->index);
+
+ buffer[0] = (val >> 8) & 0xFF;
+ buffer[1] = val & 0xFF;
+
+ ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
+
+out:
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return count;
+}
+
+static ssize_t applesmc_show_fan_position(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ int ret;
+ char newkey[5];
+ u8 buffer[17];
+ struct sensor_device_attribute_2 *sensor_attr =
+ to_sensor_dev_attr_2(attr);
+
+ newkey[0] = FAN_POSITION[0];
+ newkey[1] = '0' + sensor_attr->index;
+ newkey[2] = FAN_POSITION[2];
+ newkey[3] = FAN_POSITION[3];
+ newkey[4] = 0;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(newkey, buffer, 16);
+ buffer[16] = 0;
+
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
+}
+
+static ssize_t applesmc_calibrate_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
+}
+
+static ssize_t applesmc_calibrate_store(struct device *dev,
+ struct device_attribute *attr, const char *sysfsbuf, size_t count)
+{
+ mutex_lock(&applesmc_lock);
+ applesmc_calibrate();
+ mutex_unlock(&applesmc_lock);
+
+ return count;
+}
+
+/* Store the next backlight value to be written by the work */
+static unsigned int backlight_value;
+
+static void applesmc_backlight_set(struct work_struct *work)
+{
+ u8 buffer[2];
+
+ mutex_lock(&applesmc_lock);
+ buffer[0] = backlight_value;
+ buffer[1] = 0x00;
+ applesmc_write_key(BACKLIGHT_KEY, buffer, 2);
+ mutex_unlock(&applesmc_lock);
+}
+static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
+
+static void applesmc_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ int ret;
+
+ backlight_value = value;
+ ret = queue_work(applesmc_led_wq, &backlight_work);
+
+ if (debug && (!ret))
+ printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
+}
+
+static ssize_t applesmc_key_count_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ int ret;
+ u8 buffer[4];
+ u32 count;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
+ count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
+ ((u32)buffer[2]<<8) + buffer[3];
+
+ mutex_unlock(&applesmc_lock);
+ if (ret)
+ return ret;
+ else
+ return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
+}
+
+static ssize_t applesmc_key_at_index_read_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ char key[5];
+ char info[6];
+ int ret;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_get_key_at_index(key_at_index, key);
+
+ if (ret || !key[0]) {
+ mutex_unlock(&applesmc_lock);
+
+ return -EINVAL;
+ }
+
+ ret = applesmc_get_key_type(key, info);
+
+ if (ret) {
+ mutex_unlock(&applesmc_lock);
+
+ return ret;
+ }
+
+ /*
+ * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
+ * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
+ */
+ ret = applesmc_read_key(key, sysfsbuf, info[0]);
+
+ mutex_unlock(&applesmc_lock);
+
+ if (!ret) {
+ return info[0];
+ }
+ else {
+ return ret;
+ }
+}
+
+static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ char key[5];
+ char info[6];
+ int ret;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_get_key_at_index(key_at_index, key);
+
+ if (ret || !key[0]) {
+ mutex_unlock(&applesmc_lock);
+
+ return -EINVAL;
+ }
+
+ ret = applesmc_get_key_type(key, info);
+
+ mutex_unlock(&applesmc_lock);
+
+ if (!ret)
+ return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
+ else
+ return ret;
+}
+
+static ssize_t applesmc_key_at_index_type_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ char key[5];
+ char info[6];
+ int ret;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_get_key_at_index(key_at_index, key);
+
+ if (ret || !key[0]) {
+ mutex_unlock(&applesmc_lock);
+
+ return -EINVAL;
+ }
+
+ ret = applesmc_get_key_type(key, info);
+
+ mutex_unlock(&applesmc_lock);
+
+ if (!ret)
+ return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
+ else
+ return ret;
+}
+
+static ssize_t applesmc_key_at_index_name_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ char key[5];
+ int ret;
+
+ mutex_lock(&applesmc_lock);
+
+ ret = applesmc_get_key_at_index(key_at_index, key);
+
+ mutex_unlock(&applesmc_lock);
+
+ if (!ret && key[0])
+ return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
+ else
+ return -EINVAL;
+}
+
+static ssize_t applesmc_key_at_index_show(struct device *dev,
+ struct device_attribute *attr, char *sysfsbuf)
+{
+ return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
+}
+
+static ssize_t applesmc_key_at_index_store(struct device *dev,
+ struct device_attribute *attr, const char *sysfsbuf, size_t count)
+{
+ mutex_lock(&applesmc_lock);
+
+ key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
+
+ mutex_unlock(&applesmc_lock);
+
+ return count;
+}
+
+static struct led_classdev applesmc_backlight = {
+ .name = "smc:kbd_backlight",
+ .default_trigger = "nand-disk",
+ .brightness_set = applesmc_brightness_set,
+};
+
+static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
+static DEVICE_ATTR(calibrate, 0644,
+ applesmc_calibrate_show, applesmc_calibrate_store);
+
+static struct attribute *accelerometer_attributes[] = {
+ &dev_attr_position.attr,
+ &dev_attr_calibrate.attr,
+ NULL
+};
+
+static const struct attribute_group accelerometer_attributes_group =
+ { .attrs = accelerometer_attributes };
+
+static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
+
+static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
+static DEVICE_ATTR(key_at_index, 0644,
+ applesmc_key_at_index_show, applesmc_key_at_index_store);
+static DEVICE_ATTR(key_at_index_name, 0444,
+ applesmc_key_at_index_name_show, NULL);
+static DEVICE_ATTR(key_at_index_type, 0444,
+ applesmc_key_at_index_type_show, NULL);
+static DEVICE_ATTR(key_at_index_data_length, 0444,
+ applesmc_key_at_index_data_length_show, NULL);
+static DEVICE_ATTR(key_at_index_data, 0444,
+ applesmc_key_at_index_read_show, NULL);
+
+static struct attribute *key_enumeration_attributes[] = {
+ &dev_attr_key_count.attr,
+ &dev_attr_key_at_index.attr,
+ &dev_attr_key_at_index_name.attr,
+ &dev_attr_key_at_index_type.attr,
+ &dev_attr_key_at_index_data_length.attr,
+ &dev_attr_key_at_index_data.attr,
+ NULL
+};
+
+static const struct attribute_group key_enumeration_group =
+ { .attrs = key_enumeration_attributes };
+
+/*
+ * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
+ * - show actual speed
+ * - show/store minimum speed
+ * - show maximum speed
+ * - show safe speed
+ * - show/store target speed
+ * - show/store manual mode
+ */
+#define sysfs_fan_speeds_offset(offset) \
+static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
+ applesmc_show_fan_speed, NULL, 0, offset-1); \
+\
+static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
+ applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
+\
+static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
+ applesmc_show_fan_speed, NULL, 2, offset-1); \
+\
+static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
+ applesmc_show_fan_speed, NULL, 3, offset-1); \
+\
+static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
+ applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
+\
+static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
+ applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
+\
+static SENSOR_DEVICE_ATTR(fan##offset##_position, S_IRUGO, \
+ applesmc_show_fan_position, NULL, offset-1); \
+\
+static struct attribute *fan##offset##_attributes[] = { \
+ &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
+ &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
+ &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
+ &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
+ &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
+ &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
+ &sensor_dev_attr_fan##offset##_position.dev_attr.attr, \
+ NULL \
+};
+
+/*
+ * Create the needed functions for each fan using the macro defined above
+ * (2 fans are supported)
+ */
+sysfs_fan_speeds_offset(1);
+sysfs_fan_speeds_offset(2);
+
+static const struct attribute_group fan_attribute_groups[] = {
+ { .attrs = fan1_attributes },
+ { .attrs = fan2_attributes }
+};
+
+/*
+ * Temperature sensors sysfs entries.
+ */
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 4);
+static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 5);
+static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 6);
+static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 7);
+static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 8);
+static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 9);
+static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 10);
+static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
+ applesmc_show_temperature, NULL, 11);
+
+static struct attribute *temperature_attributes[] = {
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_temp2_input.dev_attr.attr,
+ &sensor_dev_attr_temp3_input.dev_attr.attr,
+ &sensor_dev_attr_temp4_input.dev_attr.attr,
+ &sensor_dev_attr_temp5_input.dev_attr.attr,
+ &sensor_dev_attr_temp6_input.dev_attr.attr,
+ &sensor_dev_attr_temp7_input.dev_attr.attr,
+ &sensor_dev_attr_temp8_input.dev_attr.attr,
+ &sensor_dev_attr_temp9_input.dev_attr.attr,
+ &sensor_dev_attr_temp10_input.dev_attr.attr,
+ &sensor_dev_attr_temp11_input.dev_attr.attr,
+ &sensor_dev_attr_temp12_input.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group temperature_attributes_group =
+ { .attrs = temperature_attributes };
+
+/* Module stuff */
+
+/*
+ * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
+ */
+static int applesmc_dmi_match(struct dmi_system_id *id)
+{
+ int i = 0;
+ struct dmi_match_data* dmi_data = id->driver_data;
+ printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
+ applesmc_accelerometer = dmi_data->accelerometer;
+ printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
+ applesmc_accelerometer ? "with" : "without");
+ applesmc_light = dmi_data->light;
+ printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
+ applesmc_light ? "with" : "without");
+
+ applesmc_temperature_set = dmi_data->temperature_set;
+ while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
+ i++;
+ printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
+ return 1;
+}
+
+/* Create accelerometer ressources */
+static int applesmc_create_accelerometer(void)
+{
+ int ret;
+
+ ret = sysfs_create_group(&pdev->dev.kobj,
+ &accelerometer_attributes_group);
+ if (ret)
+ goto out;
+
+ applesmc_idev = input_allocate_device();
+ if (!applesmc_idev) {
+ ret = -ENOMEM;
+ goto out_sysfs;
+ }
+
+ /* initial calibrate for the input device */
+ applesmc_calibrate();
+
+ /* initialize the input class */
+ applesmc_idev->name = "applesmc";
+ applesmc_idev->id.bustype = BUS_HOST;
+ applesmc_idev->cdev.dev = &pdev->dev;
+ applesmc_idev->evbit[0] = BIT(EV_ABS);
+ applesmc_idev->open = applesmc_idev_open;
+ applesmc_idev->close = applesmc_idev_close;
+ input_set_abs_params(applesmc_idev, ABS_X,
+ -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
+ input_set_abs_params(applesmc_idev, ABS_Y,
+ -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
+
+ ret = input_register_device(applesmc_idev);
+ if (ret)
+ goto out_idev;
+
+ /* start up our timer for the input device */
+ init_timer(&applesmc_timer);
+ applesmc_timer.function = applesmc_idev_poll;
+ applesmc_timer.expires = jiffies + APPLESMC_POLL_PERIOD;
+
+ return 0;
+
+out_idev:
+ input_free_device(applesmc_idev);
+
+out_sysfs:
+ sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
+
+out:
+ printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
+ return ret;
+}
+
+/* Release all ressources used by the accelerometer */
+static void applesmc_release_accelerometer(void)
+{
+ del_timer_sync(&applesmc_timer);
+ input_unregister_device(applesmc_idev);
+ sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
+}
+
+static __initdata struct dmi_match_data applesmc_dmi_data[] = {
+/* MacBook Pro: accelerometer, backlight and temperature set 0 */
+ { .accelerometer = 1, .light = 1, .temperature_set = 0 },
+/* MacBook: accelerometer and temperature set 0 */
+ { .accelerometer = 1, .light = 0, .temperature_set = 0 },
+/* MacBook: temperature set 1 */
+ { .accelerometer = 0, .light = 0, .temperature_set = 1 }
+};
+
+/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
+ * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
+static __initdata struct dmi_system_id applesmc_whitelist[] = {
+ { applesmc_dmi_match, "Apple MacBook Pro", {
+ DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
+ (void*)&applesmc_dmi_data[0]},
+ { applesmc_dmi_match, "Apple MacBook", {
+ DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
+ (void*)&applesmc_dmi_data[1]},
+ { applesmc_dmi_match, "Apple Macmini", {
+ DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
+ (void*)&applesmc_dmi_data[2]},
+ { .ident = NULL }
+};
+
+static int __init applesmc_init(void)
+{
+ int ret;
+ int count;
+ int i;
+
+ mutex_init(&applesmc_lock);
+
+ if (!dmi_check_system(applesmc_whitelist)) {
+ printk(KERN_WARNING "applesmc: supported laptop not found!\n");
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
+ "applesmc")) {
+ ret = -ENXIO;
+ goto out;
+ }
+
+ ret = platform_driver_register(&applesmc_driver);
+ if (ret)
+ goto out_region;
+
+ pdev = platform_device_register_simple("applesmc", -1, NULL, 0);
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
+ goto out_driver;
+ }
+
+ /* Create key enumeration sysfs files */
+ ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
+ if (ret)
+ goto out_device;
+
+ /* create fan files */
+ count = applesmc_get_fan_count();
+ if (count < 0) {
+ printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
+ } else {
+ printk(KERN_INFO "applesmc: %d fans found.\n", count);
+
+ switch (count) {
+ default:
+ printk(KERN_WARNING "applesmc: More than 2 fans found,"
+ " but at most 2 fans are supported"
+ " by the driver.\n");
+ case 2:
+ ret = sysfs_create_group(&pdev->dev.kobj,
+ &fan_attribute_groups[1]);
+ if (ret)
+ goto out_key_enumeration;
+ case 1:
+ ret = sysfs_create_group(&pdev->dev.kobj,
+ &fan_attribute_groups[0]);
+ if (ret)
+ goto out_fan_1;
+ case 0:
+ ;
+ }
+ }
+
+ for (i = 0;
+ temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
+ i++) {
+ if (temperature_attributes[i] == NULL) {
+ printk(KERN_ERR "applesmc: More temperature sensors "
+ "in temperature_sensors_sets (at least %i)"
+ "than available sysfs files in "
+ "temperature_attributes (%i), please report "
+ "this bug.\n", i, i-1);
+ goto out_temperature;
+ }
+ ret = sysfs_create_file(&pdev->dev.kobj,
+ temperature_attributes[i]);
+ if (ret)
+ goto out_temperature;
+ }
+
+ if (applesmc_accelerometer) {
+ ret = applesmc_create_accelerometer();
+ if (ret)
+ goto out_temperature;
+ }
+
+ if (applesmc_light) {
+ /* Add light sensor file */
+ ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
+ if (ret)
+ goto out_accelerometer;
+
+ /* Create the workqueue */
+ applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
+ if (!applesmc_led_wq) {
+ ret = -ENOMEM;
+ goto out_light_sysfs;
+ }
+
+ /* register as a led device */
+ ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
+ if (ret < 0)
+ goto out_light_wq;
+ }
+
+ hwmon_class_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(hwmon_class_dev)) {
+ ret = PTR_ERR(hwmon_class_dev);
+ goto out_light_ledclass;
+ }
+
+ printk(KERN_INFO "applesmc: driver successfully loaded.\n");
+
+ return 0;
+
+out_light_ledclass:
+ if (applesmc_light)
+ led_classdev_unregister(&applesmc_backlight);
+out_light_wq:
+ if (applesmc_light)
+ destroy_workqueue(applesmc_led_wq);
+out_light_sysfs:
+ if (applesmc_light)
+ sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
+out_accelerometer:
+ if (applesmc_accelerometer)
+ applesmc_release_accelerometer();
+out_temperature:
+ sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
+ sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
+out_fan_1:
+ sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
+out_key_enumeration:
+ sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
+out_device:
+ platform_device_unregister(pdev);
+out_driver:
+ platform_driver_unregister(&applesmc_driver);
+out_region:
+ release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
+out:
+ printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
+ return ret;
+}
+
+static void __exit applesmc_exit(void)
+{
+ hwmon_device_unregister(hwmon_class_dev);
+ if (applesmc_light) {
+ led_classdev_unregister(&applesmc_backlight);
+ destroy_workqueue(applesmc_led_wq);
+ sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
+ }
+ if (applesmc_accelerometer)
+ applesmc_release_accelerometer();
+ sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
+ sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
+ sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
+ sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
+ platform_device_unregister(pdev);
+ platform_driver_unregister(&applesmc_driver);
+ release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
+
+ printk(KERN_INFO "applesmc: driver unloaded.\n");
+}
+
+module_init(applesmc_init);
+module_exit(applesmc_exit);
+
+MODULE_AUTHOR("Nicolas Boichat");
+MODULE_DESCRIPTION("Apple SMC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
new file mode 100644
index 0000000..03b1f65
--- /dev/null
+++ b/drivers/hwmon/coretemp.c
@@ -0,0 +1,406 @@
+/*
+ * coretemp.c - Linux kernel module for hardware monitoring
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * Inspired from many hwmon drivers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/hwmon.h>
+#include <linux/sysfs.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <asm/msr.h>
+#include <asm/processor.h>
+
+#define DRVNAME "coretemp"
+
+typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_LABEL, SHOW_NAME } SHOW;
+
+/*
+ * Functions declaration
+ */
+
+static struct coretemp_data *coretemp_update_device(struct device *dev);
+
+struct coretemp_data {
+ struct class_device *class_dev;
+ struct mutex update_lock;
+ const char *name;
+ u32 id;
+ char valid; /* zero until following fields are valid */
+ unsigned long last_updated; /* in jiffies */
+ int temp;
+ int tjmax;
+ u8 alarm;
+};
+
+static struct coretemp_data *coretemp_update_device(struct device *dev);
+
+/*
+ * Sysfs stuff
+ */
+
+static ssize_t show_name(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ int ret;
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct coretemp_data *data = dev_get_drvdata(dev);
+
+ if (attr->index == SHOW_NAME)
+ ret = sprintf(buf, "%s\n", data->name);
+ else /* show label */
+ ret = sprintf(buf, "Core %d\n", data->id);
+ return ret;
+}
+
+static ssize_t show_alarm(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ struct coretemp_data *data = coretemp_update_device(dev);
+ /* read the Out-of-spec log, never clear */
+ return sprintf(buf, "%d\n", data->alarm);
+}
+
+static ssize_t show_temp(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct coretemp_data *data = coretemp_update_device(dev);
+ int err;
+
+ if (attr->index == SHOW_TEMP)
+ err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN;
+ else
+ err = sprintf(buf, "%d\n", data->tjmax);
+
+ return err;
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
+ SHOW_TEMP);
+static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL,
+ SHOW_TJMAX);
+static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL);
+static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
+static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
+
+static struct attribute *coretemp_attributes[] = {
+ &sensor_dev_attr_name.dev_attr.attr,
+ &sensor_dev_attr_temp1_label.dev_attr.attr,
+ &dev_attr_temp1_crit_alarm.attr,
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_temp1_crit.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group coretemp_group = {
+ .attrs = coretemp_attributes,
+};
+
+static struct coretemp_data *coretemp_update_device(struct device *dev)
+{
+ struct coretemp_data *data = dev_get_drvdata(dev);
+
+ mutex_lock(&data->update_lock);
+
+ if (!data->valid || time_after(jiffies, data->last_updated + HZ)) {
+ u32 eax, edx;
+
+ data->valid = 0;
+ rdmsr_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx);
+ data->alarm = (eax >> 5) & 1;
+ /* update only if data has been valid */
+ if (eax & 0x80000000) {
+ data->temp = data->tjmax - (((eax >> 16)
+ & 0x7f) * 1000);
+ data->valid = 1;
+ } else {
+ dev_dbg(dev, "Temperature data invalid (0x%x)\n", eax);
+ }
+ data->last_updated = jiffies;
+ }
+
+ mutex_unlock(&data->update_lock);
+ return data;
+}
+
+static int __devinit coretemp_probe(struct platform_device *pdev)
+{
+ struct coretemp_data *data;
+ struct cpuinfo_x86 *c = &(cpu_data)[pdev->id];
+ int err;
+ u32 eax, edx;
+
+ if (!(data = kzalloc(sizeof(struct coretemp_data), GFP_KERNEL))) {
+ err = -ENOMEM;
+ dev_err(&pdev->dev, "Out of memory\n");
+ goto exit;
+ }
+
+ data->id = pdev->id;
+ data->name = "coretemp";
+ mutex_init(&data->update_lock);
+ /* Tjmax default is 100 degrees C */
+ data->tjmax = 100000;
+
+ /* test if we can access the THERM_STATUS MSR */
+ err = rdmsr_safe_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx);
+ if (err) {
+ dev_err(&pdev->dev,
+ "Unable to access THERM_STATUS MSR, giving up\n");
+ goto exit_free;
+ }
+
+ /* Some processors have Tjmax 85 following magic should detect it
+ Intel won't disclose the information without signed NDA, but
+ individuals cannot sign it. Catch(ed) 22.
+ */
+
+ if (((c->x86_model == 0xf) && (c->x86_mask > 3)) ||
+ (c->x86_model == 0xe)) {
+ err = rdmsr_safe_on_cpu(data->id, 0xee, &eax, &edx);
+ if (err) {
+ dev_warn(&pdev->dev,
+ "Unable to access MSR 0xEE, Tjmax left at %d "
+ "degrees C\n", data->tjmax/1000);
+ } else if (eax & 0x40000000) {
+ data->tjmax = 85000;
+ }
+ }
+
+ platform_set_drvdata(pdev, data);
+
+ if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
+ goto exit_free;
+
+ data->class_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(data->class_dev)) {
+ err = PTR_ERR(data->class_dev);
+ dev_err(&pdev->dev, "Class registration failed (%d)\n",
+ err);
+ goto exit_class;
+ }
+
+ return 0;
+
+exit_class:
+ sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
+exit_free:
+ kfree(data);
+exit:
+ return err;
+}
+
+static int __devexit coretemp_remove(struct platform_device *pdev)
+{
+ struct coretemp_data *data = platform_get_drvdata(pdev);
+
+ hwmon_device_unregister(data->class_dev);
+ sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
+ platform_set_drvdata(pdev, NULL);
+ kfree(data);
+ return 0;
+}
+
+static struct platform_driver coretemp_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRVNAME,
+ },
+ .probe = coretemp_probe,
+ .remove = __devexit_p(coretemp_remove),
+};
+
+struct pdev_entry {
+ struct list_head list;
+ struct platform_device *pdev;
+ unsigned int cpu;
+};
+
+static LIST_HEAD(pdev_list);
+static DEFINE_MUTEX(pdev_list_mutex);
+
+static int __cpuinit coretemp_device_add(unsigned int cpu)
+{
+ int err;
+ struct platform_device *pdev;
+ struct pdev_entry *pdev_entry;
+
+ pdev = platform_device_alloc(DRVNAME, cpu);
+ if (!pdev) {
+ err = -ENOMEM;
+ printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ goto exit;
+ }
+
+ pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
+ if (!pdev_entry) {
+ err = -ENOMEM;
+ goto exit_device_put;
+ }
+
+ err = platform_device_add(pdev);
+ if (err) {
+ printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
+ err);
+ goto exit_device_free;
+ }
+
+ pdev_entry->pdev = pdev;
+ pdev_entry->cpu = cpu;
+ mutex_lock(&pdev_list_mutex);
+ list_add_tail(&pdev_entry->list, &pdev_list);
+ mutex_unlock(&pdev_list_mutex);
+
+ return 0;
+
+exit_device_free:
+ kfree(pdev_entry);
+exit_device_put:
+ platform_device_put(pdev);
+exit:
+ return err;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+void coretemp_device_remove(unsigned int cpu)
+{
+ struct pdev_entry *p, *n;
+ mutex_lock(&pdev_list_mutex);
+ list_for_each_entry_safe(p, n, &pdev_list, list) {
+ if (p->cpu == cpu) {
+ platform_device_unregister(p->pdev);
+ list_del(&p->list);
+ kfree(p);
+ }
+ }
+ mutex_unlock(&pdev_list_mutex);
+}
+
+static int coretemp_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long) hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ coretemp_device_add(cpu);
+ break;
+ case CPU_DEAD:
+ coretemp_device_remove(cpu);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata coretemp_cpu_notifier = {
+ .notifier_call = coretemp_cpu_callback,
+};
+#endif /* !CONFIG_HOTPLUG_CPU */
+
+static int __init coretemp_init(void)
+{
+ int i, err = -ENODEV;
+ struct pdev_entry *p, *n;
+
+ printk(KERN_NOTICE DRVNAME ": This driver uses undocumented features "
+ "of Core CPU. Temperature might be wrong!\n");
+
+ /* quick check if we run Intel */
+ if (cpu_data[0].x86_vendor != X86_VENDOR_INTEL)
+ goto exit;
+
+ err = platform_driver_register(&coretemp_driver);
+ if (err)
+ goto exit;
+
+ for_each_online_cpu(i) {
+ struct cpuinfo_x86 *c = &(cpu_data)[i];
+
+ /* check if family 6, models e, f */
+ if ((c->cpuid_level < 0) || (c->x86 != 0x6) ||
+ !((c->x86_model == 0xe) || (c->x86_model == 0xf))) {
+
+ /* supported CPU not found, but report the unknown
+ family 6 CPU */
+ if ((c->x86 == 0x6) && (c->x86_model > 0xf))
+ printk(KERN_WARNING DRVNAME ": Unknown CPU "
+ "model %x\n", c->x86_model);
+ continue;
+ }
+
+ err = coretemp_device_add(i);
+ if (err)
+ goto exit_devices_unreg;
+ }
+ if (list_empty(&pdev_list)) {
+ err = -ENODEV;
+ goto exit_driver_unreg;
+ }
+
+#ifdef CONFIG_HOTPLUG_CPU
+ register_hotcpu_notifier(&coretemp_cpu_notifier);
+#endif
+ return 0;
+
+exit_devices_unreg:
+ mutex_lock(&pdev_list_mutex);
+ list_for_each_entry_safe(p, n, &pdev_list, list) {
+ platform_device_unregister(p->pdev);
+ list_del(&p->list);
+ kfree(p);
+ }
+ mutex_unlock(&pdev_list_mutex);
+exit_driver_unreg:
+ platform_driver_unregister(&coretemp_driver);
+exit:
+ return err;
+}
+
+static void __exit coretemp_exit(void)
+{
+ struct pdev_entry *p, *n;
+#ifdef CONFIG_HOTPLUG_CPU
+ unregister_hotcpu_notifier(&coretemp_cpu_notifier);
+#endif
+ mutex_lock(&pdev_list_mutex);
+ list_for_each_entry_safe(p, n, &pdev_list, list) {
+ platform_device_unregister(p->pdev);
+ list_del(&p->list);
+ kfree(p);
+ }
+ mutex_unlock(&pdev_list_mutex);
+ platform_driver_unregister(&coretemp_driver);
+}
+
+MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
+MODULE_DESCRIPTION("Intel Core temperature monitor");
+MODULE_LICENSE("GPL");
+
+module_init(coretemp_init)
+module_exit(coretemp_exit)
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index 7c29734..cdbe309 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -35,6 +35,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
+#include <linux/ioport.h>
#include <asm/io.h>
static struct platform_device *pdev;
@@ -1140,6 +1141,13 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
}
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!request_region(res->start + ADDR_REG_OFFSET, 2, DRVNAME)) {
+ err = -EBUSY;
+ dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n",
+ (unsigned long)(res->start + ADDR_REG_OFFSET),
+ (unsigned long)(res->start + ADDR_REG_OFFSET + 1));
+ goto exit_free;
+ }
data->addr = res->start;
data->name = names[sio_data->kind];
mutex_init(&data->update_lock);
@@ -1165,7 +1173,7 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
/* Register sysfs interface files */
if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group)))
- goto exit_free;
+ goto exit_release_region;
if (data->has_in & (1 << 4)) { /* in4 */
if ((err = sysfs_create_group(&pdev->dev.kobj,
&f71805f_group_optin[0])))
@@ -1219,6 +1227,8 @@ exit_remove_files:
for (i = 0; i < 4; i++)
sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]);
sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq);
+exit_release_region:
+ release_region(res->start + ADDR_REG_OFFSET, 2);
exit_free:
platform_set_drvdata(pdev, NULL);
kfree(data);
@@ -1229,6 +1239,7 @@ exit:
static int __devexit f71805f_remove(struct platform_device *pdev)
{
struct f71805f_data *data = platform_get_drvdata(pdev);
+ struct resource *res;
int i;
platform_set_drvdata(pdev, NULL);
@@ -1239,6 +1250,9 @@ static int __devexit f71805f_remove(struct platform_device *pdev)
sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq);
kfree(data);
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ release_region(res->start + ADDR_REG_OFFSET, 2);
+
return 0;
}
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index bf759ea..f82fa2d 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -30,10 +30,12 @@
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/kernel.h>
+#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/dmi.h>
#include <linux/jiffies.h>
+
#include <asm/io.h>
#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */
@@ -71,10 +73,10 @@ static u8 km_activity;
static int rest_x;
static int rest_y;
-static DECLARE_MUTEX(hdaps_sem);
+static DEFINE_MUTEX(hdaps_mtx);
/*
- * __get_latch - Get the value from a given port. Callers must hold hdaps_sem.
+ * __get_latch - Get the value from a given port. Callers must hold hdaps_mtx.
*/
static inline u8 __get_latch(u16 port)
{
@@ -83,7 +85,7 @@ static inline u8 __get_latch(u16 port)
/*
* __check_latch - Check a port latch for a given value. Returns zero if the
- * port contains the given value. Callers must hold hdaps_sem.
+ * port contains the given value. Callers must hold hdaps_mtx.
*/
static inline int __check_latch(u16 port, u8 val)
{
@@ -94,7 +96,7 @@ static inline int __check_latch(u16 port, u8 val)
/*
* __wait_latch - Wait up to 100us for a port latch to get a certain value,
- * returning zero if the value is obtained. Callers must hold hdaps_sem.
+ * returning zero if the value is obtained. Callers must hold hdaps_mtx.
*/
static int __wait_latch(u16 port, u8 val)
{
@@ -111,7 +113,7 @@ static int __wait_latch(u16 port, u8 val)
/*
* __device_refresh - request a refresh from the accelerometer. Does not wait
- * for refresh to complete. Callers must hold hdaps_sem.
+ * for refresh to complete. Callers must hold hdaps_mtx.
*/
static void __device_refresh(void)
{
@@ -125,7 +127,7 @@ static void __device_refresh(void)
/*
* __device_refresh_sync - request a synchronous refresh from the
* accelerometer. We wait for the refresh to complete. Returns zero if
- * successful and nonzero on error. Callers must hold hdaps_sem.
+ * successful and nonzero on error. Callers must hold hdaps_mtx.
*/
static int __device_refresh_sync(void)
{
@@ -135,7 +137,7 @@ static int __device_refresh_sync(void)
/*
* __device_complete - indicate to the accelerometer that we are done reading
- * data, and then initiate an async refresh. Callers must hold hdaps_sem.
+ * data, and then initiate an async refresh. Callers must hold hdaps_mtx.
*/
static inline void __device_complete(void)
{
@@ -153,7 +155,7 @@ static int hdaps_readb_one(unsigned int port, u8 *val)
{
int ret;
- down(&hdaps_sem);
+ mutex_lock(&hdaps_mtx);
/* do a sync refresh -- we need to be sure that we read fresh data */
ret = __device_refresh_sync();
@@ -164,7 +166,7 @@ static int hdaps_readb_one(unsigned int port, u8 *val)
__device_complete();
out:
- up(&hdaps_sem);
+ mutex_unlock(&hdaps_mtx);
return ret;
}
@@ -199,9 +201,9 @@ static int hdaps_read_pair(unsigned int port1, unsigned int port2,
{
int ret;
- down(&hdaps_sem);
+ mutex_lock(&hdaps_mtx);
ret = __hdaps_read_pair(port1, port2, val1, val2);
- up(&hdaps_sem);
+ mutex_unlock(&hdaps_mtx);
return ret;
}
@@ -214,7 +216,7 @@ static int hdaps_device_init(void)
{
int total, ret = -ENXIO;
- down(&hdaps_sem);
+ mutex_lock(&hdaps_mtx);
outb(0x13, 0x1610);
outb(0x01, 0x161f);
@@ -280,7 +282,7 @@ static int hdaps_device_init(void)
}
out:
- up(&hdaps_sem);
+ mutex_unlock(&hdaps_mtx);
return ret;
}
@@ -314,7 +316,7 @@ static struct platform_driver hdaps_driver = {
};
/*
- * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_sem.
+ * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_mtx.
*/
static void hdaps_calibrate(void)
{
@@ -326,7 +328,7 @@ static void hdaps_mousedev_poll(unsigned long unused)
int x, y;
/* Cannot sleep. Try nonblockingly. If we fail, try again later. */
- if (down_trylock(&hdaps_sem)) {
+ if (mutex_trylock(&hdaps_mtx)) {
mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD);
return;
}
@@ -341,7 +343,7 @@ static void hdaps_mousedev_poll(unsigned long unused)
mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD);
out:
- up(&hdaps_sem);
+ mutex_unlock(&hdaps_mtx);
}
@@ -421,9 +423,9 @@ static ssize_t hdaps_calibrate_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- down(&hdaps_sem);
+ mutex_lock(&hdaps_mtx);
hdaps_calibrate();
- up(&hdaps_sem);
+ mutex_unlock(&hdaps_mtx);
return count;
}
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index b80f6ed..5aab23b 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -166,16 +166,16 @@ static struct vrm_model vrm_models[] = {
{X86_VENDOR_INTEL, 0x6, 0xE, ANY, 14}, /* Intel Core (65 nm) */
{X86_VENDOR_INTEL, 0x6, 0xF, ANY, 110}, /* Intel Conroe */
{X86_VENDOR_INTEL, 0x6, ANY, ANY, 82}, /* any P6 */
- {X86_VENDOR_INTEL, 0x7, ANY, ANY, 0}, /* Itanium */
{X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90}, /* P4 */
{X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90}, /* P4 Willamette */
{X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90}, /* P4 Northwood */
{X86_VENDOR_INTEL, 0xF, ANY, ANY, 100}, /* Prescott and above assume VRD 10 */
- {X86_VENDOR_INTEL, 0x10, ANY, ANY, 0}, /* Itanium 2 */
{X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85}, /* Eden ESP/Ezra */
{X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85}, /* Ezra T */
{X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nemiah */
- {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M */
+ {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M, Eden-N */
+ {X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0}, /* No information */
+ {X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13}, /* C7, Esther */
{X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0} /* stop here */
};
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index 7c65b8b..a40166f 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -24,6 +24,7 @@
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include "lm75.h"
@@ -39,10 +40,12 @@ I2C_CLIENT_INSMOD_1(lm75);
/* Many LM75 constants specified below */
/* The LM75 registers */
-#define LM75_REG_TEMP 0x00
#define LM75_REG_CONF 0x01
-#define LM75_REG_TEMP_HYST 0x02
-#define LM75_REG_TEMP_OS 0x03
+static const u8 LM75_REG_TEMP[3] = {
+ 0x00, /* input */
+ 0x03, /* max */
+ 0x02, /* hyst */
+};
/* Each client has this additional data */
struct lm75_data {
@@ -51,9 +54,10 @@ struct lm75_data {
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
- u16 temp_input; /* Register values */
- u16 temp_max;
- u16 temp_hyst;
+ u16 temp[3]; /* Register values,
+ 0 = input
+ 1 = max
+ 2 = hyst */
};
static int lm75_attach_adapter(struct i2c_adapter *adapter);
@@ -75,35 +79,36 @@ static struct i2c_driver lm75_driver = {
.detach_client = lm75_detach_client,
};
-#define show(value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct lm75_data *data = lm75_update_device(dev); \
- return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->value)); \
+static ssize_t show_temp(struct device *dev, struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct lm75_data *data = lm75_update_device(dev);
+ return sprintf(buf, "%d\n",
+ LM75_TEMP_FROM_REG(data->temp[attr->index]));
}
-show(temp_max);
-show(temp_hyst);
-show(temp_input);
-
-#define set(value, reg) \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct i2c_client *client = to_i2c_client(dev); \
- struct lm75_data *data = i2c_get_clientdata(client); \
- int temp = simple_strtoul(buf, NULL, 10); \
- \
- mutex_lock(&data->update_lock); \
- data->value = LM75_TEMP_TO_REG(temp); \
- lm75_write_value(client, reg, data->value); \
- mutex_unlock(&data->update_lock); \
- return count; \
+
+static ssize_t set_temp(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm75_data *data = i2c_get_clientdata(client);
+ int nr = attr->index;
+ unsigned long temp = simple_strtoul(buf, NULL, 10);
+
+ mutex_lock(&data->update_lock);
+ data->temp[nr] = LM75_TEMP_TO_REG(temp);
+ lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]);
+ mutex_unlock(&data->update_lock);
+ return count;
}
-set(temp_max, LM75_REG_TEMP_OS);
-set(temp_hyst, LM75_REG_TEMP_HYST);
-static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
-static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst);
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
+ show_temp, set_temp, 1);
+static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
+ show_temp, set_temp, 2);
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
static int lm75_attach_adapter(struct i2c_adapter *adapter)
{
@@ -113,9 +118,9 @@ static int lm75_attach_adapter(struct i2c_adapter *adapter)
}
static struct attribute *lm75_attributes[] = {
- &dev_attr_temp1_input.attr,
- &dev_attr_temp1_max.attr,
- &dev_attr_temp1_max_hyst.attr,
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_temp1_max.dev_attr.attr,
+ &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
NULL
};
@@ -283,11 +288,12 @@ static struct lm75_data *lm75_update_device(struct device *dev)
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
+ int i;
dev_dbg(&client->dev, "Starting lm75 update\n");
- data->temp_input = lm75_read_value(client, LM75_REG_TEMP);
- data->temp_max = lm75_read_value(client, LM75_REG_TEMP_OS);
- data->temp_hyst = lm75_read_value(client, LM75_REG_TEMP_HYST);
+ for (i = 0; i < ARRAY_SIZE(data->temp); i++)
+ data->temp[i] = lm75_read_value(client,
+ LM75_REG_TEMP[i]);
data->last_updated = jiffies;
data->valid = 1;
}
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index 886786c..9fb572f 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -2,6 +2,7 @@
lm78.c - Part of lm_sensors, Linux kernel modules for hardware
monitoring
Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
+ Copyright (c) 2007 Jean Delvare <khali@linux-fr.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,13 +24,18 @@
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
-#include <linux/i2c-isa.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
+#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <asm/io.h>
+/* ISA device, if found */
+static struct platform_device *pdev;
+
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24,
0x25, 0x26, 0x27, 0x28, 0x29,
@@ -121,12 +127,8 @@ static inline int TEMP_FROM_REG(s8 val)
a bit - except if there could be more than one SMBus. Groan. No solution
for this yet. */
-/* This module may seem overly long and complicated. In fact, it is not so
- bad. Quite a lot of bookkeeping is done. A real driver can often cut
- some corners. */
-
-/* For each registered chip, we need to keep some data in memory.
- The structure is dynamically allocated. */
+/* For ISA chips, we abuse the i2c_client addr and name fields. We also use
+ the driver field to differentiate between I2C and ISA chips. */
struct lm78_data {
struct i2c_client client;
struct class_device *class_dev;
@@ -152,14 +154,16 @@ struct lm78_data {
static int lm78_attach_adapter(struct i2c_adapter *adapter);
-static int lm78_isa_attach_adapter(struct i2c_adapter *adapter);
static int lm78_detect(struct i2c_adapter *adapter, int address, int kind);
static int lm78_detach_client(struct i2c_client *client);
-static int lm78_read_value(struct i2c_client *client, u8 reg);
-static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value);
+static int __devinit lm78_isa_probe(struct platform_device *pdev);
+static int __devexit lm78_isa_remove(struct platform_device *pdev);
+
+static int lm78_read_value(struct lm78_data *data, u8 reg);
+static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value);
static struct lm78_data *lm78_update_device(struct device *dev);
-static void lm78_init_client(struct i2c_client *client);
+static void lm78_init_device(struct lm78_data *data);
static struct i2c_driver lm78_driver = {
@@ -171,95 +175,78 @@ static struct i2c_driver lm78_driver = {
.detach_client = lm78_detach_client,
};
-static struct i2c_driver lm78_isa_driver = {
+static struct platform_driver lm78_isa_driver = {
.driver = {
.owner = THIS_MODULE,
- .name = "lm78-isa",
+ .name = "lm78",
},
- .attach_adapter = lm78_isa_attach_adapter,
- .detach_client = lm78_detach_client,
+ .probe = lm78_isa_probe,
+ .remove = lm78_isa_remove,
};
/* 7 Voltages */
-static ssize_t show_in(struct device *dev, char *buf, int nr)
+static ssize_t show_in(struct device *dev, struct device_attribute *da,
+ char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct lm78_data *data = lm78_update_device(dev);
- return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr]));
+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in[attr->index]));
}
-static ssize_t show_in_min(struct device *dev, char *buf, int nr)
+static ssize_t show_in_min(struct device *dev, struct device_attribute *da,
+ char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct lm78_data *data = lm78_update_device(dev);
- return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr]));
+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[attr->index]));
}
-static ssize_t show_in_max(struct device *dev, char *buf, int nr)
+static ssize_t show_in_max(struct device *dev, struct device_attribute *da,
+ char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct lm78_data *data = lm78_update_device(dev);
- return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr]));
+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[attr->index]));
}
-static ssize_t set_in_min(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_in_min(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm78_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct lm78_data *data = dev_get_drvdata(dev);
unsigned long val = simple_strtoul(buf, NULL, 10);
+ int nr = attr->index;
mutex_lock(&data->update_lock);
data->in_min[nr] = IN_TO_REG(val);
- lm78_write_value(client, LM78_REG_IN_MIN(nr), data->in_min[nr]);
+ lm78_write_value(data, LM78_REG_IN_MIN(nr), data->in_min[nr]);
mutex_unlock(&data->update_lock);
return count;
}
-static ssize_t set_in_max(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_in_max(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm78_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct lm78_data *data = dev_get_drvdata(dev);
unsigned long val = simple_strtoul(buf, NULL, 10);
+ int nr = attr->index;
mutex_lock(&data->update_lock);
data->in_max[nr] = IN_TO_REG(val);
- lm78_write_value(client, LM78_REG_IN_MAX(nr), data->in_max[nr]);
+ lm78_write_value(data, LM78_REG_IN_MAX(nr), data->in_max[nr]);
mutex_unlock(&data->update_lock);
return count;
}
#define show_in_offset(offset) \
-static ssize_t \
- show_in##offset (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_in(dev, buf, offset); \
-} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
- show_in##offset, NULL); \
-static ssize_t \
- show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_in_min(dev, buf, offset); \
-} \
-static ssize_t \
- show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_in_max(dev, buf, offset); \
-} \
-static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- return set_in_min(dev, buf, count, offset); \
-} \
-static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- return set_in_max(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
- show_in##offset##_min, set_in##offset##_min); \
-static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
- show_in##offset##_max, set_in##offset##_max);
+static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \
+ show_in, NULL, offset); \
+static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
+ show_in_min, set_in_min, offset); \
+static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
+ show_in_max, set_in_max, offset);
show_in_offset(0);
show_in_offset(1);
@@ -270,46 +257,49 @@ show_in_offset(5);
show_in_offset(6);
/* Temperature */
-static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp(struct device *dev, struct device_attribute *da,
+ char *buf)
{
struct lm78_data *data = lm78_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
}
-static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp_over(struct device *dev, struct device_attribute *da,
+ char *buf)
{
struct lm78_data *data = lm78_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
}
-static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_temp_over(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm78_data *data = i2c_get_clientdata(client);
+ struct lm78_data *data = dev_get_drvdata(dev);
long val = simple_strtol(buf, NULL, 10);
mutex_lock(&data->update_lock);
data->temp_over = TEMP_TO_REG(val);
- lm78_write_value(client, LM78_REG_TEMP_OVER, data->temp_over);
+ lm78_write_value(data, LM78_REG_TEMP_OVER, data->temp_over);
mutex_unlock(&data->update_lock);
return count;
}
-static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *da,
+ char *buf)
{
struct lm78_data *data = lm78_update_device(dev);
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst));
}
-static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm78_data *data = i2c_get_clientdata(client);
+ struct lm78_data *data = dev_get_drvdata(dev);
long val = simple_strtol(buf, NULL, 10);
mutex_lock(&data->update_lock);
data->temp_hyst = TEMP_TO_REG(val);
- lm78_write_value(client, LM78_REG_TEMP_HYST, data->temp_hyst);
+ lm78_write_value(data, LM78_REG_TEMP_HYST, data->temp_hyst);
mutex_unlock(&data->update_lock);
return count;
}
@@ -321,49 +311,59 @@ static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
show_temp_hyst, set_temp_hyst);
/* 3 Fans */
-static ssize_t show_fan(struct device *dev, char *buf, int nr)
+static ssize_t show_fan(struct device *dev, struct device_attribute *da,
+ char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct lm78_data *data = lm78_update_device(dev);
+ int nr = attr->index;
return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
DIV_FROM_REG(data->fan_div[nr])) );
}
-static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
+static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
+ char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct lm78_data *data = lm78_update_device(dev);
+ int nr = attr->index;
return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
DIV_FROM_REG(data->fan_div[nr])) );
}
-static ssize_t set_fan_min(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_fan_min(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm78_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct lm78_data *data = dev_get_drvdata(dev);
+ int nr = attr->index;
unsigned long val = simple_strtoul(buf, NULL, 10);
mutex_lock(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
- lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
+ lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
mutex_unlock(&data->update_lock);
return count;
}
-static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
+static ssize_t show_fan_div(struct device *dev, struct device_attribute *da,
+ char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct lm78_data *data = lm78_update_device(dev);
- return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
+ return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index]));
}
/* Note: we save and restore the fan minimum here, because its value is
determined in part by the fan divisor. This follows the principle of
least surprise; the user doesn't expect the fan minimum to change just
because the divisor changed. */
-static ssize_t set_fan_div(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm78_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct lm78_data *data = dev_get_drvdata(dev);
+ int nr = attr->index;
unsigned long val = simple_strtoul(buf, NULL, 10);
unsigned long min;
u8 reg;
@@ -378,13 +378,13 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
case 4: data->fan_div[nr] = 2; break;
case 8: data->fan_div[nr] = 3; break;
default:
- dev_err(&client->dev, "fan_div value %ld not "
+ dev_err(dev, "fan_div value %ld not "
"supported. Choose one of 1, 2, 4 or 8!\n", val);
mutex_unlock(&data->update_lock);
return -EINVAL;
}
- reg = lm78_read_value(client, LM78_REG_VID_FANDIV);
+ reg = lm78_read_value(data, LM78_REG_VID_FANDIV);
switch (nr) {
case 0:
reg = (reg & 0xcf) | (data->fan_div[nr] << 4);
@@ -393,63 +393,36 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
reg = (reg & 0x3f) | (data->fan_div[nr] << 6);
break;
}
- lm78_write_value(client, LM78_REG_VID_FANDIV, reg);
+ lm78_write_value(data, LM78_REG_VID_FANDIV, reg);
data->fan_min[nr] =
FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
- lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
+ lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
mutex_unlock(&data->update_lock);
return count;
}
-#define show_fan_offset(offset) \
-static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_fan(dev, buf, offset - 1); \
-} \
-static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_fan_min(dev, buf, offset - 1); \
-} \
-static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_fan_div(dev, buf, offset - 1); \
-} \
-static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- return set_fan_min(dev, buf, count, offset - 1); \
-} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_min, set_fan_##offset##_min);
-
-static ssize_t set_fan_1_div(struct device *dev, struct device_attribute *attr, const char *buf,
- size_t count)
-{
- return set_fan_div(dev, buf, count, 0) ;
-}
-
-static ssize_t set_fan_2_div(struct device *dev, struct device_attribute *attr, const char *buf,
- size_t count)
-{
- return set_fan_div(dev, buf, count, 1) ;
-}
+#define show_fan_offset(offset) \
+static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
+ show_fan, NULL, offset - 1); \
+static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
+ show_fan_min, set_fan_min, offset - 1);
show_fan_offset(1);
show_fan_offset(2);
show_fan_offset(3);
/* Fan 3 divisor is locked in H/W */
-static DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
- show_fan_1_div, set_fan_1_div);
-static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
- show_fan_2_div, set_fan_2_div);
-static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL);
+static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
+ show_fan_div, set_fan_div, 0);
+static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
+ show_fan_div, set_fan_div, 1);
+static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2);
/* VID */
-static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_vid(struct device *dev, struct device_attribute *da,
+ char *buf)
{
struct lm78_data *data = lm78_update_device(dev);
return sprintf(buf, "%d\n", vid_from_reg(data->vid, 82));
@@ -457,7 +430,8 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
/* Alarms */
-static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *da,
+ char *buf)
{
struct lm78_data *data = lm78_update_device(dev);
return sprintf(buf, "%u\n", data->alarms);
@@ -475,45 +449,40 @@ static int lm78_attach_adapter(struct i2c_adapter *adapter)
return i2c_probe(adapter, &addr_data, lm78_detect);
}
-static int lm78_isa_attach_adapter(struct i2c_adapter *adapter)
-{
- return lm78_detect(adapter, isa_address, -1);
-}
-
static struct attribute *lm78_attributes[] = {
- &dev_attr_in0_input.attr,
- &dev_attr_in0_min.attr,
- &dev_attr_in0_max.attr,
- &dev_attr_in1_input.attr,
- &dev_attr_in1_min.attr,
- &dev_attr_in1_max.attr,
- &dev_attr_in2_input.attr,
- &dev_attr_in2_min.attr,
- &dev_attr_in2_max.attr,
- &dev_attr_in3_input.attr,
- &dev_attr_in3_min.attr,
- &dev_attr_in3_max.attr,
- &dev_attr_in4_input.attr,
- &dev_attr_in4_min.attr,
- &dev_attr_in4_max.attr,
- &dev_attr_in5_input.attr,
- &dev_attr_in5_min.attr,
- &dev_attr_in5_max.attr,
- &dev_attr_in6_input.attr,
- &dev_attr_in6_min.attr,
- &dev_attr_in6_max.attr,
+ &sensor_dev_attr_in0_input.dev_attr.attr,
+ &sensor_dev_attr_in0_min.dev_attr.attr,
+ &sensor_dev_attr_in0_max.dev_attr.attr,
+ &sensor_dev_attr_in1_input.dev_attr.attr,
+ &sensor_dev_attr_in1_min.dev_attr.attr,
+ &sensor_dev_attr_in1_max.dev_attr.attr,
+ &sensor_dev_attr_in2_input.dev_attr.attr,
+ &sensor_dev_attr_in2_min.dev_attr.attr,
+ &sensor_dev_attr_in2_max.dev_attr.attr,
+ &sensor_dev_attr_in3_input.dev_attr.attr,
+ &sensor_dev_attr_in3_min.dev_attr.attr,
+ &sensor_dev_attr_in3_max.dev_attr.attr,
+ &sensor_dev_attr_in4_input.dev_attr.attr,
+ &sensor_dev_attr_in4_min.dev_attr.attr,
+ &sensor_dev_attr_in4_max.dev_attr.attr,
+ &sensor_dev_attr_in5_input.dev_attr.attr,
+ &sensor_dev_attr_in5_min.dev_attr.attr,
+ &sensor_dev_attr_in5_max.dev_attr.attr,
+ &sensor_dev_attr_in6_input.dev_attr.attr,
+ &sensor_dev_attr_in6_min.dev_attr.attr,
+ &sensor_dev_attr_in6_max.dev_attr.attr,
&dev_attr_temp1_input.attr,
&dev_attr_temp1_max.attr,
&dev_attr_temp1_max_hyst.attr,
- &dev_attr_fan1_input.attr,
- &dev_attr_fan1_min.attr,
- &dev_attr_fan1_div.attr,
- &dev_attr_fan2_input.attr,
- &dev_attr_fan2_min.attr,
- &dev_attr_fan2_div.attr,
- &dev_attr_fan3_input.attr,
- &dev_attr_fan3_min.attr,
- &dev_attr_fan3_div.attr,
+ &sensor_dev_attr_fan1_input.dev_attr.attr,
+ &sensor_dev_attr_fan1_min.dev_attr.attr,
+ &sensor_dev_attr_fan1_div.dev_attr.attr,
+ &sensor_dev_attr_fan2_input.dev_attr.attr,
+ &sensor_dev_attr_fan2_min.dev_attr.attr,
+ &sensor_dev_attr_fan2_div.dev_attr.attr,
+ &sensor_dev_attr_fan3_input.dev_attr.attr,
+ &sensor_dev_attr_fan3_min.dev_attr.attr,
+ &sensor_dev_attr_fan3_div.dev_attr.attr,
&dev_attr_alarms.attr,
&dev_attr_cpu0_vid.attr,
@@ -524,6 +493,17 @@ static const struct attribute_group lm78_group = {
.attrs = lm78_attributes,
};
+/* I2C devices get this name attribute automatically, but for ISA devices
+ we must create it by ourselves. */
+static ssize_t show_name(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ struct lm78_data *data = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%s\n", data->client.name);
+}
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
/* This function is called by i2c_probe */
static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
{
@@ -531,54 +511,10 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
struct i2c_client *new_client;
struct lm78_data *data;
const char *client_name = "";
- int is_isa = i2c_is_isa_adapter(adapter);
- if (!is_isa &&
- !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
err = -ENODEV;
- goto ERROR0;
- }
-
- /* Reserve the ISA region */
- if (is_isa)
- if (!request_region(address, LM78_EXTENT,
- lm78_isa_driver.driver.name)) {
- err = -EBUSY;
- goto ERROR0;
- }
-
- /* Probe whether there is anything available on this address. Already
- done for SMBus clients */
- if (kind < 0) {
- if (is_isa) {
-
-#define REALLY_SLOW_IO
- /* We need the timeouts for at least some LM78-like
- chips. But only if we read 'undefined' registers. */
- i = inb_p(address + 1);
- if (inb_p(address + 2) != i) {
- err = -ENODEV;
- goto ERROR1;
- }
- if (inb_p(address + 3) != i) {
- err = -ENODEV;
- goto ERROR1;
- }
- if (inb_p(address + 7) != i) {
- err = -ENODEV;
- goto ERROR1;
- }
-#undef REALLY_SLOW_IO
-
- /* Let's just hope nothing breaks here */
- i = inb_p(address + 5) & 0x7f;
- outb_p(~i & 0x7f, address + 5);
- if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
- outb_p(i, address + 5);
- err = -ENODEV;
- goto ERROR1;
- }
- }
+ goto ERROR1;
}
/* OK. For now, we presume we have a valid client. We now create the
@@ -591,22 +527,19 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
}
new_client = &data->client;
- if (is_isa)
- mutex_init(&data->lock);
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
- new_client->driver = is_isa ? &lm78_isa_driver : &lm78_driver;
- new_client->flags = 0;
+ new_client->driver = &lm78_driver;
/* Now, we do the remaining detection. */
if (kind < 0) {
- if (lm78_read_value(new_client, LM78_REG_CONFIG) & 0x80) {
+ if (lm78_read_value(data, LM78_REG_CONFIG) & 0x80) {
err = -ENODEV;
goto ERROR2;
}
- if (!is_isa && (lm78_read_value(
- new_client, LM78_REG_I2C_ADDR) != address)) {
+ if (lm78_read_value(data, LM78_REG_I2C_ADDR) !=
+ address) {
err = -ENODEV;
goto ERROR2;
}
@@ -614,7 +547,7 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
/* Determine the chip type. */
if (kind <= 0) {
- i = lm78_read_value(new_client, LM78_REG_CHIPID);
+ i = lm78_read_value(data, LM78_REG_CHIPID);
if (i == 0x00 || i == 0x20 /* LM78 */
|| i == 0x40) /* LM78-J */
kind = lm78;
@@ -641,21 +574,12 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
data->type = kind;
- data->valid = 0;
- mutex_init(&data->update_lock);
-
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto ERROR2;
/* Initialize the LM78 chip */
- lm78_init_client(new_client);
-
- /* A few vars need to be filled upon startup */
- for (i = 0; i < 3; i++) {
- data->fan_min[i] = lm78_read_value(new_client,
- LM78_REG_FAN_MIN(i));
- }
+ lm78_init_device(data);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&new_client->dev.kobj, &lm78_group)))
@@ -676,9 +600,6 @@ ERROR3:
ERROR2:
kfree(data);
ERROR1:
- if (is_isa)
- release_region(address, LM78_EXTENT);
-ERROR0:
return err;
}
@@ -693,9 +614,77 @@ static int lm78_detach_client(struct i2c_client *client)
if ((err = i2c_detach_client(client)))
return err;
- if(i2c_is_isa_client(client))
- release_region(client->addr, LM78_EXTENT);
+ kfree(data);
+
+ return 0;
+}
+
+static int __devinit lm78_isa_probe(struct platform_device *pdev)
+{
+ int err;
+ struct lm78_data *data;
+ struct resource *res;
+ const char *name;
+
+ /* Reserve the ISA region */
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!request_region(res->start, LM78_EXTENT, "lm78")) {
+ err = -EBUSY;
+ goto exit;
+ }
+
+ if (!(data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto exit_release_region;
+ }
+ mutex_init(&data->lock);
+ data->client.addr = res->start;
+ i2c_set_clientdata(&data->client, data);
+ platform_set_drvdata(pdev, data);
+
+ if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) {
+ data->type = lm79;
+ name = "lm79";
+ } else {
+ data->type = lm78;
+ name = "lm78";
+ }
+ strlcpy(data->client.name, name, I2C_NAME_SIZE);
+
+ /* Initialize the LM78 chip */
+ lm78_init_device(data);
+
+ /* Register sysfs hooks */
+ if ((err = sysfs_create_group(&pdev->dev.kobj, &lm78_group))
+ || (err = device_create_file(&pdev->dev, &dev_attr_name)))
+ goto exit_remove_files;
+
+ data->class_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(data->class_dev)) {
+ err = PTR_ERR(data->class_dev);
+ goto exit_remove_files;
+ }
+
+ return 0;
+
+ exit_remove_files:
+ sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
+ device_remove_file(&pdev->dev, &dev_attr_name);
+ kfree(data);
+ exit_release_region:
+ release_region(res->start, LM78_EXTENT);
+ exit:
+ return err;
+}
+
+static int __devexit lm78_isa_remove(struct platform_device *pdev)
+{
+ struct lm78_data *data = platform_get_drvdata(pdev);
+ hwmon_device_unregister(data->class_dev);
+ sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
+ device_remove_file(&pdev->dev, &dev_attr_name);
+ release_region(data->client.addr, LM78_EXTENT);
kfree(data);
return 0;
@@ -706,11 +695,12 @@ static int lm78_detach_client(struct i2c_client *client)
separately.
We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
would slow down the LM78 access and should not be necessary. */
-static int lm78_read_value(struct i2c_client *client, u8 reg)
+static int lm78_read_value(struct lm78_data *data, u8 reg)
{
- int res;
- if (i2c_is_isa_client(client)) {
- struct lm78_data *data = i2c_get_clientdata(client);
+ struct i2c_client *client = &data->client;
+
+ if (!client->driver) { /* ISA device */
+ int res;
mutex_lock(&data->lock);
outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET);
res = inb_p(client->addr + LM78_DATA_REG_OFFSET);
@@ -727,10 +717,11 @@ static int lm78_read_value(struct i2c_client *client, u8 reg)
would slow down the LM78 access and should not be necessary.
There are some ugly typecasts here, but the good new is - they should
nowhere else be necessary! */
-static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value)
+static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value)
{
- if (i2c_is_isa_client(client)) {
- struct lm78_data *data = i2c_get_clientdata(client);
+ struct i2c_client *client = &data->client;
+
+ if (!client->driver) { /* ISA device */
mutex_lock(&data->lock);
outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET);
outb_p(value, client->addr + LM78_DATA_REG_OFFSET);
@@ -740,20 +731,29 @@ static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value)
return i2c_smbus_write_byte_data(client, reg, value);
}
-static void lm78_init_client(struct i2c_client *client)
+static void lm78_init_device(struct lm78_data *data)
{
- u8 config = lm78_read_value(client, LM78_REG_CONFIG);
+ u8 config;
+ int i;
/* Start monitoring */
- if (!(config & 0x01))
- lm78_write_value(client, LM78_REG_CONFIG,
+ config = lm78_read_value(data, LM78_REG_CONFIG);
+ if ((config & 0x09) != 0x01)
+ lm78_write_value(data, LM78_REG_CONFIG,
(config & 0xf7) | 0x01);
+
+ /* A few vars need to be filled upon startup */
+ for (i = 0; i < 3; i++) {
+ data->fan_min[i] = lm78_read_value(data,
+ LM78_REG_FAN_MIN(i));
+ }
+
+ mutex_init(&data->update_lock);
}
static struct lm78_data *lm78_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct lm78_data *data = i2c_get_clientdata(client);
+ struct lm78_data *data = dev_get_drvdata(dev);
int i;
mutex_lock(&data->update_lock);
@@ -761,39 +761,39 @@ static struct lm78_data *lm78_update_device(struct device *dev)
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
- dev_dbg(&client->dev, "Starting lm78 update\n");
+ dev_dbg(dev, "Starting lm78 update\n");
for (i = 0; i <= 6; i++) {
data->in[i] =
- lm78_read_value(client, LM78_REG_IN(i));
+ lm78_read_value(data, LM78_REG_IN(i));
data->in_min[i] =
- lm78_read_value(client, LM78_REG_IN_MIN(i));
+ lm78_read_value(data, LM78_REG_IN_MIN(i));
data->in_max[i] =
- lm78_read_value(client, LM78_REG_IN_MAX(i));
+ lm78_read_value(data, LM78_REG_IN_MAX(i));
}
for (i = 0; i < 3; i++) {
data->fan[i] =
- lm78_read_value(client, LM78_REG_FAN(i));
+ lm78_read_value(data, LM78_REG_FAN(i));
data->fan_min[i] =
- lm78_read_value(client, LM78_REG_FAN_MIN(i));
+ lm78_read_value(data, LM78_REG_FAN_MIN(i));
}
- data->temp = lm78_read_value(client, LM78_REG_TEMP);
+ data->temp = lm78_read_value(data, LM78_REG_TEMP);
data->temp_over =
- lm78_read_value(client, LM78_REG_TEMP_OVER);
+ lm78_read_value(data, LM78_REG_TEMP_OVER);
data->temp_hyst =
- lm78_read_value(client, LM78_REG_TEMP_HYST);
- i = lm78_read_value(client, LM78_REG_VID_FANDIV);
+ lm78_read_value(data, LM78_REG_TEMP_HYST);
+ i = lm78_read_value(data, LM78_REG_VID_FANDIV);
data->vid = i & 0x0f;
if (data->type == lm79)
data->vid |=
- (lm78_read_value(client, LM78_REG_CHIPID) &
+ (lm78_read_value(data, LM78_REG_CHIPID) &
0x01) << 4;
else
data->vid |= 0x10;
data->fan_div[0] = (i >> 4) & 0x03;
data->fan_div[1] = i >> 6;
- data->alarms = lm78_read_value(client, LM78_REG_ALARM1) +
- (lm78_read_value(client, LM78_REG_ALARM2) << 8);
+ data->alarms = lm78_read_value(data, LM78_REG_ALARM1) +
+ (lm78_read_value(data, LM78_REG_ALARM2) << 8);
data->last_updated = jiffies;
data->valid = 1;
@@ -805,26 +805,154 @@ static struct lm78_data *lm78_update_device(struct device *dev)
return data;
}
+/* return 1 if a supported chip is found, 0 otherwise */
+static int __init lm78_isa_found(unsigned short address)
+{
+ int val, save, found = 0;
+
+ if (!request_region(address, LM78_EXTENT, "lm78"))
+ return 0;
+
+#define REALLY_SLOW_IO
+ /* We need the timeouts for at least some LM78-like
+ chips. But only if we read 'undefined' registers. */
+ val = inb_p(address + 1);
+ if (inb_p(address + 2) != val
+ || inb_p(address + 3) != val
+ || inb_p(address + 7) != val)
+ goto release;
+#undef REALLY_SLOW_IO
+
+ /* We should be able to change the 7 LSB of the address port. The
+ MSB (busy flag) should be clear initially, set after the write. */
+ save = inb_p(address + LM78_ADDR_REG_OFFSET);
+ if (save & 0x80)
+ goto release;
+ val = ~save & 0x7f;
+ outb_p(val, address + LM78_ADDR_REG_OFFSET);
+ if (inb_p(address + LM78_ADDR_REG_OFFSET) != (val | 0x80)) {
+ outb_p(save, address + LM78_ADDR_REG_OFFSET);
+ goto release;
+ }
+
+ /* We found a device, now see if it could be an LM78 */
+ outb_p(LM78_REG_CONFIG, address + LM78_ADDR_REG_OFFSET);
+ val = inb_p(address + LM78_DATA_REG_OFFSET);
+ if (val & 0x80)
+ goto release;
+ outb_p(LM78_REG_I2C_ADDR, address + LM78_ADDR_REG_OFFSET);
+ val = inb_p(address + LM78_DATA_REG_OFFSET);
+ if (val < 0x03 || val > 0x77) /* Not a valid I2C address */
+ goto release;
+
+ /* The busy flag should be clear again */
+ if (inb_p(address + LM78_ADDR_REG_OFFSET) & 0x80)
+ goto release;
+
+ /* Explicitly prevent the misdetection of Winbond chips */
+ outb_p(0x4f, address + LM78_ADDR_REG_OFFSET);
+ val = inb_p(address + LM78_DATA_REG_OFFSET);
+ if (val == 0xa3 || val == 0x5c)
+ goto release;
+
+ /* Explicitly prevent the misdetection of ITE chips */
+ outb_p(0x58, address + LM78_ADDR_REG_OFFSET);
+ val = inb_p(address + LM78_DATA_REG_OFFSET);
+ if (val == 0x90)
+ goto release;
+
+ /* Determine the chip type */
+ outb_p(LM78_REG_CHIPID, address + LM78_ADDR_REG_OFFSET);
+ val = inb_p(address + LM78_DATA_REG_OFFSET);
+ if (val == 0x00 /* LM78 */
+ || val == 0x40 /* LM78-J */
+ || (val & 0xfe) == 0xc0) /* LM79 */
+ found = 1;
+
+ if (found)
+ pr_info("lm78: Found an %s chip at %#x\n",
+ val & 0x80 ? "LM79" : "LM78", (int)address);
+
+ release:
+ release_region(address, LM78_EXTENT);
+ return found;
+}
+
+static int __init lm78_isa_device_add(unsigned short address)
+{
+ struct resource res = {
+ .start = address,
+ .end = address + LM78_EXTENT,
+ .name = "lm78",
+ .flags = IORESOURCE_IO,
+ };
+ int err;
+
+ pdev = platform_device_alloc("lm78", address);
+ if (!pdev) {
+ err = -ENOMEM;
+ printk(KERN_ERR "lm78: Device allocation failed\n");
+ goto exit;
+ }
+
+ err = platform_device_add_resources(pdev, &res, 1);
+ if (err) {
+ printk(KERN_ERR "lm78: Device resource addition failed "
+ "(%d)\n", err);
+ goto exit_device_put;
+ }
+
+ err = platform_device_add(pdev);
+ if (err) {
+ printk(KERN_ERR "lm78: Device addition failed (%d)\n",
+ err);
+ goto exit_device_put;
+ }
+
+ return 0;
+
+ exit_device_put:
+ platform_device_put(pdev);
+ exit:
+ pdev = NULL;
+ return err;
+}
+
static int __init sm_lm78_init(void)
{
int res;
res = i2c_add_driver(&lm78_driver);
if (res)
- return res;
+ goto exit;
- /* Don't exit if this one fails, we still want the I2C variants
- to work! */
- if (i2c_isa_add_driver(&lm78_isa_driver))
- isa_address = 0;
+ if (lm78_isa_found(isa_address)) {
+ res = platform_driver_register(&lm78_isa_driver);
+ if (res)
+ goto exit_unreg_i2c_driver;
+
+ /* Sets global pdev as a side effect */
+ res = lm78_isa_device_add(isa_address);
+ if (res)
+ goto exit_unreg_isa_driver;
+ }
return 0;
+
+ exit_unreg_isa_driver:
+ platform_driver_unregister(&lm78_isa_driver);
+ exit_unreg_i2c_driver:
+ i2c_del_driver(&lm78_driver);
+ exit:
+ return res;
}
static void __exit sm_lm78_exit(void)
{
- if (isa_address)
- i2c_isa_del_driver(&lm78_isa_driver);
+ if (pdev) {
+ platform_device_unregister(pdev);
+ platform_driver_unregister(&lm78_isa_driver);
+ }
i2c_del_driver(&lm78_driver);
}
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c
index 3ce8254..988ae1c 100644
--- a/drivers/hwmon/lm87.c
+++ b/drivers/hwmon/lm87.c
@@ -747,6 +747,7 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
}
if (!(data->channel & CHAN_NO_VID)) {
+ data->vrm = vid_which_vrm();
if ((err = device_create_file(&new_client->dev,
&dev_attr_cpu0_vid))
|| (err = device_create_file(&new_client->dev,
@@ -779,7 +780,6 @@ static void lm87_init_client(struct i2c_client *client)
u8 config;
data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE);
- data->vrm = vid_which_vrm();
config = lm87_read_value(client, LM87_REG_CONFIG);
if (!(config & 0x01)) {
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c
new file mode 100644
index 0000000..8415664
--- /dev/null
+++ b/drivers/hwmon/max6650.c
@@ -0,0 +1,693 @@
+/*
+ * max6650.c - Part of lm_sensors, Linux kernel modules for hardware
+ * monitoring.
+ *
+ * (C) 2007 by Hans J. Koch <hjk@linutronix.de>
+ *
+ * based on code written by John Morris <john.morris@spirentcom.com>
+ * Copyright (c) 2003 Spirent Communications
+ * and Claus Gindhart <claus.gindhart@kontron.com>
+ *
+ * This module has only been tested with the MAX6650 chip. It should
+ * also work with the MAX6651. It does not distinguish max6650 and max6651
+ * chips.
+ *
+ * Tha datasheet was last seen at:
+ *
+ * http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+
+/*
+ * Addresses to scan. There are four disjoint possibilities, by pin config.
+ */
+
+static unsigned short normal_i2c[] = {0x1b, 0x1f, 0x48, 0x4b, I2C_CLIENT_END};
+
+/*
+ * Insmod parameters
+ */
+
+/* fan_voltage: 5=5V fan, 12=12V fan, 0=don't change */
+static int fan_voltage;
+/* prescaler: Possible values are 1, 2, 4, 8, 16 or 0 for don't change */
+static int prescaler;
+/* clock: The clock frequency of the chip the driver should assume */
+static int clock = 254000;
+
+module_param(fan_voltage, int, S_IRUGO);
+module_param(prescaler, int, S_IRUGO);
+module_param(clock, int, S_IRUGO);
+
+I2C_CLIENT_INSMOD_1(max6650);
+
+/*
+ * MAX 6650/6651 registers
+ */
+
+#define MAX6650_REG_SPEED 0x00
+#define MAX6650_REG_CONFIG 0x02
+#define MAX6650_REG_GPIO_DEF 0x04
+#define MAX6650_REG_DAC 0x06
+#define MAX6650_REG_ALARM_EN 0x08
+#define MAX6650_REG_ALARM 0x0A
+#define MAX6650_REG_TACH0 0x0C
+#define MAX6650_REG_TACH1 0x0E
+#define MAX6650_REG_TACH2 0x10
+#define MAX6650_REG_TACH3 0x12
+#define MAX6650_REG_GPIO_STAT 0x14
+#define MAX6650_REG_COUNT 0x16
+
+/*
+ * Config register bits
+ */
+
+#define MAX6650_CFG_V12 0x08
+#define MAX6650_CFG_PRESCALER_MASK 0x07
+#define MAX6650_CFG_PRESCALER_2 0x01
+#define MAX6650_CFG_PRESCALER_4 0x02
+#define MAX6650_CFG_PRESCALER_8 0x03
+#define MAX6650_CFG_PRESCALER_16 0x04
+#define MAX6650_CFG_MODE_MASK 0x30
+#define MAX6650_CFG_MODE_ON 0x00
+#define MAX6650_CFG_MODE_OFF 0x10
+#define MAX6650_CFG_MODE_CLOSED_LOOP 0x20
+#define MAX6650_CFG_MODE_OPEN_LOOP 0x30
+#define MAX6650_COUNT_MASK 0x03
+
+/* Minimum and maximum values of the FAN-RPM */
+#define FAN_RPM_MIN 240
+#define FAN_RPM_MAX 30000
+
+#define DIV_FROM_REG(reg) (1 << (reg & 7))
+
+static int max6650_attach_adapter(struct i2c_adapter *adapter);
+static int max6650_detect(struct i2c_adapter *adapter, int address, int kind);
+static int max6650_init_client(struct i2c_client *client);
+static int max6650_detach_client(struct i2c_client *client);
+static struct max6650_data *max6650_update_device(struct device *dev);
+
+/*
+ * Driver data (common to all clients)
+ */
+
+static struct i2c_driver max6650_driver = {
+ .driver = {
+ .name = "max6650",
+ },
+ .attach_adapter = max6650_attach_adapter,
+ .detach_client = max6650_detach_client,
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct max6650_data
+{
+ struct i2c_client client;
+ struct class_device *class_dev;
+ struct mutex update_lock;
+ char valid; /* zero until following fields are valid */
+ unsigned long last_updated; /* in jiffies */
+
+ /* register values */
+ u8 speed;
+ u8 config;
+ u8 tach[4];
+ u8 count;
+ u8 dac;
+};
+
+static ssize_t get_fan(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct max6650_data *data = max6650_update_device(dev);
+ int rpm;
+
+ /*
+ * Calculation details:
+ *
+ * Each tachometer counts over an interval given by the "count"
+ * register (0.25, 0.5, 1 or 2 seconds). This module assumes
+ * that the fans produce two pulses per revolution (this seems
+ * to be the most common).
+ */
+
+ rpm = ((data->tach[attr->index] * 120) / DIV_FROM_REG(data->count));
+ return sprintf(buf, "%d\n", rpm);
+}
+
+/*
+ * Set the fan speed to the specified RPM (or read back the RPM setting).
+ * This works in closed loop mode only. Use pwm1 for open loop speed setting.
+ *
+ * The MAX6650/1 will automatically control fan speed when in closed loop
+ * mode.
+ *
+ * Assumptions:
+ *
+ * 1) The MAX6650/1 internal 254kHz clock frequency is set correctly. Use
+ * the clock module parameter if you need to fine tune this.
+ *
+ * 2) The prescaler (low three bits of the config register) has already
+ * been set to an appropriate value. Use the prescaler module parameter
+ * if your BIOS doesn't initialize the chip properly.
+ *
+ * The relevant equations are given on pages 21 and 22 of the datasheet.
+ *
+ * From the datasheet, the relevant equation when in regulation is:
+ *
+ * [fCLK / (128 x (KTACH + 1))] = 2 x FanSpeed / KSCALE
+ *
+ * where:
+ *
+ * fCLK is the oscillator frequency (either the 254kHz internal
+ * oscillator or the externally applied clock)
+ *
+ * KTACH is the value in the speed register
+ *
+ * FanSpeed is the speed of the fan in rps
+ *
+ * KSCALE is the prescaler value (1, 2, 4, 8, or 16)
+ *
+ * When reading, we need to solve for FanSpeed. When writing, we need to
+ * solve for KTACH.
+ *
+ * Note: this tachometer is completely separate from the tachometers
+ * used to measure the fan speeds. Only one fan's speed (fan1) is
+ * controlled.
+ */
+
+static ssize_t get_target(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct max6650_data *data = max6650_update_device(dev);
+ int kscale, ktach, rpm;
+
+ /*
+ * Use the datasheet equation:
+ *
+ * FanSpeed = KSCALE x fCLK / [256 x (KTACH + 1)]
+ *
+ * then multiply by 60 to give rpm.
+ */
+
+ kscale = DIV_FROM_REG(data->config);
+ ktach = data->speed;
+ rpm = 60 * kscale * clock / (256 * (ktach + 1));
+ return sprintf(buf, "%d\n", rpm);
+}
+
+static ssize_t set_target(struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct max6650_data *data = i2c_get_clientdata(client);
+ int rpm = simple_strtoul(buf, NULL, 10);
+ int kscale, ktach;
+
+ rpm = SENSORS_LIMIT(rpm, FAN_RPM_MIN, FAN_RPM_MAX);
+
+ /*
+ * Divide the required speed by 60 to get from rpm to rps, then
+ * use the datasheet equation:
+ *
+ * KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1
+ */
+
+ mutex_lock(&data->update_lock);
+
+ kscale = DIV_FROM_REG(data->config);
+ ktach = ((clock * kscale) / (256 * rpm / 60)) - 1;
+ if (ktach < 0)
+ ktach = 0;
+ if (ktach > 255)
+ ktach = 255;
+ data->speed = ktach;
+
+ i2c_smbus_write_byte_data(client, MAX6650_REG_SPEED, data->speed);
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+/*
+ * Get/set the fan speed in open loop mode using pwm1 sysfs file.
+ * Speed is given as a relative value from 0 to 255, where 255 is maximum
+ * speed. Note that this is done by writing directly to the chip's DAC,
+ * it won't change the closed loop speed set by fan1_target.
+ * Also note that due to rounding errors it is possible that you don't read
+ * back exactly the value you have set.
+ */
+
+static ssize_t get_pwm(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ int pwm;
+ struct max6650_data *data = max6650_update_device(dev);
+
+ /* Useful range for dac is 0-180 for 12V fans and 0-76 for 5V fans.
+ Lower DAC values mean higher speeds. */
+ if (data->config & MAX6650_CFG_V12)
+ pwm = 255 - (255 * (int)data->dac)/180;
+ else
+ pwm = 255 - (255 * (int)data->dac)/76;
+
+ if (pwm < 0)
+ pwm = 0;
+
+ return sprintf(buf, "%d\n", pwm);
+}
+
+static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct max6650_data *data = i2c_get_clientdata(client);
+ int pwm = simple_strtoul(buf, NULL, 10);
+
+ pwm = SENSORS_LIMIT(pwm, 0, 255);
+
+ mutex_lock(&data->update_lock);
+
+ if (data->config & MAX6650_CFG_V12)
+ data->dac = 180 - (180 * pwm)/255;
+ else
+ data->dac = 76 - (76 * pwm)/255;
+
+ i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, data->dac);
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+/*
+ * Get/Set controller mode:
+ * Possible values:
+ * 0 = Fan always on
+ * 1 = Open loop, Voltage is set according to speed, not regulated.
+ * 2 = Closed loop, RPM for all fans regulated by fan1 tachometer
+ */
+
+static ssize_t get_enable(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct max6650_data *data = max6650_update_device(dev);
+ int mode = (data->config & MAX6650_CFG_MODE_MASK) >> 4;
+ int sysfs_modes[4] = {0, 1, 2, 1};
+
+ return sprintf(buf, "%d\n", sysfs_modes[mode]);
+}
+
+static ssize_t set_enable(struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct max6650_data *data = i2c_get_clientdata(client);
+ int mode = simple_strtoul(buf, NULL, 10);
+ int max6650_modes[3] = {0, 3, 2};
+
+ if ((mode < 0)||(mode > 2)) {
+ dev_err(&client->dev,
+ "illegal value for pwm1_enable (%d)\n", mode);
+ return -EINVAL;
+ }
+
+ mutex_lock(&data->update_lock);
+
+ data->config = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG);
+ data->config = (data->config & ~MAX6650_CFG_MODE_MASK)
+ | (max6650_modes[mode] << 4);
+
+ i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, data->config);
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+/*
+ * Read/write functions for fan1_div sysfs file. The MAX6650 has no such
+ * divider. We handle this by converting between divider and counttime:
+ *
+ * (counttime == k) <==> (divider == 2^k), k = 0, 1, 2, or 3
+ *
+ * Lower values of k allow to connect a faster fan without the risk of
+ * counter overflow. The price is lower resolution. You can also set counttime
+ * using the module parameter. Note that the module parameter "prescaler" also
+ * influences the behaviour. Unfortunately, there's no sysfs attribute
+ * defined for that. See the data sheet for details.
+ */
+
+static ssize_t get_div(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct max6650_data *data = max6650_update_device(dev);
+
+ return sprintf(buf, "%d\n", DIV_FROM_REG(data->count));
+}
+
+static ssize_t set_div(struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct max6650_data *data = i2c_get_clientdata(client);
+ int div = simple_strtoul(buf, NULL, 10);
+
+ mutex_lock(&data->update_lock);
+ switch (div) {
+ case 1:
+ data->count = 0;
+ break;
+ case 2:
+ data->count = 1;
+ break;
+ case 4:
+ data->count = 2;
+ break;
+ case 8:
+ data->count = 3;
+ break;
+ default:
+ dev_err(&client->dev,
+ "illegal value for fan divider (%d)\n", div);
+ return -EINVAL;
+ }
+
+ i2c_smbus_write_byte_data(client, MAX6650_REG_COUNT, data->count);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, get_fan, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, get_fan, NULL, 3);
+static DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, get_target, set_target);
+static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_div, set_div);
+static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, get_enable, set_enable);
+static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm);
+
+
+static struct attribute *max6650_attrs[] = {
+ &sensor_dev_attr_fan1_input.dev_attr.attr,
+ &sensor_dev_attr_fan2_input.dev_attr.attr,
+ &sensor_dev_attr_fan3_input.dev_attr.attr,
+ &sensor_dev_attr_fan4_input.dev_attr.attr,
+ &dev_attr_fan1_target.attr,
+ &dev_attr_fan1_div.attr,
+ &dev_attr_pwm1_enable.attr,
+ &dev_attr_pwm1.attr,
+ NULL
+};
+
+static struct attribute_group max6650_attr_grp = {
+ .attrs = max6650_attrs,
+};
+
+/*
+ * Real code
+ */
+
+static int max6650_attach_adapter(struct i2c_adapter *adapter)
+{
+ if (!(adapter->class & I2C_CLASS_HWMON)) {
+ dev_dbg(&adapter->dev,
+ "FATAL: max6650_attach_adapter class HWMON not set\n");
+ return 0;
+ }
+
+ return i2c_probe(adapter, &addr_data, max6650_detect);
+}
+
+/*
+ * The following function does more than just detection. If detection
+ * succeeds, it also registers the new chip.
+ */
+
+static int max6650_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+ struct i2c_client *client;
+ struct max6650_data *data;
+ int err = -ENODEV;
+
+ dev_dbg(&adapter->dev, "max6650_detect called, kind = %d\n", kind);
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+ dev_dbg(&adapter->dev, "max6650: I2C bus doesn't support "
+ "byte read mode, skipping.\n");
+ return 0;
+ }
+
+ if (!(data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL))) {
+ dev_err(&adapter->dev, "max6650: out of memory.\n");
+ return -ENOMEM;
+ }
+
+ client = &data->client;
+ i2c_set_clientdata(client, data);
+ client->addr = address;
+ client->adapter = adapter;
+ client->driver = &max6650_driver;
+
+ /*
+ * Now we do the remaining detection. A negative kind means that
+ * the driver was loaded with no force parameter (default), so we
+ * must both detect and identify the chip (actually there is only
+ * one possible kind of chip for now, max6650). A zero kind means that
+ * the driver was loaded with the force parameter, the detection
+ * step shall be skipped. A positive kind means that the driver
+ * was loaded with the force parameter and a given kind of chip is
+ * requested, so both the detection and the identification steps
+ * are skipped.
+ *
+ * Currently I can find no way to distinguish between a MAX6650 and
+ * a MAX6651. This driver has only been tried on the former.
+ */
+
+ if ((kind < 0) &&
+ ( (i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG) & 0xC0)
+ ||(i2c_smbus_read_byte_data(client, MAX6650_REG_GPIO_STAT) & 0xE0)
+ ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN) & 0xE0)
+ ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM) & 0xE0)
+ ||(i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT) & 0xFC))) {
+ dev_dbg(&adapter->dev,
+ "max6650: detection failed at 0x%02x.\n", address);
+ goto err_free;
+ }
+
+ dev_info(&adapter->dev, "max6650: chip found at 0x%02x.\n", address);
+
+ strlcpy(client->name, "max6650", I2C_NAME_SIZE);
+ mutex_init(&data->update_lock);
+
+ if ((err = i2c_attach_client(client))) {
+ dev_err(&adapter->dev, "max6650: failed to attach client.\n");
+ goto err_free;
+ }
+
+ /*
+ * Initialize the max6650 chip
+ */
+ if (max6650_init_client(client))
+ goto err_detach;
+
+ err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp);
+ if (err)
+ goto err_detach;
+
+ data->class_dev = hwmon_device_register(&client->dev);
+ if (!IS_ERR(data->class_dev))
+ return 0;
+
+ err = PTR_ERR(data->class_dev);
+ dev_err(&client->dev, "error registering hwmon device.\n");
+ sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp);
+err_detach:
+ i2c_detach_client(client);
+err_free:
+ kfree(data);
+ return err;
+}
+
+static int max6650_detach_client(struct i2c_client *client)
+{
+ struct max6650_data *data = i2c_get_clientdata(client);
+ int err;
+
+ sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp);
+ hwmon_device_unregister(data->class_dev);
+ err = i2c_detach_client(client);
+ if (!err)
+ kfree(data);
+ return err;
+}
+
+static int max6650_init_client(struct i2c_client *client)
+{
+ struct max6650_data *data = i2c_get_clientdata(client);
+ int config;
+ int err = -EIO;
+
+ config = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG);
+
+ if (config < 0) {
+ dev_err(&client->dev, "Error reading config, aborting.\n");
+ return err;
+ }
+
+ switch (fan_voltage) {
+ case 0:
+ break;
+ case 5:
+ config &= ~MAX6650_CFG_V12;
+ break;
+ case 12:
+ config |= MAX6650_CFG_V12;
+ break;
+ default:
+ dev_err(&client->dev,
+ "illegal value for fan_voltage (%d)\n",
+ fan_voltage);
+ }
+
+ dev_info(&client->dev, "Fan voltage is set to %dV.\n",
+ (config & MAX6650_CFG_V12) ? 12 : 5);
+
+ switch (prescaler) {
+ case 0:
+ break;
+ case 1:
+ config &= ~MAX6650_CFG_PRESCALER_MASK;
+ break;
+ case 2:
+ config = (config & ~MAX6650_CFG_PRESCALER_MASK)
+ | MAX6650_CFG_PRESCALER_2;
+ break;
+ case 4:
+ config = (config & ~MAX6650_CFG_PRESCALER_MASK)
+ | MAX6650_CFG_PRESCALER_4;
+ break;
+ case 8:
+ config = (config & ~MAX6650_CFG_PRESCALER_MASK)
+ | MAX6650_CFG_PRESCALER_8;
+ break;
+ case 16:
+ config = (config & ~MAX6650_CFG_PRESCALER_MASK)
+ | MAX6650_CFG_PRESCALER_16;
+ break;
+ default:
+ dev_err(&client->dev,
+ "illegal value for prescaler (%d)\n",
+ prescaler);
+ }
+
+ dev_info(&client->dev, "Prescaler is set to %d.\n",
+ 1 << (config & MAX6650_CFG_PRESCALER_MASK));
+
+ /* If mode is set to "full off", we change it to "open loop" and
+ * set DAC to 255, which has the same effect. We do this because
+ * there's no "full off" mode defined in hwmon specifcations.
+ */
+
+ if ((config & MAX6650_CFG_MODE_MASK) == MAX6650_CFG_MODE_OFF) {
+ dev_dbg(&client->dev, "Change mode to open loop, full off.\n");
+ config = (config & ~MAX6650_CFG_MODE_MASK)
+ | MAX6650_CFG_MODE_OPEN_LOOP;
+ if (i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, 255)) {
+ dev_err(&client->dev, "DAC write error, aborting.\n");
+ return err;
+ }
+ }
+
+ if (i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, config)) {
+ dev_err(&client->dev, "Config write error, aborting.\n");
+ return err;
+ }
+
+ data->config = config;
+ data->count = i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT);
+
+ return 0;
+}
+
+static const u8 tach_reg[] = {
+ MAX6650_REG_TACH0,
+ MAX6650_REG_TACH1,
+ MAX6650_REG_TACH2,
+ MAX6650_REG_TACH3,
+};
+
+static struct max6650_data *max6650_update_device(struct device *dev)
+{
+ int i;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct max6650_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+ data->speed = i2c_smbus_read_byte_data(client,
+ MAX6650_REG_SPEED);
+ data->config = i2c_smbus_read_byte_data(client,
+ MAX6650_REG_CONFIG);
+ for (i = 0; i < 4; i++) {
+ data->tach[i] = i2c_smbus_read_byte_data(client,
+ tach_reg[i]);
+ }
+ data->count = i2c_smbus_read_byte_data(client,
+ MAX6650_REG_COUNT);
+ data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC);
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+static int __init sensors_max6650_init(void)
+{
+ return i2c_add_driver(&max6650_driver);
+}
+
+static void __exit sensors_max6650_exit(void)
+{
+ i2c_del_driver(&max6650_driver);
+}
+
+MODULE_AUTHOR("Hans J. Koch");
+MODULE_DESCRIPTION("MAX6650 sensor driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_max6650_init);
+module_exit(sensors_max6650_exit);
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
index affa21a..29354fa 100644
--- a/drivers/hwmon/pc87427.c
+++ b/drivers/hwmon/pc87427.c
@@ -31,6 +31,7 @@
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
+#include <linux/ioport.h>
#include <asm/io.h>
static struct platform_device *pdev;
@@ -429,6 +430,12 @@ static int __devinit pc87427_probe(struct platform_device *pdev)
/* This will need to be revisited when we add support for
temperature and voltage monitoring. */
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) {
+ err = -EBUSY;
+ dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n",
+ (unsigned long)res->start, (unsigned long)res->end);
+ goto exit_kfree;
+ }
data->address[0] = res->start;
mutex_init(&data->lock);
@@ -438,7 +445,7 @@ static int __devinit pc87427_probe(struct platform_device *pdev)
/* Register sysfs hooks */
if ((err = device_create_file(&pdev->dev, &dev_attr_name)))
- goto exit_kfree;
+ goto exit_release_region;
for (i = 0; i < 8; i++) {
if (!(data->fan_enabled & (1 << i)))
continue;
@@ -462,6 +469,8 @@ exit_remove_files:
continue;
sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
}
+exit_release_region:
+ release_region(res->start, res->end - res->start + 1);
exit_kfree:
platform_set_drvdata(pdev, NULL);
kfree(data);
@@ -472,6 +481,7 @@ exit:
static int __devexit pc87427_remove(struct platform_device *pdev)
{
struct pc87427_data *data = platform_get_drvdata(pdev);
+ struct resource *res;
int i;
platform_set_drvdata(pdev, NULL);
@@ -484,6 +494,9 @@ static int __devexit pc87427_remove(struct platform_device *pdev)
}
kfree(data);
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ release_region(res->start, res->end - res->start + 1);
+
return 0;
}
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index 72b0e2d..943abbd 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -30,16 +30,17 @@
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-isa.h>
+#include <linux/platform_device.h>
#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <asm/io.h>
-/* Address is autodetected, there is no default value */
-static unsigned short address;
+static struct platform_device *pdev;
+
+#define DRVNAME "smsc47b397"
/* Super-I/0 registers and commands */
@@ -91,7 +92,8 @@ static u8 smsc47b397_reg_temp[] = {0x25, 0x26, 0x27, 0x80};
#define SMSC47B397_REG_FAN_MSB(nr) (0x29 + 2 * (nr))
struct smsc47b397_data {
- struct i2c_client client;
+ unsigned short addr;
+ const char *name;
struct class_device *class_dev;
struct mutex lock;
@@ -104,45 +106,43 @@ struct smsc47b397_data {
u8 temp[4];
};
-static int smsc47b397_read_value(struct i2c_client *client, u8 reg)
+static int smsc47b397_read_value(struct smsc47b397_data* data, u8 reg)
{
- struct smsc47b397_data *data = i2c_get_clientdata(client);
int res;
mutex_lock(&data->lock);
- outb(reg, client->addr);
- res = inb_p(client->addr + 1);
+ outb(reg, data->addr);
+ res = inb_p(data->addr + 1);
mutex_unlock(&data->lock);
return res;
}
static struct smsc47b397_data *smsc47b397_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct smsc47b397_data *data = i2c_get_clientdata(client);
+ struct smsc47b397_data *data = dev_get_drvdata(dev);
int i;
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
- dev_dbg(&client->dev, "starting device update...\n");
+ dev_dbg(dev, "starting device update...\n");
/* 4 temperature inputs, 4 fan inputs */
for (i = 0; i < 4; i++) {
- data->temp[i] = smsc47b397_read_value(client,
+ data->temp[i] = smsc47b397_read_value(data,
SMSC47B397_REG_TEMP(i));
/* must read LSB first */
- data->fan[i] = smsc47b397_read_value(client,
+ data->fan[i] = smsc47b397_read_value(data,
SMSC47B397_REG_FAN_LSB(i));
- data->fan[i] |= smsc47b397_read_value(client,
+ data->fan[i] |= smsc47b397_read_value(data,
SMSC47B397_REG_FAN_MSB(i)) << 8;
}
data->last_updated = jiffies;
data->valid = 1;
- dev_dbg(&client->dev, "... device update complete\n");
+ dev_dbg(dev, "... device update complete\n");
}
mutex_unlock(&data->update_lock);
@@ -157,24 +157,18 @@ static int temp_from_reg(u8 reg)
return (s8)reg * 1000;
}
-/* 0 <= nr <= 3 */
-static ssize_t show_temp(struct device *dev, char *buf, int nr)
+static ssize_t show_temp(struct device *dev, struct device_attribute
+ *devattr, char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct smsc47b397_data *data = smsc47b397_update_device(dev);
- return sprintf(buf, "%d\n", temp_from_reg(data->temp[nr]));
+ return sprintf(buf, "%d\n", temp_from_reg(data->temp[attr->index]));
}
-#define sysfs_temp(num) \
-static ssize_t show_temp##num(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_temp(dev, buf, num-1); \
-} \
-static DEVICE_ATTR(temp##num##_input, S_IRUGO, show_temp##num, NULL)
-
-sysfs_temp(1);
-sysfs_temp(2);
-sysfs_temp(3);
-sysfs_temp(4);
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3);
/* FAN: 1 RPM/bit
REG: count of 90kHz pulses / revolution */
@@ -183,35 +177,37 @@ static int fan_from_reg(u16 reg)
return 90000 * 60 / reg;
}
-/* 0 <= nr <= 3 */
-static ssize_t show_fan(struct device *dev, char *buf, int nr)
+static ssize_t show_fan(struct device *dev, struct device_attribute
+ *devattr, char *buf)
{
- struct smsc47b397_data *data = smsc47b397_update_device(dev);
- return sprintf(buf, "%d\n", fan_from_reg(data->fan[nr]));
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct smsc47b397_data *data = smsc47b397_update_device(dev);
+ return sprintf(buf, "%d\n", fan_from_reg(data->fan[attr->index]));
}
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3);
-#define sysfs_fan(num) \
-static ssize_t show_fan##num(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_fan(dev, buf, num-1); \
-} \
-static DEVICE_ATTR(fan##num##_input, S_IRUGO, show_fan##num, NULL)
-
-sysfs_fan(1);
-sysfs_fan(2);
-sysfs_fan(3);
-sysfs_fan(4);
+static ssize_t show_name(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ struct smsc47b397_data *data = dev_get_drvdata(dev);
+ return sprintf(buf, "%s\n", data->name);
+}
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
static struct attribute *smsc47b397_attributes[] = {
- &dev_attr_temp1_input.attr,
- &dev_attr_temp2_input.attr,
- &dev_attr_temp3_input.attr,
- &dev_attr_temp4_input.attr,
- &dev_attr_fan1_input.attr,
- &dev_attr_fan2_input.attr,
- &dev_attr_fan3_input.attr,
- &dev_attr_fan4_input.attr,
-
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_temp2_input.dev_attr.attr,
+ &sensor_dev_attr_temp3_input.dev_attr.attr,
+ &sensor_dev_attr_temp4_input.dev_attr.attr,
+ &sensor_dev_attr_fan1_input.dev_attr.attr,
+ &sensor_dev_attr_fan2_input.dev_attr.attr,
+ &sensor_dev_attr_fan3_input.dev_attr.attr,
+ &sensor_dev_attr_fan4_input.dev_attr.attr,
+
+ &dev_attr_name.attr,
NULL
};
@@ -219,44 +215,44 @@ static const struct attribute_group smsc47b397_group = {
.attrs = smsc47b397_attributes,
};
-static int smsc47b397_detach_client(struct i2c_client *client)
+static int __devexit smsc47b397_remove(struct platform_device *pdev)
{
- struct smsc47b397_data *data = i2c_get_clientdata(client);
- int err;
+ struct smsc47b397_data *data = platform_get_drvdata(pdev);
+ struct resource *res;
hwmon_device_unregister(data->class_dev);
- sysfs_remove_group(&client->dev.kobj, &smsc47b397_group);
-
- if ((err = i2c_detach_client(client)))
- return err;
-
- release_region(client->addr, SMSC_EXTENT);
+ sysfs_remove_group(&pdev->dev.kobj, &smsc47b397_group);
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ release_region(res->start, SMSC_EXTENT);
kfree(data);
return 0;
}
-static int smsc47b397_detect(struct i2c_adapter *adapter);
+static int smsc47b397_probe(struct platform_device *pdev);
-static struct i2c_driver smsc47b397_driver = {
+static struct platform_driver smsc47b397_driver = {
.driver = {
.owner = THIS_MODULE,
- .name = "smsc47b397",
+ .name = DRVNAME,
},
- .attach_adapter = smsc47b397_detect,
- .detach_client = smsc47b397_detach_client,
+ .probe = smsc47b397_probe,
+ .remove = __devexit_p(smsc47b397_remove),
};
-static int smsc47b397_detect(struct i2c_adapter *adapter)
+static int __devinit smsc47b397_probe(struct platform_device *pdev)
{
- struct i2c_client *new_client;
+ struct device *dev = &pdev->dev;
struct smsc47b397_data *data;
+ struct resource *res;
int err = 0;
- if (!request_region(address, SMSC_EXTENT,
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!request_region(res->start, SMSC_EXTENT,
smsc47b397_driver.driver.name)) {
- dev_err(&adapter->dev, "Region 0x%x already in use!\n",
- address);
+ dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
+ (unsigned long)res->start,
+ (unsigned long)res->start + SMSC_EXTENT - 1);
return -EBUSY;
}
@@ -265,25 +261,16 @@ static int smsc47b397_detect(struct i2c_adapter *adapter)
goto error_release;
}
- new_client = &data->client;
- i2c_set_clientdata(new_client, data);
- new_client->addr = address;
+ data->addr = res->start;
+ data->name = "smsc47b397";
mutex_init(&data->lock);
- new_client->adapter = adapter;
- new_client->driver = &smsc47b397_driver;
- new_client->flags = 0;
-
- strlcpy(new_client->name, "smsc47b397", I2C_NAME_SIZE);
-
mutex_init(&data->update_lock);
+ platform_set_drvdata(pdev, data);
- if ((err = i2c_attach_client(new_client)))
+ if ((err = sysfs_create_group(&dev->kobj, &smsc47b397_group)))
goto error_free;
- if ((err = sysfs_create_group(&new_client->dev.kobj, &smsc47b397_group)))
- goto error_detach;
-
- data->class_dev = hwmon_device_register(&new_client->dev);
+ data->class_dev = hwmon_device_register(dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto error_remove;
@@ -292,13 +279,50 @@ static int smsc47b397_detect(struct i2c_adapter *adapter)
return 0;
error_remove:
- sysfs_remove_group(&new_client->dev.kobj, &smsc47b397_group);
-error_detach:
- i2c_detach_client(new_client);
+ sysfs_remove_group(&dev->kobj, &smsc47b397_group);
error_free:
kfree(data);
error_release:
- release_region(address, SMSC_EXTENT);
+ release_region(res->start, SMSC_EXTENT);
+ return err;
+}
+
+static int __init smsc47b397_device_add(unsigned short address)
+{
+ struct resource res = {
+ .start = address,
+ .end = address + SMSC_EXTENT - 1,
+ .name = DRVNAME,
+ .flags = IORESOURCE_IO,
+ };
+ int err;
+
+ pdev = platform_device_alloc(DRVNAME, address);
+ if (!pdev) {
+ err = -ENOMEM;
+ printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ goto exit;
+ }
+
+ err = platform_device_add_resources(pdev, &res, 1);
+ if (err) {
+ printk(KERN_ERR DRVNAME ": Device resource addition failed "
+ "(%d)\n", err);
+ goto exit_device_put;
+ }
+
+ err = platform_device_add(pdev);
+ if (err) {
+ printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
+ err);
+ goto exit_device_put;
+ }
+
+ return 0;
+
+exit_device_put:
+ platform_device_put(pdev);
+exit:
return err;
}
@@ -320,7 +344,7 @@ static int __init smsc47b397_find(unsigned short *addr)
*addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8)
| superio_inb(SUPERIO_REG_BASE_LSB);
- printk(KERN_INFO "smsc47b397: found SMSC %s "
+ printk(KERN_INFO DRVNAME ": found SMSC %s "
"(base address 0x%04x, revision %u)\n",
id == 0x81 ? "SCH5307-NS" : "LPC47B397-NC", *addr, rev);
@@ -330,17 +354,33 @@ static int __init smsc47b397_find(unsigned short *addr)
static int __init smsc47b397_init(void)
{
+ unsigned short address;
int ret;
if ((ret = smsc47b397_find(&address)))
return ret;
- return i2c_isa_add_driver(&smsc47b397_driver);
+ ret = platform_driver_register(&smsc47b397_driver);
+ if (ret)
+ goto exit;
+
+ /* Sets global pdev as a side effect */
+ ret = smsc47b397_device_add(address);
+ if (ret)
+ goto exit_driver;
+
+ return 0;
+
+exit_driver:
+ platform_driver_unregister(&smsc47b397_driver);
+exit:
+ return ret;
}
static void __exit smsc47b397_exit(void)
{
- i2c_isa_del_driver(&smsc47b397_driver);
+ platform_device_unregister(pdev);
+ platform_driver_unregister(&smsc47b397_driver);
}
MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index beb881c..1e21c8c 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -3,10 +3,11 @@
for hardware monitoring
Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x,
- LPC47M14x, LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips.
+ LPC47M14x, LPC47M15x, LPC47M192, LPC47M292 and LPC47M997
+ Super-I/O chips.
Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
- Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
+ Copyright (C) 2004-2007 Jean Delvare <khali@linux-fr.org>
Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com>
and Jean Delvare
@@ -29,17 +30,19 @@
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-isa.h>
+#include <linux/platform_device.h>
#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <asm/io.h>
-/* Address is autodetected, there is no default value */
-static unsigned short address;
+static struct platform_device *pdev;
+
+#define DRVNAME "smsc47m1"
+enum chips { smsc47m1, smsc47m2 };
/* Super-I/0 registers and commands */
@@ -87,10 +90,18 @@ superio_exit(void)
#define SMSC47M1_REG_ALARM 0x04
#define SMSC47M1_REG_TPIN(nr) (0x34 - (nr))
#define SMSC47M1_REG_PPIN(nr) (0x36 - (nr))
-#define SMSC47M1_REG_PWM(nr) (0x56 + (nr))
#define SMSC47M1_REG_FANDIV 0x58
-#define SMSC47M1_REG_FAN(nr) (0x59 + (nr))
-#define SMSC47M1_REG_FAN_PRELOAD(nr) (0x5B + (nr))
+
+static const u8 SMSC47M1_REG_FAN[3] = { 0x59, 0x5a, 0x6b };
+static const u8 SMSC47M1_REG_FAN_PRELOAD[3] = { 0x5b, 0x5c, 0x6c };
+static const u8 SMSC47M1_REG_PWM[3] = { 0x56, 0x57, 0x69 };
+
+#define SMSC47M2_REG_ALARM6 0x09
+#define SMSC47M2_REG_TPIN1 0x38
+#define SMSC47M2_REG_TPIN2 0x37
+#define SMSC47M2_REG_TPIN3 0x2d
+#define SMSC47M2_REG_PPIN3 0x2c
+#define SMSC47M2_REG_FANDIV3 0x6a
#define MIN_FROM_REG(reg,div) ((reg)>=192 ? 0 : \
983040/((192-(reg))*(div)))
@@ -102,45 +113,57 @@ superio_exit(void)
#define PWM_TO_REG(reg) (((reg) >> 1) & 0x7E)
struct smsc47m1_data {
- struct i2c_client client;
+ unsigned short addr;
+ const char *name;
+ enum chips type;
struct class_device *class_dev;
- struct mutex lock;
struct mutex update_lock;
unsigned long last_updated; /* In jiffies */
- u8 fan[2]; /* Register value */
- u8 fan_preload[2]; /* Register value */
- u8 fan_div[2]; /* Register encoding, shifted right */
+ u8 fan[3]; /* Register value */
+ u8 fan_preload[3]; /* Register value */
+ u8 fan_div[3]; /* Register encoding, shifted right */
u8 alarms; /* Register encoding */
- u8 pwm[2]; /* Register value (bit 7 is enable) */
+ u8 pwm[3]; /* Register value (bit 0 is disable) */
};
+struct smsc47m1_sio_data {
+ enum chips type;
+};
-static int smsc47m1_detect(struct i2c_adapter *adapter);
-static int smsc47m1_detach_client(struct i2c_client *client);
-
-static int smsc47m1_read_value(struct i2c_client *client, u8 reg);
-static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value);
+static int smsc47m1_probe(struct platform_device *pdev);
+static int smsc47m1_remove(struct platform_device *pdev);
static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
int init);
+static inline int smsc47m1_read_value(struct smsc47m1_data *data, u8 reg)
+{
+ return inb_p(data->addr + reg);
+}
-static struct i2c_driver smsc47m1_driver = {
+static inline void smsc47m1_write_value(struct smsc47m1_data *data, u8 reg,
+ u8 value)
+{
+ outb_p(value, data->addr + reg);
+}
+
+static struct platform_driver smsc47m1_driver = {
.driver = {
.owner = THIS_MODULE,
- .name = "smsc47m1",
+ .name = DRVNAME,
},
- .attach_adapter = smsc47m1_detect,
- .detach_client = smsc47m1_detach_client,
+ .probe = smsc47m1_probe,
+ .remove = __devexit_p(smsc47m1_remove),
};
-/* nr is 0 or 1 in the callback functions below */
-
-static ssize_t get_fan(struct device *dev, char *buf, int nr)
+static ssize_t get_fan(struct device *dev, struct device_attribute
+ *devattr, char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
+ int nr = attr->index;
/* This chip (stupidly) stops monitoring fan speed if PWM is
enabled and duty cycle is 0%. This is fine if the monitoring
and control concern the same fan, but troublesome if they are
@@ -152,43 +175,54 @@ static ssize_t get_fan(struct device *dev, char *buf, int nr)
return sprintf(buf, "%d\n", rpm);
}
-static ssize_t get_fan_min(struct device *dev, char *buf, int nr)
+static ssize_t get_fan_min(struct device *dev, struct device_attribute
+ *devattr, char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
+ int nr = attr->index;
int rpm = MIN_FROM_REG(data->fan_preload[nr],
DIV_FROM_REG(data->fan_div[nr]));
return sprintf(buf, "%d\n", rpm);
}
-static ssize_t get_fan_div(struct device *dev, char *buf, int nr)
+static ssize_t get_fan_div(struct device *dev, struct device_attribute
+ *devattr, char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
- return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
+ return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index]));
}
-static ssize_t get_pwm(struct device *dev, char *buf, int nr)
+static ssize_t get_pwm(struct device *dev, struct device_attribute
+ *devattr, char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
- return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
+ return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[attr->index]));
}
-static ssize_t get_pwm_en(struct device *dev, char *buf, int nr)
+static ssize_t get_pwm_en(struct device *dev, struct device_attribute
+ *devattr, char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
- return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[nr]));
+ return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[attr->index]));
}
-static ssize_t get_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t get_alarms(struct device *dev, struct device_attribute
+ *devattr, char *buf)
{
struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
return sprintf(buf, "%d\n", data->alarms);
}
-static ssize_t set_fan_min(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_fan_min(struct device *dev, struct device_attribute
+ *devattr, const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct smsc47m1_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct smsc47m1_data *data = dev_get_drvdata(dev);
+ int nr = attr->index;
long rpmdiv, val = simple_strtol(buf, NULL, 10);
mutex_lock(&data->update_lock);
@@ -200,7 +234,7 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
}
data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv);
- smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
+ smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr],
data->fan_preload[nr]);
mutex_unlock(&data->update_lock);
@@ -211,12 +245,12 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
determined in part by the fan clock divider. This follows the principle
of least surprise; the user doesn't expect the fan minimum to change just
because the divider changed. */
-static ssize_t set_fan_div(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_fan_div(struct device *dev, struct device_attribute
+ *devattr, const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct smsc47m1_data *data = i2c_get_clientdata(client);
-
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct smsc47m1_data *data = dev_get_drvdata(dev);
+ int nr = attr->index;
long new_div = simple_strtol(buf, NULL, 10), tmp;
u8 old_div = DIV_FROM_REG(data->fan_div[nr]);
@@ -234,27 +268,38 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
return -EINVAL;
}
- tmp = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV) & 0x0F;
- tmp |= (data->fan_div[0] << 4) | (data->fan_div[1] << 6);
- smsc47m1_write_value(client, SMSC47M1_REG_FANDIV, tmp);
+ switch (nr) {
+ case 0:
+ case 1:
+ tmp = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV)
+ & ~(0x03 << (4 + 2 * nr));
+ tmp |= data->fan_div[nr] << (4 + 2 * nr);
+ smsc47m1_write_value(data, SMSC47M1_REG_FANDIV, tmp);
+ break;
+ case 2:
+ tmp = smsc47m1_read_value(data, SMSC47M2_REG_FANDIV3) & 0xCF;
+ tmp |= data->fan_div[2] << 4;
+ smsc47m1_write_value(data, SMSC47M2_REG_FANDIV3, tmp);
+ break;
+ }
/* Preserve fan min */
tmp = 192 - (old_div * (192 - data->fan_preload[nr])
+ new_div / 2) / new_div;
data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191);
- smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
+ smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr],
data->fan_preload[nr]);
mutex_unlock(&data->update_lock);
return count;
}
-static ssize_t set_pwm(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_pwm(struct device *dev, struct device_attribute
+ *devattr, const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct smsc47m1_data *data = i2c_get_clientdata(client);
-
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct smsc47m1_data *data = dev_get_drvdata(dev);
+ int nr = attr->index;
long val = simple_strtol(buf, NULL, 10);
if (val < 0 || val > 255)
@@ -263,19 +308,19 @@ static ssize_t set_pwm(struct device *dev, const char *buf,
mutex_lock(&data->update_lock);
data->pwm[nr] &= 0x81; /* Preserve additional bits */
data->pwm[nr] |= PWM_TO_REG(val);
- smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
+ smsc47m1_write_value(data, SMSC47M1_REG_PWM[nr],
data->pwm[nr]);
mutex_unlock(&data->update_lock);
return count;
}
-static ssize_t set_pwm_en(struct device *dev, const char *buf,
- size_t count, int nr)
+static ssize_t set_pwm_en(struct device *dev, struct device_attribute
+ *devattr, const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct smsc47m1_data *data = i2c_get_clientdata(client);
-
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ struct smsc47m1_data *data = dev_get_drvdata(dev);
+ int nr = attr->index;
long val = simple_strtol(buf, NULL, 10);
if (val != 0 && val != 1)
@@ -284,7 +329,7 @@ static ssize_t set_pwm_en(struct device *dev, const char *buf,
mutex_lock(&data->update_lock);
data->pwm[nr] &= 0xFE; /* preserve the other bits */
data->pwm[nr] |= !val;
- smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
+ smsc47m1_write_value(data, SMSC47M1_REG_PWM[nr],
data->pwm[nr]);
mutex_unlock(&data->update_lock);
@@ -292,79 +337,55 @@ static ssize_t set_pwm_en(struct device *dev, const char *buf,
}
#define fan_present(offset) \
-static ssize_t get_fan##offset (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return get_fan(dev, buf, offset - 1); \
-} \
-static ssize_t get_fan##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return get_fan_min(dev, buf, offset - 1); \
-} \
-static ssize_t set_fan##offset##_min (struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- return set_fan_min(dev, buf, count, offset - 1); \
-} \
-static ssize_t get_fan##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return get_fan_div(dev, buf, offset - 1); \
-} \
-static ssize_t set_fan##offset##_div (struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- return set_fan_div(dev, buf, count, offset - 1); \
-} \
-static ssize_t get_pwm##offset (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return get_pwm(dev, buf, offset - 1); \
-} \
-static ssize_t set_pwm##offset (struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- return set_pwm(dev, buf, count, offset - 1); \
-} \
-static ssize_t get_pwm##offset##_en (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return get_pwm_en(dev, buf, offset - 1); \
-} \
-static ssize_t set_pwm##offset##_en (struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- return set_pwm_en(dev, buf, count, offset - 1); \
-} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan##offset, \
- NULL); \
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- get_fan##offset##_min, set_fan##offset##_min); \
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
- get_fan##offset##_div, set_fan##offset##_div); \
-static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
- get_pwm##offset, set_pwm##offset); \
-static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
- get_pwm##offset##_en, set_pwm##offset##_en);
+static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan, \
+ NULL, offset - 1); \
+static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
+ get_fan_min, set_fan_min, offset - 1); \
+static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
+ get_fan_div, set_fan_div, offset - 1); \
+static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
+ get_pwm, set_pwm, offset - 1); \
+static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
+ get_pwm_en, set_pwm_en, offset - 1)
fan_present(1);
fan_present(2);
+fan_present(3);
static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL);
+static ssize_t show_name(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ struct smsc47m1_data *data = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%s\n", data->name);
+}
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
/* Almost all sysfs files may or may not be created depending on the chip
setup so we create them individually. It is still convenient to define a
group to remove them all at once. */
static struct attribute *smsc47m1_attributes[] = {
- &dev_attr_fan1_input.attr,
- &dev_attr_fan1_min.attr,
- &dev_attr_fan1_div.attr,
- &dev_attr_fan2_input.attr,
- &dev_attr_fan2_min.attr,
- &dev_attr_fan2_div.attr,
-
- &dev_attr_pwm1.attr,
- &dev_attr_pwm1_enable.attr,
- &dev_attr_pwm2.attr,
- &dev_attr_pwm2_enable.attr,
+ &sensor_dev_attr_fan1_input.dev_attr.attr,
+ &sensor_dev_attr_fan1_min.dev_attr.attr,
+ &sensor_dev_attr_fan1_div.dev_attr.attr,
+ &sensor_dev_attr_fan2_input.dev_attr.attr,
+ &sensor_dev_attr_fan2_min.dev_attr.attr,
+ &sensor_dev_attr_fan2_div.dev_attr.attr,
+ &sensor_dev_attr_fan3_input.dev_attr.attr,
+ &sensor_dev_attr_fan3_min.dev_attr.attr,
+ &sensor_dev_attr_fan3_div.dev_attr.attr,
+
+ &sensor_dev_attr_pwm1.dev_attr.attr,
+ &sensor_dev_attr_pwm1_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm2.dev_attr.attr,
+ &sensor_dev_attr_pwm2_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm3.dev_attr.attr,
+ &sensor_dev_attr_pwm3_enable.dev_attr.attr,
&dev_attr_alarms.attr,
+ &dev_attr_name.attr,
NULL
};
@@ -372,7 +393,8 @@ static const struct attribute_group smsc47m1_group = {
.attrs = smsc47m1_attributes,
};
-static int __init smsc47m1_find(unsigned short *addr)
+static int __init smsc47m1_find(unsigned short *addr,
+ struct smsc47m1_sio_data *sio_data)
{
u8 val;
@@ -386,18 +408,32 @@ static int __init smsc47m1_find(unsigned short *addr)
* can do much more besides (device id 0x60).
* The LPC47M997 is undocumented, but seems to be compatible with
* the LPC47M192, and has the same device id.
+ * The LPC47M292 (device id 0x6B) is somewhat compatible, but it
+ * supports a 3rd fan, and the pin configuration registers are
+ * unfortunately different.
*/
- if (val == 0x51)
- printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n");
- else if (val == 0x59)
- printk(KERN_INFO "smsc47m1: Found SMSC "
- "LPC47M10x/LPC47M112/LPC47M13x\n");
- else if (val == 0x5F)
- printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n");
- else if (val == 0x60)
- printk(KERN_INFO "smsc47m1: Found SMSC "
- "LPC47M15x/LPC47M192/LPC47M997\n");
- else {
+ switch (val) {
+ case 0x51:
+ pr_info(DRVNAME ": Found SMSC LPC47B27x\n");
+ sio_data->type = smsc47m1;
+ break;
+ case 0x59:
+ pr_info(DRVNAME ": Found SMSC LPC47M10x/LPC47M112/LPC47M13x\n");
+ sio_data->type = smsc47m1;
+ break;
+ case 0x5F:
+ pr_info(DRVNAME ": Found SMSC LPC47M14x\n");
+ sio_data->type = smsc47m1;
+ break;
+ case 0x60:
+ pr_info(DRVNAME ": Found SMSC LPC47M15x/LPC47M192/LPC47M997\n");
+ sio_data->type = smsc47m1;
+ break;
+ case 0x6B:
+ pr_info(DRVNAME ": Found SMSC LPC47M292\n");
+ sio_data->type = smsc47m2;
+ break;
+ default:
superio_exit();
return -ENODEV;
}
@@ -407,7 +443,7 @@ static int __init smsc47m1_find(unsigned short *addr)
| superio_inb(SUPERIO_REG_BASE + 1);
val = superio_inb(SUPERIO_REG_ACT);
if (*addr == 0 || (val & 0x01) == 0) {
- printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n");
+ pr_info(DRVNAME ": Device is disabled, will not use\n");
superio_exit();
return -ENODEV;
}
@@ -416,15 +452,25 @@ static int __init smsc47m1_find(unsigned short *addr)
return 0;
}
-static int smsc47m1_detect(struct i2c_adapter *adapter)
+static int __devinit smsc47m1_probe(struct platform_device *pdev)
{
- struct i2c_client *new_client;
+ struct device *dev = &pdev->dev;
+ struct smsc47m1_sio_data *sio_data = dev->platform_data;
struct smsc47m1_data *data;
+ struct resource *res;
int err = 0;
- int fan1, fan2, pwm1, pwm2;
-
- if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.driver.name)) {
- dev_err(&adapter->dev, "Region 0x%x already in use!\n", address);
+ int fan1, fan2, fan3, pwm1, pwm2, pwm3;
+
+ static const char *names[] = {
+ "smsc47m1",
+ "smsc47m2",
+ };
+
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!request_region(res->start, SMSC_EXTENT, DRVNAME)) {
+ dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
+ (unsigned long)res->start,
+ (unsigned long)res->end);
return -EBUSY;
}
@@ -433,93 +479,114 @@ static int smsc47m1_detect(struct i2c_adapter *adapter)
goto error_release;
}
- new_client = &data->client;
- i2c_set_clientdata(new_client, data);
- new_client->addr = address;
- mutex_init(&data->lock);
- new_client->adapter = adapter;
- new_client->driver = &smsc47m1_driver;
- new_client->flags = 0;
-
- strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE);
+ data->addr = res->start;
+ data->type = sio_data->type;
+ data->name = names[sio_data->type];
mutex_init(&data->update_lock);
+ platform_set_drvdata(pdev, data);
/* If no function is properly configured, there's no point in
actually registering the chip. */
- fan1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(0)) & 0x05)
- == 0x05;
- fan2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(1)) & 0x05)
- == 0x05;
- pwm1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(0)) & 0x05)
+ pwm1 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(0)) & 0x05)
== 0x04;
- pwm2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(1)) & 0x05)
+ pwm2 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(1)) & 0x05)
== 0x04;
- if (!(fan1 || fan2 || pwm1 || pwm2)) {
- dev_warn(&adapter->dev, "Device at 0x%x is not configured, "
- "will not use\n", new_client->addr);
+ if (data->type == smsc47m2) {
+ fan1 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN1)
+ & 0x0d) == 0x09;
+ fan2 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN2)
+ & 0x0d) == 0x09;
+ fan3 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN3)
+ & 0x0d) == 0x0d;
+ pwm3 = (smsc47m1_read_value(data, SMSC47M2_REG_PPIN3)
+ & 0x0d) == 0x08;
+ } else {
+ fan1 = (smsc47m1_read_value(data, SMSC47M1_REG_TPIN(0))
+ & 0x05) == 0x05;
+ fan2 = (smsc47m1_read_value(data, SMSC47M1_REG_TPIN(1))
+ & 0x05) == 0x05;
+ fan3 = 0;
+ pwm3 = 0;
+ }
+ if (!(fan1 || fan2 || fan3 || pwm1 || pwm2 || pwm3)) {
+ dev_warn(dev, "Device not configured, will not use\n");
err = -ENODEV;
goto error_free;
}
- if ((err = i2c_attach_client(new_client)))
- goto error_free;
-
/* Some values (fan min, clock dividers, pwm registers) may be
needed before any update is triggered, so we better read them
at least once here. We don't usually do it that way, but in
this particular case, manually reading 5 registers out of 8
doesn't make much sense and we're better using the existing
function. */
- smsc47m1_update_device(&new_client->dev, 1);
+ smsc47m1_update_device(dev, 1);
/* Register sysfs hooks */
if (fan1) {
- if ((err = device_create_file(&new_client->dev,
- &dev_attr_fan1_input))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_fan1_min))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_fan1_div)))
+ if ((err = device_create_file(dev,
+ &sensor_dev_attr_fan1_input.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_fan1_min.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_fan1_div.dev_attr)))
goto error_remove_files;
} else
- dev_dbg(&new_client->dev, "Fan 1 not enabled by hardware, "
- "skipping\n");
+ dev_dbg(dev, "Fan 1 not enabled by hardware, skipping\n");
if (fan2) {
- if ((err = device_create_file(&new_client->dev,
- &dev_attr_fan2_input))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_fan2_min))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_fan2_div)))
+ if ((err = device_create_file(dev,
+ &sensor_dev_attr_fan2_input.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_fan2_min.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_fan2_div.dev_attr)))
goto error_remove_files;
} else
- dev_dbg(&new_client->dev, "Fan 2 not enabled by hardware, "
- "skipping\n");
+ dev_dbg(dev, "Fan 2 not enabled by hardware, skipping\n");
+
+ if (fan3) {
+ if ((err = device_create_file(dev,
+ &sensor_dev_attr_fan3_input.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_fan3_min.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_fan3_div.dev_attr)))
+ goto error_remove_files;
+ } else
+ dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n");
if (pwm1) {
- if ((err = device_create_file(&new_client->dev,
- &dev_attr_pwm1))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_pwm1_enable)))
+ if ((err = device_create_file(dev,
+ &sensor_dev_attr_pwm1.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_pwm1_enable.dev_attr)))
goto error_remove_files;
} else
- dev_dbg(&new_client->dev, "PWM 1 not enabled by hardware, "
- "skipping\n");
+ dev_dbg(dev, "PWM 1 not enabled by hardware, skipping\n");
+
if (pwm2) {
- if ((err = device_create_file(&new_client->dev,
- &dev_attr_pwm2))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_pwm2_enable)))
+ if ((err = device_create_file(dev,
+ &sensor_dev_attr_pwm2.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_pwm2_enable.dev_attr)))
+ goto error_remove_files;
+ } else
+ dev_dbg(dev, "PWM 2 not enabled by hardware, skipping\n");
+
+ if (pwm3) {
+ if ((err = device_create_file(dev,
+ &sensor_dev_attr_pwm3.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_pwm3_enable.dev_attr)))
goto error_remove_files;
} else
- dev_dbg(&new_client->dev, "PWM 2 not enabled by hardware, "
- "skipping\n");
+ dev_dbg(dev, "PWM 3 not enabled by hardware, skipping\n");
- if ((err = device_create_file(&new_client->dev, &dev_attr_alarms)))
+ if ((err = device_create_file(dev, &dev_attr_alarms)))
goto error_remove_files;
- data->class_dev = hwmon_device_register(&new_client->dev);
+ data->class_dev = hwmon_device_register(dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto error_remove_files;
@@ -528,78 +595,71 @@ static int smsc47m1_detect(struct i2c_adapter *adapter)
return 0;
error_remove_files:
- sysfs_remove_group(&new_client->dev.kobj, &smsc47m1_group);
- i2c_detach_client(new_client);
+ sysfs_remove_group(&dev->kobj, &smsc47m1_group);
error_free:
kfree(data);
error_release:
- release_region(address, SMSC_EXTENT);
+ release_region(res->start, SMSC_EXTENT);
return err;
}
-static int smsc47m1_detach_client(struct i2c_client *client)
+static int __devexit smsc47m1_remove(struct platform_device *pdev)
{
- struct smsc47m1_data *data = i2c_get_clientdata(client);
- int err;
+ struct smsc47m1_data *data = platform_get_drvdata(pdev);
+ struct resource *res;
+ platform_set_drvdata(pdev, NULL);
hwmon_device_unregister(data->class_dev);
- sysfs_remove_group(&client->dev.kobj, &smsc47m1_group);
-
- if ((err = i2c_detach_client(client)))
- return err;
+ sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group);
- release_region(client->addr, SMSC_EXTENT);
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ release_region(res->start, SMSC_EXTENT);
kfree(data);
return 0;
}
-static int smsc47m1_read_value(struct i2c_client *client, u8 reg)
-{
- int res;
-
- mutex_lock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
- res = inb_p(client->addr + reg);
- mutex_unlock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
- return res;
-}
-
-static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value)
-{
- mutex_lock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
- outb_p(value, client->addr + reg);
- mutex_unlock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
-}
-
static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
int init)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct smsc47m1_data *data = i2c_get_clientdata(client);
+ struct smsc47m1_data *data = dev_get_drvdata(dev);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
- int i;
-
- for (i = 0; i < 2; i++) {
- data->fan[i] = smsc47m1_read_value(client,
- SMSC47M1_REG_FAN(i));
- data->fan_preload[i] = smsc47m1_read_value(client,
- SMSC47M1_REG_FAN_PRELOAD(i));
- data->pwm[i] = smsc47m1_read_value(client,
- SMSC47M1_REG_PWM(i));
+ int i, fan_nr;
+ fan_nr = data->type == smsc47m2 ? 3 : 2;
+
+ for (i = 0; i < fan_nr; i++) {
+ data->fan[i] = smsc47m1_read_value(data,
+ SMSC47M1_REG_FAN[i]);
+ data->fan_preload[i] = smsc47m1_read_value(data,
+ SMSC47M1_REG_FAN_PRELOAD[i]);
+ data->pwm[i] = smsc47m1_read_value(data,
+ SMSC47M1_REG_PWM[i]);
}
- i = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV);
+ i = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV);
data->fan_div[0] = (i >> 4) & 0x03;
data->fan_div[1] = i >> 6;
- data->alarms = smsc47m1_read_value(client,
+ data->alarms = smsc47m1_read_value(data,
SMSC47M1_REG_ALARM) >> 6;
/* Clear alarms if needed */
if (data->alarms)
- smsc47m1_write_value(client, SMSC47M1_REG_ALARM, 0xC0);
+ smsc47m1_write_value(data, SMSC47M1_REG_ALARM, 0xC0);
+
+ if (fan_nr >= 3) {
+ data->fan_div[2] = (smsc47m1_read_value(data,
+ SMSC47M2_REG_FANDIV3) >> 4) & 0x03;
+ data->alarms |= (smsc47m1_read_value(data,
+ SMSC47M2_REG_ALARM6) & 0x40) >> 4;
+ /* Clear alarm if needed */
+ if (data->alarms & 0x04)
+ smsc47m1_write_value(data,
+ SMSC47M2_REG_ALARM6,
+ 0x40);
+ }
data->last_updated = jiffies;
}
@@ -608,18 +668,86 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
return data;
}
+static int __init smsc47m1_device_add(unsigned short address,
+ const struct smsc47m1_sio_data *sio_data)
+{
+ struct resource res = {
+ .start = address,
+ .end = address + SMSC_EXTENT - 1,
+ .name = DRVNAME,
+ .flags = IORESOURCE_IO,
+ };
+ int err;
+
+ pdev = platform_device_alloc(DRVNAME, address);
+ if (!pdev) {
+ err = -ENOMEM;
+ printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ goto exit;
+ }
+
+ err = platform_device_add_resources(pdev, &res, 1);
+ if (err) {
+ printk(KERN_ERR DRVNAME ": Device resource addition failed "
+ "(%d)\n", err);
+ goto exit_device_put;
+ }
+
+ pdev->dev.platform_data = kmalloc(sizeof(struct smsc47m1_sio_data),
+ GFP_KERNEL);
+ if (!pdev->dev.platform_data) {
+ err = -ENOMEM;
+ printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
+ goto exit_device_put;
+ }
+ memcpy(pdev->dev.platform_data, sio_data,
+ sizeof(struct smsc47m1_sio_data));
+
+ err = platform_device_add(pdev);
+ if (err) {
+ printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
+ err);
+ goto exit_device_put;
+ }
+
+ return 0;
+
+exit_device_put:
+ platform_device_put(pdev);
+exit:
+ return err;
+}
+
static int __init sm_smsc47m1_init(void)
{
- if (smsc47m1_find(&address)) {
+ int err;
+ unsigned short address;
+ struct smsc47m1_sio_data sio_data;
+
+ if (smsc47m1_find(&address, &sio_data))
return -ENODEV;
- }
- return i2c_isa_add_driver(&smsc47m1_driver);
+ err = platform_driver_register(&smsc47m1_driver);
+ if (err)
+ goto exit;
+
+ /* Sets global pdev as a side effect */
+ err = smsc47m1_device_add(address, &sio_data);
+ if (err)
+ goto exit_driver;
+
+ return 0;
+
+exit_driver:
+ platform_driver_unregister(&smsc47m1_driver);
+exit:
+ return err;
}
static void __exit sm_smsc47m1_exit(void)
{
- i2c_isa_del_driver(&smsc47m1_driver);
+ platform_device_unregister(pdev);
+ platform_driver_unregister(&smsc47m1_driver);
}
MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c
index a6833f4..a012f39 100644
--- a/drivers/hwmon/smsc47m192.c
+++ b/drivers/hwmon/smsc47m192.c
@@ -1,6 +1,6 @@
/*
smsc47m192.c - Support for hardware monitoring block of
- SMSC LPC47M192 and LPC47M997 Super I/O chips
+ SMSC LPC47M192 and compatible Super I/O chips
Copyright (C) 2006 Hartmut Rick <linux@rick.claranet.de>
@@ -518,7 +518,7 @@ static int smsc47m192_detect(struct i2c_adapter *adapter, int address,
&& (i2c_smbus_read_byte_data(client,
SMSC47M192_REG_VID4) & 0xfe) == 0x80) {
dev_info(&adapter->dev,
- "found SMSC47M192 or SMSC47M997, "
+ "found SMSC47M192 or compatible, "
"version 2, stepping A%d\n", version & 0x0f);
} else {
dev_dbg(&adapter->dev,
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index 89c23d6..9f3e332 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -31,6 +31,7 @@
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
+#include <linux/ioport.h>
#include <asm/io.h>
static int uch_config = -1;
@@ -1130,6 +1131,12 @@ static int __devinit vt1211_probe(struct platform_device *pdev)
}
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) {
+ err = -EBUSY;
+ dev_err(dev, "Failed to request region 0x%lx-0x%lx\n",
+ (unsigned long)res->start, (unsigned long)res->end);
+ goto EXIT_KFREE;
+ }
data->addr = res->start;
data->name = DRVNAME;
mutex_init(&data->update_lock);
@@ -1197,6 +1204,8 @@ EXIT_DEV_REMOVE:
dev_err(dev, "Sysfs interface creation failed (%d)\n", err);
EXIT_DEV_REMOVE_SILENT:
vt1211_remove_sysfs(pdev);
+ release_region(res->start, res->end - res->start + 1);
+EXIT_KFREE:
platform_set_drvdata(pdev, NULL);
kfree(data);
EXIT:
@@ -1206,12 +1215,16 @@ EXIT:
static int __devexit vt1211_remove(struct platform_device *pdev)
{
struct vt1211_data *data = platform_get_drvdata(pdev);
+ struct resource *res;
hwmon_device_unregister(data->class_dev);
vt1211_remove_sysfs(pdev);
platform_set_drvdata(pdev, NULL);
kfree(data);
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ release_region(res->start, res->end - res->start + 1);
+
return 0;
}
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index d7e2406..a5b774b 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -5,6 +5,7 @@
Philip Edelbrock <phil@netroedge.com>,
and Mark Studebaker <mdsxyz123@yahoo.com>
Ported to 2.6 by Bernhard C. Schrenk <clemy@clemy.org>
+ Copyright (c) 2007 Jean Delvare <khali@linux-fr.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -42,15 +43,20 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-isa.h>
+#include <linux/platform_device.h>
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
+#include <linux/ioport.h>
#include <asm/io.h>
#include "lm75.h"
+static struct platform_device *pdev;
+
+#define DRVNAME "w83627hf"
+enum chips { w83627hf, w83627thf, w83697hf, w83637hf, w83687thf };
+
static u16 force_addr;
module_param(force_addr, ushort, 0);
MODULE_PARM_DESC(force_addr,
@@ -60,12 +66,6 @@ module_param(force_i2c, byte, 0);
MODULE_PARM_DESC(force_i2c,
"Initialize the i2c address of the sensors");
-/* The actual ISA address is read from Super-I/O configuration space */
-static unsigned short address;
-
-/* Insmod parameters */
-enum chips { any_chip, w83627hf, w83627thf, w83697hf, w83637hf, w83687thf };
-
static int reset;
module_param(reset, bool, 0);
MODULE_PARM_DESC(reset, "Set to one to reset chip on load");
@@ -156,9 +156,9 @@ superio_exit(void)
#define WINB_REGION_OFFSET 5
#define WINB_REGION_SIZE 2
-/* Where are the sensors address/data registers relative to the base address */
-#define W83781D_ADDR_REG_OFFSET 5
-#define W83781D_DATA_REG_OFFSET 6
+/* Where are the sensors address/data registers relative to the region offset */
+#define W83781D_ADDR_REG_OFFSET 0
+#define W83781D_DATA_REG_OFFSET 1
/* The W83781D registers */
/* The W83782D registers for nr=7,8 are in bank 5 */
@@ -289,7 +289,8 @@ static inline u8 DIV_TO_REG(long val)
/* For each registered chip, we need to keep some data in memory.
The structure is dynamically allocated. */
struct w83627hf_data {
- struct i2c_client client;
+ unsigned short addr;
+ const char *name;
struct class_device *class_dev;
struct mutex lock;
enum chips type;
@@ -298,9 +299,6 @@ struct w83627hf_data {
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
- struct i2c_client *lm75; /* for secondary I2C addresses */
- /* pointer to array of 2 subclients */
-
u8 in[9]; /* Register value */
u8 in_max[9]; /* Register value */
u8 in_min[9]; /* Register value */
@@ -327,22 +325,26 @@ struct w83627hf_data {
u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */
};
+struct w83627hf_sio_data {
+ enum chips type;
+};
+
-static int w83627hf_detect(struct i2c_adapter *adapter);
-static int w83627hf_detach_client(struct i2c_client *client);
+static int w83627hf_probe(struct platform_device *pdev);
+static int w83627hf_remove(struct platform_device *pdev);
-static int w83627hf_read_value(struct i2c_client *client, u16 reg);
-static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value);
+static int w83627hf_read_value(struct w83627hf_data *data, u16 reg);
+static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value);
static struct w83627hf_data *w83627hf_update_device(struct device *dev);
-static void w83627hf_init_client(struct i2c_client *client);
+static void w83627hf_init_device(struct platform_device *pdev);
-static struct i2c_driver w83627hf_driver = {
+static struct platform_driver w83627hf_driver = {
.driver = {
.owner = THIS_MODULE,
- .name = "w83627hf",
+ .name = DRVNAME,
},
- .attach_adapter = w83627hf_detect,
- .detach_client = w83627hf_detach_client,
+ .probe = w83627hf_probe,
+ .remove = __devexit_p(w83627hf_remove),
};
/* following are the sysfs callback functions */
@@ -360,15 +362,14 @@ show_in_reg(in_max)
static ssize_t \
store_in_##reg (struct device *dev, const char *buf, size_t count, int nr) \
{ \
- struct i2c_client *client = to_i2c_client(dev); \
- struct w83627hf_data *data = i2c_get_clientdata(client); \
+ struct w83627hf_data *data = dev_get_drvdata(dev); \
u32 val; \
\
val = simple_strtoul(buf, NULL, 10); \
\
mutex_lock(&data->update_lock); \
data->in_##reg[nr] = IN_TO_REG(val); \
- w83627hf_write_value(client, W83781D_REG_IN_##REG(nr), \
+ w83627hf_write_value(data, W83781D_REG_IN_##REG(nr), \
data->in_##reg[nr]); \
\
mutex_unlock(&data->update_lock); \
@@ -452,8 +453,7 @@ static ssize_t show_regs_in_max0(struct device *dev, struct device_attribute *at
static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83627hf_data *data = i2c_get_clientdata(client);
+ struct w83627hf_data *data = dev_get_drvdata(dev);
u32 val;
val = simple_strtoul(buf, NULL, 10);
@@ -472,7 +472,7 @@ static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *a
/* use VRM8 (standard) calculation */
data->in_min[0] = IN_TO_REG(val);
- w83627hf_write_value(client, W83781D_REG_IN_MIN(0), data->in_min[0]);
+ w83627hf_write_value(data, W83781D_REG_IN_MIN(0), data->in_min[0]);
mutex_unlock(&data->update_lock);
return count;
}
@@ -480,8 +480,7 @@ static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *a
static ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83627hf_data *data = i2c_get_clientdata(client);
+ struct w83627hf_data *data = dev_get_drvdata(dev);
u32 val;
val = simple_strtoul(buf, NULL, 10);
@@ -500,7 +499,7 @@ static ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *a
/* use VRM8 (standard) calculation */
data->in_max[0] = IN_TO_REG(val);
- w83627hf_write_value(client, W83781D_REG_IN_MAX(0), data->in_max[0]);
+ w83627hf_write_value(data, W83781D_REG_IN_MAX(0), data->in_max[0]);
mutex_unlock(&data->update_lock);
return count;
}
@@ -525,8 +524,7 @@ show_fan_reg(fan_min);
static ssize_t
store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83627hf_data *data = i2c_get_clientdata(client);
+ struct w83627hf_data *data = dev_get_drvdata(dev);
u32 val;
val = simple_strtoul(buf, NULL, 10);
@@ -534,7 +532,7 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
mutex_lock(&data->update_lock);
data->fan_min[nr - 1] =
FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1]));
- w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr),
+ w83627hf_write_value(data, W83781D_REG_FAN_MIN(nr),
data->fan_min[nr - 1]);
mutex_unlock(&data->update_lock);
@@ -587,8 +585,7 @@ show_temp_reg(temp_max_hyst);
static ssize_t \
store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \
{ \
- struct i2c_client *client = to_i2c_client(dev); \
- struct w83627hf_data *data = i2c_get_clientdata(client); \
+ struct w83627hf_data *data = dev_get_drvdata(dev); \
u32 val; \
\
val = simple_strtoul(buf, NULL, 10); \
@@ -597,11 +594,11 @@ store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \
\
if (nr >= 2) { /* TEMP2 and TEMP3 */ \
data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \
- w83627hf_write_value(client, W83781D_REG_TEMP_##REG(nr), \
+ w83627hf_write_value(data, W83781D_REG_TEMP_##REG(nr), \
data->temp_##reg##_add[nr-2]); \
} else { /* TEMP1 */ \
data->temp_##reg = TEMP_TO_REG(val); \
- w83627hf_write_value(client, W83781D_REG_TEMP_##REG(nr), \
+ w83627hf_write_value(data, W83781D_REG_TEMP_##REG(nr), \
data->temp_##reg); \
} \
\
@@ -659,8 +656,7 @@ show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
static ssize_t
store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83627hf_data *data = i2c_get_clientdata(client);
+ struct w83627hf_data *data = dev_get_drvdata(dev);
u32 val;
val = simple_strtoul(buf, NULL, 10);
@@ -695,8 +691,7 @@ static ssize_t
store_beep_reg(struct device *dev, const char *buf, size_t count,
int update_mask)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83627hf_data *data = i2c_get_clientdata(client);
+ struct w83627hf_data *data = dev_get_drvdata(dev);
u32 val, val2;
val = simple_strtoul(buf, NULL, 10);
@@ -705,18 +700,18 @@ store_beep_reg(struct device *dev, const char *buf, size_t count,
if (update_mask == BEEP_MASK) { /* We are storing beep_mask */
data->beep_mask = BEEP_MASK_TO_REG(val);
- w83627hf_write_value(client, W83781D_REG_BEEP_INTS1,
+ w83627hf_write_value(data, W83781D_REG_BEEP_INTS1,
data->beep_mask & 0xff);
- w83627hf_write_value(client, W83781D_REG_BEEP_INTS3,
+ w83627hf_write_value(data, W83781D_REG_BEEP_INTS3,
((data->beep_mask) >> 16) & 0xff);
val2 = (data->beep_mask >> 8) & 0x7f;
} else { /* We are storing beep_enable */
val2 =
- w83627hf_read_value(client, W83781D_REG_BEEP_INTS2) & 0x7f;
+ w83627hf_read_value(data, W83781D_REG_BEEP_INTS2) & 0x7f;
data->beep_enable = BEEP_ENABLE_TO_REG(val);
}
- w83627hf_write_value(client, W83781D_REG_BEEP_INTS2,
+ w83627hf_write_value(data, W83781D_REG_BEEP_INTS2,
val2 | data->beep_enable << 7);
mutex_unlock(&data->update_lock);
@@ -754,8 +749,7 @@ show_fan_div_reg(struct device *dev, char *buf, int nr)
static ssize_t
store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83627hf_data *data = i2c_get_clientdata(client);
+ struct w83627hf_data *data = dev_get_drvdata(dev);
unsigned long min;
u8 reg;
unsigned long val = simple_strtoul(buf, NULL, 10);
@@ -768,19 +762,19 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
data->fan_div[nr] = DIV_TO_REG(val);
- reg = (w83627hf_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
+ reg = (w83627hf_read_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
& (nr==0 ? 0xcf : 0x3f))
| ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6));
- w83627hf_write_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);
+ w83627hf_write_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);
- reg = (w83627hf_read_value(client, W83781D_REG_VBAT)
+ reg = (w83627hf_read_value(data, W83781D_REG_VBAT)
& ~(1 << (5 + nr)))
| ((data->fan_div[nr] & 0x04) << (3 + nr));
- w83627hf_write_value(client, W83781D_REG_VBAT, reg);
+ w83627hf_write_value(data, W83781D_REG_VBAT, reg);
/* Restore fan_min */
data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
- w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
+ w83627hf_write_value(data, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
mutex_unlock(&data->update_lock);
return count;
@@ -814,8 +808,7 @@ show_pwm_reg(struct device *dev, char *buf, int nr)
static ssize_t
store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83627hf_data *data = i2c_get_clientdata(client);
+ struct w83627hf_data *data = dev_get_drvdata(dev);
u32 val;
val = simple_strtoul(buf, NULL, 10);
@@ -825,14 +818,14 @@ store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr)
if (data->type == w83627thf) {
/* bits 0-3 are reserved in 627THF */
data->pwm[nr - 1] = PWM_TO_REG(val) & 0xf0;
- w83627hf_write_value(client,
+ w83627hf_write_value(data,
W836X7HF_REG_PWM(data->type, nr),
data->pwm[nr - 1] |
- (w83627hf_read_value(client,
+ (w83627hf_read_value(data,
W836X7HF_REG_PWM(data->type, nr)) & 0x0f));
} else {
data->pwm[nr - 1] = PWM_TO_REG(val);
- w83627hf_write_value(client,
+ w83627hf_write_value(data,
W836X7HF_REG_PWM(data->type, nr),
data->pwm[nr - 1]);
}
@@ -868,8 +861,7 @@ show_sensor_reg(struct device *dev, char *buf, int nr)
static ssize_t
store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83627hf_data *data = i2c_get_clientdata(client);
+ struct w83627hf_data *data = dev_get_drvdata(dev);
u32 val, tmp;
val = simple_strtoul(buf, NULL, 10);
@@ -878,31 +870,31 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
switch (val) {
case 1: /* PII/Celeron diode */
- tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
- w83627hf_write_value(client, W83781D_REG_SCFG1,
+ tmp = w83627hf_read_value(data, W83781D_REG_SCFG1);
+ w83627hf_write_value(data, W83781D_REG_SCFG1,
tmp | BIT_SCFG1[nr - 1]);
- tmp = w83627hf_read_value(client, W83781D_REG_SCFG2);
- w83627hf_write_value(client, W83781D_REG_SCFG2,
+ tmp = w83627hf_read_value(data, W83781D_REG_SCFG2);
+ w83627hf_write_value(data, W83781D_REG_SCFG2,
tmp | BIT_SCFG2[nr - 1]);
data->sens[nr - 1] = val;
break;
case 2: /* 3904 */
- tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
- w83627hf_write_value(client, W83781D_REG_SCFG1,
+ tmp = w83627hf_read_value(data, W83781D_REG_SCFG1);
+ w83627hf_write_value(data, W83781D_REG_SCFG1,
tmp | BIT_SCFG1[nr - 1]);
- tmp = w83627hf_read_value(client, W83781D_REG_SCFG2);
- w83627hf_write_value(client, W83781D_REG_SCFG2,
+ tmp = w83627hf_read_value(data, W83781D_REG_SCFG2);
+ w83627hf_write_value(data, W83781D_REG_SCFG2,
tmp & ~BIT_SCFG2[nr - 1]);
data->sens[nr - 1] = val;
break;
case W83781D_DEFAULT_BETA: /* thermistor */
- tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
- w83627hf_write_value(client, W83781D_REG_SCFG1,
+ tmp = w83627hf_read_value(data, W83781D_REG_SCFG1);
+ w83627hf_write_value(data, W83781D_REG_SCFG1,
tmp & ~BIT_SCFG1[nr - 1]);
data->sens[nr - 1] = val;
break;
default:
- dev_err(&client->dev,
+ dev_err(dev,
"Invalid sensor type %ld; must be 1, 2, or %d\n",
(long) val, W83781D_DEFAULT_BETA);
break;
@@ -929,35 +921,85 @@ sysfs_sensor(1);
sysfs_sensor(2);
sysfs_sensor(3);
-static int __init w83627hf_find(int sioaddr, unsigned short *addr)
+static ssize_t show_name(struct device *dev, struct device_attribute
+ *devattr, char *buf)
+{
+ struct w83627hf_data *data = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%s\n", data->name);
+}
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+static int __init w83627hf_find(int sioaddr, unsigned short *addr,
+ struct w83627hf_sio_data *sio_data)
{
+ int err = -ENODEV;
u16 val;
+ static const __initdata char *names[] = {
+ "W83627HF",
+ "W83627THF",
+ "W83697HF",
+ "W83637HF",
+ "W83687THF",
+ };
+
REG = sioaddr;
VAL = sioaddr + 1;
superio_enter();
val= superio_inb(DEVID);
- if(val != W627_DEVID &&
- val != W627THF_DEVID &&
- val != W697_DEVID &&
- val != W637_DEVID &&
- val != W687THF_DEVID) {
- superio_exit();
- return -ENODEV;
+ switch (val) {
+ case W627_DEVID:
+ sio_data->type = w83627hf;
+ break;
+ case W627THF_DEVID:
+ sio_data->type = w83627thf;
+ break;
+ case W697_DEVID:
+ sio_data->type = w83697hf;
+ break;
+ case W637_DEVID:
+ sio_data->type = w83637hf;
+ break;
+ case W687THF_DEVID:
+ sio_data->type = w83687thf;
+ break;
+ default:
+ pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%x)\n", val);
+ goto exit;
}
superio_select(W83627HF_LD_HWM);
+ force_addr &= WINB_ALIGNMENT;
+ if (force_addr) {
+ printk(KERN_WARNING DRVNAME ": Forcing address 0x%x\n",
+ force_addr);
+ superio_outb(WINB_BASE_REG, force_addr >> 8);
+ superio_outb(WINB_BASE_REG + 1, force_addr & 0xff);
+ }
val = (superio_inb(WINB_BASE_REG) << 8) |
superio_inb(WINB_BASE_REG + 1);
*addr = val & WINB_ALIGNMENT;
- if (*addr == 0 && force_addr == 0) {
- superio_exit();
- return -ENODEV;
+ if (*addr == 0) {
+ printk(KERN_WARNING DRVNAME ": Base address not set, "
+ "skipping\n");
+ goto exit;
}
+ val = superio_inb(WINB_ACT_REG);
+ if (!(val & 0x01)) {
+ printk(KERN_WARNING DRVNAME ": Enabling HWM logical device\n");
+ superio_outb(WINB_ACT_REG, val | 0x01);
+ }
+
+ err = 0;
+ pr_info(DRVNAME ": Found %s chip at %#x\n",
+ names[sio_data->type], *addr);
+
+ exit:
superio_exit();
- return 0;
+ return err;
}
static struct attribute *w83627hf_attributes[] = {
@@ -1003,6 +1045,7 @@ static struct attribute *w83627hf_attributes[] = {
&dev_attr_pwm1.attr,
&dev_attr_pwm2.attr,
+ &dev_attr_name.attr,
NULL
};
@@ -1039,161 +1082,92 @@ static const struct attribute_group w83627hf_group_opt = {
.attrs = w83627hf_attributes_opt,
};
-static int w83627hf_detect(struct i2c_adapter *adapter)
+static int __devinit w83627hf_probe(struct platform_device *pdev)
{
- int val, kind;
- struct i2c_client *new_client;
+ struct device *dev = &pdev->dev;
+ struct w83627hf_sio_data *sio_data = dev->platform_data;
struct w83627hf_data *data;
- int err = 0;
- const char *client_name = "";
-
- if(force_addr)
- address = force_addr & WINB_ALIGNMENT;
+ struct resource *res;
+ int err;
- if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE,
- w83627hf_driver.driver.name)) {
+ static const char *names[] = {
+ "w83627hf",
+ "w83627thf",
+ "w83697hf",
+ "w83637hf",
+ "w83687thf",
+ };
+
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!request_region(res->start, WINB_REGION_SIZE, DRVNAME)) {
+ dev_err(dev, "Failed to request region 0x%lx-0x%lx\n",
+ (unsigned long)res->start,
+ (unsigned long)(res->start + WINB_REGION_SIZE - 1));
err = -EBUSY;
goto ERROR0;
}
- if(force_addr) {
- printk("w83627hf.o: forcing ISA address 0x%04X\n", address);
- superio_enter();
- superio_select(W83627HF_LD_HWM);
- superio_outb(WINB_BASE_REG, address >> 8);
- superio_outb(WINB_BASE_REG+1, address & 0xff);
- superio_exit();
- }
-
- superio_enter();
- val= superio_inb(DEVID);
- if(val == W627_DEVID)
- kind = w83627hf;
- else if(val == W697_DEVID)
- kind = w83697hf;
- else if(val == W627THF_DEVID)
- kind = w83627thf;
- else if(val == W637_DEVID)
- kind = w83637hf;
- else if (val == W687THF_DEVID)
- kind = w83687thf;
- else {
- dev_info(&adapter->dev,
- "Unsupported chip (dev_id=0x%02X).\n", val);
- goto ERROR1;
- }
-
- superio_select(W83627HF_LD_HWM);
- if((val = 0x01 & superio_inb(WINB_ACT_REG)) == 0)
- superio_outb(WINB_ACT_REG, 1);
- superio_exit();
-
- /* OK. For now, we presume we have a valid client. We now create the
- client structure, even though we cannot fill it completely yet.
- But it allows us to access w83627hf_{read,write}_value. */
-
if (!(data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) {
err = -ENOMEM;
goto ERROR1;
}
-
- new_client = &data->client;
- i2c_set_clientdata(new_client, data);
- new_client->addr = address;
+ data->addr = res->start;
+ data->type = sio_data->type;
+ data->name = names[sio_data->type];
mutex_init(&data->lock);
- new_client->adapter = adapter;
- new_client->driver = &w83627hf_driver;
- new_client->flags = 0;
-
-
- if (kind == w83627hf) {
- client_name = "w83627hf";
- } else if (kind == w83627thf) {
- client_name = "w83627thf";
- } else if (kind == w83697hf) {
- client_name = "w83697hf";
- } else if (kind == w83637hf) {
- client_name = "w83637hf";
- } else if (kind == w83687thf) {
- client_name = "w83687thf";
- }
-
- /* Fill in the remaining client fields and put into the global list */
- strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
- data->type = kind;
- data->valid = 0;
mutex_init(&data->update_lock);
-
- /* Tell the I2C layer a new client has arrived */
- if ((err = i2c_attach_client(new_client)))
- goto ERROR2;
-
- data->lm75 = NULL;
+ platform_set_drvdata(pdev, data);
/* Initialize the chip */
- w83627hf_init_client(new_client);
+ w83627hf_init_device(pdev);
/* A few vars need to be filled upon startup */
- data->fan_min[0] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(1));
- data->fan_min[1] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(2));
- data->fan_min[2] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(3));
+ data->fan_min[0] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(1));
+ data->fan_min[1] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(2));
+ data->fan_min[2] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(3));
/* Register common device attributes */
- if ((err = sysfs_create_group(&new_client->dev.kobj, &w83627hf_group)))
+ if ((err = sysfs_create_group(&dev->kobj, &w83627hf_group)))
goto ERROR3;
/* Register chip-specific device attributes */
- if (kind == w83627hf || kind == w83697hf)
- if ((err = device_create_file(&new_client->dev,
- &dev_attr_in5_input))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_in5_min))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_in5_max))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_in6_input))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_in6_min))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_in6_max)))
+ if (data->type == w83627hf || data->type == w83697hf)
+ if ((err = device_create_file(dev, &dev_attr_in5_input))
+ || (err = device_create_file(dev, &dev_attr_in5_min))
+ || (err = device_create_file(dev, &dev_attr_in5_max))
+ || (err = device_create_file(dev, &dev_attr_in6_input))
+ || (err = device_create_file(dev, &dev_attr_in6_min))
+ || (err = device_create_file(dev, &dev_attr_in6_max)))
goto ERROR4;
- if (kind != w83697hf)
- if ((err = device_create_file(&new_client->dev,
- &dev_attr_in1_input))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_in1_min))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_in1_max))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_fan3_input))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_fan3_min))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_fan3_div))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_temp3_input))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_temp3_max))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_temp3_max_hyst))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_temp3_type)))
+ if (data->type != w83697hf)
+ if ((err = device_create_file(dev, &dev_attr_in1_input))
+ || (err = device_create_file(dev, &dev_attr_in1_min))
+ || (err = device_create_file(dev, &dev_attr_in1_max))
+ || (err = device_create_file(dev, &dev_attr_fan3_input))
+ || (err = device_create_file(dev, &dev_attr_fan3_min))
+ || (err = device_create_file(dev, &dev_attr_fan3_div))
+ || (err = device_create_file(dev, &dev_attr_temp3_input))
+ || (err = device_create_file(dev, &dev_attr_temp3_max))
+ || (err = device_create_file(dev, &dev_attr_temp3_max_hyst))
+ || (err = device_create_file(dev, &dev_attr_temp3_type)))
goto ERROR4;
- if (kind != w83697hf && data->vid != 0xff)
- if ((err = device_create_file(&new_client->dev,
- &dev_attr_cpu0_vid))
- || (err = device_create_file(&new_client->dev,
- &dev_attr_vrm)))
+ if (data->type != w83697hf && data->vid != 0xff) {
+ /* Convert VID to voltage based on VRM */
+ data->vrm = vid_which_vrm();
+
+ if ((err = device_create_file(dev, &dev_attr_cpu0_vid))
+ || (err = device_create_file(dev, &dev_attr_vrm)))
goto ERROR4;
+ }
- if (kind == w83627thf || kind == w83637hf || kind == w83687thf)
- if ((err = device_create_file(&new_client->dev,
- &dev_attr_pwm3)))
+ if (data->type == w83627thf || data->type == w83637hf
+ || data->type == w83687thf)
+ if ((err = device_create_file(dev, &dev_attr_pwm3)))
goto ERROR4;
- data->class_dev = hwmon_device_register(&new_client->dev);
+ data->class_dev = hwmon_device_register(dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto ERROR4;
@@ -1202,47 +1176,37 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
return 0;
ERROR4:
- sysfs_remove_group(&new_client->dev.kobj, &w83627hf_group);
- sysfs_remove_group(&new_client->dev.kobj, &w83627hf_group_opt);
+ sysfs_remove_group(&dev->kobj, &w83627hf_group);
+ sysfs_remove_group(&dev->kobj, &w83627hf_group_opt);
ERROR3:
- i2c_detach_client(new_client);
- ERROR2:
kfree(data);
ERROR1:
- release_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE);
+ release_region(res->start, WINB_REGION_SIZE);
ERROR0:
return err;
}
-static int w83627hf_detach_client(struct i2c_client *client)
+static int __devexit w83627hf_remove(struct platform_device *pdev)
{
- struct w83627hf_data *data = i2c_get_clientdata(client);
- int err;
+ struct w83627hf_data *data = platform_get_drvdata(pdev);
+ struct resource *res;
+ platform_set_drvdata(pdev, NULL);
hwmon_device_unregister(data->class_dev);
- sysfs_remove_group(&client->dev.kobj, &w83627hf_group);
- sysfs_remove_group(&client->dev.kobj, &w83627hf_group_opt);
-
- if ((err = i2c_detach_client(client)))
- return err;
-
- release_region(client->addr + WINB_REGION_OFFSET, WINB_REGION_SIZE);
+ sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group);
+ sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt);
kfree(data);
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ release_region(res->start, WINB_REGION_SIZE);
+
return 0;
}
-/*
- ISA access must always be locked explicitly!
- We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
- would slow down the W83781D access and should not be necessary.
- There are some ugly typecasts here, but the good news is - they should
- nowhere else be necessary! */
-static int w83627hf_read_value(struct i2c_client *client, u16 reg)
+static int w83627hf_read_value(struct w83627hf_data *data, u16 reg)
{
- struct w83627hf_data *data = i2c_get_clientdata(client);
int res, word_sized;
mutex_lock(&data->lock);
@@ -1253,29 +1217,29 @@ static int w83627hf_read_value(struct i2c_client *client, u16 reg)
|| ((reg & 0x00ff) == 0x55));
if (reg & 0xff00) {
outb_p(W83781D_REG_BANK,
- client->addr + W83781D_ADDR_REG_OFFSET);
+ data->addr + W83781D_ADDR_REG_OFFSET);
outb_p(reg >> 8,
- client->addr + W83781D_DATA_REG_OFFSET);
+ data->addr + W83781D_DATA_REG_OFFSET);
}
- outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET);
- res = inb_p(client->addr + W83781D_DATA_REG_OFFSET);
+ outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET);
+ res = inb_p(data->addr + W83781D_DATA_REG_OFFSET);
if (word_sized) {
outb_p((reg & 0xff) + 1,
- client->addr + W83781D_ADDR_REG_OFFSET);
+ data->addr + W83781D_ADDR_REG_OFFSET);
res =
- (res << 8) + inb_p(client->addr +
+ (res << 8) + inb_p(data->addr +
W83781D_DATA_REG_OFFSET);
}
if (reg & 0xff00) {
outb_p(W83781D_REG_BANK,
- client->addr + W83781D_ADDR_REG_OFFSET);
- outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
+ data->addr + W83781D_ADDR_REG_OFFSET);
+ outb_p(0, data->addr + W83781D_DATA_REG_OFFSET);
}
mutex_unlock(&data->lock);
return res;
}
-static int w83627thf_read_gpio5(struct i2c_client *client)
+static int __devinit w83627thf_read_gpio5(struct platform_device *pdev)
{
int res = 0xff, sel;
@@ -1284,7 +1248,7 @@ static int w83627thf_read_gpio5(struct i2c_client *client)
/* Make sure these GPIO pins are enabled */
if (!(superio_inb(W83627THF_GPIO5_EN) & (1<<3))) {
- dev_dbg(&client->dev, "GPIO5 disabled, no VID function\n");
+ dev_dbg(&pdev->dev, "GPIO5 disabled, no VID function\n");
goto exit;
}
@@ -1292,12 +1256,12 @@ static int w83627thf_read_gpio5(struct i2c_client *client)
There must be at least five (VRM 9), and possibly 6 (VRM 10) */
sel = superio_inb(W83627THF_GPIO5_IOSR) & 0x3f;
if ((sel & 0x1f) != 0x1f) {
- dev_dbg(&client->dev, "GPIO5 not configured for VID "
+ dev_dbg(&pdev->dev, "GPIO5 not configured for VID "
"function\n");
goto exit;
}
- dev_info(&client->dev, "Reading VID from GPIO5\n");
+ dev_info(&pdev->dev, "Reading VID from GPIO5\n");
res = superio_inb(W83627THF_GPIO5_DR) & sel;
exit:
@@ -1305,7 +1269,7 @@ exit:
return res;
}
-static int w83687thf_read_vid(struct i2c_client *client)
+static int __devinit w83687thf_read_vid(struct platform_device *pdev)
{
int res = 0xff;
@@ -1314,13 +1278,13 @@ static int w83687thf_read_vid(struct i2c_client *client)
/* Make sure these GPIO pins are enabled */
if (!(superio_inb(W83687THF_VID_EN) & (1 << 2))) {
- dev_dbg(&client->dev, "VID disabled, no VID function\n");
+ dev_dbg(&pdev->dev, "VID disabled, no VID function\n");
goto exit;
}
/* Make sure the pins are configured for input */
if (!(superio_inb(W83687THF_VID_CFG) & (1 << 4))) {
- dev_dbg(&client->dev, "VID configured as output, "
+ dev_dbg(&pdev->dev, "VID configured as output, "
"no VID function\n");
goto exit;
}
@@ -1332,9 +1296,8 @@ exit:
return res;
}
-static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value)
+static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value)
{
- struct w83627hf_data *data = i2c_get_clientdata(client);
int word_sized;
mutex_lock(&data->lock);
@@ -1344,33 +1307,33 @@ static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value)
|| ((reg & 0x00ff) == 0x55));
if (reg & 0xff00) {
outb_p(W83781D_REG_BANK,
- client->addr + W83781D_ADDR_REG_OFFSET);
+ data->addr + W83781D_ADDR_REG_OFFSET);
outb_p(reg >> 8,
- client->addr + W83781D_DATA_REG_OFFSET);
+ data->addr + W83781D_DATA_REG_OFFSET);
}
- outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET);
+ outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET);
if (word_sized) {
outb_p(value >> 8,
- client->addr + W83781D_DATA_REG_OFFSET);
+ data->addr + W83781D_DATA_REG_OFFSET);
outb_p((reg & 0xff) + 1,
- client->addr + W83781D_ADDR_REG_OFFSET);
+ data->addr + W83781D_ADDR_REG_OFFSET);
}
outb_p(value & 0xff,
- client->addr + W83781D_DATA_REG_OFFSET);
+ data->addr + W83781D_DATA_REG_OFFSET);
if (reg & 0xff00) {
outb_p(W83781D_REG_BANK,
- client->addr + W83781D_ADDR_REG_OFFSET);
- outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
+ data->addr + W83781D_ADDR_REG_OFFSET);
+ outb_p(0, data->addr + W83781D_DATA_REG_OFFSET);
}
mutex_unlock(&data->lock);
return 0;
}
-static void w83627hf_init_client(struct i2c_client *client)
+static void __devinit w83627hf_init_device(struct platform_device *pdev)
{
- struct w83627hf_data *data = i2c_get_clientdata(client);
+ struct w83627hf_data *data = platform_get_drvdata(pdev);
int i;
- int type = data->type;
+ enum chips type = data->type;
u8 tmp;
if (reset) {
@@ -1379,57 +1342,53 @@ static void w83627hf_init_client(struct i2c_client *client)
speed...) so it is now optional. It might even go away if
nobody reports it as being useful, as I see very little
reason why this would be needed at all. */
- dev_info(&client->dev, "If reset=1 solved a problem you were "
+ dev_info(&pdev->dev, "If reset=1 solved a problem you were "
"having, please report!\n");
/* save this register */
- i = w83627hf_read_value(client, W83781D_REG_BEEP_CONFIG);
+ i = w83627hf_read_value(data, W83781D_REG_BEEP_CONFIG);
/* Reset all except Watchdog values and last conversion values
This sets fan-divs to 2, among others */
- w83627hf_write_value(client, W83781D_REG_CONFIG, 0x80);
+ w83627hf_write_value(data, W83781D_REG_CONFIG, 0x80);
/* Restore the register and disable power-on abnormal beep.
This saves FAN 1/2/3 input/output values set by BIOS. */
- w83627hf_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80);
+ w83627hf_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80);
/* Disable master beep-enable (reset turns it on).
Individual beeps should be reset to off but for some reason
disabling this bit helps some people not get beeped */
- w83627hf_write_value(client, W83781D_REG_BEEP_INTS2, 0);
+ w83627hf_write_value(data, W83781D_REG_BEEP_INTS2, 0);
}
/* Minimize conflicts with other winbond i2c-only clients... */
/* disable i2c subclients... how to disable main i2c client?? */
/* force i2c address to relatively uncommon address */
- w83627hf_write_value(client, W83781D_REG_I2C_SUBADDR, 0x89);
- w83627hf_write_value(client, W83781D_REG_I2C_ADDR, force_i2c);
+ w83627hf_write_value(data, W83781D_REG_I2C_SUBADDR, 0x89);
+ w83627hf_write_value(data, W83781D_REG_I2C_ADDR, force_i2c);
/* Read VID only once */
- if (w83627hf == data->type || w83637hf == data->type) {
- int lo = w83627hf_read_value(client, W83781D_REG_VID_FANDIV);
- int hi = w83627hf_read_value(client, W83781D_REG_CHIPID);
+ if (type == w83627hf || type == w83637hf) {
+ int lo = w83627hf_read_value(data, W83781D_REG_VID_FANDIV);
+ int hi = w83627hf_read_value(data, W83781D_REG_CHIPID);
data->vid = (lo & 0x0f) | ((hi & 0x01) << 4);
- } else if (w83627thf == data->type) {
- data->vid = w83627thf_read_gpio5(client);
- } else if (w83687thf == data->type) {
- data->vid = w83687thf_read_vid(client);
+ } else if (type == w83627thf) {
+ data->vid = w83627thf_read_gpio5(pdev);
+ } else if (type == w83687thf) {
+ data->vid = w83687thf_read_vid(pdev);
}
/* Read VRM & OVT Config only once */
- if (w83627thf == data->type || w83637hf == data->type
- || w83687thf == data->type) {
+ if (type == w83627thf || type == w83637hf || type == w83687thf) {
data->vrm_ovt =
- w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG);
+ w83627hf_read_value(data, W83627THF_REG_VRM_OVT_CFG);
}
- /* Convert VID to voltage based on VRM */
- data->vrm = vid_which_vrm();
-
- tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
+ tmp = w83627hf_read_value(data, W83781D_REG_SCFG1);
for (i = 1; i <= 3; i++) {
if (!(tmp & BIT_SCFG1[i - 1])) {
data->sens[i - 1] = W83781D_DEFAULT_BETA;
} else {
if (w83627hf_read_value
- (client,
+ (data,
W83781D_REG_SCFG2) & BIT_SCFG2[i - 1])
data->sens[i - 1] = 1;
else
@@ -1441,38 +1400,37 @@ static void w83627hf_init_client(struct i2c_client *client)
if(init) {
/* Enable temp2 */
- tmp = w83627hf_read_value(client, W83781D_REG_TEMP2_CONFIG);
+ tmp = w83627hf_read_value(data, W83781D_REG_TEMP2_CONFIG);
if (tmp & 0x01) {
- dev_warn(&client->dev, "Enabling temp2, readings "
+ dev_warn(&pdev->dev, "Enabling temp2, readings "
"might not make sense\n");
- w83627hf_write_value(client, W83781D_REG_TEMP2_CONFIG,
+ w83627hf_write_value(data, W83781D_REG_TEMP2_CONFIG,
tmp & 0xfe);
}
/* Enable temp3 */
if (type != w83697hf) {
- tmp = w83627hf_read_value(client,
+ tmp = w83627hf_read_value(data,
W83781D_REG_TEMP3_CONFIG);
if (tmp & 0x01) {
- dev_warn(&client->dev, "Enabling temp3, "
+ dev_warn(&pdev->dev, "Enabling temp3, "
"readings might not make sense\n");
- w83627hf_write_value(client,
+ w83627hf_write_value(data,
W83781D_REG_TEMP3_CONFIG, tmp & 0xfe);
}
}
}
/* Start monitoring */
- w83627hf_write_value(client, W83781D_REG_CONFIG,
- (w83627hf_read_value(client,
+ w83627hf_write_value(data, W83781D_REG_CONFIG,
+ (w83627hf_read_value(data,
W83781D_REG_CONFIG) & 0xf7)
| 0x01);
}
static struct w83627hf_data *w83627hf_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83627hf_data *data = i2c_get_clientdata(client);
+ struct w83627hf_data *data = dev_get_drvdata(dev);
int i;
mutex_lock(&data->update_lock);
@@ -1486,23 +1444,23 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
&& (i == 5 || i == 6)))
continue;
data->in[i] =
- w83627hf_read_value(client, W83781D_REG_IN(i));
+ w83627hf_read_value(data, W83781D_REG_IN(i));
data->in_min[i] =
- w83627hf_read_value(client,
+ w83627hf_read_value(data,
W83781D_REG_IN_MIN(i));
data->in_max[i] =
- w83627hf_read_value(client,
+ w83627hf_read_value(data,
W83781D_REG_IN_MAX(i));
}
for (i = 1; i <= 3; i++) {
data->fan[i - 1] =
- w83627hf_read_value(client, W83781D_REG_FAN(i));
+ w83627hf_read_value(data, W83781D_REG_FAN(i));
data->fan_min[i - 1] =
- w83627hf_read_value(client,
+ w83627hf_read_value(data,
W83781D_REG_FAN_MIN(i));
}
for (i = 1; i <= 3; i++) {
- u8 tmp = w83627hf_read_value(client,
+ u8 tmp = w83627hf_read_value(data,
W836X7HF_REG_PWM(data->type, i));
/* bits 0-3 are reserved in 627THF */
if (data->type == w83627thf)
@@ -1513,47 +1471,47 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
break;
}
- data->temp = w83627hf_read_value(client, W83781D_REG_TEMP(1));
+ data->temp = w83627hf_read_value(data, W83781D_REG_TEMP(1));
data->temp_max =
- w83627hf_read_value(client, W83781D_REG_TEMP_OVER(1));
+ w83627hf_read_value(data, W83781D_REG_TEMP_OVER(1));
data->temp_max_hyst =
- w83627hf_read_value(client, W83781D_REG_TEMP_HYST(1));
+ w83627hf_read_value(data, W83781D_REG_TEMP_HYST(1));
data->temp_add[0] =
- w83627hf_read_value(client, W83781D_REG_TEMP(2));
+ w83627hf_read_value(data, W83781D_REG_TEMP(2));
data->temp_max_add[0] =
- w83627hf_read_value(client, W83781D_REG_TEMP_OVER(2));
+ w83627hf_read_value(data, W83781D_REG_TEMP_OVER(2));
data->temp_max_hyst_add[0] =
- w83627hf_read_value(client, W83781D_REG_TEMP_HYST(2));
+ w83627hf_read_value(data, W83781D_REG_TEMP_HYST(2));
if (data->type != w83697hf) {
data->temp_add[1] =
- w83627hf_read_value(client, W83781D_REG_TEMP(3));
+ w83627hf_read_value(data, W83781D_REG_TEMP(3));
data->temp_max_add[1] =
- w83627hf_read_value(client, W83781D_REG_TEMP_OVER(3));
+ w83627hf_read_value(data, W83781D_REG_TEMP_OVER(3));
data->temp_max_hyst_add[1] =
- w83627hf_read_value(client, W83781D_REG_TEMP_HYST(3));
+ w83627hf_read_value(data, W83781D_REG_TEMP_HYST(3));
}
- i = w83627hf_read_value(client, W83781D_REG_VID_FANDIV);
+ i = w83627hf_read_value(data, W83781D_REG_VID_FANDIV);
data->fan_div[0] = (i >> 4) & 0x03;
data->fan_div[1] = (i >> 6) & 0x03;
if (data->type != w83697hf) {
- data->fan_div[2] = (w83627hf_read_value(client,
+ data->fan_div[2] = (w83627hf_read_value(data,
W83781D_REG_PIN) >> 6) & 0x03;
}
- i = w83627hf_read_value(client, W83781D_REG_VBAT);
+ i = w83627hf_read_value(data, W83781D_REG_VBAT);
data->fan_div[0] |= (i >> 3) & 0x04;
data->fan_div[1] |= (i >> 4) & 0x04;
if (data->type != w83697hf)
data->fan_div[2] |= (i >> 5) & 0x04;
data->alarms =
- w83627hf_read_value(client, W83781D_REG_ALARM1) |
- (w83627hf_read_value(client, W83781D_REG_ALARM2) << 8) |
- (w83627hf_read_value(client, W83781D_REG_ALARM3) << 16);
- i = w83627hf_read_value(client, W83781D_REG_BEEP_INTS2);
+ w83627hf_read_value(data, W83781D_REG_ALARM1) |
+ (w83627hf_read_value(data, W83781D_REG_ALARM2) << 8) |
+ (w83627hf_read_value(data, W83781D_REG_ALARM3) << 16);
+ i = w83627hf_read_value(data, W83781D_REG_BEEP_INTS2);
data->beep_enable = i >> 7;
data->beep_mask = ((i & 0x7f) << 8) |
- w83627hf_read_value(client, W83781D_REG_BEEP_INTS1) |
- w83627hf_read_value(client, W83781D_REG_BEEP_INTS3) << 16;
+ w83627hf_read_value(data, W83781D_REG_BEEP_INTS1) |
+ w83627hf_read_value(data, W83781D_REG_BEEP_INTS3) << 16;
data->last_updated = jiffies;
data->valid = 1;
}
@@ -1563,19 +1521,87 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
return data;
}
+static int __init w83627hf_device_add(unsigned short address,
+ const struct w83627hf_sio_data *sio_data)
+{
+ struct resource res = {
+ .start = address + WINB_REGION_OFFSET,
+ .end = address + WINB_REGION_OFFSET + WINB_REGION_SIZE - 1,
+ .name = DRVNAME,
+ .flags = IORESOURCE_IO,
+ };
+ int err;
+
+ pdev = platform_device_alloc(DRVNAME, address);
+ if (!pdev) {
+ err = -ENOMEM;
+ printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+ goto exit;
+ }
+
+ err = platform_device_add_resources(pdev, &res, 1);
+ if (err) {
+ printk(KERN_ERR DRVNAME ": Device resource addition failed "
+ "(%d)\n", err);
+ goto exit_device_put;
+ }
+
+ pdev->dev.platform_data = kmalloc(sizeof(struct w83627hf_sio_data),
+ GFP_KERNEL);
+ if (!pdev->dev.platform_data) {
+ err = -ENOMEM;
+ printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
+ goto exit_device_put;
+ }
+ memcpy(pdev->dev.platform_data, sio_data,
+ sizeof(struct w83627hf_sio_data));
+
+ err = platform_device_add(pdev);
+ if (err) {
+ printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
+ err);
+ goto exit_device_put;
+ }
+
+ return 0;
+
+exit_device_put:
+ platform_device_put(pdev);
+exit:
+ return err;
+}
+
static int __init sensors_w83627hf_init(void)
{
- if (w83627hf_find(0x2e, &address)
- && w83627hf_find(0x4e, &address)) {
+ int err;
+ unsigned short address;
+ struct w83627hf_sio_data sio_data;
+
+ if (w83627hf_find(0x2e, &address, &sio_data)
+ && w83627hf_find(0x4e, &address, &sio_data))
return -ENODEV;
- }
- return i2c_isa_add_driver(&w83627hf_driver);
+ err = platform_driver_register(&w83627hf_driver);
+ if (err)
+ goto exit;
+
+ /* Sets global pdev as a side effect */
+ err = w83627hf_device_add(address, &sio_data);
+ if (err)
+ goto exit_driver;
+
+ return 0;
+
+exit_driver:
+ platform_driver_unregister(&w83627hf_driver);
+exit:
+ return err;
}
static void __exit sensors_w83627hf_exit(void)
{
- i2c_isa_del_driver(&w83627hf_driver);
+ platform_device_unregister(pdev);
+ platform_driver_unregister(&w83627hf_driver);
}
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index a47da3e..f85b48f 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -2,8 +2,9 @@
w83781d.c - Part of lm_sensors, Linux kernel modules for hardware
monitoring
Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>,
- Philip Edelbrock <phil@netroedge.com>,
- and Mark Studebaker <mdsxyz123@yahoo.com>
+ Philip Edelbrock <phil@netroedge.com>,
+ and Mark Studebaker <mdsxyz123@yahoo.com>
+ Copyright (c) 2007 Jean Delvare <khali@linux-fr.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -38,15 +39,20 @@
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
-#include <linux/i2c-isa.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
+#include <linux/hwmon-sysfs.h>
#include <linux/sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <asm/io.h>
#include "lm75.h"
+/* ISA device, if found */
+static struct platform_device *pdev;
+
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
@@ -75,8 +81,8 @@ MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
#define W83781D_ADDR_REG_OFFSET 5
#define W83781D_DATA_REG_OFFSET 6
-/* The W83781D registers */
-/* The W83782D registers for nr=7,8 are in bank 5 */
+/* The device registers */
+/* in nr from 0 to 8 */
#define W83781D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \
(0x554 + (((nr) - 7) * 2)))
#define W83781D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \
@@ -84,12 +90,14 @@ MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
#define W83781D_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \
(0x550 + (nr) - 7))
-#define W83781D_REG_FAN_MIN(nr) (0x3a + (nr))
-#define W83781D_REG_FAN(nr) (0x27 + (nr))
+/* fan nr from 0 to 2 */
+#define W83781D_REG_FAN_MIN(nr) (0x3b + (nr))
+#define W83781D_REG_FAN(nr) (0x28 + (nr))
#define W83781D_REG_BANK 0x4E
#define W83781D_REG_TEMP2_CONFIG 0x152
#define W83781D_REG_TEMP3_CONFIG 0x252
+/* temp nr from 1 to 3 */
#define W83781D_REG_TEMP(nr) ((nr == 3) ? (0x0250) : \
((nr == 2) ? (0x0150) : \
(0x27)))
@@ -127,19 +135,9 @@ MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
#define W83781D_REG_VBAT 0x5D
/* PWM 782D (1-4) and 783S (1-2) only */
-#define W83781D_REG_PWM1 0x5B /* 782d and 783s/627hf datasheets disagree */
- /* on which is which; */
-#define W83781D_REG_PWM2 0x5A /* We follow the 782d convention here, */
- /* However 782d is probably wrong. */
-#define W83781D_REG_PWM3 0x5E
-#define W83781D_REG_PWM4 0x5F
+static const u8 W83781D_REG_PWM[] = { 0x5B, 0x5A, 0x5E, 0x5F };
#define W83781D_REG_PWMCLK12 0x5C
#define W83781D_REG_PWMCLK34 0x45C
-static const u8 regpwm[] = { W83781D_REG_PWM1, W83781D_REG_PWM2,
- W83781D_REG_PWM3, W83781D_REG_PWM4
-};
-
-#define W83781D_REG_PWM(nr) (regpwm[(nr) - 1])
#define W83781D_REG_I2C_ADDR 0x48
#define W83781D_REG_I2C_SUBADDR 0x4A
@@ -159,12 +157,9 @@ static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 };
#define W83781D_REG_RT_IDX 0x50
#define W83781D_REG_RT_VAL 0x51
-/* Conversions. Rounding and limit checking is only done on the TO_REG
- variants. Note that you should be a bit careful with which arguments
- these macros are called: arguments may be evaluated more than once.
- Fixing this is just not worth it. */
-#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255))
-#define IN_FROM_REG(val) (((val) * 16) / 10)
+/* Conversions */
+#define IN_TO_REG(val) SENSORS_LIMIT(((val) + 8) / 16, 0, 255)
+#define IN_FROM_REG(val) ((val) * 16)
static inline u8
FAN_TO_REG(long rpm, int div)
@@ -175,24 +170,24 @@ FAN_TO_REG(long rpm, int div)
return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
}
-#define FAN_FROM_REG(val,div) ((val) == 0 ? -1 : \
- ((val) == 255 ? 0 : \
- 1350000 / ((val) * (div))))
+static inline long
+FAN_FROM_REG(u8 val, int div)
+{
+ if (val == 0)
+ return -1;
+ if (val == 255)
+ return 0;
+ return 1350000 / (val * div);
+}
-#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val) < 0 ? (val)+0x100*1000 \
- : (val)) / 1000, 0, 0xff))
-#define TEMP_FROM_REG(val) (((val) & 0x80 ? (val)-0x100 : (val)) * 1000)
+#define TEMP_TO_REG(val) SENSORS_LIMIT((val) / 1000, -127, 128)
+#define TEMP_FROM_REG(val) ((val) * 1000)
-#define PWM_FROM_REG(val) (val)
-#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255))
#define BEEP_MASK_FROM_REG(val,type) ((type) == as99127f ? \
(val) ^ 0x7fff : (val))
#define BEEP_MASK_TO_REG(val,type) ((type) == as99127f ? \
(~(val)) & 0x7fff : (val) & 0xffffff)
-#define BEEP_ENABLE_TO_REG(val) ((val) ? 1 : 0)
-#define BEEP_ENABLE_FROM_REG(val) ((val) ? 1 : 0)
-
#define DIV_FROM_REG(val) (1 << (val))
static inline u8
@@ -207,7 +202,7 @@ DIV_TO_REG(long val, enum chips type)
break;
val >>= 1;
}
- return ((u8) i);
+ return i;
}
/* There are some complications in a module like this. First off, W83781D chips
@@ -221,8 +216,8 @@ DIV_TO_REG(long val, enum chips type)
a bit - except if there could be more than one SMBus. Groan. No solution
for this yet. */
-/* For each registered chip, we need to keep some data in memory.
- The structure is dynamically allocated. */
+/* For ISA chips, we abuse the i2c_client addr and name fields. We also use
+ the driver field to differentiate between I2C and ISA chips. */
struct w83781d_data {
struct i2c_client client;
struct class_device *class_dev;
@@ -241,9 +236,9 @@ struct w83781d_data {
u8 in_min[9]; /* Register value - 8 & 9 for 782D only */
u8 fan[3]; /* Register value */
u8 fan_min[3]; /* Register value */
- u8 temp;
- u8 temp_max; /* Register value */
- u8 temp_max_hyst; /* Register value */
+ s8 temp; /* Register value */
+ s8 temp_max; /* Register value */
+ s8 temp_max_hyst; /* Register value */
u16 temp_add[2]; /* Register value */
u16 temp_max_add[2]; /* Register value */
u16 temp_max_hyst_add[2]; /* Register value */
@@ -253,7 +248,7 @@ struct w83781d_data {
u32 beep_mask; /* Register encoding, combined */
u8 beep_enable; /* Boolean */
u8 pwm[4]; /* Register value */
- u8 pwmenable[4]; /* Boolean */
+ u8 pwm2_enable; /* Boolean */
u16 sens[3]; /* 782D/783S only.
1 = pentium diode; 2 = 3904 diode;
3000-5000 = thermistor beta.
@@ -263,14 +258,16 @@ struct w83781d_data {
};
static int w83781d_attach_adapter(struct i2c_adapter *adapter);
-static int w83781d_isa_attach_adapter(struct i2c_adapter *adapter);
static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind);
static int w83781d_detach_client(struct i2c_client *client);
-static int w83781d_read_value(struct i2c_client *client, u16 reg);
-static int w83781d_write_value(struct i2c_client *client, u16 reg, u16 value);
+static int __devinit w83781d_isa_probe(struct platform_device *pdev);
+static int __devexit w83781d_isa_remove(struct platform_device *pdev);
+
+static int w83781d_read_value(struct w83781d_data *data, u16 reg);
+static int w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value);
static struct w83781d_data *w83781d_update_device(struct device *dev);
-static void w83781d_init_client(struct i2c_client *client);
+static void w83781d_init_device(struct device *dev);
static struct i2c_driver w83781d_driver = {
.driver = {
@@ -281,39 +278,44 @@ static struct i2c_driver w83781d_driver = {
.detach_client = w83781d_detach_client,
};
-static struct i2c_driver w83781d_isa_driver = {
+static struct platform_driver w83781d_isa_driver = {
.driver = {
.owner = THIS_MODULE,
- .name = "w83781d-isa",
+ .name = "w83781d",
},
- .attach_adapter = w83781d_isa_attach_adapter,
- .detach_client = w83781d_detach_client,
+ .probe = w83781d_isa_probe,
+ .remove = w83781d_isa_remove,
};
/* following are the sysfs callback functions */
#define show_in_reg(reg) \
-static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
+static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \
+ char *buf) \
{ \
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
struct w83781d_data *data = w83781d_update_device(dev); \
- return sprintf(buf,"%ld\n", (long)IN_FROM_REG(data->reg[nr] * 10)); \
+ return sprintf(buf, "%ld\n", \
+ (long)IN_FROM_REG(data->reg[attr->index])); \
}
show_in_reg(in);
show_in_reg(in_min);
show_in_reg(in_max);
#define store_in_reg(REG, reg) \
-static ssize_t store_in_##reg (struct device *dev, const char *buf, size_t count, int nr) \
+static ssize_t store_in_##reg (struct device *dev, struct device_attribute \
+ *da, const char *buf, size_t count) \
{ \
- struct i2c_client *client = to_i2c_client(dev); \
- struct w83781d_data *data = i2c_get_clientdata(client); \
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
+ struct w83781d_data *data = dev_get_drvdata(dev); \
+ int nr = attr->index; \
u32 val; \
\
- val = simple_strtoul(buf, NULL, 10) / 10; \
+ val = simple_strtoul(buf, NULL, 10); \
\
mutex_lock(&data->update_lock); \
data->in_##reg[nr] = IN_TO_REG(val); \
- w83781d_write_value(client, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \
+ w83781d_write_value(data, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \
\
mutex_unlock(&data->update_lock); \
return count; \
@@ -321,29 +323,13 @@ static ssize_t store_in_##reg (struct device *dev, const char *buf, size_t count
store_in_reg(MIN, min);
store_in_reg(MAX, max);
-#define sysfs_in_offset(offset) \
-static ssize_t \
-show_regs_in_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_in(dev, buf, offset); \
-} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL);
-
-#define sysfs_in_reg_offset(reg, offset) \
-static ssize_t show_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_in_##reg (dev, buf, offset); \
-} \
-static ssize_t store_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- return store_in_##reg (dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_in_##reg##offset, store_regs_in_##reg##offset);
-
#define sysfs_in_offsets(offset) \
-sysfs_in_offset(offset); \
-sysfs_in_reg_offset(min, offset); \
-sysfs_in_reg_offset(max, offset);
+static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \
+ show_in, NULL, offset); \
+static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
+ show_in_min, store_in_min, offset); \
+static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
+ show_in_max, store_in_max, offset)
sysfs_in_offsets(0);
sysfs_in_offsets(1);
@@ -356,63 +342,56 @@ sysfs_in_offsets(7);
sysfs_in_offsets(8);
#define show_fan_reg(reg) \
-static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
+static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \
+ char *buf) \
{ \
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
struct w83781d_data *data = w83781d_update_device(dev); \
return sprintf(buf,"%ld\n", \
- FAN_FROM_REG(data->reg[nr-1], (long)DIV_FROM_REG(data->fan_div[nr-1]))); \
+ FAN_FROM_REG(data->reg[attr->index], \
+ DIV_FROM_REG(data->fan_div[attr->index]))); \
}
show_fan_reg(fan);
show_fan_reg(fan_min);
static ssize_t
-store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
+store_fan_min(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83781d_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct w83781d_data *data = dev_get_drvdata(dev);
+ int nr = attr->index;
u32 val;
val = simple_strtoul(buf, NULL, 10);
mutex_lock(&data->update_lock);
- data->fan_min[nr - 1] =
- FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1]));
- w83781d_write_value(client, W83781D_REG_FAN_MIN(nr),
- data->fan_min[nr - 1]);
+ data->fan_min[nr] =
+ FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
+ w83781d_write_value(data, W83781D_REG_FAN_MIN(nr),
+ data->fan_min[nr]);
mutex_unlock(&data->update_lock);
return count;
}
-#define sysfs_fan_offset(offset) \
-static ssize_t show_regs_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_fan(dev, buf, offset); \
-} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);
-
-#define sysfs_fan_min_offset(offset) \
-static ssize_t show_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_fan_min(dev, buf, offset); \
-} \
-static ssize_t store_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- return store_fan_min(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, show_regs_fan_min##offset, store_regs_fan_min##offset);
-
-sysfs_fan_offset(1);
-sysfs_fan_min_offset(1);
-sysfs_fan_offset(2);
-sysfs_fan_min_offset(2);
-sysfs_fan_offset(3);
-sysfs_fan_min_offset(3);
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR,
+ show_fan_min, store_fan_min, 0);
+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR,
+ show_fan_min, store_fan_min, 1);
+static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO | S_IWUSR,
+ show_fan_min, store_fan_min, 2);
#define show_temp_reg(reg) \
-static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
+static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \
+ char *buf) \
{ \
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
struct w83781d_data *data = w83781d_update_device(dev); \
+ int nr = attr->index; \
if (nr >= 2) { /* TEMP2 and TEMP3 */ \
return sprintf(buf,"%d\n", \
LM75_TEMP_FROM_REG(data->reg##_add[nr-2])); \
@@ -425,10 +404,12 @@ show_temp_reg(temp_max);
show_temp_reg(temp_max_hyst);
#define store_temp_reg(REG, reg) \
-static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \
+static ssize_t store_temp_##reg (struct device *dev, \
+ struct device_attribute *da, const char *buf, size_t count) \
{ \
- struct i2c_client *client = to_i2c_client(dev); \
- struct w83781d_data *data = i2c_get_clientdata(client); \
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
+ struct w83781d_data *data = dev_get_drvdata(dev); \
+ int nr = attr->index; \
s32 val; \
\
val = simple_strtol(buf, NULL, 10); \
@@ -437,11 +418,11 @@ static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t cou
\
if (nr >= 2) { /* TEMP2 and TEMP3 */ \
data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \
- w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \
+ w83781d_write_value(data, W83781D_REG_TEMP_##REG(nr), \
data->temp_##reg##_add[nr-2]); \
} else { /* TEMP1 */ \
data->temp_##reg = TEMP_TO_REG(val); \
- w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \
+ w83781d_write_value(data, W83781D_REG_TEMP_##REG(nr), \
data->temp_##reg); \
} \
\
@@ -451,29 +432,13 @@ static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t cou
store_temp_reg(OVER, max);
store_temp_reg(HYST, max_hyst);
-#define sysfs_temp_offset(offset) \
-static ssize_t \
-show_regs_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_temp(dev, buf, offset); \
-} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);
-
-#define sysfs_temp_reg_offset(reg, offset) \
-static ssize_t show_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_temp_##reg (dev, buf, offset); \
-} \
-static ssize_t store_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- return store_temp_##reg (dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_temp_##reg##offset, store_regs_temp_##reg##offset);
-
#define sysfs_temp_offsets(offset) \
-sysfs_temp_offset(offset); \
-sysfs_temp_reg_offset(max, offset); \
-sysfs_temp_reg_offset(max_hyst, offset);
+static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
+ show_temp, NULL, offset); \
+static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
+ show_temp_max, store_temp_max, offset); \
+static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \
+ show_temp_max_hyst, store_temp_max_hyst, offset);
sysfs_temp_offsets(1);
sysfs_temp_offsets(2);
@@ -498,8 +463,7 @@ show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
static ssize_t
store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83781d_data *data = i2c_get_clientdata(client);
+ struct w83781d_data *data = dev_get_drvdata(dev);
u32 val;
val = simple_strtoul(buf, NULL, 10);
@@ -528,68 +492,67 @@ static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr
static ssize_t show_beep_enable (struct device *dev, struct device_attribute *attr, char *buf)
{
struct w83781d_data *data = w83781d_update_device(dev);
- return sprintf(buf, "%ld\n",
- (long)BEEP_ENABLE_FROM_REG(data->beep_enable));
+ return sprintf(buf, "%ld\n", (long)data->beep_enable);
}
-#define BEEP_ENABLE 0 /* Store beep_enable */
-#define BEEP_MASK 1 /* Store beep_mask */
-
static ssize_t
-store_beep_reg(struct device *dev, const char *buf, size_t count,
- int update_mask)
+store_beep_mask(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83781d_data *data = i2c_get_clientdata(client);
- u32 val, val2;
+ struct w83781d_data *data = dev_get_drvdata(dev);
+ u32 val;
val = simple_strtoul(buf, NULL, 10);
mutex_lock(&data->update_lock);
+ data->beep_mask = BEEP_MASK_TO_REG(val, data->type);
+ w83781d_write_value(data, W83781D_REG_BEEP_INTS1,
+ data->beep_mask & 0xff);
+ w83781d_write_value(data, W83781D_REG_BEEP_INTS2,
+ ((data->beep_mask >> 8) & 0x7f)
+ | data->beep_enable << 7);
+ if (data->type != w83781d && data->type != as99127f) {
+ w83781d_write_value(data, W83781D_REG_BEEP_INTS3,
+ ((data->beep_mask) >> 16) & 0xff);
+ }
+ mutex_unlock(&data->update_lock);
- if (update_mask == BEEP_MASK) { /* We are storing beep_mask */
- data->beep_mask = BEEP_MASK_TO_REG(val, data->type);
- w83781d_write_value(client, W83781D_REG_BEEP_INTS1,
- data->beep_mask & 0xff);
-
- if ((data->type != w83781d) && (data->type != as99127f)) {
- w83781d_write_value(client, W83781D_REG_BEEP_INTS3,
- ((data->beep_mask) >> 16) & 0xff);
- }
+ return count;
+}
- val2 = (data->beep_mask >> 8) & 0x7f;
- } else { /* We are storing beep_enable */
- val2 = w83781d_read_value(client, W83781D_REG_BEEP_INTS2) & 0x7f;
- data->beep_enable = BEEP_ENABLE_TO_REG(val);
- }
+static ssize_t
+store_beep_enable(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct w83781d_data *data = dev_get_drvdata(dev);
+ u32 val;
- w83781d_write_value(client, W83781D_REG_BEEP_INTS2,
- val2 | data->beep_enable << 7);
+ val = simple_strtoul(buf, NULL, 10);
+ if (val != 0 && val != 1)
+ return -EINVAL;
+ mutex_lock(&data->update_lock);
+ data->beep_enable = val;
+ val = w83781d_read_value(data, W83781D_REG_BEEP_INTS2) & 0x7f;
+ val |= data->beep_enable << 7;
+ w83781d_write_value(data, W83781D_REG_BEEP_INTS2, val);
mutex_unlock(&data->update_lock);
+
return count;
}
-#define sysfs_beep(REG, reg) \
-static ssize_t show_regs_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_beep_##reg(dev, attr, buf); \
-} \
-static ssize_t store_regs_beep_##reg (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- return store_beep_reg(dev, buf, count, BEEP_##REG); \
-} \
-static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_regs_beep_##reg);
-
-sysfs_beep(ENABLE, enable);
-sysfs_beep(MASK, mask);
+static DEVICE_ATTR(beep_mask, S_IRUGO | S_IWUSR,
+ show_beep_mask, store_beep_mask);
+static DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR,
+ show_beep_enable, store_beep_enable);
static ssize_t
-show_fan_div_reg(struct device *dev, char *buf, int nr)
+show_fan_div(struct device *dev, struct device_attribute *da, char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct w83781d_data *data = w83781d_update_device(dev);
return sprintf(buf, "%ld\n",
- (long) DIV_FROM_REG(data->fan_div[nr - 1]));
+ (long) DIV_FROM_REG(data->fan_div[attr->index]));
}
/* Note: we save and restore the fan minimum here, because its value is
@@ -597,11 +560,13 @@ show_fan_div_reg(struct device *dev, char *buf, int nr)
least surprise; the user doesn't expect the fan minimum to change just
because the divisor changed. */
static ssize_t
-store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
+store_fan_div(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83781d_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct w83781d_data *data = dev_get_drvdata(dev);
unsigned long min;
+ int nr = attr->index;
u8 reg;
unsigned long val = simple_strtoul(buf, NULL, 10);
@@ -613,77 +578,72 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
data->fan_div[nr] = DIV_TO_REG(val, data->type);
- reg = (w83781d_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
+ reg = (w83781d_read_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
& (nr==0 ? 0xcf : 0x3f))
| ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6));
- w83781d_write_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);
+ w83781d_write_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);
/* w83781d and as99127f don't have extended divisor bits */
if (data->type != w83781d && data->type != as99127f) {
- reg = (w83781d_read_value(client, W83781D_REG_VBAT)
+ reg = (w83781d_read_value(data, W83781D_REG_VBAT)
& ~(1 << (5 + nr)))
| ((data->fan_div[nr] & 0x04) << (3 + nr));
- w83781d_write_value(client, W83781D_REG_VBAT, reg);
+ w83781d_write_value(data, W83781D_REG_VBAT, reg);
}
/* Restore fan_min */
data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
- w83781d_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
+ w83781d_write_value(data, W83781D_REG_FAN_MIN(nr), data->fan_min[nr]);
mutex_unlock(&data->update_lock);
return count;
}
-#define sysfs_fan_div(offset) \
-static ssize_t show_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_fan_div_reg(dev, buf, offset); \
-} \
-static ssize_t store_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- return store_fan_div_reg(dev, buf, count, offset - 1); \
-} \
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset);
-
-sysfs_fan_div(1);
-sysfs_fan_div(2);
-sysfs_fan_div(3);
+static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
+ show_fan_div, store_fan_div, 0);
+static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
+ show_fan_div, store_fan_div, 1);
+static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO | S_IWUSR,
+ show_fan_div, store_fan_div, 2);
static ssize_t
-show_pwm_reg(struct device *dev, char *buf, int nr)
+show_pwm(struct device *dev, struct device_attribute *da, char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct w83781d_data *data = w83781d_update_device(dev);
- return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr - 1]));
+ return sprintf(buf, "%d\n", (int)data->pwm[attr->index]);
}
static ssize_t
-show_pwmenable_reg(struct device *dev, char *buf, int nr)
+show_pwm2_enable(struct device *dev, struct device_attribute *da, char *buf)
{
struct w83781d_data *data = w83781d_update_device(dev);
- return sprintf(buf, "%ld\n", (long) data->pwmenable[nr - 1]);
+ return sprintf(buf, "%d\n", (int)data->pwm2_enable);
}
static ssize_t
-store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr)
+store_pwm(struct device *dev, struct device_attribute *da, const char *buf,
+ size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83781d_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct w83781d_data *data = dev_get_drvdata(dev);
+ int nr = attr->index;
u32 val;
val = simple_strtoul(buf, NULL, 10);
mutex_lock(&data->update_lock);
- data->pwm[nr - 1] = PWM_TO_REG(val);
- w83781d_write_value(client, W83781D_REG_PWM(nr), data->pwm[nr - 1]);
+ data->pwm[nr] = SENSORS_LIMIT(val, 0, 255);
+ w83781d_write_value(data, W83781D_REG_PWM[nr], data->pwm[nr]);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t
-store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr)
+store_pwm2_enable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83781d_data *data = i2c_get_clientdata(client);
+ struct w83781d_data *data = dev_get_drvdata(dev);
u32 val, reg;
val = simple_strtoul(buf, NULL, 10);
@@ -693,15 +653,15 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr)
switch (val) {
case 0:
case 1:
- reg = w83781d_read_value(client, W83781D_REG_PWMCLK12);
- w83781d_write_value(client, W83781D_REG_PWMCLK12,
+ reg = w83781d_read_value(data, W83781D_REG_PWMCLK12);
+ w83781d_write_value(data, W83781D_REG_PWMCLK12,
(reg & 0xf7) | (val << 3));
- reg = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
- w83781d_write_value(client, W83781D_REG_BEEP_CONFIG,
+ reg = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG);
+ w83781d_write_value(data, W83781D_REG_BEEP_CONFIG,
(reg & 0xef) | (!val << 4));
- data->pwmenable[nr - 1] = val;
+ data->pwm2_enable = val;
break;
default:
@@ -713,50 +673,29 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr)
return count;
}
-#define sysfs_pwm(offset) \
-static ssize_t show_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_pwm_reg(dev, buf, offset); \
-} \
-static ssize_t store_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- return store_pwm_reg(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
- show_regs_pwm_##offset, store_regs_pwm_##offset);
-
-#define sysfs_pwmenable(offset) \
-static ssize_t show_regs_pwmenable_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_pwmenable_reg(dev, buf, offset); \
-} \
-static ssize_t store_regs_pwmenable_##offset (struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- return store_pwmenable_reg(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
- show_regs_pwmenable_##offset, store_regs_pwmenable_##offset);
-
-sysfs_pwm(1);
-sysfs_pwm(2);
-sysfs_pwmenable(2); /* only PWM2 can be enabled/disabled */
-sysfs_pwm(3);
-sysfs_pwm(4);
+static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 0);
+static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 1);
+static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 2);
+static SENSOR_DEVICE_ATTR(pwm4, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 3);
+/* only PWM2 can be enabled/disabled */
+static DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR,
+ show_pwm2_enable, store_pwm2_enable);
static ssize_t
-show_sensor_reg(struct device *dev, char *buf, int nr)
+show_sensor(struct device *dev, struct device_attribute *da, char *buf)
{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct w83781d_data *data = w83781d_update_device(dev);
- return sprintf(buf, "%ld\n", (long) data->sens[nr - 1]);
+ return sprintf(buf, "%d\n", (int)data->sens[attr->index]);
}
static ssize_t
-store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
+store_sensor(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83781d_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct w83781d_data *data = dev_get_drvdata(dev);
+ int nr = attr->index;
u32 val, tmp;
val = simple_strtoul(buf, NULL, 10);
@@ -765,28 +704,28 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
switch (val) {
case 1: /* PII/Celeron diode */
- tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
- w83781d_write_value(client, W83781D_REG_SCFG1,
- tmp | BIT_SCFG1[nr - 1]);
- tmp = w83781d_read_value(client, W83781D_REG_SCFG2);
- w83781d_write_value(client, W83781D_REG_SCFG2,
- tmp | BIT_SCFG2[nr - 1]);
- data->sens[nr - 1] = val;
+ tmp = w83781d_read_value(data, W83781D_REG_SCFG1);
+ w83781d_write_value(data, W83781D_REG_SCFG1,
+ tmp | BIT_SCFG1[nr]);
+ tmp = w83781d_read_value(data, W83781D_REG_SCFG2);
+ w83781d_write_value(data, W83781D_REG_SCFG2,
+ tmp | BIT_SCFG2[nr]);
+ data->sens[nr] = val;
break;
case 2: /* 3904 */
- tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
- w83781d_write_value(client, W83781D_REG_SCFG1,
- tmp | BIT_SCFG1[nr - 1]);
- tmp = w83781d_read_value(client, W83781D_REG_SCFG2);
- w83781d_write_value(client, W83781D_REG_SCFG2,
- tmp & ~BIT_SCFG2[nr - 1]);
- data->sens[nr - 1] = val;
+ tmp = w83781d_read_value(data, W83781D_REG_SCFG1);
+ w83781d_write_value(data, W83781D_REG_SCFG1,
+ tmp | BIT_SCFG1[nr]);
+ tmp = w83781d_read_value(data, W83781D_REG_SCFG2);
+ w83781d_write_value(data, W83781D_REG_SCFG2,
+ tmp & ~BIT_SCFG2[nr]);
+ data->sens[nr] = val;
break;
case W83781D_DEFAULT_BETA: /* thermistor */
- tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
- w83781d_write_value(client, W83781D_REG_SCFG1,
- tmp & ~BIT_SCFG1[nr - 1]);
- data->sens[nr - 1] = val;
+ tmp = w83781d_read_value(data, W83781D_REG_SCFG1);
+ w83781d_write_value(data, W83781D_REG_SCFG1,
+ tmp & ~BIT_SCFG1[nr]);
+ data->sens[nr] = val;
break;
default:
dev_err(dev, "Invalid sensor type %ld; must be 1, 2, or %d\n",
@@ -798,20 +737,22 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
return count;
}
-#define sysfs_sensor(offset) \
-static ssize_t show_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return show_sensor_reg(dev, buf, offset); \
-} \
-static ssize_t store_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- return store_sensor_reg(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, show_regs_sensor_##offset, store_regs_sensor_##offset);
+static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR,
+ show_sensor, store_sensor, 0);
+static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR,
+ show_sensor, store_sensor, 0);
+static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR,
+ show_sensor, store_sensor, 0);
-sysfs_sensor(1);
-sysfs_sensor(2);
-sysfs_sensor(3);
+/* I2C devices get this name attribute automatically, but for ISA devices
+ we must create it by ourselves. */
+static ssize_t
+show_name(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+ struct w83781d_data *data = dev_get_drvdata(dev);
+ return sprintf(buf, "%s\n", data->client.name);
+}
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
/* This function is called when:
* w83781d_driver is inserted (when this module is loaded), for each
@@ -825,12 +766,6 @@ w83781d_attach_adapter(struct i2c_adapter *adapter)
return i2c_probe(adapter, &addr_data, w83781d_detect);
}
-static int
-w83781d_isa_attach_adapter(struct i2c_adapter *adapter)
-{
- return w83781d_detect(adapter, isa_address, -1);
-}
-
/* Assumes that adapter is of I2C, not ISA variety.
* OTHERWISE DON'T CALL THIS
*/
@@ -862,12 +797,12 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
goto ERROR_SC_1;
}
}
- w83781d_write_value(new_client, W83781D_REG_I2C_SUBADDR,
+ w83781d_write_value(data, W83781D_REG_I2C_SUBADDR,
(force_subclients[2] & 0x07) |
((force_subclients[3] & 0x07) << 4));
data->lm75[0]->addr = force_subclients[2];
} else {
- val1 = w83781d_read_value(new_client, W83781D_REG_I2C_SUBADDR);
+ val1 = w83781d_read_value(data, W83781D_REG_I2C_SUBADDR);
data->lm75[0]->addr = 0x48 + (val1 & 0x07);
}
@@ -937,20 +872,20 @@ ERROR_SC_0:
return err;
}
-#define IN_UNIT_ATTRS(X) \
- &dev_attr_in##X##_input.attr, \
- &dev_attr_in##X##_min.attr, \
- &dev_attr_in##X##_max.attr
+#define IN_UNIT_ATTRS(X) \
+ &sensor_dev_attr_in##X##_input.dev_attr.attr, \
+ &sensor_dev_attr_in##X##_min.dev_attr.attr, \
+ &sensor_dev_attr_in##X##_max.dev_attr.attr
-#define FAN_UNIT_ATTRS(X) \
- &dev_attr_fan##X##_input.attr, \
- &dev_attr_fan##X##_min.attr, \
- &dev_attr_fan##X##_div.attr
+#define FAN_UNIT_ATTRS(X) \
+ &sensor_dev_attr_fan##X##_input.dev_attr.attr, \
+ &sensor_dev_attr_fan##X##_min.dev_attr.attr, \
+ &sensor_dev_attr_fan##X##_div.dev_attr.attr
-#define TEMP_UNIT_ATTRS(X) \
- &dev_attr_temp##X##_input.attr, \
- &dev_attr_temp##X##_max.attr, \
- &dev_attr_temp##X##_max_hyst.attr
+#define TEMP_UNIT_ATTRS(X) \
+ &sensor_dev_attr_temp##X##_input.dev_attr.attr, \
+ &sensor_dev_attr_temp##X##_max.dev_attr.attr, \
+ &sensor_dev_attr_temp##X##_max_hyst.dev_attr.attr
static struct attribute* w83781d_attributes[] = {
IN_UNIT_ATTRS(0),
@@ -980,91 +915,115 @@ static struct attribute *w83781d_attributes_opt[] = {
IN_UNIT_ATTRS(7),
IN_UNIT_ATTRS(8),
TEMP_UNIT_ATTRS(3),
- &dev_attr_pwm1.attr,
- &dev_attr_pwm2.attr,
+ &sensor_dev_attr_pwm1.dev_attr.attr,
+ &sensor_dev_attr_pwm2.dev_attr.attr,
+ &sensor_dev_attr_pwm3.dev_attr.attr,
+ &sensor_dev_attr_pwm4.dev_attr.attr,
&dev_attr_pwm2_enable.attr,
- &dev_attr_pwm3.attr,
- &dev_attr_pwm4.attr,
- &dev_attr_temp1_type.attr,
- &dev_attr_temp2_type.attr,
- &dev_attr_temp3_type.attr,
+ &sensor_dev_attr_temp1_type.dev_attr.attr,
+ &sensor_dev_attr_temp2_type.dev_attr.attr,
+ &sensor_dev_attr_temp3_type.dev_attr.attr,
NULL
};
static const struct attribute_group w83781d_group_opt = {
.attrs = w83781d_attributes_opt,
};
+/* No clean up is done on error, it's up to the caller */
static int
-w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
+w83781d_create_files(struct device *dev, int kind, int is_isa)
{
- int i = 0, val1 = 0, val2;
- struct i2c_client *client;
- struct device *dev;
- struct w83781d_data *data;
int err;
- const char *client_name = "";
- int is_isa = i2c_is_isa_adapter(adapter);
- enum vendor { winbond, asus } vendid;
- if (!is_isa
- && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- err = -EINVAL;
- goto ERROR0;
+ if ((err = sysfs_create_group(&dev->kobj, &w83781d_group)))
+ return err;
+
+ if (kind != w83783s) {
+ if ((err = device_create_file(dev,
+ &sensor_dev_attr_in1_input.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_in1_min.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_in1_max.dev_attr)))
+ return err;
+ }
+ if (kind != as99127f && kind != w83781d && kind != w83783s) {
+ if ((err = device_create_file(dev,
+ &sensor_dev_attr_in7_input.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_in7_min.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_in7_max.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_in8_input.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_in8_min.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_in8_max.dev_attr)))
+ return err;
+ }
+ if (kind != w83783s) {
+ if ((err = device_create_file(dev,
+ &sensor_dev_attr_temp3_input.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_temp3_max.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_temp3_max_hyst.dev_attr)))
+ return err;
}
- /* Prevent users from forcing a kind for a bus it isn't supposed
- to possibly be on */
- if (is_isa && (kind == as99127f || kind == w83783s)) {
- dev_err(&adapter->dev,
- "Cannot force I2C-only chip for ISA address 0x%02x.\n",
- address);
- err = -EINVAL;
- goto ERROR0;
+ if (kind != w83781d && kind != as99127f) {
+ if ((err = device_create_file(dev,
+ &sensor_dev_attr_pwm1.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_pwm2.dev_attr))
+ || (err = device_create_file(dev, &dev_attr_pwm2_enable)))
+ return err;
}
-
- if (is_isa)
- if (!request_region(address, W83781D_EXTENT,
- w83781d_isa_driver.driver.name)) {
- dev_dbg(&adapter->dev, "Request of region "
- "0x%x-0x%x for w83781d failed\n", address,
- address + W83781D_EXTENT - 1);
- err = -EBUSY;
- goto ERROR0;
+ if (kind == w83782d && !is_isa) {
+ if ((err = device_create_file(dev,
+ &sensor_dev_attr_pwm3.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_pwm4.dev_attr)))
+ return err;
+ }
+
+ if (kind != as99127f && kind != w83781d) {
+ if ((err = device_create_file(dev,
+ &sensor_dev_attr_temp1_type.dev_attr))
+ || (err = device_create_file(dev,
+ &sensor_dev_attr_temp2_type.dev_attr)))
+ return err;
+ if (kind != w83783s) {
+ if ((err = device_create_file(dev,
+ &sensor_dev_attr_temp3_type.dev_attr)))
+ return err;
}
+ }
- /* Probe whether there is anything available on this address. Already
- done for SMBus clients */
- if (kind < 0) {
- if (is_isa) {
+ if (is_isa) {
+ err = device_create_file(&pdev->dev, &dev_attr_name);
+ if (err)
+ return err;
+ }
-#define REALLY_SLOW_IO
- /* We need the timeouts for at least some LM78-like
- chips. But only if we read 'undefined' registers. */
- i = inb_p(address + 1);
- if (inb_p(address + 2) != i
- || inb_p(address + 3) != i
- || inb_p(address + 7) != i) {
- dev_dbg(&adapter->dev, "Detection of w83781d "
- "chip failed at step 1\n");
- err = -ENODEV;
- goto ERROR1;
- }
-#undef REALLY_SLOW_IO
+ return 0;
+}
- /* Let's just hope nothing breaks here */
- i = inb_p(address + 5) & 0x7f;
- outb_p(~i & 0x7f, address + 5);
- val2 = inb_p(address + 5) & 0x7f;
- if (val2 != (~i & 0x7f)) {
- outb_p(i, address + 5);
- dev_dbg(&adapter->dev, "Detection of w83781d "
- "chip failed at step 2 (0x%x != "
- "0x%x at 0x%x)\n", val2, ~i & 0x7f,
- address + 5);
- err = -ENODEV;
- goto ERROR1;
- }
- }
+static int
+w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+ int val1 = 0, val2;
+ struct i2c_client *client;
+ struct device *dev;
+ struct w83781d_data *data;
+ int err;
+ const char *client_name = "";
+ enum vendor { winbond, asus } vendid;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+ err = -EINVAL;
+ goto ERROR1;
}
/* OK. For now, we presume we have a valid client. We now create the
@@ -1081,8 +1040,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
client->addr = address;
mutex_init(&data->lock);
client->adapter = adapter;
- client->driver = is_isa ? &w83781d_isa_driver : &w83781d_driver;
- client->flags = 0;
+ client->driver = &w83781d_driver;
dev = &client->dev;
/* Now, we do the remaining detection. */
@@ -1092,14 +1050,14 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
force_*=... parameter, and the Winbond will be reset to the right
bank. */
if (kind < 0) {
- if (w83781d_read_value(client, W83781D_REG_CONFIG) & 0x80) {
+ if (w83781d_read_value(data, W83781D_REG_CONFIG) & 0x80) {
dev_dbg(&adapter->dev, "Detection of w83781d chip "
"failed at step 3\n");
err = -ENODEV;
goto ERROR2;
}
- val1 = w83781d_read_value(client, W83781D_REG_BANK);
- val2 = w83781d_read_value(client, W83781D_REG_CHIPMAN);
+ val1 = w83781d_read_value(data, W83781D_REG_BANK);
+ val2 = w83781d_read_value(data, W83781D_REG_CHIPMAN);
/* Check for Winbond or Asus ID if in bank 0 */
if ((!(val1 & 0x07)) &&
(((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3))
@@ -1111,10 +1069,10 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
}
/* If Winbond SMBus, check address at 0x48.
Asus doesn't support, except for as99127f rev.2 */
- if ((!is_isa) && (((!(val1 & 0x80)) && (val2 == 0xa3)) ||
- ((val1 & 0x80) && (val2 == 0x5c)))) {
+ if ((!(val1 & 0x80) && (val2 == 0xa3)) ||
+ ((val1 & 0x80) && (val2 == 0x5c))) {
if (w83781d_read_value
- (client, W83781D_REG_I2C_ADDR) != address) {
+ (data, W83781D_REG_I2C_ADDR) != address) {
dev_dbg(&adapter->dev, "Detection of w83781d "
"chip failed at step 5\n");
err = -ENODEV;
@@ -1125,14 +1083,14 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
/* We have either had a force parameter, or we have already detected the
Winbond. Put it now into bank 0 and Vendor ID High Byte */
- w83781d_write_value(client, W83781D_REG_BANK,
- (w83781d_read_value(client, W83781D_REG_BANK)
+ w83781d_write_value(data, W83781D_REG_BANK,
+ (w83781d_read_value(data, W83781D_REG_BANK)
& 0x78) | 0x80);
/* Determine the chip type. */
if (kind <= 0) {
/* get vendor ID */
- val2 = w83781d_read_value(client, W83781D_REG_CHIPMAN);
+ val2 = w83781d_read_value(data, W83781D_REG_CHIPMAN);
if (val2 == 0x5c)
vendid = winbond;
else if (val2 == 0x12)
@@ -1144,17 +1102,16 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
goto ERROR2;
}
- val1 = w83781d_read_value(client, W83781D_REG_WCHIPID);
+ val1 = w83781d_read_value(data, W83781D_REG_WCHIPID);
if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond)
kind = w83781d;
else if (val1 == 0x30 && vendid == winbond)
kind = w83782d;
- else if (val1 == 0x40 && vendid == winbond && !is_isa
- && address == 0x2d)
+ else if (val1 == 0x40 && vendid == winbond && address == 0x2d)
kind = w83783s;
else if (val1 == 0x21 && vendid == winbond)
kind = w83627hf;
- else if (val1 == 0x31 && !is_isa && address >= 0x28)
+ else if (val1 == 0x31 && address >= 0x28)
kind = as99127f;
else {
if (kind == 0)
@@ -1182,86 +1139,23 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
strlcpy(client->name, client_name, I2C_NAME_SIZE);
data->type = kind;
- data->valid = 0;
- mutex_init(&data->update_lock);
-
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto ERROR2;
/* attach secondary i2c lm75-like clients */
- if (!is_isa) {
- if ((err = w83781d_detect_subclients(adapter, address,
- kind, client)))
- goto ERROR3;
- } else {
- data->lm75[0] = NULL;
- data->lm75[1] = NULL;
- }
+ if ((err = w83781d_detect_subclients(adapter, address,
+ kind, client)))
+ goto ERROR3;
/* Initialize the chip */
- w83781d_init_client(client);
-
- /* A few vars need to be filled upon startup */
- for (i = 1; i <= 3; i++) {
- data->fan_min[i - 1] = w83781d_read_value(client,
- W83781D_REG_FAN_MIN(i));
- }
- if (kind != w83781d && kind != as99127f)
- for (i = 0; i < 4; i++)
- data->pwmenable[i] = 1;
+ w83781d_init_device(dev);
/* Register sysfs hooks */
- if ((err = sysfs_create_group(&dev->kobj, &w83781d_group)))
+ err = w83781d_create_files(dev, kind, 0);
+ if (err)
goto ERROR4;
- if (kind != w83783s) {
- if ((err = device_create_file(dev, &dev_attr_in1_input))
- || (err = device_create_file(dev, &dev_attr_in1_min))
- || (err = device_create_file(dev, &dev_attr_in1_max)))
- goto ERROR4;
- }
- if (kind != as99127f && kind != w83781d && kind != w83783s) {
- if ((err = device_create_file(dev, &dev_attr_in7_input))
- || (err = device_create_file(dev, &dev_attr_in7_min))
- || (err = device_create_file(dev, &dev_attr_in7_max))
- || (err = device_create_file(dev, &dev_attr_in8_input))
- || (err = device_create_file(dev, &dev_attr_in8_min))
- || (err = device_create_file(dev, &dev_attr_in8_max)))
- goto ERROR4;
- }
- if (kind != w83783s) {
- if ((err = device_create_file(dev, &dev_attr_temp3_input))
- || (err = device_create_file(dev, &dev_attr_temp3_max))
- || (err = device_create_file(dev,
- &dev_attr_temp3_max_hyst)))
- goto ERROR4;
- }
-
- if (kind != w83781d && kind != as99127f) {
- if ((err = device_create_file(dev, &dev_attr_pwm1))
- || (err = device_create_file(dev, &dev_attr_pwm2))
- || (err = device_create_file(dev, &dev_attr_pwm2_enable)))
- goto ERROR4;
- }
- if (kind == w83782d && !is_isa) {
- if ((err = device_create_file(dev, &dev_attr_pwm3))
- || (err = device_create_file(dev, &dev_attr_pwm4)))
- goto ERROR4;
- }
-
- if (kind != as99127f && kind != w83781d) {
- if ((err = device_create_file(dev, &dev_attr_temp1_type))
- || (err = device_create_file(dev,
- &dev_attr_temp2_type)))
- goto ERROR4;
- if (kind != w83783s) {
- if ((err = device_create_file(dev,
- &dev_attr_temp3_type)))
- goto ERROR4;
- }
- }
-
data->class_dev = hwmon_device_register(dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
@@ -1287,9 +1181,6 @@ ERROR3:
ERROR2:
kfree(data);
ERROR1:
- if (is_isa)
- release_region(address, W83781D_EXTENT);
-ERROR0:
return err;
}
@@ -1305,8 +1196,6 @@ w83781d_detach_client(struct i2c_client *client)
sysfs_remove_group(&client->dev.kobj, &w83781d_group);
sysfs_remove_group(&client->dev.kobj, &w83781d_group_opt);
}
- if (i2c_is_isa_client(client))
- release_region(client->addr, W83781D_EXTENT);
if ((err = i2c_detach_client(client)))
return err;
@@ -1322,6 +1211,88 @@ w83781d_detach_client(struct i2c_client *client)
return 0;
}
+static int __devinit
+w83781d_isa_probe(struct platform_device *pdev)
+{
+ int err, reg;
+ struct w83781d_data *data;
+ struct resource *res;
+ const char *name;
+
+ /* Reserve the ISA region */
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!request_region(res->start, W83781D_EXTENT, "w83781d")) {
+ err = -EBUSY;
+ goto exit;
+ }
+
+ if (!(data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto exit_release_region;
+ }
+ mutex_init(&data->lock);
+ data->client.addr = res->start;
+ i2c_set_clientdata(&data->client, data);
+ platform_set_drvdata(pdev, data);
+
+ reg = w83781d_read_value(data, W83781D_REG_WCHIPID);
+ switch (reg) {
+ case 0x21:
+ data->type = w83627hf;
+ name = "w83627hf";
+ break;
+ case 0x30:
+ data->type = w83782d;
+ name = "w83782d";
+ break;
+ default:
+ data->type = w83781d;
+ name = "w83781d";
+ }
+ strlcpy(data->client.name, name, I2C_NAME_SIZE);
+
+ /* Initialize the W83781D chip */
+ w83781d_init_device(&pdev->dev);
+
+ /* Register sysfs hooks */
+ err = w83781d_create_files(&pdev->dev, data->type, 1);
+ if (err)
+ goto exit_remove_files;
+
+ data->class_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(data->class_dev)) {
+ err = PTR_ERR(data->class_dev);
+ goto exit_remove_files;
+ }
+
+ return 0;
+
+ exit_remove_files:
+ sysfs_remove_group(&pdev->dev.kobj, &w83781d_group);
+ sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt);
+ device_remove_file(&pdev->dev, &dev_attr_name);
+ kfree(data);
+ exit_release_region:
+ release_region(res->start, W83781D_EXTENT);
+ exit:
+ return err;
+}
+
+static int __devexit
+w83781d_isa_remove(struct platform_device *pdev)
+{
+ struct w83781d_data *data = platform_get_drvdata(pdev);
+
+ hwmon_device_unregister(data->class_dev);
+ sysfs_remove_group(&pdev->dev.kobj, &w83781d_group);
+ sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt);
+ device_remove_file(&pdev->dev, &dev_attr_name);
+ release_region(data->client.addr, W83781D_EXTENT);
+ kfree(data);
+
+ return 0;
+}
+
/* The SMBus locks itself, usually, but nothing may access the Winbond between
bank switches. ISA access must always be locked explicitly!
We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
@@ -1329,14 +1300,14 @@ w83781d_detach_client(struct i2c_client *client)
There are some ugly typecasts here, but the good news is - they should
nowhere else be necessary! */
static int
-w83781d_read_value(struct i2c_client *client, u16 reg)
+w83781d_read_value(struct w83781d_data *data, u16 reg)
{
- struct w83781d_data *data = i2c_get_clientdata(client);
+ struct i2c_client *client = &data->client;
int res, word_sized, bank;
struct i2c_client *cl;
mutex_lock(&data->lock);
- if (i2c_is_isa_client(client)) {
+ if (!client->driver) { /* ISA device */
word_sized = (((reg & 0xff00) == 0x100)
|| ((reg & 0xff00) == 0x200))
&& (((reg & 0x00ff) == 0x50)
@@ -1398,14 +1369,14 @@ w83781d_read_value(struct i2c_client *client, u16 reg)
}
static int
-w83781d_write_value(struct i2c_client *client, u16 reg, u16 value)
+w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value)
{
- struct w83781d_data *data = i2c_get_clientdata(client);
+ struct i2c_client *client = &data->client;
int word_sized, bank;
struct i2c_client *cl;
mutex_lock(&data->lock);
- if (i2c_is_isa_client(client)) {
+ if (!client->driver) { /* ISA device */
word_sized = (((reg & 0xff00) == 0x100)
|| ((reg & 0xff00) == 0x200))
&& (((reg & 0x00ff) == 0x53)
@@ -1462,13 +1433,18 @@ w83781d_write_value(struct i2c_client *client, u16 reg, u16 value)
}
static void
-w83781d_init_client(struct i2c_client *client)
+w83781d_init_device(struct device *dev)
{
- struct w83781d_data *data = i2c_get_clientdata(client);
+ struct w83781d_data *data = dev_get_drvdata(dev);
int i, p;
int type = data->type;
u8 tmp;
+ if (type == w83627hf)
+ dev_info(dev, "The W83627HF chip is better supported by the "
+ "w83627hf driver, support will be dropped from the "
+ "w83781d driver soon\n");
+
if (reset && type != as99127f) { /* this resets registers we don't have
documentation for on the as99127f */
/* Resetting the chip has been the default for a long time,
@@ -1477,42 +1453,42 @@ w83781d_init_client(struct i2c_client *client)
It might even go away if nobody reports it as being useful,
as I see very little reason why this would be needed at
all. */
- dev_info(&client->dev, "If reset=1 solved a problem you were "
+ dev_info(dev, "If reset=1 solved a problem you were "
"having, please report!\n");
/* save these registers */
- i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
- p = w83781d_read_value(client, W83781D_REG_PWMCLK12);
+ i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG);
+ p = w83781d_read_value(data, W83781D_REG_PWMCLK12);
/* Reset all except Watchdog values and last conversion values
This sets fan-divs to 2, among others */
- w83781d_write_value(client, W83781D_REG_CONFIG, 0x80);
+ w83781d_write_value(data, W83781D_REG_CONFIG, 0x80);
/* Restore the registers and disable power-on abnormal beep.
This saves FAN 1/2/3 input/output values set by BIOS. */
- w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80);
- w83781d_write_value(client, W83781D_REG_PWMCLK12, p);
+ w83781d_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80);
+ w83781d_write_value(data, W83781D_REG_PWMCLK12, p);
/* Disable master beep-enable (reset turns it on).
Individual beep_mask should be reset to off but for some reason
disabling this bit helps some people not get beeped */
- w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0);
+ w83781d_write_value(data, W83781D_REG_BEEP_INTS2, 0);
}
/* Disable power-on abnormal beep, as advised by the datasheet.
Already done if reset=1. */
if (init && !reset && type != as99127f) {
- i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
- w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80);
+ i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG);
+ w83781d_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80);
}
data->vrm = vid_which_vrm();
if ((type != w83781d) && (type != as99127f)) {
- tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
+ tmp = w83781d_read_value(data, W83781D_REG_SCFG1);
for (i = 1; i <= 3; i++) {
if (!(tmp & BIT_SCFG1[i - 1])) {
data->sens[i - 1] = W83781D_DEFAULT_BETA;
} else {
if (w83781d_read_value
- (client,
+ (data,
W83781D_REG_SCFG2) & BIT_SCFG2[i - 1])
data->sens[i - 1] = 1;
else
@@ -1525,38 +1501,46 @@ w83781d_init_client(struct i2c_client *client)
if (init && type != as99127f) {
/* Enable temp2 */
- tmp = w83781d_read_value(client, W83781D_REG_TEMP2_CONFIG);
+ tmp = w83781d_read_value(data, W83781D_REG_TEMP2_CONFIG);
if (tmp & 0x01) {
- dev_warn(&client->dev, "Enabling temp2, readings "
+ dev_warn(dev, "Enabling temp2, readings "
"might not make sense\n");
- w83781d_write_value(client, W83781D_REG_TEMP2_CONFIG,
+ w83781d_write_value(data, W83781D_REG_TEMP2_CONFIG,
tmp & 0xfe);
}
/* Enable temp3 */
if (type != w83783s) {
- tmp = w83781d_read_value(client,
+ tmp = w83781d_read_value(data,
W83781D_REG_TEMP3_CONFIG);
if (tmp & 0x01) {
- dev_warn(&client->dev, "Enabling temp3, "
+ dev_warn(dev, "Enabling temp3, "
"readings might not make sense\n");
- w83781d_write_value(client,
+ w83781d_write_value(data,
W83781D_REG_TEMP3_CONFIG, tmp & 0xfe);
}
}
}
/* Start monitoring */
- w83781d_write_value(client, W83781D_REG_CONFIG,
- (w83781d_read_value(client,
+ w83781d_write_value(data, W83781D_REG_CONFIG,
+ (w83781d_read_value(data,
W83781D_REG_CONFIG) & 0xf7)
| 0x01);
+
+ /* A few vars need to be filled upon startup */
+ for (i = 0; i < 3; i++) {
+ data->fan_min[i] = w83781d_read_value(data,
+ W83781D_REG_FAN_MIN(i));
+ }
+
+ mutex_init(&data->update_lock);
}
static struct w83781d_data *w83781d_update_device(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct w83781d_data *data = i2c_get_clientdata(client);
+ struct w83781d_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = &data->client;
int i;
mutex_lock(&data->update_lock);
@@ -1569,98 +1553,97 @@ static struct w83781d_data *w83781d_update_device(struct device *dev)
if (data->type == w83783s && i == 1)
continue; /* 783S has no in1 */
data->in[i] =
- w83781d_read_value(client, W83781D_REG_IN(i));
+ w83781d_read_value(data, W83781D_REG_IN(i));
data->in_min[i] =
- w83781d_read_value(client, W83781D_REG_IN_MIN(i));
+ w83781d_read_value(data, W83781D_REG_IN_MIN(i));
data->in_max[i] =
- w83781d_read_value(client, W83781D_REG_IN_MAX(i));
+ w83781d_read_value(data, W83781D_REG_IN_MAX(i));
if ((data->type != w83782d)
&& (data->type != w83627hf) && (i == 6))
break;
}
- for (i = 1; i <= 3; i++) {
- data->fan[i - 1] =
- w83781d_read_value(client, W83781D_REG_FAN(i));
- data->fan_min[i - 1] =
- w83781d_read_value(client, W83781D_REG_FAN_MIN(i));
+ for (i = 0; i < 3; i++) {
+ data->fan[i] =
+ w83781d_read_value(data, W83781D_REG_FAN(i));
+ data->fan_min[i] =
+ w83781d_read_value(data, W83781D_REG_FAN_MIN(i));
}
if (data->type != w83781d && data->type != as99127f) {
- for (i = 1; i <= 4; i++) {
- data->pwm[i - 1] =
- w83781d_read_value(client,
- W83781D_REG_PWM(i));
- if ((data->type != w83782d
- || i2c_is_isa_client(client))
- && i == 2)
+ for (i = 0; i < 4; i++) {
+ data->pwm[i] =
+ w83781d_read_value(data,
+ W83781D_REG_PWM[i]);
+ if ((data->type != w83782d || !client->driver)
+ && i == 1)
break;
}
/* Only PWM2 can be disabled */
- data->pwmenable[1] = (w83781d_read_value(client,
+ data->pwm2_enable = (w83781d_read_value(data,
W83781D_REG_PWMCLK12) & 0x08) >> 3;
}
- data->temp = w83781d_read_value(client, W83781D_REG_TEMP(1));
+ data->temp = w83781d_read_value(data, W83781D_REG_TEMP(1));
data->temp_max =
- w83781d_read_value(client, W83781D_REG_TEMP_OVER(1));
+ w83781d_read_value(data, W83781D_REG_TEMP_OVER(1));
data->temp_max_hyst =
- w83781d_read_value(client, W83781D_REG_TEMP_HYST(1));
+ w83781d_read_value(data, W83781D_REG_TEMP_HYST(1));
data->temp_add[0] =
- w83781d_read_value(client, W83781D_REG_TEMP(2));
+ w83781d_read_value(data, W83781D_REG_TEMP(2));
data->temp_max_add[0] =
- w83781d_read_value(client, W83781D_REG_TEMP_OVER(2));
+ w83781d_read_value(data, W83781D_REG_TEMP_OVER(2));
data->temp_max_hyst_add[0] =
- w83781d_read_value(client, W83781D_REG_TEMP_HYST(2));
+ w83781d_read_value(data, W83781D_REG_TEMP_HYST(2));
if (data->type != w83783s) {
data->temp_add[1] =
- w83781d_read_value(client, W83781D_REG_TEMP(3));
+ w83781d_read_value(data, W83781D_REG_TEMP(3));
data->temp_max_add[1] =
- w83781d_read_value(client,
+ w83781d_read_value(data,
W83781D_REG_TEMP_OVER(3));
data->temp_max_hyst_add[1] =
- w83781d_read_value(client,
+ w83781d_read_value(data,
W83781D_REG_TEMP_HYST(3));
}
- i = w83781d_read_value(client, W83781D_REG_VID_FANDIV);
+ i = w83781d_read_value(data, W83781D_REG_VID_FANDIV);
data->vid = i & 0x0f;
- data->vid |= (w83781d_read_value(client,
+ data->vid |= (w83781d_read_value(data,
W83781D_REG_CHIPID) & 0x01) << 4;
data->fan_div[0] = (i >> 4) & 0x03;
data->fan_div[1] = (i >> 6) & 0x03;
- data->fan_div[2] = (w83781d_read_value(client,
+ data->fan_div[2] = (w83781d_read_value(data,
W83781D_REG_PIN) >> 6) & 0x03;
if ((data->type != w83781d) && (data->type != as99127f)) {
- i = w83781d_read_value(client, W83781D_REG_VBAT);
+ i = w83781d_read_value(data, W83781D_REG_VBAT);
data->fan_div[0] |= (i >> 3) & 0x04;
data->fan_div[1] |= (i >> 4) & 0x04;
data->fan_div[2] |= (i >> 5) & 0x04;
}
if ((data->type == w83782d) || (data->type == w83627hf)) {
- data->alarms = w83781d_read_value(client,
+ data->alarms = w83781d_read_value(data,
W83782D_REG_ALARM1)
- | (w83781d_read_value(client,
+ | (w83781d_read_value(data,
W83782D_REG_ALARM2) << 8)
- | (w83781d_read_value(client,
+ | (w83781d_read_value(data,
W83782D_REG_ALARM3) << 16);
} else if (data->type == w83783s) {
- data->alarms = w83781d_read_value(client,
+ data->alarms = w83781d_read_value(data,
W83782D_REG_ALARM1)
- | (w83781d_read_value(client,
+ | (w83781d_read_value(data,
W83782D_REG_ALARM2) << 8);
} else {
/* No real-time status registers, fall back to
interrupt status registers */
- data->alarms = w83781d_read_value(client,
+ data->alarms = w83781d_read_value(data,
W83781D_REG_ALARM1)
- | (w83781d_read_value(client,
+ | (w83781d_read_value(data,
W83781D_REG_ALARM2) << 8);
}
- i = w83781d_read_value(client, W83781D_REG_BEEP_INTS2);
+ i = w83781d_read_value(data, W83781D_REG_BEEP_INTS2);
data->beep_enable = i >> 7;
data->beep_mask = ((i & 0x7f) << 8) +
- w83781d_read_value(client, W83781D_REG_BEEP_INTS1);
+ w83781d_read_value(data, W83781D_REG_BEEP_INTS1);
if ((data->type != w83781d) && (data->type != as99127f)) {
data->beep_mask |=
- w83781d_read_value(client,
+ w83781d_read_value(data,
W83781D_REG_BEEP_INTS3) << 16;
}
data->last_updated = jiffies;
@@ -1672,6 +1655,133 @@ static struct w83781d_data *w83781d_update_device(struct device *dev)
return data;
}
+/* return 1 if a supported chip is found, 0 otherwise */
+static int __init
+w83781d_isa_found(unsigned short address)
+{
+ int val, save, found = 0;
+
+ if (!request_region(address, W83781D_EXTENT, "w83781d"))
+ return 0;
+
+#define REALLY_SLOW_IO
+ /* We need the timeouts for at least some W83781D-like
+ chips. But only if we read 'undefined' registers. */
+ val = inb_p(address + 1);
+ if (inb_p(address + 2) != val
+ || inb_p(address + 3) != val
+ || inb_p(address + 7) != val) {
+ pr_debug("w83781d: Detection failed at step 1\n");
+ goto release;
+ }
+#undef REALLY_SLOW_IO
+
+ /* We should be able to change the 7 LSB of the address port. The
+ MSB (busy flag) should be clear initially, set after the write. */
+ save = inb_p(address + W83781D_ADDR_REG_OFFSET);
+ if (save & 0x80) {
+ pr_debug("w83781d: Detection failed at step 2\n");
+ goto release;
+ }
+ val = ~save & 0x7f;
+ outb_p(val, address + W83781D_ADDR_REG_OFFSET);
+ if (inb_p(address + W83781D_ADDR_REG_OFFSET) != (val | 0x80)) {
+ outb_p(save, address + W83781D_ADDR_REG_OFFSET);
+ pr_debug("w83781d: Detection failed at step 3\n");
+ goto release;
+ }
+
+ /* We found a device, now see if it could be a W83781D */
+ outb_p(W83781D_REG_CONFIG, address + W83781D_ADDR_REG_OFFSET);
+ val = inb_p(address + W83781D_DATA_REG_OFFSET);
+ if (val & 0x80) {
+ pr_debug("w83781d: Detection failed at step 4\n");
+ goto release;
+ }
+ outb_p(W83781D_REG_BANK, address + W83781D_ADDR_REG_OFFSET);
+ save = inb_p(address + W83781D_DATA_REG_OFFSET);
+ outb_p(W83781D_REG_CHIPMAN, address + W83781D_ADDR_REG_OFFSET);
+ val = inb_p(address + W83781D_DATA_REG_OFFSET);
+ if ((!(save & 0x80) && (val != 0xa3))
+ || ((save & 0x80) && (val != 0x5c))) {
+ pr_debug("w83781d: Detection failed at step 5\n");
+ goto release;
+ }
+ outb_p(W83781D_REG_I2C_ADDR, address + W83781D_ADDR_REG_OFFSET);
+ val = inb_p(address + W83781D_DATA_REG_OFFSET);
+ if (val < 0x03 || val > 0x77) { /* Not a valid I2C address */
+ pr_debug("w83781d: Detection failed at step 6\n");
+ goto release;
+ }
+
+ /* The busy flag should be clear again */
+ if (inb_p(address + W83781D_ADDR_REG_OFFSET) & 0x80) {
+ pr_debug("w83781d: Detection failed at step 7\n");
+ goto release;
+ }
+
+ /* Determine the chip type */
+ outb_p(W83781D_REG_BANK, address + W83781D_ADDR_REG_OFFSET);
+ save = inb_p(address + W83781D_DATA_REG_OFFSET);
+ outb_p(save & 0xf8, address + W83781D_DATA_REG_OFFSET);
+ outb_p(W83781D_REG_WCHIPID, address + W83781D_ADDR_REG_OFFSET);
+ val = inb_p(address + W83781D_DATA_REG_OFFSET);
+ if ((val & 0xfe) == 0x10 /* W83781D */
+ || val == 0x30 /* W83782D */
+ || val == 0x21) /* W83627HF */
+ found = 1;
+
+ if (found)
+ pr_info("w83781d: Found a %s chip at %#x\n",
+ val == 0x21 ? "W83627HF" :
+ val == 0x30 ? "W83782D" : "W83781D", (int)address);
+
+ release:
+ release_region(address, W83781D_EXTENT);
+ return found;
+}
+
+static int __init
+w83781d_isa_device_add(unsigned short address)
+{
+ struct resource res = {
+ .start = address,
+ .end = address + W83781D_EXTENT,
+ .name = "w83781d",
+ .flags = IORESOURCE_IO,
+ };
+ int err;
+
+ pdev = platform_device_alloc("w83781d", address);
+ if (!pdev) {
+ err = -ENOMEM;
+ printk(KERN_ERR "w83781d: Device allocation failed\n");
+ goto exit;
+ }
+
+ err = platform_device_add_resources(pdev, &res, 1);
+ if (err) {
+ printk(KERN_ERR "w83781d: Device resource addition failed "
+ "(%d)\n", err);
+ goto exit_device_put;
+ }
+
+ err = platform_device_add(pdev);
+ if (err) {
+ printk(KERN_ERR "w83781d: Device addition failed (%d)\n",
+ err);
+ goto exit_device_put;
+ }
+
+ return 0;
+
+ exit_device_put:
+ platform_device_put(pdev);
+ exit:
+ pdev = NULL;
+ return err;
+}
+
static int __init
sensors_w83781d_init(void)
{
@@ -1679,21 +1789,36 @@ sensors_w83781d_init(void)
res = i2c_add_driver(&w83781d_driver);
if (res)
- return res;
+ goto exit;
+
+ if (w83781d_isa_found(isa_address)) {
+ res = platform_driver_register(&w83781d_isa_driver);
+ if (res)
+ goto exit_unreg_i2c_driver;
- /* Don't exit if this one fails, we still want the I2C variants
- to work! */
- if (i2c_isa_add_driver(&w83781d_isa_driver))
- isa_address = 0;
+ /* Sets global pdev as a side effect */
+ res = w83781d_isa_device_add(isa_address);
+ if (res)
+ goto exit_unreg_isa_driver;
+ }
return 0;
+
+ exit_unreg_isa_driver:
+ platform_driver_unregister(&w83781d_isa_driver);
+ exit_unreg_i2c_driver:
+ i2c_del_driver(&w83781d_driver);
+ exit:
+ return res;
}
static void __exit
sensors_w83781d_exit(void)
{
- if (isa_address)
- i2c_isa_del_driver(&w83781d_isa_driver);
+ if (pdev) {
+ platform_device_unregister(pdev);
+ platform_driver_unregister(&w83781d_isa_driver);
+ }
i2c_del_driver(&w83781d_driver);
}
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index 8c95370..039a07f 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -175,6 +175,7 @@ static void i2c_parport_attach (struct parport *port)
}
adapter->algo_data.data = port;
adapter->adapter.algo_data = &adapter->algo_data;
+ adapter->adapter.dev.parent = port->physport->dev;
if (parport_claim_or_block(adapter->pdev) < 0) {
printk(KERN_ERR "i2c-parport: Could not claim parallel port\n");
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index c059b27..873544a 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -852,9 +852,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
{
struct pxa_i2c *i2c = &i2c_pxa;
struct resource *res;
-#ifdef CONFIG_I2C_PXA_SLAVE
struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
-#endif
int ret;
int irq;
@@ -902,14 +900,14 @@ static int i2c_pxa_probe(struct platform_device *dev)
pxa_gpio_mode(GPIO117_I2CSCL_MD);
pxa_gpio_mode(GPIO118_I2CSDA_MD);
#endif
- pxa_set_cken(CKEN14_I2C, 1);
+ pxa_set_cken(CKEN_I2C, 1);
break;
#ifdef CONFIG_PXA27x
case 1:
local_irq_disable();
PCFR |= PCFR_PI2CEN;
local_irq_enable();
- pxa_set_cken(CKEN15_PWRI2C, 1);
+ pxa_set_cken(CKEN_PWRI2C, 1);
#endif
}
@@ -924,6 +922,10 @@ static int i2c_pxa_probe(struct platform_device *dev)
i2c->adap.algo_data = i2c;
i2c->adap.dev.parent = &dev->dev;
+ if (plat) {
+ i2c->adap.class = plat->class;
+ }
+
ret = i2c_add_adapter(&i2c->adap);
if (ret < 0) {
printk(KERN_INFO "I2C: Failed to add bus\n");
@@ -946,11 +948,11 @@ eadapt:
ereqirq:
switch (dev->id) {
case 0:
- pxa_set_cken(CKEN14_I2C, 0);
+ pxa_set_cken(CKEN_I2C, 0);
break;
#ifdef CONFIG_PXA27x
case 1:
- pxa_set_cken(CKEN15_PWRI2C, 0);
+ pxa_set_cken(CKEN_PWRI2C, 0);
local_irq_disable();
PCFR &= ~PCFR_PI2CEN;
local_irq_enable();
@@ -973,11 +975,11 @@ static int i2c_pxa_remove(struct platform_device *dev)
free_irq(i2c->irq, i2c);
switch (dev->id) {
case 0:
- pxa_set_cken(CKEN14_I2C, 0);
+ pxa_set_cken(CKEN_I2C, 0);
break;
#ifdef CONFIG_PXA27x
case 1:
- pxa_set_cken(CKEN15_PWRI2C, 0);
+ pxa_set_cken(CKEN_PWRI2C, 0);
local_irq_disable();
PCFR &= ~PCFR_PI2CEN;
local_irq_enable();
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index 0db56e7..0d6bd4f 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -28,7 +28,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/i2c.h>
-#include <linux/smp_lock.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mutex.h>
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
index 214fbb1..7ed92dc 100644
--- a/drivers/i2c/chips/tps65010.c
+++ b/drivers/i2c/chips/tps65010.c
@@ -351,8 +351,10 @@ static void tps65010_interrupt(struct tps65010 *tps)
#if 0
/* REVISIT: this might need its own workqueue
* plus tweaks including deadlock avoidance ...
+ * also needs to get error handling and probably
+ * an #ifdef CONFIG_SOFTWARE_SUSPEND
*/
- software_suspend();
+ pm_suspend(PM_SUSPEND_DISK);
#endif
poll = 1;
}
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index cb4fa9b..e7a7097 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -30,7 +30,6 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/i2c.h>
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 2da5cbb..2cdd629 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -395,7 +395,7 @@ static void __devinit apple_kiwi_init(struct pci_dev *pdev)
unsigned int class_rev = 0;
u8 conf;
- if (np == NULL || !device_is_compatible(np, "kiwi-root"))
+ if (np == NULL || !of_device_is_compatible(np, "kiwi-root"))
return;
pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 071a030..a49ebe4 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1157,32 +1157,32 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
pmif->cable_80 = 0;
pmif->broken_dma = pmif->broken_dma_warn = 0;
- if (device_is_compatible(np, "shasta-ata"))
+ if (of_device_is_compatible(np, "shasta-ata"))
pmif->kind = controller_sh_ata6;
- else if (device_is_compatible(np, "kauai-ata"))
+ else if (of_device_is_compatible(np, "kauai-ata"))
pmif->kind = controller_un_ata6;
- else if (device_is_compatible(np, "K2-UATA"))
+ else if (of_device_is_compatible(np, "K2-UATA"))
pmif->kind = controller_k2_ata6;
- else if (device_is_compatible(np, "keylargo-ata")) {
+ else if (of_device_is_compatible(np, "keylargo-ata")) {
if (strcmp(np->name, "ata-4") == 0)
pmif->kind = controller_kl_ata4;
else
pmif->kind = controller_kl_ata3;
- } else if (device_is_compatible(np, "heathrow-ata"))
+ } else if (of_device_is_compatible(np, "heathrow-ata"))
pmif->kind = controller_heathrow;
else {
pmif->kind = controller_ohare;
pmif->broken_dma = 1;
}
- bidp = get_property(np, "AAPL,bus-id", NULL);
+ bidp = of_get_property(np, "AAPL,bus-id", NULL);
pmif->aapl_bus_id = bidp ? *bidp : 0;
/* Get cable type from device-tree */
if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6
|| pmif->kind == controller_k2_ata6
|| pmif->kind == controller_sh_ata6) {
- const char* cable = get_property(np, "cable-type", NULL);
+ const char* cable = of_get_property(np, "cable-type", NULL);
if (cable && !strncmp(cable, "80-", 3))
pmif->cable_80 = 1;
}
@@ -1190,8 +1190,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
* they have a 80 conductor cable, this seem to be always the case unless
* the user mucked around
*/
- if (device_is_compatible(np, "K2-UATA") ||
- device_is_compatible(np, "shasta-ata"))
+ if (of_device_is_compatible(np, "K2-UATA") ||
+ of_device_is_compatible(np, "shasta-ata"))
pmif->cable_80 = 1;
/* On Kauai-type controllers, we make sure the FCR is correct */
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 026e38f..2081413 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -94,7 +94,6 @@
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/bitops.h>
#include <asm/byteorder.h>
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index c6aefd9..d382500 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -35,7 +35,6 @@
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include <linux/cdev.h>
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 95ca26d..87ebd08 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -39,7 +39,6 @@
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <linux/types.h>
diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c
index 1d796e7..a06bcc6 100644
--- a/drivers/infiniband/core/fmr_pool.c
+++ b/drivers/infiniband/core/fmr_pool.c
@@ -43,6 +43,8 @@
#include "core_priv.h"
+#define PFX "fmr_pool: "
+
enum {
IB_FMR_MAX_REMAPS = 32,
@@ -150,7 +152,7 @@ static void ib_fmr_batch_release(struct ib_fmr_pool *pool)
#ifdef DEBUG
if (fmr->ref_count !=0) {
- printk(KERN_WARNING "Unmapping FMR 0x%08x with ref count %d",
+ printk(KERN_WARNING PFX "Unmapping FMR 0x%08x with ref count %d",
fmr, fmr->ref_count);
}
#endif
@@ -168,7 +170,7 @@ static void ib_fmr_batch_release(struct ib_fmr_pool *pool)
ret = ib_unmap_fmr(&fmr_list);
if (ret)
- printk(KERN_WARNING "ib_unmap_fmr returned %d", ret);
+ printk(KERN_WARNING PFX "ib_unmap_fmr returned %d", ret);
spin_lock_irq(&pool->pool_lock);
list_splice(&unmap_list, &pool->free_list);
@@ -226,20 +228,20 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
device = pd->device;
if (!device->alloc_fmr || !device->dealloc_fmr ||
!device->map_phys_fmr || !device->unmap_fmr) {
- printk(KERN_WARNING "Device %s does not support fast memory regions",
+ printk(KERN_INFO PFX "Device %s does not support FMRs\n",
device->name);
return ERR_PTR(-ENOSYS);
}
attr = kmalloc(sizeof *attr, GFP_KERNEL);
if (!attr) {
- printk(KERN_WARNING "couldn't allocate device attr struct");
+ printk(KERN_WARNING PFX "couldn't allocate device attr struct");
return ERR_PTR(-ENOMEM);
}
ret = ib_query_device(device, attr);
if (ret) {
- printk(KERN_WARNING "couldn't query device");
+ printk(KERN_WARNING PFX "couldn't query device: %d", ret);
kfree(attr);
return ERR_PTR(ret);
}
@@ -253,7 +255,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
pool = kmalloc(sizeof *pool, GFP_KERNEL);
if (!pool) {
- printk(KERN_WARNING "couldn't allocate pool struct");
+ printk(KERN_WARNING PFX "couldn't allocate pool struct");
return ERR_PTR(-ENOMEM);
}
@@ -270,7 +272,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
kmalloc(IB_FMR_HASH_SIZE * sizeof *pool->cache_bucket,
GFP_KERNEL);
if (!pool->cache_bucket) {
- printk(KERN_WARNING "Failed to allocate cache in pool");
+ printk(KERN_WARNING PFX "Failed to allocate cache in pool");
ret = -ENOMEM;
goto out_free_pool;
}
@@ -294,7 +296,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
"ib_fmr(%s)",
device->name);
if (IS_ERR(pool->thread)) {
- printk(KERN_WARNING "couldn't start cleanup thread");
+ printk(KERN_WARNING PFX "couldn't start cleanup thread");
ret = PTR_ERR(pool->thread);
goto out_free_pool;
}
@@ -311,8 +313,8 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
fmr = kmalloc(sizeof *fmr + params->max_pages_per_fmr * sizeof (u64),
GFP_KERNEL);
if (!fmr) {
- printk(KERN_WARNING "failed to allocate fmr struct "
- "for FMR %d", i);
+ printk(KERN_WARNING PFX "failed to allocate fmr "
+ "struct for FMR %d", i);
goto out_fail;
}
@@ -323,7 +325,8 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
fmr->fmr = ib_alloc_fmr(pd, params->access, &fmr_attr);
if (IS_ERR(fmr->fmr)) {
- printk(KERN_WARNING "fmr_create failed for FMR %d", i);
+ printk(KERN_WARNING PFX "fmr_create failed "
+ "for FMR %d", i);
kfree(fmr);
goto out_fail;
}
@@ -378,7 +381,7 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool)
}
if (i < pool->pool_size)
- printk(KERN_WARNING "pool still has %d regions registered",
+ printk(KERN_WARNING PFX "pool still has %d regions registered",
pool->pool_size - i);
kfree(pool->cache_bucket);
@@ -463,8 +466,7 @@ struct ib_pool_fmr *ib_fmr_pool_map_phys(struct ib_fmr_pool *pool_handle,
list_add(&fmr->list, &pool->free_list);
spin_unlock_irqrestore(&pool->pool_lock, flags);
- printk(KERN_WARNING "fmr_map returns %d\n",
- result);
+ printk(KERN_WARNING PFX "fmr_map returns %d\n", result);
return ERR_PTR(result);
}
@@ -516,7 +518,7 @@ int ib_fmr_pool_unmap(struct ib_pool_fmr *fmr)
#ifdef DEBUG
if (fmr->ref_count < 0)
- printk(KERN_WARNING "FMR %p has ref count %d < 0",
+ printk(KERN_WARNING PFX "FMR %p has ref count %d < 0",
fmr, fmr->ref_count);
#endif
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 6edfecf..85ccf13 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -2771,7 +2771,7 @@ static int ib_mad_port_open(struct ib_device *device,
cq_size = (IB_MAD_QP_SEND_SIZE + IB_MAD_QP_RECV_SIZE) * 2;
port_priv->cq = ib_create_cq(port_priv->device,
ib_mad_thread_completion_handler,
- NULL, port_priv, cq_size);
+ NULL, port_priv, cq_size, 0);
if (IS_ERR(port_priv->cq)) {
printk(KERN_ERR PFX "Couldn't create ib_mad CQ\n");
ret = PTR_ERR(port_priv->cq);
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 4fd75af..bab6676 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -802,6 +802,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
INIT_LIST_HEAD(&obj->async_list);
cq = file->device->ib_dev->create_cq(file->device->ib_dev, cmd.cqe,
+ cmd.comp_vector,
file->ucontext, &udata);
if (IS_ERR(cq)) {
ret = PTR_ERR(cq);
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index f8bc822..d44e547 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -752,7 +752,7 @@ static void ib_uverbs_add_one(struct ib_device *device)
spin_unlock(&map_lock);
uverbs_dev->ib_dev = device;
- uverbs_dev->num_comp_vectors = 1;
+ uverbs_dev->num_comp_vectors = device->num_comp_vectors;
uverbs_dev->dev = cdev_alloc();
if (!uverbs_dev->dev)
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index ccdf93d..86ed8af 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -609,11 +609,11 @@ EXPORT_SYMBOL(ib_destroy_qp);
struct ib_cq *ib_create_cq(struct ib_device *device,
ib_comp_handler comp_handler,
void (*event_handler)(struct ib_event *, void *),
- void *cq_context, int cqe)
+ void *cq_context, int cqe, int comp_vector)
{
struct ib_cq *cq;
- cq = device->create_cq(device, cqe, NULL, NULL);
+ cq = device->create_cq(device, cqe, comp_vector, NULL, NULL);
if (!IS_ERR(cq)) {
cq->device = device;
diff --git a/drivers/infiniband/hw/amso1100/c2.h b/drivers/infiniband/hw/amso1100/c2.h
index 04a9db5..fa58200 100644
--- a/drivers/infiniband/hw/amso1100/c2.h
+++ b/drivers/infiniband/hw/amso1100/c2.h
@@ -519,7 +519,7 @@ extern void c2_free_cq(struct c2_dev *c2dev, struct c2_cq *cq);
extern void c2_cq_event(struct c2_dev *c2dev, u32 mq_index);
extern void c2_cq_clean(struct c2_dev *c2dev, struct c2_qp *qp, u32 mq_index);
extern int c2_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry);
-extern int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify);
+extern int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
/* CM */
extern int c2_llp_connect(struct iw_cm_id *cm_id,
diff --git a/drivers/infiniband/hw/amso1100/c2_cq.c b/drivers/infiniband/hw/amso1100/c2_cq.c
index 5175c99..d2b3366 100644
--- a/drivers/infiniband/hw/amso1100/c2_cq.c
+++ b/drivers/infiniband/hw/amso1100/c2_cq.c
@@ -217,17 +217,19 @@ int c2_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)
return npolled;
}
-int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
+int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags)
{
struct c2_mq_shared __iomem *shared;
struct c2_cq *cq;
+ unsigned long flags;
+ int ret = 0;
cq = to_c2cq(ibcq);
shared = cq->mq.peer;
- if (notify == IB_CQ_NEXT_COMP)
+ if ((notify_flags & IB_CQ_SOLICITED_MASK) == IB_CQ_NEXT_COMP)
writeb(C2_CQ_NOTIFICATION_TYPE_NEXT, &shared->notification_type);
- else if (notify == IB_CQ_SOLICITED)
+ else if ((notify_flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED)
writeb(C2_CQ_NOTIFICATION_TYPE_NEXT_SE, &shared->notification_type);
else
return -EINVAL;
@@ -241,7 +243,13 @@ int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
*/
readb(&shared->armed);
- return 0;
+ if (notify_flags & IB_CQ_REPORT_MISSED_EVENTS) {
+ spin_lock_irqsave(&cq->lock, flags);
+ ret = !c2_mq_empty(&cq->mq);
+ spin_unlock_irqrestore(&cq->lock, flags);
+ }
+
+ return ret;
}
static void c2_free_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq)
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c
index 607c09b..1091662 100644
--- a/drivers/infiniband/hw/amso1100/c2_provider.c
+++ b/drivers/infiniband/hw/amso1100/c2_provider.c
@@ -290,7 +290,7 @@ static int c2_destroy_qp(struct ib_qp *ib_qp)
return 0;
}
-static struct ib_cq *c2_create_cq(struct ib_device *ibdev, int entries,
+static struct ib_cq *c2_create_cq(struct ib_device *ibdev, int entries, int vector,
struct ib_ucontext *context,
struct ib_udata *udata)
{
@@ -795,6 +795,7 @@ int c2_register_device(struct c2_dev *dev)
memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid));
memcpy(&dev->ibdev.node_guid, dev->pseudo_netdev->dev_addr, 6);
dev->ibdev.phys_port_cnt = 1;
+ dev->ibdev.num_comp_vectors = 1;
dev->ibdev.dma_device = &dev->pcidev->dev;
dev->ibdev.query_device = c2_query_device;
dev->ibdev.query_port = c2_query_port;
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index f5e9aee..76049af 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -114,7 +114,10 @@ int cxio_hal_cq_op(struct cxio_rdev *rdev_p, struct t3_cq *cq,
return -EIO;
}
}
+
+ return 1;
}
+
return 0;
}
diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h
index 90d7b89..ff7290e 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_wr.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h
@@ -38,6 +38,7 @@
#include "firmware_exports.h"
#define T3_MAX_SGE 4
+#define T3_MAX_INLINE 64
#define Q_EMPTY(rptr,wptr) ((rptr)==(wptr))
#define Q_FULL(rptr,wptr,size_log2) ( (((wptr)-(rptr))>>(size_log2)) && \
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index 3b4b0ac..b2faff5 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -1109,6 +1109,15 @@ static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
PDBG("%s ep %p\n", __FUNCTION__, ep);
+ /*
+ * We get 2 abort replies from the HW. The first one must
+ * be ignored except for scribbling that we need one more.
+ */
+ if (!(ep->flags & ABORT_REQ_IN_PROGRESS)) {
+ ep->flags |= ABORT_REQ_IN_PROGRESS;
+ return CPL_RET_BUF_DONE;
+ }
+
close_complete_upcall(ep);
state_set(&ep->com, DEAD);
release_ep_resources(ep);
@@ -1189,6 +1198,7 @@ static int listen_stop(struct iwch_listen_ep *ep)
}
req = (struct cpl_close_listserv_req *) skb_put(skb, sizeof(*req));
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
+ req->cpu_idx = 0;
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid));
skb->priority = 1;
ep->com.tdev->send(ep->com.tdev, skb);
@@ -1475,6 +1485,15 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
int ret;
int state;
+ /*
+ * We get 2 peer aborts from the HW. The first one must
+ * be ignored except for scribbling that we need one more.
+ */
+ if (!(ep->flags & PEER_ABORT_IN_PROGRESS)) {
+ ep->flags |= PEER_ABORT_IN_PROGRESS;
+ return CPL_RET_BUF_DONE;
+ }
+
if (is_neg_adv_abort(req->status)) {
PDBG("%s neg_adv_abort ep %p tid %d\n", __FUNCTION__, ep,
ep->hwtid);
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.h b/drivers/infiniband/hw/cxgb3/iwch_cm.h
index 0c6f281..21a388c 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.h
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.h
@@ -143,6 +143,11 @@ enum iwch_ep_state {
DEAD,
};
+enum iwch_ep_flags {
+ PEER_ABORT_IN_PROGRESS = (1 << 0),
+ ABORT_REQ_IN_PROGRESS = (1 << 1),
+};
+
struct iwch_ep_common {
struct iw_cm_id *cm_id;
struct iwch_qp *qp;
@@ -181,6 +186,7 @@ struct iwch_ep {
u16 plen;
u32 ird;
u32 ord;
+ u32 flags;
};
static inline struct iwch_ep *to_ep(struct iw_cm_id *cm_id)
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index af28a31..a891493 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -139,7 +139,7 @@ static int iwch_destroy_cq(struct ib_cq *ib_cq)
return 0;
}
-static struct ib_cq *iwch_create_cq(struct ib_device *ibdev, int entries,
+static struct ib_cq *iwch_create_cq(struct ib_device *ibdev, int entries, int vector,
struct ib_ucontext *ib_context,
struct ib_udata *udata)
{
@@ -292,7 +292,7 @@ static int iwch_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata)
#endif
}
-static int iwch_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
+static int iwch_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
{
struct iwch_dev *rhp;
struct iwch_cq *chp;
@@ -303,7 +303,7 @@ static int iwch_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
chp = to_iwch_cq(ibcq);
rhp = chp->rhp;
- if (notify == IB_CQ_SOLICITED)
+ if ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED)
cq_op = CQ_ARM_SE;
else
cq_op = CQ_ARM_AN;
@@ -317,9 +317,11 @@ static int iwch_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
PDBG("%s rptr 0x%x\n", __FUNCTION__, chp->cq.rptr);
err = cxio_hal_cq_op(&rhp->rdev, &chp->cq, cq_op, 0);
spin_unlock_irqrestore(&chp->lock, flag);
- if (err)
+ if (err < 0)
printk(KERN_ERR MOD "Error %d rearming CQID 0x%x\n", err,
chp->cq.cqid);
+ if (err > 0 && !(flags & IB_CQ_REPORT_MISSED_EVENTS))
+ err = 0;
return err;
}
@@ -780,6 +782,9 @@ static struct ib_qp *iwch_create_qp(struct ib_pd *pd,
if (rqsize > T3_MAX_RQ_SIZE)
return ERR_PTR(-EINVAL);
+ if (attrs->cap.max_inline_data > T3_MAX_INLINE)
+ return ERR_PTR(-EINVAL);
+
/*
* NOTE: The SQ and total WQ sizes don't need to be
* a power of two. However, all the code assumes
@@ -1107,6 +1112,7 @@ int iwch_register_device(struct iwch_dev *dev)
dev->ibdev.node_type = RDMA_NODE_RNIC;
memcpy(dev->ibdev.node_desc, IWCH_NODE_DESC, sizeof(IWCH_NODE_DESC));
dev->ibdev.phys_port_cnt = dev->rdev.port_info.nports;
+ dev->ibdev.num_comp_vectors = 1;
dev->ibdev.dma_device = &(dev->rdev.rnic_info.pdev->dev);
dev->ibdev.query_device = iwch_query_device;
dev->ibdev.query_port = iwch_query_port;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c
index 0a472c9..714dddb 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_qp.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c
@@ -471,43 +471,62 @@ int iwch_bind_mw(struct ib_qp *qp,
return err;
}
-static void build_term_codes(int t3err, u8 *layer_type, u8 *ecode, int tagged)
+static inline void build_term_codes(struct respQ_msg_t *rsp_msg,
+ u8 *layer_type, u8 *ecode)
{
- switch (t3err) {
+ int status = TPT_ERR_INTERNAL_ERR;
+ int tagged = 0;
+ int opcode = -1;
+ int rqtype = 0;
+ int send_inv = 0;
+
+ if (rsp_msg) {
+ status = CQE_STATUS(rsp_msg->cqe);
+ opcode = CQE_OPCODE(rsp_msg->cqe);
+ rqtype = RQ_TYPE(rsp_msg->cqe);
+ send_inv = (opcode == T3_SEND_WITH_INV) ||
+ (opcode == T3_SEND_WITH_SE_INV);
+ tagged = (opcode == T3_RDMA_WRITE) ||
+ (rqtype && (opcode == T3_READ_RESP));
+ }
+
+ switch (status) {
case TPT_ERR_STAG:
- if (tagged == 1) {
- *layer_type = LAYER_DDP|DDP_TAGGED_ERR;
- *ecode = DDPT_INV_STAG;
- } else if (tagged == 2) {
+ if (send_inv) {
+ *layer_type = LAYER_RDMAP|RDMAP_REMOTE_OP;
+ *ecode = RDMAP_CANT_INV_STAG;
+ } else {
*layer_type = LAYER_RDMAP|RDMAP_REMOTE_PROT;
*ecode = RDMAP_INV_STAG;
}
break;
case TPT_ERR_PDID:
+ *layer_type = LAYER_RDMAP|RDMAP_REMOTE_PROT;
+ if ((opcode == T3_SEND_WITH_INV) ||
+ (opcode == T3_SEND_WITH_SE_INV))
+ *ecode = RDMAP_CANT_INV_STAG;
+ else
+ *ecode = RDMAP_STAG_NOT_ASSOC;
+ break;
case TPT_ERR_QPID:
+ *layer_type = LAYER_RDMAP|RDMAP_REMOTE_PROT;
+ *ecode = RDMAP_STAG_NOT_ASSOC;
+ break;
case TPT_ERR_ACCESS:
- if (tagged == 1) {
- *layer_type = LAYER_DDP|DDP_TAGGED_ERR;
- *ecode = DDPT_STAG_NOT_ASSOC;
- } else if (tagged == 2) {
- *layer_type = LAYER_RDMAP|RDMAP_REMOTE_PROT;
- *ecode = RDMAP_STAG_NOT_ASSOC;
- }
+ *layer_type = LAYER_RDMAP|RDMAP_REMOTE_PROT;
+ *ecode = RDMAP_ACC_VIOL;
break;
case TPT_ERR_WRAP:
*layer_type = LAYER_RDMAP|RDMAP_REMOTE_PROT;
*ecode = RDMAP_TO_WRAP;
break;
case TPT_ERR_BOUND:
- if (tagged == 1) {
+ if (tagged) {
*layer_type = LAYER_DDP|DDP_TAGGED_ERR;
*ecode = DDPT_BASE_BOUNDS;
- } else if (tagged == 2) {
+ } else {
*layer_type = LAYER_RDMAP|RDMAP_REMOTE_PROT;
*ecode = RDMAP_BASE_BOUNDS;
- } else {
- *layer_type = LAYER_DDP|DDP_UNTAGGED_ERR;
- *ecode = DDPU_MSG_TOOBIG;
}
break;
case TPT_ERR_INVALIDATE_SHARED_MR:
@@ -591,8 +610,6 @@ int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg)
{
union t3_wr *wqe;
struct terminate_message *term;
- int status;
- int tagged = 0;
struct sk_buff *skb;
PDBG("%s %d\n", __FUNCTION__, __LINE__);
@@ -610,17 +627,7 @@ int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg)
/* immediate data starts here. */
term = (struct terminate_message *)wqe->send.sgl;
- if (rsp_msg) {
- status = CQE_STATUS(rsp_msg->cqe);
- if (CQE_OPCODE(rsp_msg->cqe) == T3_RDMA_WRITE)
- tagged = 1;
- if ((CQE_OPCODE(rsp_msg->cqe) == T3_READ_REQ) ||
- (CQE_OPCODE(rsp_msg->cqe) == T3_READ_RESP))
- tagged = 2;
- } else {
- status = TPT_ERR_INTERNAL_ERR;
- }
- build_term_codes(status, &term->layer_etype, &term->ecode, tagged);
+ build_term_codes(rsp_msg, &term->layer_etype, &term->ecode);
build_fw_riwrh((void *)wqe, T3_WR_SEND,
T3_COMPLETION_FLAG | T3_NOTIFY_FLAG, 1,
qhp->ep->hwtid, 5);
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index e2cdc1a..67f0670 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -113,7 +113,7 @@ struct ehca_qp* ehca_cq_get_qp(struct ehca_cq *cq, int real_qp_num)
return ret;
}
-struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe,
+struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
struct ib_ucontext *context,
struct ib_udata *udata)
{
diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h
index 95fd59f..e14b029 100644
--- a/drivers/infiniband/hw/ehca/ehca_iverbs.h
+++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h
@@ -123,7 +123,7 @@ int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq);
void *ehca_poll_eq(struct ehca_shca *shca, struct ehca_eq *eq);
-struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe,
+struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
struct ib_ucontext *context,
struct ib_udata *udata);
@@ -135,7 +135,7 @@ int ehca_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc);
int ehca_peek_cq(struct ib_cq *cq, int wc_cnt);
-int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify cq_notify);
+int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags notify_flags);
struct ib_qp *ehca_create_qp(struct ib_pd *pd,
struct ib_qp_init_attr *init_attr,
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 4700085..fe90e74 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -313,6 +313,7 @@ int ehca_init_device(struct ehca_shca *shca)
shca->ib_device.node_type = RDMA_NODE_IB_CA;
shca->ib_device.phys_port_cnt = shca->num_ports;
+ shca->ib_device.num_comp_vectors = 1;
shca->ib_device.dma_device = &shca->ibmebus_dev->ofdev.dev;
shca->ib_device.query_device = ehca_query_device;
shca->ib_device.query_port = ehca_query_port;
@@ -375,7 +376,7 @@ static int ehca_create_aqp1(struct ehca_shca *shca, u32 port)
return -EPERM;
}
- ibcq = ib_create_cq(&shca->ib_device, NULL, NULL, (void*)(-1), 10);
+ ibcq = ib_create_cq(&shca->ib_device, NULL, NULL, (void*)(-1), 10, 0);
if (IS_ERR(ibcq)) {
ehca_err(&shca->ib_device, "Cannot create AQP1 CQ.");
return PTR_ERR(ibcq);
@@ -569,7 +570,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
struct ib_pd *ibpd;
int ret;
- handle = get_property(dev->ofdev.node, "ibm,hca-handle", NULL);
+ handle = of_get_property(dev->ofdev.node, "ibm,hca-handle", NULL);
if (!handle) {
ehca_gen_err("Cannot get eHCA handle for adapter: %s.",
dev->ofdev.node->full_name);
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c b/drivers/infiniband/hw/ehca/ehca_reqs.c
index 08d3f89..caec9de 100644
--- a/drivers/infiniband/hw/ehca/ehca_reqs.c
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -634,11 +634,13 @@ poll_cq_exit0:
return ret;
}
-int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify cq_notify)
+int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags notify_flags)
{
struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq);
+ unsigned long spl_flags;
+ int ret = 0;
- switch (cq_notify) {
+ switch (notify_flags & IB_CQ_SOLICITED_MASK) {
case IB_CQ_SOLICITED:
hipz_set_cqx_n0(my_cq, 1);
break;
@@ -649,5 +651,11 @@ int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify cq_notify)
return -EINVAL;
}
- return 0;
+ if (notify_flags & IB_CQ_REPORT_MISSED_EVENTS) {
+ spin_lock_irqsave(&my_cq->spinlock, spl_flags);
+ ret = ipz_qeit_is_valid(&my_cq->ipz_queue);
+ spin_unlock_irqrestore(&my_cq->spinlock, spl_flags);
+ }
+
+ return ret;
}
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.h b/drivers/infiniband/hw/ehca/ipz_pt_fn.h
index 8199c45..57f141a 100644
--- a/drivers/infiniband/hw/ehca/ipz_pt_fn.h
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.h
@@ -140,6 +140,14 @@ static inline void *ipz_qeit_get_inc_valid(struct ipz_queue *queue)
return cqe;
}
+static inline int ipz_qeit_is_valid(struct ipz_queue *queue)
+{
+ struct ehca_cqe *cqe = ipz_qeit_get(queue);
+ u32 cqe_flags = cqe->cqe_flags;
+
+ return cqe_flags >> 7 == (queue->toggle_state & 1);
+}
+
/*
* returns and resets Queue Entry iterator
* returns address (kv) of first Queue Entry
diff --git a/drivers/infiniband/hw/ipath/ipath_cq.c b/drivers/infiniband/hw/ipath/ipath_cq.c
index ea78e6d..3e9241b 100644
--- a/drivers/infiniband/hw/ipath/ipath_cq.c
+++ b/drivers/infiniband/hw/ipath/ipath_cq.c
@@ -204,7 +204,7 @@ static void send_complete(unsigned long data)
*
* Called by ib_create_cq() in the generic verbs code.
*/
-struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
+struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vector,
struct ib_ucontext *context,
struct ib_udata *udata)
{
@@ -243,33 +243,21 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
* See ipath_mmap() for details.
*/
if (udata && udata->outlen >= sizeof(__u64)) {
- struct ipath_mmap_info *ip;
- __u64 offset = (__u64) wc;
int err;
+ u32 s = sizeof *wc + sizeof(struct ib_wc) * entries;
- err = ib_copy_to_udata(udata, &offset, sizeof(offset));
- if (err) {
- ret = ERR_PTR(err);
+ cq->ip = ipath_create_mmap_info(dev, s, context, wc);
+ if (!cq->ip) {
+ ret = ERR_PTR(-ENOMEM);
goto bail_wc;
}
- /* Allocate info for ipath_mmap(). */
- ip = kmalloc(sizeof(*ip), GFP_KERNEL);
- if (!ip) {
- ret = ERR_PTR(-ENOMEM);
- goto bail_wc;
+ err = ib_copy_to_udata(udata, &cq->ip->offset,
+ sizeof(cq->ip->offset));
+ if (err) {
+ ret = ERR_PTR(err);
+ goto bail_ip;
}
- cq->ip = ip;
- ip->context = context;
- ip->obj = wc;
- kref_init(&ip->ref);
- ip->mmap_cnt = 0;
- ip->size = PAGE_ALIGN(sizeof(*wc) +
- sizeof(struct ib_wc) * entries);
- spin_lock_irq(&dev->pending_lock);
- ip->next = dev->pending_mmaps;
- dev->pending_mmaps = ip;
- spin_unlock_irq(&dev->pending_lock);
} else
cq->ip = NULL;
@@ -277,12 +265,18 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
if (dev->n_cqs_allocated == ib_ipath_max_cqs) {
spin_unlock(&dev->n_cqs_lock);
ret = ERR_PTR(-ENOMEM);
- goto bail_wc;
+ goto bail_ip;
}
dev->n_cqs_allocated++;
spin_unlock(&dev->n_cqs_lock);
+ if (cq->ip) {
+ spin_lock_irq(&dev->pending_lock);
+ list_add(&cq->ip->pending_mmaps, &dev->pending_mmaps);
+ spin_unlock_irq(&dev->pending_lock);
+ }
+
/*
* ib_create_cq() will initialize cq->ibcq except for cq->ibcq.cqe.
* The number of entries should be >= the number requested or return
@@ -301,12 +295,12 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
goto done;
+bail_ip:
+ kfree(cq->ip);
bail_wc:
vfree(wc);
-
bail_cq:
kfree(cq);
-
done:
return ret;
}
@@ -340,17 +334,18 @@ int ipath_destroy_cq(struct ib_cq *ibcq)
/**
* ipath_req_notify_cq - change the notification type for a completion queue
* @ibcq: the completion queue
- * @notify: the type of notification to request
+ * @notify_flags: the type of notification to request
*
* Returns 0 for success.
*
* This may be called from interrupt context. Also called by
* ib_req_notify_cq() in the generic verbs code.
*/
-int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
+int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags)
{
struct ipath_cq *cq = to_icq(ibcq);
unsigned long flags;
+ int ret = 0;
spin_lock_irqsave(&cq->lock, flags);
/*
@@ -358,9 +353,15 @@ int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
* any other transitions (see C11-31 and C11-32 in ch. 11.4.2.2).
*/
if (cq->notify != IB_CQ_NEXT_COMP)
- cq->notify = notify;
+ cq->notify = notify_flags & IB_CQ_SOLICITED_MASK;
+
+ if ((notify_flags & IB_CQ_REPORT_MISSED_EVENTS) &&
+ cq->queue->head != cq->queue->tail)
+ ret = 1;
+
spin_unlock_irqrestore(&cq->lock, flags);
- return 0;
+
+ return ret;
}
/**
@@ -443,13 +444,12 @@ int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata)
if (cq->ip) {
struct ipath_ibdev *dev = to_idev(ibcq->device);
struct ipath_mmap_info *ip = cq->ip;
+ u32 s = sizeof *wc + sizeof(struct ib_wc) * cqe;
- ip->obj = wc;
- ip->size = PAGE_ALIGN(sizeof(*wc) +
- sizeof(struct ib_wc) * cqe);
+ ipath_update_mmap_info(dev, ip, s, wc);
spin_lock_irq(&dev->pending_lock);
- ip->next = dev->pending_mmaps;
- dev->pending_mmaps = ip;
+ if (list_empty(&ip->pending_mmaps))
+ list_add(&ip->pending_mmaps, &dev->pending_mmaps);
spin_unlock_irq(&dev->pending_lock);
}
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
index 036ed1e..ebd5c7b 100644
--- a/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -523,7 +523,7 @@ static int ipathfs_fill_super(struct super_block *sb, void *data,
int ret;
static struct tree_descr files[] = {
- [1] = {"atomic_stats", &atomic_stats_ops, S_IRUGO},
+ [2] = {"atomic_stats", &atomic_stats_ops, S_IRUGO},
{""},
};
diff --git a/drivers/infiniband/hw/ipath/ipath_mmap.c b/drivers/infiniband/hw/ipath/ipath_mmap.c
index a82157d..937bc33 100644
--- a/drivers/infiniband/hw/ipath/ipath_mmap.c
+++ b/drivers/infiniband/hw/ipath/ipath_mmap.c
@@ -46,6 +46,11 @@ void ipath_release_mmap_info(struct kref *ref)
{
struct ipath_mmap_info *ip =
container_of(ref, struct ipath_mmap_info, ref);
+ struct ipath_ibdev *dev = to_idev(ip->context->device);
+
+ spin_lock_irq(&dev->pending_lock);
+ list_del(&ip->pending_mmaps);
+ spin_unlock_irq(&dev->pending_lock);
vfree(ip->obj);
kfree(ip);
@@ -60,14 +65,12 @@ static void ipath_vma_open(struct vm_area_struct *vma)
struct ipath_mmap_info *ip = vma->vm_private_data;
kref_get(&ip->ref);
- ip->mmap_cnt++;
}
static void ipath_vma_close(struct vm_area_struct *vma)
{
struct ipath_mmap_info *ip = vma->vm_private_data;
- ip->mmap_cnt--;
kref_put(&ip->ref, ipath_release_mmap_info);
}
@@ -87,7 +90,7 @@ int ipath_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
struct ipath_ibdev *dev = to_idev(context->device);
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
unsigned long size = vma->vm_end - vma->vm_start;
- struct ipath_mmap_info *ip, **pp;
+ struct ipath_mmap_info *ip, *pp;
int ret = -EINVAL;
/*
@@ -96,15 +99,16 @@ int ipath_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
* CQ, QP, or SRQ is soon followed by a call to mmap().
*/
spin_lock_irq(&dev->pending_lock);
- for (pp = &dev->pending_mmaps; (ip = *pp); pp = &ip->next) {
+ list_for_each_entry_safe(ip, pp, &dev->pending_mmaps,
+ pending_mmaps) {
/* Only the creator is allowed to mmap the object */
- if (context != ip->context || (void *) offset != ip->obj)
+ if (context != ip->context || (__u64) offset != ip->offset)
continue;
/* Don't allow a mmap larger than the object. */
if (size > ip->size)
break;
- *pp = ip->next;
+ list_del_init(&ip->pending_mmaps);
spin_unlock_irq(&dev->pending_lock);
ret = remap_vmalloc_range(vma, ip->obj, 0);
@@ -119,3 +123,51 @@ int ipath_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
done:
return ret;
}
+
+/*
+ * Allocate information for ipath_mmap
+ */
+struct ipath_mmap_info *ipath_create_mmap_info(struct ipath_ibdev *dev,
+ u32 size,
+ struct ib_ucontext *context,
+ void *obj) {
+ struct ipath_mmap_info *ip;
+
+ ip = kmalloc(sizeof *ip, GFP_KERNEL);
+ if (!ip)
+ goto bail;
+
+ size = PAGE_ALIGN(size);
+
+ spin_lock_irq(&dev->mmap_offset_lock);
+ if (dev->mmap_offset == 0)
+ dev->mmap_offset = PAGE_SIZE;
+ ip->offset = dev->mmap_offset;
+ dev->mmap_offset += size;
+ spin_unlock_irq(&dev->mmap_offset_lock);
+
+ INIT_LIST_HEAD(&ip->pending_mmaps);
+ ip->size = size;
+ ip->context = context;
+ ip->obj = obj;
+ kref_init(&ip->ref);
+
+bail:
+ return ip;
+}
+
+void ipath_update_mmap_info(struct ipath_ibdev *dev,
+ struct ipath_mmap_info *ip,
+ u32 size, void *obj) {
+ size = PAGE_ALIGN(size);
+
+ spin_lock_irq(&dev->mmap_offset_lock);
+ if (dev->mmap_offset == 0)
+ dev->mmap_offset = PAGE_SIZE;
+ ip->offset = dev->mmap_offset;
+ dev->mmap_offset += size;
+ spin_unlock_irq(&dev->mmap_offset_lock);
+
+ ip->size = size;
+ ip->obj = obj;
+}
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
index 16db9ac..bfef08e 100644
--- a/drivers/infiniband/hw/ipath/ipath_qp.c
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c
@@ -844,34 +844,36 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
* See ipath_mmap() for details.
*/
if (udata && udata->outlen >= sizeof(__u64)) {
- struct ipath_mmap_info *ip;
- __u64 offset = (__u64) qp->r_rq.wq;
int err;
- err = ib_copy_to_udata(udata, &offset, sizeof(offset));
- if (err) {
- ret = ERR_PTR(err);
- goto bail_rwq;
- }
+ if (!qp->r_rq.wq) {
+ __u64 offset = 0;
- if (qp->r_rq.wq) {
- /* Allocate info for ipath_mmap(). */
- ip = kmalloc(sizeof(*ip), GFP_KERNEL);
- if (!ip) {
+ err = ib_copy_to_udata(udata, &offset,
+ sizeof(offset));
+ if (err) {
+ ret = ERR_PTR(err);
+ goto bail_rwq;
+ }
+ } else {
+ u32 s = sizeof(struct ipath_rwq) +
+ qp->r_rq.size * sz;
+
+ qp->ip =
+ ipath_create_mmap_info(dev, s,
+ ibpd->uobject->context,
+ qp->r_rq.wq);
+ if (!qp->ip) {
ret = ERR_PTR(-ENOMEM);
goto bail_rwq;
}
- qp->ip = ip;
- ip->context = ibpd->uobject->context;
- ip->obj = qp->r_rq.wq;
- kref_init(&ip->ref);
- ip->mmap_cnt = 0;
- ip->size = PAGE_ALIGN(sizeof(struct ipath_rwq) +
- qp->r_rq.size * sz);
- spin_lock_irq(&dev->pending_lock);
- ip->next = dev->pending_mmaps;
- dev->pending_mmaps = ip;
- spin_unlock_irq(&dev->pending_lock);
+
+ err = ib_copy_to_udata(udata, &(qp->ip->offset),
+ sizeof(qp->ip->offset));
+ if (err) {
+ ret = ERR_PTR(err);
+ goto bail_ip;
+ }
}
}
@@ -885,6 +887,12 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
dev->n_qps_allocated++;
spin_unlock(&dev->n_qps_lock);
+ if (qp->ip) {
+ spin_lock_irq(&dev->pending_lock);
+ list_add(&qp->ip->pending_mmaps, &dev->pending_mmaps);
+ spin_unlock_irq(&dev->pending_lock);
+ }
+
ret = &qp->ibqp;
goto bail;
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c
index b4b88d0..1915771 100644
--- a/drivers/infiniband/hw/ipath/ipath_rc.c
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c
@@ -98,13 +98,21 @@ static int ipath_make_rc_ack(struct ipath_qp *qp,
case OP(RDMA_READ_RESPONSE_LAST):
case OP(RDMA_READ_RESPONSE_ONLY):
case OP(ATOMIC_ACKNOWLEDGE):
- qp->s_ack_state = OP(ACKNOWLEDGE);
+ /*
+ * We can increment the tail pointer now that the last
+ * response has been sent instead of only being
+ * constructed.
+ */
+ if (++qp->s_tail_ack_queue > IPATH_MAX_RDMA_ATOMIC)
+ qp->s_tail_ack_queue = 0;
/* FALLTHROUGH */
+ case OP(SEND_ONLY):
case OP(ACKNOWLEDGE):
/* Check for no next entry in the queue. */
if (qp->r_head_ack_queue == qp->s_tail_ack_queue) {
if (qp->s_flags & IPATH_S_ACK_PENDING)
goto normal;
+ qp->s_ack_state = OP(ACKNOWLEDGE);
goto bail;
}
@@ -117,12 +125,8 @@ static int ipath_make_rc_ack(struct ipath_qp *qp,
if (len > pmtu) {
len = pmtu;
qp->s_ack_state = OP(RDMA_READ_RESPONSE_FIRST);
- } else {
+ } else
qp->s_ack_state = OP(RDMA_READ_RESPONSE_ONLY);
- if (++qp->s_tail_ack_queue >
- IPATH_MAX_RDMA_ATOMIC)
- qp->s_tail_ack_queue = 0;
- }
ohdr->u.aeth = ipath_compute_aeth(qp);
hwords++;
qp->s_ack_rdma_psn = e->psn;
@@ -139,8 +143,6 @@ static int ipath_make_rc_ack(struct ipath_qp *qp,
cpu_to_be32(e->atomic_data);
hwords += sizeof(ohdr->u.at) / sizeof(u32);
bth2 = e->psn;
- if (++qp->s_tail_ack_queue > IPATH_MAX_RDMA_ATOMIC)
- qp->s_tail_ack_queue = 0;
}
bth0 = qp->s_ack_state << 24;
break;
@@ -156,8 +158,6 @@ static int ipath_make_rc_ack(struct ipath_qp *qp,
ohdr->u.aeth = ipath_compute_aeth(qp);
hwords++;
qp->s_ack_state = OP(RDMA_READ_RESPONSE_LAST);
- if (++qp->s_tail_ack_queue > IPATH_MAX_RDMA_ATOMIC)
- qp->s_tail_ack_queue = 0;
}
bth0 = qp->s_ack_state << 24;
bth2 = qp->s_ack_rdma_psn++ & IPATH_PSN_MASK;
@@ -171,7 +171,7 @@ static int ipath_make_rc_ack(struct ipath_qp *qp,
* the ACK before setting s_ack_state to ACKNOWLEDGE
* (see above).
*/
- qp->s_ack_state = OP(ATOMIC_ACKNOWLEDGE);
+ qp->s_ack_state = OP(SEND_ONLY);
qp->s_flags &= ~IPATH_S_ACK_PENDING;
qp->s_cur_sge = NULL;
if (qp->s_nak_state)
@@ -223,23 +223,18 @@ int ipath_make_rc_req(struct ipath_qp *qp,
/* Sending responses has higher priority over sending requests. */
if ((qp->r_head_ack_queue != qp->s_tail_ack_queue ||
(qp->s_flags & IPATH_S_ACK_PENDING) ||
- qp->s_ack_state != IB_OPCODE_RC_ACKNOWLEDGE) &&
+ qp->s_ack_state != OP(ACKNOWLEDGE)) &&
ipath_make_rc_ack(qp, ohdr, pmtu, bth0p, bth2p))
goto done;
if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) ||
- qp->s_rnr_timeout)
+ qp->s_rnr_timeout || qp->s_wait_credit)
goto bail;
/* Limit the number of packets sent without an ACK. */
if (ipath_cmp24(qp->s_psn, qp->s_last_psn + IPATH_PSN_CREDIT) > 0) {
qp->s_wait_credit = 1;
dev->n_rc_stalls++;
- spin_lock(&dev->pending_lock);
- if (list_empty(&qp->timerwait))
- list_add_tail(&qp->timerwait,
- &dev->pending[dev->pending_index]);
- spin_unlock(&dev->pending_lock);
goto bail;
}
@@ -587,9 +582,12 @@ static void send_rc_ack(struct ipath_qp *qp)
u32 hwords;
struct ipath_ib_header hdr;
struct ipath_other_headers *ohdr;
+ unsigned long flags;
/* Don't send ACK or NAK if a RDMA read or atomic is pending. */
- if (qp->r_head_ack_queue != qp->s_tail_ack_queue)
+ if (qp->r_head_ack_queue != qp->s_tail_ack_queue ||
+ (qp->s_flags & IPATH_S_ACK_PENDING) ||
+ qp->s_ack_state != OP(ACKNOWLEDGE))
goto queue_ack;
/* Construct the header. */
@@ -640,11 +638,11 @@ static void send_rc_ack(struct ipath_qp *qp)
dev->n_rc_qacks++;
queue_ack:
- spin_lock_irq(&qp->s_lock);
+ spin_lock_irqsave(&qp->s_lock, flags);
qp->s_flags |= IPATH_S_ACK_PENDING;
qp->s_nak_state = qp->r_nak_state;
qp->s_ack_psn = qp->r_ack_psn;
- spin_unlock_irq(&qp->s_lock);
+ spin_unlock_irqrestore(&qp->s_lock, flags);
/* Call ipath_do_rc_send() in another thread. */
tasklet_hi_schedule(&qp->s_task);
@@ -1261,6 +1259,7 @@ ack_err:
wc.dlid_path_bits = 0;
wc.port_num = 0;
ipath_sqerror_qp(qp, &wc);
+ spin_unlock_irqrestore(&qp->s_lock, flags);
bail:
return;
}
@@ -1294,6 +1293,7 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev,
struct ipath_ack_entry *e;
u8 i, prev;
int old_req;
+ unsigned long flags;
if (diff > 0) {
/*
@@ -1327,7 +1327,7 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev,
psn &= IPATH_PSN_MASK;
e = NULL;
old_req = 1;
- spin_lock_irq(&qp->s_lock);
+ spin_lock_irqsave(&qp->s_lock, flags);
for (i = qp->r_head_ack_queue; ; i = prev) {
if (i == qp->s_tail_ack_queue)
old_req = 0;
@@ -1425,7 +1425,7 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev,
* after all the previous RDMA reads and atomics.
*/
if (i == qp->r_head_ack_queue) {
- spin_unlock_irq(&qp->s_lock);
+ spin_unlock_irqrestore(&qp->s_lock, flags);
qp->r_nak_state = 0;
qp->r_ack_psn = qp->r_psn - 1;
goto send_ack;
@@ -1439,11 +1439,10 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev,
break;
}
qp->r_nak_state = 0;
- spin_unlock_irq(&qp->s_lock);
tasklet_hi_schedule(&qp->s_task);
unlock_done:
- spin_unlock_irq(&qp->s_lock);
+ spin_unlock_irqrestore(&qp->s_lock, flags);
done:
return 1;
@@ -1453,10 +1452,12 @@ send_ack:
static void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err)
{
- spin_lock_irq(&qp->s_lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&qp->s_lock, flags);
qp->state = IB_QPS_ERR;
ipath_error_qp(qp, err);
- spin_unlock_irq(&qp->s_lock);
+ spin_unlock_irqrestore(&qp->s_lock, flags);
}
/**
diff --git a/drivers/infiniband/hw/ipath/ipath_srq.c b/drivers/infiniband/hw/ipath/ipath_srq.c
index 9403350..03acae6 100644
--- a/drivers/infiniband/hw/ipath/ipath_srq.c
+++ b/drivers/infiniband/hw/ipath/ipath_srq.c
@@ -139,33 +139,24 @@ struct ib_srq *ipath_create_srq(struct ib_pd *ibpd,
* See ipath_mmap() for details.
*/
if (udata && udata->outlen >= sizeof(__u64)) {
- struct ipath_mmap_info *ip;
- __u64 offset = (__u64) srq->rq.wq;
int err;
+ u32 s = sizeof(struct ipath_rwq) + srq->rq.size * sz;
- err = ib_copy_to_udata(udata, &offset, sizeof(offset));
- if (err) {
- ret = ERR_PTR(err);
+ srq->ip =
+ ipath_create_mmap_info(dev, s,
+ ibpd->uobject->context,
+ srq->rq.wq);
+ if (!srq->ip) {
+ ret = ERR_PTR(-ENOMEM);
goto bail_wq;
}
- /* Allocate info for ipath_mmap(). */
- ip = kmalloc(sizeof(*ip), GFP_KERNEL);
- if (!ip) {
- ret = ERR_PTR(-ENOMEM);
- goto bail_wq;
+ err = ib_copy_to_udata(udata, &srq->ip->offset,
+ sizeof(srq->ip->offset));
+ if (err) {
+ ret = ERR_PTR(err);
+ goto bail_ip;
}
- srq->ip = ip;
- ip->context = ibpd->uobject->context;
- ip->obj = srq->rq.wq;
- kref_init(&ip->ref);
- ip->mmap_cnt = 0;
- ip->size = PAGE_ALIGN(sizeof(struct ipath_rwq) +
- srq->rq.size * sz);
- spin_lock_irq(&dev->pending_lock);
- ip->next = dev->pending_mmaps;
- dev->pending_mmaps = ip;
- spin_unlock_irq(&dev->pending_lock);
} else
srq->ip = NULL;
@@ -181,21 +172,27 @@ struct ib_srq *ipath_create_srq(struct ib_pd *ibpd,
if (dev->n_srqs_allocated == ib_ipath_max_srqs) {
spin_unlock(&dev->n_srqs_lock);
ret = ERR_PTR(-ENOMEM);
- goto bail_wq;
+ goto bail_ip;
}
dev->n_srqs_allocated++;
spin_unlock(&dev->n_srqs_lock);
+ if (srq->ip) {
+ spin_lock_irq(&dev->pending_lock);
+ list_add(&srq->ip->pending_mmaps, &dev->pending_mmaps);
+ spin_unlock_irq(&dev->pending_lock);
+ }
+
ret = &srq->ibsrq;
goto done;
+bail_ip:
+ kfree(srq->ip);
bail_wq:
vfree(srq->rq.wq);
-
bail_srq:
kfree(srq);
-
done:
return ret;
}
@@ -312,13 +309,13 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
if (srq->ip) {
struct ipath_mmap_info *ip = srq->ip;
struct ipath_ibdev *dev = to_idev(srq->ibsrq.device);
+ u32 s = sizeof(struct ipath_rwq) + size * sz;
- ip->obj = wq;
- ip->size = PAGE_ALIGN(sizeof(struct ipath_rwq) +
- size * sz);
+ ipath_update_mmap_info(dev, ip, s, wq);
spin_lock_irq(&dev->pending_lock);
- ip->next = dev->pending_mmaps;
- dev->pending_mmaps = ip;
+ if (list_empty(&ip->pending_mmaps))
+ list_add(&ip->pending_mmaps,
+ &dev->pending_mmaps);
spin_unlock_irq(&dev->pending_lock);
}
} else if (attr_mask & IB_SRQ_LIMIT) {
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index 18c6df2..12933e7 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -1476,7 +1476,10 @@ int ipath_register_ib_device(struct ipath_devdata *dd)
ret = -ENOMEM;
goto err_lk;
}
+ INIT_LIST_HEAD(&idev->pending_mmaps);
spin_lock_init(&idev->pending_lock);
+ idev->mmap_offset = PAGE_SIZE;
+ spin_lock_init(&idev->mmap_offset_lock);
INIT_LIST_HEAD(&idev->pending[0]);
INIT_LIST_HEAD(&idev->pending[1]);
INIT_LIST_HEAD(&idev->pending[2]);
@@ -1558,6 +1561,7 @@ int ipath_register_ib_device(struct ipath_devdata *dd)
(1ull << IB_USER_VERBS_CMD_POST_SRQ_RECV);
dev->node_type = RDMA_NODE_IB_CA;
dev->phys_port_cnt = 1;
+ dev->num_comp_vectors = 1;
dev->dma_device = &dd->pcidev->dev;
dev->query_device = ipath_query_device;
dev->modify_device = ipath_modify_device;
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h
index 7c4929f..7064fc2 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.h
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.h
@@ -173,12 +173,12 @@ struct ipath_ah {
* this as its vm_private_data.
*/
struct ipath_mmap_info {
- struct ipath_mmap_info *next;
+ struct list_head pending_mmaps;
struct ib_ucontext *context;
void *obj;
+ __u64 offset;
struct kref ref;
unsigned size;
- unsigned mmap_cnt;
};
/*
@@ -422,7 +422,7 @@ struct ipath_qp {
#define IPATH_S_RDMAR_PENDING 0x04
#define IPATH_S_ACK_PENDING 0x08
-#define IPATH_PSN_CREDIT 2048
+#define IPATH_PSN_CREDIT 512
/*
* Since struct ipath_swqe is not a fixed size, we can't simply index into
@@ -485,9 +485,10 @@ struct ipath_opcode_stats {
struct ipath_ibdev {
struct ib_device ibdev;
- struct list_head dev_list;
struct ipath_devdata *dd;
- struct ipath_mmap_info *pending_mmaps;
+ struct list_head pending_mmaps;
+ spinlock_t mmap_offset_lock;
+ u32 mmap_offset;
int ib_unit; /* This is the device number */
u16 sm_lid; /* in host order */
u8 sm_sl;
@@ -734,13 +735,13 @@ int ipath_destroy_srq(struct ib_srq *ibsrq);
int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry);
-struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries,
+struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vector,
struct ib_ucontext *context,
struct ib_udata *udata);
int ipath_destroy_cq(struct ib_cq *ibcq);
-int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify notify);
+int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags);
int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata);
@@ -768,6 +769,15 @@ int ipath_dealloc_fmr(struct ib_fmr *ibfmr);
void ipath_release_mmap_info(struct kref *ref);
+struct ipath_mmap_info *ipath_create_mmap_info(struct ipath_ibdev *dev,
+ u32 size,
+ struct ib_ucontext *context,
+ void *obj);
+
+void ipath_update_mmap_info(struct ipath_ibdev *dev,
+ struct ipath_mmap_info *ip,
+ u32 size, void *obj);
+
int ipath_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev);
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index efd79ef..cf0868f 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -726,11 +726,12 @@ repoll:
return err == 0 || err == -EAGAIN ? npolled : err;
}
-int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify)
+int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags)
{
__be32 doorbell[2];
- doorbell[0] = cpu_to_be32((notify == IB_CQ_SOLICITED ?
+ doorbell[0] = cpu_to_be32(((flags & IB_CQ_SOLICITED_MASK) ==
+ IB_CQ_SOLICITED ?
MTHCA_TAVOR_CQ_DB_REQ_NOT_SOL :
MTHCA_TAVOR_CQ_DB_REQ_NOT) |
to_mcq(cq)->cqn);
@@ -743,7 +744,7 @@ int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify)
return 0;
}
-int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
+int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
{
struct mthca_cq *cq = to_mcq(ibcq);
__be32 doorbell[2];
@@ -755,7 +756,8 @@ int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
doorbell[0] = ci;
doorbell[1] = cpu_to_be32((cq->cqn << 8) | (2 << 5) | (sn << 3) |
- (notify == IB_CQ_SOLICITED ? 1 : 2));
+ ((flags & IB_CQ_SOLICITED_MASK) ==
+ IB_CQ_SOLICITED ? 1 : 2));
mthca_write_db_rec(doorbell, cq->arm_db);
@@ -766,7 +768,7 @@ int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)
wmb();
doorbell[0] = cpu_to_be32((sn << 28) |
- (notify == IB_CQ_SOLICITED ?
+ ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?
MTHCA_ARBEL_CQ_DB_REQ_NOT_SOL :
MTHCA_ARBEL_CQ_DB_REQ_NOT) |
cq->cqn);
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index b7e42ef..9bae3cc 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -495,8 +495,8 @@ void mthca_unmap_eq_icm(struct mthca_dev *dev);
int mthca_poll_cq(struct ib_cq *ibcq, int num_entries,
struct ib_wc *entry);
-int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify);
-int mthca_arbel_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify);
+int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
+int mthca_arbel_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
int mthca_init_cq(struct mthca_dev *dev, int nent,
struct mthca_ucontext *ctx, u32 pdn,
struct mthca_cq *cq);
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 47e6fd4..1c05486 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -663,6 +663,7 @@ static int mthca_destroy_qp(struct ib_qp *qp)
}
static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries,
+ int comp_vector,
struct ib_ucontext *context,
struct ib_udata *udata)
{
@@ -1292,6 +1293,7 @@ int mthca_register_device(struct mthca_dev *dev)
(1ull << IB_USER_VERBS_CMD_DETACH_MCAST);
dev->ib_dev.node_type = RDMA_NODE_IB_CA;
dev->ib_dev.phys_port_cnt = dev->limits.num_ports;
+ dev->ib_dev.num_comp_vectors = 1;
dev->ib_dev.dma_device = &dev->pdev->dev;
dev->ib_dev.query_device = mthca_query_device;
dev->ib_dev.query_port = mthca_query_port;
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 8fe6fee..fee60c8 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -701,6 +701,19 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH);
}
+ if (ibqp->qp_type == IB_QPT_RC &&
+ cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
+ u8 sched_queue = ibqp->uobject ? 0x2 : 0x1;
+
+ if (mthca_is_memfree(dev))
+ qp_context->rlkey_arbel_sched_queue |= sched_queue;
+ else
+ qp_context->tavor_sched_queue |= cpu_to_be32(sched_queue);
+
+ qp_param->opt_param_mask |=
+ cpu_to_be32(MTHCA_QP_OPTPAR_SCHED_QUEUE);
+ }
+
if (attr_mask & IB_QP_TIMEOUT) {
qp_context->pri_path.ackto = attr->timeout << 3;
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index d8f6bb4..87310ee 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -310,6 +310,7 @@ extern struct workqueue_struct *ipoib_workqueue;
/* functions */
+int ipoib_poll(struct net_device *dev, int *budget);
void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr);
struct ipoib_ah *ipoib_create_ah(struct net_device *dev,
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 0c4e59b..785bc85 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -370,7 +370,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
if (!likely(wr_id & IPOIB_CM_RX_UPDATE_MASK)) {
p = wc->qp->qp_context;
- if (time_after_eq(jiffies, p->jiffies + IPOIB_CM_RX_UPDATE_TIME)) {
+ if (p && time_after_eq(jiffies, p->jiffies + IPOIB_CM_RX_UPDATE_TIME)) {
spin_lock_irqsave(&priv->lock, flags);
p->jiffies = jiffies;
/* Move this entry to list head, but do
@@ -416,7 +416,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
skb->dev = dev;
/* XXX get correct PACKET_ type here */
skb->pkt_type = PACKET_HOST;
- netif_rx_ni(skb);
+ netif_receive_skb(skb);
repost:
if (unlikely(ipoib_cm_post_receive(dev, wr_id)))
@@ -592,7 +592,9 @@ int ipoib_cm_dev_open(struct net_device *dev)
priv->cm.id = ib_create_cm_id(priv->ca, ipoib_cm_rx_handler, dev);
if (IS_ERR(priv->cm.id)) {
printk(KERN_WARNING "%s: failed to create CM ID\n", priv->ca->name);
- return IS_ERR(priv->cm.id);
+ ret = PTR_ERR(priv->cm.id);
+ priv->cm.id = NULL;
+ return ret;
}
ret = ib_cm_listen(priv->cm.id, cpu_to_be64(IPOIB_CM_IETF_ID | priv->qp->qp_num),
@@ -601,6 +603,7 @@ int ipoib_cm_dev_open(struct net_device *dev)
printk(KERN_WARNING "%s: failed to listen on ID 0x%llx\n", priv->ca->name,
IPOIB_CM_IETF_ID | priv->qp->qp_num);
ib_destroy_cm_id(priv->cm.id);
+ priv->cm.id = NULL;
return ret;
}
return 0;
@@ -611,10 +614,11 @@ void ipoib_cm_dev_stop(struct net_device *dev)
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_cm_rx *p;
- if (!IPOIB_CM_SUPPORTED(dev->dev_addr))
+ if (!IPOIB_CM_SUPPORTED(dev->dev_addr) || !priv->cm.id)
return;
ib_destroy_cm_id(priv->cm.id);
+ priv->cm.id = NULL;
spin_lock_irq(&priv->lock);
while (!list_empty(&priv->cm.passive_ids)) {
p = list_entry(priv->cm.passive_ids.next, typeof(*p), list);
@@ -789,7 +793,7 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn,
}
p->cq = ib_create_cq(priv->ca, ipoib_cm_tx_completion, NULL, p,
- ipoib_sendq_size + 1);
+ ipoib_sendq_size + 1, 0);
if (IS_ERR(p->cq)) {
ret = PTR_ERR(p->cq);
ipoib_warn(priv, "failed to allocate tx cq: %d\n", ret);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 1bdb910..68d72c6 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -226,7 +226,7 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
skb->dev = dev;
/* XXX get correct PACKET_ type here */
skb->pkt_type = PACKET_HOST;
- netif_rx_ni(skb);
+ netif_receive_skb(skb);
} else {
ipoib_dbg_data(priv, "dropping loopback packet\n");
dev_kfree_skb_any(skb);
@@ -280,28 +280,63 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
wc->status, wr_id, wc->vendor_err);
}
-static void ipoib_ib_handle_wc(struct net_device *dev, struct ib_wc *wc)
+int ipoib_poll(struct net_device *dev, int *budget)
{
- if (wc->wr_id & IPOIB_CM_OP_SRQ)
- ipoib_cm_handle_rx_wc(dev, wc);
- else if (wc->wr_id & IPOIB_OP_RECV)
- ipoib_ib_handle_rx_wc(dev, wc);
- else
- ipoib_ib_handle_tx_wc(dev, wc);
+ struct ipoib_dev_priv *priv = netdev_priv(dev);
+ int max = min(*budget, dev->quota);
+ int done;
+ int t;
+ int empty;
+ int n, i;
+
+ done = 0;
+ empty = 0;
+
+ while (max) {
+ t = min(IPOIB_NUM_WC, max);
+ n = ib_poll_cq(priv->cq, t, priv->ibwc);
+
+ for (i = 0; i < n; ++i) {
+ struct ib_wc *wc = priv->ibwc + i;
+
+ if (wc->wr_id & IPOIB_CM_OP_SRQ) {
+ ++done;
+ --max;
+ ipoib_cm_handle_rx_wc(dev, wc);
+ } else if (wc->wr_id & IPOIB_OP_RECV) {
+ ++done;
+ --max;
+ ipoib_ib_handle_rx_wc(dev, wc);
+ } else
+ ipoib_ib_handle_tx_wc(dev, wc);
+ }
+
+ if (n != t) {
+ empty = 1;
+ break;
+ }
+ }
+
+ dev->quota -= done;
+ *budget -= done;
+
+ if (empty) {
+ netif_rx_complete(dev);
+ if (unlikely(ib_req_notify_cq(priv->cq,
+ IB_CQ_NEXT_COMP |
+ IB_CQ_REPORT_MISSED_EVENTS)) &&
+ netif_rx_reschedule(dev, 0))
+ return 1;
+
+ return 0;
+ }
+
+ return 1;
}
void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
{
- struct net_device *dev = (struct net_device *) dev_ptr;
- struct ipoib_dev_priv *priv = netdev_priv(dev);
- int n, i;
-
- ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
- do {
- n = ib_poll_cq(cq, IPOIB_NUM_WC, priv->ibwc);
- for (i = 0; i < n; ++i)
- ipoib_ib_handle_wc(dev, priv->ibwc + i);
- } while (n == IPOIB_NUM_WC);
+ netif_rx_schedule(dev_ptr);
}
static inline int post_send(struct ipoib_dev_priv *priv,
@@ -514,9 +549,10 @@ int ipoib_ib_dev_stop(struct net_device *dev)
struct ib_qp_attr qp_attr;
unsigned long begin;
struct ipoib_tx_buf *tx_req;
- int i;
+ int i, n;
clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
+ netif_poll_disable(dev);
ipoib_cm_dev_stop(dev);
@@ -568,6 +604,18 @@ int ipoib_ib_dev_stop(struct net_device *dev)
goto timeout;
}
+ do {
+ n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
+ for (i = 0; i < n; ++i) {
+ if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
+ ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
+ else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
+ ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
+ else
+ ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
+ }
+ } while (n == IPOIB_NUM_WC);
+
msleep(1);
}
@@ -596,6 +644,9 @@ timeout:
msleep(1);
}
+ netif_poll_enable(dev);
+ ib_req_notify_cq(priv->cq, IB_CQ_NEXT_COMP);
+
return 0;
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index b4c380c..0a428f2 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -948,6 +948,8 @@ static void ipoib_setup(struct net_device *dev)
dev->hard_header = ipoib_hard_header;
dev->set_multicast_list = ipoib_set_mcast_list;
dev->neigh_setup = ipoib_neigh_setup_dev;
+ dev->poll = ipoib_poll;
+ dev->weight = 100;
dev->watchdog_timeo = HZ;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
index 7f3ec20..5c3c6a4 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
@@ -187,7 +187,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca)
if (!ret)
size += ipoib_recvq_size;
- priv->cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev, size);
+ priv->cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev, size, 0);
if (IS_ERR(priv->cq)) {
printk(KERN_WARNING "%s: failed to create CQ\n", ca->name);
goto out_free_mr;
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 1fc9674..3702e23 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -35,7 +35,6 @@
#include <asm/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/version.h>
@@ -76,7 +75,7 @@ static int iser_create_device_ib_res(struct iser_device *device)
iser_cq_callback,
iser_cq_event_callback,
(void *)device,
- ISER_MAX_CQ_LEN);
+ ISER_MAX_CQ_LEN, 0);
if (IS_ERR(device->cq))
goto cq_err;
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 5e8ac57..39bf057 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -197,7 +197,7 @@ static int srp_create_target_ib(struct srp_target_port *target)
return -ENOMEM;
target->cq = ib_create_cq(target->srp_host->dev->dev, srp_completion,
- NULL, target, SRP_CQ_SIZE);
+ NULL, target, SRP_CQ_SIZE, 0);
if (IS_ERR(target->cq)) {
ret = PTR_ERR(target->cq);
goto out;
@@ -1468,6 +1468,25 @@ static ssize_t show_dgid(struct class_device *cdev, char *buf)
be16_to_cpu(((__be16 *) target->path.dgid.raw)[7]));
}
+static ssize_t show_orig_dgid(struct class_device *cdev, char *buf)
+{
+ struct srp_target_port *target = host_to_target(class_to_shost(cdev));
+
+ if (target->state == SRP_TARGET_DEAD ||
+ target->state == SRP_TARGET_REMOVED)
+ return -ENODEV;
+
+ return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+ be16_to_cpu(target->orig_dgid[0]),
+ be16_to_cpu(target->orig_dgid[1]),
+ be16_to_cpu(target->orig_dgid[2]),
+ be16_to_cpu(target->orig_dgid[3]),
+ be16_to_cpu(target->orig_dgid[4]),
+ be16_to_cpu(target->orig_dgid[5]),
+ be16_to_cpu(target->orig_dgid[6]),
+ be16_to_cpu(target->orig_dgid[7]));
+}
+
static ssize_t show_zero_req_lim(struct class_device *cdev, char *buf)
{
struct srp_target_port *target = host_to_target(class_to_shost(cdev));
@@ -1498,6 +1517,7 @@ static CLASS_DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL);
static CLASS_DEVICE_ATTR(service_id, S_IRUGO, show_service_id, NULL);
static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
static CLASS_DEVICE_ATTR(dgid, S_IRUGO, show_dgid, NULL);
+static CLASS_DEVICE_ATTR(orig_dgid, S_IRUGO, show_orig_dgid, NULL);
static CLASS_DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL);
static CLASS_DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL);
static CLASS_DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL);
@@ -1508,6 +1528,7 @@ static struct class_device_attribute *srp_host_attrs[] = {
&class_device_attr_service_id,
&class_device_attr_pkey,
&class_device_attr_dgid,
+ &class_device_attr_orig_dgid,
&class_device_attr_zero_req_lim,
&class_device_attr_local_ib_port,
&class_device_attr_local_ib_device,
@@ -1516,7 +1537,8 @@ static struct class_device_attribute *srp_host_attrs[] = {
static struct scsi_host_template srp_template = {
.module = THIS_MODULE,
- .name = DRV_NAME,
+ .name = "InfiniBand SRP initiator",
+ .proc_name = DRV_NAME,
.info = srp_target_info,
.queuecommand = srp_queuecommand,
.eh_abort_handler = srp_abort,
@@ -1662,6 +1684,7 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
target->path.dgid.raw[i] = simple_strtoul(dgid, NULL, 16);
}
kfree(p);
+ memcpy(target->orig_dgid, target->path.dgid.raw, 16);
break;
case SRP_OPT_PKEY:
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
index 2f3319c..1d53c7b 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -129,6 +129,7 @@ struct srp_target_port {
unsigned int scsi_id;
struct ib_sa_path_rec path;
+ __be16 orig_dgid[8];
struct ib_sa_query *path_query;
int path_query_id;
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 9623231..0e9b695 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -153,6 +153,8 @@ source "drivers/input/mouse/Kconfig"
source "drivers/input/joystick/Kconfig"
+source "drivers/input/tablet/Kconfig"
+
source "drivers/input/touchscreen/Kconfig"
source "drivers/input/misc/Kconfig"
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index b4cd106..8a2dd98 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_INPUT_EVBUG) += evbug.o
obj-$(CONFIG_INPUT_KEYBOARD) += keyboard/
obj-$(CONFIG_INPUT_MOUSE) += mouse/
obj-$(CONFIG_INPUT_JOYSTICK) += joystick/
+obj-$(CONFIG_INPUT_TABLET) += tablet/
obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
obj-$(CONFIG_INPUT_MISC) += misc/
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 1f6fcec..55a7259 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -18,7 +18,6 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/major.h>
-#include <linux/smp_lock.h>
#include <linux/device.h>
#include <linux/compat.h>
@@ -512,7 +511,7 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
- long *bits;
+ unsigned long *bits;
int len;
switch (_IOC_NR(cmd) & EV_MAX) {
@@ -557,7 +556,7 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
- int t = _IOC_NR(cmd) & ABS_MAX;
+ t = _IOC_NR(cmd) & ABS_MAX;
abs.value = dev->abs[t];
abs.minimum = dev->absmin[t];
@@ -577,7 +576,7 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
- int t = _IOC_NR(cmd) & ABS_MAX;
+ t = _IOC_NR(cmd) & ABS_MAX;
if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
return -EFAULT;
diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c
index 783b341..eebc724 100644
--- a/drivers/input/ff-core.c
+++ b/drivers/input/ff-core.c
@@ -281,7 +281,8 @@ int input_ff_event(struct input_dev *dev, unsigned int type,
break;
default:
- ff->playback(dev, code, value);
+ if (check_effect_access(ff, code, NULL) == 0)
+ ff->playback(dev, code, value);
break;
}
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 915e9ab..ccd8aba 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -11,7 +11,6 @@
*/
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/random.h>
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 9bcc542..06f0541 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -24,7 +24,6 @@
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/device.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
index 2712634..82f563e 100644
--- a/drivers/input/joystick/Kconfig
+++ b/drivers/input/joystick/Kconfig
@@ -2,7 +2,7 @@
# Joystick driver configuration
#
menuconfig INPUT_JOYSTICK
- bool "Joysticks"
+ bool "Joysticks/Gamepads"
help
If you have a joystick, 6dof controller, gamepad, steering wheel,
weapon control system or something like that you can say Y here
@@ -196,7 +196,7 @@ config JOYSTICK_TWIDJOY
config JOYSTICK_DB9
tristate "Multisystem, Sega Genesis, Saturn joysticks and gamepads"
depends on PARPORT
- ---help---
+ help
Say Y here if you have a Sega Master System gamepad, Sega Genesis
gamepad, Sega Saturn gamepad, or a Multisystem -- Atari, Amiga,
Commodore, Amstrad CPC joystick connected to your parallel port.
@@ -253,4 +253,18 @@ config JOYSTICK_JOYDUMP
To compile this driver as a module, choose M here: the
module will be called joydump.
+config JOYSTICK_XPAD
+ tristate "X-Box gamepad support"
+ select USB
+ help
+ Say Y here if you want to use the X-Box pad with your computer.
+ Make sure to say Y to "Joystick support" (CONFIG_INPUT_JOYDEV)
+ and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well.
+
+ For information about how to connect the X-Box pad to USB, see
+ <file:Documentation/input/xpad.txt>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called xpad.
+
endif
diff --git a/drivers/input/joystick/Makefile b/drivers/input/joystick/Makefile
index 5231f6f..e855abb 100644
--- a/drivers/input/joystick/Makefile
+++ b/drivers/input/joystick/Makefile
@@ -26,5 +26,6 @@ obj-$(CONFIG_JOYSTICK_TMDC) += tmdc.o
obj-$(CONFIG_JOYSTICK_TURBOGRAFX) += turbografx.o
obj-$(CONFIG_JOYSTICK_TWIDJOY) += twidjoy.o
obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o
+obj-$(CONFIG_JOYSTICK_XPAD) += xpad.o
obj-$(CONFIG_JOYSTICK_IFORCE) += iforce/
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index 1c1afb5..bdd157c 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -53,7 +53,7 @@ MODULE_LICENSE("GPL");
#define ANALOG_PORTS 16
static char *js[ANALOG_PORTS];
-static int js_nargs;
+static unsigned int js_nargs;
static int analog_options[ANALOG_PORTS];
module_param_array_named(map, js, charp, &js_nargs, 0);
MODULE_PARM_DESC(map, "Describes analog joysticks type/capabilities");
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
index c27593b..86ad102 100644
--- a/drivers/input/joystick/db9.c
+++ b/drivers/input/joystick/db9.c
@@ -46,17 +46,17 @@ MODULE_LICENSE("GPL");
struct db9_config {
int args[2];
- int nargs;
+ unsigned int nargs;
};
#define DB9_MAX_PORTS 3
-static struct db9_config db9[DB9_MAX_PORTS] __initdata;
+static struct db9_config db9_cfg[DB9_MAX_PORTS] __initdata;
-module_param_array_named(dev, db9[0].args, int, &db9[0].nargs, 0);
+module_param_array_named(dev, db9_cfg[0].args, int, &db9_cfg[0].nargs, 0);
MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
-module_param_array_named(dev2, db9[1].args, int, &db9[0].nargs, 0);
+module_param_array_named(dev2, db9_cfg[1].args, int, &db9_cfg[0].nargs, 0);
MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
-module_param_array_named(dev3, db9[2].args, int, &db9[2].nargs, 0);
+module_param_array_named(dev3, db9_cfg[2].args, int, &db9_cfg[2].nargs, 0);
MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)");
#define DB9_ARG_PARPORT 0
@@ -680,17 +680,17 @@ static int __init db9_init(void)
int err = 0;
for (i = 0; i < DB9_MAX_PORTS; i++) {
- if (db9[i].nargs == 0 || db9[i].args[DB9_ARG_PARPORT] < 0)
+ if (db9_cfg[i].nargs == 0 || db9_cfg[i].args[DB9_ARG_PARPORT] < 0)
continue;
- if (db9[i].nargs < 2) {
+ if (db9_cfg[i].nargs < 2) {
printk(KERN_ERR "db9.c: Device type must be specified.\n");
err = -EINVAL;
break;
}
- db9_base[i] = db9_probe(db9[i].args[DB9_ARG_PARPORT],
- db9[i].args[DB9_ARG_MODE]);
+ db9_base[i] = db9_probe(db9_cfg[i].args[DB9_ARG_PARPORT],
+ db9_cfg[i].args[DB9_ARG_MODE]);
if (IS_ERR(db9_base[i])) {
err = PTR_ERR(db9_base[i]);
break;
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
index c71b58f..1a452e0 100644
--- a/drivers/input/joystick/gamecon.c
+++ b/drivers/input/joystick/gamecon.c
@@ -48,16 +48,16 @@ MODULE_LICENSE("GPL");
struct gc_config {
int args[GC_MAX_DEVICES + 1];
- int nargs;
+ unsigned int nargs;
};
-static struct gc_config gc[GC_MAX_PORTS] __initdata;
+static struct gc_config gc_cfg[GC_MAX_PORTS] __initdata;
-module_param_array_named(map, gc[0].args, int, &gc[0].nargs, 0);
+module_param_array_named(map, gc_cfg[0].args, int, &gc_cfg[0].nargs, 0);
MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<pad1>,<pad2>,..<pad5>)");
-module_param_array_named(map2, gc[1].args, int, &gc[1].nargs, 0);
+module_param_array_named(map2, gc_cfg[1].args, int, &gc_cfg[1].nargs, 0);
MODULE_PARM_DESC(map2, "Describes second set of devices");
-module_param_array_named(map3, gc[2].args, int, &gc[2].nargs, 0);
+module_param_array_named(map3, gc_cfg[2].args, int, &gc_cfg[2].nargs, 0);
MODULE_PARM_DESC(map3, "Describes third set of devices");
/* see also gs_psx_delay parameter in PSX support section */
@@ -810,16 +810,17 @@ static int __init gc_init(void)
int err = 0;
for (i = 0; i < GC_MAX_PORTS; i++) {
- if (gc[i].nargs == 0 || gc[i].args[0] < 0)
+ if (gc_cfg[i].nargs == 0 || gc_cfg[i].args[0] < 0)
continue;
- if (gc[i].nargs < 2) {
+ if (gc_cfg[i].nargs < 2) {
printk(KERN_ERR "gamecon.c: at least one device must be specified\n");
err = -EINVAL;
break;
}
- gc_base[i] = gc_probe(gc[i].args[0], gc[i].args + 1, gc[i].nargs - 1);
+ gc_base[i] = gc_probe(gc_cfg[i].args[0],
+ gc_cfg[i].args + 1, gc_cfg[i].nargs - 1);
if (IS_ERR(gc_base[i])) {
err = PTR_ERR(gc_base[i]);
break;
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index dadcf4f..40a853a 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -124,7 +124,7 @@ struct iforce {
/* Buffer used for asynchronous sending of bytes to the device */
struct circ_buf xmit;
unsigned char xmit_data[XMIT_SIZE];
- long xmit_flags[1];
+ unsigned long xmit_flags[1];
/* Force Feedback */
wait_queue_head_t wait;
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
index 0f2c608..8381c6f 100644
--- a/drivers/input/joystick/turbografx.c
+++ b/drivers/input/joystick/turbografx.c
@@ -48,16 +48,16 @@ MODULE_LICENSE("GPL");
struct tgfx_config {
int args[TGFX_MAX_DEVICES + 1];
- int nargs;
+ unsigned int nargs;
};
-static struct tgfx_config tgfx[TGFX_MAX_PORTS] __initdata;
+static struct tgfx_config tgfx_cfg[TGFX_MAX_PORTS] __initdata;
-module_param_array_named(map, tgfx[0].args, int, &tgfx[0].nargs, 0);
+module_param_array_named(map, tgfx_cfg[0].args, int, &tgfx_cfg[0].nargs, 0);
MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>");
-module_param_array_named(map2, tgfx[1].args, int, &tgfx[1].nargs, 0);
+module_param_array_named(map2, tgfx_cfg[1].args, int, &tgfx_cfg[1].nargs, 0);
MODULE_PARM_DESC(map2, "Describes second set of devices");
-module_param_array_named(map3, tgfx[2].args, int, &tgfx[2].nargs, 0);
+module_param_array_named(map3, tgfx_cfg[2].args, int, &tgfx_cfg[2].nargs, 0);
MODULE_PARM_DESC(map3, "Describes third set of devices");
#define TGFX_REFRESH_TIME HZ/100 /* 10 ms */
@@ -283,16 +283,18 @@ static int __init tgfx_init(void)
int err = 0;
for (i = 0; i < TGFX_MAX_PORTS; i++) {
- if (tgfx[i].nargs == 0 || tgfx[i].args[0] < 0)
+ if (tgfx_cfg[i].nargs == 0 || tgfx_cfg[i].args[0] < 0)
continue;
- if (tgfx[i].nargs < 2) {
+ if (tgfx_cfg[i].nargs < 2) {
printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n");
err = -EINVAL;
break;
}
- tgfx_base[i] = tgfx_probe(tgfx[i].args[0], tgfx[i].args + 1, tgfx[i].nargs - 1);
+ tgfx_base[i] = tgfx_probe(tgfx_cfg[i].args[0],
+ tgfx_cfg[i].args + 1,
+ tgfx_cfg[i].nargs - 1);
if (IS_ERR(tgfx_base[i])) {
err = PTR_ERR(tgfx_base[i]);
break;
diff --git a/drivers/usb/input/xpad.c b/drivers/input/joystick/xpad.c
index 7357239..8c8cd95 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -74,7 +74,6 @@
#include <linux/stat.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/smp_lock.h>
#include <linux/usb/input.h>
#define DRIVER_VERSION "v0.0.6"
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 9f42e4d..bd707b8 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -226,6 +226,7 @@ config KEYBOARD_PXA27x
config KEYBOARD_AAED2000
tristate "AAED-2000 keyboard"
depends on MACH_AAED2000
+ select INPUT_POLLDEV
default y
help
Say Y here to enable the keyboard on the Agilent AAED-2000
diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c
index 3a37505..63d6ead 100644
--- a/drivers/input/keyboard/aaed2000_kbd.c
+++ b/drivers/input/keyboard/aaed2000_kbd.c
@@ -14,12 +14,11 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/init.h>
-#include <linux/input.h>
+#include <linux/input-polldev.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/workqueue.h>
#include <asm/arch/hardware.h>
#include <asm/arch/aaed2000.h>
@@ -46,8 +45,7 @@ static unsigned char aaedkbd_keycode[NR_SCANCODES] = {
struct aaedkbd {
unsigned char keycode[ARRAY_SIZE(aaedkbd_keycode)];
- struct input_dev *input;
- struct work_struct workq;
+ struct input_polled_dev *poll_dev;
int kbdscan_state[KB_COLS];
int kbdscan_count[KB_COLS];
};
@@ -64,14 +62,15 @@ static void aaedkbd_report_col(struct aaedkbd *aaedkbd,
scancode = SCANCODE(row, col);
pressed = rowd & KB_ROWMASK(row);
- input_report_key(aaedkbd->input, aaedkbd->keycode[scancode], pressed);
+ input_report_key(aaedkbd->poll_dev->input,
+ aaedkbd->keycode[scancode], pressed);
}
}
/* Scan the hardware keyboard and push any changes up through the input layer */
-static void aaedkbd_work(void *data)
+static void aaedkbd_poll(struct input_polled_dev *dev)
{
- struct aaedkbd *aaedkbd = data;
+ struct aaedkbd *aaedkbd = dev->private;
unsigned int col, rowd;
col = 0;
@@ -90,51 +89,34 @@ static void aaedkbd_work(void *data)
} while (col < KB_COLS);
AAEC_GPIO_KSCAN = 0x07;
- input_sync(aaedkbd->input);
-
- schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL));
-}
-
-static int aaedkbd_open(struct input_dev *indev)
-{
- struct aaedkbd *aaedkbd = input_get_drvdata(indev);
-
- schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL));
-
- return 0;
-}
-
-static void aaedkbd_close(struct input_dev *indev)
-{
- struct aaedkbd *aaedkbd = input_get_drvdata(indev);
-
- cancel_delayed_work(&aaedkbd->workq);
- flush_scheduled_work();
+ input_sync(dev->input);
}
static int __devinit aaedkbd_probe(struct platform_device *pdev)
{
struct aaedkbd *aaedkbd;
+ struct input_polled_dev *poll_dev;
struct input_dev *input_dev;
int i;
int error;
aaedkbd = kzalloc(sizeof(struct aaedkbd), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!aaedkbd || !input_dev) {
+ poll_dev = input_allocate_polled_device();
+ if (!aaedkbd || !poll_dev) {
error = -ENOMEM;
goto fail;
}
platform_set_drvdata(pdev, aaedkbd);
- aaedkbd->input = input_dev;
-
- /* Init keyboard rescan workqueue */
- INIT_WORK(&aaedkbd->workq, aaedkbd_work, aaedkbd);
-
+ aaedkbd->poll_dev = poll_dev;
memcpy(aaedkbd->keycode, aaedkbd_keycode, sizeof(aaedkbd->keycode));
+ poll_dev->private = aaedkbd;
+ poll_dev->poll = aaedkbd_poll;
+ poll_dev->poll_interval = SCAN_INTERVAL;
+
+ input_dev = poll_dev->input;
input_dev->name = "AAED-2000 Keyboard";
input_dev->phys = "aaedkbd/input0";
input_dev->id.bustype = BUS_HOST;
@@ -143,8 +125,6 @@ static int __devinit aaedkbd_probe(struct platform_device *pdev)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &pdev->dev;
- input_set_drvdata(input_dev, aaedkbd);
-
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
input_dev->keycode = aaedkbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
@@ -154,17 +134,14 @@ static int __devinit aaedkbd_probe(struct platform_device *pdev)
set_bit(aaedkbd->keycode[i], input_dev->keybit);
clear_bit(0, input_dev->keybit);
- input_dev->open = aaedkbd_open;
- input_dev->close = aaedkbd_close;
-
- error = input_register_device(aaedkbd->input);
+ error = input_register_polled_device(aaedkbd->poll_dev);
if (error)
goto fail;
return 0;
fail: kfree(aaedkbd);
- input_free_device(input_dev);
+ input_free_polled_device(poll_dev);
return error;
}
@@ -172,7 +149,8 @@ static int __devexit aaedkbd_remove(struct platform_device *pdev)
{
struct aaedkbd *aaedkbd = platform_get_drvdata(pdev);
- input_unregister_device(aaedkbd->input);
+ input_unregister_polled_device(aaedkbd->poll_dev);
+ input_free_polled_device(aaedkbd->poll_dev);
kfree(aaedkbd);
return 0;
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 1d0d3e7..6013ace 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -40,6 +40,18 @@ config INPUT_M68K_BEEP
tristate "M68k Beeper support"
depends on M68K
+config INPUT_IXP4XX_BEEPER
+ tristate "IXP4XX Beeper support"
+ depends on ARCH_IXP4XX
+ help
+ If you say yes here, you can connect a beeper to the
+ ixp4xx gpio pins. This is used by the LinkSys NSLU2.
+
+ If unsure, say Y.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ixp4xx-beeper.
+
config INPUT_COBALT_BTNS
tristate "Cobalt button interface"
depends on MIPS_COBALT
@@ -70,17 +82,79 @@ config INPUT_ATLAS_BTNS
To compile this driver as a module, choose M here: the module will
be called atlas_btns.
-config INPUT_IXP4XX_BEEPER
- tristate "IXP4XX Beeper support"
- depends on ARCH_IXP4XX
+config INPUT_ATI_REMOTE
+ tristate "ATI / X10 USB RF remote control"
+ select USB
help
- If you say yes here, you can connect a beeper to the
- ixp4xx gpio pins. This is used by the LinkSys NSLU2.
+ Say Y here if you want to use an ATI or X10 "Lola" USB remote control.
+ These are RF remotes with USB receivers.
+ The ATI remote comes with many of ATI's All-In-Wonder video cards.
+ The X10 "Lola" remote is available at:
+ <http://www.x10.com/products/lola_sg1.htm>
+ This driver provides mouse pointer, left and right mouse buttons,
+ and maps all the other remote buttons to keypress events.
+
+ To compile this driver as a module, choose M here: the module will be
+ called ati_remote.
+
+config INPUT_ATI_REMOTE2
+ tristate "ATI / Philips USB RF remote control"
+ select USB
+ help
+ Say Y here if you want to use an ATI or Philips USB RF remote control.
+ These are RF remotes with USB receivers.
+ ATI Remote Wonder II comes with some ATI's All-In-Wonder video cards
+ and is also available as a separate product.
+ This driver provides mouse pointer, left and right mouse buttons,
+ and maps all the other remote buttons to keypress events.
+
+ To compile this driver as a module, choose M here: the module will be
+ called ati_remote2.
+
+config INPUT_KEYSPAN_REMOTE
+ tristate "Keyspan DMR USB remote control (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ select USB
+ help
+ Say Y here if you want to use a Keyspan DMR USB remote control.
+ Currently only the UIA-11 type of receiver has been tested. The tag
+ on the receiver that connects to the USB port should have a P/N that
+ will tell you what type of DMR you have. The UIA-10 type is not
+ supported at this time. This driver maps all buttons to keypress
+ events.
- If unsure, say Y.
+ To compile this driver as a module, choose M here: the module will
+ be called keyspan_remote.
+
+config INPUT_POWERMATE
+ tristate "Griffin PowerMate and Contour Jog support"
+ select USB
+ help
+ Say Y here if you want to use Griffin PowerMate or Contour Jog devices.
+ These are aluminum dials which can measure clockwise and anticlockwise
+ rotation. The dial also acts as a pushbutton. The base contains an LED
+ which can be instructed to pulse or to switch to a particular intensity.
+
+ You can download userspace tools from
+ <http://sowerbutts.com/powermate/>.
To compile this driver as a module, choose M here: the
- module will be called ixp4xx-beeper.
+ module will be called powermate.
+
+config INPUT_YEALINK
+ tristate "Yealink usb-p1k voip phone"
+ depends EXPERIMENTAL
+ select USB
+ help
+ Say Y here if you want to enable keyboard and LCD functions of the
+ Yealink usb-p1k usb phones. The audio part is enabled by the generic
+ usb sound driver, so you might want to enable that as well.
+
+ For information about how to use these additional functions, see
+ <file:Documentation/input/yealink.txt>.
+
+ To compile this driver as a module, choose M here: the module will be
+ called yealink.
config INPUT_UINPUT
tristate "User level driver support"
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 21e3cca..8b2f779 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -8,9 +8,14 @@ obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o
obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o
obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
-obj-$(CONFIG_INPUT_UINPUT) += uinput.o
+obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o
obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
+obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o
+obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
+obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
+obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
+obj-$(CONFIG_INPUT_YEALINK) += yealink.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
-obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
+obj-$(CONFIG_INPUT_UINPUT) += uinput.o
diff --git a/drivers/usb/input/ati_remote.c b/drivers/input/misc/ati_remote.c
index 471aab2..471aab2 100644
--- a/drivers/usb/input/ati_remote.c
+++ b/drivers/input/misc/ati_remote.c
diff --git a/drivers/usb/input/ati_remote2.c b/drivers/input/misc/ati_remote2.c
index a9032aa..1031543 100644
--- a/drivers/usb/input/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -405,9 +405,7 @@ static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2)
for (i = 0; i < 2; i++) {
usb_free_urb(ar2->urb[i]);
-
- if (ar2->buf[i])
- usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]);
+ usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]);
}
}
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c
index 1bffc9f..1bffc9f 100644
--- a/drivers/usb/input/keyspan_remote.c
+++ b/drivers/input/misc/keyspan_remote.c
diff --git a/drivers/usb/input/map_to_7segment.h b/drivers/input/misc/map_to_7segment.h
index a424094..a424094 100644
--- a/drivers/usb/input/map_to_7segment.h
+++ b/drivers/input/misc/map_to_7segment.h
diff --git a/drivers/usb/input/powermate.c b/drivers/input/misc/powermate.c
index 4f93a76..448a470 100644
--- a/drivers/usb/input/powermate.c
+++ b/drivers/input/misc/powermate.c
@@ -291,12 +291,10 @@ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_dev
static void powermate_free_buffers(struct usb_device *udev, struct powermate_device *pm)
{
- if (pm->data)
- usb_buffer_free(udev, POWERMATE_PAYLOAD_SIZE_MAX,
- pm->data, pm->data_dma);
- if (pm->configcr)
- usb_buffer_free(udev, sizeof(*(pm->configcr)),
- pm->configcr, pm->configcr_dma);
+ usb_buffer_free(udev, POWERMATE_PAYLOAD_SIZE_MAX,
+ pm->data, pm->data_dma);
+ usb_buffer_free(udev, sizeof(*(pm->configcr)),
+ pm->configcr, pm->configcr_dma);
}
/* Called whenever a USB device matching one in our supported devices table is connected */
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 031467e..a56ad4b 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -33,7 +33,6 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/input.h>
#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
diff --git a/drivers/usb/input/yealink.c b/drivers/input/misc/yealink.c
index c54f1a5..ab15880 100644
--- a/drivers/usb/input/yealink.c
+++ b/drivers/input/misc/yealink.c
@@ -29,7 +29,7 @@
* This driver is based on:
* - the usbb2k-api http://savannah.nongnu.org/projects/usbb2k-api/
* - information from http://memeteau.free.fr/usbb2k
- * - the xpad-driver drivers/usb/input/xpad.c
+ * - the xpad-driver drivers/input/joystick/xpad.c
*
* Thanks to:
* - Olivier Vandorpe, for providing the usbb2k-api.
@@ -818,18 +818,17 @@ static int usb_cleanup(struct yealink_dev *yld, int err)
else
input_unregister_device(yld->idev);
}
- if (yld->ctl_req)
- usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)),
- yld->ctl_req, yld->ctl_req_dma);
- if (yld->ctl_data)
- usb_buffer_free(yld->udev, USB_PKT_LEN,
- yld->ctl_data, yld->ctl_dma);
- if (yld->irq_data)
- usb_buffer_free(yld->udev, USB_PKT_LEN,
- yld->irq_data, yld->irq_dma);
-
- usb_free_urb(yld->urb_irq); /* parameter validation in core/urb */
- usb_free_urb(yld->urb_ctl); /* parameter validation in core/urb */
+
+ usb_free_urb(yld->urb_irq);
+ usb_free_urb(yld->urb_ctl);
+
+ usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)),
+ yld->ctl_req, yld->ctl_req_dma);
+ usb_buffer_free(yld->udev, USB_PKT_LEN,
+ yld->ctl_data, yld->ctl_dma);
+ usb_buffer_free(yld->udev, USB_PKT_LEN,
+ yld->irq_data, yld->irq_dma);
+
kfree(yld);
return err;
}
diff --git a/drivers/usb/input/yealink.h b/drivers/input/misc/yealink.h
index 48af0be..48af0be 100644
--- a/drivers/usb/input/yealink.h
+++ b/drivers/input/misc/yealink.h
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 81dd8c7..2ccc114 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -2,7 +2,7 @@
# Mouse driver configuration
#
menuconfig INPUT_MOUSE
- bool "Mouse"
+ bool "Mice"
default y
help
Say Y here, and a list of supported mice will be displayed.
@@ -19,7 +19,7 @@ config MOUSE_PS2
select SERIO_LIBPS2
select SERIO_I8042 if X86_PC
select SERIO_GSCPS2 if GSC
- ---help---
+ help
Say Y here if you have a PS/2 mouse connected to your system. This
includes the standard 2 or 3-button PS/2 mouse, as well as PS/2
mice with wheels and extra buttons, Microsoft, Logitech or Genius
@@ -41,7 +41,7 @@ config MOUSE_PS2_ALPS
bool "ALPS PS/2 mouse protocol extension" if EMBEDDED
default y
depends on MOUSE_PS2
- ---help---
+ help
Say Y here if you have an ALPS PS/2 touchpad connected to
your system.
@@ -51,7 +51,7 @@ config MOUSE_PS2_LOGIPS2PP
bool "Logictech PS/2++ mouse protocol extension" if EMBEDDED
default y
depends on MOUSE_PS2
- ---help---
+ help
Say Y here if you have a Logictech PS/2++ mouse connected to
your system.
@@ -61,7 +61,7 @@ config MOUSE_PS2_SYNAPTICS
bool "Synaptics PS/2 mouse protocol extension" if EMBEDDED
default y
depends on MOUSE_PS2
- ---help---
+ help
Say Y here if you have a Synaptics PS/2 TouchPad connected to
your system.
@@ -71,7 +71,7 @@ config MOUSE_PS2_LIFEBOOK
bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED
default y
depends on MOUSE_PS2
- ---help---
+ help
Say Y here if you have a Fujitsu B-series Lifebook PS/2
TouchScreen connected to your system.
@@ -81,7 +81,7 @@ config MOUSE_PS2_TRACKPOINT
bool "IBM Trackpoint PS/2 mouse protocol extension" if EMBEDDED
default y
depends on MOUSE_PS2
- ---help---
+ help
Say Y here if you have an IBM Trackpoint PS/2 mouse connected
to your system.
@@ -90,7 +90,7 @@ config MOUSE_PS2_TRACKPOINT
config MOUSE_PS2_TOUCHKIT
bool "eGalax TouchKit PS/2 protocol extension"
depends on MOUSE_PS2
- ---help---
+ help
Say Y here if you have an eGalax TouchKit PS/2 touchscreen
connected to your system.
@@ -99,7 +99,7 @@ config MOUSE_PS2_TOUCHKIT
config MOUSE_SERIAL
tristate "Serial mouse"
select SERIO
- ---help---
+ help
Say Y here if you have a serial (RS-232, COM port) mouse connected
to your system. This includes Sun, MouseSystems, Microsoft,
Logitech and all other compatible serial mice.
@@ -109,6 +109,26 @@ config MOUSE_SERIAL
To compile this driver as a module, choose M here: the
module will be called sermouse.
+config MOUSE_APPLETOUCH
+ tristate "Apple USB Touchpad support"
+ select USB
+ help
+ Say Y here if you want to use an Apple USB Touchpad.
+
+ These are the touchpads that can be found on post-February 2005
+ Apple Powerbooks (prior models have a Synaptics touchpad connected
+ to the ADB bus).
+
+ This driver provides a basic mouse driver but can be interfaced
+ with the synaptics X11 driver to provide acceleration and
+ scrolling in X11.
+
+ For further information, see
+ <file:Documentation/input/appletouch.txt>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called appletouch.
+
config MOUSE_INPORT
tristate "InPort/MS/ATIXL busmouse"
depends on ISA
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index 6a8f622..aa4ba87 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -5,6 +5,7 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o
+obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o
obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o
obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o
obj-$(CONFIG_MOUSE_INPORT) += inport.o
diff --git a/drivers/usb/input/appletouch.c b/drivers/input/mouse/appletouch.c
index e321526..e321526 100644
--- a/drivers/usb/input/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index c77788b..666ad3a 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -185,7 +185,7 @@ static int synaptics_query_hardware(struct psmouse *psmouse)
int retries = 0;
while ((retries++ < 3) && psmouse_reset(psmouse))
- printk(KERN_ERR "synaptics reset failed\n");
+ /* empty */;
if (synaptics_identify(psmouse))
return -1;
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 7678e98..8675f95 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -19,7 +19,6 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/input.h>
-#include <linux/smp_lock.h>
#include <linux/random.h>
#include <linux/major.h>
#include <linux/device.h>
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 7c17377..3888dc3 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -526,6 +526,33 @@ static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+/*
+ * i8042_toggle_aux - enables or disables AUX port on i8042 via command and
+ * verifies success by readinng CTR. Used when testing for presence of AUX
+ * port.
+ */
+static int __devinit i8042_toggle_aux(int on)
+{
+ unsigned char param;
+ int i;
+
+ if (i8042_command(&param,
+ on ? I8042_CMD_AUX_ENABLE : I8042_CMD_AUX_DISABLE))
+ return -1;
+
+ /* some chips need some time to set the I8042_CTR_AUXDIS bit */
+ for (i = 0; i < 100; i++) {
+ udelay(50);
+
+ if (i8042_command(&param, I8042_CMD_CTL_RCTR))
+ return -1;
+
+ if (!(param & I8042_CTR_AUXDIS) == on)
+ return 0;
+ }
+
+ return -1;
+}
/*
* i8042_check_aux() applies as much paranoia as it can at detecting
@@ -580,16 +607,12 @@ static int __devinit i8042_check_aux(void)
* Bit assignment test - filters out PS/2 i8042's in AT mode
*/
- if (i8042_command(&param, I8042_CMD_AUX_DISABLE))
- return -1;
- if (i8042_command(&param, I8042_CMD_CTL_RCTR) || (~param & I8042_CTR_AUXDIS)) {
+ if (i8042_toggle_aux(0)) {
printk(KERN_WARNING "Failed to disable AUX port, but continuing anyway... Is this a SiS?\n");
printk(KERN_WARNING "If AUX port is really absent please use the 'i8042.noaux' option.\n");
}
- if (i8042_command(&param, I8042_CMD_AUX_ENABLE))
- return -1;
- if (i8042_command(&param, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS))
+ if (i8042_toggle_aux(1))
return -1;
/*
diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig
new file mode 100644
index 0000000..12dfb0e
--- /dev/null
+++ b/drivers/input/tablet/Kconfig
@@ -0,0 +1,74 @@
+#
+# Tablet driver configuration
+#
+menuconfig INPUT_TABLET
+ bool "Tablets"
+ help
+ Say Y here, and a list of supported tablets will be displayed.
+ This option doesn't affect the kernel.
+
+ If unsure, say Y.
+
+if INPUT_TABLET
+
+config TABLET_USB_ACECAD
+ tristate "Acecad Flair tablet support (USB)"
+ select USB
+ help
+ Say Y here if you want to use the USB version of the Acecad Flair
+ tablet. Make sure to say Y to "Mouse support"
+ (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+ (CONFIG_INPUT_EVDEV) as well.
+
+ To compile this driver as a module, choose M here: the
+ module will be called acecad.
+
+config TABLET_USB_AIPTEK
+ tristate "Aiptek 6000U/8000U tablet support (USB)"
+ select USB
+ help
+ Say Y here if you want to use the USB version of the Aiptek 6000U
+ or Aiptek 8000U tablet. Make sure to say Y to "Mouse support"
+ (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+ (CONFIG_INPUT_EVDEV) as well.
+
+ To compile this driver as a module, choose M here: the
+ module will be called aiptek.
+
+config TABLET_USB_GTCO
+ tristate "GTCO CalComp/InterWrite USB Support"
+ depends on USB && INPUT
+ help
+ Say Y here if you want to use the USB version of the GTCO
+ CalComp/InterWrite Tablet. Make sure to say Y to "Mouse support"
+ (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+ (CONFIG_INPUT_EVDEV) as well.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gtco.
+
+config TABLET_USB_KBTAB
+ tristate "KB Gear JamStudio tablet support (USB)"
+ select USB
+ help
+ Say Y here if you want to use the USB version of the KB Gear
+ JamStudio tablet. Make sure to say Y to "Mouse support"
+ (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+ (CONFIG_INPUT_EVDEV) as well.
+
+ To compile this driver as a module, choose M here: the
+ module will be called kbtab.
+
+config TABLET_USB_WACOM
+ tristate "Wacom Intuos/Graphire tablet support (USB)"
+ select USB
+ help
+ Say Y here if you want to use the USB version of the Wacom Intuos
+ or Graphire tablet. Make sure to say Y to "Mouse support"
+ (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+ (CONFIG_INPUT_EVDEV) as well.
+
+ To compile this driver as a module, choose M here: the
+ module will be called wacom.
+
+endif
diff --git a/drivers/input/tablet/Makefile b/drivers/input/tablet/Makefile
new file mode 100644
index 0000000..ce8b9a9
--- /dev/null
+++ b/drivers/input/tablet/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the tablet drivers
+#
+
+# Multipart objects.
+wacom-objs := wacom_wac.o wacom_sys.o
+
+obj-$(CONFIG_TABLET_USB_ACECAD) += acecad.o
+obj-$(CONFIG_TABLET_USB_AIPTEK) += aiptek.o
+obj-$(CONFIG_TABLET_USB_GTCO) += gtco.o
+obj-$(CONFIG_TABLET_USB_KBTAB) += kbtab.o
+obj-$(CONFIG_TABLET_USB_WACOM) += wacom.o
diff --git a/drivers/usb/input/acecad.c b/drivers/input/tablet/acecad.c
index be8e924..dd231045 100644
--- a/drivers/usb/input/acecad.c
+++ b/drivers/input/tablet/acecad.c
@@ -54,7 +54,7 @@ struct usb_acecad {
struct input_dev *input;
struct urb *irq;
- signed char *data;
+ unsigned char *data;
dma_addr_t data_dma;
};
diff --git a/drivers/usb/input/aiptek.c b/drivers/input/tablet/aiptek.c
index cc0a498..cc0a498 100644
--- a/drivers/usb/input/aiptek.c
+++ b/drivers/input/tablet/aiptek.c
diff --git a/drivers/usb/input/gtco.c b/drivers/input/tablet/gtco.c
index b2ca10f2f..b2ca10f2f 100644
--- a/drivers/usb/input/gtco.c
+++ b/drivers/input/tablet/gtco.c
diff --git a/drivers/usb/input/kbtab.c b/drivers/input/tablet/kbtab.c
index c4781b9..91e6d00 100644
--- a/drivers/usb/input/kbtab.c
+++ b/drivers/input/tablet/kbtab.c
@@ -29,7 +29,7 @@ module_param(kb_pressure_click, int, 0);
MODULE_PARM_DESC(kb_pressure_click, "pressure threshold for clicks");
struct kbtab {
- signed char *data;
+ unsigned char *data;
dma_addr_t data_dma;
struct input_dev *dev;
struct usb_device *usbdev;
diff --git a/drivers/usb/input/wacom.h b/drivers/input/tablet/wacom.h
index d85abfc..ef01a80 100644
--- a/drivers/usb/input/wacom.h
+++ b/drivers/input/tablet/wacom.h
@@ -1,5 +1,5 @@
/*
- * drivers/usb/input/wacom.h
+ * drivers/input/tablet/wacom.h
*
* USB Wacom Graphire and Wacom Intuos tablet support
*
diff --git a/drivers/usb/input/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 1fe4820..83bddef 100644
--- a/drivers/usb/input/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -1,5 +1,5 @@
/*
- * drivers/usb/input/wacom_sys.c
+ * drivers/input/tablet/wacom_sys.c
*
* USB Wacom Graphire and Wacom Intuos tablet support - system specific code
*/
diff --git a/drivers/usb/input/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 4f3e9bc..7661f03 100644
--- a/drivers/usb/input/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -1,5 +1,5 @@
/*
- * drivers/usb/input/wacom_wac.c
+ * drivers/input/tablet/wacom_wac.c
*
* USB Wacom Graphire and Wacom Intuos tablet support - Wacom specific code
*
diff --git a/drivers/usb/input/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index a230222..a5e12e8 100644
--- a/drivers/usb/input/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -1,5 +1,5 @@
/*
- * drivers/usb/input/wacom_wac.h
+ * drivers/input/tablet/wacom_wac.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,7 +39,7 @@ struct wacom_features {
};
struct wacom_wac {
- signed char *data;
+ unsigned char *data;
int tool[2];
int id[2];
__u32 serial[2];
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 9716180..5e640ae 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -1,5 +1,5 @@
#
-# Mouse driver configuration
+# Touchscreen driver configuration
#
menuconfig INPUT_TOUCHSCREEN
bool "Touchscreens"
@@ -44,9 +44,9 @@ config TOUCHSCREEN_BITSY
config TOUCHSCREEN_CORGI
tristate "SharpSL (Corgi and Spitz series) touchscreen driver"
depends on PXA_SHARPSL
- default y
+ default y
help
- Say Y here to enable the driver for the touchscreen on the
+ Say Y here to enable the driver for the touchscreen on the
Sharp SL-C7xx and SL-Cxx00 series of PDAs.
If unsure, say N.
@@ -164,4 +164,58 @@ config TOUCHSCREEN_UCB1400
To compile this driver as a module, choose M here: the
module will be called ucb1400_ts.
+config TOUCHSCREEN_USB_COMPOSITE
+ tristate "USB Touchscreen Driver"
+ select USB
+ help
+ USB Touchscreen driver for:
+ - eGalax Touchkit USB (also includes eTurboTouch CT-410/510/700)
+ - PanJit TouchSet USB
+ - 3M MicroTouch USB (EX II series)
+ - ITM
+ - some other eTurboTouch
+ - Gunze AHL61
+ - DMC TSC-10/25
+
+ Have a look at <http://linux.chapter7.ch/touchkit/> for
+ a usage description and the required user-space stuff.
+
+ To compile this driver as a module, choose M here: the
+ module will be called usbtouchscreen.
+
+config TOUCHSCREEN_USB_EGALAX
+ default y
+ bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_PANJIT
+ default y
+ bool "PanJit device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_3M
+ default y
+ bool "3M/Microtouch EX II series device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_ITM
+ default y
+ bool "ITM device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_ETURBO
+ default y
+ bool "eTurboTouch (non-eGalax compatible) device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_GUNZE
+ default y
+ bool "Gunze AHL61 device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_DMC_TSC10
+ default y
+ bool "DMC TSC-10/25 device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 30e6e22..2f86d6a 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -1,17 +1,18 @@
#
-# Makefile for the mouse drivers.
+# Makefile for the touchscreen drivers.
#
# Each configuration option enables a list of files.
obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
-obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
-obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
-obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
-obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
-obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
-obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
-obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
+obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
+obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
+obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
+obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
+obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
+obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
+obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
+obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o
obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c
index 2490874..61c1502 100644
--- a/drivers/input/touchscreen/hp680_ts_input.c
+++ b/drivers/input/touchscreen/hp680_ts_input.c
@@ -21,7 +21,7 @@
static void do_softint(void *data);
static struct input_dev *hp680_ts_dev;
-static DECLARE_WORK(work, do_softint, 0);
+static DECLARE_WORK(work, do_softint);
static void do_softint(void *data)
{
diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index e082941..8e18e6c 100644
--- a/drivers/usb/input/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -668,9 +668,8 @@ static void usbtouch_close(struct input_dev *input)
static void usbtouch_free_buffers(struct usb_device *udev,
struct usbtouch_usb *usbtouch)
{
- if (usbtouch->data)
- usb_buffer_free(udev, usbtouch->type->rept_size,
- usbtouch->data, usbtouch->data_dma);
+ usb_buffer_free(udev, usbtouch->type->rept_size,
+ usbtouch->data, usbtouch->data_dma);
kfree(usbtouch->buffer);
}
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
index 5e5b5c9..8238b13 100644
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -48,7 +48,6 @@
#include <linux/init.h>
#include <linux/input.h>
#include <linux/major.h>
-#include <linux/smp_lock.h>
#include <linux/random.h>
#include <linux/time.h>
#include <linux/device.h>
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index db1260f..81661b8 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -18,8 +18,8 @@
#include <linux/fcntl.h>
#include <linux/fs.h>
#include <linux/signal.h>
+#include <linux/mutex.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/wait.h>
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -147,7 +147,7 @@ struct capidev {
struct capincci *nccis;
- struct semaphore ncci_list_sem;
+ struct mutex ncci_list_mtx;
};
/* -------- global variables ---------------------------------------- */
@@ -395,7 +395,7 @@ static struct capidev *capidev_alloc(void)
if (!cdev)
return NULL;
- init_MUTEX(&cdev->ncci_list_sem);
+ mutex_init(&cdev->ncci_list_mtx);
skb_queue_head_init(&cdev->recvqueue);
init_waitqueue_head(&cdev->recvwait);
write_lock_irqsave(&capidev_list_lock, flags);
@@ -414,9 +414,9 @@ static void capidev_free(struct capidev *cdev)
}
skb_queue_purge(&cdev->recvqueue);
- down(&cdev->ncci_list_sem);
+ mutex_lock(&cdev->ncci_list_mtx);
capincci_free(cdev, 0xffffffff);
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
write_lock_irqsave(&capidev_list_lock, flags);
list_del(&cdev->list);
@@ -603,15 +603,15 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) {
u16 info = CAPIMSG_U16(skb->data, 12); // Info field
if (info == 0) {
- down(&cdev->ncci_list_sem);
+ mutex_lock(&cdev->ncci_list_mtx);
capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
}
}
if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND) {
- down(&cdev->ncci_list_sem);
+ mutex_lock(&cdev->ncci_list_mtx);
capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
}
spin_lock_irqsave(&workaround_lock, flags);
if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) {
@@ -752,9 +752,9 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
- down(&cdev->ncci_list_sem);
+ mutex_lock(&cdev->ncci_list_mtx);
capincci_free(cdev, CAPIMSG_NCCI(skb->data));
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
}
cdev->errcode = capi20_put_message(&cdev->ap, skb);
@@ -939,9 +939,9 @@ capi_ioctl(struct inode *inode, struct file *file,
if (copy_from_user(&ncci, argp, sizeof(ncci)))
return -EFAULT;
- down(&cdev->ncci_list_sem);
+ mutex_lock(&cdev->ncci_list_mtx);
if ((nccip = capincci_find(cdev, (u32) ncci)) == 0) {
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
return 0;
}
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -949,7 +949,7 @@ capi_ioctl(struct inode *inode, struct file *file,
count += atomic_read(&mp->ttyopencount);
}
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
return count;
}
return 0;
@@ -964,14 +964,14 @@ capi_ioctl(struct inode *inode, struct file *file,
if (copy_from_user(&ncci, argp,
sizeof(ncci)))
return -EFAULT;
- down(&cdev->ncci_list_sem);
+ mutex_lock(&cdev->ncci_list_mtx);
nccip = capincci_find(cdev, (u32) ncci);
if (!nccip || (mp = nccip->minorp) == 0) {
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
return -ESRCH;
}
unit = mp->minor;
- up(&cdev->ncci_list_sem);
+ mutex_unlock(&cdev->ncci_list_mtx);
return unit;
}
return 0;
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c
index ad1e270..22379b9 100644
--- a/drivers/isdn/capi/capiutil.c
+++ b/drivers/isdn/capi/capiutil.c
@@ -855,7 +855,7 @@ static _cdebbuf *g_debbuf;
static u_long g_debbuf_lock;
static _cmsg *g_cmsg;
-_cdebbuf *cdebbuf_alloc(void)
+static _cdebbuf *cdebbuf_alloc(void)
{
_cdebbuf *cdb;
@@ -989,11 +989,6 @@ _cdebbuf *capi_cmsg2str(_cmsg * cmsg)
return &g_debbuf;
}
-_cdebbuf *cdebbuf_alloc(void)
-{
- return &g_debbuf;
-}
-
void cdebbuf_free(_cdebbuf *cdb)
{
}
@@ -1009,7 +1004,6 @@ void __exit cdebug_exit(void)
#endif
-EXPORT_SYMBOL(cdebbuf_alloc);
EXPORT_SYMBOL(cdebbuf_free);
EXPORT_SYMBOL(capi_cmsg2message);
EXPORT_SYMBOL(capi_message2cmsg);
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 53a1890..be77ee6 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
#else
diff --git a/drivers/isdn/hardware/eicon/capimain.c b/drivers/isdn/hardware/eicon/capimain.c
index 7a74ed3..98fcdfc 100644
--- a/drivers/isdn/hardware/eicon/capimain.c
+++ b/drivers/isdn/hardware/eicon/capimain.c
@@ -13,7 +13,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <asm/uaccess.h>
-#include <linux/smp_lock.h>
#include <linux/skbuff.h>
#include "os_capi.h"
diff --git a/drivers/isdn/hardware/eicon/dbgioctl.h b/drivers/isdn/hardware/eicon/dbgioctl.h
deleted file mode 100644
index 0fb6f5e..0000000
--- a/drivers/isdn/hardware/eicon/dbgioctl.h
+++ /dev/null
@@ -1,198 +0,0 @@
-
-/*
- *
- Copyright (c) Eicon Technology Corporation, 2000.
- *
- This source file is supplied for the use with Eicon
- Technology Corporation's range of DIVA Server Adapters.
- *
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
- *
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
- *
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-/*------------------------------------------------------------------*/
-/* file: dbgioctl.h */
-/*------------------------------------------------------------------*/
-
-#if !defined(__DBGIOCTL_H__)
-
-#define __DBGIOCTL_H__
-
-#ifdef NOT_YET_NEEDED
-/*
- * The requested operation is passed in arg0 of DbgIoctlArgs,
- * additional arguments (if any) in arg1, arg2 and arg3.
- */
-
-typedef struct
-{ ULONG arg0 ;
- ULONG arg1 ;
- ULONG arg2 ;
- ULONG arg3 ;
-} DbgIoctlArgs ;
-
-#define DBG_COPY_LOGS 0 /* copy debugs to user until buffer full */
- /* arg1: size threshold */
- /* arg2: timeout in milliseconds */
-
-#define DBG_FLUSH_LOGS 1 /* flush pending debugs to user buffer */
- /* arg1: internal driver id */
-
-#define DBG_LIST_DRVS 2 /* return the list of registered drivers */
-
-#define DBG_GET_MASK 3 /* get current debug mask of driver */
- /* arg1: internal driver id */
-
-#define DBG_SET_MASK 4 /* set/change debug mask of driver */
- /* arg1: internal driver id */
- /* arg2: new debug mask */
-
-#define DBG_GET_BUFSIZE 5 /* get current buffer size of driver */
- /* arg1: internal driver id */
- /* arg2: new debug mask */
-
-#define DBG_SET_BUFSIZE 6 /* set new buffer size of driver */
- /* arg1: new buffer size */
-
-/*
- * common internal debug message structure
- */
-
-typedef struct
-{ unsigned short id ; /* virtual driver id */
- unsigned short type ; /* special message type */
- unsigned long seq ; /* sequence number of message */
- unsigned long size ; /* size of message in bytes */
- unsigned long next ; /* offset to next buffered message */
- LARGE_INTEGER NTtime ; /* 100 ns since 1.1.1601 */
- unsigned char data[4] ;/* message data */
-} OldDbgMessage ;
-
-typedef struct
-{ LARGE_INTEGER NTtime ; /* 100 ns since 1.1.1601 */
- unsigned short size ; /* size of message in bytes */
- unsigned short ffff ; /* always 0xffff to indicate new msg */
- unsigned short id ; /* virtual driver id */
- unsigned short type ; /* special message type */
- unsigned long seq ; /* sequence number of message */
- unsigned char data[4] ;/* message data */
-} DbgMessage ;
-
-#endif
-
-#define DRV_ID_UNKNOWN 0x0C /* for messages via prtComp() */
-
-#define MSG_PROC_FLAG 0x80
-#define MSG_PROC_NO_GET(x) (((x) & MSG_PROC_FLAG) ? (((x) >> 4) & 7) : -1)
-#define MSG_PROC_NO_SET(x) (MSG_PROC_FLAG | (((x) & 7) << 4))
-
-#define MSG_TYPE_DRV_ID 0x0001
-#define MSG_TYPE_FLAGS 0x0002
-#define MSG_TYPE_STRING 0x0003
-#define MSG_TYPE_BINARY 0x0004
-
-#define MSG_HEAD_SIZE ((unsigned long)&(((DbgMessage *)0)->data[0]))
-#define MSG_ALIGN(len) (((unsigned long)(len) + MSG_HEAD_SIZE + 3) & ~3)
-#define MSG_SIZE(pMsg) MSG_ALIGN((pMsg)->size)
-#define MSG_NEXT(pMsg) ((DbgMessage *)( ((char *)(pMsg)) + MSG_SIZE(pMsg) ))
-
-#define OLD_MSG_HEAD_SIZE ((unsigned long)&(((OldDbgMessage *)0)->data[0]))
-#define OLD_MSG_ALIGN(len) (((unsigned long)(len)+OLD_MSG_HEAD_SIZE+3) & ~3)
-
-/*
- * manifest constants
- */
-
-#define MSG_FRAME_MAX_SIZE 2150 /* maximum size of B1 frame */
-#define MSG_TEXT_MAX_SIZE 1024 /* maximum size of msg text */
-#define MSG_MAX_SIZE MSG_ALIGN(MSG_FRAME_MAX_SIZE)
-#define DBG_MIN_BUFFER_SIZE 0x00008000 /* minimal total buffer size 32 KB */
-#define DBG_DEF_BUFFER_SIZE 0x00020000 /* default total buffer size 128 KB */
-#define DBG_MAX_BUFFER_SIZE 0x00400000 /* maximal total buffer size 4 MB */
-
-#define DBGDRV_NAME "Diehl_DIMAINT"
-#define UNIDBG_DRIVER L"\\Device\\Diehl_DIMAINT" /* UNICODE name for kernel */
-#define DEBUG_DRIVER "\\\\.\\" DBGDRV_NAME /* traditional string for apps */
-#define DBGVXD_NAME "DIMAINT"
-#define DEBUG_VXD "\\\\.\\" DBGVXD_NAME /* traditional string for apps */
-
-/*
- * Special IDI interface debug construction
- */
-
-#define DBG_IDI_SIG_REQ (unsigned long)0xF479C402
-#define DBG_IDI_SIG_IND (unsigned long)0xF479C403
-#define DBG_IDI_NL_REQ (unsigned long)0xF479C404
-#define DBG_IDI_NL_IND (unsigned long)0xF479C405
-
-typedef struct
-{ unsigned long magic_type ;
- unsigned short data_len ;
- unsigned char layer_ID ;
- unsigned char entity_ID ;
- unsigned char request ;
- unsigned char ret_code ;
- unsigned char indication ;
- unsigned char complete ;
- unsigned char data[4] ;
-} DbgIdiAct, *DbgIdiAction ;
-
-/*
- * We want to use the same IOCTL codes in Win95 and WinNT.
- * The official constructor for IOCTL codes is the CTL_CODE macro
- * from <winoctl.h> (<devioctl.h> in WinNT DDK environment).
- * The problem here is that we don't know how to get <winioctl.h>
- * working in a Win95 DDK environment!
- */
-
-# ifdef CTL_CODE /*{*/
-
-/* Assert that we have the same idea of the CTL_CODE macro. */
-
-#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
- ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
-)
-
-# else /* !CTL_CODE */ /*}{*/
-
-/* Use the definitions stolen from <winioctl.h>. */
-
-#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
- ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
-)
-
-#define METHOD_BUFFERED 0
-#define METHOD_IN_DIRECT 1
-#define METHOD_OUT_DIRECT 2
-#define METHOD_NEITHER 3
-
-#define FILE_ANY_ACCESS 0
-#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe
-#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe
-
-# endif /* CTL_CODE */ /*}*/
-
-/*
- * Now we can define WinNT/Win95 DeviceIoControl codes.
- *
- * These codes are defined in di_defs.h too, a possible mismatch will be
- * detected when the dbgtool is compiled.
- */
-
-#define IOCTL_DRIVER_LNK \
- CTL_CODE(0x8001U,0x701,METHOD_OUT_DIRECT,FILE_ANY_ACCESS)
-#define IOCTL_DRIVER_DBG \
- CTL_CODE(0x8001U,0x702,METHOD_OUT_DIRECT,FILE_ANY_ACCESS)
-
-#endif /* __DBGIOCTL_H__ */
diff --git a/drivers/isdn/hardware/eicon/divamnt.c b/drivers/isdn/hardware/eicon/divamnt.c
index 4aba5c5..c909289 100644
--- a/drivers/isdn/hardware/eicon/divamnt.c
+++ b/drivers/isdn/hardware/eicon/divamnt.c
@@ -13,7 +13,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/poll.h>
#include <asm/uaccess.h>
diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c
index 556b196..78f141e 100644
--- a/drivers/isdn/hardware/eicon/divasi.c
+++ b/drivers/isdn/hardware/eicon/divasi.c
@@ -14,7 +14,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
index 5e862e2..6d39f93 100644
--- a/drivers/isdn/hardware/eicon/divasmain.c
+++ b/drivers/isdn/hardware/eicon/divasmain.c
@@ -17,7 +17,6 @@
#include <linux/ioport.h>
#include <linux/workqueue.h>
#include <linux/pci.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/poll.h>
diff --git a/drivers/isdn/hardware/eicon/main_if.h b/drivers/isdn/hardware/eicon/main_if.h
deleted file mode 100644
index 0ea339a..0000000
--- a/drivers/isdn/hardware/eicon/main_if.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *
- Copyright (c) Eicon Technology Corporation, 2000.
- *
- This source file is supplied for the use with Eicon
- Technology Corporation's range of DIVA Server Adapters.
- *
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
- *
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
- *
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-/*------------------------------------------------------------------*/
-/* file: main_if.h */
-/*------------------------------------------------------------------*/
-# ifndef MAIN_IF___H
-# define MAIN_IF___H
-
-# include "debug_if.h"
-
-void DI_lock (void) ;
-void DI_unlock (void) ;
-
-#ifdef NOT_YET_NEEDED
-void DI_nttime (LARGE_INTEGER *NTtime) ;
-void DI_ntlcltime(LARGE_INTEGER *NTtime, LARGE_INTEGER *lclNTtime) ;
-void DI_nttimefields(LARGE_INTEGER *NTtime, TIME_FIELDS *TimeFields);
-unsigned long DI_wintime(LARGE_INTEGER *NTtime) ;
-
-unsigned short DiInsertProcessorNumber (int type) ;
-void DiProcessEventLog (unsigned short id, unsigned long msgID, va_list ap);
-
-void StartIoctlTimer (void (*Handler)(void), unsigned long msec) ;
-void StopIoctlTimer (void) ;
-void UnpendIoctl (DbgRequest *pDbgReq) ;
-#endif
-
-void add_to_q(int, char* , unsigned int);
-# endif /* MAIN_IF___H */
-
diff --git a/drivers/isdn/hardware/eicon/platform.h b/drivers/isdn/hardware/eicon/platform.h
index ff09f07..15d4942 100644
--- a/drivers/isdn/hardware/eicon/platform.h
+++ b/drivers/isdn/hardware/eicon/platform.h
@@ -26,7 +26,6 @@
#include <linux/vmalloc.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <asm/types.h>
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index 9f44d3e..99e70d4 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -37,7 +37,6 @@
#include <linux/kernel_stat.h>
#include <linux/usb.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include "hisax.h"
#include "hisax_if.h"
#include "hfc_usb.h"
diff --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c
index 84dccd5..6cdbad3 100644
--- a/drivers/isdn/hysdn/boardergo.c
+++ b/drivers/isdn/hysdn/boardergo.c
@@ -443,7 +443,7 @@ ergo_inithardware(hysdn_card * card)
card->waitpofready = ergo_waitpofready;
card->set_errlog_state = ergo_set_errlog_state;
INIT_WORK(&card->irq_queue, ergo_irq_bh);
- card->hysdn_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&card->hysdn_lock);
return (0);
} /* ergo_inithardware */
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 4c7deda..27b3991 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -297,8 +297,6 @@ hysdn_log_close(struct inode *ino, struct file *filep)
struct procdata *pd;
hysdn_card *card;
int retval = 0;
- unsigned long flags;
- spinlock_t hysdn_lock = SPIN_LOCK_UNLOCKED;
lock_kernel();
if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
@@ -308,7 +306,6 @@ hysdn_log_close(struct inode *ino, struct file *filep)
/* read access -> log/debug read, mark one further file as closed */
pd = NULL;
- spin_lock_irqsave(&hysdn_lock, flags);
inf = *((struct log_data **) filep->private_data); /* get first log entry */
if (inf)
pd = (struct procdata *) inf->proc_ctrl; /* still entries there */
@@ -331,7 +328,6 @@ hysdn_log_close(struct inode *ino, struct file *filep)
inf->usage_cnt--; /* decrement usage count for buffers */
inf = inf->next;
}
- spin_unlock_irqrestore(&hysdn_lock, flags);
if (pd)
if (pd->if_used <= 0) /* delete buffers if last file closed */
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index e93ad59..bb92e3c 100644
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -1462,7 +1462,7 @@ isdnloop_initcard(char *id)
skb_queue_head_init(&card->bqueue[i]);
}
skb_queue_head_init(&card->dqueue);
- card->isdnloop_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock_init(&card->isdnloop_lock);
card->next = cards;
cards = card;
if (!register_isdn(&card->interface)) {
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 0d122bf..41634fd 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -51,16 +51,19 @@
#define UNMAPPED_GVA (~(gpa_t)0)
#define KVM_MAX_VCPUS 1
+#define KVM_ALIAS_SLOTS 4
#define KVM_MEMORY_SLOTS 4
#define KVM_NUM_MMU_PAGES 256
#define KVM_MIN_FREE_MMU_PAGES 5
#define KVM_REFILL_PAGES 25
+#define KVM_MAX_CPUID_ENTRIES 40
#define FX_IMAGE_SIZE 512
#define FX_IMAGE_ALIGN 16
#define FX_BUF_SIZE (2 * FX_IMAGE_SIZE + FX_IMAGE_ALIGN)
#define DE_VECTOR 0
+#define NM_VECTOR 7
#define DF_VECTOR 8
#define TS_VECTOR 10
#define NP_VECTOR 11
@@ -73,6 +76,8 @@
#define IOPL_SHIFT 12
+#define KVM_PIO_PAGE_OFFSET 1
+
/*
* Address types:
*
@@ -106,6 +111,7 @@ struct kvm_pte_chain {
* bits 4:7 - page table level for this shadow (1-4)
* bits 8:9 - page table quadrant for 2-level guests
* bit 16 - "metaphysical" - gfn is not a real page (huge page/real mode)
+ * bits 17:18 - "access" - the user and writable bits of a huge page pde
*/
union kvm_mmu_page_role {
unsigned word;
@@ -115,6 +121,7 @@ union kvm_mmu_page_role {
unsigned quadrant : 2;
unsigned pad_for_nice_hex_output : 6;
unsigned metaphysical : 1;
+ unsigned hugepage_access : 2;
};
};
@@ -133,7 +140,6 @@ struct kvm_mmu_page {
unsigned long slot_bitmap; /* One bit set per slot which has memory
* in this shadow page.
*/
- int global; /* Set if all ptes in this page are global */
int multimapped; /* More than one parent_pte? */
int root_count; /* Currently serving as active root */
union {
@@ -219,6 +225,34 @@ enum {
VCPU_SREG_LDTR,
};
+struct kvm_pio_request {
+ unsigned long count;
+ int cur_count;
+ struct page *guest_pages[2];
+ unsigned guest_page_offset;
+ int in;
+ int size;
+ int string;
+ int down;
+ int rep;
+};
+
+struct kvm_stat {
+ u32 pf_fixed;
+ u32 pf_guest;
+ u32 tlb_flush;
+ u32 invlpg;
+
+ u32 exits;
+ u32 io_exits;
+ u32 mmio_exits;
+ u32 signal_exits;
+ u32 irq_window_exits;
+ u32 halt_exits;
+ u32 request_irq_exits;
+ u32 irq_exits;
+};
+
struct kvm_vcpu {
struct kvm *kvm;
union {
@@ -228,6 +262,8 @@ struct kvm_vcpu {
struct mutex mutex;
int cpu;
int launched;
+ u64 host_tsc;
+ struct kvm_run *run;
int interrupt_window_open;
unsigned long irq_summary; /* bit vector: 1 per word in irq_pending */
#define NR_IRQ_WORDS KVM_IRQ_BITMAP_SIZE(unsigned long)
@@ -266,6 +302,7 @@ struct kvm_vcpu {
char fx_buf[FX_BUF_SIZE];
char *host_fx_image;
char *guest_fx_image;
+ int fpu_active;
int mmio_needed;
int mmio_read_completed;
@@ -273,6 +310,14 @@ struct kvm_vcpu {
int mmio_size;
unsigned char mmio_data[8];
gpa_t mmio_phys_addr;
+ gva_t mmio_fault_cr2;
+ struct kvm_pio_request pio;
+ void *pio_data;
+
+ int sigset_active;
+ sigset_t sigset;
+
+ struct kvm_stat stat;
struct {
int active;
@@ -284,6 +329,15 @@ struct kvm_vcpu {
u32 ar;
} tr, es, ds, fs, gs;
} rmode;
+
+ int cpuid_nent;
+ struct kvm_cpuid_entry cpuid_entries[KVM_MAX_CPUID_ENTRIES];
+};
+
+struct kvm_mem_alias {
+ gfn_t base_gfn;
+ unsigned long npages;
+ gfn_t target_gfn;
};
struct kvm_memory_slot {
@@ -296,6 +350,8 @@ struct kvm_memory_slot {
struct kvm {
spinlock_t lock; /* protects everything except vcpus */
+ int naliases;
+ struct kvm_mem_alias aliases[KVM_ALIAS_SLOTS];
int nmemslots;
struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS];
/*
@@ -312,22 +368,6 @@ struct kvm {
struct file *filp;
};
-struct kvm_stat {
- u32 pf_fixed;
- u32 pf_guest;
- u32 tlb_flush;
- u32 invlpg;
-
- u32 exits;
- u32 io_exits;
- u32 mmio_exits;
- u32 signal_exits;
- u32 irq_window_exits;
- u32 halt_exits;
- u32 request_irq_exits;
- u32 irq_exits;
-};
-
struct descriptor_table {
u16 limit;
unsigned long base;
@@ -358,10 +398,8 @@ struct kvm_arch_ops {
void (*set_segment)(struct kvm_vcpu *vcpu,
struct kvm_segment *var, int seg);
void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l);
- void (*decache_cr0_cr4_guest_bits)(struct kvm_vcpu *vcpu);
+ void (*decache_cr4_guest_bits)(struct kvm_vcpu *vcpu);
void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0);
- void (*set_cr0_no_modeswitch)(struct kvm_vcpu *vcpu,
- unsigned long cr0);
void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3);
void (*set_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4);
void (*set_efer)(struct kvm_vcpu *vcpu, u64 efer);
@@ -391,7 +429,6 @@ struct kvm_arch_ops {
unsigned char *hypercall_addr);
};
-extern struct kvm_stat kvm_stat;
extern struct kvm_arch_ops *kvm_arch_ops;
#define kvm_printf(kvm, fmt ...) printk(KERN_DEBUG fmt)
@@ -400,28 +437,29 @@ extern struct kvm_arch_ops *kvm_arch_ops;
int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module);
void kvm_exit_arch(void);
+int kvm_mmu_module_init(void);
+void kvm_mmu_module_exit(void);
+
void kvm_mmu_destroy(struct kvm_vcpu *vcpu);
int kvm_mmu_create(struct kvm_vcpu *vcpu);
int kvm_mmu_setup(struct kvm_vcpu *vcpu);
int kvm_mmu_reset_context(struct kvm_vcpu *vcpu);
void kvm_mmu_slot_remove_write_access(struct kvm_vcpu *vcpu, int slot);
+void kvm_mmu_zap_all(struct kvm_vcpu *vcpu);
hpa_t gpa_to_hpa(struct kvm_vcpu *vcpu, gpa_t gpa);
#define HPA_MSB ((sizeof(hpa_t) * 8) - 1)
#define HPA_ERR_MASK ((hpa_t)1 << HPA_MSB)
static inline int is_error_hpa(hpa_t hpa) { return hpa >> HPA_MSB; }
hpa_t gva_to_hpa(struct kvm_vcpu *vcpu, gva_t gva);
+struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva);
void kvm_emulator_want_group7_invlpg(void);
extern hpa_t bad_page_address;
-static inline struct page *gfn_to_page(struct kvm_memory_slot *slot, gfn_t gfn)
-{
- return slot->phys_mem[gfn - slot->base_gfn];
-}
-
+struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn);
struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn);
void mark_page_dirty(struct kvm *kvm, gfn_t gfn);
@@ -444,6 +482,10 @@ void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long value,
struct x86_emulate_ctxt;
+int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
+ int size, unsigned long count, int string, int down,
+ gva_t address, int rep, unsigned port);
+void kvm_emulate_cpuid(struct kvm_vcpu *vcpu);
int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address);
int emulate_clts(struct kvm_vcpu *vcpu);
int emulator_get_dr(struct x86_emulate_ctxt* ctxt, int dr,
@@ -493,12 +535,6 @@ static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
return vcpu->mmu.page_fault(vcpu, gva, error_code);
}
-static inline struct page *_gfn_to_page(struct kvm *kvm, gfn_t gfn)
-{
- struct kvm_memory_slot *slot = gfn_to_memslot(kvm, gfn);
- return (slot) ? slot->phys_mem[gfn - slot->base_gfn] : NULL;
-}
-
static inline int is_long_mode(struct kvm_vcpu *vcpu)
{
#ifdef CONFIG_X86_64
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index dc7a8c7..c8b8cfa 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -51,27 +51,27 @@ static DEFINE_SPINLOCK(kvm_lock);
static LIST_HEAD(vm_list);
struct kvm_arch_ops *kvm_arch_ops;
-struct kvm_stat kvm_stat;
-EXPORT_SYMBOL_GPL(kvm_stat);
+
+#define STAT_OFFSET(x) offsetof(struct kvm_vcpu, stat.x)
static struct kvm_stats_debugfs_item {
const char *name;
- u32 *data;
+ int offset;
struct dentry *dentry;
} debugfs_entries[] = {
- { "pf_fixed", &kvm_stat.pf_fixed },
- { "pf_guest", &kvm_stat.pf_guest },
- { "tlb_flush", &kvm_stat.tlb_flush },
- { "invlpg", &kvm_stat.invlpg },
- { "exits", &kvm_stat.exits },
- { "io_exits", &kvm_stat.io_exits },
- { "mmio_exits", &kvm_stat.mmio_exits },
- { "signal_exits", &kvm_stat.signal_exits },
- { "irq_window", &kvm_stat.irq_window_exits },
- { "halt_exits", &kvm_stat.halt_exits },
- { "request_irq", &kvm_stat.request_irq_exits },
- { "irq_exits", &kvm_stat.irq_exits },
- { NULL, NULL }
+ { "pf_fixed", STAT_OFFSET(pf_fixed) },
+ { "pf_guest", STAT_OFFSET(pf_guest) },
+ { "tlb_flush", STAT_OFFSET(tlb_flush) },
+ { "invlpg", STAT_OFFSET(invlpg) },
+ { "exits", STAT_OFFSET(exits) },
+ { "io_exits", STAT_OFFSET(io_exits) },
+ { "mmio_exits", STAT_OFFSET(mmio_exits) },
+ { "signal_exits", STAT_OFFSET(signal_exits) },
+ { "irq_window", STAT_OFFSET(irq_window_exits) },
+ { "halt_exits", STAT_OFFSET(halt_exits) },
+ { "request_irq", STAT_OFFSET(request_irq_exits) },
+ { "irq_exits", STAT_OFFSET(irq_exits) },
+ { NULL }
};
static struct dentry *debugfs_dir;
@@ -346,6 +346,17 @@ static void kvm_free_physmem(struct kvm *kvm)
kvm_free_physmem_slot(&kvm->memslots[i], NULL);
}
+static void free_pio_guest_pages(struct kvm_vcpu *vcpu)
+{
+ int i;
+
+ for (i = 0; i < 2; ++i)
+ if (vcpu->pio.guest_pages[i]) {
+ __free_page(vcpu->pio.guest_pages[i]);
+ vcpu->pio.guest_pages[i] = NULL;
+ }
+}
+
static void kvm_free_vcpu(struct kvm_vcpu *vcpu)
{
if (!vcpu->vmcs)
@@ -355,6 +366,11 @@ static void kvm_free_vcpu(struct kvm_vcpu *vcpu)
kvm_mmu_destroy(vcpu);
vcpu_put(vcpu);
kvm_arch_ops->vcpu_free(vcpu);
+ free_page((unsigned long)vcpu->run);
+ vcpu->run = NULL;
+ free_page((unsigned long)vcpu->pio_data);
+ vcpu->pio_data = NULL;
+ free_pio_guest_pages(vcpu);
}
static void kvm_free_vcpus(struct kvm *kvm)
@@ -404,12 +420,12 @@ static int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
u64 pdpte;
u64 *pdpt;
int ret;
- struct kvm_memory_slot *memslot;
+ struct page *page;
spin_lock(&vcpu->kvm->lock);
- memslot = gfn_to_memslot(vcpu->kvm, pdpt_gfn);
- /* FIXME: !memslot - emulate? 0xff? */
- pdpt = kmap_atomic(gfn_to_page(memslot, pdpt_gfn), KM_USER0);
+ page = gfn_to_page(vcpu->kvm, pdpt_gfn);
+ /* FIXME: !page - emulate? 0xff? */
+ pdpt = kmap_atomic(page, KM_USER0);
ret = 1;
for (i = 0; i < 4; ++i) {
@@ -494,7 +510,6 @@ EXPORT_SYMBOL_GPL(set_cr0);
void lmsw(struct kvm_vcpu *vcpu, unsigned long msw)
{
- kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu);
set_cr0(vcpu, (vcpu->cr0 & ~0x0ful) | (msw & 0x0f));
}
EXPORT_SYMBOL_GPL(lmsw);
@@ -830,7 +845,73 @@ out:
return r;
}
-struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn)
+/*
+ * Set a new alias region. Aliases map a portion of physical memory into
+ * another portion. This is useful for memory windows, for example the PC
+ * VGA region.
+ */
+static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm,
+ struct kvm_memory_alias *alias)
+{
+ int r, n;
+ struct kvm_mem_alias *p;
+
+ r = -EINVAL;
+ /* General sanity checks */
+ if (alias->memory_size & (PAGE_SIZE - 1))
+ goto out;
+ if (alias->guest_phys_addr & (PAGE_SIZE - 1))
+ goto out;
+ if (alias->slot >= KVM_ALIAS_SLOTS)
+ goto out;
+ if (alias->guest_phys_addr + alias->memory_size
+ < alias->guest_phys_addr)
+ goto out;
+ if (alias->target_phys_addr + alias->memory_size
+ < alias->target_phys_addr)
+ goto out;
+
+ spin_lock(&kvm->lock);
+
+ p = &kvm->aliases[alias->slot];
+ p->base_gfn = alias->guest_phys_addr >> PAGE_SHIFT;
+ p->npages = alias->memory_size >> PAGE_SHIFT;
+ p->target_gfn = alias->target_phys_addr >> PAGE_SHIFT;
+
+ for (n = KVM_ALIAS_SLOTS; n > 0; --n)
+ if (kvm->aliases[n - 1].npages)
+ break;
+ kvm->naliases = n;
+
+ spin_unlock(&kvm->lock);
+
+ vcpu_load(&kvm->vcpus[0]);
+ spin_lock(&kvm->lock);
+ kvm_mmu_zap_all(&kvm->vcpus[0]);
+ spin_unlock(&kvm->lock);
+ vcpu_put(&kvm->vcpus[0]);
+
+ return 0;
+
+out:
+ return r;
+}
+
+static gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
+{
+ int i;
+ struct kvm_mem_alias *alias;
+
+ for (i = 0; i < kvm->naliases; ++i) {
+ alias = &kvm->aliases[i];
+ if (gfn >= alias->base_gfn
+ && gfn < alias->base_gfn + alias->npages)
+ return alias->target_gfn + gfn - alias->base_gfn;
+ }
+ return gfn;
+}
+
+static struct kvm_memory_slot *__gfn_to_memslot(struct kvm *kvm, gfn_t gfn)
{
int i;
@@ -843,7 +924,24 @@ struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn)
}
return NULL;
}
-EXPORT_SYMBOL_GPL(gfn_to_memslot);
+
+struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn)
+{
+ gfn = unalias_gfn(kvm, gfn);
+ return __gfn_to_memslot(kvm, gfn);
+}
+
+struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
+{
+ struct kvm_memory_slot *slot;
+
+ gfn = unalias_gfn(kvm, gfn);
+ slot = __gfn_to_memslot(kvm, gfn);
+ if (!slot)
+ return NULL;
+ return slot->phys_mem[gfn - slot->base_gfn];
+}
+EXPORT_SYMBOL_GPL(gfn_to_page);
void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
{
@@ -871,7 +969,7 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
}
static int emulator_read_std(unsigned long addr,
- unsigned long *val,
+ void *val,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
@@ -883,20 +981,20 @@ static int emulator_read_std(unsigned long addr,
unsigned offset = addr & (PAGE_SIZE-1);
unsigned tocopy = min(bytes, (unsigned)PAGE_SIZE - offset);
unsigned long pfn;
- struct kvm_memory_slot *memslot;
- void *page;
+ struct page *page;
+ void *page_virt;
if (gpa == UNMAPPED_GVA)
return X86EMUL_PROPAGATE_FAULT;
pfn = gpa >> PAGE_SHIFT;
- memslot = gfn_to_memslot(vcpu->kvm, pfn);
- if (!memslot)
+ page = gfn_to_page(vcpu->kvm, pfn);
+ if (!page)
return X86EMUL_UNHANDLEABLE;
- page = kmap_atomic(gfn_to_page(memslot, pfn), KM_USER0);
+ page_virt = kmap_atomic(page, KM_USER0);
- memcpy(data, page + offset, tocopy);
+ memcpy(data, page_virt + offset, tocopy);
- kunmap_atomic(page, KM_USER0);
+ kunmap_atomic(page_virt, KM_USER0);
bytes -= tocopy;
data += tocopy;
@@ -907,7 +1005,7 @@ static int emulator_read_std(unsigned long addr,
}
static int emulator_write_std(unsigned long addr,
- unsigned long val,
+ const void *val,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
@@ -917,7 +1015,7 @@ static int emulator_write_std(unsigned long addr,
}
static int emulator_read_emulated(unsigned long addr,
- unsigned long *val,
+ void *val,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
@@ -945,37 +1043,37 @@ static int emulator_read_emulated(unsigned long addr,
}
static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
- unsigned long val, int bytes)
+ const void *val, int bytes)
{
- struct kvm_memory_slot *m;
struct page *page;
void *virt;
if (((gpa + bytes - 1) >> PAGE_SHIFT) != (gpa >> PAGE_SHIFT))
return 0;
- m = gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT);
- if (!m)
+ page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
+ if (!page)
return 0;
- page = gfn_to_page(m, gpa >> PAGE_SHIFT);
kvm_mmu_pre_write(vcpu, gpa, bytes);
mark_page_dirty(vcpu->kvm, gpa >> PAGE_SHIFT);
virt = kmap_atomic(page, KM_USER0);
- memcpy(virt + offset_in_page(gpa), &val, bytes);
+ memcpy(virt + offset_in_page(gpa), val, bytes);
kunmap_atomic(virt, KM_USER0);
kvm_mmu_post_write(vcpu, gpa, bytes);
return 1;
}
static int emulator_write_emulated(unsigned long addr,
- unsigned long val,
+ const void *val,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
struct kvm_vcpu *vcpu = ctxt->vcpu;
gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr);
- if (gpa == UNMAPPED_GVA)
+ if (gpa == UNMAPPED_GVA) {
+ kvm_arch_ops->inject_page_fault(vcpu, addr, 2);
return X86EMUL_PROPAGATE_FAULT;
+ }
if (emulator_write_phys(vcpu, gpa, val, bytes))
return X86EMUL_CONTINUE;
@@ -984,14 +1082,14 @@ static int emulator_write_emulated(unsigned long addr,
vcpu->mmio_phys_addr = gpa;
vcpu->mmio_size = bytes;
vcpu->mmio_is_write = 1;
- memcpy(vcpu->mmio_data, &val, bytes);
+ memcpy(vcpu->mmio_data, val, bytes);
return X86EMUL_CONTINUE;
}
static int emulator_cmpxchg_emulated(unsigned long addr,
- unsigned long old,
- unsigned long new,
+ const void *old,
+ const void *new,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
@@ -1004,30 +1102,6 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
return emulator_write_emulated(addr, new, bytes, ctxt);
}
-#ifdef CONFIG_X86_32
-
-static int emulator_cmpxchg8b_emulated(unsigned long addr,
- unsigned long old_lo,
- unsigned long old_hi,
- unsigned long new_lo,
- unsigned long new_hi,
- struct x86_emulate_ctxt *ctxt)
-{
- static int reported;
- int r;
-
- if (!reported) {
- reported = 1;
- printk(KERN_WARNING "kvm: emulating exchange8b as write\n");
- }
- r = emulator_write_emulated(addr, new_lo, 4, ctxt);
- if (r != X86EMUL_CONTINUE)
- return r;
- return emulator_write_emulated(addr+4, new_hi, 4, ctxt);
-}
-
-#endif
-
static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
{
return kvm_arch_ops->get_segment_base(vcpu, seg);
@@ -1042,7 +1116,6 @@ int emulate_clts(struct kvm_vcpu *vcpu)
{
unsigned long cr0;
- kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu);
cr0 = vcpu->cr0 & ~CR0_TS_MASK;
kvm_arch_ops->set_cr0(vcpu, cr0);
return X86EMUL_CONTINUE;
@@ -1102,9 +1175,6 @@ struct x86_emulate_ops emulate_ops = {
.read_emulated = emulator_read_emulated,
.write_emulated = emulator_write_emulated,
.cmpxchg_emulated = emulator_cmpxchg_emulated,
-#ifdef CONFIG_X86_32
- .cmpxchg8b_emulated = emulator_cmpxchg8b_emulated,
-#endif
};
int emulate_instruction(struct kvm_vcpu *vcpu,
@@ -1116,6 +1186,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
int r;
int cs_db, cs_l;
+ vcpu->mmio_fault_cr2 = cr2;
kvm_arch_ops->cache_regs(vcpu);
kvm_arch_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
@@ -1166,8 +1237,10 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
kvm_arch_ops->decache_regs(vcpu);
kvm_arch_ops->set_rflags(vcpu, emulate_ctxt.eflags);
- if (vcpu->mmio_is_write)
+ if (vcpu->mmio_is_write) {
+ vcpu->mmio_needed = 0;
return EMULATE_DO_MMIO;
+ }
return EMULATE_DONE;
}
@@ -1177,7 +1250,7 @@ int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
unsigned long nr, a0, a1, a2, a3, a4, a5, ret;
- kvm_arch_ops->decache_regs(vcpu);
+ kvm_arch_ops->cache_regs(vcpu);
ret = -KVM_EINVAL;
#ifdef CONFIG_X86_64
if (is_long_mode(vcpu)) {
@@ -1201,10 +1274,19 @@ int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run)
}
switch (nr) {
default:
- ;
+ run->hypercall.args[0] = a0;
+ run->hypercall.args[1] = a1;
+ run->hypercall.args[2] = a2;
+ run->hypercall.args[3] = a3;
+ run->hypercall.args[4] = a4;
+ run->hypercall.args[5] = a5;
+ run->hypercall.ret = ret;
+ run->hypercall.longmode = is_long_mode(vcpu);
+ kvm_arch_ops->decache_regs(vcpu);
+ return 0;
}
vcpu->regs[VCPU_REGS_RAX] = ret;
- kvm_arch_ops->cache_regs(vcpu);
+ kvm_arch_ops->decache_regs(vcpu);
return 1;
}
EXPORT_SYMBOL_GPL(kvm_hypercall);
@@ -1237,7 +1319,7 @@ void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw,
unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr)
{
- kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu);
+ kvm_arch_ops->decache_cr4_guest_bits(vcpu);
switch (cr) {
case 0:
return vcpu->cr0;
@@ -1442,6 +1524,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
printk(KERN_WARNING "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n",
__FUNCTION__, data);
break;
+ case MSR_IA32_MCG_STATUS:
+ printk(KERN_WARNING "%s: MSR_IA32_MCG_STATUS 0x%llx, nop\n",
+ __FUNCTION__, data);
+ break;
case MSR_IA32_UCODE_REV:
case MSR_IA32_UCODE_WRITE:
case 0x200 ... 0x2ff: /* MTRRs */
@@ -1478,6 +1564,8 @@ static int set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
void kvm_resched(struct kvm_vcpu *vcpu)
{
+ if (!need_resched())
+ return;
vcpu_put(vcpu);
cond_resched();
vcpu_load(vcpu);
@@ -1502,29 +1590,250 @@ void save_msrs(struct vmx_msr_entry *e, int n)
}
EXPORT_SYMBOL_GPL(save_msrs);
+void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
+{
+ int i;
+ u32 function;
+ struct kvm_cpuid_entry *e, *best;
+
+ kvm_arch_ops->cache_regs(vcpu);
+ function = vcpu->regs[VCPU_REGS_RAX];
+ vcpu->regs[VCPU_REGS_RAX] = 0;
+ vcpu->regs[VCPU_REGS_RBX] = 0;
+ vcpu->regs[VCPU_REGS_RCX] = 0;
+ vcpu->regs[VCPU_REGS_RDX] = 0;
+ best = NULL;
+ for (i = 0; i < vcpu->cpuid_nent; ++i) {
+ e = &vcpu->cpuid_entries[i];
+ if (e->function == function) {
+ best = e;
+ break;
+ }
+ /*
+ * Both basic or both extended?
+ */
+ if (((e->function ^ function) & 0x80000000) == 0)
+ if (!best || e->function > best->function)
+ best = e;
+ }
+ if (best) {
+ vcpu->regs[VCPU_REGS_RAX] = best->eax;
+ vcpu->regs[VCPU_REGS_RBX] = best->ebx;
+ vcpu->regs[VCPU_REGS_RCX] = best->ecx;
+ vcpu->regs[VCPU_REGS_RDX] = best->edx;
+ }
+ kvm_arch_ops->decache_regs(vcpu);
+ kvm_arch_ops->skip_emulated_instruction(vcpu);
+}
+EXPORT_SYMBOL_GPL(kvm_emulate_cpuid);
+
+static int pio_copy_data(struct kvm_vcpu *vcpu)
+{
+ void *p = vcpu->pio_data;
+ void *q;
+ unsigned bytes;
+ int nr_pages = vcpu->pio.guest_pages[1] ? 2 : 1;
+
+ kvm_arch_ops->vcpu_put(vcpu);
+ q = vmap(vcpu->pio.guest_pages, nr_pages, VM_READ|VM_WRITE,
+ PAGE_KERNEL);
+ if (!q) {
+ kvm_arch_ops->vcpu_load(vcpu);
+ free_pio_guest_pages(vcpu);
+ return -ENOMEM;
+ }
+ q += vcpu->pio.guest_page_offset;
+ bytes = vcpu->pio.size * vcpu->pio.cur_count;
+ if (vcpu->pio.in)
+ memcpy(q, p, bytes);
+ else
+ memcpy(p, q, bytes);
+ q -= vcpu->pio.guest_page_offset;
+ vunmap(q);
+ kvm_arch_ops->vcpu_load(vcpu);
+ free_pio_guest_pages(vcpu);
+ return 0;
+}
+
+static int complete_pio(struct kvm_vcpu *vcpu)
+{
+ struct kvm_pio_request *io = &vcpu->pio;
+ long delta;
+ int r;
+
+ kvm_arch_ops->cache_regs(vcpu);
+
+ if (!io->string) {
+ if (io->in)
+ memcpy(&vcpu->regs[VCPU_REGS_RAX], vcpu->pio_data,
+ io->size);
+ } else {
+ if (io->in) {
+ r = pio_copy_data(vcpu);
+ if (r) {
+ kvm_arch_ops->cache_regs(vcpu);
+ return r;
+ }
+ }
+
+ delta = 1;
+ if (io->rep) {
+ delta *= io->cur_count;
+ /*
+ * The size of the register should really depend on
+ * current address size.
+ */
+ vcpu->regs[VCPU_REGS_RCX] -= delta;
+ }
+ if (io->down)
+ delta = -delta;
+ delta *= io->size;
+ if (io->in)
+ vcpu->regs[VCPU_REGS_RDI] += delta;
+ else
+ vcpu->regs[VCPU_REGS_RSI] += delta;
+ }
+
+ kvm_arch_ops->decache_regs(vcpu);
+
+ io->count -= io->cur_count;
+ io->cur_count = 0;
+
+ if (!io->count)
+ kvm_arch_ops->skip_emulated_instruction(vcpu);
+ return 0;
+}
+
+int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
+ int size, unsigned long count, int string, int down,
+ gva_t address, int rep, unsigned port)
+{
+ unsigned now, in_page;
+ int i;
+ int nr_pages = 1;
+ struct page *page;
+
+ vcpu->run->exit_reason = KVM_EXIT_IO;
+ vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
+ vcpu->run->io.size = size;
+ vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE;
+ vcpu->run->io.count = count;
+ vcpu->run->io.port = port;
+ vcpu->pio.count = count;
+ vcpu->pio.cur_count = count;
+ vcpu->pio.size = size;
+ vcpu->pio.in = in;
+ vcpu->pio.string = string;
+ vcpu->pio.down = down;
+ vcpu->pio.guest_page_offset = offset_in_page(address);
+ vcpu->pio.rep = rep;
+
+ if (!string) {
+ kvm_arch_ops->cache_regs(vcpu);
+ memcpy(vcpu->pio_data, &vcpu->regs[VCPU_REGS_RAX], 4);
+ kvm_arch_ops->decache_regs(vcpu);
+ return 0;
+ }
+
+ if (!count) {
+ kvm_arch_ops->skip_emulated_instruction(vcpu);
+ return 1;
+ }
+
+ now = min(count, PAGE_SIZE / size);
+
+ if (!down)
+ in_page = PAGE_SIZE - offset_in_page(address);
+ else
+ in_page = offset_in_page(address) + size;
+ now = min(count, (unsigned long)in_page / size);
+ if (!now) {
+ /*
+ * String I/O straddles page boundary. Pin two guest pages
+ * so that we satisfy atomicity constraints. Do just one
+ * transaction to avoid complexity.
+ */
+ nr_pages = 2;
+ now = 1;
+ }
+ if (down) {
+ /*
+ * String I/O in reverse. Yuck. Kill the guest, fix later.
+ */
+ printk(KERN_ERR "kvm: guest string pio down\n");
+ inject_gp(vcpu);
+ return 1;
+ }
+ vcpu->run->io.count = now;
+ vcpu->pio.cur_count = now;
+
+ for (i = 0; i < nr_pages; ++i) {
+ spin_lock(&vcpu->kvm->lock);
+ page = gva_to_page(vcpu, address + i * PAGE_SIZE);
+ if (page)
+ get_page(page);
+ vcpu->pio.guest_pages[i] = page;
+ spin_unlock(&vcpu->kvm->lock);
+ if (!page) {
+ inject_gp(vcpu);
+ free_pio_guest_pages(vcpu);
+ return 1;
+ }
+ }
+
+ if (!vcpu->pio.in)
+ return pio_copy_data(vcpu);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(kvm_setup_pio);
+
static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
int r;
+ sigset_t sigsaved;
vcpu_load(vcpu);
+ if (vcpu->sigset_active)
+ sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
+
/* re-sync apic's tpr */
vcpu->cr8 = kvm_run->cr8;
- if (kvm_run->emulated) {
- kvm_arch_ops->skip_emulated_instruction(vcpu);
- kvm_run->emulated = 0;
+ if (vcpu->pio.cur_count) {
+ r = complete_pio(vcpu);
+ if (r)
+ goto out;
}
- if (kvm_run->mmio_completed) {
+ if (vcpu->mmio_needed) {
memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
vcpu->mmio_read_completed = 1;
+ vcpu->mmio_needed = 0;
+ r = emulate_instruction(vcpu, kvm_run,
+ vcpu->mmio_fault_cr2, 0);
+ if (r == EMULATE_DO_MMIO) {
+ /*
+ * Read-modify-write. Back to userspace.
+ */
+ kvm_run->exit_reason = KVM_EXIT_MMIO;
+ r = 0;
+ goto out;
+ }
}
- vcpu->mmio_needed = 0;
+ if (kvm_run->exit_reason == KVM_EXIT_HYPERCALL) {
+ kvm_arch_ops->cache_regs(vcpu);
+ vcpu->regs[VCPU_REGS_RAX] = kvm_run->hypercall.ret;
+ kvm_arch_ops->decache_regs(vcpu);
+ }
r = kvm_arch_ops->run(vcpu, kvm_run);
+out:
+ if (vcpu->sigset_active)
+ sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+
vcpu_put(vcpu);
return r;
}
@@ -1633,7 +1942,7 @@ static int kvm_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
sregs->gdt.limit = dt.limit;
sregs->gdt.base = dt.base;
- kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu);
+ kvm_arch_ops->decache_cr4_guest_bits(vcpu);
sregs->cr0 = vcpu->cr0;
sregs->cr2 = vcpu->cr2;
sregs->cr3 = vcpu->cr3;
@@ -1665,16 +1974,6 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
vcpu_load(vcpu);
- set_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
- set_segment(vcpu, &sregs->ds, VCPU_SREG_DS);
- set_segment(vcpu, &sregs->es, VCPU_SREG_ES);
- set_segment(vcpu, &sregs->fs, VCPU_SREG_FS);
- set_segment(vcpu, &sregs->gs, VCPU_SREG_GS);
- set_segment(vcpu, &sregs->ss, VCPU_SREG_SS);
-
- set_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
- set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
-
dt.limit = sregs->idt.limit;
dt.base = sregs->idt.base;
kvm_arch_ops->set_idt(vcpu, &dt);
@@ -1694,10 +1993,10 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
#endif
vcpu->apic_base = sregs->apic_base;
- kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu);
+ kvm_arch_ops->decache_cr4_guest_bits(vcpu);
mmu_reset_needed |= vcpu->cr0 != sregs->cr0;
- kvm_arch_ops->set_cr0_no_modeswitch(vcpu, sregs->cr0);
+ kvm_arch_ops->set_cr0(vcpu, sregs->cr0);
mmu_reset_needed |= vcpu->cr4 != sregs->cr4;
kvm_arch_ops->set_cr4(vcpu, sregs->cr4);
@@ -1714,6 +2013,16 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
if (vcpu->irq_pending[i])
__set_bit(i, &vcpu->irq_summary);
+ set_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
+ set_segment(vcpu, &sregs->ds, VCPU_SREG_DS);
+ set_segment(vcpu, &sregs->es, VCPU_SREG_ES);
+ set_segment(vcpu, &sregs->fs, VCPU_SREG_FS);
+ set_segment(vcpu, &sregs->gs, VCPU_SREG_GS);
+ set_segment(vcpu, &sregs->ss, VCPU_SREG_SS);
+
+ set_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
+ set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
+
vcpu_put(vcpu);
return 0;
@@ -1887,6 +2196,36 @@ static int kvm_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
return r;
}
+static struct page *kvm_vcpu_nopage(struct vm_area_struct *vma,
+ unsigned long address,
+ int *type)
+{
+ struct kvm_vcpu *vcpu = vma->vm_file->private_data;
+ unsigned long pgoff;
+ struct page *page;
+
+ *type = VM_FAULT_MINOR;
+ pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+ if (pgoff == 0)
+ page = virt_to_page(vcpu->run);
+ else if (pgoff == KVM_PIO_PAGE_OFFSET)
+ page = virt_to_page(vcpu->pio_data);
+ else
+ return NOPAGE_SIGBUS;
+ get_page(page);
+ return page;
+}
+
+static struct vm_operations_struct kvm_vcpu_vm_ops = {
+ .nopage = kvm_vcpu_nopage,
+};
+
+static int kvm_vcpu_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ vma->vm_ops = &kvm_vcpu_vm_ops;
+ return 0;
+}
+
static int kvm_vcpu_release(struct inode *inode, struct file *filp)
{
struct kvm_vcpu *vcpu = filp->private_data;
@@ -1899,6 +2238,7 @@ static struct file_operations kvm_vcpu_fops = {
.release = kvm_vcpu_release,
.unlocked_ioctl = kvm_vcpu_ioctl,
.compat_ioctl = kvm_vcpu_ioctl,
+ .mmap = kvm_vcpu_mmap,
};
/*
@@ -1947,6 +2287,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n)
{
int r;
struct kvm_vcpu *vcpu;
+ struct page *page;
r = -EINVAL;
if (!valid_vcpu(n))
@@ -1961,9 +2302,22 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n)
return -EEXIST;
}
+ page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+ r = -ENOMEM;
+ if (!page)
+ goto out_unlock;
+ vcpu->run = page_address(page);
+
+ page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+ r = -ENOMEM;
+ if (!page)
+ goto out_free_run;
+ vcpu->pio_data = page_address(page);
+
vcpu->host_fx_image = (char*)ALIGN((hva_t)vcpu->fx_buf,
FX_IMAGE_ALIGN);
vcpu->guest_fx_image = vcpu->host_fx_image + FX_IMAGE_SIZE;
+ vcpu->cr0 = 0x10;
r = kvm_arch_ops->vcpu_create(vcpu);
if (r < 0)
@@ -1990,11 +2344,107 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n)
out_free_vcpus:
kvm_free_vcpu(vcpu);
+out_free_run:
+ free_page((unsigned long)vcpu->run);
+ vcpu->run = NULL;
+out_unlock:
mutex_unlock(&vcpu->mutex);
out:
return r;
}
+static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
+ struct kvm_cpuid *cpuid,
+ struct kvm_cpuid_entry __user *entries)
+{
+ int r;
+
+ r = -E2BIG;
+ if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
+ goto out;
+ r = -EFAULT;
+ if (copy_from_user(&vcpu->cpuid_entries, entries,
+ cpuid->nent * sizeof(struct kvm_cpuid_entry)))
+ goto out;
+ vcpu->cpuid_nent = cpuid->nent;
+ return 0;
+
+out:
+ return r;
+}
+
+static int kvm_vcpu_ioctl_set_sigmask(struct kvm_vcpu *vcpu, sigset_t *sigset)
+{
+ if (sigset) {
+ sigdelsetmask(sigset, sigmask(SIGKILL)|sigmask(SIGSTOP));
+ vcpu->sigset_active = 1;
+ vcpu->sigset = *sigset;
+ } else
+ vcpu->sigset_active = 0;
+ return 0;
+}
+
+/*
+ * fxsave fpu state. Taken from x86_64/processor.h. To be killed when
+ * we have asm/x86/processor.h
+ */
+struct fxsave {
+ u16 cwd;
+ u16 swd;
+ u16 twd;
+ u16 fop;
+ u64 rip;
+ u64 rdp;
+ u32 mxcsr;
+ u32 mxcsr_mask;
+ u32 st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
+#ifdef CONFIG_X86_64
+ u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */
+#else
+ u32 xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
+#endif
+};
+
+static int kvm_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
+{
+ struct fxsave *fxsave = (struct fxsave *)vcpu->guest_fx_image;
+
+ vcpu_load(vcpu);
+
+ memcpy(fpu->fpr, fxsave->st_space, 128);
+ fpu->fcw = fxsave->cwd;
+ fpu->fsw = fxsave->swd;
+ fpu->ftwx = fxsave->twd;
+ fpu->last_opcode = fxsave->fop;
+ fpu->last_ip = fxsave->rip;
+ fpu->last_dp = fxsave->rdp;
+ memcpy(fpu->xmm, fxsave->xmm_space, sizeof fxsave->xmm_space);
+
+ vcpu_put(vcpu);
+
+ return 0;
+}
+
+static int kvm_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
+{
+ struct fxsave *fxsave = (struct fxsave *)vcpu->guest_fx_image;
+
+ vcpu_load(vcpu);
+
+ memcpy(fxsave->st_space, fpu->fpr, 128);
+ fxsave->cwd = fpu->fcw;
+ fxsave->swd = fpu->fsw;
+ fxsave->twd = fpu->ftwx;
+ fxsave->fop = fpu->last_opcode;
+ fxsave->rip = fpu->last_ip;
+ fxsave->rdp = fpu->last_dp;
+ memcpy(fxsave->xmm_space, fpu->xmm, sizeof fxsave->xmm_space);
+
+ vcpu_put(vcpu);
+
+ return 0;
+}
+
static long kvm_vcpu_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg)
{
@@ -2003,21 +2453,12 @@ static long kvm_vcpu_ioctl(struct file *filp,
int r = -EINVAL;
switch (ioctl) {
- case KVM_RUN: {
- struct kvm_run kvm_run;
-
- r = -EFAULT;
- if (copy_from_user(&kvm_run, argp, sizeof kvm_run))
+ case KVM_RUN:
+ r = -EINVAL;
+ if (arg)
goto out;
- r = kvm_vcpu_ioctl_run(vcpu, &kvm_run);
- if (r < 0 && r != -EINTR)
- goto out;
- if (copy_to_user(argp, &kvm_run, sizeof kvm_run)) {
- r = -EFAULT;
- goto out;
- }
+ r = kvm_vcpu_ioctl_run(vcpu, vcpu->run);
break;
- }
case KVM_GET_REGS: {
struct kvm_regs kvm_regs;
@@ -2113,6 +2554,66 @@ static long kvm_vcpu_ioctl(struct file *filp,
case KVM_SET_MSRS:
r = msr_io(vcpu, argp, do_set_msr, 0);
break;
+ case KVM_SET_CPUID: {
+ struct kvm_cpuid __user *cpuid_arg = argp;
+ struct kvm_cpuid cpuid;
+
+ r = -EFAULT;
+ if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
+ goto out;
+ r = kvm_vcpu_ioctl_set_cpuid(vcpu, &cpuid, cpuid_arg->entries);
+ if (r)
+ goto out;
+ break;
+ }
+ case KVM_SET_SIGNAL_MASK: {
+ struct kvm_signal_mask __user *sigmask_arg = argp;
+ struct kvm_signal_mask kvm_sigmask;
+ sigset_t sigset, *p;
+
+ p = NULL;
+ if (argp) {
+ r = -EFAULT;
+ if (copy_from_user(&kvm_sigmask, argp,
+ sizeof kvm_sigmask))
+ goto out;
+ r = -EINVAL;
+ if (kvm_sigmask.len != sizeof sigset)
+ goto out;
+ r = -EFAULT;
+ if (copy_from_user(&sigset, sigmask_arg->sigset,
+ sizeof sigset))
+ goto out;
+ p = &sigset;
+ }
+ r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset);
+ break;
+ }
+ case KVM_GET_FPU: {
+ struct kvm_fpu fpu;
+
+ memset(&fpu, 0, sizeof fpu);
+ r = kvm_vcpu_ioctl_get_fpu(vcpu, &fpu);
+ if (r)
+ goto out;
+ r = -EFAULT;
+ if (copy_to_user(argp, &fpu, sizeof fpu))
+ goto out;
+ r = 0;
+ break;
+ }
+ case KVM_SET_FPU: {
+ struct kvm_fpu fpu;
+
+ r = -EFAULT;
+ if (copy_from_user(&fpu, argp, sizeof fpu))
+ goto out;
+ r = kvm_vcpu_ioctl_set_fpu(vcpu, &fpu);
+ if (r)
+ goto out;
+ r = 0;
+ break;
+ }
default:
;
}
@@ -2155,6 +2656,17 @@ static long kvm_vm_ioctl(struct file *filp,
goto out;
break;
}
+ case KVM_SET_MEMORY_ALIAS: {
+ struct kvm_memory_alias alias;
+
+ r = -EFAULT;
+ if (copy_from_user(&alias, argp, sizeof alias))
+ goto out;
+ r = kvm_vm_ioctl_set_memory_alias(kvm, &alias);
+ if (r)
+ goto out;
+ break;
+ }
default:
;
}
@@ -2168,15 +2680,11 @@ static struct page *kvm_vm_nopage(struct vm_area_struct *vma,
{
struct kvm *kvm = vma->vm_file->private_data;
unsigned long pgoff;
- struct kvm_memory_slot *slot;
struct page *page;
*type = VM_FAULT_MINOR;
pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
- slot = gfn_to_memslot(kvm, pgoff);
- if (!slot)
- return NOPAGE_SIGBUS;
- page = gfn_to_page(slot, pgoff);
+ page = gfn_to_page(kvm, pgoff);
if (!page)
return NOPAGE_SIGBUS;
get_page(page);
@@ -2248,13 +2756,19 @@ static long kvm_dev_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg)
{
void __user *argp = (void __user *)arg;
- int r = -EINVAL;
+ long r = -EINVAL;
switch (ioctl) {
case KVM_GET_API_VERSION:
+ r = -EINVAL;
+ if (arg)
+ goto out;
r = KVM_API_VERSION;
break;
case KVM_CREATE_VM:
+ r = -EINVAL;
+ if (arg)
+ goto out;
r = kvm_dev_ioctl_create_vm();
break;
case KVM_GET_MSR_INDEX_LIST: {
@@ -2284,6 +2798,18 @@ static long kvm_dev_ioctl(struct file *filp,
r = 0;
break;
}
+ case KVM_CHECK_EXTENSION:
+ /*
+ * No extensions defined at present.
+ */
+ r = 0;
+ break;
+ case KVM_GET_VCPU_MMAP_SIZE:
+ r = -EINVAL;
+ if (arg)
+ goto out;
+ r = 2 * PAGE_SIZE;
+ break;
default:
;
}
@@ -2299,7 +2825,7 @@ static struct file_operations kvm_chardev_ops = {
};
static struct miscdevice kvm_dev = {
- MISC_DYNAMIC_MINOR,
+ KVM_MINOR,
"kvm",
&kvm_chardev_ops,
};
@@ -2385,14 +2911,39 @@ static struct notifier_block kvm_cpu_notifier = {
.priority = 20, /* must be > scheduler priority */
};
+static u64 stat_get(void *_offset)
+{
+ unsigned offset = (long)_offset;
+ u64 total = 0;
+ struct kvm *kvm;
+ struct kvm_vcpu *vcpu;
+ int i;
+
+ spin_lock(&kvm_lock);
+ list_for_each_entry(kvm, &vm_list, vm_list)
+ for (i = 0; i < KVM_MAX_VCPUS; ++i) {
+ vcpu = &kvm->vcpus[i];
+ total += *(u32 *)((void *)vcpu + offset);
+ }
+ spin_unlock(&kvm_lock);
+ return total;
+}
+
+static void stat_set(void *offset, u64 val)
+{
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(stat_fops, stat_get, stat_set, "%llu\n");
+
static __init void kvm_init_debug(void)
{
struct kvm_stats_debugfs_item *p;
debugfs_dir = debugfs_create_dir("kvm", NULL);
for (p = debugfs_entries; p->name; ++p)
- p->dentry = debugfs_create_u32(p->name, 0444, debugfs_dir,
- p->data);
+ p->dentry = debugfs_create_file(p->name, 0444, debugfs_dir,
+ (void *)(long)p->offset,
+ &stat_fops);
}
static void kvm_exit_debug(void)
@@ -2522,6 +3073,10 @@ static __init int kvm_init(void)
static struct page *bad_page;
int r;
+ r = kvm_mmu_module_init();
+ if (r)
+ goto out4;
+
r = register_filesystem(&kvm_fs_type);
if (r)
goto out3;
@@ -2550,6 +3105,8 @@ out:
out2:
unregister_filesystem(&kvm_fs_type);
out3:
+ kvm_mmu_module_exit();
+out4:
return r;
}
@@ -2559,6 +3116,7 @@ static __exit void kvm_exit(void)
__free_page(pfn_to_page(bad_page_address >> PAGE_SHIFT));
mntput(kvmfs_mnt);
unregister_filesystem(&kvm_fs_type);
+ kvm_mmu_module_exit();
}
module_init(kvm_init)
diff --git a/drivers/kvm/kvm_svm.h b/drivers/kvm/kvm_svm.h
index 624f1ca..a869983 100644
--- a/drivers/kvm/kvm_svm.h
+++ b/drivers/kvm/kvm_svm.h
@@ -9,17 +9,15 @@
#include "svm.h"
#include "kvm.h"
-static const u32 host_save_msrs[] = {
+static const u32 host_save_user_msrs[] = {
#ifdef CONFIG_X86_64
MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE,
- MSR_FS_BASE, MSR_GS_BASE,
+ MSR_FS_BASE,
#endif
MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
- MSR_IA32_DEBUGCTLMSR, /*MSR_IA32_LASTBRANCHFROMIP,
- MSR_IA32_LASTBRANCHTOIP, MSR_IA32_LASTINTFROMIP,MSR_IA32_LASTINTTOIP,*/
};
-#define NR_HOST_SAVE_MSRS ARRAY_SIZE(host_save_msrs)
+#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
#define NUM_DB_REGS 4
struct vcpu_svm {
@@ -28,13 +26,12 @@ struct vcpu_svm {
struct svm_cpu_data *svm_data;
uint64_t asid_generation;
- unsigned long cr0;
- unsigned long cr4;
unsigned long db_regs[NUM_DB_REGS];
u64 next_rip;
- u64 host_msrs[NR_HOST_SAVE_MSRS];
+ u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
+ u64 host_gs_base;
unsigned long host_cr2;
unsigned long host_db_regs[NUM_DB_REGS];
unsigned long host_dr6;
diff --git a/drivers/kvm/kvm_vmx.h b/drivers/kvm/kvm_vmx.h
deleted file mode 100644
index d139f73..0000000
--- a/drivers/kvm/kvm_vmx.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __KVM_VMX_H
-#define __KVM_VMX_H
-
-#ifdef CONFIG_X86_64
-/*
- * avoid save/load MSR_SYSCALL_MASK and MSR_LSTAR by std vt
- * mechanism (cpu bug AA24)
- */
-#define NR_BAD_MSRS 2
-#else
-#define NR_BAD_MSRS 0
-#endif
-
-#endif
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index cab26f3..e8e2281 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -52,11 +52,15 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg) {}
static int dbg = 1;
#endif
+#ifndef MMU_DEBUG
+#define ASSERT(x) do { } while (0)
+#else
#define ASSERT(x) \
if (!(x)) { \
printk(KERN_WARNING "assertion failed %s:%d: %s\n", \
__FILE__, __LINE__, #x); \
}
+#endif
#define PT64_PT_BITS 9
#define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS)
@@ -159,6 +163,9 @@ struct kvm_rmap_desc {
struct kvm_rmap_desc *more;
};
+static struct kmem_cache *pte_chain_cache;
+static struct kmem_cache *rmap_desc_cache;
+
static int is_write_protection(struct kvm_vcpu *vcpu)
{
return vcpu->cr0 & CR0_WP_MASK;
@@ -196,14 +203,15 @@ static int is_rmap_pte(u64 pte)
}
static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
- size_t objsize, int min)
+ struct kmem_cache *base_cache, int min,
+ gfp_t gfp_flags)
{
void *obj;
if (cache->nobjs >= min)
return 0;
while (cache->nobjs < ARRAY_SIZE(cache->objects)) {
- obj = kzalloc(objsize, GFP_NOWAIT);
+ obj = kmem_cache_zalloc(base_cache, gfp_flags);
if (!obj)
return -ENOMEM;
cache->objects[cache->nobjs++] = obj;
@@ -217,20 +225,35 @@ static void mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc)
kfree(mc->objects[--mc->nobjs]);
}
-static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu)
+static int __mmu_topup_memory_caches(struct kvm_vcpu *vcpu, gfp_t gfp_flags)
{
int r;
r = mmu_topup_memory_cache(&vcpu->mmu_pte_chain_cache,
- sizeof(struct kvm_pte_chain), 4);
+ pte_chain_cache, 4, gfp_flags);
if (r)
goto out;
r = mmu_topup_memory_cache(&vcpu->mmu_rmap_desc_cache,
- sizeof(struct kvm_rmap_desc), 1);
+ rmap_desc_cache, 1, gfp_flags);
out:
return r;
}
+static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu)
+{
+ int r;
+
+ r = __mmu_topup_memory_caches(vcpu, GFP_NOWAIT);
+ if (r < 0) {
+ spin_unlock(&vcpu->kvm->lock);
+ kvm_arch_ops->vcpu_put(vcpu);
+ r = __mmu_topup_memory_caches(vcpu, GFP_KERNEL);
+ kvm_arch_ops->vcpu_load(vcpu);
+ spin_lock(&vcpu->kvm->lock);
+ }
+ return r;
+}
+
static void mmu_free_memory_caches(struct kvm_vcpu *vcpu)
{
mmu_free_memory_cache(&vcpu->mmu_pte_chain_cache);
@@ -390,13 +413,11 @@ static void rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn)
{
struct kvm *kvm = vcpu->kvm;
struct page *page;
- struct kvm_memory_slot *slot;
struct kvm_rmap_desc *desc;
u64 *spte;
- slot = gfn_to_memslot(kvm, gfn);
- BUG_ON(!slot);
- page = gfn_to_page(slot, gfn);
+ page = gfn_to_page(kvm, gfn);
+ BUG_ON(!page);
while (page_private(page)) {
if (!(page_private(page) & 1))
@@ -417,6 +438,7 @@ static void rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn)
}
}
+#ifdef MMU_DEBUG
static int is_empty_shadow_page(hpa_t page_hpa)
{
u64 *pos;
@@ -431,15 +453,15 @@ static int is_empty_shadow_page(hpa_t page_hpa)
}
return 1;
}
+#endif
static void kvm_mmu_free_page(struct kvm_vcpu *vcpu, hpa_t page_hpa)
{
struct kvm_mmu_page *page_head = page_header(page_hpa);
ASSERT(is_empty_shadow_page(page_hpa));
- list_del(&page_head->link);
page_head->page_hpa = page_hpa;
- list_add(&page_head->link, &vcpu->free_pages);
+ list_move(&page_head->link, &vcpu->free_pages);
++vcpu->kvm->n_free_mmu_pages;
}
@@ -457,11 +479,9 @@ static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu,
return NULL;
page = list_entry(vcpu->free_pages.next, struct kvm_mmu_page, link);
- list_del(&page->link);
- list_add(&page->link, &vcpu->kvm->active_mmu_pages);
+ list_move(&page->link, &vcpu->kvm->active_mmu_pages);
ASSERT(is_empty_shadow_page(page->page_hpa));
page->slot_bitmap = 0;
- page->global = 1;
page->multimapped = 0;
page->parent_pte = parent_pte;
--vcpu->kvm->n_free_mmu_pages;
@@ -569,6 +589,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
gva_t gaddr,
unsigned level,
int metaphysical,
+ unsigned hugepage_access,
u64 *parent_pte)
{
union kvm_mmu_page_role role;
@@ -582,6 +603,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
role.glevels = vcpu->mmu.root_level;
role.level = level;
role.metaphysical = metaphysical;
+ role.hugepage_access = hugepage_access;
if (vcpu->mmu.root_level <= PT32_ROOT_LEVEL) {
quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level));
quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1;
@@ -669,10 +691,8 @@ static void kvm_mmu_zap_page(struct kvm_vcpu *vcpu,
if (!page->root_count) {
hlist_del(&page->hash_link);
kvm_mmu_free_page(vcpu, page->page_hpa);
- } else {
- list_del(&page->link);
- list_add(&page->link, &vcpu->kvm->active_mmu_pages);
- }
+ } else
+ list_move(&page->link, &vcpu->kvm->active_mmu_pages);
}
static int kvm_mmu_unprotect_page(struct kvm_vcpu *vcpu, gfn_t gfn)
@@ -714,14 +734,12 @@ hpa_t safe_gpa_to_hpa(struct kvm_vcpu *vcpu, gpa_t gpa)
hpa_t gpa_to_hpa(struct kvm_vcpu *vcpu, gpa_t gpa)
{
- struct kvm_memory_slot *slot;
struct page *page;
ASSERT((gpa & HPA_ERR_MASK) == 0);
- slot = gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT);
- if (!slot)
+ page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
+ if (!page)
return gpa | HPA_ERR_MASK;
- page = gfn_to_page(slot, gpa >> PAGE_SHIFT);
return ((hpa_t)page_to_pfn(page) << PAGE_SHIFT)
| (gpa & (PAGE_SIZE-1));
}
@@ -735,6 +753,15 @@ hpa_t gva_to_hpa(struct kvm_vcpu *vcpu, gva_t gva)
return gpa_to_hpa(vcpu, gpa);
}
+struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva)
+{
+ gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, gva);
+
+ if (gpa == UNMAPPED_GVA)
+ return NULL;
+ return pfn_to_page(gpa_to_hpa(vcpu, gpa) >> PAGE_SHIFT);
+}
+
static void nonpaging_new_cr3(struct kvm_vcpu *vcpu)
{
}
@@ -772,7 +799,7 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, hpa_t p)
>> PAGE_SHIFT;
new_table = kvm_mmu_get_page(vcpu, pseudo_gfn,
v, level - 1,
- 1, &table[index]);
+ 1, 0, &table[index]);
if (!new_table) {
pgprintk("nonpaging_map: ENOMEM\n");
return -ENOMEM;
@@ -804,10 +831,12 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu)
for (i = 0; i < 4; ++i) {
hpa_t root = vcpu->mmu.pae_root[i];
- ASSERT(VALID_PAGE(root));
- root &= PT64_BASE_ADDR_MASK;
- page = page_header(root);
- --page->root_count;
+ if (root) {
+ ASSERT(VALID_PAGE(root));
+ root &= PT64_BASE_ADDR_MASK;
+ page = page_header(root);
+ --page->root_count;
+ }
vcpu->mmu.pae_root[i] = INVALID_PAGE;
}
vcpu->mmu.root_hpa = INVALID_PAGE;
@@ -827,7 +856,7 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
ASSERT(!VALID_PAGE(root));
page = kvm_mmu_get_page(vcpu, root_gfn, 0,
- PT64_ROOT_LEVEL, 0, NULL);
+ PT64_ROOT_LEVEL, 0, 0, NULL);
root = page->page_hpa;
++page->root_count;
vcpu->mmu.root_hpa = root;
@@ -838,13 +867,17 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
hpa_t root = vcpu->mmu.pae_root[i];
ASSERT(!VALID_PAGE(root));
- if (vcpu->mmu.root_level == PT32E_ROOT_LEVEL)
+ if (vcpu->mmu.root_level == PT32E_ROOT_LEVEL) {
+ if (!is_present_pte(vcpu->pdptrs[i])) {
+ vcpu->mmu.pae_root[i] = 0;
+ continue;
+ }
root_gfn = vcpu->pdptrs[i] >> PAGE_SHIFT;
- else if (vcpu->mmu.root_level == 0)
+ } else if (vcpu->mmu.root_level == 0)
root_gfn = 0;
page = kvm_mmu_get_page(vcpu, root_gfn, i << 30,
PT32_ROOT_LEVEL, !is_paging(vcpu),
- NULL);
+ 0, NULL);
root = page->page_hpa;
++page->root_count;
vcpu->mmu.pae_root[i] = root | PT_PRESENT_MASK;
@@ -903,7 +936,7 @@ static int nonpaging_init_context(struct kvm_vcpu *vcpu)
static void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu)
{
- ++kvm_stat.tlb_flush;
+ ++vcpu->stat.tlb_flush;
kvm_arch_ops->tlb_flush(vcpu);
}
@@ -918,11 +951,6 @@ static void paging_new_cr3(struct kvm_vcpu *vcpu)
kvm_arch_ops->set_cr3(vcpu, vcpu->mmu.root_hpa);
}
-static void mark_pagetable_nonglobal(void *shadow_pte)
-{
- page_header(__pa(shadow_pte))->global = 0;
-}
-
static inline void set_pte_common(struct kvm_vcpu *vcpu,
u64 *shadow_pte,
gpa_t gaddr,
@@ -940,9 +968,6 @@ static inline void set_pte_common(struct kvm_vcpu *vcpu,
*shadow_pte |= access_bits;
- if (!(*shadow_pte & PT_GLOBAL_MASK))
- mark_pagetable_nonglobal(shadow_pte);
-
if (is_error_hpa(paddr)) {
*shadow_pte |= gaddr;
*shadow_pte |= PT_SHADOW_IO_MARK;
@@ -1316,6 +1341,51 @@ void kvm_mmu_slot_remove_write_access(struct kvm_vcpu *vcpu, int slot)
}
}
+void kvm_mmu_zap_all(struct kvm_vcpu *vcpu)
+{
+ destroy_kvm_mmu(vcpu);
+
+ while (!list_empty(&vcpu->kvm->active_mmu_pages)) {
+ struct kvm_mmu_page *page;
+
+ page = container_of(vcpu->kvm->active_mmu_pages.next,
+ struct kvm_mmu_page, link);
+ kvm_mmu_zap_page(vcpu, page);
+ }
+
+ mmu_free_memory_caches(vcpu);
+ kvm_arch_ops->tlb_flush(vcpu);
+ init_kvm_mmu(vcpu);
+}
+
+void kvm_mmu_module_exit(void)
+{
+ if (pte_chain_cache)
+ kmem_cache_destroy(pte_chain_cache);
+ if (rmap_desc_cache)
+ kmem_cache_destroy(rmap_desc_cache);
+}
+
+int kvm_mmu_module_init(void)
+{
+ pte_chain_cache = kmem_cache_create("kvm_pte_chain",
+ sizeof(struct kvm_pte_chain),
+ 0, 0, NULL, NULL);
+ if (!pte_chain_cache)
+ goto nomem;
+ rmap_desc_cache = kmem_cache_create("kvm_rmap_desc",
+ sizeof(struct kvm_rmap_desc),
+ 0, 0, NULL, NULL);
+ if (!rmap_desc_cache)
+ goto nomem;
+
+ return 0;
+
+nomem:
+ kvm_mmu_module_exit();
+ return -ENOMEM;
+}
+
#ifdef AUDIT
static const char *audit_msg;
@@ -1338,7 +1408,7 @@ static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte,
for (i = 0; i < PT64_ENT_PER_PAGE; ++i, va += va_delta) {
u64 ent = pt[i];
- if (!ent & PT_PRESENT_MASK)
+ if (!(ent & PT_PRESENT_MASK))
continue;
va = canonicalize(va);
@@ -1360,7 +1430,7 @@ static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte,
static void audit_mappings(struct kvm_vcpu *vcpu)
{
- int i;
+ unsigned i;
if (vcpu->mmu.root_level == 4)
audit_mappings_page(vcpu, vcpu->mmu.root_hpa, 0, 4);
diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h
index f3bcee9..73ffbff 100644
--- a/drivers/kvm/paging_tmpl.h
+++ b/drivers/kvm/paging_tmpl.h
@@ -148,8 +148,7 @@ static int FNAME(walk_addr)(struct guest_walker *walker,
break;
}
- if (walker->level != 3 || is_long_mode(vcpu))
- walker->inherited_ar &= walker->table[index];
+ walker->inherited_ar &= walker->table[index];
table_gfn = (*ptep & PT_BASE_ADDR_MASK) >> PAGE_SHIFT;
paddr = safe_gpa_to_hpa(vcpu, *ptep & PT_BASE_ADDR_MASK);
kunmap_atomic(walker->table, KM_USER0);
@@ -248,6 +247,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
u64 shadow_pte;
int metaphysical;
gfn_t table_gfn;
+ unsigned hugepage_access = 0;
if (is_present_pte(*shadow_ent) || is_io_pte(*shadow_ent)) {
if (level == PT_PAGE_TABLE_LEVEL)
@@ -277,6 +277,9 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
if (level - 1 == PT_PAGE_TABLE_LEVEL
&& walker->level == PT_DIRECTORY_LEVEL) {
metaphysical = 1;
+ hugepage_access = *guest_ent;
+ hugepage_access &= PT_USER_MASK | PT_WRITABLE_MASK;
+ hugepage_access >>= PT_WRITABLE_SHIFT;
table_gfn = (*guest_ent & PT_BASE_ADDR_MASK)
>> PAGE_SHIFT;
} else {
@@ -284,7 +287,8 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
table_gfn = walker->table_gfn[level - 2];
}
shadow_page = kvm_mmu_get_page(vcpu, table_gfn, addr, level-1,
- metaphysical, shadow_ent);
+ metaphysical, hugepage_access,
+ shadow_ent);
shadow_addr = shadow_page->page_hpa;
shadow_pte = shadow_addr | PT_PRESENT_MASK | PT_ACCESSED_MASK
| PT_WRITABLE_MASK | PT_USER_MASK;
@@ -444,7 +448,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
if (is_io_pte(*shadow_pte))
return 1;
- ++kvm_stat.pf_fixed;
+ ++vcpu->stat.pf_fixed;
kvm_mmu_audit(vcpu, "post page fault (fixed)");
return write_pt;
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 3d8ea7a..9c15f32 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -44,6 +44,10 @@ MODULE_LICENSE("GPL");
#define KVM_EFER_LMA (1 << 10)
#define KVM_EFER_LME (1 << 8)
+#define SVM_FEATURE_NPT (1 << 0)
+#define SVM_FEATURE_LBRV (1 << 1)
+#define SVM_DEATURE_SVML (1 << 2)
+
unsigned long iopm_base;
unsigned long msrpm_base;
@@ -59,15 +63,16 @@ struct kvm_ldttss_desc {
struct svm_cpu_data {
int cpu;
- uint64_t asid_generation;
- uint32_t max_asid;
- uint32_t next_asid;
+ u64 asid_generation;
+ u32 max_asid;
+ u32 next_asid;
struct kvm_ldttss_desc *tss_desc;
struct page *save_area;
};
static DEFINE_PER_CPU(struct svm_cpu_data *, svm_data);
+static uint32_t svm_features;
struct svm_init_data {
int cpu;
@@ -82,6 +87,11 @@ static u32 msrpm_ranges[] = {0, 0xc0000000, 0xc0010000};
#define MAX_INST_SIZE 15
+static inline u32 svm_has(u32 feat)
+{
+ return svm_features & feat;
+}
+
static unsigned get_addr_size(struct kvm_vcpu *vcpu)
{
struct vmcb_save_area *sa = &vcpu->svm->vmcb->save;
@@ -203,13 +213,6 @@ static void inject_ud(struct kvm_vcpu *vcpu)
UD_VECTOR;
}
-static void inject_db(struct kvm_vcpu *vcpu)
-{
- vcpu->svm->vmcb->control.event_inj = SVM_EVTINJ_VALID |
- SVM_EVTINJ_TYPE_EXEPT |
- DB_VECTOR;
-}
-
static int is_page_fault(uint32_t info)
{
info &= SVM_EVTINJ_VEC_MASK | SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID;
@@ -309,6 +312,7 @@ static void svm_hardware_enable(void *garbage)
svm_data->asid_generation = 1;
svm_data->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
svm_data->next_asid = svm_data->max_asid + 1;
+ svm_features = cpuid_edx(SVM_CPUID_FUNC);
asm volatile ( "sgdt %0" : "=m"(gdt_descr) );
gdt = (struct desc_struct *)gdt_descr.address;
@@ -459,7 +463,6 @@ static void init_vmcb(struct vmcb *vmcb)
{
struct vmcb_control_area *control = &vmcb->control;
struct vmcb_save_area *save = &vmcb->save;
- u64 tsc;
control->intercept_cr_read = INTERCEPT_CR0_MASK |
INTERCEPT_CR3_MASK |
@@ -511,12 +514,13 @@ static void init_vmcb(struct vmcb *vmcb)
(1ULL << INTERCEPT_VMSAVE) |
(1ULL << INTERCEPT_STGI) |
(1ULL << INTERCEPT_CLGI) |
- (1ULL << INTERCEPT_SKINIT);
+ (1ULL << INTERCEPT_SKINIT) |
+ (1ULL << INTERCEPT_MONITOR) |
+ (1ULL << INTERCEPT_MWAIT);
control->iopm_base_pa = iopm_base;
control->msrpm_base_pa = msrpm_base;
- rdtscll(tsc);
- control->tsc_offset = -tsc;
+ control->tsc_offset = 0;
control->int_ctl = V_INTR_MASKING_MASK;
init_seg(&save->es);
@@ -576,12 +580,15 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu)
vcpu->svm->vmcb = page_address(page);
memset(vcpu->svm->vmcb, 0, PAGE_SIZE);
vcpu->svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT;
- vcpu->svm->cr0 = 0x00000010;
vcpu->svm->asid_generation = 0;
memset(vcpu->svm->db_regs, 0, sizeof(vcpu->svm->db_regs));
init_vmcb(vcpu->svm->vmcb);
fx_init(vcpu);
+ vcpu->fpu_active = 1;
+ vcpu->apic_base = 0xfee00000 |
+ /*for vcpu 0*/ MSR_IA32_APICBASE_BSP |
+ MSR_IA32_APICBASE_ENABLE;
return 0;
@@ -602,11 +609,34 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu)
static void svm_vcpu_load(struct kvm_vcpu *vcpu)
{
- get_cpu();
+ int cpu, i;
+
+ cpu = get_cpu();
+ if (unlikely(cpu != vcpu->cpu)) {
+ u64 tsc_this, delta;
+
+ /*
+ * Make sure that the guest sees a monotonically
+ * increasing TSC.
+ */
+ rdtscll(tsc_this);
+ delta = vcpu->host_tsc - tsc_this;
+ vcpu->svm->vmcb->control.tsc_offset += delta;
+ vcpu->cpu = cpu;
+ }
+
+ for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
+ rdmsrl(host_save_user_msrs[i], vcpu->svm->host_user_msrs[i]);
}
static void svm_vcpu_put(struct kvm_vcpu *vcpu)
{
+ int i;
+
+ for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
+ wrmsrl(host_save_user_msrs[i], vcpu->svm->host_user_msrs[i]);
+
+ rdtscll(vcpu->host_tsc);
put_cpu();
}
@@ -714,7 +744,7 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
vcpu->svm->vmcb->save.gdtr.base = dt->base ;
}
-static void svm_decache_cr0_cr4_guest_bits(struct kvm_vcpu *vcpu)
+static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
{
}
@@ -733,9 +763,15 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
}
}
#endif
- vcpu->svm->cr0 = cr0;
- vcpu->svm->vmcb->save.cr0 = cr0 | CR0_PG_MASK | CR0_WP_MASK;
+ if ((vcpu->cr0 & CR0_TS_MASK) && !(cr0 & CR0_TS_MASK)) {
+ vcpu->svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
+ vcpu->fpu_active = 1;
+ }
+
vcpu->cr0 = cr0;
+ cr0 |= CR0_PG_MASK | CR0_WP_MASK;
+ cr0 &= ~(CR0_CD_MASK | CR0_NW_MASK);
+ vcpu->svm->vmcb->save.cr0 = cr0;
}
static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
@@ -785,18 +821,16 @@ static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg)
static void load_host_msrs(struct kvm_vcpu *vcpu)
{
- int i;
-
- for ( i = 0; i < NR_HOST_SAVE_MSRS; i++)
- wrmsrl(host_save_msrs[i], vcpu->svm->host_msrs[i]);
+#ifdef CONFIG_X86_64
+ wrmsrl(MSR_GS_BASE, vcpu->svm->host_gs_base);
+#endif
}
static void save_host_msrs(struct kvm_vcpu *vcpu)
{
- int i;
-
- for ( i = 0; i < NR_HOST_SAVE_MSRS; i++)
- rdmsrl(host_save_msrs[i], vcpu->svm->host_msrs[i]);
+#ifdef CONFIG_X86_64
+ rdmsrl(MSR_GS_BASE, vcpu->svm->host_gs_base);
+#endif
}
static void new_asid(struct kvm_vcpu *vcpu, struct svm_cpu_data *svm_data)
@@ -890,7 +924,7 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
case EMULATE_DONE:
return 1;
case EMULATE_DO_MMIO:
- ++kvm_stat.mmio_exits;
+ ++vcpu->stat.mmio_exits;
kvm_run->exit_reason = KVM_EXIT_MMIO;
return 0;
case EMULATE_FAIL:
@@ -904,6 +938,16 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
return 0;
}
+static int nm_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+ vcpu->svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
+ if (!(vcpu->cr0 & CR0_TS_MASK))
+ vcpu->svm->vmcb->save.cr0 &= ~CR0_TS_MASK;
+ vcpu->fpu_active = 1;
+
+ return 1;
+}
+
static int shutdown_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
/*
@@ -981,7 +1025,7 @@ static int io_get_override(struct kvm_vcpu *vcpu,
return 0;
}
-static unsigned long io_adress(struct kvm_vcpu *vcpu, int ins, u64 *address)
+static unsigned long io_adress(struct kvm_vcpu *vcpu, int ins, gva_t *address)
{
unsigned long addr_mask;
unsigned long *reg;
@@ -1025,38 +1069,38 @@ static unsigned long io_adress(struct kvm_vcpu *vcpu, int ins, u64 *address)
static int io_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
u32 io_info = vcpu->svm->vmcb->control.exit_info_1; //address size bug?
- int _in = io_info & SVM_IOIO_TYPE_MASK;
+ int size, down, in, string, rep;
+ unsigned port;
+ unsigned long count;
+ gva_t address = 0;
- ++kvm_stat.io_exits;
+ ++vcpu->stat.io_exits;
vcpu->svm->next_rip = vcpu->svm->vmcb->control.exit_info_2;
- kvm_run->exit_reason = KVM_EXIT_IO;
- kvm_run->io.port = io_info >> 16;
- kvm_run->io.direction = (_in) ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
- kvm_run->io.size = ((io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT);
- kvm_run->io.string = (io_info & SVM_IOIO_STR_MASK) != 0;
- kvm_run->io.rep = (io_info & SVM_IOIO_REP_MASK) != 0;
+ in = (io_info & SVM_IOIO_TYPE_MASK) != 0;
+ port = io_info >> 16;
+ size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT;
+ string = (io_info & SVM_IOIO_STR_MASK) != 0;
+ rep = (io_info & SVM_IOIO_REP_MASK) != 0;
+ count = 1;
+ down = (vcpu->svm->vmcb->save.rflags & X86_EFLAGS_DF) != 0;
- if (kvm_run->io.string) {
+ if (string) {
unsigned addr_mask;
- addr_mask = io_adress(vcpu, _in, &kvm_run->io.address);
+ addr_mask = io_adress(vcpu, in, &address);
if (!addr_mask) {
printk(KERN_DEBUG "%s: get io address failed\n",
__FUNCTION__);
return 1;
}
- if (kvm_run->io.rep) {
- kvm_run->io.count
- = vcpu->regs[VCPU_REGS_RCX] & addr_mask;
- kvm_run->io.string_down = (vcpu->svm->vmcb->save.rflags
- & X86_EFLAGS_DF) != 0;
- }
- } else
- kvm_run->io.value = vcpu->svm->vmcb->save.rax;
- return 0;
+ if (rep)
+ count = vcpu->regs[VCPU_REGS_RCX] & addr_mask;
+ }
+ return kvm_setup_pio(vcpu, kvm_run, in, size, count, string, down,
+ address, rep, port);
}
static int nop_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
@@ -1072,13 +1116,14 @@ static int halt_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
return 1;
kvm_run->exit_reason = KVM_EXIT_HLT;
- ++kvm_stat.halt_exits;
+ ++vcpu->stat.halt_exits;
return 0;
}
static int vmmcall_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
- vcpu->svm->vmcb->save.rip += 3;
+ vcpu->svm->next_rip = vcpu->svm->vmcb->save.rip + 3;
+ skip_emulated_instruction(vcpu);
return kvm_hypercall(vcpu, kvm_run);
}
@@ -1098,8 +1143,8 @@ static int task_switch_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_r
static int cpuid_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
vcpu->svm->next_rip = vcpu->svm->vmcb->save.rip + 2;
- kvm_run->exit_reason = KVM_EXIT_CPUID;
- return 0;
+ kvm_emulate_cpuid(vcpu);
+ return 1;
}
static int emulate_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
@@ -1239,7 +1284,7 @@ static int interrupt_window_interception(struct kvm_vcpu *vcpu,
*/
if (kvm_run->request_interrupt_window &&
!vcpu->irq_summary) {
- ++kvm_stat.irq_window_exits;
+ ++vcpu->stat.irq_window_exits;
kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
return 0;
}
@@ -1267,6 +1312,7 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu,
[SVM_EXIT_WRITE_DR5] = emulate_on_interception,
[SVM_EXIT_WRITE_DR7] = emulate_on_interception,
[SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception,
+ [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception,
[SVM_EXIT_INTR] = nop_on_interception,
[SVM_EXIT_NMI] = nop_on_interception,
[SVM_EXIT_SMI] = nop_on_interception,
@@ -1288,6 +1334,8 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu,
[SVM_EXIT_STGI] = invalid_op_interception,
[SVM_EXIT_CLGI] = invalid_op_interception,
[SVM_EXIT_SKINIT] = invalid_op_interception,
+ [SVM_EXIT_MONITOR] = invalid_op_interception,
+ [SVM_EXIT_MWAIT] = invalid_op_interception,
};
@@ -1295,8 +1343,6 @@ static int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
u32 exit_code = vcpu->svm->vmcb->control.exit_code;
- kvm_run->exit_type = KVM_EXIT_TYPE_VM_EXIT;
-
if (is_external_interrupt(vcpu->svm->vmcb->control.exit_int_info) &&
exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR)
printk(KERN_ERR "%s: unexpected exit_ini_info 0x%x "
@@ -1307,12 +1353,7 @@ static int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
if (exit_code >= ARRAY_SIZE(svm_exit_handlers)
|| svm_exit_handlers[exit_code] == 0) {
kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
- printk(KERN_ERR "%s: 0x%x @ 0x%llx cr0 0x%lx rflags 0x%llx\n",
- __FUNCTION__,
- exit_code,
- vcpu->svm->vmcb->save.rip,
- vcpu->cr0,
- vcpu->svm->vmcb->save.rflags);
+ kvm_run->hw.hardware_exit_reason = exit_code;
return 0;
}
@@ -1461,8 +1502,10 @@ again:
load_db_regs(vcpu->svm->db_regs);
}
- fx_save(vcpu->host_fx_image);
- fx_restore(vcpu->guest_fx_image);
+ if (vcpu->fpu_active) {
+ fx_save(vcpu->host_fx_image);
+ fx_restore(vcpu->guest_fx_image);
+ }
asm volatile (
#ifdef CONFIG_X86_64
@@ -1573,8 +1616,10 @@ again:
#endif
: "cc", "memory" );
- fx_save(vcpu->guest_fx_image);
- fx_restore(vcpu->host_fx_image);
+ if (vcpu->fpu_active) {
+ fx_save(vcpu->guest_fx_image);
+ fx_restore(vcpu->host_fx_image);
+ }
if ((vcpu->svm->vmcb->save.dr7 & 0xff))
load_db_regs(vcpu->svm->host_db_regs);
@@ -1606,8 +1651,9 @@ again:
vcpu->svm->next_rip = 0;
if (vcpu->svm->vmcb->control.exit_code == SVM_EXIT_ERR) {
- kvm_run->exit_type = KVM_EXIT_TYPE_FAIL_ENTRY;
- kvm_run->exit_reason = vcpu->svm->vmcb->control.exit_code;
+ kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+ kvm_run->fail_entry.hardware_entry_failure_reason
+ = vcpu->svm->vmcb->control.exit_code;
post_kvm_run_save(vcpu, kvm_run);
return 0;
}
@@ -1615,14 +1661,16 @@ again:
r = handle_exit(vcpu, kvm_run);
if (r > 0) {
if (signal_pending(current)) {
- ++kvm_stat.signal_exits;
+ ++vcpu->stat.signal_exits;
post_kvm_run_save(vcpu, kvm_run);
+ kvm_run->exit_reason = KVM_EXIT_INTR;
return -EINTR;
}
if (dm_request_for_irq_injection(vcpu, kvm_run)) {
- ++kvm_stat.request_irq_exits;
+ ++vcpu->stat.request_irq_exits;
post_kvm_run_save(vcpu, kvm_run);
+ kvm_run->exit_reason = KVM_EXIT_INTR;
return -EINTR;
}
kvm_resched(vcpu);
@@ -1641,6 +1689,12 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
{
vcpu->svm->vmcb->save.cr3 = root;
force_new_asid(vcpu);
+
+ if (vcpu->fpu_active) {
+ vcpu->svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR);
+ vcpu->svm->vmcb->save.cr0 |= CR0_TS_MASK;
+ vcpu->fpu_active = 0;
+ }
}
static void svm_inject_page_fault(struct kvm_vcpu *vcpu,
@@ -1649,7 +1703,7 @@ static void svm_inject_page_fault(struct kvm_vcpu *vcpu,
{
uint32_t exit_int_info = vcpu->svm->vmcb->control.exit_int_info;
- ++kvm_stat.pf_guest;
+ ++vcpu->stat.pf_guest;
if (is_page_fault(exit_int_info)) {
@@ -1709,9 +1763,8 @@ static struct kvm_arch_ops svm_arch_ops = {
.get_segment = svm_get_segment,
.set_segment = svm_set_segment,
.get_cs_db_l_bits = svm_get_cs_db_l_bits,
- .decache_cr0_cr4_guest_bits = svm_decache_cr0_cr4_guest_bits,
+ .decache_cr4_guest_bits = svm_decache_cr4_guest_bits,
.set_cr0 = svm_set_cr0,
- .set_cr0_no_modeswitch = svm_set_cr0,
.set_cr3 = svm_set_cr3,
.set_cr4 = svm_set_cr4,
.set_efer = svm_set_efer,
diff --git a/drivers/kvm/svm.h b/drivers/kvm/svm.h
index df731c3..5e93814 100644
--- a/drivers/kvm/svm.h
+++ b/drivers/kvm/svm.h
@@ -44,6 +44,9 @@ enum {
INTERCEPT_RDTSCP,
INTERCEPT_ICEBP,
INTERCEPT_WBINVD,
+ INTERCEPT_MONITOR,
+ INTERCEPT_MWAIT,
+ INTERCEPT_MWAIT_COND,
};
@@ -298,6 +301,9 @@ struct __attribute__ ((__packed__)) vmcb {
#define SVM_EXIT_RDTSCP 0x087
#define SVM_EXIT_ICEBP 0x088
#define SVM_EXIT_WBINVD 0x089
+#define SVM_EXIT_MONITOR 0x08a
+#define SVM_EXIT_MWAIT 0x08b
+#define SVM_EXIT_MWAIT_COND 0x08c
#define SVM_EXIT_NPF 0x400
#define SVM_EXIT_ERR -1
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index fbbf9d6..724db00 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -17,7 +17,6 @@
#include "kvm.h"
#include "vmx.h"
-#include "kvm_vmx.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
@@ -70,6 +69,10 @@ static struct kvm_vmx_segment_field {
VMX_SEGMENT_FIELD(LDTR),
};
+/*
+ * Keep MSR_K6_STAR at the end, as setup_msrs() will try to optimize it
+ * away by decrementing the array size.
+ */
static const u32 vmx_msr_index[] = {
#ifdef CONFIG_X86_64
MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR, MSR_KERNEL_GS_BASE,
@@ -78,6 +81,19 @@ static const u32 vmx_msr_index[] = {
};
#define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index)
+#ifdef CONFIG_X86_64
+static unsigned msr_offset_kernel_gs_base;
+#define NR_64BIT_MSRS 4
+/*
+ * avoid save/load MSR_SYSCALL_MASK and MSR_LSTAR by std vt
+ * mechanism (cpu bug AA24)
+ */
+#define NR_BAD_MSRS 2
+#else
+#define NR_64BIT_MSRS 0
+#define NR_BAD_MSRS 0
+#endif
+
static inline int is_page_fault(u32 intr_info)
{
return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
@@ -85,6 +101,13 @@ static inline int is_page_fault(u32 intr_info)
(INTR_TYPE_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK);
}
+static inline int is_no_device(u32 intr_info)
+{
+ return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
+ INTR_INFO_VALID_MASK)) ==
+ (INTR_TYPE_EXCEPTION | NM_VECTOR | INTR_INFO_VALID_MASK);
+}
+
static inline int is_external_interrupt(u32 intr_info)
{
return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK))
@@ -200,6 +223,16 @@ static void vmcs_write64(unsigned long field, u64 value)
#endif
}
+static void vmcs_clear_bits(unsigned long field, u32 mask)
+{
+ vmcs_writel(field, vmcs_readl(field) & ~mask);
+}
+
+static void vmcs_set_bits(unsigned long field, u32 mask)
+{
+ vmcs_writel(field, vmcs_readl(field) | mask);
+}
+
/*
* Switches to specified vcpu, until a matching vcpu_put(), but assumes
* vcpu mutex is already taken.
@@ -297,6 +330,44 @@ static void vmx_inject_gp(struct kvm_vcpu *vcpu, unsigned error_code)
}
/*
+ * Set up the vmcs to automatically save and restore system
+ * msrs. Don't touch the 64-bit msrs if the guest is in legacy
+ * mode, as fiddling with msrs is very expensive.
+ */
+static void setup_msrs(struct kvm_vcpu *vcpu)
+{
+ int nr_skip, nr_good_msrs;
+
+ if (is_long_mode(vcpu))
+ nr_skip = NR_BAD_MSRS;
+ else
+ nr_skip = NR_64BIT_MSRS;
+ nr_good_msrs = vcpu->nmsrs - nr_skip;
+
+ /*
+ * MSR_K6_STAR is only needed on long mode guests, and only
+ * if efer.sce is enabled.
+ */
+ if (find_msr_entry(vcpu, MSR_K6_STAR)) {
+ --nr_good_msrs;
+#ifdef CONFIG_X86_64
+ if (is_long_mode(vcpu) && (vcpu->shadow_efer & EFER_SCE))
+ ++nr_good_msrs;
+#endif
+ }
+
+ vmcs_writel(VM_ENTRY_MSR_LOAD_ADDR,
+ virt_to_phys(vcpu->guest_msrs + nr_skip));
+ vmcs_writel(VM_EXIT_MSR_STORE_ADDR,
+ virt_to_phys(vcpu->guest_msrs + nr_skip));
+ vmcs_writel(VM_EXIT_MSR_LOAD_ADDR,
+ virt_to_phys(vcpu->host_msrs + nr_skip));
+ vmcs_write32(VM_EXIT_MSR_STORE_COUNT, nr_good_msrs); /* 22.2.2 */
+ vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, nr_good_msrs); /* 22.2.2 */
+ vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, nr_good_msrs); /* 22.2.2 */
+}
+
+/*
* reads and returns guest's timestamp counter "register"
* guest_tsc = host_tsc + tsc_offset -- 21.3
*/
@@ -712,6 +783,8 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
vmcs_write32(GUEST_CS_AR_BYTES, 0xf3);
vmcs_write32(GUEST_CS_LIMIT, 0xffff);
+ if (vmcs_readl(GUEST_CS_BASE) == 0xffff0000)
+ vmcs_writel(GUEST_CS_BASE, 0xf0000);
vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4);
fix_rmode_seg(VCPU_SREG_ES, &vcpu->rmode.es);
@@ -754,11 +827,8 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
#endif
-static void vmx_decache_cr0_cr4_guest_bits(struct kvm_vcpu *vcpu)
+static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
{
- vcpu->cr0 &= KVM_GUEST_CR0_MASK;
- vcpu->cr0 |= vmcs_readl(GUEST_CR0) & ~KVM_GUEST_CR0_MASK;
-
vcpu->cr4 &= KVM_GUEST_CR4_MASK;
vcpu->cr4 |= vmcs_readl(GUEST_CR4) & ~KVM_GUEST_CR4_MASK;
}
@@ -780,22 +850,11 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
}
#endif
- vmcs_writel(CR0_READ_SHADOW, cr0);
- vmcs_writel(GUEST_CR0,
- (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON);
- vcpu->cr0 = cr0;
-}
-
-/*
- * Used when restoring the VM to avoid corrupting segment registers
- */
-static void vmx_set_cr0_no_modeswitch(struct kvm_vcpu *vcpu, unsigned long cr0)
-{
- if (!vcpu->rmode.active && !(cr0 & CR0_PE_MASK))
- enter_rmode(vcpu);
+ if (!(cr0 & CR0_TS_MASK)) {
+ vcpu->fpu_active = 1;
+ vmcs_clear_bits(EXCEPTION_BITMAP, CR0_TS_MASK);
+ }
- vcpu->rmode.active = ((cr0 & CR0_PE_MASK) == 0);
- update_exception_bitmap(vcpu);
vmcs_writel(CR0_READ_SHADOW, cr0);
vmcs_writel(GUEST_CR0,
(cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON);
@@ -805,6 +864,12 @@ static void vmx_set_cr0_no_modeswitch(struct kvm_vcpu *vcpu, unsigned long cr0)
static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
{
vmcs_writel(GUEST_CR3, cr3);
+
+ if (!(vcpu->cr0 & CR0_TS_MASK)) {
+ vcpu->fpu_active = 0;
+ vmcs_set_bits(GUEST_CR0, CR0_TS_MASK);
+ vmcs_set_bits(EXCEPTION_BITMAP, 1 << NM_VECTOR);
+ }
}
static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
@@ -835,6 +900,7 @@ static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
msr->data = efer & ~EFER_LME;
}
+ setup_msrs(vcpu);
}
#endif
@@ -878,7 +944,14 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu,
vmcs_writel(sf->base, var->base);
vmcs_write32(sf->limit, var->limit);
vmcs_write16(sf->selector, var->selector);
- if (var->unusable)
+ if (vcpu->rmode.active && var->s) {
+ /*
+ * Hack real-mode segments into vm86 compatibility.
+ */
+ if (var->base == 0xffff0000 && var->selector == 0xf000)
+ vmcs_writel(sf->base, 0xf0000);
+ ar = 0xf3;
+ } else if (var->unusable)
ar = 1 << 16;
else {
ar = var->type & 15;
@@ -933,9 +1006,9 @@ static int init_rmode_tss(struct kvm* kvm)
gfn_t fn = rmode_tss_base(kvm) >> PAGE_SHIFT;
char *page;
- p1 = _gfn_to_page(kvm, fn++);
- p2 = _gfn_to_page(kvm, fn++);
- p3 = _gfn_to_page(kvm, fn);
+ p1 = gfn_to_page(kvm, fn++);
+ p2 = gfn_to_page(kvm, fn++);
+ p3 = gfn_to_page(kvm, fn);
if (!p1 || !p2 || !p3) {
kvm_printf(kvm,"%s: gfn_to_page failed\n", __FUNCTION__);
@@ -991,7 +1064,6 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
struct descriptor_table dt;
int i;
int ret = 0;
- int nr_good_msrs;
extern asmlinkage void kvm_vmx_return(void);
if (!init_rmode_tss(vcpu->kvm)) {
@@ -1136,23 +1208,17 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
vcpu->host_msrs[j].reserved = 0;
vcpu->host_msrs[j].data = data;
vcpu->guest_msrs[j] = vcpu->host_msrs[j];
+#ifdef CONFIG_X86_64
+ if (index == MSR_KERNEL_GS_BASE)
+ msr_offset_kernel_gs_base = j;
+#endif
++vcpu->nmsrs;
}
- printk(KERN_DEBUG "kvm: msrs: %d\n", vcpu->nmsrs);
- nr_good_msrs = vcpu->nmsrs - NR_BAD_MSRS;
- vmcs_writel(VM_ENTRY_MSR_LOAD_ADDR,
- virt_to_phys(vcpu->guest_msrs + NR_BAD_MSRS));
- vmcs_writel(VM_EXIT_MSR_STORE_ADDR,
- virt_to_phys(vcpu->guest_msrs + NR_BAD_MSRS));
- vmcs_writel(VM_EXIT_MSR_LOAD_ADDR,
- virt_to_phys(vcpu->host_msrs + NR_BAD_MSRS));
+ setup_msrs(vcpu);
+
vmcs_write32_fixedbits(MSR_IA32_VMX_EXIT_CTLS, VM_EXIT_CONTROLS,
(HOST_IS_64 << 9)); /* 22.2,1, 20.7.1 */
- vmcs_write32(VM_EXIT_MSR_STORE_COUNT, nr_good_msrs); /* 22.2.2 */
- vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, nr_good_msrs); /* 22.2.2 */
- vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, nr_good_msrs); /* 22.2.2 */
-
/* 22.2.1, 20.8.1 */
vmcs_write32_fixedbits(MSR_IA32_VMX_ENTRY_CTLS,
@@ -1164,7 +1230,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu)
vmcs_writel(TPR_THRESHOLD, 0);
#endif
- vmcs_writel(CR0_GUEST_HOST_MASK, KVM_GUEST_CR0_MASK);
+ vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL);
vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK);
vcpu->cr0 = 0x60000010;
@@ -1190,7 +1256,7 @@ static void inject_rmode_irq(struct kvm_vcpu *vcpu, int irq)
u16 sp = vmcs_readl(GUEST_RSP);
u32 ss_limit = vmcs_read32(GUEST_SS_LIMIT);
- if (sp > ss_limit || sp - 6 > sp) {
+ if (sp > ss_limit || sp < 6 ) {
vcpu_printf(vcpu, "%s: #SS, rsp 0x%lx ss 0x%lx limit 0x%x\n",
__FUNCTION__,
vmcs_readl(GUEST_RSP),
@@ -1330,6 +1396,15 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
asm ("int $2");
return 1;
}
+
+ if (is_no_device(intr_info)) {
+ vcpu->fpu_active = 1;
+ vmcs_clear_bits(EXCEPTION_BITMAP, 1 << NM_VECTOR);
+ if (!(vcpu->cr0 & CR0_TS_MASK))
+ vmcs_clear_bits(GUEST_CR0, CR0_TS_MASK);
+ return 1;
+ }
+
error_code = 0;
rip = vmcs_readl(GUEST_RIP);
if (intr_info & INTR_INFO_DELIEVER_CODE_MASK)
@@ -1355,7 +1430,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
case EMULATE_DONE:
return 1;
case EMULATE_DO_MMIO:
- ++kvm_stat.mmio_exits;
+ ++vcpu->stat.mmio_exits;
kvm_run->exit_reason = KVM_EXIT_MMIO;
return 0;
case EMULATE_FAIL:
@@ -1384,7 +1459,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
static int handle_external_interrupt(struct kvm_vcpu *vcpu,
struct kvm_run *kvm_run)
{
- ++kvm_stat.irq_exits;
+ ++vcpu->stat.irq_exits;
return 1;
}
@@ -1394,7 +1469,7 @@ static int handle_triple_fault(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
return 0;
}
-static int get_io_count(struct kvm_vcpu *vcpu, u64 *count)
+static int get_io_count(struct kvm_vcpu *vcpu, unsigned long *count)
{
u64 inst;
gva_t rip;
@@ -1439,33 +1514,35 @@ static int get_io_count(struct kvm_vcpu *vcpu, u64 *count)
done:
countr_size *= 8;
*count = vcpu->regs[VCPU_REGS_RCX] & (~0ULL >> (64 - countr_size));
+ //printk("cx: %lx\n", vcpu->regs[VCPU_REGS_RCX]);
return 1;
}
static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
u64 exit_qualification;
+ int size, down, in, string, rep;
+ unsigned port;
+ unsigned long count;
+ gva_t address;
- ++kvm_stat.io_exits;
+ ++vcpu->stat.io_exits;
exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
- kvm_run->exit_reason = KVM_EXIT_IO;
- if (exit_qualification & 8)
- kvm_run->io.direction = KVM_EXIT_IO_IN;
- else
- kvm_run->io.direction = KVM_EXIT_IO_OUT;
- kvm_run->io.size = (exit_qualification & 7) + 1;
- kvm_run->io.string = (exit_qualification & 16) != 0;
- kvm_run->io.string_down
- = (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_DF) != 0;
- kvm_run->io.rep = (exit_qualification & 32) != 0;
- kvm_run->io.port = exit_qualification >> 16;
- if (kvm_run->io.string) {
- if (!get_io_count(vcpu, &kvm_run->io.count))
+ in = (exit_qualification & 8) != 0;
+ size = (exit_qualification & 7) + 1;
+ string = (exit_qualification & 16) != 0;
+ down = (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_DF) != 0;
+ count = 1;
+ rep = (exit_qualification & 32) != 0;
+ port = exit_qualification >> 16;
+ address = 0;
+ if (string) {
+ if (rep && !get_io_count(vcpu, &count))
return 1;
- kvm_run->io.address = vmcs_readl(GUEST_LINEAR_ADDRESS);
- } else
- kvm_run->io.value = vcpu->regs[VCPU_REGS_RAX]; /* rax */
- return 0;
+ address = vmcs_readl(GUEST_LINEAR_ADDRESS);
+ }
+ return kvm_setup_pio(vcpu, kvm_run, in, size, count, string, down,
+ address, rep, port);
}
static void
@@ -1514,6 +1591,15 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
return 1;
};
break;
+ case 2: /* clts */
+ vcpu_load_rsp_rip(vcpu);
+ vcpu->fpu_active = 1;
+ vmcs_clear_bits(EXCEPTION_BITMAP, 1 << NM_VECTOR);
+ vmcs_clear_bits(GUEST_CR0, CR0_TS_MASK);
+ vcpu->cr0 &= ~CR0_TS_MASK;
+ vmcs_writel(CR0_READ_SHADOW, vcpu->cr0);
+ skip_emulated_instruction(vcpu);
+ return 1;
case 1: /*mov from cr*/
switch (cr) {
case 3:
@@ -1523,8 +1609,6 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
skip_emulated_instruction(vcpu);
return 1;
case 8:
- printk(KERN_DEBUG "handle_cr: read CR8 "
- "cpu erratum AA15\n");
vcpu_load_rsp_rip(vcpu);
vcpu->regs[reg] = vcpu->cr8;
vcpu_put_rsp_rip(vcpu);
@@ -1583,8 +1667,8 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
static int handle_cpuid(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
- kvm_run->exit_reason = KVM_EXIT_CPUID;
- return 0;
+ kvm_emulate_cpuid(vcpu);
+ return 1;
}
static int handle_rdmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
@@ -1639,7 +1723,7 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu,
if (kvm_run->request_interrupt_window &&
!vcpu->irq_summary) {
kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
- ++kvm_stat.irq_window_exits;
+ ++vcpu->stat.irq_window_exits;
return 0;
}
return 1;
@@ -1652,13 +1736,13 @@ static int handle_halt(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
return 1;
kvm_run->exit_reason = KVM_EXIT_HLT;
- ++kvm_stat.halt_exits;
+ ++vcpu->stat.halt_exits;
return 0;
}
static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
- vmcs_writel(GUEST_RIP, vmcs_readl(GUEST_RIP)+3);
+ skip_emulated_instruction(vcpu);
return kvm_hypercall(vcpu, kvm_run);
}
@@ -1699,7 +1783,6 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
exit_reason != EXIT_REASON_EXCEPTION_NMI )
printk(KERN_WARNING "%s: unexpected, valid vectoring info and "
"exit reason is 0x%x\n", __FUNCTION__, exit_reason);
- kvm_run->instruction_length = vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
if (exit_reason < kvm_vmx_max_exit_handlers
&& kvm_vmx_exit_handlers[exit_reason])
return kvm_vmx_exit_handlers[exit_reason](vcpu, kvm_run);
@@ -1763,11 +1846,21 @@ again:
if (vcpu->guest_debug.enabled)
kvm_guest_debug_pre(vcpu);
- fx_save(vcpu->host_fx_image);
- fx_restore(vcpu->guest_fx_image);
+ if (vcpu->fpu_active) {
+ fx_save(vcpu->host_fx_image);
+ fx_restore(vcpu->guest_fx_image);
+ }
+ /*
+ * Loading guest fpu may have cleared host cr0.ts
+ */
+ vmcs_writel(HOST_CR0, read_cr0());
- save_msrs(vcpu->host_msrs, vcpu->nmsrs);
- load_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
+#ifdef CONFIG_X86_64
+ if (is_long_mode(vcpu)) {
+ save_msrs(vcpu->host_msrs + msr_offset_kernel_gs_base, 1);
+ load_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
+ }
+#endif
asm (
/* Store host registers */
@@ -1909,21 +2002,28 @@ again:
reload_tss();
}
- ++kvm_stat.exits;
+ ++vcpu->stat.exits;
- save_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
- load_msrs(vcpu->host_msrs, NR_BAD_MSRS);
+#ifdef CONFIG_X86_64
+ if (is_long_mode(vcpu)) {
+ save_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
+ load_msrs(vcpu->host_msrs, NR_BAD_MSRS);
+ }
+#endif
+
+ if (vcpu->fpu_active) {
+ fx_save(vcpu->guest_fx_image);
+ fx_restore(vcpu->host_fx_image);
+ }
- fx_save(vcpu->guest_fx_image);
- fx_restore(vcpu->host_fx_image);
vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
- kvm_run->exit_type = 0;
if (fail) {
- kvm_run->exit_type = KVM_EXIT_TYPE_FAIL_ENTRY;
- kvm_run->exit_reason = vmcs_read32(VM_INSTRUCTION_ERROR);
+ kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+ kvm_run->fail_entry.hardware_entry_failure_reason
+ = vmcs_read32(VM_INSTRUCTION_ERROR);
r = 0;
} else {
/*
@@ -1933,19 +2033,20 @@ again:
profile_hit(KVM_PROFILING, (void *)vmcs_readl(GUEST_RIP));
vcpu->launched = 1;
- kvm_run->exit_type = KVM_EXIT_TYPE_VM_EXIT;
r = kvm_handle_exit(kvm_run, vcpu);
if (r > 0) {
/* Give scheduler a change to reschedule. */
if (signal_pending(current)) {
- ++kvm_stat.signal_exits;
+ ++vcpu->stat.signal_exits;
post_kvm_run_save(vcpu, kvm_run);
+ kvm_run->exit_reason = KVM_EXIT_INTR;
return -EINTR;
}
if (dm_request_for_irq_injection(vcpu, kvm_run)) {
- ++kvm_stat.request_irq_exits;
+ ++vcpu->stat.request_irq_exits;
post_kvm_run_save(vcpu, kvm_run);
+ kvm_run->exit_reason = KVM_EXIT_INTR;
return -EINTR;
}
@@ -1969,7 +2070,7 @@ static void vmx_inject_page_fault(struct kvm_vcpu *vcpu,
{
u32 vect_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
- ++kvm_stat.pf_guest;
+ ++vcpu->stat.pf_guest;
if (is_page_fault(vect_info)) {
printk(KERN_DEBUG "inject_page_fault: "
@@ -2026,6 +2127,7 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu)
vmcs_clear(vmcs);
vcpu->vmcs = vmcs;
vcpu->launched = 0;
+ vcpu->fpu_active = 1;
return 0;
@@ -2062,9 +2164,8 @@ static struct kvm_arch_ops vmx_arch_ops = {
.get_segment = vmx_get_segment,
.set_segment = vmx_set_segment,
.get_cs_db_l_bits = vmx_get_cs_db_l_bits,
- .decache_cr0_cr4_guest_bits = vmx_decache_cr0_cr4_guest_bits,
+ .decache_cr4_guest_bits = vmx_decache_cr4_guest_bits,
.set_cr0 = vmx_set_cr0,
- .set_cr0_no_modeswitch = vmx_set_cr0_no_modeswitch,
.set_cr3 = vmx_set_cr3,
.set_cr4 = vmx_set_cr4,
#ifdef CONFIG_X86_64
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 7513cdd..7ade090 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -833,8 +833,9 @@ done_prefixes:
dst.ptr = (unsigned long *)cr2;
dst.bytes = (d & ByteOp) ? 1 : op_bytes;
if (d & BitOp) {
- dst.ptr += src.val / BITS_PER_LONG;
- dst.bytes = sizeof(long);
+ unsigned long mask = ~(dst.bytes * 8 - 1);
+
+ dst.ptr = (void *)dst.ptr + (src.val & mask) / 8;
}
if (!(d & Mov) && /* optimisation - avoid slow emulated read */
((rc = ops->read_emulated((unsigned long)dst.ptr,
@@ -1044,7 +1045,7 @@ done_prefixes:
if ((rc = ops->write_std(
register_address(ctxt->ss_base,
_regs[VCPU_REGS_RSP]),
- dst.val, dst.bytes, ctxt)) != 0)
+ &dst.val, dst.bytes, ctxt)) != 0)
goto done;
dst.val = dst.orig_val; /* skanky: disable writeback */
break;
@@ -1077,12 +1078,12 @@ writeback:
case OP_MEM:
if (lock_prefix)
rc = ops->cmpxchg_emulated((unsigned long)dst.
- ptr, dst.orig_val,
- dst.val, dst.bytes,
+ ptr, &dst.orig_val,
+ &dst.val, dst.bytes,
ctxt);
else
rc = ops->write_emulated((unsigned long)dst.ptr,
- dst.val, dst.bytes,
+ &dst.val, dst.bytes,
ctxt);
if (rc != 0)
goto done;
@@ -1320,36 +1321,8 @@ twobyte_special_insn:
realmode_set_cr(ctxt->vcpu, modrm_reg, modrm_val, &_eflags);
break;
case 0xc7: /* Grp9 (cmpxchg8b) */
-#if defined(__i386__)
- {
- unsigned long old_lo, old_hi;
- if (((rc = ops->read_emulated(cr2 + 0, &old_lo, 4,
- ctxt)) != 0)
- || ((rc = ops->read_emulated(cr2 + 4, &old_hi, 4,
- ctxt)) != 0))
- goto done;
- if ((old_lo != _regs[VCPU_REGS_RAX])
- || (old_hi != _regs[VCPU_REGS_RDX])) {
- _regs[VCPU_REGS_RAX] = old_lo;
- _regs[VCPU_REGS_RDX] = old_hi;
- _eflags &= ~EFLG_ZF;
- } else if (ops->cmpxchg8b_emulated == NULL) {
- rc = X86EMUL_UNHANDLEABLE;
- goto done;
- } else {
- if ((rc = ops->cmpxchg8b_emulated(cr2, old_lo,
- old_hi,
- _regs[VCPU_REGS_RBX],
- _regs[VCPU_REGS_RCX],
- ctxt)) != 0)
- goto done;
- _eflags |= EFLG_ZF;
- }
- break;
- }
-#elif defined(CONFIG_X86_64)
{
- unsigned long old, new;
+ u64 old, new;
if ((rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0)
goto done;
if (((u32) (old >> 0) != (u32) _regs[VCPU_REGS_RAX]) ||
@@ -1358,15 +1331,15 @@ twobyte_special_insn:
_regs[VCPU_REGS_RDX] = (u32) (old >> 32);
_eflags &= ~EFLG_ZF;
} else {
- new = (_regs[VCPU_REGS_RCX] << 32) | (u32) _regs[VCPU_REGS_RBX];
- if ((rc = ops->cmpxchg_emulated(cr2, old,
- new, 8, ctxt)) != 0)
+ new = ((u64)_regs[VCPU_REGS_RCX] << 32)
+ | (u32) _regs[VCPU_REGS_RBX];
+ if ((rc = ops->cmpxchg_emulated(cr2, &old,
+ &new, 8, ctxt)) != 0)
goto done;
_eflags |= EFLG_ZF;
}
break;
}
-#endif
}
goto writeback;
diff --git a/drivers/kvm/x86_emulate.h b/drivers/kvm/x86_emulate.h
index 5d41bd5..ea3407d 100644
--- a/drivers/kvm/x86_emulate.h
+++ b/drivers/kvm/x86_emulate.h
@@ -59,8 +59,7 @@ struct x86_emulate_ops {
* @val: [OUT] Value read from memory, zero-extended to 'u_long'.
* @bytes: [IN ] Number of bytes to read from memory.
*/
- int (*read_std)(unsigned long addr,
- unsigned long *val,
+ int (*read_std)(unsigned long addr, void *val,
unsigned int bytes, struct x86_emulate_ctxt * ctxt);
/*
@@ -71,8 +70,7 @@ struct x86_emulate_ops {
* required).
* @bytes: [IN ] Number of bytes to write to memory.
*/
- int (*write_std)(unsigned long addr,
- unsigned long val,
+ int (*write_std)(unsigned long addr, const void *val,
unsigned int bytes, struct x86_emulate_ctxt * ctxt);
/*
@@ -82,7 +80,7 @@ struct x86_emulate_ops {
* @bytes: [IN ] Number of bytes to read from memory.
*/
int (*read_emulated) (unsigned long addr,
- unsigned long *val,
+ void *val,
unsigned int bytes,
struct x86_emulate_ctxt * ctxt);
@@ -94,7 +92,7 @@ struct x86_emulate_ops {
* @bytes: [IN ] Number of bytes to write to memory.
*/
int (*write_emulated) (unsigned long addr,
- unsigned long val,
+ const void *val,
unsigned int bytes,
struct x86_emulate_ctxt * ctxt);
@@ -107,29 +105,11 @@ struct x86_emulate_ops {
* @bytes: [IN ] Number of bytes to access using CMPXCHG.
*/
int (*cmpxchg_emulated) (unsigned long addr,
- unsigned long old,
- unsigned long new,
+ const void *old,
+ const void *new,
unsigned int bytes,
struct x86_emulate_ctxt * ctxt);
- /*
- * cmpxchg8b_emulated: Emulate an atomic (LOCKed) CMPXCHG8B operation on an
- * emulated/special memory area.
- * @addr: [IN ] Linear address to access.
- * @old: [IN ] Value expected to be current at @addr.
- * @new: [IN ] Value to write to @addr.
- * NOTES:
- * 1. This function is only ever called when emulating a real CMPXCHG8B.
- * 2. This function is *never* called on x86/64 systems.
- * 2. Not defining this function (i.e., specifying NULL) is equivalent
- * to defining a function that always returns X86EMUL_UNHANDLEABLE.
- */
- int (*cmpxchg8b_emulated) (unsigned long addr,
- unsigned long old_lo,
- unsigned long old_hi,
- unsigned long new_lo,
- unsigned long new_hi,
- struct x86_emulate_ctxt * ctxt);
};
struct cpu_user_regs;
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 1a86387..a32c91e 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -1,6 +1,10 @@
-menu "Macintosh device drivers"
+menuconfig MACINTOSH_DRIVERS
+ bool "Macintosh device drivers"
depends on PPC || MAC || X86
+ default y
+
+if MACINTOSH_DRIVERS
config ADB
bool "Apple Desktop Bus (ADB) support"
@@ -109,7 +113,9 @@ config PMAC_SMU
config PMAC_APM_EMU
tristate "APM emulation"
- depends on PPC_PMAC && PPC32 && PM && ADB_PMU
+ select SYS_SUPPORTS_APM_EMULATION
+ select APM_EMULATION
+ depends on ADB_PMU && PM
config PMAC_MEDIABAY
bool "Support PowerBook hotswap media bay"
@@ -234,4 +240,4 @@ config PMAC_RACKMETER
This driver procides some support to control the front panel
blue LEDs "vu-meter" of the XServer macs.
-endmenu
+endif # MACINTOSH_DRIVERS
diff --git a/drivers/macintosh/apm_emu.c b/drivers/macintosh/apm_emu.c
index cdb0bea..9821e63 100644
--- a/drivers/macintosh/apm_emu.c
+++ b/drivers/macintosh/apm_emu.c
@@ -1,9 +1,7 @@
-/* APM emulation layer for PowerMac
- *
- * Copyright 2001 Benjamin Herrenschmidt (benh@kernel.crashing.org)
+/*
+ * APM emulation for PMU-based machines
*
- * Lots of code inherited from apm.c, see appropriate notice in
- * arch/i386/kernel/apm.c
+ * Copyright 2001 Benjamin Herrenschmidt (benh@kernel.crashing.org)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -18,429 +16,39 @@
*
*/
-#include <linux/module.h>
-
-#include <linux/poll.h>
-#include <linux/types.h>
-#include <linux/stddef.h>
-#include <linux/timer.h>
-#include <linux/fcntl.h>
-#include <linux/slab.h>
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-#include <linux/miscdevice.h>
-#include <linux/apm_bios.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/pm.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
-
+#include <linux/module.h>
+#include <linux/apm-emulation.h>
#include <linux/adb.h>
#include <linux/pmu.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/machdep.h>
-
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(args...) printk(KERN_DEBUG args)
-//#define DBG(args...) xmon_printf(args)
-#else
-#define DBG(args...) do { } while (0)
-#endif
-
-/*
- * The apm_bios device is one of the misc char devices.
- * This is its minor number.
- */
-#define APM_MINOR_DEV 134
-
-/*
- * Maximum number of events stored
- */
-#define APM_MAX_EVENTS 20
-
-#define FAKE_APM_BIOS_VERSION 0x0101
-
-#define APM_USER_NOTIFY_TIMEOUT (5*HZ)
-
-/*
- * The per-file APM data
- */
-struct apm_user {
- int magic;
- struct apm_user * next;
- int suser: 1;
- int suspend_waiting: 1;
- int suspends_pending;
- int suspends_read;
- int event_head;
- int event_tail;
- apm_event_t events[APM_MAX_EVENTS];
-};
-
-/*
- * The magic number in apm_user
- */
-#define APM_BIOS_MAGIC 0x4101
-
-/*
- * Local variables
- */
-static int suspends_pending;
-
-static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
-static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
-static struct apm_user * user_list;
-
-static void apm_notify_sleep(struct pmu_sleep_notifier *self, int when);
-static struct pmu_sleep_notifier apm_sleep_notifier = {
- apm_notify_sleep,
- SLEEP_LEVEL_USERLAND,
-};
-
-static const char driver_version[] = "0.5"; /* no spaces */
-
-#ifdef DEBUG
-static char * apm_event_name[] = {
- "system standby",
- "system suspend",
- "normal resume",
- "critical resume",
- "low battery",
- "power status change",
- "update time",
- "critical suspend",
- "user standby",
- "user suspend",
- "system standby resume",
- "capabilities change"
-};
-#define NR_APM_EVENT_NAME \
- (sizeof(apm_event_name) / sizeof(apm_event_name[0]))
-
-#endif
-
-static int queue_empty(struct apm_user *as)
-{
- return as->event_head == as->event_tail;
-}
-
-static apm_event_t get_queued_event(struct apm_user *as)
-{
- as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
- return as->events[as->event_tail];
-}
-
-static void queue_event(apm_event_t event, struct apm_user *sender)
-{
- struct apm_user * as;
-
- DBG("apm_emu: queue_event(%s)\n", apm_event_name[event-1]);
- if (user_list == NULL)
- return;
- for (as = user_list; as != NULL; as = as->next) {
- if (as == sender)
- continue;
- as->event_head = (as->event_head + 1) % APM_MAX_EVENTS;
- if (as->event_head == as->event_tail) {
- static int notified;
-
- if (notified++ == 0)
- printk(KERN_ERR "apm_emu: an event queue overflowed\n");
- as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
- }
- as->events[as->event_head] = event;
- if (!as->suser)
- continue;
- switch (event) {
- case APM_SYS_SUSPEND:
- case APM_USER_SUSPEND:
- as->suspends_pending++;
- suspends_pending++;
- break;
- case APM_NORMAL_RESUME:
- as->suspend_waiting = 0;
- break;
- }
- }
- wake_up_interruptible(&apm_waitqueue);
-}
-
-static int check_apm_user(struct apm_user *as, const char *func)
-{
- if ((as == NULL) || (as->magic != APM_BIOS_MAGIC)) {
- printk(KERN_ERR "apm_emu: %s passed bad filp\n", func);
- return 1;
- }
- return 0;
-}
-
-static ssize_t do_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
-{
- struct apm_user * as;
- size_t i;
- apm_event_t event;
- DECLARE_WAITQUEUE(wait, current);
-
- as = fp->private_data;
- if (check_apm_user(as, "read"))
- return -EIO;
- if (count < sizeof(apm_event_t))
- return -EINVAL;
- if (queue_empty(as)) {
- if (fp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- add_wait_queue(&apm_waitqueue, &wait);
-repeat:
- set_current_state(TASK_INTERRUPTIBLE);
- if (queue_empty(as) && !signal_pending(current)) {
- schedule();
- goto repeat;
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&apm_waitqueue, &wait);
- }
- i = count;
- while ((i >= sizeof(event)) && !queue_empty(as)) {
- event = get_queued_event(as);
- DBG("apm_emu: do_read, returning: %s\n", apm_event_name[event-1]);
- if (copy_to_user(buf, &event, sizeof(event))) {
- if (i < count)
- break;
- return -EFAULT;
- }
- switch (event) {
- case APM_SYS_SUSPEND:
- case APM_USER_SUSPEND:
- as->suspends_read++;
- break;
- }
- buf += sizeof(event);
- i -= sizeof(event);
- }
- if (i < count)
- return count - i;
- if (signal_pending(current))
- return -ERESTARTSYS;
- return 0;
-}
-
-static unsigned int do_poll(struct file *fp, poll_table * wait)
-{
- struct apm_user * as;
-
- as = fp->private_data;
- if (check_apm_user(as, "poll"))
- return 0;
- poll_wait(fp, &apm_waitqueue, wait);
- if (!queue_empty(as))
- return POLLIN | POLLRDNORM;
- return 0;
-}
-
-static int do_ioctl(struct inode * inode, struct file *filp,
- u_int cmd, u_long arg)
-{
- struct apm_user * as;
- DECLARE_WAITQUEUE(wait, current);
-
- as = filp->private_data;
- if (check_apm_user(as, "ioctl"))
- return -EIO;
- if (!as->suser)
- return -EPERM;
- switch (cmd) {
- case APM_IOC_SUSPEND:
- /* If a suspend message was sent to userland, we
- * consider this as a confirmation message
- */
- if (as->suspends_read > 0) {
- as->suspends_read--;
- as->suspends_pending--;
- suspends_pending--;
- } else {
- // Route to PMU suspend ?
- break;
- }
- as->suspend_waiting = 1;
- add_wait_queue(&apm_waitqueue, &wait);
- DBG("apm_emu: ioctl waking up sleep waiter !\n");
- wake_up(&apm_suspend_waitqueue);
- mb();
- while(as->suspend_waiting && !signal_pending(current)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&apm_waitqueue, &wait);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int do_release(struct inode * inode, struct file * filp)
-{
- struct apm_user * as;
-
- as = filp->private_data;
- if (check_apm_user(as, "release"))
- return 0;
- filp->private_data = NULL;
- lock_kernel();
- if (as->suspends_pending > 0) {
- suspends_pending -= as->suspends_pending;
- if (suspends_pending <= 0)
- wake_up(&apm_suspend_waitqueue);
- }
- if (user_list == as)
- user_list = as->next;
- else {
- struct apm_user * as1;
-
- for (as1 = user_list;
- (as1 != NULL) && (as1->next != as);
- as1 = as1->next)
- ;
- if (as1 == NULL)
- printk(KERN_ERR "apm: filp not in user list\n");
- else
- as1->next = as->next;
- }
- unlock_kernel();
- kfree(as);
- return 0;
-}
-
-static int do_open(struct inode * inode, struct file * filp)
-{
- struct apm_user * as;
-
- as = kmalloc(sizeof(*as), GFP_KERNEL);
- if (as == NULL) {
- printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
- sizeof(*as));
- return -ENOMEM;
- }
- as->magic = APM_BIOS_MAGIC;
- as->event_tail = as->event_head = 0;
- as->suspends_pending = 0;
- as->suspends_read = 0;
- /*
- * XXX - this is a tiny bit broken, when we consider BSD
- * process accounting. If the device is opened by root, we
- * instantly flag that we used superuser privs. Who knows,
- * we might close the device immediately without doing a
- * privileged operation -- cevans
- */
- as->suser = capable(CAP_SYS_ADMIN);
- as->next = user_list;
- user_list = as;
- filp->private_data = as;
-
- DBG("apm_emu: opened by %s, suser: %d\n", current->comm, (int)as->suser);
-
- return 0;
-}
-
-/* Wait for all clients to ack the suspend request. APM API
- * doesn't provide a way to NAK, but this could be added
- * here.
- */
-static void wait_all_suspend(void)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(&apm_suspend_waitqueue, &wait);
- DBG("apm_emu: wait_all_suspend(), suspends_pending: %d\n", suspends_pending);
- while(suspends_pending > 0) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule();
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&apm_suspend_waitqueue, &wait);
-
- DBG("apm_emu: wait_all_suspend() - complete !\n");
-}
-
-static void apm_notify_sleep(struct pmu_sleep_notifier *self, int when)
-{
- switch(when) {
- case PBOOK_SLEEP_REQUEST:
- queue_event(APM_SYS_SUSPEND, NULL);
- wait_all_suspend();
- break;
- case PBOOK_WAKE:
- queue_event(APM_NORMAL_RESUME, NULL);
- break;
- }
-}
-
#define APM_CRITICAL 10
#define APM_LOW 30
-static int apm_emu_get_info(char *buf, char **start, off_t fpos, int length)
+static void pmu_apm_get_power_status(struct apm_power_info *info)
{
- /* Arguments, with symbols from linux/apm_bios.h. Information is
- from the Get Power Status (0x0a) call unless otherwise noted.
+ int percentage = -1;
+ int batteries = 0;
+ int time_units = -1;
+ int real_count = 0;
+ int i;
+ char charging = 0;
+ long charge = -1;
+ long amperage = 0;
+ unsigned long btype = 0;
+
+ info->battery_status = APM_BATTERY_STATUS_UNKNOWN;
+ info->battery_flag = APM_BATTERY_FLAG_UNKNOWN;
+ info->units = APM_UNITS_MINS;
+
+ if (pmu_power_flags & PMU_PWR_AC_PRESENT)
+ info->ac_line_status = APM_AC_ONLINE;
+ else
+ info->ac_line_status = APM_AC_OFFLINE;
- 0) Linux driver version (this will change if format changes)
- 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2.
- 2) APM flags from APM Installation Check (0x00):
- bit 0: APM_16_BIT_SUPPORT
- bit 1: APM_32_BIT_SUPPORT
- bit 2: APM_IDLE_SLOWS_CLOCK
- bit 3: APM_BIOS_DISABLED
- bit 4: APM_BIOS_DISENGAGED
- 3) AC line status
- 0x00: Off-line
- 0x01: On-line
- 0x02: On backup power (BIOS >= 1.1 only)
- 0xff: Unknown
- 4) Battery status
- 0x00: High
- 0x01: Low
- 0x02: Critical
- 0x03: Charging
- 0x04: Selected battery not present (BIOS >= 1.2 only)
- 0xff: Unknown
- 5) Battery flag
- bit 0: High
- bit 1: Low
- bit 2: Critical
- bit 3: Charging
- bit 7: No system battery
- 0xff: Unknown
- 6) Remaining battery life (percentage of charge):
- 0-100: valid
- -1: Unknown
- 7) Remaining battery life (time units):
- Number of remaining minutes or seconds
- -1: Unknown
- 8) min = minutes; sec = seconds */
-
- unsigned short ac_line_status;
- unsigned short battery_status = 0;
- unsigned short battery_flag = 0xff;
- int percentage = -1;
- int time_units = -1;
- int real_count = 0;
- int i;
- char * p = buf;
- char charging = 0;
- long charge = -1;
- long amperage = 0;
- unsigned long btype = 0;
-
- ac_line_status = ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0);
for (i=0; i<pmu_battery_count; i++) {
if (pmu_batteries[i].flags & PMU_BATT_PRESENT) {
- battery_status++;
+ batteries++;
if (percentage < 0)
percentage = 0;
if (charge < 0)
@@ -456,9 +64,9 @@ static int apm_emu_get_info(char *buf, char **start, off_t fpos, int length)
charging++;
}
}
- if (0 == battery_status)
- ac_line_status = 1;
- battery_status = 0xff;
+ if (batteries == 0)
+ info->ac_line_status = APM_AC_ONLINE;
+
if (real_count) {
if (amperage < 0) {
if (btype == PMU_BATT_TYPE_SMART)
@@ -468,85 +76,44 @@ static int apm_emu_get_info(char *buf, char **start, off_t fpos, int length)
}
percentage /= real_count;
if (charging > 0) {
- battery_status = 0x03;
- battery_flag = 0x08;
+ info->battery_status = APM_BATTERY_STATUS_CHARGING;
+ info->battery_flag = APM_BATTERY_FLAG_CHARGING;
} else if (percentage <= APM_CRITICAL) {
- battery_status = 0x02;
- battery_flag = 0x04;
+ info->battery_status = APM_BATTERY_STATUS_CRITICAL;
+ info->battery_flag = APM_BATTERY_FLAG_CRITICAL;
} else if (percentage <= APM_LOW) {
- battery_status = 0x01;
- battery_flag = 0x02;
+ info->battery_status = APM_BATTERY_STATUS_LOW;
+ info->battery_flag = APM_BATTERY_FLAG_LOW;
} else {
- battery_status = 0x00;
- battery_flag = 0x01;
+ info->battery_status = APM_BATTERY_STATUS_HIGH;
+ info->battery_flag = APM_BATTERY_FLAG_HIGH;
}
}
- p += sprintf(p, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
- driver_version,
- (FAKE_APM_BIOS_VERSION >> 8) & 0xff,
- FAKE_APM_BIOS_VERSION & 0xff,
- 0,
- ac_line_status,
- battery_status,
- battery_flag,
- percentage,
- time_units,
- "min");
- return p - buf;
+ info->battery_life = percentage;
+ info->time = time_units;
}
-static const struct file_operations apm_bios_fops = {
- .owner = THIS_MODULE,
- .read = do_read,
- .poll = do_poll,
- .ioctl = do_ioctl,
- .open = do_open,
- .release = do_release,
-};
-
-static struct miscdevice apm_device = {
- APM_MINOR_DEV,
- "apm_bios",
- &apm_bios_fops
-};
-
static int __init apm_emu_init(void)
{
- struct proc_dir_entry *apm_proc;
-
- if (sys_ctrler != SYS_CTRLER_PMU) {
- printk(KERN_INFO "apm_emu: Requires a machine with a PMU.\n");
- return -ENODEV;
- }
-
- apm_proc = create_proc_info_entry("apm", 0, NULL, apm_emu_get_info);
- if (apm_proc)
- apm_proc->owner = THIS_MODULE;
+ apm_get_power_status = pmu_apm_get_power_status;
- if (misc_register(&apm_device) != 0)
- printk(KERN_INFO "Could not create misc. device for apm\n");
-
- pmu_register_sleep_notifier(&apm_sleep_notifier);
-
- printk(KERN_INFO "apm_emu: APM Emulation %s initialized.\n", driver_version);
+ printk(KERN_INFO "apm_emu: PMU APM Emulation initialized.\n");
return 0;
}
static void __exit apm_emu_exit(void)
{
- pmu_unregister_sleep_notifier(&apm_sleep_notifier);
- misc_deregister(&apm_device);
- remove_proc_entry("apm", NULL);
+ if (apm_get_power_status == pmu_apm_get_power_status)
+ apm_get_power_status = NULL;
- printk(KERN_INFO "apm_emu: APM Emulation removed.\n");
+ printk(KERN_INFO "apm_emu: PMU APM Emulation removed.\n");
}
module_init(apm_emu_init);
module_exit(apm_emu_exit);
MODULE_AUTHOR("Benjamin Herrenschmidt");
-MODULE_DESCRIPTION("APM emulation layer for PowerMac");
+MODULE_DESCRIPTION("APM emulation for PowerMac");
MODULE_LICENSE("GPL");
-
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
index 1599dc3..76c1e8e 100644
--- a/drivers/macintosh/mac_hid.c
+++ b/drivers/macintosh/mac_hid.c
@@ -24,7 +24,7 @@ static int mouse_last_keycode;
#if defined(CONFIG_SYSCTL)
/* file(s) in /proc/sys/dev/mac_hid */
-ctl_table mac_hid_files[] = {
+static ctl_table mac_hid_files[] = {
{
.ctl_name = DEV_MAC_HID_MOUSE_BUTTON_EMULATION,
.procname = "mouse_button_emulation",
@@ -53,7 +53,7 @@ ctl_table mac_hid_files[] = {
};
/* dir in /proc/sys/dev */
-ctl_table mac_hid_dir[] = {
+static ctl_table mac_hid_dir[] = {
{
.ctl_name = DEV_MAC_HID,
.procname = "mac_hid",
@@ -65,7 +65,7 @@ ctl_table mac_hid_dir[] = {
};
/* /proc/sys/dev itself, in case that is not there yet */
-ctl_table mac_hid_root_dir[] = {
+static ctl_table mac_hid_root_dir[] = {
{
.ctl_name = CTL_DEV,
.procname = "dev",
@@ -127,7 +127,7 @@ static int emumousebtn_input_register(void)
return ret;
}
-int __init mac_hid_init(void)
+static int __init mac_hid_init(void)
{
int err;
diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c
index cc82679..112e5ef 100644
--- a/drivers/macintosh/macio_sysfs.c
+++ b/drivers/macintosh/macio_sysfs.c
@@ -41,28 +41,15 @@ compatible_show (struct device *dev, struct device_attribute *attr, char *buf)
static ssize_t modalias_show (struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct of_device *of;
- const char *compat;
- int cplen;
- int length;
+ struct of_device *ofdev = to_of_device(dev);
+ int len;
- of = &to_macio_device (dev)->ofdev;
- compat = of_get_property(of->node, "compatible", &cplen);
- if (!compat) compat = "", cplen = 1;
- length = sprintf (buf, "of:N%sT%s", of->node->name, of->node->type);
- buf += length;
- while (cplen > 0) {
- int l;
- l = sprintf (buf, "C%s", compat);
- length += l;
- buf += l;
- l = strlen (compat) + 1;
- compat += l;
- cplen -= l;
- }
- length += sprintf(buf, "\n");
+ len = of_device_get_modalias(ofdev, buf, PAGE_SIZE);
- return length;
+ buf[len] = '\n';
+ buf[len+1] = 0;
+
+ return len+1;
}
macio_config_of_attr (name, "%s\n");
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index a98a328..f8e1a13 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -606,7 +606,7 @@ static void smu_expose_childs(struct work_struct *unused)
struct device_node *np;
for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;)
- if (device_is_compatible(np, "smu-sensors"))
+ if (of_device_is_compatible(np, "smu-sensors"))
of_platform_device_create(np, "smu-sensors",
&smu->of_dev->dev);
}
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 2289034..bd55e6a 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -19,7 +19,6 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/wait.h>
#include <linux/suspend.h>
#include <linux/kthread.h>
@@ -560,9 +559,9 @@ thermostat_init(void)
np = of_find_node_by_name(NULL, "fan");
if (!np)
return -ENODEV;
- if (device_is_compatible(np, "adt7460"))
+ if (of_device_is_compatible(np, "adt7460"))
therm_type = ADT7460;
- else if (device_is_compatible(np, "adt7467"))
+ else if (of_device_is_compatible(np, "adt7467"))
therm_type = ADT7467;
else
return -ENODEV;
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 78ff186..dbb2240 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -117,7 +117,6 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/wait.h>
#include <linux/reboot.h>
#include <linux/kmod.h>
diff --git a/drivers/macintosh/via-pmu-led.c b/drivers/macintosh/via-pmu-led.c
index fc89a70..55ad956 100644
--- a/drivers/macintosh/via-pmu-led.c
+++ b/drivers/macintosh/via-pmu-led.c
@@ -31,7 +31,6 @@ static spinlock_t pmu_blink_lock;
static struct adb_request pmu_blink_req;
/* -1: no change, 0: request off, 1: request on */
static int requested_change;
-static int sleeping;
static void pmu_req_done(struct adb_request * req)
{
@@ -41,7 +40,7 @@ static void pmu_req_done(struct adb_request * req)
/* if someone requested a change in the meantime
* (we only see the last one which is fine)
* then apply it now */
- if (requested_change != -1 && !sleeping)
+ if (requested_change != -1 && !pmu_sys_suspended)
pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change);
/* reset requested change */
requested_change = -1;
@@ -66,7 +65,7 @@ static void pmu_led_set(struct led_classdev *led_cdev,
break;
}
/* if request isn't done, then don't do anything */
- if (pmu_blink_req.complete && !sleeping)
+ if (pmu_blink_req.complete && !pmu_sys_suspended)
pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change);
out:
spin_unlock_irqrestore(&pmu_blink_lock, flags);
@@ -80,32 +79,6 @@ static struct led_classdev pmu_led = {
.brightness_set = pmu_led_set,
};
-#ifdef CONFIG_PM
-static void pmu_led_sleep_call(struct pmu_sleep_notifier *self, int when)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&pmu_blink_lock, flags);
-
- switch (when) {
- case PBOOK_SLEEP_REQUEST:
- sleeping = 1;
- break;
- case PBOOK_WAKE:
- sleeping = 0;
- break;
- default:
- /* do nothing */
- break;
- }
- spin_unlock_irqrestore(&pmu_blink_lock, flags);
-}
-
-static struct pmu_sleep_notifier via_pmu_led_sleep_notif = {
- .notifier_call = pmu_led_sleep_call,
-};
-#endif
-
static int __init via_pmu_led_init(void)
{
struct device_node *dt;
@@ -135,9 +108,7 @@ static int __init via_pmu_led_init(void)
/* no outstanding req */
pmu_blink_req.complete = 1;
pmu_blink_req.done = pmu_req_done;
-#ifdef CONFIG_PM
- pmu_register_sleep_notifier(&via_pmu_led_sleep_notif);
-#endif
+
return led_classdev_register(NULL, &pmu_led);
}
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 1729d3f..157080b 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -310,14 +310,14 @@ int __init find_via_pmu(void)
PMU_INT_TICK;
if (vias->parent->name && ((strcmp(vias->parent->name, "ohare") == 0)
- || device_is_compatible(vias->parent, "ohare")))
+ || of_device_is_compatible(vias->parent, "ohare")))
pmu_kind = PMU_OHARE_BASED;
- else if (device_is_compatible(vias->parent, "paddington"))
+ else if (of_device_is_compatible(vias->parent, "paddington"))
pmu_kind = PMU_PADDINGTON_BASED;
- else if (device_is_compatible(vias->parent, "heathrow"))
+ else if (of_device_is_compatible(vias->parent, "heathrow"))
pmu_kind = PMU_HEATHROW_BASED;
- else if (device_is_compatible(vias->parent, "Keylargo")
- || device_is_compatible(vias->parent, "K2-Keylargo")) {
+ else if (of_device_is_compatible(vias->parent, "Keylargo")
+ || of_device_is_compatible(vias->parent, "K2-Keylargo")) {
struct device_node *gpiop;
struct device_node *adbp;
u64 gaddr = OF_BAD_ADDR;
@@ -2759,7 +2759,7 @@ pmu_polled_request(struct adb_request *req)
#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
-static int pmu_sys_suspended;
+int pmu_sys_suspended;
static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state)
{
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index 94c117e..192b26e 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -27,7 +27,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/kthread.h>
#include <linux/jiffies.h>
#include <linux/reboot.h>
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index ab4d1b6..a0fabf3 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -188,10 +188,10 @@ static int wf_lm75_attach(struct i2c_adapter *adapter)
if (loc == NULL || addr == 0)
continue;
/* real lm75 */
- if (device_is_compatible(dev, "lm75"))
+ if (of_device_is_compatible(dev, "lm75"))
wf_lm75_create(adapter, addr, 0, loc);
/* ds1775 (compatible, better resolution */
- else if (device_is_compatible(dev, "ds1775"))
+ else if (of_device_is_compatible(dev, "ds1775"))
wf_lm75_create(adapter, addr, 1, loc);
}
return 0;
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
index eaa74af..5f03aab 100644
--- a/drivers/macintosh/windfarm_max6690_sensor.c
+++ b/drivers/macintosh/windfarm_max6690_sensor.c
@@ -131,7 +131,7 @@ static int wf_max6690_attach(struct i2c_adapter *adapter)
*/
if (!pmac_i2c_match_adapter(dev, adapter))
continue;
- if (!device_is_compatible(dev, "max6690"))
+ if (!of_device_is_compatible(dev, "max6690"))
continue;
addr = pmac_i2c_get_dev_addr(dev);
loc = of_get_property(dev, "hwsensor-location", NULL);
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
index ff398ad..58c2590 100644
--- a/drivers/macintosh/windfarm_smu_controls.c
+++ b/drivers/macintosh/windfarm_smu_controls.c
@@ -263,7 +263,7 @@ static int __init smu_controls_init(void)
/* Look for RPM fans */
for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;)
if (!strcmp(fans->name, "rpm-fans") ||
- device_is_compatible(fans, "smu-rpm-fans"))
+ of_device_is_compatible(fans, "smu-rpm-fans"))
break;
for (fan = NULL;
fans && (fan = of_get_next_child(fans, fan)) != NULL;) {
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
index 9a6c2cf..1043b39 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -380,7 +380,7 @@ static int wf_sat_attach(struct i2c_adapter *adapter)
busnode = pmac_i2c_get_bus_node(bus);
while ((dev = of_get_next_child(busnode, dev)) != NULL)
- if (device_is_compatible(dev, "smu-sat"))
+ if (of_device_is_compatible(dev, "smu-sat"))
wf_sat_create(adapter, dev);
return 0;
}
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index e61e0ef..5a4a74c 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1456,10 +1456,10 @@ int bitmap_create(mddev_t *mddev)
bitmap->offset = mddev->bitmap_offset;
if (file) {
get_file(file);
- do_sync_file_range(file, 0, LLONG_MAX,
- SYNC_FILE_RANGE_WAIT_BEFORE |
- SYNC_FILE_RANGE_WRITE |
- SYNC_FILE_RANGE_WAIT_AFTER);
+ do_sync_mapping_range(file->f_mapping, 0, LLONG_MAX,
+ SYNC_FILE_RANGE_WAIT_BEFORE |
+ SYNC_FILE_RANGE_WRITE |
+ SYNC_FILE_RANGE_WAIT_AFTER);
}
/* read superblock from bitmap file (this sets bitmap->chunksize) */
err = bitmap_read_sb(bitmap);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 509171c..2b4315d 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3080,7 +3080,7 @@ static int do_md_run(mddev_t * mddev)
if (test_bit(Faulty, &rdev->flags))
continue;
sync_blockdev(rdev->bdev);
- invalidate_bdev(rdev->bdev, 0);
+ invalidate_bdev(rdev->bdev);
}
md_probe(mddev->unit, NULL, NULL);
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index 3bf084f..87623d2 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -22,7 +22,6 @@
#ifndef DST_COMMON_H
#define DST_COMMON_H
-#include <linux/smp_lock.h>
#include <linux/dvb/frontend.h>
#include <linux/device.h>
#include <linux/mutex.h>
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index 654c9e9..58678c0 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -32,7 +32,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/delay.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include "av7110.h"
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
index e9b4e88..e1c1294 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -34,7 +34,6 @@
#include <linux/fs.h>
#include <linux/timer.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include "av7110.h"
#include "av7110_hw.h"
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 4d7150e..70aee4e 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -33,7 +33,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/delay.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include "av7110.h"
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index cde5d3a..fcd9994 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -31,7 +31,6 @@
#include <linux/fs.h>
#include <linux/timer.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include "av7110.h"
#include "av7110_hw.h"
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index df8d052..449df1b 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -79,7 +79,6 @@
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/usb.h>
-#include <linux/smp_lock.h>
/*
* Version Information
diff --git a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h
index 6eaa692..78392fb 100644
--- a/drivers/media/video/cpia.h
+++ b/drivers/media/video/cpia.h
@@ -47,7 +47,6 @@
#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <linux/list.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
struct cpia_camera_ops
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
index 19711aa..c431df8 100644
--- a/drivers/media/video/cpia_pp.c
+++ b/drivers/media/video/cpia_pp.c
@@ -34,7 +34,6 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
-#include <linux/smp_lock.h>
#include <linux/sched.h>
#include <linux/kmod.h>
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 3956c25..2d666b5 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -27,6 +27,8 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+
#include <asm/delay.h>
#include <sound/driver.h>
#include <sound/core.h>
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index b2eb32e..2ebde2f 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -26,6 +26,7 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <asm/delay.h>
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index e627062..259ea08 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -49,7 +49,6 @@
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/kthread.h>
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index fbce1d5..b94ef8a 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1,4 +1,3 @@
-
/*
*
* device driver for Conexant 2388x based TV cards
@@ -34,6 +33,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <asm/div64.h>
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index ff4b238..a5731f9 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -37,7 +37,6 @@
#include <asm/atomic.h>
#include <linux/delay.h>
#include <linux/usb.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include "dabusb.h"
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h
index 68b082b..18c6422 100644
--- a/drivers/media/video/ov511.h
+++ b/drivers/media/video/ov511.h
@@ -4,7 +4,6 @@
#include <asm/uaccess.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
-#include <linux/smp_lock.h>
#include <linux/usb.h>
#include <linux/mutex.h>
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
index e976c48..9ea41c6 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -25,7 +25,6 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/smp_lock.h>
#include <linux/usb.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index dd759d6..7b56041 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -27,7 +27,6 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include <linux/smp_lock.h>
#include <asm/div64.h>
#include "saa7134-reg.h"
diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h
index c0891b3..835ef87 100644
--- a/drivers/media/video/se401.h
+++ b/drivers/media/video/se401.h
@@ -5,7 +5,6 @@
#include <asm/uaccess.h>
#include <linux/videodev.h>
#include <media/v4l2-common.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#define se401_DEBUG /* Turn on debug messages */
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index a2da5d2..c9bf9db 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -26,7 +26,6 @@
#include <linux/videodev.h>
#include <linux/i2c.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c
index 687f026..37ce36b 100644
--- a/drivers/media/video/usbvideo/usbvideo.c
+++ b/drivers/media/video/usbvideo/usbvideo.c
@@ -20,7 +20,6 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/spinlock.h>
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index bcb551ad..9118a62 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -30,7 +30,6 @@
#include <linux/mm.h>
#include <linux/utsname.h>
#include <linux/highmem.h>
-#include <linux/smp_lock.h>
#include <linux/videodev.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 2167041..aa3258b 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -52,7 +52,6 @@
#include <linux/mm.h>
#include <linux/utsname.h>
#include <linux/highmem.h>
-#include <linux/smp_lock.h>
#include <linux/videodev.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index d2c1ae0..a861e15 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -23,7 +23,6 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/file.h>
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 49f1df7..13ee550 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -47,7 +47,6 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/errno.h>
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 80ac5f8..5263b50 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -30,7 +30,6 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/errno.h>
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 0743237..cf0ed6c 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -2034,7 +2034,7 @@ zoran_do_ioctl (struct inode *inode,
* but moving the free code outside the munmap() handler fixes
* all this... If someone knows why, please explain me (Ronald)
*/
- if (!!mutex_trylock(&zr->resource_lock)) {
+ if (mutex_trylock(&zr->resource_lock)) {
/* we obtained it! Let's try to free some things */
if (fh->jpg_buffers.ready_to_be_freed)
jpg_fbuffer_free(file);
diff --git a/drivers/message/i2o/i2o_lan.h b/drivers/message/i2o/i2o_lan.h
deleted file mode 100644
index 6502b81..0000000
--- a/drivers/message/i2o/i2o_lan.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * i2o_lan.h I2O LAN Class definitions
- *
- * I2O LAN CLASS OSM May 26th 2000
- *
- * (C) Copyright 1999, 2000 University of Helsinki,
- * Department of Computer Science
- *
- * This code is still under development / test.
- *
- * Author: Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
- * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
- * Taneli Vähäkangas <Taneli.Vahakangas@cs.Helsinki.FI>
- */
-
-#ifndef _I2O_LAN_H
-#define _I2O_LAN_H
-
-/* Default values for tunable parameters first */
-
-#define I2O_LAN_MAX_BUCKETS_OUT 96
-#define I2O_LAN_BUCKET_THRESH 18 /* 9 buckets in one message */
-#define I2O_LAN_RX_COPYBREAK 200
-#define I2O_LAN_TX_TIMEOUT (1*HZ)
-#define I2O_LAN_TX_BATCH_MODE 2 /* 2=automatic, 1=on, 0=off */
-#define I2O_LAN_EVENT_MASK 0 /* 0=None, 0xFFC00002=All */
-
-/* LAN types */
-#define I2O_LAN_ETHERNET 0x0030
-#define I2O_LAN_100VG 0x0040
-#define I2O_LAN_TR 0x0050
-#define I2O_LAN_FDDI 0x0060
-#define I2O_LAN_FIBRE_CHANNEL 0x0070
-#define I2O_LAN_UNKNOWN 0x00000000
-
-/* Connector types */
-
-/* Ethernet */
-#define I2O_LAN_AUI (I2O_LAN_ETHERNET << 4) + 0x00000001
-#define I2O_LAN_10BASE5 (I2O_LAN_ETHERNET << 4) + 0x00000002
-#define I2O_LAN_FIORL (I2O_LAN_ETHERNET << 4) + 0x00000003
-#define I2O_LAN_10BASE2 (I2O_LAN_ETHERNET << 4) + 0x00000004
-#define I2O_LAN_10BROAD36 (I2O_LAN_ETHERNET << 4) + 0x00000005
-#define I2O_LAN_10BASE_T (I2O_LAN_ETHERNET << 4) + 0x00000006
-#define I2O_LAN_10BASE_FP (I2O_LAN_ETHERNET << 4) + 0x00000007
-#define I2O_LAN_10BASE_FB (I2O_LAN_ETHERNET << 4) + 0x00000008
-#define I2O_LAN_10BASE_FL (I2O_LAN_ETHERNET << 4) + 0x00000009
-#define I2O_LAN_100BASE_TX (I2O_LAN_ETHERNET << 4) + 0x0000000A
-#define I2O_LAN_100BASE_FX (I2O_LAN_ETHERNET << 4) + 0x0000000B
-#define I2O_LAN_100BASE_T4 (I2O_LAN_ETHERNET << 4) + 0x0000000C
-#define I2O_LAN_1000BASE_SX (I2O_LAN_ETHERNET << 4) + 0x0000000D
-#define I2O_LAN_1000BASE_LX (I2O_LAN_ETHERNET << 4) + 0x0000000E
-#define I2O_LAN_1000BASE_CX (I2O_LAN_ETHERNET << 4) + 0x0000000F
-#define I2O_LAN_1000BASE_T (I2O_LAN_ETHERNET << 4) + 0x00000010
-
-/* AnyLAN */
-#define I2O_LAN_100VG_ETHERNET (I2O_LAN_100VG << 4) + 0x00000001
-#define I2O_LAN_100VG_TR (I2O_LAN_100VG << 4) + 0x00000002
-
-/* Token Ring */
-#define I2O_LAN_4MBIT (I2O_LAN_TR << 4) + 0x00000001
-#define I2O_LAN_16MBIT (I2O_LAN_TR << 4) + 0x00000002
-
-/* FDDI */
-#define I2O_LAN_125MBAUD (I2O_LAN_FDDI << 4) + 0x00000001
-
-/* Fibre Channel */
-#define I2O_LAN_POINT_POINT (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000001
-#define I2O_LAN_ARB_LOOP (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000002
-#define I2O_LAN_PUBLIC_LOOP (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000003
-#define I2O_LAN_FABRIC (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000004
-
-#define I2O_LAN_EMULATION 0x00000F00
-#define I2O_LAN_OTHER 0x00000F01
-#define I2O_LAN_DEFAULT 0xFFFFFFFF
-
-/* LAN class functions */
-
-#define LAN_PACKET_SEND 0x3B
-#define LAN_SDU_SEND 0x3D
-#define LAN_RECEIVE_POST 0x3E
-#define LAN_RESET 0x35
-#define LAN_SUSPEND 0x37
-
-/* LAN DetailedStatusCode defines */
-#define I2O_LAN_DSC_SUCCESS 0x00
-#define I2O_LAN_DSC_DEVICE_FAILURE 0x01
-#define I2O_LAN_DSC_DESTINATION_NOT_FOUND 0x02
-#define I2O_LAN_DSC_TRANSMIT_ERROR 0x03
-#define I2O_LAN_DSC_TRANSMIT_ABORTED 0x04
-#define I2O_LAN_DSC_RECEIVE_ERROR 0x05
-#define I2O_LAN_DSC_RECEIVE_ABORTED 0x06
-#define I2O_LAN_DSC_DMA_ERROR 0x07
-#define I2O_LAN_DSC_BAD_PACKET_DETECTED 0x08
-#define I2O_LAN_DSC_OUT_OF_MEMORY 0x09
-#define I2O_LAN_DSC_BUCKET_OVERRUN 0x0A
-#define I2O_LAN_DSC_IOP_INTERNAL_ERROR 0x0B
-#define I2O_LAN_DSC_CANCELED 0x0C
-#define I2O_LAN_DSC_INVALID_TRANSACTION_CONTEXT 0x0D
-#define I2O_LAN_DSC_DEST_ADDRESS_DETECTED 0x0E
-#define I2O_LAN_DSC_DEST_ADDRESS_OMITTED 0x0F
-#define I2O_LAN_DSC_PARTIAL_PACKET_RETURNED 0x10
-#define I2O_LAN_DSC_SUSPENDED 0x11
-
-struct i2o_packet_info {
- u32 offset:24;
- u32 flags:8;
- u32 len:24;
- u32 status:8;
-};
-
-struct i2o_bucket_descriptor {
- u32 context; /* FIXME: 64bit support */
- struct i2o_packet_info packet_info[1];
-};
-
-/* Event Indicator Mask Flags for LAN OSM */
-
-#define I2O_LAN_EVT_LINK_DOWN 0x01
-#define I2O_LAN_EVT_LINK_UP 0x02
-#define I2O_LAN_EVT_MEDIA_CHANGE 0x04
-
-#include <linux/netdevice.h>
-#include <linux/fddidevice.h>
-
-struct i2o_lan_local {
- u8 unit;
- struct i2o_device *i2o_dev;
-
- struct fddi_statistics stats; /* see also struct net_device_stats */
- unsigned short (*type_trans) (struct sk_buff *, struct net_device *);
- atomic_t buckets_out; /* nbr of unused buckets on DDM */
- atomic_t tx_out; /* outstanding TXes */
- u8 tx_count; /* packets in one TX message frame */
- u16 tx_max_out; /* DDM's Tx queue len */
- u8 sgl_max; /* max SGLs in one message frame */
- u32 m; /* IOP address of the batch msg frame */
-
- struct work_struct i2o_batch_send_task;
- int send_active;
- struct sk_buff **i2o_fbl; /* Free bucket list (to reuse skbs) */
- int i2o_fbl_tail;
- spinlock_t fbl_lock;
-
- spinlock_t tx_lock;
-
- u32 max_size_mc_table; /* max number of multicast addresses */
-
- /* LAN OSM configurable parameters are here: */
-
- u16 max_buckets_out; /* max nbr of buckets to send to DDM */
- u16 bucket_thresh; /* send more when this many used */
- u16 rx_copybreak;
-
- u8 tx_batch_mode; /* Set when using batch mode sends */
- u32 i2o_event_mask; /* To turn on interesting event flags */
-};
-
-#endif /* _I2O_LAN_H */
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index ce1a481..cb8c264 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -21,7 +21,6 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sched.h>
#include <linux/completion.h>
#include <linux/delay.h>
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index a3c525b..877e790 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -25,6 +25,15 @@ config IBM_ASM
information on the specific driver level and support statement
for your IBM server.
+config PHANTOM
+ tristate "Sensable PHANToM"
+ depends on PCI
+ help
+ Say Y here if you want to build a driver for Sensable PHANToM device.
+
+ If you choose to build module, its name will be phantom. If unsure,
+ say N here.
+
If unsure, say N.
@@ -178,4 +187,13 @@ config THINKPAD_ACPI_BAY
If you are not sure, say Y here.
+config BLINK
+ tristate "Keyboard blink driver"
+ help
+ Driver that when loaded will blink the keyboard LEDs continuously.
+ This is useful for debugging and for kernels that cannot necessarily
+ output something to the screen like kexec kernels to give the user
+ a visual indication that the kernel is doing something.
+
+
endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index e325164..5b6d46d 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -7,9 +7,11 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/
obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o
+obj-$(CONFIG_BLINK) += blink.o
obj-$(CONFIG_LKDTM) += lkdtm.o
obj-$(CONFIG_TIFM_CORE) += tifm_core.o
obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
+obj-$(CONFIG_PHANTOM) += phantom.o
obj-$(CONFIG_SGI_IOC4) += ioc4.o
obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
diff --git a/drivers/misc/blink.c b/drivers/misc/blink.c
new file mode 100644
index 0000000..634431c
--- /dev/null
+++ b/drivers/misc/blink.c
@@ -0,0 +1,27 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/jiffies.h>
+
+static void do_blink(unsigned long data);
+
+static DEFINE_TIMER(blink_timer, do_blink, 0 ,0);
+
+static void do_blink(unsigned long data)
+{
+ static long count;
+ if (panic_blink)
+ panic_blink(count++);
+ blink_timer.expires = jiffies + msecs_to_jiffies(1);
+ add_timer(&blink_timer);
+}
+
+static int blink_init(void)
+{
+ printk(KERN_INFO "Enabling keyboard blinking\n");
+ do_blink(0);
+ return 0;
+}
+
+module_init(blink_init);
+
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
new file mode 100644
index 0000000..35b139b
--- /dev/null
+++ b/drivers/misc/phantom.c
@@ -0,0 +1,463 @@
+/*
+ * Copyright (C) 2005-2007 Jiri Slaby <jirislaby@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * You need an userspace library to cooperate with this driver. It (and other
+ * info) may be obtained here:
+ * http://www.fi.muni.cz/~xslaby/phantom.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/pci.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/interrupt.h>
+#include <linux/cdev.h>
+#include <linux/phantom.h>
+
+#include <asm/atomic.h>
+#include <asm/io.h>
+
+#define PHANTOM_VERSION "n0.9.5"
+
+#define PHANTOM_MAX_MINORS 8
+
+#define PHN_IRQCTL 0x4c /* irq control in caddr space */
+
+#define PHB_RUNNING 1
+
+static struct class *phantom_class;
+static int phantom_major;
+
+struct phantom_device {
+ unsigned int opened;
+ void __iomem *caddr;
+ u32 __iomem *iaddr;
+ u32 __iomem *oaddr;
+ unsigned long status;
+ atomic_t counter;
+
+ wait_queue_head_t wait;
+ struct cdev cdev;
+
+ struct mutex open_lock;
+};
+
+static unsigned char phantom_devices[PHANTOM_MAX_MINORS];
+
+static int phantom_status(struct phantom_device *dev, unsigned long newstat)
+{
+ pr_debug("phantom_status %lx %lx\n", dev->status, newstat);
+
+ if (!(dev->status & PHB_RUNNING) && (newstat & PHB_RUNNING)) {
+ atomic_set(&dev->counter, 0);
+ iowrite32(PHN_CTL_IRQ, dev->iaddr + PHN_CONTROL);
+ iowrite32(0x43, dev->caddr + PHN_IRQCTL);
+ } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING))
+ iowrite32(0, dev->caddr + PHN_IRQCTL);
+
+ dev->status = newstat;
+
+ return 0;
+}
+
+/*
+ * File ops
+ */
+
+static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg)
+{
+ struct phantom_device *dev = file->private_data;
+ struct phm_regs rs;
+ struct phm_reg r;
+ void __user *argp = (void __user *)arg;
+ unsigned int i;
+
+ if (_IOC_TYPE(cmd) != PH_IOC_MAGIC ||
+ _IOC_NR(cmd) > PH_IOC_MAXNR)
+ return -ENOTTY;
+
+ switch (cmd) {
+ case PHN_SET_REG:
+ if (copy_from_user(&r, argp, sizeof(r)))
+ return -EFAULT;
+
+ if (r.reg > 7)
+ return -EINVAL;
+
+ if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) &&
+ phantom_status(dev, dev->status | PHB_RUNNING))
+ return -ENODEV;
+
+ pr_debug("phantom: writing %x to %u\n", r.value, r.reg);
+ iowrite32(r.value, dev->iaddr + r.reg);
+
+ if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ))
+ phantom_status(dev, dev->status & ~PHB_RUNNING);
+ break;
+ case PHN_SET_REGS:
+ if (copy_from_user(&rs, argp, sizeof(rs)))
+ return -EFAULT;
+
+ pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask);
+ for (i = 0; i < min(rs.count, 8U); i++)
+ if ((1 << i) & rs.mask)
+ iowrite32(rs.values[i], dev->oaddr + i);
+ break;
+ case PHN_GET_REG:
+ if (copy_from_user(&r, argp, sizeof(r)))
+ return -EFAULT;
+
+ if (r.reg > 7)
+ return -EINVAL;
+
+ r.value = ioread32(dev->iaddr + r.reg);
+
+ if (copy_to_user(argp, &r, sizeof(r)))
+ return -EFAULT;
+ break;
+ case PHN_GET_REGS:
+ if (copy_from_user(&rs, argp, sizeof(rs)))
+ return -EFAULT;
+
+ pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask);
+ for (i = 0; i < min(rs.count, 8U); i++)
+ if ((1 << i) & rs.mask)
+ rs.values[i] = ioread32(dev->iaddr + i);
+
+ if (copy_to_user(argp, &rs, sizeof(rs)))
+ return -EFAULT;
+ break;
+ default:
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
+static int phantom_open(struct inode *inode, struct file *file)
+{
+ struct phantom_device *dev = container_of(inode->i_cdev,
+ struct phantom_device, cdev);
+
+ nonseekable_open(inode, file);
+
+ if (mutex_lock_interruptible(&dev->open_lock))
+ return -ERESTARTSYS;
+
+ if (dev->opened) {
+ mutex_unlock(&dev->open_lock);
+ return -EINVAL;
+ }
+
+ file->private_data = dev;
+
+ dev->opened++;
+ mutex_unlock(&dev->open_lock);
+
+ return 0;
+}
+
+static int phantom_release(struct inode *inode, struct file *file)
+{
+ struct phantom_device *dev = file->private_data;
+
+ mutex_lock(&dev->open_lock);
+
+ dev->opened = 0;
+ phantom_status(dev, dev->status & ~PHB_RUNNING);
+
+ mutex_unlock(&dev->open_lock);
+
+ return 0;
+}
+
+static unsigned int phantom_poll(struct file *file, poll_table *wait)
+{
+ struct phantom_device *dev = file->private_data;
+ unsigned int mask = 0;
+
+ pr_debug("phantom_poll: %d\n", atomic_read(&dev->counter));
+ poll_wait(file, &dev->wait, wait);
+ if (atomic_read(&dev->counter)) {
+ mask = POLLIN | POLLRDNORM;
+ atomic_dec(&dev->counter);
+ } else if ((dev->status & PHB_RUNNING) == 0)
+ mask = POLLIN | POLLRDNORM | POLLERR;
+ pr_debug("phantom_poll end: %x/%d\n", mask, atomic_read(&dev->counter));
+
+ return mask;
+}
+
+static struct file_operations phantom_file_ops = {
+ .open = phantom_open,
+ .release = phantom_release,
+ .ioctl = phantom_ioctl,
+ .poll = phantom_poll,
+};
+
+static irqreturn_t phantom_isr(int irq, void *data)
+{
+ struct phantom_device *dev = data;
+
+ if (!(ioread32(dev->iaddr + PHN_CONTROL) & PHN_CTL_IRQ))
+ return IRQ_NONE;
+
+ iowrite32(0, dev->iaddr);
+ iowrite32(0xc0, dev->iaddr);
+
+ atomic_inc(&dev->counter);
+ wake_up_interruptible(&dev->wait);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * Init and deinit driver
+ */
+
+static unsigned int __devinit phantom_get_free(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < PHANTOM_MAX_MINORS; i++)
+ if (phantom_devices[i] == 0)
+ break;
+
+ return i;
+}
+
+static int __devinit phantom_probe(struct pci_dev *pdev,
+ const struct pci_device_id *pci_id)
+{
+ struct phantom_device *pht;
+ unsigned int minor;
+ int retval;
+
+ retval = pci_enable_device(pdev);
+ if (retval)
+ goto err;
+
+ minor = phantom_get_free();
+ if (minor == PHANTOM_MAX_MINORS) {
+ dev_err(&pdev->dev, "too many devices found!\n");
+ retval = -EIO;
+ goto err_dis;
+ }
+
+ phantom_devices[minor] = 1;
+
+ retval = pci_request_regions(pdev, "phantom");
+ if (retval)
+ goto err_null;
+
+ retval = -ENOMEM;
+ pht = kzalloc(sizeof(*pht), GFP_KERNEL);
+ if (pht == NULL) {
+ dev_err(&pdev->dev, "unable to allocate device\n");
+ goto err_reg;
+ }
+
+ pht->caddr = pci_iomap(pdev, 0, 0);
+ if (pht->caddr == NULL) {
+ dev_err(&pdev->dev, "can't remap conf space\n");
+ goto err_fr;
+ }
+ pht->iaddr = pci_iomap(pdev, 2, 0);
+ if (pht->iaddr == NULL) {
+ dev_err(&pdev->dev, "can't remap input space\n");
+ goto err_unmc;
+ }
+ pht->oaddr = pci_iomap(pdev, 3, 0);
+ if (pht->oaddr == NULL) {
+ dev_err(&pdev->dev, "can't remap output space\n");
+ goto err_unmi;
+ }
+
+ mutex_init(&pht->open_lock);
+ init_waitqueue_head(&pht->wait);
+ cdev_init(&pht->cdev, &phantom_file_ops);
+ pht->cdev.owner = THIS_MODULE;
+
+ iowrite32(0, pht->caddr + PHN_IRQCTL);
+ retval = request_irq(pdev->irq, phantom_isr,
+ IRQF_SHARED | IRQF_DISABLED, "phantom", pht);
+ if (retval) {
+ dev_err(&pdev->dev, "can't establish ISR\n");
+ goto err_unmo;
+ }
+
+ retval = cdev_add(&pht->cdev, MKDEV(phantom_major, minor), 1);
+ if (retval) {
+ dev_err(&pdev->dev, "chardev registration failed\n");
+ goto err_irq;
+ }
+
+ if (IS_ERR(device_create(phantom_class, &pdev->dev, MKDEV(phantom_major,
+ minor), "phantom%u", minor)))
+ dev_err(&pdev->dev, "can't create device\n");
+
+ pci_set_drvdata(pdev, pht);
+
+ return 0;
+err_irq:
+ free_irq(pdev->irq, pht);
+err_unmo:
+ pci_iounmap(pdev, pht->oaddr);
+err_unmi:
+ pci_iounmap(pdev, pht->iaddr);
+err_unmc:
+ pci_iounmap(pdev, pht->caddr);
+err_fr:
+ kfree(pht);
+err_reg:
+ pci_release_regions(pdev);
+err_null:
+ phantom_devices[minor] = 0;
+err_dis:
+ pci_disable_device(pdev);
+err:
+ return retval;
+}
+
+static void __devexit phantom_remove(struct pci_dev *pdev)
+{
+ struct phantom_device *pht = pci_get_drvdata(pdev);
+ unsigned int minor = MINOR(pht->cdev.dev);
+
+ device_destroy(phantom_class, MKDEV(phantom_major, minor));
+
+ cdev_del(&pht->cdev);
+
+ iowrite32(0, pht->caddr + PHN_IRQCTL);
+ free_irq(pdev->irq, pht);
+
+ pci_iounmap(pdev, pht->oaddr);
+ pci_iounmap(pdev, pht->iaddr);
+ pci_iounmap(pdev, pht->caddr);
+
+ kfree(pht);
+
+ pci_release_regions(pdev);
+
+ phantom_devices[minor] = 0;
+
+ pci_disable_device(pdev);
+}
+
+#ifdef CONFIG_PM
+static int phantom_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct phantom_device *dev = pci_get_drvdata(pdev);
+
+ iowrite32(0, dev->caddr + PHN_IRQCTL);
+
+ return 0;
+}
+
+static int phantom_resume(struct pci_dev *pdev)
+{
+ struct phantom_device *dev = pci_get_drvdata(pdev);
+
+ iowrite32(0, dev->caddr + PHN_IRQCTL);
+
+ return 0;
+}
+#else
+#define phantom_suspend NULL
+#define phantom_resume NULL
+#endif
+
+static struct pci_device_id phantom_pci_tbl[] __devinitdata = {
+ { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050),
+ .class = PCI_CLASS_BRIDGE_OTHER << 8, .class_mask = 0xffff00 },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, phantom_pci_tbl);
+
+static struct pci_driver phantom_pci_driver = {
+ .name = "phantom",
+ .id_table = phantom_pci_tbl,
+ .probe = phantom_probe,
+ .remove = __devexit_p(phantom_remove),
+ .suspend = phantom_suspend,
+ .resume = phantom_resume
+};
+
+static ssize_t phantom_show_version(struct class *cls, char *buf)
+{
+ return sprintf(buf, PHANTOM_VERSION "\n");
+}
+
+static CLASS_ATTR(version, 0444, phantom_show_version, NULL);
+
+static int __init phantom_init(void)
+{
+ int retval;
+ dev_t dev;
+
+ phantom_class = class_create(THIS_MODULE, "phantom");
+ if (IS_ERR(phantom_class)) {
+ retval = PTR_ERR(phantom_class);
+ printk(KERN_ERR "phantom: can't register phantom class\n");
+ goto err;
+ }
+ retval = class_create_file(phantom_class, &class_attr_version);
+ if (retval) {
+ printk(KERN_ERR "phantom: can't create sysfs version file\n");
+ goto err_class;
+ }
+
+ retval = alloc_chrdev_region(&dev, 0, PHANTOM_MAX_MINORS, "phantom");
+ if (retval) {
+ printk(KERN_ERR "phantom: can't register character device\n");
+ goto err_attr;
+ }
+ phantom_major = MAJOR(dev);
+
+ retval = pci_register_driver(&phantom_pci_driver);
+ if (retval) {
+ printk(KERN_ERR "phantom: can't register pci driver\n");
+ goto err_unchr;
+ }
+
+ printk(KERN_INFO "Phantom Linux Driver, version " PHANTOM_VERSION ", "
+ "init OK\n");
+
+ return 0;
+err_unchr:
+ unregister_chrdev_region(dev, PHANTOM_MAX_MINORS);
+err_attr:
+ class_remove_file(phantom_class, &class_attr_version);
+err_class:
+ class_destroy(phantom_class);
+err:
+ return retval;
+}
+
+static void __exit phantom_exit(void)
+{
+ pci_unregister_driver(&phantom_pci_driver);
+
+ unregister_chrdev_region(MKDEV(phantom_major, 0), PHANTOM_MAX_MINORS);
+
+ class_remove_file(phantom_class, &class_attr_version);
+ class_destroy(phantom_class);
+
+ pr_debug("phantom: module successfully removed\n");
+}
+
+module_init(phantom_init);
+module_exit(phantom_exit);
+
+MODULE_AUTHOR("Jiri Slaby <jirislaby@gmail.com>");
+MODULE_DESCRIPTION("Sensable Phantom driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(PHANTOM_VERSION);
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
index 1ba6c08..c08ad8f 100644
--- a/drivers/misc/tifm_7xx1.c
+++ b/drivers/misc/tifm_7xx1.c
@@ -105,7 +105,8 @@ static unsigned char tifm_7xx1_toggle_sock_power(char __iomem *sock_addr)
== TIFM_TYPE_XD)
msleep(40);
- writel((s_state & 7) | 0x0c00, sock_addr + SOCK_CONTROL);
+ writel((s_state & TIFM_CTRL_POWER_MASK) | 0x0c00,
+ sock_addr + SOCK_CONTROL);
/* wait for power to stabilize */
msleep(20);
for (cnt = 16; cnt <= 256; cnt <<= 1) {
@@ -122,6 +123,12 @@ static unsigned char tifm_7xx1_toggle_sock_power(char __iomem *sock_addr)
return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7;
}
+inline static void tifm_7xx1_sock_power_off(char __iomem *sock_addr)
+{
+ writel((~TIFM_CTRL_POWER_MASK) & readl(sock_addr + SOCK_CONTROL),
+ sock_addr + SOCK_CONTROL);
+}
+
inline static char __iomem *
tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num)
{
@@ -133,6 +140,7 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
struct tifm_adapter *fm = container_of(work, struct tifm_adapter,
media_switcher);
struct tifm_dev *sock;
+ char __iomem *sock_addr;
unsigned long flags;
unsigned char media_id;
unsigned int socket_change_set, cnt;
@@ -158,11 +166,12 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
"%s : demand removing card from socket %u:%u\n",
fm->cdev.class_id, fm->id, cnt);
fm->sockets[cnt] = NULL;
+ sock_addr = sock->addr;
spin_unlock_irqrestore(&fm->lock, flags);
device_unregister(&sock->dev);
spin_lock_irqsave(&fm->lock, flags);
- writel(0x0e00, tifm_7xx1_sock_addr(fm->addr, cnt)
- + SOCK_CONTROL);
+ tifm_7xx1_sock_power_off(sock_addr);
+ writel(0x0e00, sock_addr + SOCK_CONTROL);
}
spin_unlock_irqrestore(&fm->lock, flags);
@@ -205,8 +214,16 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state)
{
+ struct tifm_adapter *fm = pci_get_drvdata(dev);
+ int cnt;
+
dev_dbg(&dev->dev, "suspending host\n");
+ for (cnt = 0; cnt < fm->num_sockets; cnt++) {
+ if (fm->sockets[cnt])
+ tifm_7xx1_sock_power_off(fm->sockets[cnt]->addr);
+ }
+
pci_save_state(dev);
pci_enable_wake(dev, pci_choose_state(dev, state), 0);
pci_disable_device(dev);
@@ -357,6 +374,7 @@ err_out:
static void tifm_7xx1_remove(struct pci_dev *dev)
{
struct tifm_adapter *fm = pci_get_drvdata(dev);
+ int cnt;
fm->eject = tifm_7xx1_dummy_eject;
writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
@@ -365,6 +383,9 @@ static void tifm_7xx1_remove(struct pci_dev *dev)
tifm_remove_adapter(fm);
+ for (cnt = 0; cnt < fm->num_sockets; cnt++)
+ tifm_7xx1_sock_power_off(tifm_7xx1_sock_addr(fm->addr, cnt));
+
pci_set_drvdata(dev, NULL);
iounmap(fm->addr);
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 6c97491..45b7d53 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -2,10 +2,8 @@
# MMC subsystem configuration
#
-menu "MMC/SD Card support"
-
-config MMC
- tristate "MMC support"
+menuconfig MMC
+ tristate "MMC/SD card support"
help
MMC is the "multi-media card" bus protocol.
@@ -19,10 +17,12 @@ config MMC_DEBUG
This is an option for use by developers; most people should
say N here. This enables MMC core and driver debugging.
+if MMC
+
source "drivers/mmc/core/Kconfig"
source "drivers/mmc/card/Kconfig"
source "drivers/mmc/host/Kconfig"
-endmenu
+endif # MMC
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig
index 01a9fd3..9320a8c 100644
--- a/drivers/mmc/card/Kconfig
+++ b/drivers/mmc/card/Kconfig
@@ -3,11 +3,10 @@
#
comment "MMC/SD Card Drivers"
- depends MMC
config MMC_BLOCK
tristate "MMC block device driver"
- depends on MMC && BLOCK
+ depends on BLOCK
default y
help
Say Y here to enable the MMC block device driver support.
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
index 94222b9..ab37a6d 100644
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/mmc/core/Kconfig
@@ -4,7 +4,6 @@
config MMC_UNSAFE_RESUME
bool "Allow unsafe resume (DANGEROUS)"
- depends on MMC != n
help
If you say Y here, the MMC layer will assume that all cards
stayed in their respective slots during the suspend. The
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 72c7cf4..b6c1670 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -500,9 +500,10 @@ void __mmc_release_bus(struct mmc_host *host)
void mmc_detect_change(struct mmc_host *host, unsigned long delay)
{
#ifdef CONFIG_MMC_DEBUG
- mmc_claim_host(host);
+ unsigned long flags;
+ spin_lock_irqsave(host->lock, flags);
BUG_ON(host->removed);
- mmc_release_host(host);
+ spin_unlock_irqrestore(host->lock, flags);
#endif
mmc_schedule_delayed_work(&host->detect, delay);
@@ -625,9 +626,10 @@ EXPORT_SYMBOL(mmc_add_host);
void mmc_remove_host(struct mmc_host *host)
{
#ifdef CONFIG_MMC_DEBUG
- mmc_claim_host(host);
+ unsigned long flags;
+ spin_lock_irqsave(&host->lock, flags);
host->removed = 1;
- mmc_release_host(host);
+ spin_unlock_irqrestore(&host->lock, flags);
#endif
mmc_flush_scheduled_work();
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index ed4deab..e23082f 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -3,11 +3,10 @@
#
comment "MMC/SD Host Controller Drivers"
- depends on MMC
config MMC_ARMMMCI
tristate "ARM AMBA Multimedia Card Interface support"
- depends on ARM_AMBA && MMC
+ depends on ARM_AMBA
help
This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card
Interface (PL180 and PL181) support. If you have an ARM(R)
@@ -17,7 +16,7 @@ config MMC_ARMMMCI
config MMC_PXA
tristate "Intel PXA25x/26x/27x Multimedia Card Interface support"
- depends on ARCH_PXA && MMC
+ depends on ARCH_PXA
help
This selects the Intel(R) PXA(R) Multimedia card Interface.
If you have a PXA(R) platform with a Multimedia Card slot,
@@ -27,7 +26,7 @@ config MMC_PXA
config MMC_SDHCI
tristate "Secure Digital Host Controller Interface support (EXPERIMENTAL)"
- depends on PCI && MMC && EXPERIMENTAL
+ depends on PCI && EXPERIMENTAL
help
This select the generic Secure Digital Host Controller Interface.
It is used by manufacturers such as Texas Instruments(R), Ricoh(R)
@@ -38,7 +37,7 @@ config MMC_SDHCI
config MMC_OMAP
tristate "TI OMAP Multimedia Card Interface support"
- depends on ARCH_OMAP && MMC
+ depends on ARCH_OMAP
select TPS65010 if MACH_OMAP_H2
help
This selects the TI OMAP Multimedia card Interface.
@@ -49,7 +48,7 @@ config MMC_OMAP
config MMC_WBSD
tristate "Winbond W83L51xD SD/MMC Card Interface support"
- depends on MMC && ISA_DMA_API
+ depends on ISA_DMA_API
help
This selects the Winbond(R) W83L51xD Secure digital and
Multimedia card Interface.
@@ -60,7 +59,7 @@ config MMC_WBSD
config MMC_AU1X
tristate "Alchemy AU1XX0 MMC Card Interface support"
- depends on MMC && SOC_AU1200
+ depends on SOC_AU1200
help
This selects the AMD Alchemy(R) Multimedia card interface.
If you have a Alchemy platform with a MMC slot, say Y or M here.
@@ -69,7 +68,7 @@ config MMC_AU1X
config MMC_AT91
tristate "AT91 SD/MMC Card Interface support"
- depends on ARCH_AT91 && MMC
+ depends on ARCH_AT91
help
This selects the AT91 MCI controller.
@@ -77,7 +76,7 @@ config MMC_AT91
config MMC_IMX
tristate "Motorola i.MX Multimedia Card Interface support"
- depends on ARCH_IMX && MMC
+ depends on ARCH_IMX
help
This selects the Motorola i.MX Multimedia card Interface.
If you have a i.MX platform with a Multimedia Card slot,
@@ -87,7 +86,7 @@ config MMC_IMX
config MMC_TIFM_SD
tristate "TI Flash Media MMC/SD Interface support (EXPERIMENTAL)"
- depends on MMC && EXPERIMENTAL && PCI
+ depends on EXPERIMENTAL && PCI
select TIFM_CORE
help
Say Y here if you want to be able to access MMC/SD cards with
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index a98ff98..d97d386 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -368,14 +368,14 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (CLOCKRATE / clk > ios->clock)
clk <<= 1;
host->clkrt = fls(clk) - 1;
- pxa_set_cken(CKEN12_MMC, 1);
+ pxa_set_cken(CKEN_MMC, 1);
/*
* we write clkrt on the next command
*/
} else {
pxamci_stop_clock(host);
- pxa_set_cken(CKEN12_MMC, 0);
+ pxa_set_cken(CKEN_MMC, 0);
}
if (host->power_mode != ios->power_mode) {
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index 7511f96..8b736e9 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -1021,10 +1021,6 @@ static void tifm_sd_remove(struct tifm_dev *sock)
mmc_remove_host(mmc);
dev_dbg(&sock->dev, "after remove\n");
- /* The meaning of the bit majority in this constant is unknown. */
- writel(0xfff8 & readl(sock->addr + SOCK_CONTROL),
- sock->addr + SOCK_CONTROL);
-
mmc_free_host(mmc);
}
@@ -1032,14 +1028,7 @@ static void tifm_sd_remove(struct tifm_dev *sock)
static int tifm_sd_suspend(struct tifm_dev *sock, pm_message_t state)
{
- struct mmc_host *mmc = tifm_get_drvdata(sock);
- int rc;
-
- rc = mmc_suspend_host(mmc, state);
- /* The meaning of the bit majority in this constant is unknown. */
- writel(0xfff8 & readl(sock->addr + SOCK_CONTROL),
- sock->addr + SOCK_CONTROL);
- return rc;
+ return mmc_suspend_host(tifm_get_drvdata(sock), state);
}
static int tifm_sd_resume(struct tifm_dev *sock)
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 690c942..ff642f8 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -49,8 +49,8 @@ config MTD_MS02NV
If you want to compile this driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
- say M here and read <file:Documentation/modules.txt>. The module will
- be called ms02-nv.o.
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+ The module will be called ms02-nv.ko.
config MTD_DATAFLASH
tristate "Support for AT45xxx DataFlash"
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index ce47544..fc4cc8b 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -40,13 +40,11 @@ struct block2mtd_dev {
static LIST_HEAD(blkmtd_device_list);
-static struct page* page_read(struct address_space *mapping, int index)
+static struct page *page_read(struct address_space *mapping, int index)
{
- filler_t *filler = (filler_t*)mapping->a_ops->readpage;
- return read_cache_page(mapping, index, filler, NULL);
+ return read_mapping_page(mapping, index, NULL);
}
-
/* erase a specified part of the device */
static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len)
{
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index 7efe744..72107dc 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -48,7 +48,7 @@ static int parse_flash_partitions(struct device_node *node,
const u32 *part;
const char *name;
- part = get_property(node, "partitions", &plen);
+ part = of_get_property(node, "partitions", &plen);
if (part == NULL)
goto err;
@@ -59,7 +59,7 @@ static int parse_flash_partitions(struct device_node *node,
goto err;
}
- name = get_property(node, "partition-names", &plen);
+ name = of_get_property(node, "partition-names", &plen);
for (i = 0; i < retval; i++) {
(*parts)[i].offset = *part++;
@@ -153,7 +153,7 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev
goto err_out;
}
- width = get_property(dp, "bank-width", NULL);
+ width = of_get_property(dp, "bank-width", NULL);
if (width == NULL) {
dev_err(&dev->dev, "Can't get the flash bank width!\n");
err = -EINVAL;
@@ -174,7 +174,7 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev
simple_map_init(&info->map);
- of_probe = get_property(dp, "probe-type", NULL);
+ of_probe = of_get_property(dp, "probe-type", NULL);
if (of_probe == NULL) {
probe_type = rom_probe_types;
for (; info->mtd == NULL && *probe_type != NULL; probe_type++)
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 524b83b..51bc7e2 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -216,7 +216,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
int last_devnum = -1;
struct gendisk *gd;
- if (!!mutex_trylock(&mtd_table_mutex)) {
+ if (mutex_trylock(&mtd_table_mutex)) {
mutex_unlock(&mtd_table_mutex);
BUG();
}
@@ -294,7 +294,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
{
- if (!!mutex_trylock(&mtd_table_mutex)) {
+ if (mutex_trylock(&mtd_table_mutex)) {
mutex_unlock(&mtd_table_mutex);
BUG();
}
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index d847ee1..3dba573 100644
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -940,8 +940,7 @@ static void ltree_entry_ctor(void *obj, struct kmem_cache *cache,
{
struct ltree_entry *le = obj;
- if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) !=
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
return;
le->users = 0;
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 69dba62..b86ccd2 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -822,7 +822,7 @@ config SMC91X
tristate "SMC 91C9x/91C1xxx support"
select CRC32
select MII
- depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00)
+ depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00 || BFIN)
help
This is a driver for SMC's 91x series of Ethernet chipsets,
including the SMC91C94 and the SMC91C111. Say Y if you want it
@@ -833,8 +833,8 @@ config SMC91X
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called smc91x. If you want to compile it as a
- module, say M here and read <file:Documentation/modules.txt> as well
- as <file:Documentation/networking/net-modules.txt>.
+ module, say M here and read <file:Documentation/kbuild/modules.txt>
+ as well as <file:Documentation/networking/net-modules.txt>.
config SMC9194
tristate "SMC 9194 support"
@@ -889,7 +889,7 @@ config SMC911X
This driver is also available as a module. The module will be
called smc911x. If you want to compile it as a module, say M
- here and read <file:Documentation/modules.txt>
+ here and read <file:Documentation/kbuild/modules.txt>
config NET_VENDOR_RACAL
bool "Racal-Interlan (Micom) NI cards"
@@ -1104,7 +1104,7 @@ config ETH16I
config NE2000
tristate "NE2000/NE1000 support"
- depends on NET_ISA || (Q40 && m) || M32R
+ depends on NET_ISA || (Q40 && m) || M32R || TOSHIBA_RBTX4927 || TOSHIBA_RBTX4938
select CRC32
---help---
If you have a network (Ethernet) card of this type, say Y and read
@@ -2488,6 +2488,7 @@ config NETXEN_NIC
config PASEMI_MAC
tristate "PA Semi 1/10Gbit MAC"
depends on PPC64 && PCI
+ select PHYLIB
help
This driver supports the on-chip 1/10Gbit Ethernet controller on
PA Semi's PWRficient line of chips.
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
index 152fa7a..ef2cc80 100644
--- a/drivers/net/arm/at91_ether.c
+++ b/drivers/net/arm/at91_ether.c
@@ -225,6 +225,16 @@ static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id)
if (!(phy & ((1 << 2) | 1)))
goto done;
}
+ else if (lp->phy_type == MII_T78Q21x3_ID) { /* ack interrupt in Teridian PHY */
+ read_phy(lp->phy_address, MII_T78Q21INT_REG, &phy);
+ if (!(phy & ((1 << 2) | 1)))
+ goto done;
+ }
+ else if (lp->phy_type == MII_DP83848_ID) {
+ read_phy(lp->phy_address, MII_DPPHYSTS_REG, &phy); /* ack interrupt in DP83848 PHY */
+ if (!(phy & (1 << 7)))
+ goto done;
+ }
update_linkspeed(dev, 0);
@@ -280,6 +290,19 @@ static void enable_phyirq(struct net_device *dev)
dsintr = (1 << 10) | ( 1 << 8);
write_phy(lp->phy_address, MII_TPISTATUS, dsintr);
}
+ else if (lp->phy_type == MII_T78Q21x3_ID) { /* for Teridian PHY */
+ read_phy(lp->phy_address, MII_T78Q21INT_REG, &dsintr);
+ dsintr = dsintr | 0x500; /* set bits 8, 10 */
+ write_phy(lp->phy_address, MII_T78Q21INT_REG, dsintr);
+ }
+ else if (lp->phy_type == MII_DP83848_ID) { /* National Semiconductor DP83848 PHY */
+ read_phy(lp->phy_address, MII_DPMISR_REG, &dsintr);
+ dsintr = dsintr | 0x3c; /* set bits 2..5 */
+ write_phy(lp->phy_address, MII_DPMISR_REG, dsintr);
+ read_phy(lp->phy_address, MII_DPMICR_REG, &dsintr);
+ dsintr = dsintr | 0x3; /* set bits 0,1 */
+ write_phy(lp->phy_address, MII_DPMICR_REG, dsintr);
+ }
disable_mdi();
spin_unlock_irq(&lp->lock);
@@ -323,6 +346,19 @@ static void disable_phyirq(struct net_device *dev)
dsintr = ~((1 << 10) | (1 << 8));
write_phy(lp->phy_address, MII_TPISTATUS, dsintr);
}
+ else if (lp->phy_type == MII_T78Q21x3_ID) { /* for Teridian PHY */
+ read_phy(lp->phy_address, MII_T78Q21INT_REG, &dsintr);
+ dsintr = dsintr & ~0x500; /* clear bits 8, 10 */
+ write_phy(lp->phy_address, MII_T78Q21INT_REG, dsintr);
+ }
+ else if (lp->phy_type == MII_DP83848_ID) { /* National Semiconductor DP83848 PHY */
+ read_phy(lp->phy_address, MII_DPMICR_REG, &dsintr);
+ dsintr = dsintr & ~0x3; /* clear bits 0, 1 */
+ write_phy(lp->phy_address, MII_DPMICR_REG, dsintr);
+ read_phy(lp->phy_address, MII_DPMISR_REG, &dsintr);
+ dsintr = dsintr & ~0x3c; /* clear bits 2..5 */
+ write_phy(lp->phy_address, MII_DPMISR_REG, dsintr);
+ }
disable_mdi();
spin_unlock_irq(&lp->lock);
@@ -535,8 +571,8 @@ static void at91ether_sethashtable(struct net_device *dev)
mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
}
- at91_emac_write(AT91_EMAC_HSH, mc_filter[0]);
- at91_emac_write(AT91_EMAC_HSL, mc_filter[1]);
+ at91_emac_write(AT91_EMAC_HSL, mc_filter[0]);
+ at91_emac_write(AT91_EMAC_HSH, mc_filter[1]);
}
/*
@@ -1062,10 +1098,16 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
printk(KERN_INFO "%s: Broadcom BCM5221 PHY\n", dev->name);
else if (phy_type == MII_DP83847_ID)
printk(KERN_INFO "%s: National Semiconductor DP83847 PHY\n", dev->name);
+ else if (phy_type == MII_DP83848_ID)
+ printk(KERN_INFO "%s: National Semiconductor DP83848 PHY\n", dev->name);
else if (phy_type == MII_AC101L_ID)
printk(KERN_INFO "%s: Altima AC101L PHY\n", dev->name);
else if (phy_type == MII_KS8721_ID)
printk(KERN_INFO "%s: Micrel KS8721 PHY\n", dev->name);
+ else if (phy_type == MII_T78Q21x3_ID)
+ printk(KERN_INFO "%s: Teridian 78Q21x3 PHY\n", dev->name);
+ else if (phy_type == MII_LAN83C185_ID)
+ printk(KERN_INFO "%s: SMSC LAN83C185 PHY\n", dev->name);
return 0;
}
@@ -1103,8 +1145,11 @@ static int __init at91ether_probe(struct platform_device *pdev)
case MII_RTL8201_ID: /* Realtek RTL8201: PHY_ID1 = 0, PHY_ID2 = 0x8201 */
case MII_BCM5221_ID: /* Broadcom BCM5221: PHY_ID1 = 0x40, PHY_ID2 = 0x61e0 */
case MII_DP83847_ID: /* National Semiconductor DP83847: */
+ case MII_DP83848_ID: /* National Semiconductor DP83848: */
case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */
case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */
+ case MII_T78Q21x3_ID: /* Teridian 78Q21x3: PHY_ID1 = 0x0E, PHY_ID2 = 7237 */
+ case MII_LAN83C185_ID: /* SMSC LAN83C185: PHY_ID1 = 0x0007, PHY_ID2 = 0xC0A1 */
detected = at91ether_setup(phy_id, phy_address, pdev, ether_clk);
break;
}
diff --git a/drivers/net/arm/at91_ether.h b/drivers/net/arm/at91_ether.h
index b6b665d..a38fd2d 100644
--- a/drivers/net/arm/at91_ether.h
+++ b/drivers/net/arm/at91_ether.h
@@ -17,39 +17,46 @@
/* Davicom 9161 PHY */
-#define MII_DM9161_ID 0x0181b880
-#define MII_DM9161A_ID 0x0181b8a0
-
-/* Davicom specific registers */
-#define MII_DSCR_REG 16
-#define MII_DSCSR_REG 17
-#define MII_DSINTR_REG 21
+#define MII_DM9161_ID 0x0181b880
+#define MII_DM9161A_ID 0x0181b8a0
+#define MII_DSCR_REG 16
+#define MII_DSCSR_REG 17
+#define MII_DSINTR_REG 21
/* Intel LXT971A PHY */
-#define MII_LXT971A_ID 0x001378E0
-
-/* Intel specific registers */
-#define MII_ISINTE_REG 18
-#define MII_ISINTS_REG 19
-#define MII_LEDCTRL_REG 20
+#define MII_LXT971A_ID 0x001378E0
+#define MII_ISINTE_REG 18
+#define MII_ISINTS_REG 19
+#define MII_LEDCTRL_REG 20
/* Realtek RTL8201 PHY */
-#define MII_RTL8201_ID 0x00008200
+#define MII_RTL8201_ID 0x00008200
/* Broadcom BCM5221 PHY */
-#define MII_BCM5221_ID 0x004061e0
-
-/* Broadcom specific registers */
-#define MII_BCMINTR_REG 26
+#define MII_BCM5221_ID 0x004061e0
+#define MII_BCMINTR_REG 26
/* National Semiconductor DP83847 */
-#define MII_DP83847_ID 0x20005c30
+#define MII_DP83847_ID 0x20005c30
+
+/* National Semiconductor DP83848 */
+#define MII_DP83848_ID 0x20005c90
+#define MII_DPPHYSTS_REG 16
+#define MII_DPMICR_REG 17
+#define MII_DPMISR_REG 18
/* Altima AC101L PHY */
-#define MII_AC101L_ID 0x00225520
+#define MII_AC101L_ID 0x00225520
/* Micrel KS8721 PHY */
-#define MII_KS8721_ID 0x00221610
+#define MII_KS8721_ID 0x00221610
+
+/* Teridian 78Q2123/78Q2133 */
+#define MII_T78Q21x3_ID 0x000e7230
+#define MII_T78Q21INT_REG 17
+
+/* SMSC LAN83C185 */
+#define MII_LAN83C185_ID 0x0007C0A0
/* ........................................................................ */
diff --git a/drivers/net/atl1/atl1_ethtool.c b/drivers/net/atl1/atl1_ethtool.c
index c11c277..1f616c5 100644
--- a/drivers/net/atl1/atl1_ethtool.c
+++ b/drivers/net/atl1/atl1_ethtool.c
@@ -156,8 +156,7 @@ static int atl1_set_settings(struct net_device *netdev,
u16 old_media_type = hw->media_type;
if (netif_running(adapter->netdev)) {
- printk(KERN_DEBUG "%s: ethtool shutting down adapter\n",
- atl1_driver_name);
+ dev_dbg(&adapter->pdev->dev, "ethtool shutting down adapter\n");
atl1_down(adapter);
}
@@ -166,9 +165,8 @@ static int atl1_set_settings(struct net_device *netdev,
else {
if (ecmd->speed == SPEED_1000) {
if (ecmd->duplex != DUPLEX_FULL) {
- printk(KERN_WARNING
- "%s: can't force to 1000M half duplex\n",
- atl1_driver_name);
+ dev_warn(&adapter->pdev->dev,
+ "can't force to 1000M half duplex\n");
ret_val = -EINVAL;
goto exit_sset;
}
@@ -206,9 +204,8 @@ static int atl1_set_settings(struct net_device *netdev,
}
if (atl1_phy_setup_autoneg_adv(hw)) {
ret_val = -EINVAL;
- printk(KERN_WARNING
- "%s: invalid ethtool speed/duplex setting\n",
- atl1_driver_name);
+ dev_warn(&adapter->pdev->dev,
+ "invalid ethtool speed/duplex setting\n");
goto exit_sset;
}
if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
@@ -239,12 +236,10 @@ exit_sset:
hw->media_type = old_media_type;
if (netif_running(adapter->netdev)) {
- printk(KERN_DEBUG "%s: ethtool starting adapter\n",
- atl1_driver_name);
+ dev_dbg(&adapter->pdev->dev, "ethtool starting adapter\n");
atl1_up(adapter);
} else if (!ret_val) {
- printk(KERN_DEBUG "%s: ethtool resetting adapter\n",
- atl1_driver_name);
+ dev_dbg(&adapter->pdev->dev, "ethtool resetting adapter\n");
atl1_reset(adapter);
}
return ret_val;
diff --git a/drivers/net/atl1/atl1_hw.c b/drivers/net/atl1/atl1_hw.c
index 69482e0..ef886bd 100644
--- a/drivers/net/atl1/atl1_hw.c
+++ b/drivers/net/atl1/atl1_hw.c
@@ -2,20 +2,20 @@
* Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
* Copyright(c) 2006 Chris Snook <csnook@redhat.com>
* Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
- *
+ *
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- *
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
- *
+ *
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
- *
+ *
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
@@ -38,12 +38,13 @@
*/
s32 atl1_reset_hw(struct atl1_hw *hw)
{
+ struct pci_dev *pdev = hw->back->pdev;
u32 icr;
int i;
- /*
+ /*
* Clear Interrupt mask to stop board from generating
- * interrupts & Clear any pending interrupt events
+ * interrupts & Clear any pending interrupt events
*/
/*
* iowrite32(0, hw->hw_addr + REG_IMR);
@@ -74,7 +75,7 @@ s32 atl1_reset_hw(struct atl1_hw *hw)
}
if (icr) {
- printk (KERN_DEBUG "icr = %x\n", icr);
+ dev_dbg(&pdev->dev, "ICR = 0x%x\n", icr);
return icr;
}
@@ -136,8 +137,8 @@ s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data)
int i;
val = ((u32) (reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT |
- MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 <<
- MDIO_CLK_SEL_SHIFT;
+ MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 <<
+ MDIO_CLK_SEL_SHIFT;
iowrite32(val, hw->hw_addr + REG_MDIO_CTRL);
ioread32(hw->hw_addr + REG_MDIO_CTRL);
@@ -204,7 +205,7 @@ static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf)
/*
* get_permanent_address
- * return 0 if get valid mac address,
+ * return 0 if get valid mac address,
*/
static int atl1_get_permanent_address(struct atl1_hw *hw)
{
@@ -301,7 +302,7 @@ static int atl1_get_permanent_address(struct atl1_hw *hw)
}
/*
- * Reads the adapter's MAC address from the EEPROM
+ * Reads the adapter's MAC address from the EEPROM
* hw - Struct containing variables accessed by shared code
*/
s32 atl1_read_mac_addr(struct atl1_hw *hw)
@@ -437,6 +438,7 @@ s32 atl1_phy_enter_power_saving(struct atl1_hw *hw)
*/
static s32 atl1_phy_reset(struct atl1_hw *hw)
{
+ struct pci_dev *pdev = hw->back->pdev;
s32 ret_val;
u16 phy_data;
@@ -468,8 +470,7 @@ static s32 atl1_phy_reset(struct atl1_hw *hw)
u32 val;
int i;
/* pcie serdes link may be down! */
- printk(KERN_DEBUG "%s: autoneg caused pcie phy link down\n",
- atl1_driver_name);
+ dev_dbg(&pdev->dev, "pcie phy link down\n");
for (i = 0; i < 25; i++) {
msleep(1);
@@ -479,9 +480,7 @@ static s32 atl1_phy_reset(struct atl1_hw *hw)
}
if ((val & (MDIO_START | MDIO_BUSY)) != 0) {
- printk(KERN_WARNING
- "%s: pcie link down at least for 25ms\n",
- atl1_driver_name);
+ dev_warn(&pdev->dev, "pcie link down at least 25ms\n");
return ret_val;
}
}
@@ -571,6 +570,7 @@ s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw)
*/
static s32 atl1_setup_link(struct atl1_hw *hw)
{
+ struct pci_dev *pdev = hw->back->pdev;
s32 ret_val;
/*
@@ -581,15 +581,13 @@ static s32 atl1_setup_link(struct atl1_hw *hw)
*/
ret_val = atl1_phy_setup_autoneg_adv(hw);
if (ret_val) {
- printk(KERN_DEBUG "%s: error setting up autonegotiation\n",
- atl1_driver_name);
+ dev_dbg(&pdev->dev, "error setting up autonegotiation\n");
return ret_val;
}
/* SW.Reset , En-Auto-Neg if needed */
ret_val = atl1_phy_reset(hw);
if (ret_val) {
- printk(KERN_DEBUG "%s: error resetting the phy\n",
- atl1_driver_name);
+ dev_dbg(&pdev->dev, "error resetting phy\n");
return ret_val;
}
hw->phy_configured = true;
@@ -631,7 +629,7 @@ static void atl1_init_flash_opcode(struct atl1_hw *hw)
* Performs basic configuration of the adapter.
* hw - Struct containing variables accessed by shared code
* Assumes that the controller has previously been reset and is in a
- * post-reset uninitialized state. Initializes multicast table,
+ * post-reset uninitialized state. Initializes multicast table,
* and Calls routines to setup link
* Leaves the transmit and receive units disabled and uninitialized.
*/
@@ -669,6 +667,7 @@ s32 atl1_init_hw(struct atl1_hw *hw)
*/
s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
{
+ struct pci_dev *pdev = hw->back->pdev;
s32 ret_val;
u16 phy_data;
@@ -691,8 +690,7 @@ s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
*speed = SPEED_10;
break;
default:
- printk(KERN_DEBUG "%s: error getting speed\n",
- atl1_driver_name);
+ dev_dbg(&pdev->dev, "error getting speed\n");
return ATL1_ERR_PHY_SPEED;
break;
}
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index 4b1d4d1..d28f88b 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -188,8 +188,7 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
size = sizeof(struct atl1_buffer) * (tpd_ring->count + rfd_ring->count);
tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL);
if (unlikely(!tpd_ring->buffer_info)) {
- printk(KERN_WARNING "%s: kzalloc failed , size = D%d\n",
- atl1_driver_name, size);
+ dev_err(&pdev->dev, "kzalloc failed , size = D%d\n", size);
goto err_nomem;
}
rfd_ring->buffer_info =
@@ -207,9 +206,7 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
&ring_header->dma);
if (unlikely(!ring_header->desc)) {
- printk(KERN_WARNING
- "%s: pci_alloc_consistent failed, size = D%d\n",
- atl1_driver_name, size);
+ dev_err(&pdev->dev, "pci_alloc_consistent failed\n");
goto err_nomem;
}
@@ -373,8 +370,7 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC |
ERR_FLAG_CODE | ERR_FLAG_OV)) {
adapter->hw_csum_err++;
- printk(KERN_DEBUG "%s: rx checksum error\n",
- atl1_driver_name);
+ dev_dbg(&adapter->pdev->dev, "rx checksum error\n");
return;
}
}
@@ -393,8 +389,9 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
}
/* IPv4, but hardware thinks its checksum is wrong */
- printk(KERN_DEBUG "%s: hw csum wrong pkt_flag:%x, err_flag:%x\n",
- atl1_driver_name, rrd->pkt_flg, rrd->err_flg);
+ dev_dbg(&adapter->pdev->dev,
+ "hw csum wrong, pkt_flag:%x, err_flag:%x\n",
+ rrd->pkt_flg, rrd->err_flg);
skb->ip_summed = CHECKSUM_COMPLETE;
skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum);
adapter->hw_csum_err++;
@@ -507,14 +504,13 @@ chk_rrd:
/* rrd seems to be bad */
if (unlikely(i-- > 0)) {
/* rrd may not be DMAed completely */
- printk(KERN_DEBUG
- "%s: RRD may not be DMAed completely\n",
- atl1_driver_name);
+ dev_dbg(&adapter->pdev->dev,
+ "incomplete RRD DMA transfer\n");
udelay(1);
goto chk_rrd;
}
/* bad rrd */
- printk(KERN_DEBUG "%s: bad RRD\n", atl1_driver_name);
+ dev_dbg(&adapter->pdev->dev, "bad RRD\n");
/* see if update RFD index */
if (rrd->num_buf > 1) {
u16 num_buf;
@@ -685,8 +681,8 @@ static void atl1_check_for_link(struct atl1_adapter *adapter)
/* notify upper layer link down ASAP */
if (!(phy_data & BMSR_LSTATUS)) { /* Link Down */
if (netif_carrier_ok(netdev)) { /* old link state: Up */
- printk(KERN_INFO "%s: %s link is down\n",
- atl1_driver_name, netdev->name);
+ dev_info(&adapter->pdev->dev, "%s link is down\n",
+ netdev->name);
adapter->link_speed = SPEED_0;
netif_carrier_off(netdev);
netif_stop_queue(netdev);
@@ -731,8 +727,8 @@ static irqreturn_t atl1_intr(int irq, void *data)
/* check if PCIE PHY Link down */
if (status & ISR_PHY_LINKDOWN) {
- printk(KERN_DEBUG "%s: pcie phy link down %x\n",
- atl1_driver_name, status);
+ dev_dbg(&adapter->pdev->dev, "pcie phy link down %x\n",
+ status);
if (netif_running(adapter->netdev)) { /* reset MAC */
iowrite32(0, adapter->hw.hw_addr + REG_IMR);
schedule_work(&adapter->pcie_dma_to_rst_task);
@@ -742,9 +738,9 @@ static irqreturn_t atl1_intr(int irq, void *data)
/* check if DMA read/write error ? */
if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
- printk(KERN_DEBUG
- "%s: pcie DMA r/w error (status = 0x%x)\n",
- atl1_driver_name, status);
+ dev_dbg(&adapter->pdev->dev,
+ "pcie DMA r/w error (status = 0x%x)\n",
+ status);
iowrite32(0, adapter->hw.hw_addr + REG_IMR);
schedule_work(&adapter->pcie_dma_to_rst_task);
return IRQ_HANDLED;
@@ -762,14 +758,13 @@ static irqreturn_t atl1_intr(int irq, void *data)
/* rx exception */
if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |
+ ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
+ ISR_HOST_RRD_OV | ISR_CMB_RX))) {
+ if (status & (ISR_RXF_OV | ISR_RFD_UNRUN |
ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
- ISR_HOST_RRD_OV | ISR_CMB_RX))) {
- if (status &
- (ISR_RXF_OV | ISR_RFD_UNRUN | ISR_RRD_OV |
- ISR_HOST_RFD_UNRUN | ISR_HOST_RRD_OV))
- printk(KERN_INFO
- "%s: rx exception: status = 0x%x\n",
- atl1_driver_name, status);
+ ISR_HOST_RRD_OV))
+ dev_dbg(&adapter->pdev->dev,
+ "rx exception, ISR = 0x%x\n", status);
atl1_intr_rx(adapter);
}
@@ -874,8 +869,7 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
atl1_read_phy_reg(hw, MII_BMSR, &phy_data);
if (!(phy_data & BMSR_LSTATUS)) { /* link down */
if (netif_carrier_ok(netdev)) { /* old link state: Up */
- printk(KERN_INFO "%s: link is down\n",
- atl1_driver_name);
+ dev_info(&adapter->pdev->dev, "link is down\n");
adapter->link_speed = SPEED_0;
netif_carrier_off(netdev);
netif_stop_queue(netdev);
@@ -918,11 +912,11 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
adapter->link_speed = speed;
adapter->link_duplex = duplex;
atl1_setup_mac_ctrl(adapter);
- printk(KERN_INFO "%s: %s link is up %d Mbps %s\n",
- atl1_driver_name, netdev->name,
- adapter->link_speed,
- adapter->link_duplex ==
- FULL_DUPLEX ? "full duplex" : "half duplex");
+ dev_info(&adapter->pdev->dev,
+ "%s link is up %d Mbps %s\n",
+ netdev->name, adapter->link_speed,
+ adapter->link_duplex == FULL_DUPLEX ?
+ "full duplex" : "half duplex");
}
if (!netif_carrier_ok(netdev)) { /* Link down -> Up */
netif_carrier_on(netdev);
@@ -1330,8 +1324,8 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
cso = skb_transport_offset(skb);
css = cso + skb->csum_offset;
if (unlikely(cso & 0x1)) {
- printk(KERN_DEBUG "%s: payload offset != even number\n",
- atl1_driver_name);
+ dev_dbg(&adapter->pdev->dev,
+ "payload offset not an even number\n");
return -1;
}
csum->csumpl |= (cso & CSUM_PARAM_PLOADOFFSET_MASK) <<
@@ -1579,7 +1573,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (!spin_trylock(&adapter->lock)) {
/* Can't get lock - tell upper layer to requeue */
local_irq_restore(flags);
- printk(KERN_DEBUG "%s: TX locked\n", atl1_driver_name);
+ dev_dbg(&adapter->pdev->dev, "tx locked\n");
return NETDEV_TX_LOCKED;
}
@@ -1587,7 +1581,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* not enough descriptors */
netif_stop_queue(netdev);
spin_unlock_irqrestore(&adapter->lock, flags);
- printk(KERN_DEBUG "%s: TX busy\n", atl1_driver_name);
+ dev_dbg(&adapter->pdev->dev, "tx busy\n");
return NETDEV_TX_BUSY;
}
@@ -1841,8 +1835,7 @@ static int atl1_change_mtu(struct net_device *netdev, int new_mtu)
if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
(max_frame > MAX_JUMBO_FRAME_SIZE)) {
- printk(KERN_WARNING "%s: invalid MTU setting\n",
- atl1_driver_name);
+ dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
return -EINVAL;
}
@@ -2136,9 +2129,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
if (err) {
err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (err) {
- printk(KERN_DEBUG
- "%s: no usable DMA configuration, aborting\n",
- atl1_driver_name);
+ dev_err(&pdev->dev, "no usable DMA configuration\n");
goto err_dma;
}
pci_using_64 = false;
@@ -2175,7 +2166,9 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
goto err_pci_iomap;
}
/* get device revision number */
- adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr + (REG_MASTER_CTRL + 2));
+ adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr +
+ (REG_MASTER_CTRL + 2));
+ dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
/* set default ring resource counts */
adapter->rfd_ring.count = adapter->rrd_ring.count = ATL1_DEFAULT_RFD;
@@ -2466,8 +2459,6 @@ static void __exit atl1_exit_module(void)
*/
static int __init atl1_init_module(void)
{
- printk(KERN_INFO "%s - version %s\n", atl1_driver_string, DRIVER_VERSION);
- printk(KERN_INFO "%s\n", atl1_copyright);
return pci_register_driver(&atl1_driver);
}
diff --git a/drivers/net/atl1/atl1_param.c b/drivers/net/atl1/atl1_param.c
index bcd0bd8..4246bb9 100644
--- a/drivers/net/atl1/atl1_param.c
+++ b/drivers/net/atl1/atl1_param.c
@@ -23,6 +23,7 @@
#include <linux/types.h>
#include <linux/moduleparam.h>
+#include <linux/pci.h>
#include "atl1.h"
/*
@@ -93,7 +94,7 @@ struct atl1_option {
} arg;
};
-static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
+static int __devinit atl1_validate_option(int *value, struct atl1_option *opt, struct pci_dev *pdev)
{
if (*value == OPTION_UNSET) {
*value = opt->def;
@@ -104,19 +105,17 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
case enable_option:
switch (*value) {
case OPTION_ENABLED:
- printk(KERN_INFO "%s: %s Enabled\n", atl1_driver_name,
- opt->name);
+ dev_info(&pdev->dev, "%s enabled\n", opt->name);
return 0;
case OPTION_DISABLED:
- printk(KERN_INFO "%s: %s Disabled\n", atl1_driver_name,
- opt->name);
+ dev_info(&pdev->dev, "%s disabled\n", opt->name);
return 0;
}
break;
case range_option:
if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
- printk(KERN_INFO "%s: %s set to %i\n",
- atl1_driver_name, opt->name, *value);
+ dev_info(&pdev->dev, "%s set to %i\n", opt->name,
+ *value);
return 0;
}
break;
@@ -128,8 +127,8 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
ent = &opt->arg.l.p[i];
if (*value == ent->i) {
if (ent->str[0] != '\0')
- printk(KERN_INFO "%s: %s\n",
- atl1_driver_name, ent->str);
+ dev_info(&pdev->dev, "%s\n",
+ ent->str);
return 0;
}
}
@@ -140,8 +139,8 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
break;
}
- printk(KERN_INFO "%s: invalid %s specified (%i) %s\n",
- atl1_driver_name, opt->name, *value, opt->err);
+ dev_info(&pdev->dev, "invalid %s specified (%i) %s\n",
+ opt->name, *value, opt->err);
*value = opt->def;
return -1;
}
@@ -157,12 +156,11 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
*/
void __devinit atl1_check_options(struct atl1_adapter *adapter)
{
+ struct pci_dev *pdev = adapter->pdev;
int bd = adapter->bd_number;
if (bd >= ATL1_MAX_NIC) {
- printk(KERN_NOTICE "%s: warning: no configuration for board #%i\n",
- atl1_driver_name, bd);
- printk(KERN_NOTICE "%s: using defaults for all values\n",
- atl1_driver_name);
+ dev_notice(&pdev->dev, "no configuration for board#%i\n", bd);
+ dev_notice(&pdev->dev, "using defaults for all values\n");
}
{ /* Interrupt Moderate Timer */
struct atl1_option opt = {
@@ -177,7 +175,7 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter)
int val;
if (num_int_mod_timer > bd) {
val = int_mod_timer[bd];
- atl1_validate_option(&val, &opt);
+ atl1_validate_option(&val, &opt, pdev);
adapter->imt = (u16) val;
} else
adapter->imt = (u16) (opt.def);
@@ -197,7 +195,7 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter)
int val;
if (num_flash_vendor > bd) {
val = flash_vendor[bd];
- atl1_validate_option(&val, &opt);
+ atl1_validate_option(&val, &opt, pdev);
adapter->hw.flash_vendor = (u8) val;
} else
adapter->hw.flash_vendor = (u8) (opt.def);
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 4612725..9b8d7d9 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1260,9 +1260,10 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
printk(KERN_ERR "BMAC: can't use, need 3 addrs and 3 intrs\n");
return -ENODEV;
}
- prop_addr = get_property(macio_get_of_node(mdev), "mac-address", NULL);
+ prop_addr = of_get_property(macio_get_of_node(mdev),
+ "mac-address", NULL);
if (prop_addr == NULL) {
- prop_addr = get_property(macio_get_of_node(mdev),
+ prop_addr = of_get_property(macio_get_of_node(mdev),
"local-mac-address", NULL);
if (prop_addr == NULL) {
printk(KERN_ERR "BMAC: Can't get mac-address\n");
diff --git a/drivers/net/cxgb3/version.h b/drivers/net/cxgb3/version.h
index 042e27e..b112317 100644
--- a/drivers/net/cxgb3/version.h
+++ b/drivers/net/cxgb3/version.h
@@ -38,7 +38,7 @@
#define DRV_VERSION "1.0-ko"
/* Firmware version */
-#define FW_VERSION_MAJOR 3
-#define FW_VERSION_MINOR 3
+#define FW_VERSION_MAJOR 4
+#define FW_VERSION_MINOR 0
#define FW_VERSION_MICRO 0
#endif /* __CHELSIO_VERSION_H */
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 8cc1174..264fa0e 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -77,9 +77,6 @@
#define DM9000_PHY 0x40 /* PHY address 0x01 */
-#define TRUE 1
-#define FALSE 0
-
#define CARDNAME "dm9000"
#define PFX CARDNAME ": "
@@ -601,7 +598,7 @@ dm9000_probe(struct platform_device *pdev)
printk("%s: not found (%d).\n", CARDNAME, ret);
dm9000_release_board(pdev, db);
- kfree(ndev);
+ free_netdev(ndev);
return ret;
}
@@ -896,7 +893,7 @@ dm9000_rx(struct net_device *dev)
struct dm9000_rxhdr rxhdr;
struct sk_buff *skb;
u8 rxbyte, *rdptr;
- int GoodPacket;
+ bool GoodPacket;
int RxLen;
/* Check packet ready or not */
@@ -918,7 +915,7 @@ dm9000_rx(struct net_device *dev)
return;
/* A packet ready now & Get status/length */
- GoodPacket = TRUE;
+ GoodPacket = true;
writeb(DM9000_MRCMD, db->io_addr);
(db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));
@@ -927,7 +924,7 @@ dm9000_rx(struct net_device *dev)
/* Packet Status check */
if (RxLen < 0x40) {
- GoodPacket = FALSE;
+ GoodPacket = false;
PRINTK1("Bad Packet received (runt)\n");
}
@@ -936,7 +933,7 @@ dm9000_rx(struct net_device *dev)
}
if (rxhdr.RxStatus & 0xbf00) {
- GoodPacket = FALSE;
+ GoodPacket = false;
if (rxhdr.RxStatus & 0x100) {
PRINTK1("fifo error\n");
db->stats.rx_fifo_errors++;
@@ -1193,7 +1190,7 @@ dm9000_drv_remove(struct platform_device *pdev)
unregister_netdev(ndev);
dm9000_release_board(pdev, (board_info_t *) ndev->priv);
- kfree(ndev); /* free device structure */
+ free_netdev(ndev); /* free device structure */
PRINTK1("clean_module() exit\n");
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index c7a5614..f6e0cb1 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -1803,10 +1803,10 @@ static inline int ehea_hash_skb(struct sk_buff *skb, int num_qps)
u32 tmp;
if ((skb->protocol == htons(ETH_P_IP)) &&
- (skb->nh.iph->protocol == IPPROTO_TCP)) {
- tcp = (struct tcphdr*)(skb->nh.raw + (skb->nh.iph->ihl * 4));
+ (ip_hdr(skb)->protocol == IPPROTO_TCP)) {
+ tcp = (struct tcphdr*)(skb_network_header(skb) + (ip_hdr(skb)->ihl * 4));
tmp = (tcp->source + (tcp->dest << 16)) % 31;
- tmp += skb->nh.iph->daddr % 31;
+ tmp += ip_hdr(skb)->daddr % 31;
return tmp % num_qps;
}
else
@@ -2603,14 +2603,13 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
{
struct device_node *lhea_dn;
struct device_node *eth_dn = NULL;
-
- u32 *dn_log_port_id;
+ const u32 *dn_log_port_id;
int i = 0;
lhea_dn = adapter->ebus_dev->ofdev.node;
while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
- dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no",
+ dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
NULL);
if (!dn_log_port_id) {
ehea_error("bad device node: eth_dn name=%s",
@@ -2645,12 +2644,12 @@ static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter,
{
struct device_node *lhea_dn;
struct device_node *eth_dn = NULL;
- u32 *dn_log_port_id;
+ const u32 *dn_log_port_id;
lhea_dn = adapter->ebus_dev->ofdev.node;
while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
- dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no",
+ dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
NULL);
if (dn_log_port_id)
if (*dn_log_port_id == logical_port_id)
@@ -2774,7 +2773,7 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
const struct of_device_id *id)
{
struct ehea_adapter *adapter;
- u64 *adapter_handle;
+ const u64 *adapter_handle;
int ret;
if (!dev || !dev->ofdev.node) {
@@ -2791,7 +2790,7 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
adapter->ebus_dev = dev;
- adapter_handle = (u64*)get_property(dev->ofdev.node, "ibm,hea-handle",
+ adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle",
NULL);
if (adapter_handle)
adapter->handle = *adapter_handle;
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index fb196fd..55ff0fb 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -134,7 +134,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
DCSR(si->rxdma) &= ~DCSR_RUN;
/* disable FICP */
ICCR0 = 0;
- pxa_set_cken(CKEN13_FICP, 0);
+ pxa_set_cken(CKEN_FICP, 0);
/* set board transceiver to SIR mode */
si->pdata->transceiver_mode(si->dev, IR_SIRMODE);
@@ -144,7 +144,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
pxa_gpio_mode(GPIO47_STTXD_MD);
/* enable the STUART clock */
- pxa_set_cken(CKEN5_STUART, 1);
+ pxa_set_cken(CKEN_STUART, 1);
}
/* disable STUART first */
@@ -169,7 +169,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
/* disable STUART */
STIER = 0;
STISR = 0;
- pxa_set_cken(CKEN5_STUART, 0);
+ pxa_set_cken(CKEN_STUART, 0);
/* disable FICP first */
ICCR0 = 0;
@@ -182,7 +182,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
pxa_gpio_mode(GPIO47_ICPTXD_MD);
/* enable the FICP clock */
- pxa_set_cken(CKEN13_FICP, 1);
+ pxa_set_cken(CKEN_FICP, 1);
si->speed = speed;
pxa_irda_fir_dma_rx_start(si);
@@ -593,7 +593,7 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
/* disable STUART SIR mode */
STISR = 0;
/* disable the STUART clock */
- pxa_set_cken(CKEN5_STUART, 0);
+ pxa_set_cken(CKEN_STUART, 0);
/* disable DMA */
DCSR(si->txdma) &= ~DCSR_RUN;
@@ -601,7 +601,7 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
/* disable FICP */
ICCR0 = 0;
/* disable the FICP clock */
- pxa_set_cken(CKEN13_FICP, 0);
+ pxa_set_cken(CKEN_FICP, 0);
DRCMR17 = 0;
DRCMR18 = 0;
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index 17b0c3a..9d6c8f3 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -14,7 +14,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <net/irda/irda.h>
diff --git a/drivers/net/irda/sir_dongle.c b/drivers/net/irda/sir_dongle.c
index d7e32d9..25d5b8a 100644
--- a/drivers/net/irda/sir_dongle.c
+++ b/drivers/net/irda/sir_dongle.c
@@ -14,7 +14,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/kmod.h>
#include <linux/mutex.h>
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 198bf3b..9043bf4 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -79,11 +79,17 @@ MODULE_AUTHOR("Daniele Peri <peri@csai.unipa.it>");
MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver");
MODULE_LICENSE("GPL");
-static int ircc_dma = 255;
+static int smsc_nopnp;
+module_param_named(nopnp, smsc_nopnp, bool, 0);
+MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings");
+
+#define DMA_INVAL 255
+static int ircc_dma = DMA_INVAL;
module_param(ircc_dma, int, 0);
MODULE_PARM_DESC(ircc_dma, "DMA channel");
-static int ircc_irq = 255;
+#define IRQ_INVAL 255
+static int ircc_irq = IRQ_INVAL;
module_param(ircc_irq, int, 0);
MODULE_PARM_DESC(ircc_irq, "IRQ line");
@@ -360,7 +366,6 @@ static inline void register_bank(int iobase, int bank)
iobase + IRCC_MASTER);
}
-#ifdef CONFIG_PNP
/* PNP hotplug support */
static const struct pnp_device_id smsc_ircc_pnp_table[] = {
{ .id = "SMCf010", .driver_data = 0 },
@@ -368,7 +373,35 @@ static const struct pnp_device_id smsc_ircc_pnp_table[] = {
{ }
};
MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table);
-#endif
+
+static int pnp_driver_registered;
+
+static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev,
+ const struct pnp_device_id *dev_id)
+{
+ unsigned int firbase, sirbase;
+ u8 dma, irq;
+
+ if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
+ pnp_dma_valid(dev, 0) && pnp_irq_valid(dev, 0)))
+ return -EINVAL;
+
+ sirbase = pnp_port_start(dev, 0);
+ firbase = pnp_port_start(dev, 1);
+ dma = pnp_dma(dev, 0);
+ irq = pnp_irq(dev, 0);
+
+ if (smsc_ircc_open(firbase, sirbase, dma, irq))
+ return -ENODEV;
+
+ return 0;
+}
+
+static struct pnp_driver smsc_ircc_pnp_driver = {
+ .name = "smsc-ircc2",
+ .id_table = smsc_ircc_pnp_table,
+ .probe = smsc_ircc_pnp_probe,
+};
/*******************************************************************************
@@ -379,6 +412,35 @@ MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table);
*
*******************************************************************************/
+static int __init smsc_ircc_legacy_probe(void)
+{
+ int ret = 0;
+
+ if (ircc_fir > 0 && ircc_sir > 0) {
+ IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir);
+ IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir);
+
+ if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq))
+ ret = -ENODEV;
+ } else {
+ ret = -ENODEV;
+
+ /* try user provided configuration register base address */
+ if (ircc_cfg > 0) {
+ IRDA_MESSAGE(" Overriding configuration address "
+ "0x%04x\n", ircc_cfg);
+ if (!smsc_superio_fdc(ircc_cfg))
+ ret = 0;
+ if (!smsc_superio_lpc(ircc_cfg))
+ ret = 0;
+ }
+
+ if (smsc_ircc_look_for_chips() > 0)
+ ret = 0;
+ }
+ return ret;
+}
+
/*
* Function smsc_ircc_init ()
*
@@ -406,31 +468,20 @@ static int __init smsc_ircc_init(void)
dev_count = 0;
- if (ircc_fir > 0 && ircc_sir > 0) {
- IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir);
- IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir);
-
- if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq))
- ret = -ENODEV;
+ if (smsc_nopnp || !pnp_platform_devices ||
+ ircc_cfg || ircc_fir || ircc_sir ||
+ ircc_dma != DMA_INVAL || ircc_irq != IRQ_INVAL) {
+ ret = smsc_ircc_legacy_probe();
} else {
- ret = -ENODEV;
-
- /* try user provided configuration register base address */
- if (ircc_cfg > 0) {
- IRDA_MESSAGE(" Overriding configuration address "
- "0x%04x\n", ircc_cfg);
- if (!smsc_superio_fdc(ircc_cfg))
- ret = 0;
- if (!smsc_superio_lpc(ircc_cfg))
- ret = 0;
- }
-
- if (smsc_ircc_look_for_chips() > 0)
- ret = 0;
+ if (pnp_register_driver(&smsc_ircc_pnp_driver) == 0)
+ pnp_driver_registered = 1;
}
- if (ret)
+ if (ret) {
+ if (pnp_driver_registered)
+ pnp_unregister_driver(&smsc_ircc_pnp_driver);
platform_driver_unregister(&smsc_ircc_driver);
+ }
return ret;
}
@@ -646,7 +697,7 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self,
self->io.fifo_size = SMSC_IRCC2_FIFO_SIZE;
self->io.speed = SMSC_IRCC2_C_IRDA_FALLBACK_SPEED;
- if (irq < 255) {
+ if (irq != IRQ_INVAL) {
if (irq != chip_irq)
IRDA_MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n",
driver_name, chip_irq, irq);
@@ -654,7 +705,7 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self,
} else
self->io.irq = chip_irq;
- if (dma < 255) {
+ if (dma != DMA_INVAL) {
if (dma != chip_dma)
IRDA_MESSAGE("%s, Overriding DMA - chip says %d, using %d\n",
driver_name, chip_dma, dma);
@@ -1840,6 +1891,9 @@ static void __exit smsc_ircc_cleanup(void)
smsc_ircc_close(dev_self[i]);
}
+ if (pnp_driver_registered)
+ pnp_unregister_driver(&smsc_ircc_pnp_driver);
+
platform_driver_unregister(&smsc_ircc_driver);
}
@@ -2836,9 +2890,9 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
tmpconf.fir_io = ircc_fir;
if (ircc_sir != 0)
tmpconf.sir_io = ircc_sir;
- if (ircc_dma != 0xff)
+ if (ircc_dma != DMA_INVAL)
tmpconf.fir_dma = ircc_dma;
- if (ircc_irq != 0xff)
+ if (ircc_irq != IRQ_INVAL)
tmpconf.fir_irq = ircc_irq;
IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name);
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index c4be973..bf78ef1 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -44,7 +44,6 @@ MODULE_LICENSE("GPL");
#include <linux/time.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index b3bd623..52b9332 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -110,9 +110,9 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
return -ENODEV;
}
- addr = get_property(mace, "mac-address", NULL);
+ addr = of_get_property(mace, "mac-address", NULL);
if (addr == NULL) {
- addr = get_property(mace, "local-mac-address", NULL);
+ addr = of_get_property(mace, "local-mac-address", NULL);
if (addr == NULL) {
printk(KERN_ERR "Can't get mac-address for MACE %s\n",
mace->full_name);
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 16e3c43..5d14be7 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -290,6 +290,8 @@ MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n");
#define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8)
+static void myri10ge_set_multicast_list(struct net_device *dev);
+
static inline void put_be32(__be32 val, __be32 __iomem * p)
{
__raw_writel((__force __u32) val, (__force void __iomem *)p);
@@ -353,6 +355,8 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
return 0;
} else if (result == MXGEFW_CMD_UNKNOWN) {
return -ENOSYS;
+ } else if (result == MXGEFW_CMD_ERROR_UNALIGNED) {
+ return -E2BIG;
} else {
dev_err(&mgp->pdev->dev,
"command %d failed, result = %d\n",
@@ -712,14 +716,78 @@ myri10ge_change_promisc(struct myri10ge_priv *mgp, int promisc, int atomic)
mgp->dev->name);
}
-static int myri10ge_reset(struct myri10ge_priv *mgp)
+static int myri10ge_dma_test(struct myri10ge_priv *mgp, int test_type)
{
struct myri10ge_cmd cmd;
int status;
- size_t bytes;
u32 len;
struct page *dmatest_page;
dma_addr_t dmatest_bus;
+ char *test = " ";
+
+ dmatest_page = alloc_page(GFP_KERNEL);
+ if (!dmatest_page)
+ return -ENOMEM;
+ dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE,
+ DMA_BIDIRECTIONAL);
+
+ /* Run a small DMA test.
+ * The magic multipliers to the length tell the firmware
+ * to do DMA read, write, or read+write tests. The
+ * results are returned in cmd.data0. The upper 16
+ * bits or the return is the number of transfers completed.
+ * The lower 16 bits is the time in 0.5us ticks that the
+ * transfers took to complete.
+ */
+
+ len = mgp->tx.boundary;
+
+ cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+ cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
+ cmd.data2 = len * 0x10000;
+ status = myri10ge_send_cmd(mgp, test_type, &cmd, 0);
+ if (status != 0) {
+ test = "read";
+ goto abort;
+ }
+ mgp->read_dma = ((cmd.data0 >> 16) * len * 2) / (cmd.data0 & 0xffff);
+ cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+ cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
+ cmd.data2 = len * 0x1;
+ status = myri10ge_send_cmd(mgp, test_type, &cmd, 0);
+ if (status != 0) {
+ test = "write";
+ goto abort;
+ }
+ mgp->write_dma = ((cmd.data0 >> 16) * len * 2) / (cmd.data0 & 0xffff);
+
+ cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+ cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
+ cmd.data2 = len * 0x10001;
+ status = myri10ge_send_cmd(mgp, test_type, &cmd, 0);
+ if (status != 0) {
+ test = "read/write";
+ goto abort;
+ }
+ mgp->read_write_dma = ((cmd.data0 >> 16) * len * 2 * 2) /
+ (cmd.data0 & 0xffff);
+
+abort:
+ pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
+ put_page(dmatest_page);
+
+ if (status != 0 && test_type != MXGEFW_CMD_UNALIGNED_TEST)
+ dev_warn(&mgp->pdev->dev, "DMA %s benchmark failed: %d\n",
+ test, status);
+
+ return status;
+}
+
+static int myri10ge_reset(struct myri10ge_priv *mgp)
+{
+ struct myri10ge_cmd cmd;
+ int status;
+ size_t bytes;
/* try to send a reset command to the card to see if it
* is alive */
@@ -729,11 +797,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
dev_err(&mgp->pdev->dev, "failed reset\n");
return -ENXIO;
}
- dmatest_page = alloc_page(GFP_KERNEL);
- if (!dmatest_page)
- return -ENOMEM;
- dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE,
- DMA_BIDIRECTIONAL);
+
+ (void)myri10ge_dma_test(mgp, MXGEFW_DMA_TEST);
/* Now exchange information about interrupts */
@@ -761,52 +826,6 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
}
put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
- /* Run a small DMA test.
- * The magic multipliers to the length tell the firmware
- * to do DMA read, write, or read+write tests. The
- * results are returned in cmd.data0. The upper 16
- * bits or the return is the number of transfers completed.
- * The lower 16 bits is the time in 0.5us ticks that the
- * transfers took to complete.
- */
-
- len = mgp->tx.boundary;
-
- cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
- cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
- cmd.data2 = len * 0x10000;
- status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
- if (status == 0)
- mgp->read_dma = ((cmd.data0 >> 16) * len * 2) /
- (cmd.data0 & 0xffff);
- else
- dev_warn(&mgp->pdev->dev, "DMA read benchmark failed: %d\n",
- status);
- cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
- cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
- cmd.data2 = len * 0x1;
- status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
- if (status == 0)
- mgp->write_dma = ((cmd.data0 >> 16) * len * 2) /
- (cmd.data0 & 0xffff);
- else
- dev_warn(&mgp->pdev->dev, "DMA write benchmark failed: %d\n",
- status);
-
- cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
- cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
- cmd.data2 = len * 0x10001;
- status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
- if (status == 0)
- mgp->read_write_dma = ((cmd.data0 >> 16) * len * 2 * 2) /
- (cmd.data0 & 0xffff);
- else
- dev_warn(&mgp->pdev->dev,
- "DMA read/write benchmark failed: %d\n", status);
-
- pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
- put_page(dmatest_page);
-
memset(mgp->rx_done.entry, 0, bytes);
/* reset mcp/driver shared state back to 0 */
@@ -820,10 +839,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
mgp->rx_done.cnt = 0;
mgp->link_changes = 0;
status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr);
- myri10ge_change_promisc(mgp, 0, 0);
myri10ge_change_pause(mgp, mgp->pause);
- if (mgp->adopted_rx_filter_bug)
- (void)myri10ge_send_cmd(mgp, MXGEFW_ENABLE_ALLMULTI, &cmd, 1);
+ myri10ge_set_multicast_list(mgp->dev);
return status;
}
@@ -1355,7 +1372,9 @@ static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = {
"tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt",
"wake_queue", "stop_queue", "watchdog_resets", "tx_linearized",
"link_changes", "link_up", "dropped_link_overflow",
- "dropped_link_error_or_filtered", "dropped_multicast_filtered",
+ "dropped_link_error_or_filtered",
+ "dropped_pause", "dropped_bad_phy", "dropped_bad_crc32",
+ "dropped_unicast_filtered", "dropped_multicast_filtered",
"dropped_runt", "dropped_overrun", "dropped_no_small_buffer",
"dropped_no_big_buffer"
};
@@ -1412,6 +1431,11 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_overflow);
data[i++] =
(unsigned int)ntohl(mgp->fw_stats->dropped_link_error_or_filtered);
+ data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_pause);
+ data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_phy);
+ data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_crc32);
+ data[i++] =
+ (unsigned int)ntohl(mgp->fw_stats->dropped_unicast_filtered);
data[i++] =
(unsigned int)ntohl(mgp->fw_stats->dropped_multicast_filtered);
data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_runt);
@@ -2276,7 +2300,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev)
myri10ge_change_promisc(mgp, dev->flags & IFF_PROMISC, 1);
/* This firmware is known to not support multicast */
- if (!mgp->fw_multicast_support || mgp->adopted_rx_filter_bug)
+ if (!mgp->fw_multicast_support)
return;
/* Disable multicast filtering */
@@ -2288,7 +2312,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev)
goto abort;
}
- if (dev->flags & IFF_ALLMULTI) {
+ if ((dev->flags & IFF_ALLMULTI) || mgp->adopted_rx_filter_bug) {
/* request to disable multicast filtering, so quit here */
return;
}
@@ -2461,8 +2485,6 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
err_cap |= PCI_ERR_CAP_ECRC_GENE;
pci_write_config_dword(bridge, cap + PCI_ERR_CAP, err_cap);
dev_info(dev, "Enabled ECRC on upstream bridge %s\n", pci_name(bridge));
- mgp->tx.boundary = 4096;
- mgp->fw_name = myri10ge_fw_aligned;
}
/*
@@ -2484,22 +2506,70 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
* firmware image, and set tx.boundary to 4KB.
*/
-#define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7
-#define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa
-#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1 0x3510
-#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4 0x351b
-#define PCI_DEVICE_ID_INTEL_E3000_PCIE 0x2779
-#define PCI_DEVICE_ID_INTEL_E3010_PCIE 0x277a
-#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST 0x140
-#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST 0x142
-
-static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
+static void myri10ge_firmware_probe(struct myri10ge_priv *mgp)
{
- struct pci_dev *bridge = mgp->pdev->bus->self;
+ struct pci_dev *pdev = mgp->pdev;
+ struct device *dev = &pdev->dev;
+ int cap, status;
+ u16 val;
+
+ mgp->tx.boundary = 4096;
+ /*
+ * Verify the max read request size was set to 4KB
+ * before trying the test with 4KB.
+ */
+ cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+ if (cap < 64) {
+ dev_err(dev, "Bad PCI_CAP_ID_EXP location %d\n", cap);
+ goto abort;
+ }
+ status = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &val);
+ if (status != 0) {
+ dev_err(dev, "Couldn't read max read req size: %d\n", status);
+ goto abort;
+ }
+ if ((val & (5 << 12)) != (5 << 12)) {
+ dev_warn(dev, "Max Read Request size != 4096 (0x%x)\n", val);
+ mgp->tx.boundary = 2048;
+ }
+ /*
+ * load the optimized firmware (which assumes aligned PCIe
+ * completions) in order to see if it works on this host.
+ */
+ mgp->fw_name = myri10ge_fw_aligned;
+ status = myri10ge_load_firmware(mgp);
+ if (status != 0) {
+ goto abort;
+ }
+
+ /*
+ * Enable ECRC if possible
+ */
+ myri10ge_enable_ecrc(mgp);
+
+ /*
+ * Run a DMA test which watches for unaligned completions and
+ * aborts on the first one seen.
+ */
+ status = myri10ge_dma_test(mgp, MXGEFW_CMD_UNALIGNED_TEST);
+ if (status == 0)
+ return; /* keep the aligned firmware */
+
+ if (status != -E2BIG)
+ dev_warn(dev, "DMA test failed: %d\n", status);
+ if (status == -ENOSYS)
+ dev_warn(dev, "Falling back to ethp! "
+ "Please install up to date fw\n");
+abort:
+ /* fall back to using the unaligned firmware */
mgp->tx.boundary = 2048;
mgp->fw_name = myri10ge_fw_unaligned;
+}
+
+static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
+{
if (myri10ge_force_firmware == 0) {
int link_width, exp_cap;
u16 lnk;
@@ -2508,8 +2578,6 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
pci_read_config_word(mgp->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk);
link_width = (lnk >> 4) & 0x3f;
- myri10ge_enable_ecrc(mgp);
-
/* Check to see if Link is less than 8 or if the
* upstream bridge is known to provide aligned
* completions */
@@ -2518,46 +2586,8 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
link_width);
mgp->tx.boundary = 4096;
mgp->fw_name = myri10ge_fw_aligned;
- } else if (bridge &&
- /* ServerWorks HT2000/HT1000 */
- ((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
- && bridge->device ==
- PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE)
- /* ServerWorks HT2100 */
- || (bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
- && bridge->device >=
- PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST
- && bridge->device <=
- PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST)
- /* All Intel E3000/E3010 PCIE ports */
- || (bridge->vendor == PCI_VENDOR_ID_INTEL
- && (bridge->device ==
- PCI_DEVICE_ID_INTEL_E3000_PCIE
- || bridge->device ==
- PCI_DEVICE_ID_INTEL_E3010_PCIE))
- /* All Intel 6310/6311/6321ESB PCIE ports */
- || (bridge->vendor == PCI_VENDOR_ID_INTEL
- && bridge->device >=
- PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1
- && bridge->device <=
- PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4)
- /* All Intel E5000 PCIE ports */
- || (bridge->vendor == PCI_VENDOR_ID_INTEL
- && bridge->device >=
- PCI_DEVICE_ID_INTEL_E5000_PCIE23
- && bridge->device <=
- PCI_DEVICE_ID_INTEL_E5000_PCIE47))) {
- dev_info(&mgp->pdev->dev,
- "Assuming aligned completions (0x%x:0x%x)\n",
- bridge->vendor, bridge->device);
- mgp->tx.boundary = 4096;
- mgp->fw_name = myri10ge_fw_aligned;
- } else if (bridge &&
- bridge->vendor == PCI_VENDOR_ID_SGI &&
- bridge->device == 0x4002 /* TIOCE pcie-port */ ) {
- /* this pcie bridge does not support 4K rdma request */
- mgp->tx.boundary = 2048;
- mgp->fw_name = myri10ge_fw_aligned;
+ } else {
+ myri10ge_firmware_probe(mgp);
}
} else {
if (myri10ge_force_firmware == 1) {
@@ -2825,7 +2855,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
status = -ENODEV;
goto abort_with_netdev;
}
- myri10ge_select_firmware(mgp);
/* Find the vendor-specific cap so we can check
* the reboot register later on */
@@ -2919,6 +2948,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto abort_with_ioremap;
memset(mgp->rx_done.entry, 0, bytes);
+ myri10ge_select_firmware(mgp);
+
status = myri10ge_load_firmware(mgp);
if (status != 0) {
dev_err(&pdev->dev, "failed to load firmware\n");
diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h
index 29463b3..a1d2a22 100644
--- a/drivers/net/myri10ge/myri10ge_mcp.h
+++ b/drivers/net/myri10ge/myri10ge_mcp.h
@@ -200,6 +200,13 @@ enum myri10ge_mcp_cmd_type {
/* data0, data1 = bus addr,
* data2 = sizeof(struct mcp_irq_data) from driver point of view, allows
* adding new stuff to mcp_irq_data without changing the ABI */
+
+ MXGEFW_CMD_UNALIGNED_TEST,
+ /* same than DMA_TEST (same args) but abort with UNALIGNED on unaligned
+ * chipset */
+
+ MXGEFW_CMD_UNALIGNED_STATUS
+ /* return data = boolean, true if the chipset is known to be unaligned */
};
enum myri10ge_mcp_cmd_status {
@@ -212,18 +219,27 @@ enum myri10ge_mcp_cmd_status {
MXGEFW_CMD_ERROR_HASH_ERROR,
MXGEFW_CMD_ERROR_BAD_PORT,
MXGEFW_CMD_ERROR_RESOURCES,
- MXGEFW_CMD_ERROR_MULTICAST
+ MXGEFW_CMD_ERROR_MULTICAST,
+ MXGEFW_CMD_ERROR_UNALIGNED
};
#define MXGEFW_OLD_IRQ_DATA_LEN 40
struct mcp_irq_data {
/* add new counters at the beginning */
- __be32 future_use[5];
+ __be32 future_use[1];
+ __be32 dropped_pause;
+ __be32 dropped_unicast_filtered;
+ __be32 dropped_bad_crc32;
+ __be32 dropped_bad_phy;
__be32 dropped_multicast_filtered;
/* 40 Bytes */
__be32 send_done_count;
+#define MXGEFW_LINK_DOWN 0
+#define MXGEFW_LINK_UP 1
+#define MXGEFW_LINK_MYRINET 2
+#define MXGEFW_LINK_UNKNOWN 3
__be32 link_up;
__be32 dropped_link_overflow;
__be32 dropped_link_error_or_filtered;
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index a8d7ff2..223e0e6 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -81,6 +81,8 @@ static const int multicast_filter_limit = 100;
Setting to > 1518 effectively disables this feature. */
static int rx_copybreak;
+static int dspcfg_workaround = 1;
+
/* Used to pass the media type, etc.
Both 'options[]' and 'full_duplex[]' should exist for driver
interoperability.
@@ -139,12 +141,14 @@ MODULE_LICENSE("GPL");
module_param(mtu, int, 0);
module_param(debug, int, 0);
module_param(rx_copybreak, int, 0);
+module_param(dspcfg_workaround, int, 1);
module_param_array(options, int, NULL, 0);
module_param_array(full_duplex, int, NULL, 0);
MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)");
MODULE_PARM_DESC(debug, "DP8381x default debug level");
MODULE_PARM_DESC(rx_copybreak,
"DP8381x copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(dspcfg_workaround, "DP8381x: control DspCfg workaround");
MODULE_PARM_DESC(options,
"DP8381x: Bits 0-3: media type, bit 17: full duplex");
MODULE_PARM_DESC(full_duplex, "DP8381x full duplex setting(s) (1)");
@@ -590,6 +594,7 @@ struct netdev_private {
u32 srr;
/* expected DSPCFG value */
u16 dspcfg;
+ int dspcfg_workaround;
/* parms saved in ethtool format */
u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */
u8 duplex; /* Duplex, half or full */
@@ -656,6 +661,56 @@ static int netdev_get_regs(struct net_device *dev, u8 *buf);
static int netdev_get_eeprom(struct net_device *dev, u8 *buf);
static const struct ethtool_ops ethtool_ops;
+#define NATSEMI_ATTR(_name) \
+static ssize_t natsemi_show_##_name(struct device *dev, \
+ struct device_attribute *attr, char *buf); \
+ static ssize_t natsemi_set_##_name(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t count); \
+ static DEVICE_ATTR(_name, 0644, natsemi_show_##_name, natsemi_set_##_name)
+
+#define NATSEMI_CREATE_FILE(_dev, _name) \
+ device_create_file(&_dev->dev, &dev_attr_##_name)
+#define NATSEMI_REMOVE_FILE(_dev, _name) \
+ device_create_file(&_dev->dev, &dev_attr_##_name)
+
+NATSEMI_ATTR(dspcfg_workaround);
+
+static ssize_t natsemi_show_dspcfg_workaround(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct netdev_private *np = netdev_priv(to_net_dev(dev));
+
+ return sprintf(buf, "%s\n", np->dspcfg_workaround ? "on" : "off");
+}
+
+static ssize_t natsemi_set_dspcfg_workaround(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct netdev_private *np = netdev_priv(to_net_dev(dev));
+ int new_setting;
+ u32 flags;
+
+ /* Find out the new setting */
+ if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
+ new_setting = 1;
+ else if (!strncmp("off", buf, count - 1)
+ || !strncmp("0", buf, count - 1))
+ new_setting = 0;
+ else
+ return count;
+
+ spin_lock_irqsave(&np->lock, flags);
+
+ np->dspcfg_workaround = new_setting;
+
+ spin_unlock_irqrestore(&np->lock, flags);
+
+ return count;
+}
+
static inline void __iomem *ns_ioaddr(struct net_device *dev)
{
return (void __iomem *) dev->base_addr;
@@ -820,6 +875,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
np->ignore_phy = 1;
else
np->ignore_phy = 0;
+ np->dspcfg_workaround = dspcfg_workaround;
/* Initial port:
* - If configured to ignore the PHY set up for external.
@@ -899,6 +955,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
if (i)
goto err_register_netdev;
+ if (NATSEMI_CREATE_FILE(pdev, dspcfg_workaround))
+ goto err_create_file;
+
if (netif_msg_drv(np)) {
printk(KERN_INFO "natsemi %s: %s at %#08lx (%s), ",
dev->name, natsemi_pci_info[chip_idx].name, iostart,
@@ -915,6 +974,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
}
return 0;
+ err_create_file:
+ unregister_netdev(dev);
+
err_register_netdev:
iounmap(ioaddr);
@@ -1727,7 +1789,8 @@ static void init_registers(struct net_device *dev)
* It seems that a reference set for this chip went out with incorrect info,
* and there exist boards that aren't quite right. An unexpected voltage
* drop can cause the PHY to get itself in a weird state (basically reset).
- * NOTE: this only seems to affect revC chips.
+ * NOTE: this only seems to affect revC chips. The user can disable
+ * this check via dspcfg_workaround sysfs option.
* 3) check of death of the RX path due to OOM
*/
static void netdev_timer(unsigned long data)
@@ -1753,10 +1816,10 @@ static void netdev_timer(unsigned long data)
writew(1, ioaddr+PGSEL);
dspcfg = readw(ioaddr+DSPCFG);
writew(0, ioaddr+PGSEL);
- if (dspcfg != np->dspcfg) {
+ if (np->dspcfg_workaround && dspcfg != np->dspcfg) {
if (!netif_queue_stopped(dev)) {
spin_unlock_irq(&np->lock);
- if (netif_msg_hw(np))
+ if (netif_msg_drv(np))
printk(KERN_NOTICE "%s: possible phy reset: "
"re-initializing\n", dev->name);
disable_irq(dev->irq);
@@ -3157,6 +3220,7 @@ static void __devexit natsemi_remove1 (struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
void __iomem * ioaddr = ns_ioaddr(dev);
+ NATSEMI_REMOVE_FILE(pdev, dspcfg_workaround);
unregister_netdev (dev);
pci_release_regions (pdev);
iounmap(ioaddr);
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index a5c4199..c9f74bf 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -51,14 +51,11 @@ static const char version2[] =
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/jiffies.h>
+#include <linux/platform_device.h>
#include <asm/system.h>
#include <asm/io.h>
-#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
-#include <asm/tx4938/rbtx4938.h>
-#endif
-
#include "8390.h"
#define DRV_NAME "ne"
@@ -77,8 +74,13 @@ static const char version2[] =
/* Do we have a non std. amount of memory? (in units of 256 byte pages) */
/* #define PACKETBUF_MEMSIZE 0x40 */
+#if !defined(MODULE) && (defined(CONFIG_ISA) || defined(CONFIG_M32R))
+/* Do we need a portlist for the ISA auto-probe ? */
+#define NEEDS_PORTLIST
+#endif
+
/* A zero-terminated list of I/O addresses to be probed at boot. */
-#ifndef MODULE
+#ifdef NEEDS_PORTLIST
static unsigned int netcard_portlist[] __initdata = {
0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0
};
@@ -146,7 +148,7 @@ bad_clone_list[] __initdata = {
# define DCR_VAL 0x49
#endif
-static int ne_probe1(struct net_device *dev, int ioaddr);
+static int ne_probe1(struct net_device *dev, unsigned long ioaddr);
static int ne_probe_isapnp(struct net_device *dev);
static int ne_open(struct net_device *dev);
@@ -184,8 +186,8 @@ static void ne_block_output(struct net_device *dev, const int count,
static int __init do_ne_probe(struct net_device *dev)
{
- unsigned int base_addr = dev->base_addr;
-#ifndef MODULE
+ unsigned long base_addr = dev->base_addr;
+#ifdef NEEDS_PORTLIST
int orig_irq = dev->irq;
#endif
@@ -201,7 +203,7 @@ static int __init do_ne_probe(struct net_device *dev)
if (isapnp_present() && (ne_probe_isapnp(dev) == 0))
return 0;
-#ifndef MODULE
+#ifdef NEEDS_PORTLIST
/* Last resort. The semi-risky ISA auto-probe. */
for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) {
int ioaddr = netcard_portlist[base_addr];
@@ -226,10 +228,6 @@ struct net_device * __init ne_probe(int unit)
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
-#ifdef CONFIG_TOSHIBA_RBTX4938
- dev->base_addr = RBTX4938_RTL_8019_BASE;
- dev->irq = RBTX4938_RTL_8019_IRQ;
-#endif
err = do_ne_probe(dev);
if (err)
goto out;
@@ -285,7 +283,7 @@ static int __init ne_probe_isapnp(struct net_device *dev)
return -ENODEV;
}
-static int __init ne_probe1(struct net_device *dev, int ioaddr)
+static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
{
int i;
unsigned char SA_prom[32];
@@ -324,7 +322,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
if (ei_debug && version_printed++ == 0)
printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2);
- printk(KERN_INFO "NE*000 ethercard probe at %#3x:", ioaddr);
+ printk(KERN_INFO "NE*000 ethercard probe at %#3lx:", ioaddr);
/* A user with a poor card that fails to ack the reset, or that
does not have a valid 0x57,0x57 signature can still use this
@@ -516,8 +514,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
}
#endif
- printk("\n%s: %s found at %#x, using IRQ %d.\n",
- dev->name, name, ioaddr, dev->irq);
+ printk("\n");
ei_status.name = name;
ei_status.tx_start_page = start_page;
@@ -547,6 +544,8 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
ret = register_netdev(dev);
if (ret)
goto out_irq;
+ printk(KERN_INFO "%s: %s found at %#lx, using IRQ %d.\n",
+ dev->name, name, ioaddr, dev->irq);
return 0;
out_irq:
@@ -807,6 +806,87 @@ retry:
return;
}
+static int __init ne_drv_probe(struct platform_device *pdev)
+{
+ struct net_device *dev;
+ struct resource *res;
+ int err, irq;
+
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!res || irq < 0)
+ return -ENODEV;
+
+ dev = alloc_ei_netdev();
+ if (!dev)
+ return -ENOMEM;
+ dev->irq = irq;
+ dev->base_addr = res->start;
+ err = do_ne_probe(dev);
+ if (err) {
+ free_netdev(dev);
+ return err;
+ }
+ platform_set_drvdata(pdev, dev);
+ return 0;
+}
+
+static int __exit ne_drv_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+
+ unregister_netdev(dev);
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, NE_IO_EXTENT);
+ free_netdev(dev);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ne_drv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+
+ if (netif_running(dev))
+ netif_device_detach(dev);
+ return 0;
+}
+
+static int ne_drv_resume(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+
+ if (netif_running(dev)) {
+ ne_reset_8390(dev);
+ NS8390_init(dev, 1);
+ netif_device_attach(dev);
+ }
+ return 0;
+}
+#else
+#define ne_drv_suspend NULL
+#define ne_drv_resume NULL
+#endif
+
+static struct platform_driver ne_driver = {
+ .remove = __exit_p(ne_drv_remove),
+ .suspend = ne_drv_suspend,
+ .resume = ne_drv_resume,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ne_init(void)
+{
+ return platform_driver_probe(&ne_driver, ne_drv_probe);
+}
+
+static void __exit ne_exit(void)
+{
+ platform_driver_unregister(&ne_driver);
+}
#ifdef MODULE
#define MAX_NE_CARDS 4 /* Max number of NE cards per module */
@@ -832,6 +912,7 @@ ISA device autoprobes on a running machine are not recommended anyway. */
int __init init_module(void)
{
int this_dev, found = 0;
+ int plat_found = !ne_init();
for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
struct net_device *dev = alloc_ei_netdev();
@@ -845,7 +926,7 @@ int __init init_module(void)
continue;
}
free_netdev(dev);
- if (found)
+ if (found || plat_found)
break;
if (io[this_dev] != 0)
printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]);
@@ -853,7 +934,7 @@ int __init init_module(void)
printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n");
return -ENXIO;
}
- if (found)
+ if (found || plat_found)
return 0;
return -ENODEV;
}
@@ -871,6 +952,7 @@ void __exit cleanup_module(void)
{
int this_dev;
+ ne_exit();
for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
struct net_device *dev = dev_ne[this_dev];
if (dev) {
@@ -880,4 +962,7 @@ void __exit cleanup_module(void)
}
}
}
+#else /* MODULE */
+module_init(ne_init);
+module_exit(ne_exit);
#endif /* MODULE */
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 6a32338..3439f8c 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -104,7 +104,6 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
-#include <linux/smp_lock.h>
#include <linux/workqueue.h>
#include <linux/init.h>
#include <linux/ip.h> /* for iph */
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 76fe9dd..bc7f3dee 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -33,6 +33,8 @@
#include <linux/tcp.h>
#include <net/checksum.h>
+#include <asm/irq.h>
+
#include "pasemi_mac.h"
@@ -51,6 +53,16 @@
#define RX_RING_SIZE 512
#define TX_RING_SIZE 512
+#define DEFAULT_MSG_ENABLE \
+ (NETIF_MSG_DRV | \
+ NETIF_MSG_PROBE | \
+ NETIF_MSG_LINK | \
+ NETIF_MSG_TIMER | \
+ NETIF_MSG_IFDOWN | \
+ NETIF_MSG_IFUP | \
+ NETIF_MSG_RX_ERR | \
+ NETIF_MSG_TX_ERR)
+
#define TX_DESC(mac, num) ((mac)->tx->desc[(num) & (TX_RING_SIZE-1)])
#define TX_DESC_INFO(mac, num) ((mac)->tx->desc_info[(num) & (TX_RING_SIZE-1)])
#define RX_DESC(mac, num) ((mac)->rx->desc[(num) & (RX_RING_SIZE-1)])
@@ -59,11 +71,13 @@
#define BUF_SIZE 1646 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
-/* XXXOJN these should come out of the device tree some day */
-#define PAS_DMA_CAP_BASE 0xe00d0040
-#define PAS_DMA_CAP_SIZE 0x100
-#define PAS_DMA_COM_BASE 0xe00d0100
-#define PAS_DMA_COM_SIZE 0x100
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
+MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver");
+
+static int debug = -1; /* -1 == use DEFAULT_MSG_ENABLE as value */
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value");
static struct pasdma_status *dma_status;
@@ -80,7 +94,12 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac)
return -ENOENT;
}
- maddr = get_property(dn, "mac-address", NULL);
+ maddr = of_get_property(dn, "local-mac-address", NULL);
+
+ /* Fall back to mac-address for older firmware */
+ if (maddr == NULL)
+ maddr = of_get_property(dn, "mac-address", NULL);
+
if (maddr == NULL) {
dev_warn(&pdev->dev,
"no mac address in device tree, not configuring\n");
@@ -277,8 +296,8 @@ static void pasemi_mac_free_rx_resources(struct net_device *dev)
for (i = 0; i < RX_RING_SIZE; i++) {
info = &RX_DESC_INFO(mac, i);
dp = &RX_DESC(mac, i);
- if (info->dma) {
- if (info->skb) {
+ if (info->skb) {
+ if (info->dma) {
pci_unmap_single(mac->dma_pdev,
info->dma,
info->skb->len,
@@ -309,82 +328,120 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev)
struct pasemi_mac *mac = netdev_priv(dev);
unsigned int i;
int start = mac->rx->next_to_fill;
- unsigned int count;
+ unsigned int limit, count;
- count = (mac->rx->next_to_clean + RX_RING_SIZE -
+ limit = (mac->rx->next_to_clean + RX_RING_SIZE -
mac->rx->next_to_fill) & (RX_RING_SIZE - 1);
/* Check to see if we're doing first-time setup */
if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0))
- count = RX_RING_SIZE;
+ limit = RX_RING_SIZE;
- if (count <= 0)
+ if (limit <= 0)
return;
- for (i = start; i < start + count; i++) {
+ i = start;
+ for (count = limit; count; count--) {
struct pasemi_mac_buffer *info = &RX_DESC_INFO(mac, i);
u64 *buff = &RX_BUFF(mac, i);
struct sk_buff *skb;
dma_addr_t dma;
- skb = dev_alloc_skb(BUF_SIZE);
+ /* skb might still be in there for recycle on short receives */
+ if (info->skb)
+ skb = info->skb;
+ else
+ skb = dev_alloc_skb(BUF_SIZE);
- if (!skb) {
- count = i - start;
+ if (unlikely(!skb))
break;
- }
dma = pci_map_single(mac->dma_pdev, skb->data, skb->len,
PCI_DMA_FROMDEVICE);
- if (dma_mapping_error(dma)) {
+ if (unlikely(dma_mapping_error(dma))) {
dev_kfree_skb_irq(info->skb);
- count = i - start;
break;
}
info->skb = skb;
info->dma = dma;
*buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma);
+ i++;
}
wmb();
pci_write_config_dword(mac->dma_pdev,
PAS_DMA_RXCHAN_INCR(mac->dma_rxch),
- count);
+ limit - count);
pci_write_config_dword(mac->dma_pdev,
PAS_DMA_RXINT_INCR(mac->dma_if),
- count);
+ limit - count);
- mac->rx->next_to_fill += count;
+ mac->rx->next_to_fill += limit - count;
}
+static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac)
+{
+ unsigned int reg, stat;
+ /* Re-enable packet count interrupts: finally
+ * ack the packet count interrupt we got in rx_intr.
+ */
+
+ pci_read_config_dword(mac->iob_pdev,
+ PAS_IOB_DMA_RXCH_STAT(mac->dma_rxch),
+ &stat);
+
+ reg = PAS_IOB_DMA_RXCH_RESET_PCNT(stat & PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
+ | PAS_IOB_DMA_RXCH_RESET_PINTC;
+
+ pci_write_config_dword(mac->iob_pdev,
+ PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch),
+ reg);
+}
+
+static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac)
+{
+ unsigned int reg, stat;
+
+ /* Re-enable packet count interrupts */
+ pci_read_config_dword(mac->iob_pdev,
+ PAS_IOB_DMA_TXCH_STAT(mac->dma_txch), &stat);
+
+ reg = PAS_IOB_DMA_TXCH_RESET_PCNT(stat & PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
+ | PAS_IOB_DMA_TXCH_RESET_PINTC;
+
+ pci_write_config_dword(mac->iob_pdev,
+ PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg);
+}
+
+
static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
{
- unsigned int i;
- int start, count;
+ unsigned int n;
+ int count;
+ struct pas_dma_xct_descr *dp;
+ struct pasemi_mac_buffer *info;
+ struct sk_buff *skb;
+ unsigned int i, len;
+ u64 macrx;
+ dma_addr_t dma;
spin_lock(&mac->rx->lock);
- start = mac->rx->next_to_clean;
- count = 0;
+ n = mac->rx->next_to_clean;
- for (i = start; i < (start + RX_RING_SIZE) && count < limit; i++) {
- struct pas_dma_xct_descr *dp;
- struct pasemi_mac_buffer *info;
- struct sk_buff *skb;
- unsigned int j, len;
- dma_addr_t dma;
+ for (count = limit; count; count--) {
rmb();
- dp = &RX_DESC(mac, i);
+ dp = &RX_DESC(mac, n);
+ macrx = dp->macrx;
- if (!(dp->macrx & XCT_MACRX_O))
+ if (!(macrx & XCT_MACRX_O))
break;
- count++;
info = NULL;
@@ -396,29 +453,42 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
*/
dma = (dp->ptr & XCT_PTR_ADDR_M);
- for (j = start; j < (start + RX_RING_SIZE); j++) {
- info = &RX_DESC_INFO(mac, j);
+ for (i = n; i < (n + RX_RING_SIZE); i++) {
+ info = &RX_DESC_INFO(mac, i);
if (info->dma == dma)
break;
}
- BUG_ON(!info);
- BUG_ON(info->dma != dma);
+ skb = info->skb;
+ info->dma = 0;
- pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len,
+ pci_unmap_single(mac->dma_pdev, dma, skb->len,
PCI_DMA_FROMDEVICE);
- skb = info->skb;
-
- len = (dp->macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
+ len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
+
+ if (len < 256) {
+ struct sk_buff *new_skb =
+ netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN);
+ if (new_skb) {
+ skb_reserve(new_skb, NET_IP_ALIGN);
+ memcpy(new_skb->data - NET_IP_ALIGN,
+ skb->data - NET_IP_ALIGN,
+ len + NET_IP_ALIGN);
+ /* save the skb in buffer_info as good */
+ skb = new_skb;
+ }
+ /* else just continue with the old one */
+ } else
+ info->skb = NULL;
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, mac->netdev);
- if ((dp->macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) {
+ if ((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) {
skb->ip_summed = CHECKSUM_COMPLETE;
- skb->csum = (dp->macrx & XCT_MACRX_CSUM_M) >>
+ skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
XCT_MACRX_CSUM_S;
} else
skb->ip_summed = CHECKSUM_NONE;
@@ -428,13 +498,13 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
netif_receive_skb(skb);
- info->dma = 0;
- info->skb = NULL;
dp->ptr = 0;
dp->macrx = 0;
+
+ n++;
}
- mac->rx->next_to_clean += count;
+ mac->rx->next_to_clean += limit - count;
pasemi_mac_replenish_rx_ring(mac->netdev);
spin_unlock(&mac->rx->lock);
@@ -476,6 +546,8 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
mac->tx->next_to_clean += count;
spin_unlock_irqrestore(&mac->tx->lock, flags);
+ netif_wake_queue(mac->netdev);
+
return count;
}
@@ -486,18 +558,28 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data)
struct pasemi_mac *mac = netdev_priv(dev);
unsigned int reg;
- if (!(*mac->rx_status & PAS_STATUS_INT))
+ if (!(*mac->rx_status & PAS_STATUS_CAUSE_M))
return IRQ_NONE;
- netif_rx_schedule(dev);
- pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG,
- PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0));
+ if (*mac->rx_status & PAS_STATUS_ERROR)
+ printk("rx_status reported error\n");
+
+ /* Don't reset packet count so it won't fire again but clear
+ * all others.
+ */
+
+ pci_read_config_dword(mac->dma_pdev, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), &reg);
- reg = PAS_IOB_DMA_RXCH_RESET_PINTC | PAS_IOB_DMA_RXCH_RESET_SINTC |
- PAS_IOB_DMA_RXCH_RESET_DINTC;
+ reg = 0;
+ if (*mac->rx_status & PAS_STATUS_SOFT)
+ reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
+ if (*mac->rx_status & PAS_STATUS_ERROR)
+ reg |= PAS_IOB_DMA_RXCH_RESET_DINTC;
if (*mac->rx_status & PAS_STATUS_TIMER)
reg |= PAS_IOB_DMA_RXCH_RESET_TINTC;
+ netif_rx_schedule(dev);
+
pci_write_config_dword(mac->iob_pdev,
PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg);
@@ -510,31 +592,137 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data)
struct net_device *dev = data;
struct pasemi_mac *mac = netdev_priv(dev);
unsigned int reg;
- int was_full;
- was_full = mac->tx->next_to_clean - mac->tx->next_to_use == TX_RING_SIZE;
-
- if (!(*mac->tx_status & PAS_STATUS_INT))
+ if (!(*mac->tx_status & PAS_STATUS_CAUSE_M))
return IRQ_NONE;
pasemi_mac_clean_tx(mac);
- reg = PAS_IOB_DMA_TXCH_RESET_PINTC | PAS_IOB_DMA_TXCH_RESET_SINTC;
- if (*mac->tx_status & PAS_STATUS_TIMER)
- reg |= PAS_IOB_DMA_TXCH_RESET_TINTC;
+ reg = PAS_IOB_DMA_TXCH_RESET_PINTC;
+
+ if (*mac->tx_status & PAS_STATUS_SOFT)
+ reg |= PAS_IOB_DMA_TXCH_RESET_SINTC;
+ if (*mac->tx_status & PAS_STATUS_ERROR)
+ reg |= PAS_IOB_DMA_TXCH_RESET_DINTC;
pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch),
reg);
- if (was_full)
- netif_wake_queue(dev);
-
return IRQ_HANDLED;
}
+static void pasemi_adjust_link(struct net_device *dev)
+{
+ struct pasemi_mac *mac = netdev_priv(dev);
+ int msg;
+ unsigned int flags;
+ unsigned int new_flags;
+
+ if (!mac->phydev->link) {
+ /* If no link, MAC speed settings don't matter. Just report
+ * link down and return.
+ */
+ if (mac->link && netif_msg_link(mac))
+ printk(KERN_INFO "%s: Link is down.\n", dev->name);
+
+ netif_carrier_off(dev);
+ mac->link = 0;
+
+ return;
+ } else
+ netif_carrier_on(dev);
+
+ pci_read_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, &flags);
+ new_flags = flags & ~(PAS_MAC_CFG_PCFG_HD | PAS_MAC_CFG_PCFG_SPD_M |
+ PAS_MAC_CFG_PCFG_TSR_M);
+
+ if (!mac->phydev->duplex)
+ new_flags |= PAS_MAC_CFG_PCFG_HD;
+
+ switch (mac->phydev->speed) {
+ case 1000:
+ new_flags |= PAS_MAC_CFG_PCFG_SPD_1G |
+ PAS_MAC_CFG_PCFG_TSR_1G;
+ break;
+ case 100:
+ new_flags |= PAS_MAC_CFG_PCFG_SPD_100M |
+ PAS_MAC_CFG_PCFG_TSR_100M;
+ break;
+ case 10:
+ new_flags |= PAS_MAC_CFG_PCFG_SPD_10M |
+ PAS_MAC_CFG_PCFG_TSR_10M;
+ break;
+ default:
+ printk("Unsupported speed %d\n", mac->phydev->speed);
+ }
+
+ /* Print on link or speed/duplex change */
+ msg = mac->link != mac->phydev->link || flags != new_flags;
+
+ mac->duplex = mac->phydev->duplex;
+ mac->speed = mac->phydev->speed;
+ mac->link = mac->phydev->link;
+
+ if (new_flags != flags)
+ pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, new_flags);
+
+ if (msg && netif_msg_link(mac))
+ printk(KERN_INFO "%s: Link is up at %d Mbps, %s duplex.\n",
+ dev->name, mac->speed, mac->duplex ? "full" : "half");
+}
+
+static int pasemi_mac_phy_init(struct net_device *dev)
+{
+ struct pasemi_mac *mac = netdev_priv(dev);
+ struct device_node *dn, *phy_dn;
+ struct phy_device *phydev;
+ unsigned int phy_id;
+ const phandle *ph;
+ const unsigned int *prop;
+ struct resource r;
+ int ret;
+
+ dn = pci_device_to_OF_node(mac->pdev);
+ ph = of_get_property(dn, "phy-handle", NULL);
+ if (!ph)
+ return -ENODEV;
+ phy_dn = of_find_node_by_phandle(*ph);
+
+ prop = of_get_property(phy_dn, "reg", NULL);
+ ret = of_address_to_resource(phy_dn->parent, 0, &r);
+ if (ret)
+ goto err;
+
+ phy_id = *prop;
+ snprintf(mac->phy_id, BUS_ID_SIZE, PHY_ID_FMT, (int)r.start, phy_id);
+
+ of_node_put(phy_dn);
+
+ mac->link = 0;
+ mac->speed = 0;
+ mac->duplex = -1;
+
+ phydev = phy_connect(dev, mac->phy_id, &pasemi_adjust_link, 0, PHY_INTERFACE_MODE_SGMII);
+
+ if (IS_ERR(phydev)) {
+ printk(KERN_ERR "%s: Could not attach to phy\n", dev->name);
+ return PTR_ERR(phydev);
+ }
+
+ mac->phydev = phydev;
+
+ return 0;
+
+err:
+ of_node_put(phy_dn);
+ return -ENODEV;
+}
+
+
static int pasemi_mac_open(struct net_device *dev)
{
struct pasemi_mac *mac = netdev_priv(dev);
+ int base_irq;
unsigned int flags;
int ret;
@@ -558,10 +746,18 @@ static int pasemi_mac_open(struct net_device *dev)
flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G;
pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch),
- PAS_IOB_DMA_RXCH_CFG_CNTTH(30));
+ PAS_IOB_DMA_RXCH_CFG_CNTTH(1));
+ pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch),
+ PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
+
+ /* Clear out any residual packet count state from firmware */
+ pasemi_mac_restart_rx_intr(mac);
+ pasemi_mac_restart_tx_intr(mac);
+
+ /* 0xffffff is max value, about 16ms */
pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG,
- PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000));
+ PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff));
pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, flags);
@@ -595,31 +791,50 @@ static int pasemi_mac_open(struct net_device *dev)
pasemi_mac_replenish_rx_ring(dev);
+ ret = pasemi_mac_phy_init(dev);
+ /* Some configs don't have PHYs (XAUI etc), so don't complain about
+ * failed init due to -ENODEV.
+ */
+ if (ret && ret != -ENODEV)
+ dev_warn(&mac->pdev->dev, "phy init failed: %d\n", ret);
+
netif_start_queue(dev);
netif_poll_enable(dev);
- ret = request_irq(mac->dma_pdev->irq + mac->dma_txch,
- &pasemi_mac_tx_intr, IRQF_DISABLED,
+ /* Interrupts are a bit different for our DMA controller: While
+ * it's got one a regular PCI device header, the interrupt there
+ * is really the base of the range it's using. Each tx and rx
+ * channel has it's own interrupt source.
+ */
+
+ base_irq = virq_to_hw(mac->dma_pdev->irq);
+
+ mac->tx_irq = irq_create_mapping(NULL, base_irq + mac->dma_txch);
+ mac->rx_irq = irq_create_mapping(NULL, base_irq + 20 + mac->dma_txch);
+
+ ret = request_irq(mac->tx_irq, &pasemi_mac_tx_intr, IRQF_DISABLED,
mac->tx->irq_name, dev);
if (ret) {
dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
- mac->dma_pdev->irq + mac->dma_txch, ret);
+ base_irq + mac->dma_txch, ret);
goto out_tx_int;
}
- ret = request_irq(mac->dma_pdev->irq + 20 + mac->dma_rxch,
- &pasemi_mac_rx_intr, IRQF_DISABLED,
+ ret = request_irq(mac->rx_irq, &pasemi_mac_rx_intr, IRQF_DISABLED,
mac->rx->irq_name, dev);
if (ret) {
dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
- mac->dma_pdev->irq + 20 + mac->dma_rxch, ret);
+ base_irq + 20 + mac->dma_rxch, ret);
goto out_rx_int;
}
+ if (mac->phydev)
+ phy_start(mac->phydev);
+
return 0;
out_rx_int:
- free_irq(mac->dma_pdev->irq + mac->dma_txch, dev);
+ free_irq(mac->tx_irq, dev);
out_tx_int:
netif_poll_disable(dev);
netif_stop_queue(dev);
@@ -639,6 +854,11 @@ static int pasemi_mac_close(struct net_device *dev)
unsigned int stat;
int retries;
+ if (mac->phydev) {
+ phy_stop(mac->phydev);
+ phy_disconnect(mac->phydev);
+ }
+
netif_stop_queue(dev);
/* Clean out any pending buffers */
@@ -660,40 +880,37 @@ static int pasemi_mac_close(struct net_device *dev)
pci_read_config_dword(mac->dma_pdev,
PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch),
&stat);
- if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
+ if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
break;
cond_resched();
}
- if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)) {
+ if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel\n");
- }
for (retries = 0; retries < MAX_RETRIES; retries++) {
pci_read_config_dword(mac->dma_pdev,
PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch),
&stat);
- if (stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)
+ if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT))
break;
cond_resched();
}
- if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)) {
+ if (stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)
dev_err(&mac->dma_pdev->dev, "Failed to stop rx channel\n");
- }
for (retries = 0; retries < MAX_RETRIES; retries++) {
pci_read_config_dword(mac->dma_pdev,
PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
&stat);
- if (stat & PAS_DMA_RXINT_RCMDSTA_ACT)
+ if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT))
break;
cond_resched();
}
- if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT)) {
+ if (stat & PAS_DMA_RXINT_RCMDSTA_ACT)
dev_err(&mac->dma_pdev->dev, "Failed to stop rx interface\n");
- }
/* Then, disable the channel. This must be done separately from
* stopping, since you can't disable when active.
@@ -706,8 +923,8 @@ static int pasemi_mac_close(struct net_device *dev)
pci_write_config_dword(mac->dma_pdev,
PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0);
- free_irq(mac->dma_pdev->irq + mac->dma_txch, dev);
- free_irq(mac->dma_pdev->irq + 20 + mac->dma_rxch, dev);
+ free_irq(mac->tx_irq, dev);
+ free_irq(mac->rx_irq, dev);
/* Free resources */
pasemi_mac_free_rx_resources(dev);
@@ -802,6 +1019,7 @@ static struct net_device_stats *pasemi_mac_get_stats(struct net_device *dev)
return &mac->stats;
}
+
static void pasemi_mac_set_rx_mode(struct net_device *dev)
{
struct pasemi_mac *mac = netdev_priv(dev);
@@ -826,18 +1044,17 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget)
pkts = pasemi_mac_clean_rx(mac, limit);
+ dev->quota -= pkts;
+ *budget -= pkts;
+
if (pkts < limit) {
/* all done, no more packets present */
netif_rx_complete(dev);
- /* re-enable receive interrupts */
- pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG,
- PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000));
+ pasemi_mac_restart_rx_intr(mac);
return 0;
} else {
/* used up our quantum, so reschedule */
- dev->quota -= pkts;
- *budget -= pkts;
return 1;
}
}
@@ -937,6 +1154,11 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
mac->rx_status = &dma_status->rx_sta[mac->dma_rxch];
mac->tx_status = &dma_status->tx_sta[mac->dma_txch];
+ mac->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
+
+ /* Enable most messages by default */
+ mac->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
+
err = register_netdev(dev);
if (err) {
@@ -1011,9 +1233,5 @@ int pasemi_mac_init_module(void)
return pci_register_driver(&pasemi_mac_driver);
}
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
-MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver");
-
module_init(pasemi_mac_init_module);
module_exit(pasemi_mac_cleanup_module);
diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h
index c3e37e4..8bc0cea 100644
--- a/drivers/net/pasemi_mac.h
+++ b/drivers/net/pasemi_mac.h
@@ -24,6 +24,7 @@
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
+#include <linux/phy.h>
struct pasemi_mac_txring {
spinlock_t lock;
@@ -54,6 +55,7 @@ struct pasemi_mac {
struct pci_dev *pdev;
struct pci_dev *dma_pdev;
struct pci_dev *iob_pdev;
+ struct phy_device *phydev;
struct net_device_stats stats;
/* Pointer to the cacheable per-channel status registers */
@@ -73,6 +75,14 @@ struct pasemi_mac {
struct pasemi_mac_txring *tx;
struct pasemi_mac_rxring *rx;
+ unsigned long tx_irq;
+ unsigned long rx_irq;
+ int link;
+ int speed;
+ int duplex;
+
+ unsigned int msg_enable;
+ char phy_id[BUS_ID_SIZE];
};
/* Software status descriptor (desc_info) */
@@ -193,11 +203,15 @@ enum {
#define PAS_DMA_RXINT_RCMDSTA(i) (0x200+(i)*_PAS_DMA_RXINT_STRIDE)
#define PAS_DMA_RXINT_RCMDSTA_EN 0x00000001
#define PAS_DMA_RXINT_RCMDSTA_ST 0x00000002
-#define PAS_DMA_RXINT_RCMDSTA_OO 0x00000100
-#define PAS_DMA_RXINT_RCMDSTA_BP 0x00000200
-#define PAS_DMA_RXINT_RCMDSTA_DR 0x00000400
+#define PAS_DMA_RXINT_RCMDSTA_MBT 0x00000008
+#define PAS_DMA_RXINT_RCMDSTA_MDR 0x00000010
+#define PAS_DMA_RXINT_RCMDSTA_MOO 0x00000020
+#define PAS_DMA_RXINT_RCMDSTA_MBP 0x00000040
#define PAS_DMA_RXINT_RCMDSTA_BT 0x00000800
-#define PAS_DMA_RXINT_RCMDSTA_TB 0x00001000
+#define PAS_DMA_RXINT_RCMDSTA_DR 0x00001000
+#define PAS_DMA_RXINT_RCMDSTA_OO 0x00002000
+#define PAS_DMA_RXINT_RCMDSTA_BP 0x00004000
+#define PAS_DMA_RXINT_RCMDSTA_TB 0x00008000
#define PAS_DMA_RXINT_RCMDSTA_ACT 0x00010000
#define PAS_DMA_RXINT_RCMDSTA_DROPS_M 0xfffe0000
#define PAS_DMA_RXINT_RCMDSTA_DROPS_S 17
@@ -297,6 +311,7 @@ enum {
#define PAS_STATUS_DCNT_S 16
#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull
#define PAS_STATUS_BPCNT_S 32
+#define PAS_STATUS_CAUSE_M 0xf000000000000000ull
#define PAS_STATUS_TIMER 0x1000000000000000ull
#define PAS_STATUS_ERROR 0x2000000000000000ull
#define PAS_STATUS_SOFT 0x4000000000000000ull
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index 809ec44..258d6f3 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -1420,7 +1420,7 @@ set_addresses(struct net_device *dev)
kio_addr_t ioaddr = dev->base_addr;
local_info_t *lp = netdev_priv(dev);
struct dev_mc_list *dmi = dev->mc_list;
- char *addr;
+ unsigned char *addr;
int i,j,k,n;
SelectPage(k=0x50);
@@ -1429,6 +1429,9 @@ set_addresses(struct net_device *dev)
if (++n > 9)
break;
i = 0;
+ if (n > 1 && n <= dev->mc_count && dmi) {
+ dmi = dmi->next;
+ }
}
if (j > 15) {
j = 8;
@@ -1436,10 +1439,9 @@ set_addresses(struct net_device *dev)
SelectPage(k);
}
- if (n && n <= dev->mc_count && dmi) {
+ if (n && n <= dev->mc_count && dmi)
addr = dmi->dmi_addr;
- dmi = dmi->next;
- } else
+ else
addr = dev->dev_addr;
if (lp->mohawk)
@@ -1465,10 +1467,10 @@ set_multicast_list(struct net_device *dev)
if (dev->flags & IFF_PROMISC) { /* snoop */
PutByte(XIRCREG42_SWC1, 0x06); /* set MPE and PME */
} else if (dev->mc_count > 9 || (dev->flags & IFF_ALLMULTI)) {
- PutByte(XIRCREG42_SWC1, 0x06); /* set MPE */
+ PutByte(XIRCREG42_SWC1, 0x02); /* set MPE */
} else if (dev->mc_count) {
/* the chip can filter 9 addresses perfectly */
- PutByte(XIRCREG42_SWC1, 0x00);
+ PutByte(XIRCREG42_SWC1, 0x01);
SelectPage(0x40);
PutByte(XIRCREG40_CMD0, Offline);
set_addresses(dev);
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 6d596ca..5411687 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -40,7 +40,6 @@
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/rwsem.h>
#include <linux/stddef.h>
#include <linux/device.h>
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 21afe10..b07da10 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -135,10 +135,13 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
/* Wake on Lan only supported on Yukon chips with rev 1 or above */
static u32 wol_supported(const struct skge_hw *hw)
{
- if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev != 0)
- return WAKE_MAGIC | WAKE_PHY;
- else
+ if (hw->chip_id == CHIP_ID_GENESIS)
return 0;
+
+ if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0)
+ return 0;
+
+ return WAKE_MAGIC | WAKE_PHY;
}
static u32 pci_wake_enabled(struct pci_dev *dev)
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 238c2ca..a307310 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -124,10 +124,7 @@ static const struct pci_device_id sky2_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */
-#ifdef broken
- /* This device causes data corruption problems that are not resolved */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */
-#endif
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
@@ -3581,10 +3578,21 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
goto err_out;
}
+ /* Some Gigabyte motherboards have 88e8056 but cause problems
+ * There is some unresolved hardware related problem that causes
+ * descriptor errors and receive data corruption.
+ */
+ if (pdev->vendor == PCI_VENDOR_ID_MARVELL &&
+ pdev->device == 0x4364 && pdev->subsystem_vendor == 0x1458) {
+ dev_err(&pdev->dev,
+ "88E8056 on Gigabyte motherboards not supported\n");
+ goto err_out_disable;
+ }
+
err = pci_request_regions(pdev, DRV_NAME);
if (err) {
dev_err(&pdev->dev, "cannot obtain PCI resources\n");
- goto err_out;
+ goto err_out_disable;
}
pci_set_master(pdev);
@@ -3721,6 +3729,7 @@ err_out_free_hw:
kfree(hw);
err_out_free_regions:
pci_release_regions(pdev);
+err_out_disable:
pci_disable_device(pdev);
err_out:
return err;
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index d2767e6..111f23d 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -55,6 +55,53 @@
#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
+#elif defined(CONFIG_BFIN)
+
+#define SMC_IRQ_FLAGS IRQF_TRIGGER_HIGH
+
+# if defined (CONFIG_BFIN561_EZKIT)
+#define SMC_CAN_USE_8BIT 0
+#define SMC_CAN_USE_16BIT 1
+#define SMC_CAN_USE_32BIT 1
+#define SMC_IO_SHIFT 0
+#define SMC_NOWAIT 1
+#define SMC_USE_BFIN_DMA 0
+
+
+#define SMC_inw(a, r) readw((a) + (r))
+#define SMC_outw(v, a, r) writew(v, (a) + (r))
+#define SMC_inl(a, r) readl((a) + (r))
+#define SMC_outl(v, a, r) writel(v, (a) + (r))
+#define SMC_outsl(a, r, p, l) outsl((unsigned long *)((a) + (r)), p, l)
+#define SMC_insl(a, r, p, l) insl ((unsigned long *)((a) + (r)), p, l)
+# else
+#define SMC_CAN_USE_8BIT 0
+#define SMC_CAN_USE_16BIT 1
+#define SMC_CAN_USE_32BIT 0
+#define SMC_IO_SHIFT 0
+#define SMC_NOWAIT 1
+#define SMC_USE_BFIN_DMA 0
+
+
+#define SMC_inw(a, r) readw((a) + (r))
+#define SMC_outw(v, a, r) writew(v, (a) + (r))
+#define SMC_outsw(a, r, p, l) outsw((unsigned long *)((a) + (r)), p, l)
+#define SMC_insw(a, r, p, l) insw ((unsigned long *)((a) + (r)), p, l)
+# endif
+/* check if the mac in reg is valid */
+#define SMC_GET_MAC_ADDR(addr) \
+ do { \
+ unsigned int __v; \
+ __v = SMC_inw(ioaddr, ADDR0_REG); \
+ addr[0] = __v; addr[1] = __v >> 8; \
+ __v = SMC_inw(ioaddr, ADDR1_REG); \
+ addr[2] = __v; addr[3] = __v >> 8; \
+ __v = SMC_inw(ioaddr, ADDR2_REG); \
+ addr[4] = __v; addr[5] = __v >> 8; \
+ if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) { \
+ random_ether_addr(addr); \
+ } \
+ } while (0)
#elif defined(CONFIG_REDWOOD_5) || defined(CONFIG_REDWOOD_6)
/* We can only do 16-bit reads and writes in the static memory space. */
@@ -232,6 +279,40 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
+#elif defined(CONFIG_SUPERH)
+
+#if defined(CONFIG_SH_7780_SOLUTION_ENGINE) || defined(CONFIG_SH_7722_SOLUTION_ENGINE)
+#define SMC_CAN_USE_8BIT 0
+#define SMC_CAN_USE_16BIT 1
+#define SMC_CAN_USE_32BIT 0
+#define SMC_IO_SHIFT 0
+#define SMC_NOWAIT 1
+
+#define SMC_inb(a, r) (inw((a) + ((r)&~1)) >> (8*(r%2)))&0xff
+#define SMC_inw(a, r) inw((a) + (r))
+#define SMC_outb(v, a, r) outw(((inw((a)+((r)&~1))*(0xff<<8*(r%2)))) | ((v)<<(8*(r&2)))), (a) + ((r)&~1))
+
+#define SMC_outw(v, a, r) outw(v, (a) + (r))
+#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
+
+#else /* BOARDS */
+
+#define SMC_CAN_USE_8BIT 1
+#define SMC_CAN_USE_16BIT 1
+#define SMC_CAN_USE_32BIT 1
+
+#define SMC_inb(a, r) inb((a) + (r))
+#define SMC_inw(a, r) inw((a) + (r))
+#define SMC_outb(v, a, r) outb(v, (a) + (r))
+#define SMC_outw(v, a, r) outw(v, (a) + (r))
+#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
+
+#endif /* BOARDS */
+
+#define set_irq_type(irq, type) do {} while (0)
+
#elif defined(CONFIG_M32R)
#define SMC_CAN_USE_8BIT 0
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 230da14..c15e972 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1830,7 +1830,7 @@ try_host_fw:
if (!dn)
goto out_err;
- fw_prop = get_property(dn, "firmware", &fw_size);
+ fw_prop = of_get_property(dn, "firmware", &fw_size);
if (!fw_prop)
goto out_err;
@@ -2236,7 +2236,7 @@ spider_net_setup_netdev(struct spider_net_card *card)
if (!dn)
return -EIO;
- mac = get_property(dn, "local-mac-address", NULL);
+ mac = of_get_property(dn, "local-mac-address", NULL);
if (!mac)
return -EIO;
memcpy(addr.sa_data, mac, ETH_ALEN);
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 5da7321..4328038 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2903,7 +2903,7 @@ static int __devinit gem_get_device_address(struct gem *gp)
struct net_device *dev = gp->dev;
const unsigned char *addr;
- addr = get_property(gp->of_node, "local-mac-address", NULL);
+ addr = of_get_property(gp->of_node, "local-mac-address", NULL);
if (addr == NULL) {
#ifdef CONFIG_SPARC
addr = idprom->id_ethaddr;
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c
index 56a110c..61843fd 100644
--- a/drivers/net/sungem_phy.c
+++ b/drivers/net/sungem_phy.c
@@ -451,7 +451,7 @@ static int bcm5421_init(struct mii_phy* phy)
if (phy->platform_data) {
struct device_node *np = of_get_parent(phy->platform_data);
int can_low_power = 1;
- if (np == NULL || get_property(np, "no-autolowpower", NULL))
+ if (np == NULL || of_get_property(np, "no-autolowpower", NULL))
can_low_power = 0;
if (can_low_power) {
/* Enable automatic low-power */
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index f1e2dfc..463d600 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -540,7 +540,6 @@ static struct sk_buff *alloc_rxbuf_skb(struct net_device *dev,
skb = dev_alloc_skb(RX_BUF_SIZE);
if (!skb)
return NULL;
- skb->dev = dev;
*dma_handle = pci_map_single(hwdev, skb->data, RX_BUF_SIZE,
PCI_DMA_FROMDEVICE);
if (pci_dma_mapping_error(*dma_handle)) {
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 59d6e74..e5e901e 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -64,8 +64,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.75"
-#define DRV_MODULE_RELDATE "March 23, 2007"
+#define DRV_MODULE_VERSION "3.76"
+#define DRV_MODULE_RELDATE "May 5, 2007"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -3019,6 +3019,16 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
}
}
+ if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND) {
+ u32 val = tr32(PCIE_PWR_MGMT_THRESH);
+ if (!netif_carrier_ok(tp->dev))
+ val = (val & ~PCIE_PWR_MGMT_L1_THRESH_MSK) |
+ tp->pwrmgmt_thresh;
+ else
+ val |= PCIE_PWR_MGMT_L1_THRESH_MSK;
+ tw32(PCIE_PWR_MGMT_THRESH, val);
+ }
+
return err;
}
@@ -3580,8 +3590,12 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
* Writing non-zero to intr-mbox-0 additional tells the
* NIC to stop sending us irqs, engaging "in-intr-handler"
* event coalescing.
+ *
+ * Flush the mailbox to de-assert the IRQ immediately to prevent
+ * spurious interrupts. The flush impacts performance but
+ * excessive spurious interrupts can be worse in some cases.
*/
- tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+ tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
if (tg3_irq_sync(tp))
goto out;
sblk->status &= ~SD_STATUS_UPDATED;
@@ -3625,8 +3639,12 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
* writing non-zero to intr-mbox-0 additional tells the
* NIC to stop sending us irqs, engaging "in-intr-handler"
* event coalescing.
+ *
+ * Flush the mailbox to de-assert the IRQ immediately to prevent
+ * spurious interrupts. The flush impacts performance but
+ * excessive spurious interrupts can be worse in some cases.
*/
- tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+ tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
if (tg3_irq_sync(tp))
goto out;
if (netif_rx_schedule_prep(dev)) {
@@ -10004,6 +10022,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
tp->tg3_flags2 |= TG3_FLG2_IS_NIC;
}
+ if (tr32(VCPU_CFGSHDW) & VCPU_CFGSHDW_ASPM_DBNC)
+ tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
return;
}
@@ -10131,6 +10151,14 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
/* bootcode if bit 18 is set */
if (cfg2 & (1 << 18))
tp->tg3_flags2 |= TG3_FLG2_SERDES_PREEMPHASIS;
+
+ if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
+ u32 cfg3;
+
+ tg3_read_mem(tp, NIC_SRAM_DATA_CFG_3, &cfg3);
+ if (cfg3 & NIC_SRAM_ASPM_DEBOUNCE)
+ tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
+ }
}
}
@@ -10998,6 +11026,10 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
*/
tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE;
+ if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND)
+ tp->pwrmgmt_thresh = tr32(PCIE_PWR_MGMT_THRESH) &
+ PCIE_PWR_MGMT_L1_THRESH_MSK;
+
return err;
}
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index dcdfc08..4d334cf 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1150,6 +1150,9 @@
#define VCPU_STATUS_INIT_DONE 0x04000000
#define VCPU_STATUS_DRV_RESET 0x08000000
+#define VCPU_CFGSHDW 0x00005104
+#define VCPU_CFGSHDW_ASPM_DBNC 0x00001000
+
/* Mailboxes */
#define GRCMBOX_BASE 0x00005600
#define GRCMBOX_INTERRUPT_0 0x00005800 /* 64-bit */
@@ -1507,6 +1510,8 @@
#define PCIE_TRANS_CFG_1SHOT_MSI 0x20000000
#define PCIE_TRANS_CFG_LOM 0x00000020
+#define PCIE_PWR_MGMT_THRESH 0x00007d28
+#define PCIE_PWR_MGMT_L1_THRESH_MSK 0x0000ff00
#define TG3_EEPROM_MAGIC 0x669955aa
#define TG3_EEPROM_MAGIC_FW 0xa5000000
@@ -1593,6 +1598,9 @@
#define SHASTA_EXT_LED_MAC 0x00010000
#define SHASTA_EXT_LED_COMBO 0x00018000
+#define NIC_SRAM_DATA_CFG_3 0x00000d3c
+#define NIC_SRAM_ASPM_DEBOUNCE 0x00000002
+
#define NIC_SRAM_RX_MINI_BUFFER_DESC 0x00001000
#define NIC_SRAM_DMA_DESC_POOL_BASE 0x00002000
@@ -2200,6 +2208,7 @@ struct tg3 {
#define TG3_FLAG_USE_LINKCHG_REG 0x00000008
#define TG3_FLAG_USE_MI_INTERRUPT 0x00000010
#define TG3_FLAG_ENABLE_ASF 0x00000020
+#define TG3_FLAG_ASPM_WORKAROUND 0x00000040
#define TG3_FLAG_POLL_SERDES 0x00000080
#define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100
#define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200
@@ -2288,6 +2297,7 @@ struct tg3 {
u32 grc_local_ctrl;
u32 dma_rwctrl;
u32 coalesce_mode;
+ u32 pwrmgmt_thresh;
/* PCI block */
u16 pci_chip_rev_id;
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 0bfc2c9..1aabc91 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -82,6 +82,7 @@ struct tsi108_prv_data {
unsigned int phy; /* Index of PHY for this interface */
unsigned int irq_num;
unsigned int id;
+ unsigned int phy_type;
struct timer_list timer;/* Timer that triggers the check phy function */
unsigned int rxtail; /* Next entry in rxring to read */
@@ -1256,11 +1257,11 @@ static void tsi108_init_phy(struct net_device *dev)
if (i == 0)
printk(KERN_ERR "%s function time out \n", __FUNCTION__);
-#if (TSI108_PHY_TYPE == PHY_BCM54XX) /* Broadcom BCM54xx PHY */
- tsi108_write_mii(data, 0x09, 0x0300);
- tsi108_write_mii(data, 0x10, 0x1020);
- tsi108_write_mii(data, 0x1c, 0x8c00);
-#endif
+ if (data->phy_type == TSI108_PHY_BCM54XX) {
+ tsi108_write_mii(data, 0x09, 0x0300);
+ tsi108_write_mii(data, 0x10, 0x1020);
+ tsi108_write_mii(data, 0x1c, 0x8c00);
+ }
tsi108_write_mii(data,
MII_BMCR,
@@ -1587,6 +1588,7 @@ tsi108_init_one(struct platform_device *pdev)
data->mii_if.supports_gmii = mii_check_gmii_support(&data->mii_if);
data->phy = einfo->phy;
+ data->phy_type = einfo->phy_type;
data->irq_num = einfo->irq_num;
data->id = pdev->id;
dev->open = tsi108_open;
diff --git a/drivers/net/tsi108_eth.h b/drivers/net/tsi108_eth.h
index 77a769d..5a77ae6 100644
--- a/drivers/net/tsi108_eth.h
+++ b/drivers/net/tsi108_eth.h
@@ -43,15 +43,6 @@
in_be32((data->phyregs + (offset)))
/*
- * PHY Configuration Options
- *
- * NOTE: Enable set of definitions corresponding to your board type
- */
-#define PHY_MV88E 1 /* Marvel 88Exxxx PHY */
-#define PHY_BCM54XX 2 /* Broardcom BCM54xx PHY */
-#define TSI108_PHY_TYPE PHY_MV88E
-
-/*
* TSI108 GIGE port registers
*/
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 16b9acd..d7aff81 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -3787,7 +3787,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
ugeth_vdbg("%s: IN", __FUNCTION__);
- prop = get_property(np, "device-id", NULL);
+ prop = of_get_property(np, "device-id", NULL);
ucc_num = *prop - 1;
if ((ucc_num < 0) || (ucc_num > 7))
return -ENODEV;
@@ -3795,9 +3795,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
ug_info = &ugeth_info[ucc_num];
ug_info->uf_info.ucc_num = ucc_num;
- prop = get_property(np, "rx-clock", NULL);
+ prop = of_get_property(np, "rx-clock", NULL);
ug_info->uf_info.rx_clock = *prop;
- prop = get_property(np, "tx-clock", NULL);
+ prop = of_get_property(np, "tx-clock", NULL);
ug_info->uf_info.tx_clock = *prop;
err = of_address_to_resource(np, 0, &res);
if (err)
@@ -3806,23 +3806,23 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
ug_info->uf_info.regs = res.start;
ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
- ph = get_property(np, "phy-handle", NULL);
+ ph = of_get_property(np, "phy-handle", NULL);
phy = of_find_node_by_phandle(*ph);
if (phy == NULL)
return -ENODEV;
/* set the PHY address */
- prop = get_property(phy, "reg", NULL);
+ prop = of_get_property(phy, "reg", NULL);
if (prop == NULL)
return -1;
ug_info->phy_address = *prop;
/* get the phy interface type, or default to MII */
- prop = get_property(np, "interface-type", NULL);
+ prop = of_get_property(np, "interface-type", NULL);
if (!prop) {
/* handle interface property present in old trees */
- prop = get_property(phy, "interface", NULL);
+ prop = of_get_property(phy, "interface", NULL);
if (prop != NULL)
phy_interface = enet_to_phy_interface[*prop];
else
@@ -3832,10 +3832,10 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
}
/* get speed, or derive from interface */
- prop = get_property(np, "max-speed", NULL);
+ prop = of_get_property(np, "max-speed", NULL);
if (!prop) {
/* handle interface property present in old trees */
- prop = get_property(phy, "interface", NULL);
+ prop = of_get_property(phy, "interface", NULL);
if (prop != NULL)
max_speed = enet_to_speed[*prop];
} else {
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index 73b5a53..27a1ef3 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -172,7 +172,7 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma
while ((child = of_get_next_child(np, child)) != NULL) {
int irq = irq_of_parse_and_map(child, 0);
if (irq != NO_IRQ) {
- const u32 *id = get_property(child, "reg", NULL);
+ const u32 *id = of_get_property(child, "reg", NULL);
new_bus->irq[*id] = irq;
}
}
@@ -203,7 +203,7 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma
if ((res.start >= tempres.start) &&
(res.end <= tempres.end)) {
/* set this UCC to be the MII master */
- const u32 *id = get_property(tempnp, "device-id", NULL);
+ const u32 *id = of_get_property(tempnp, "device-id", NULL);
if (id == NULL)
goto bus_register_fail;
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 2346473..9ef49ce 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -90,7 +90,6 @@
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/device.h>
#undef COSA_SLOW_IO /* for testing purposes only */
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index c4b3dc2..e273347 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -153,8 +153,8 @@ config IPW2100
If you want to compile the driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
- say M here and read <file:Documentation/modules.txt>. The module
- will be called ipw2100.ko.
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+ The module will be called ipw2100.ko.
config IPW2100_MONITOR
bool "Enable promiscuous mode"
@@ -208,8 +208,8 @@ config IPW2200
If you want to compile the driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
- say M here and read <file:Documentation/modules.txt>. The module
- will be called ipw2200.ko.
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+ The module will be called ipw2200.ko.
config IPW2200_MONITOR
bool "Enable promiscuous mode"
@@ -267,7 +267,7 @@ config IPW2200_DEBUG
config LIBERTAS_USB
tristate "Marvell Libertas 8388 802.11a/b/g cards"
- depends on NET_RADIO && USB
+ depends on USB && WLAN_80211
select FW_LOADER
---help---
A driver for Marvell Libertas 8388 USB devices.
@@ -517,8 +517,8 @@ config PRISM54
If you want to compile the driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
- say M here and read <file:Documentation/modules.txt>. The module
- will be called prism54.ko.
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+ The module will be called prism54.ko.
config USB_ZD1201
tristate "USB ZD1201 based Wireless device support"
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index f21bbaf..2d3a180 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -25,7 +25,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
#include <linux/sched.h>
#include <linux/ptrace.h>
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index cb08bc5..cdea7f7 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1,7 +1,6 @@
/* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */
#include <linux/types.h>
-#include <linux/smp_lock.h>
#include <linux/ethtool.h>
#include <net/ieee80211_crypt.h>
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 21c4c29..5b86ee5 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -38,7 +38,6 @@
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <asm/byteorder.h>
#include <asm/pdc.h>
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 316c06f..8b7d84e 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -201,7 +201,7 @@ static int parport_config(struct pcmcia_device *link)
p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
link->irq.AssignedIRQ, PARPORT_DMA_NONE,
- NULL);
+ &link->dev);
if (p == NULL) {
printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
"0x%3x, irq %u failed\n", link->io.BasePort1,
diff --git a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c
index e5b0a54..77726fc 100644
--- a/drivers/parport/parport_mfc3.c
+++ b/drivers/parport/parport_mfc3.c
@@ -356,6 +356,7 @@ static int __init parport_mfc3_init(void)
if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, IRQF_SHARED, p->name, &pp_mfc3_ops))
goto out_irq;
}
+ p->dev = &z->dev;
this_port[pias++] = p;
printk(KERN_INFO "%s: Multiface III port using irq\n", p->name);
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 3de2623..02c0d52 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -53,6 +53,7 @@
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/pnp.h>
+#include <linux/platform_device.h>
#include <linux/sysctl.h>
#include <asm/io.h>
@@ -620,6 +621,7 @@ static size_t parport_pc_fifo_write_block_dma (struct parport *port,
unsigned long dmaflag;
size_t left = length;
const struct parport_pc_private *priv = port->physport->private_data;
+ struct device *dev = port->physport->dev;
dma_addr_t dma_addr, dma_handle;
size_t maxlen = 0x10000; /* max 64k per DMA transfer */
unsigned long start = (unsigned long) buf;
@@ -631,8 +633,8 @@ dump_parport_state ("enter fifo_write_block_dma", port);
if ((start ^ end) & ~0xffffUL)
maxlen = 0x10000 - (start & 0xffff);
- dma_addr = dma_handle = pci_map_single(priv->dev, (void *)buf, length,
- PCI_DMA_TODEVICE);
+ dma_addr = dma_handle = dma_map_single(dev, (void *)buf, length,
+ DMA_TO_DEVICE);
} else {
/* above 16 MB we use a bounce buffer as ISA-DMA is not possible */
maxlen = PAGE_SIZE; /* sizeof(priv->dma_buf) */
@@ -728,9 +730,9 @@ dump_parport_state ("enter fifo_write_block_dma", port);
/* Turn off DMA mode */
frob_econtrol (port, 1<<3, 0);
-
+
if (dma_handle)
- pci_unmap_single(priv->dev, dma_handle, length, PCI_DMA_TODEVICE);
+ dma_unmap_single(dev, dma_handle, length, DMA_TO_DEVICE);
dump_parport_state ("leave fifo_write_block_dma", port);
return length - left;
@@ -2146,7 +2148,7 @@ static DEFINE_SPINLOCK(ports_lock);
struct parport *parport_pc_probe_port (unsigned long int base,
unsigned long int base_hi,
int irq, int dma,
- struct pci_dev *dev)
+ struct device *dev)
{
struct parport_pc_private *priv;
struct parport_operations *ops;
@@ -2155,6 +2157,17 @@ struct parport *parport_pc_probe_port (unsigned long int base,
struct resource *base_res;
struct resource *ECR_res = NULL;
struct resource *EPP_res = NULL;
+ struct platform_device *pdev = NULL;
+
+ if (!dev) {
+ /* We need a physical device to attach to, but none was
+ * provided. Create our own. */
+ pdev = platform_device_register_simple("parport_pc",
+ base, NULL, 0);
+ if (IS_ERR(pdev))
+ return NULL;
+ dev = &pdev->dev;
+ }
ops = kmalloc(sizeof (struct parport_operations), GFP_KERNEL);
if (!ops)
@@ -2180,9 +2193,10 @@ struct parport *parport_pc_probe_port (unsigned long int base,
priv->fifo_depth = 0;
priv->dma_buf = NULL;
priv->dma_handle = 0;
- priv->dev = dev;
INIT_LIST_HEAD(&priv->list);
priv->port = p;
+
+ p->dev = dev;
p->base_hi = base_hi;
p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT;
p->private_data = priv;
@@ -2305,9 +2319,10 @@ struct parport *parport_pc_probe_port (unsigned long int base,
p->dma = PARPORT_DMA_NONE;
} else {
priv->dma_buf =
- pci_alloc_consistent(priv->dev,
+ dma_alloc_coherent(dev,
PAGE_SIZE,
- &priv->dma_handle);
+ &priv->dma_handle,
+ GFP_KERNEL);
if (! priv->dma_buf) {
printk (KERN_WARNING "%s: "
"cannot get buffer for DMA, "
@@ -2356,6 +2371,8 @@ out3:
out2:
kfree (ops);
out1:
+ if (pdev)
+ platform_device_unregister(pdev);
return NULL;
}
@@ -2383,7 +2400,7 @@ void parport_pc_unregister_port (struct parport *p)
release_region(p->base_hi, 3);
#if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA)
if (priv->dma_buf)
- pci_free_consistent(priv->dev, PAGE_SIZE,
+ dma_free_coherent(p->physport->dev, PAGE_SIZE,
priv->dma_buf,
priv->dma_handle);
#endif
@@ -2489,7 +2506,7 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq,
*/
release_resource(base_res);
if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi,
- irq, PARPORT_DMA_NONE, NULL)) {
+ irq, PARPORT_DMA_NONE, &pdev->dev)) {
printk (KERN_INFO
"parport_pc: ITE 8872 parallel port: io=0x%X",
ite8872_lpt);
@@ -2672,7 +2689,7 @@ static int __devinit sio_via_probe (struct pci_dev *pdev, int autoirq,
}
/* finally, do the probe with values obtained */
- if (parport_pc_probe_port (port1, port2, irq, dma, NULL)) {
+ if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev)) {
printk (KERN_INFO
"parport_pc: VIA parallel port: io=0x%X", port1);
if (irq != PARPORT_IRQ_NONE)
@@ -2970,7 +2987,7 @@ static int parport_pc_pci_probe (struct pci_dev *dev,
parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi);
data->ports[count] =
parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
- PARPORT_DMA_NONE, dev);
+ PARPORT_DMA_NONE, &dev->dev);
if (data->ports[count])
count++;
}
@@ -3077,8 +3094,8 @@ static int parport_pc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id
} else
dma = PARPORT_DMA_NONE;
- printk(KERN_INFO "parport: PnPBIOS parport detected.\n");
- if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, NULL)))
+ dev_info(&dev->dev, "reported by %s\n", dev->protocol->name);
+ if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, &dev->dev)))
return -ENODEV;
pnp_set_drvdata(dev,pdata);
@@ -3103,6 +3120,21 @@ static struct pnp_driver parport_pc_pnp_driver = {
};
+static int __devinit parport_pc_platform_probe(struct platform_device *pdev)
+{
+ /* Always succeed, the actual probing is done in
+ * parport_pc_probe_port(). */
+ return 0;
+}
+
+static struct platform_driver parport_pc_platform_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "parport_pc",
+ },
+ .probe = parport_pc_platform_probe,
+};
+
/* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */
static int __devinit __attribute__((unused))
parport_pc_find_isa_ports (int autoirq, int autodma)
@@ -3378,9 +3410,15 @@ __setup("parport_init_mode=",parport_init_mode_setup);
static int __init parport_pc_init(void)
{
+ int err;
+
if (parse_parport_params())
return -EINVAL;
+ err = platform_driver_register(&parport_pc_platform_driver);
+ if (err)
+ return err;
+
if (io[0]) {
int i;
/* Only probe the ports we were given. */
@@ -3405,6 +3443,7 @@ static void __exit parport_pc_exit(void)
pci_unregister_driver (&parport_pc_pci_driver);
if (pnp_registered_parport)
pnp_unregister_driver (&parport_pc_pnp_driver);
+ platform_driver_unregister(&parport_pc_platform_driver);
spin_lock(&ports_lock);
while (!list_empty(&ports_list)) {
@@ -3413,6 +3452,9 @@ static void __exit parport_pc_exit(void)
priv = list_entry(ports_list.next,
struct parport_pc_private, list);
port = priv->port;
+ if (port->dev && port->dev->bus == &platform_bus_type)
+ platform_device_unregister(
+ to_platform_device(port->dev));
spin_unlock(&ports_lock);
parport_pc_unregister_port(port);
spin_lock(&ports_lock);
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index 78c0a26..90ea3b8 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -305,7 +305,7 @@ static int __devinit parport_register (struct pci_dev *dev,
dev_dbg(&dev->dev, "PCI parallel port detected: I/O at "
"%#lx(%#lx)\n", io_lo, io_hi);
port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
- PARPORT_DMA_NONE, dev);
+ PARPORT_DMA_NONE, &dev->dev);
if (port) {
priv->port[priv->num_par++] = port;
success = 1;
@@ -392,6 +392,7 @@ static int parport_serial_pci_suspend(struct pci_dev *dev, pm_message_t state)
static int parport_serial_pci_resume(struct pci_dev *dev)
{
struct parport_serial_private *priv = pci_get_drvdata(dev);
+ int err;
pci_set_power_state(dev, PCI_D0);
pci_restore_state(dev);
@@ -399,7 +400,12 @@ static int parport_serial_pci_resume(struct pci_dev *dev)
/*
* The device may have been disabled. Re-enable it.
*/
- pci_enable_device(dev);
+ err = pci_enable_device(dev);
+ if (err) {
+ printk(KERN_ERR "parport_serial: %s: error enabling "
+ "device for resume (%d)\n", pci_name(dev), err);
+ return err;
+ }
if (priv->serial)
pciserial_resume_ports(priv->serial);
diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c
index 400bb90..d27019c 100644
--- a/drivers/parport/parport_sunbpp.c
+++ b/drivers/parport/parport_sunbpp.c
@@ -322,6 +322,7 @@ static int __devinit init_one_port(struct sbus_dev *sdev)
goto out_free_ops;
p->size = size;
+ p->dev = &sdev->ofdev.dev;
if ((err = request_irq(p->irq, parport_sunbpp_interrupt,
IRQF_SHARED, p->name, p)) != 0) {
diff --git a/drivers/parport/share.c b/drivers/parport/share.c
index fd9129e..cd66442 100644
--- a/drivers/parport/share.c
+++ b/drivers/parport/share.c
@@ -365,6 +365,11 @@ void parport_announce_port (struct parport *port)
parport_daisy_init(port);
#endif
+ if (!port->dev)
+ printk(KERN_WARNING "%s: fix this legacy "
+ "no-device port driver!\n",
+ port->name);
+
parport_proc_register(port);
mutex_lock(&registration_lock);
spin_lock_irq(&parportlist_lock);
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index 40c79b0..fa5c019 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -40,7 +40,6 @@
#include <linux/pci_hotplug.h>
#include <linux/slab.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include "acpiphp.h"
#define MY_NAME "acpiphp"
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index fca978f..9ef4e98 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -46,7 +46,6 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include "../pci.h"
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index 5939294..0316eea 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -34,7 +34,6 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/wait.h>
-#include <linux/smp_lock.h>
#include "../pci.h"
#include "../../../arch/i386/pci/pci.h" /* for struct irq_routing_table */
#include "ibmphp.h"
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c
index f55ac38..46abaa8 100644
--- a/drivers/pci/hotplug/ibmphp_hpc.c
+++ b/drivers/pci/hotplug/ibmphp_hpc.c
@@ -32,7 +32,6 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/pci.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/mutex.h>
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 63f3bd1..bd433ef 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -34,7 +34,6 @@
#include <linux/sysfs.h>
#include <linux/pagemap.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/mount.h>
#include <linux/namei.h>
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 847936f..458c08e 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -29,7 +29,6 @@
#include <linux/pci_hotplug.h>
#include <linux/slab.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/eeh.h> /* for eeh_add_device() */
#include <asm/rtas.h> /* rtas_call */
@@ -170,10 +169,10 @@ static int get_children_props(struct device_node *dn, const int **drc_indexes,
{
const int *indexes, *names, *types, *domains;
- indexes = get_property(dn, "ibm,drc-indexes", NULL);
- names = get_property(dn, "ibm,drc-names", NULL);
- types = get_property(dn, "ibm,drc-types", NULL);
- domains = get_property(dn, "ibm,drc-power-domains", NULL);
+ indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
+ names = of_get_property(dn, "ibm,drc-names", NULL);
+ types = of_get_property(dn, "ibm,drc-types", NULL);
+ domains = of_get_property(dn, "ibm,drc-power-domains", NULL);
if (!indexes || !names || !types || !domains) {
/* Slot does not have dynamically-removable children */
@@ -206,7 +205,7 @@ int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
char *name_tmp, *type_tmp;
int i, rc;
- my_index = get_property(dn, "ibm,my-drc-index", NULL);
+ my_index = of_get_property(dn, "ibm,my-drc-index", NULL);
if (!my_index) {
/* Node isn't DLPAR/hotplug capable */
return -EINVAL;
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 2c94d44..d2fc355 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -30,7 +30,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/smp_lock.h>
#include <linux/pci.h>
#include <linux/workqueue.h>
#include "../pci.h"
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 9e1321d..e6740d1 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -12,7 +12,6 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/ioport.h>
-#include <linux/smp_lock.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/msi.h>
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index ed87aa5..0425a7b 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index 99baabc..948efc7 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -360,7 +360,6 @@ static struct platform_driver at91_cf_driver = {
.name = (char *) driver_name,
.owner = THIS_MODULE,
},
- .probe = at91_cf_probe,
.remove = __exit_p(at91_cf_remove),
.suspend = at91_cf_suspend,
.resume = at91_cf_resume,
@@ -370,7 +369,7 @@ static struct platform_driver at91_cf_driver = {
static int __init at91_cf_init(void)
{
- return platform_driver_register(&at91_cf_driver);
+ return platform_driver_probe(&at91_cf_driver, at91_cf_probe);
}
module_init(at91_cf_init);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 18e111e..143c6ef 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -234,6 +234,89 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
/*======================================================================*/
+struct pcmcia_dynid {
+ struct list_head node;
+ struct pcmcia_device_id id;
+};
+
+/**
+ * pcmcia_store_new_id - add a new PCMCIA device ID to this driver and re-probe devices
+ * @driver: target device driver
+ * @buf: buffer for scanning device ID data
+ * @count: input size
+ *
+ * Adds a new dynamic PCMCIA device ID to this driver,
+ * and causes the driver to probe for all devices again.
+ */
+static ssize_t
+pcmcia_store_new_id(struct device_driver *driver, const char *buf, size_t count)
+{
+ struct pcmcia_dynid *dynid;
+ struct pcmcia_driver *pdrv = to_pcmcia_drv(driver);
+ __u16 match_flags, manf_id, card_id;
+ __u8 func_id, function, device_no;
+ __u32 prod_id_hash[4] = {0, 0, 0, 0};
+ int fields=0;
+ int retval = 0;
+
+ fields = sscanf(buf, "%hx %hx %hx %hhx %hhx %hhx %x %x %x %x",
+ &match_flags, &manf_id, &card_id, &func_id, &function, &device_no,
+ &prod_id_hash[0], &prod_id_hash[1], &prod_id_hash[2], &prod_id_hash[3]);
+ if (fields < 6)
+ return -EINVAL;
+
+ dynid = kzalloc(sizeof(struct pcmcia_dynid), GFP_KERNEL);
+ if (!dynid)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&dynid->node);
+ dynid->id.match_flags = match_flags;
+ dynid->id.manf_id = manf_id;
+ dynid->id.card_id = card_id;
+ dynid->id.func_id = func_id;
+ dynid->id.function = function;
+ dynid->id.device_no = device_no;
+ memcpy(dynid->id.prod_id_hash, prod_id_hash, sizeof(__u32) * 4);
+
+ spin_lock(&pdrv->dynids.lock);
+ list_add_tail(&pdrv->dynids.list, &dynid->node);
+ spin_unlock(&pdrv->dynids.lock);
+
+ if (get_driver(&pdrv->drv)) {
+ retval = driver_attach(&pdrv->drv);
+ put_driver(&pdrv->drv);
+ }
+
+ if (retval)
+ return retval;
+ return count;
+}
+static DRIVER_ATTR(new_id, S_IWUSR, NULL, pcmcia_store_new_id);
+
+static void
+pcmcia_free_dynids(struct pcmcia_driver *drv)
+{
+ struct pcmcia_dynid *dynid, *n;
+
+ spin_lock(&drv->dynids.lock);
+ list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
+ list_del(&dynid->node);
+ kfree(dynid);
+ }
+ spin_unlock(&drv->dynids.lock);
+}
+
+static int
+pcmcia_create_newid_file(struct pcmcia_driver *drv)
+{
+ int error = 0;
+ if (drv->probe != NULL)
+ error = sysfs_create_file(&drv->drv.kobj,
+ &driver_attr_new_id.attr);
+ return error;
+}
+
+
/**
* pcmcia_register_driver - register a PCMCIA driver with the bus core
*
@@ -241,6 +324,8 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
*/
int pcmcia_register_driver(struct pcmcia_driver *driver)
{
+ int error;
+
if (!driver)
return -EINVAL;
@@ -249,10 +334,20 @@ int pcmcia_register_driver(struct pcmcia_driver *driver)
/* initialize common fields */
driver->drv.bus = &pcmcia_bus_type;
driver->drv.owner = driver->owner;
+ spin_lock_init(&driver->dynids.lock);
+ INIT_LIST_HEAD(&driver->dynids.list);
ds_dbg(3, "registering driver %s\n", driver->drv.name);
- return driver_register(&driver->drv);
+ error = driver_register(&driver->drv);
+ if (error < 0)
+ return error;
+
+ error = pcmcia_create_newid_file(driver);
+ if (error)
+ driver_unregister(&driver->drv);
+
+ return error;
}
EXPORT_SYMBOL(pcmcia_register_driver);
@@ -263,6 +358,7 @@ void pcmcia_unregister_driver(struct pcmcia_driver *driver)
{
ds_dbg(3, "unregistering driver %s\n", driver->drv.name);
driver_unregister(&driver->drv);
+ pcmcia_free_dynids(driver);
}
EXPORT_SYMBOL(pcmcia_unregister_driver);
@@ -927,6 +1023,21 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
struct pcmcia_device * p_dev = to_pcmcia_dev(dev);
struct pcmcia_driver * p_drv = to_pcmcia_drv(drv);
struct pcmcia_device_id *did = p_drv->id_table;
+ struct pcmcia_dynid *dynid;
+
+ /* match dynamic devices first */
+ spin_lock(&p_drv->dynids.lock);
+ list_for_each_entry(dynid, &p_drv->dynids.list, node) {
+ ds_dbg(3, "trying to match %s to %s\n", dev->bus_id,
+ drv->name);
+ if (pcmcia_devmatch(p_dev, &dynid->id)) {
+ ds_dbg(0, "matched %s to %s\n", dev->bus_id,
+ drv->name);
+ spin_unlock(&p_drv->dynids.lock);
+ return 1;
+ }
+ }
+ spin_unlock(&p_drv->dynids.lock);
#ifdef CONFIG_PCMCIA_IOCTL
/* matching by cardmgr */
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index fda0694..383107b 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -175,6 +175,7 @@ static int __init mst_pcmcia_init(void)
if (!mst_pcmcia_device)
return -ENOMEM;
+ mst_pcmcia_device->dev.uevent_suppress = 0;
mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops;
ret = platform_device_add(mst_pcmcia_device);
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index b7b9e14..a2daa3f 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -261,6 +261,7 @@ static int __init sharpsl_pcmcia_init(void)
if (!sharpsl_pcmcia_device)
return -ENOMEM;
+ sharpsl_pcmcia_device->dev.uevent_suppress = 0;
sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev;
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index aec83ec..3e20b1c 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -14,6 +14,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/errno.h>
+#include <linux/dma-mapping.h>
#include "base.h"
@@ -22,6 +23,14 @@ static LIST_HEAD(pnp_protocols);
LIST_HEAD(pnp_global);
DEFINE_SPINLOCK(pnp_lock);
+/*
+ * ACPI or PNPBIOS should tell us about all platform devices, so we can
+ * skip some blind probes. ISAPNP typically enumerates only plug-in ISA
+ * devices, not built-in things like COM ports.
+ */
+int pnp_platform_devices;
+EXPORT_SYMBOL(pnp_platform_devices);
+
void *pnp_alloc(long size)
{
void *result;
@@ -114,6 +123,8 @@ int __pnp_add_device(struct pnp_dev *dev)
int ret;
pnp_fixup_device(dev);
dev->dev.bus = &pnp_bus_type;
+ dev->dev.dma_mask = &dev->dma_mask;
+ dev->dma_mask = dev->dev.coherent_dma_mask = DMA_24BIT_MASK;
dev->dev.release = &pnp_release_device;
dev->status = PNP_READY;
spin_lock(&pnp_lock);
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 62eda5d..a005487 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
* Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com>
- *
+ *
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
@@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
+
#include <linux/acpi.h>
#include <linux/pnp.h>
#include <acpi/acpi_bus.h>
@@ -82,7 +82,7 @@ static void __init pnpidacpi_to_pnpid(char *id, char *str)
static int pnpacpi_get_resources(struct pnp_dev * dev, struct pnp_resource_table * res)
{
acpi_status status;
- status = pnpacpi_parse_allocated_resource((acpi_handle)dev->data,
+ status = pnpacpi_parse_allocated_resource((acpi_handle)dev->data,
&dev->res);
return ACPI_FAILURE(status) ? -ENODEV : 0;
}
@@ -112,9 +112,9 @@ static int pnpacpi_set_resources(struct pnp_dev * dev, struct pnp_resource_table
static int pnpacpi_disable_resources(struct pnp_dev *dev)
{
acpi_status status;
-
+
/* acpi_unregister_gsi(pnp_irq(dev, 0)); */
- status = acpi_evaluate_object((acpi_handle)dev->data,
+ status = acpi_evaluate_object((acpi_handle)dev->data,
"_DIS", NULL, NULL);
return ACPI_FAILURE(status) ? -ENODEV : 0;
}
@@ -167,7 +167,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name));
dev->number = num;
-
+
/* set the initial values for the PnP device */
dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
if (!dev_id)
@@ -185,14 +185,14 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
}
if(dev->capabilities & PNP_CONFIGURABLE) {
- status = pnpacpi_parse_resource_option_data(device->handle,
+ status = pnpacpi_parse_resource_option_data(device->handle,
dev);
if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s", dev_id->id);
goto err1;
}
}
-
+
/* parse compatible ids */
if (device->flags.compatible_ids) {
struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
@@ -236,6 +236,42 @@ static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,
return AE_OK;
}
+static int __init acpi_pnp_match(struct device *dev, void *_pnp)
+{
+ struct acpi_device *acpi = to_acpi_device(dev);
+ struct pnp_dev *pnp = _pnp;
+
+ /* true means it matched */
+ return acpi->flags.hardware_id
+ && !acpi_get_physical_device(acpi->handle)
+ && compare_pnp_id(pnp->id, acpi->pnp.hardware_id);
+}
+
+static int __init acpi_pnp_find_device(struct device *dev, acpi_handle *handle)
+{
+ struct device *adev;
+ struct acpi_device *acpi;
+
+ adev = bus_find_device(&acpi_bus_type, NULL,
+ to_pnp_dev(dev),
+ acpi_pnp_match);
+ if (!adev)
+ return -ENODEV;
+
+ acpi = to_acpi_device(adev);
+ *handle = acpi->handle;
+ put_device(adev);
+ return 0;
+}
+
+/* complete initialization of a PNPACPI device includes having
+ * pnpdev->dev.archdata.acpi_handle point to its ACPI sibling.
+ */
+static struct acpi_bus_type __initdata acpi_pnp_bus = {
+ .bus = &pnp_bus_type,
+ .find_device = acpi_pnp_find_device,
+};
+
int pnpacpi_disabled __initdata;
static int __init pnpacpi_init(void)
{
@@ -245,8 +281,11 @@ static int __init pnpacpi_init(void)
}
pnp_info("PnP ACPI init");
pnp_register_protocol(&pnpacpi_protocol);
+ register_acpi_bus_type(&acpi_pnp_bus);
acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL);
pnp_info("PnP ACPI: found %d devices", num);
+ unregister_acpi_bus_type(&acpi_pnp_bus);
+ pnp_platform_devices = 1;
return 0;
}
subsys_initcall(pnpacpi_init);
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 95738db..3a201b7 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -62,6 +62,7 @@
#include <linux/delay.h>
#include <linux/acpi.h>
#include <linux/freezer.h>
+#include <linux/kthread.h>
#include <asm/page.h>
#include <asm/desc.h>
@@ -159,9 +160,7 @@ static int pnp_dock_thread(void * unused)
{
static struct pnp_docking_station_info now;
int docked = -1, d = 0;
- daemonize("kpnpbiosd");
- allow_signal(SIGKILL);
- while(!unloading && !signal_pending(current))
+ while (!unloading)
{
int status;
@@ -170,11 +169,8 @@ static int pnp_dock_thread(void * unused)
*/
msleep_interruptible(2000);
- if(signal_pending(current)) {
- if (try_to_freeze())
- continue;
- break;
- }
+ if (try_to_freeze())
+ continue;
status = pnp_bios_dock_station_info(&now);
@@ -574,6 +570,7 @@ static int __init pnpbios_init(void)
/* scan for pnpbios devices */
build_devlist();
+ pnp_platform_devices = 1;
return 0;
}
@@ -581,6 +578,7 @@ subsys_initcall(pnpbios_init);
static int __init pnpbios_thread_init(void)
{
+ struct task_struct *task;
#if defined(CONFIG_PPC_MERGE)
if (check_legacy_ioport(PNPBIOS_BASE))
return 0;
@@ -589,7 +587,8 @@ static int __init pnpbios_thread_init(void)
return 0;
#ifdef CONFIG_HOTPLUG
init_completion(&unload_sem);
- if (kernel_thread(pnp_dock_thread, NULL, CLONE_KERNEL) > 0)
+ task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd");
+ if (!IS_ERR(task))
unloading = 0;
#endif
return 0;
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index e97ecef..277df50 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -16,6 +16,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/pnp.h>
+#include <linux/io.h>
#include "base.h"
@@ -106,6 +107,34 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev)
return;
}
+static void quirk_smc_enable(struct pnp_dev *dev)
+{
+ unsigned int firbase;
+
+ if (!dev->active || !pnp_port_valid(dev, 1))
+ return;
+
+ /*
+ * On the HP/Compaq nw8240 (and probably other similar machines),
+ * there is an SMCF010 device with two I/O port regions:
+ *
+ * 0x3e8-0x3ef SIR
+ * 0x100-0x10f FIR
+ *
+ * _STA reports the device is enabled, but in fact, the BIOS
+ * neglects to enable the FIR range. Fortunately, it does fully
+ * enable the device if we call _SRS.
+ */
+ firbase = pnp_port_start(dev, 1);
+ if (inb(firbase + 0x7 /* IRCC_MASTER */) == 0xff) {
+ pnp_err("%s (%s) enabled but not responding, disabling and "
+ "re-enabling", dev->dev.bus_id, pnp_dev_name(dev));
+ pnp_disable_dev(dev);
+ pnp_activate_dev(dev);
+ }
+}
+
+
/*
* PnP Quirks
* Cards or devices that need some tweaking due to incomplete resource info
@@ -126,6 +155,7 @@ static struct pnp_fixup pnp_fixups[] = {
{ "CTL0043", quirk_sb16audio_resources },
{ "CTL0044", quirk_sb16audio_resources },
{ "CTL0045", quirk_sb16audio_resources },
+ { "SMCf010", quirk_smc_enable },
{ "" }
};
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c
index 7d7cab1..ec2d36a 100644
--- a/drivers/ps3/vuart.c
+++ b/drivers/ps3/vuart.c
@@ -886,12 +886,12 @@ static int ps3_vuart_probe(struct device *_dev)
if (++vuart_bus_priv.use_count == 1) {
- result = ps3_alloc_vuart_irq(PS3_BINDING_CPU_ANY,
+ result = ps3_vuart_irq_setup(PS3_BINDING_CPU_ANY,
(void*)&vuart_bus_priv.bmp.status, &vuart_bus_priv.virq);
if (result) {
dev_dbg(&dev->core,
- "%s:%d: ps3_alloc_vuart_irq failed (%d)\n",
+ "%s:%d: ps3_vuart_irq_setup failed (%d)\n",
__func__, __LINE__, result);
result = -EPERM;
goto fail_alloc_irq;
@@ -937,7 +937,7 @@ static int ps3_vuart_probe(struct device *_dev)
fail_probe:
ps3_vuart_set_interrupt_mask(dev, 0);
fail_request_irq:
- ps3_free_vuart_irq(vuart_bus_priv.virq);
+ ps3_vuart_irq_destroy(vuart_bus_priv.virq);
vuart_bus_priv.virq = NO_IRQ;
fail_alloc_irq:
--vuart_bus_priv.use_count;
@@ -975,7 +975,7 @@ static int ps3_vuart_remove(struct device *_dev)
if (--vuart_bus_priv.use_count == 0) {
BUG();
free_irq(vuart_bus_priv.virq, &vuart_bus_priv);
- ps3_free_vuart_irq(vuart_bus_priv.virq);
+ ps3_vuart_irq_destroy(vuart_bus_priv.virq);
vuart_bus_priv.virq = NO_IRQ;
}
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 95826b9..5e43983 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -21,21 +21,31 @@ config RTC_CLASS
will be called rtc-class.
config RTC_HCTOSYS
- bool "Set system time from RTC on startup"
+ bool "Set system time from RTC on startup and resume"
depends on RTC_CLASS = y
default y
help
- If you say yes here, the system time will be set using
- the value read from the specified RTC device. This is useful
- in order to avoid unnecessary fsck runs.
+ If you say yes here, the system time (wall clock) will be set using
+ the value read from a specified RTC device. This is useful to avoid
+ unnecessary fsck runs at boot time, and to network better.
config RTC_HCTOSYS_DEVICE
- string "The RTC to read the time from"
+ string "RTC used to set the system time"
depends on RTC_HCTOSYS = y
default "rtc0"
help
- The RTC device that will be used as the source for
- the system time, usually rtc0.
+ The RTC device that will be used to (re)initialize the system
+ clock, usually rtc0. Initialization is done when the system
+ starts up, and when it resumes from a low power state.
+
+ This clock should be battery-backed, so that it reads the correct
+ time when the system boots from a power-off state. Otherwise, your
+ system will need an external clock source (like an NTP server).
+
+ If the clock you specify here is not battery backed, it may still
+ be useful to reinitialize system time when resuming from system
+ sleep states. Do not specify an RTC here unless it stays powered
+ during all this system's supported sleep states.
config RTC_DEBUG
bool "RTC debug support"
@@ -48,7 +58,7 @@ comment "RTC interfaces"
depends on RTC_CLASS
config RTC_INTF_SYSFS
- tristate "sysfs"
+ boolean "sysfs"
depends on RTC_CLASS && SYSFS
default RTC_CLASS
help
@@ -59,7 +69,7 @@ config RTC_INTF_SYSFS
will be called rtc-sysfs.
config RTC_INTF_PROC
- tristate "proc"
+ boolean "proc"
depends on RTC_CLASS && PROC_FS
default RTC_CLASS
help
@@ -71,7 +81,7 @@ config RTC_INTF_PROC
will be called rtc-proc.
config RTC_INTF_DEV
- tristate "dev"
+ boolean "dev"
depends on RTC_CLASS
default RTC_CLASS
help
@@ -92,44 +102,26 @@ config RTC_INTF_DEV_UIE_EMUL
driver does not expose RTC_UIE ioctls. Those requests generate
once-per-second update interrupts, used for synchronization.
-comment "RTC drivers"
+config RTC_DRV_TEST
+ tristate "Test driver/device"
depends on RTC_CLASS
-
-# this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
-# requires <asm/mc146818rtc.h> defining CMOS_READ/CMOS_WRITE, and a
-# global rtc_lock ... it's not yet just another platform_device.
-
-config RTC_DRV_CMOS
- tristate "PC-style 'CMOS' real time clock"
- depends on RTC_CLASS && (X86 || ALPHA || ARM26 || ARM \
- || M32R || ATARI || POWERPC)
- help
- Say "yes" here to get direct support for the real time clock
- found in every PC or ACPI-based system, and some other boards.
- Specifically the original MC146818, compatibles like those in
- PC south bridges, the DS12887 or M48T86, some multifunction
- or LPC bus chips, and so on.
-
- Your system will need to define the platform device used by
- this driver, otherwise it won't be accessible. This means
- you can safely enable this driver if you don't know whether
- or not your board has this kind of hardware.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-cmos.
-
-config RTC_DRV_X1205
- tristate "Xicor/Intersil X1205"
- depends on RTC_CLASS && I2C
help
If you say yes here you get support for the
- Xicor/Intersil X1205 RTC chip.
+ RTC test driver. It's a software RTC which can be
+ used to test the RTC subsystem APIs. It gets
+ the time from the system clock.
+ You want this driver only if you are doing development
+ on the RTC subsystem. Please read the source code
+ for further details.
This driver can also be built as a module. If so, the module
- will be called rtc-x1205.
+ will be called rtc-test.
+
+comment "I2C RTC drivers"
+ depends on RTC_CLASS
config RTC_DRV_DS1307
- tristate "Dallas/Maxim DS1307 and similar I2C RTC chips"
+ tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00"
depends on RTC_CLASS && I2C
help
If you say yes here you get support for various compatible RTC
@@ -146,53 +138,55 @@ config RTC_DRV_DS1307
This driver can also be built as a module. If so, the module
will be called rtc-ds1307.
-config RTC_DRV_DS1553
- tristate "Dallas DS1553"
- depends on RTC_CLASS
+config RTC_DRV_DS1672
+ tristate "Dallas/Maxim DS1672"
+ depends on RTC_CLASS && I2C
help
If you say yes here you get support for the
- Dallas DS1553 timekeeping chip.
+ Dallas/Maxim DS1672 timekeeping chip.
This driver can also be built as a module. If so, the module
- will be called rtc-ds1553.
+ will be called rtc-ds1672.
-config RTC_DRV_ISL1208
- tristate "Intersil 1208"
+config RTC_DRV_MAX6900
+ tristate "Maxim 6900"
depends on RTC_CLASS && I2C
help
- If you say yes here you get support for the
- Intersil 1208 RTC chip.
+ If you say yes here you will get support for the
+ Maxim MAX6900 I2C RTC chip.
This driver can also be built as a module. If so, the module
- will be called rtc-isl1208.
+ will be called rtc-max6900.
-config RTC_DRV_DS1672
- tristate "Dallas/Maxim DS1672"
+config RTC_DRV_RS5C372
+ tristate "Ricoh RS5C372A/B"
depends on RTC_CLASS && I2C
help
If you say yes here you get support for the
- Dallas/Maxim DS1672 timekeeping chip.
+ Ricoh RS5C372A and RS5C372B RTC chips.
This driver can also be built as a module. If so, the module
- will be called rtc-ds1672.
+ will be called rtc-rs5c372.
-config RTC_DRV_DS1742
- tristate "Dallas DS1742/1743"
- depends on RTC_CLASS
+config RTC_DRV_ISL1208
+ tristate "Intersil 1208"
+ depends on RTC_CLASS && I2C
help
If you say yes here you get support for the
- Dallas DS1742/1743 timekeeping chip.
+ Intersil 1208 RTC chip.
This driver can also be built as a module. If so, the module
- will be called rtc-ds1742.
+ will be called rtc-isl1208.
-config RTC_DRV_OMAP
- tristate "TI OMAP1"
- depends on RTC_CLASS && ( \
- ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 )
+config RTC_DRV_X1205
+ tristate "Xicor/Intersil X1205"
+ depends on RTC_CLASS && I2C
help
- Say "yes" here to support the real time clock on TI OMAP1 chips.
- This driver can also be built as a module called rtc-omap.
+ If you say yes here you get support for the
+ Xicor/Intersil X1205 RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-x1205.
config RTC_DRV_PCF8563
tristate "Philips PCF8563/Epson RTC8564"
@@ -207,16 +201,20 @@ config RTC_DRV_PCF8563
config RTC_DRV_PCF8583
tristate "Philips PCF8583"
- depends on RTC_CLASS && I2C && ARCH_RPC
+ depends on RTC_CLASS && I2C
help
If you say yes here you get support for the Philips PCF8583
- RTC chip found on Acorn RiscPCs. This driver supports the
+ RTC chip found on Acorn RiscPCs. This driver supports the
platform specific method of retrieving the current year from
- the RTC's SRAM.
+ the RTC's SRAM. It will work on other platforms with the same
+ chip, but the year will probably have to be tweaked.
This driver can also be built as a module. If so, the module
will be called rtc-pcf8583.
+comment "SPI RTC drivers"
+ depends on RTC_CLASS
+
config RTC_DRV_RS5C348
tristate "Ricoh RS5C348A/B"
depends on RTC_CLASS && SPI
@@ -227,15 +225,92 @@ config RTC_DRV_RS5C348
This driver can also be built as a module. If so, the module
will be called rtc-rs5c348.
-config RTC_DRV_RS5C372
- tristate "Ricoh RS5C372A/B"
- depends on RTC_CLASS && I2C
+config RTC_DRV_MAX6902
+ tristate "Maxim 6902"
+ depends on RTC_CLASS && SPI
+ help
+ If you say yes here you will get support for the
+ Maxim MAX6902 SPI RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-max6902.
+
+comment "Platform RTC drivers"
+ depends on RTC_CLASS
+
+# this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
+# requires <asm/mc146818rtc.h> defining CMOS_READ/CMOS_WRITE, and a
+# global rtc_lock ... it's not yet just another platform_device.
+
+config RTC_DRV_CMOS
+ tristate "PC-style 'CMOS'"
+ depends on RTC_CLASS && (X86 || ALPHA || ARM26 || ARM \
+ || M32R || ATARI || POWERPC)
+ help
+ Say "yes" here to get direct support for the real time clock
+ found in every PC or ACPI-based system, and some other boards.
+ Specifically the original MC146818, compatibles like those in
+ PC south bridges, the DS12887 or M48T86, some multifunction
+ or LPC bus chips, and so on.
+
+ Your system will need to define the platform device used by
+ this driver, otherwise it won't be accessible. This means
+ you can safely enable this driver if you don't know whether
+ or not your board has this kind of hardware.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-cmos.
+
+config RTC_DRV_DS1553
+ tristate "Dallas DS1553"
+ depends on RTC_CLASS
help
If you say yes here you get support for the
- Ricoh RS5C372A and RS5C372B RTC chips.
+ Dallas DS1553 timekeeping chip.
This driver can also be built as a module. If so, the module
- will be called rtc-rs5c372.
+ will be called rtc-ds1553.
+
+config RTC_DRV_DS1742
+ tristate "Dallas DS1742/1743"
+ depends on RTC_CLASS
+ help
+ If you say yes here you get support for the
+ Dallas DS1742/1743 timekeeping chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-ds1742.
+
+config RTC_DRV_M48T86
+ tristate "ST M48T86/Dallas DS12887"
+ depends on RTC_CLASS
+ help
+ If you say Y here you will get support for the
+ ST M48T86 and Dallas DS12887 RTC chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-m48t86.
+
+config RTC_DRV_V3020
+ tristate "EM Microelectronic V3020"
+ depends on RTC_CLASS
+ help
+ If you say yes here you will get support for the
+ EM Microelectronic v3020 RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-v3020.
+
+comment "on-CPU RTC drivers"
+ depends on RTC_CLASS
+
+config RTC_DRV_OMAP
+ tristate "TI OMAP1"
+ depends on RTC_CLASS && ( \
+ ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 )
+ help
+ Say "yes" here to support the real time clock on TI OMAP1 chips.
+ This driver can also be built as a module called rtc-omap.
config RTC_DRV_S3C
tristate "Samsung S3C series SoC RTC"
@@ -253,16 +328,6 @@ config RTC_DRV_S3C
This driver can also be build as a module. If so, the module
will be called rtc-s3c.
-config RTC_DRV_M48T86
- tristate "ST M48T86/Dallas DS12887"
- depends on RTC_CLASS
- help
- If you say Y here you will get support for the
- ST M48T86 and Dallas DS12887 RTC chips.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-m48t86.
-
config RTC_DRV_EP93XX
tristate "Cirrus Logic EP93XX"
depends on RTC_CLASS && ARCH_EP93XX
@@ -308,7 +373,7 @@ config RTC_DRV_PL031
depends on RTC_CLASS && ARM_AMBA
help
If you say Y here you will get access to ARM AMBA
- PrimeCell PL031 UART found on certain ARM SOCs.
+ PrimeCell PL031 RTC found on certain ARM SOCs.
To compile this driver as a module, choose M here: the
module will be called rtc-pl031.
@@ -319,39 +384,20 @@ config RTC_DRV_AT91RM9200
help
Driver for the Atmel AT91RM9200's internal RTC (Realtime Clock).
-config RTC_DRV_TEST
- tristate "Test driver/device"
- depends on RTC_CLASS
- help
- If you say yes here you get support for the
- RTC test driver. It's a software RTC which can be
- used to test the RTC subsystem APIs. It gets
- the time from the system clock.
- You want this driver only if you are doing development
- on the RTC subsystem. Please read the source code
- for further details.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-test.
-
-config RTC_DRV_MAX6902
- tristate "Maxim 6902"
- depends on RTC_CLASS && SPI
+config RTC_DRV_BFIN
+ tristate "Blackfin On-Chip RTC"
+ depends on RTC_CLASS && BFIN
help
If you say yes here you will get support for the
- Maxim MAX6902 spi RTC chip.
+ Blackfin On-Chip Real Time Clock.
This driver can also be built as a module. If so, the module
- will be called rtc-max6902.
+ will be called rtc-bfin.
-config RTC_DRV_V3020
- tristate "EM Microelectronic V3020"
- depends on RTC_CLASS
+config RTC_DRV_RS5C313
+ tristate "Ricoh RS5C313"
+ depends on RTC_CLASS && BROKEN
help
- If you say yes here you will get support for the
- EM Microelectronic v3020 RTC chip.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-v3020.
+ If you say yes here you get support for the Ricoh RS5C313 RTC chips.
endmenu
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 92bfe1b..a1afbc2 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -11,9 +11,9 @@ obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o
obj-$(CONFIG_RTC_CLASS) += rtc-core.o
rtc-core-y := class.o interface.o
-obj-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
-obj-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o
-obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
+rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
+rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o
+rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
@@ -30,11 +30,14 @@ obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o
obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
+obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o
obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
+obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o
+obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 04aaa63..8b3cd31 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -16,19 +16,94 @@
#include <linux/kdev_t.h>
#include <linux/idr.h>
+#include "rtc-core.h"
+
+
static DEFINE_IDR(rtc_idr);
static DEFINE_MUTEX(idr_lock);
struct class *rtc_class;
-static void rtc_device_release(struct class_device *class_dev)
+static void rtc_device_release(struct device *dev)
{
- struct rtc_device *rtc = to_rtc_device(class_dev);
+ struct rtc_device *rtc = to_rtc_device(dev);
mutex_lock(&idr_lock);
idr_remove(&rtc_idr, rtc->id);
mutex_unlock(&idr_lock);
kfree(rtc);
}
+#if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
+
+/*
+ * On suspend(), measure the delta between one RTC and the
+ * system's wall clock; restore it on resume().
+ */
+
+static struct timespec delta;
+static time_t oldtime;
+
+static int rtc_suspend(struct device *dev, pm_message_t mesg)
+{
+ struct rtc_device *rtc = to_rtc_device(dev);
+ struct rtc_time tm;
+
+ if (strncmp(rtc->dev.bus_id,
+ CONFIG_RTC_HCTOSYS_DEVICE,
+ BUS_ID_SIZE) != 0)
+ return 0;
+
+ rtc_read_time(rtc, &tm);
+ rtc_tm_to_time(&tm, &oldtime);
+
+ /* RTC precision is 1 second; adjust delta for avg 1/2 sec err */
+ set_normalized_timespec(&delta,
+ xtime.tv_sec - oldtime,
+ xtime.tv_nsec - (NSEC_PER_SEC >> 1));
+
+ return 0;
+}
+
+static int rtc_resume(struct device *dev)
+{
+ struct rtc_device *rtc = to_rtc_device(dev);
+ struct rtc_time tm;
+ time_t newtime;
+ struct timespec time;
+
+ if (strncmp(rtc->dev.bus_id,
+ CONFIG_RTC_HCTOSYS_DEVICE,
+ BUS_ID_SIZE) != 0)
+ return 0;
+
+ rtc_read_time(rtc, &tm);
+ if (rtc_valid_tm(&tm) != 0) {
+ pr_debug("%s: bogus resume time\n", rtc->dev.bus_id);
+ return 0;
+ }
+ rtc_tm_to_time(&tm, &newtime);
+ if (newtime <= oldtime) {
+ if (newtime < oldtime)
+ pr_debug("%s: time travel!\n", rtc->dev.bus_id);
+ return 0;
+ }
+
+ /* restore wall clock using delta against this RTC;
+ * adjust again for avg 1/2 second RTC sampling error
+ */
+ set_normalized_timespec(&time,
+ newtime + delta.tv_sec,
+ (NSEC_PER_SEC >> 1) + delta.tv_nsec);
+ do_settimeofday(&time);
+
+ return 0;
+}
+
+#else
+#define rtc_suspend NULL
+#define rtc_resume NULL
+#endif
+
+
/**
* rtc_device_register - register w/ RTC class
* @dev: the device to register
@@ -70,23 +145,29 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
rtc->ops = ops;
rtc->owner = owner;
rtc->max_user_freq = 64;
- rtc->class_dev.dev = dev;
- rtc->class_dev.class = rtc_class;
- rtc->class_dev.release = rtc_device_release;
+ rtc->dev.parent = dev;
+ rtc->dev.class = rtc_class;
+ rtc->dev.release = rtc_device_release;
mutex_init(&rtc->ops_lock);
spin_lock_init(&rtc->irq_lock);
spin_lock_init(&rtc->irq_task_lock);
strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
- snprintf(rtc->class_dev.class_id, BUS_ID_SIZE, "rtc%d", id);
+ snprintf(rtc->dev.bus_id, BUS_ID_SIZE, "rtc%d", id);
- err = class_device_register(&rtc->class_dev);
+ rtc_dev_prepare(rtc);
+
+ err = device_register(&rtc->dev);
if (err)
goto exit_kfree;
+ rtc_dev_add_device(rtc);
+ rtc_sysfs_add_device(rtc);
+ rtc_proc_add_device(rtc);
+
dev_info(dev, "rtc core: registered %s as %s\n",
- rtc->name, rtc->class_dev.class_id);
+ rtc->name, rtc->dev.bus_id);
return rtc;
@@ -113,26 +194,22 @@ EXPORT_SYMBOL_GPL(rtc_device_register);
*/
void rtc_device_unregister(struct rtc_device *rtc)
{
- if (class_device_get(&rtc->class_dev) != NULL) {
+ if (get_device(&rtc->dev) != NULL) {
mutex_lock(&rtc->ops_lock);
/* remove innards of this RTC, then disable it, before
* letting any rtc_class_open() users access it again
*/
- class_device_unregister(&rtc->class_dev);
+ rtc_sysfs_del_device(rtc);
+ rtc_dev_del_device(rtc);
+ rtc_proc_del_device(rtc);
+ device_unregister(&rtc->dev);
rtc->ops = NULL;
mutex_unlock(&rtc->ops_lock);
- class_device_put(&rtc->class_dev);
+ put_device(&rtc->dev);
}
}
EXPORT_SYMBOL_GPL(rtc_device_unregister);
-int rtc_interface_register(struct class_interface *intf)
-{
- intf->class = rtc_class;
- return class_interface_register(intf);
-}
-EXPORT_SYMBOL_GPL(rtc_interface_register);
-
static int __init rtc_init(void)
{
rtc_class = class_create(THIS_MODULE, "rtc");
@@ -140,11 +217,16 @@ static int __init rtc_init(void)
printk(KERN_ERR "%s: couldn't create class\n", __FILE__);
return PTR_ERR(rtc_class);
}
+ rtc_class->suspend = rtc_suspend;
+ rtc_class->resume = rtc_resume;
+ rtc_dev_init();
+ rtc_sysfs_init(rtc_class);
return 0;
}
static void __exit rtc_exit(void)
{
+ rtc_dev_exit();
class_destroy(rtc_class);
}
diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c
index d02fe9a..1785272 100644
--- a/drivers/rtc/hctosys.c
+++ b/drivers/rtc/hctosys.c
@@ -26,15 +26,15 @@ static int __init rtc_hctosys(void)
{
int err;
struct rtc_time tm;
- struct class_device *class_dev = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+ struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
- if (class_dev == NULL) {
+ if (rtc == NULL) {
printk("%s: unable to open rtc device (%s)\n",
__FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
return -ENODEV;
}
- err = rtc_read_time(class_dev, &tm);
+ err = rtc_read_time(rtc, &tm);
if (err == 0) {
err = rtc_valid_tm(&tm);
if (err == 0) {
@@ -46,7 +46,7 @@ static int __init rtc_hctosys(void)
do_settimeofday(&tv);
- dev_info(class_dev->dev,
+ dev_info(rtc->dev.parent,
"setting the system clock to "
"%d-%02d-%02d %02d:%02d:%02d (%u)\n",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
@@ -54,14 +54,14 @@ static int __init rtc_hctosys(void)
(unsigned int) tv.tv_sec);
}
else
- dev_err(class_dev->dev,
+ dev_err(rtc->dev.parent,
"hctosys: invalid date/time\n");
}
else
- dev_err(class_dev->dev,
+ dev_err(rtc->dev.parent,
"hctosys: unable to read the hardware clock\n");
- rtc_class_close(class_dev);
+ rtc_class_close(rtc);
return 0;
}
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index ef40df0..ad66c6e 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -13,10 +13,9 @@
#include <linux/rtc.h>
-int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm)
+int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
{
int err;
- struct rtc_device *rtc = to_rtc_device(class_dev);
err = mutex_lock_interruptible(&rtc->ops_lock);
if (err)
@@ -28,7 +27,7 @@ int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm)
err = -EINVAL;
else {
memset(tm, 0, sizeof(struct rtc_time));
- err = rtc->ops->read_time(class_dev->dev, tm);
+ err = rtc->ops->read_time(rtc->dev.parent, tm);
}
mutex_unlock(&rtc->ops_lock);
@@ -36,10 +35,9 @@ int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm)
}
EXPORT_SYMBOL_GPL(rtc_read_time);
-int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm)
+int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
{
int err;
- struct rtc_device *rtc = to_rtc_device(class_dev);
err = rtc_valid_tm(tm);
if (err != 0)
@@ -54,17 +52,16 @@ int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm)
else if (!rtc->ops->set_time)
err = -EINVAL;
else
- err = rtc->ops->set_time(class_dev->dev, tm);
+ err = rtc->ops->set_time(rtc->dev.parent, tm);
mutex_unlock(&rtc->ops_lock);
return err;
}
EXPORT_SYMBOL_GPL(rtc_set_time);
-int rtc_set_mmss(struct class_device *class_dev, unsigned long secs)
+int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
{
int err;
- struct rtc_device *rtc = to_rtc_device(class_dev);
err = mutex_lock_interruptible(&rtc->ops_lock);
if (err)
@@ -73,11 +70,11 @@ int rtc_set_mmss(struct class_device *class_dev, unsigned long secs)
if (!rtc->ops)
err = -ENODEV;
else if (rtc->ops->set_mmss)
- err = rtc->ops->set_mmss(class_dev->dev, secs);
+ err = rtc->ops->set_mmss(rtc->dev.parent, secs);
else if (rtc->ops->read_time && rtc->ops->set_time) {
struct rtc_time new, old;
- err = rtc->ops->read_time(class_dev->dev, &old);
+ err = rtc->ops->read_time(rtc->dev.parent, &old);
if (err == 0) {
rtc_time_to_tm(secs, &new);
@@ -89,7 +86,8 @@ int rtc_set_mmss(struct class_device *class_dev, unsigned long secs)
*/
if (!((old.tm_hour == 23 && old.tm_min == 59) ||
(new.tm_hour == 23 && new.tm_min == 59)))
- err = rtc->ops->set_time(class_dev->dev, &new);
+ err = rtc->ops->set_time(rtc->dev.parent,
+ &new);
}
}
else
@@ -101,10 +99,9 @@ int rtc_set_mmss(struct class_device *class_dev, unsigned long secs)
}
EXPORT_SYMBOL_GPL(rtc_set_mmss);
-int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
+int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{
int err;
- struct rtc_device *rtc = to_rtc_device(class_dev);
err = mutex_lock_interruptible(&rtc->ops_lock);
if (err)
@@ -116,7 +113,7 @@ int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
err = -EINVAL;
else {
memset(alarm, 0, sizeof(struct rtc_wkalrm));
- err = rtc->ops->read_alarm(class_dev->dev, alarm);
+ err = rtc->ops->read_alarm(rtc->dev.parent, alarm);
}
mutex_unlock(&rtc->ops_lock);
@@ -124,10 +121,13 @@ int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
}
EXPORT_SYMBOL_GPL(rtc_read_alarm);
-int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
+int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{
int err;
- struct rtc_device *rtc = to_rtc_device(class_dev);
+
+ err = rtc_valid_tm(&alarm->time);
+ if (err != 0)
+ return err;
err = mutex_lock_interruptible(&rtc->ops_lock);
if (err)
@@ -138,7 +138,7 @@ int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
else if (!rtc->ops->set_alarm)
err = -EINVAL;
else
- err = rtc->ops->set_alarm(class_dev->dev, alarm);
+ err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
mutex_unlock(&rtc->ops_lock);
return err;
@@ -147,16 +147,14 @@ EXPORT_SYMBOL_GPL(rtc_set_alarm);
/**
* rtc_update_irq - report RTC periodic, alarm, and/or update irqs
- * @class_dev: the rtc's class device
+ * @rtc: the rtc device
* @num: how many irqs are being reported (usually one)
* @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF
* Context: in_interrupt(), irqs blocked
*/
-void rtc_update_irq(struct class_device *class_dev,
+void rtc_update_irq(struct rtc_device *rtc,
unsigned long num, unsigned long events)
{
- struct rtc_device *rtc = to_rtc_device(class_dev);
-
spin_lock(&rtc->irq_lock);
rtc->irq_data = (rtc->irq_data + (num << 8)) | events;
spin_unlock(&rtc->irq_lock);
@@ -171,40 +169,43 @@ void rtc_update_irq(struct class_device *class_dev,
}
EXPORT_SYMBOL_GPL(rtc_update_irq);
-struct class_device *rtc_class_open(char *name)
+struct rtc_device *rtc_class_open(char *name)
{
- struct class_device *class_dev = NULL,
- *class_dev_tmp;
+ struct device *dev;
+ struct rtc_device *rtc = NULL;
down(&rtc_class->sem);
- list_for_each_entry(class_dev_tmp, &rtc_class->children, node) {
- if (strncmp(class_dev_tmp->class_id, name, BUS_ID_SIZE) == 0) {
- class_dev = class_device_get(class_dev_tmp);
+ list_for_each_entry(dev, &rtc_class->devices, node) {
+ if (strncmp(dev->bus_id, name, BUS_ID_SIZE) == 0) {
+ dev = get_device(dev);
+ if (dev)
+ rtc = to_rtc_device(dev);
break;
}
}
- if (class_dev) {
- if (!try_module_get(to_rtc_device(class_dev)->owner))
- class_dev = NULL;
+ if (rtc) {
+ if (!try_module_get(rtc->owner)) {
+ put_device(dev);
+ rtc = NULL;
+ }
}
up(&rtc_class->sem);
- return class_dev;
+ return rtc;
}
EXPORT_SYMBOL_GPL(rtc_class_open);
-void rtc_class_close(struct class_device *class_dev)
+void rtc_class_close(struct rtc_device *rtc)
{
- module_put(to_rtc_device(class_dev)->owner);
- class_device_put(class_dev);
+ module_put(rtc->owner);
+ put_device(&rtc->dev);
}
EXPORT_SYMBOL_GPL(rtc_class_close);
-int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task)
+int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
{
int retval = -EBUSY;
- struct rtc_device *rtc = to_rtc_device(class_dev);
if (task == NULL || task->func == NULL)
return -EINVAL;
@@ -220,9 +221,8 @@ int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task)
}
EXPORT_SYMBOL_GPL(rtc_irq_register);
-void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task)
+void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task)
{
- struct rtc_device *rtc = to_rtc_device(class_dev);
spin_lock_irq(&rtc->irq_task_lock);
if (rtc->irq_task == task)
@@ -231,11 +231,10 @@ void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task)
}
EXPORT_SYMBOL_GPL(rtc_irq_unregister);
-int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int enabled)
+int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled)
{
int err = 0;
unsigned long flags;
- struct rtc_device *rtc = to_rtc_device(class_dev);
if (rtc->ops->irq_set_state == NULL)
return -ENXIO;
@@ -246,17 +245,16 @@ int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
if (err == 0)
- err = rtc->ops->irq_set_state(class_dev->dev, enabled);
+ err = rtc->ops->irq_set_state(rtc->dev.parent, enabled);
return err;
}
EXPORT_SYMBOL_GPL(rtc_irq_set_state);
-int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int freq)
+int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
{
int err = 0;
unsigned long flags;
- struct rtc_device *rtc = to_rtc_device(class_dev);
if (rtc->ops->irq_set_freq == NULL)
return -ENXIO;
@@ -267,7 +265,7 @@ int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
if (err == 0) {
- err = rtc->ops->irq_set_freq(class_dev->dev, freq);
+ err = rtc->ops->irq_set_freq(rtc->dev.parent, freq);
if (err == 0)
rtc->irq_freq = freq;
}
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index ac0e68e..33795e5 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -263,7 +263,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
at91_sys_write(AT91_RTC_SCCR, rtsr); /* clear status reg */
- rtc_update_irq(&rtc->class_dev, 1, events);
+ rtc_update_irq(rtc, 1, events);
pr_debug("%s(): num=%ld, events=0x%02lx\n", __FUNCTION__,
events >> 8, events & 0x000000FF);
@@ -348,21 +348,10 @@ static int __exit at91_rtc_remove(struct platform_device *pdev)
/* AT91RM9200 RTC Power management control */
-static struct timespec at91_rtc_delta;
static u32 at91_rtc_imr;
static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct rtc_time tm;
- struct timespec time;
-
- time.tv_nsec = 0;
-
- /* calculate time delta for suspend */
- at91_rtc_readtime(&pdev->dev, &tm);
- rtc_tm_to_time(&tm, &time.tv_sec);
- save_time_delta(&at91_rtc_delta, &time);
-
/* this IRQ is shared with DBGU and other hardware which isn't
* necessarily doing PM like we are...
*/
@@ -374,36 +363,17 @@ static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state)
else
at91_sys_write(AT91_RTC_IDR, at91_rtc_imr);
}
-
- pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
- 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
-
return 0;
}
static int at91_rtc_resume(struct platform_device *pdev)
{
- struct rtc_time tm;
- struct timespec time;
-
- time.tv_nsec = 0;
-
- at91_rtc_readtime(&pdev->dev, &tm);
- rtc_tm_to_time(&tm, &time.tv_sec);
- restore_time_delta(&at91_rtc_delta, &time);
-
if (at91_rtc_imr) {
if (device_may_wakeup(&pdev->dev))
disable_irq_wake(AT91_ID_SYS);
else
at91_sys_write(AT91_RTC_IER, at91_rtc_imr);
}
-
- pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
- 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
-
return 0;
}
#else
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c
new file mode 100644
index 0000000..260ead9
--- /dev/null
+++ b/drivers/rtc/rtc-bfin.c
@@ -0,0 +1,445 @@
+/*
+ * Blackfin On-Chip Real Time Clock Driver
+ * Supports BF531/BF532/BF533/BF534/BF536/BF537
+ *
+ * Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+/* The biggest issue we deal with in this driver is that register writes are
+ * synced to the RTC frequency of 1Hz. So if you write to a register and
+ * attempt to write again before the first write has completed, the new write
+ * is simply discarded. This can easily be troublesome if userspace disables
+ * one event (say periodic) and then right after enables an event (say alarm).
+ * Since all events are maintained in the same interrupt mask register, if
+ * we wrote to it to disable the first event and then wrote to it again to
+ * enable the second event, that second event would not be enabled as the
+ * write would be discarded and things quickly fall apart.
+ *
+ * To keep this delay from significantly degrading performance (we, in theory,
+ * would have to sleep for up to 1 second everytime we wanted to write a
+ * register), we only check the write pending status before we start to issue
+ * a new write. We bank on the idea that it doesnt matter when the sync
+ * happens so long as we don't attempt another write before it does. The only
+ * time userspace would take this penalty is when they try and do multiple
+ * operations right after another ... but in this case, they need to take the
+ * sync penalty, so we should be OK.
+ *
+ * Also note that the RTC_ISTAT register does not suffer this penalty; its
+ * writes to clear status registers complete immediately.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/bcd.h>
+#include <linux/rtc.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+
+#include <asm/blackfin.h>
+
+#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __FUNCTION__, __LINE__, ## args)
+#define stampit() stamp("here i am")
+
+struct bfin_rtc {
+ struct rtc_device *rtc_dev;
+ struct rtc_time rtc_alarm;
+ spinlock_t lock;
+};
+
+/* Bit values for the ISTAT / ICTL registers */
+#define RTC_ISTAT_WRITE_COMPLETE 0x8000
+#define RTC_ISTAT_WRITE_PENDING 0x4000
+#define RTC_ISTAT_ALARM_DAY 0x0040
+#define RTC_ISTAT_24HR 0x0020
+#define RTC_ISTAT_HOUR 0x0010
+#define RTC_ISTAT_MIN 0x0008
+#define RTC_ISTAT_SEC 0x0004
+#define RTC_ISTAT_ALARM 0x0002
+#define RTC_ISTAT_STOPWATCH 0x0001
+
+/* Shift values for RTC_STAT register */
+#define DAY_BITS_OFF 17
+#define HOUR_BITS_OFF 12
+#define MIN_BITS_OFF 6
+#define SEC_BITS_OFF 0
+
+/* Some helper functions to convert between the common RTC notion of time
+ * and the internal Blackfin notion that is stored in 32bits.
+ */
+static inline u32 rtc_time_to_bfin(unsigned long now)
+{
+ u32 sec = (now % 60);
+ u32 min = (now % (60 * 60)) / 60;
+ u32 hour = (now % (60 * 60 * 24)) / (60 * 60);
+ u32 days = (now / (60 * 60 * 24));
+ return (sec << SEC_BITS_OFF) +
+ (min << MIN_BITS_OFF) +
+ (hour << HOUR_BITS_OFF) +
+ (days << DAY_BITS_OFF);
+}
+static inline unsigned long rtc_bfin_to_time(u32 rtc_bfin)
+{
+ return (((rtc_bfin >> SEC_BITS_OFF) & 0x003F)) +
+ (((rtc_bfin >> MIN_BITS_OFF) & 0x003F) * 60) +
+ (((rtc_bfin >> HOUR_BITS_OFF) & 0x001F) * 60 * 60) +
+ (((rtc_bfin >> DAY_BITS_OFF) & 0x7FFF) * 60 * 60 * 24);
+}
+static inline void rtc_bfin_to_tm(u32 rtc_bfin, struct rtc_time *tm)
+{
+ rtc_time_to_tm(rtc_bfin_to_time(rtc_bfin), tm);
+}
+
+/* Wait for the previous write to a RTC register to complete.
+ * Unfortunately, we can't sleep here as that introduces a race condition when
+ * turning on interrupt events. Consider this:
+ * - process sets alarm
+ * - process enables alarm
+ * - process sleeps while waiting for rtc write to sync
+ * - interrupt fires while process is sleeping
+ * - interrupt acks the event by writing to ISTAT
+ * - interrupt sets the WRITE PENDING bit
+ * - interrupt handler finishes
+ * - process wakes up, sees WRITE PENDING bit set, goes to sleep
+ * - interrupt fires while process is sleeping
+ * If anyone can point out the obvious solution here, i'm listening :). This
+ * shouldn't be an issue on an SMP or preempt system as this function should
+ * only be called with the rtc lock held.
+ */
+static void rtc_bfin_sync_pending(void)
+{
+ stampit();
+ while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_COMPLETE)) {
+ if (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING))
+ break;
+ }
+ bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE);
+}
+
+static void rtc_bfin_reset(struct bfin_rtc *rtc)
+{
+ /* Initialize the RTC. Enable pre-scaler to scale RTC clock
+ * to 1Hz and clear interrupt/status registers. */
+ spin_lock_irq(&rtc->lock);
+ rtc_bfin_sync_pending();
+ bfin_write_RTC_PREN(0x1);
+ bfin_write_RTC_ICTL(0);
+ bfin_write_RTC_SWCNT(0);
+ bfin_write_RTC_ALARM(0);
+ bfin_write_RTC_ISTAT(0xFFFF);
+ spin_unlock_irq(&rtc->lock);
+}
+
+static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id)
+{
+ struct platform_device *pdev = to_platform_device(dev_id);
+ struct bfin_rtc *rtc = platform_get_drvdata(pdev);
+ unsigned long events = 0;
+ u16 rtc_istat;
+
+ stampit();
+
+ spin_lock_irq(&rtc->lock);
+
+ rtc_istat = bfin_read_RTC_ISTAT();
+
+ if (rtc_istat & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) {
+ bfin_write_RTC_ISTAT(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY);
+ events |= RTC_AF | RTC_IRQF;
+ }
+
+ if (rtc_istat & RTC_ISTAT_STOPWATCH) {
+ bfin_write_RTC_ISTAT(RTC_ISTAT_STOPWATCH);
+ events |= RTC_PF | RTC_IRQF;
+ bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq);
+ }
+
+ if (rtc_istat & RTC_ISTAT_SEC) {
+ bfin_write_RTC_ISTAT(RTC_ISTAT_SEC);
+ events |= RTC_UF | RTC_IRQF;
+ }
+
+ rtc_update_irq(rtc->rtc_dev, 1, events);
+
+ spin_unlock_irq(&rtc->lock);
+
+ return IRQ_HANDLED;
+}
+
+static int bfin_rtc_open(struct device *dev)
+{
+ struct bfin_rtc *rtc = dev_get_drvdata(dev);
+ int ret;
+
+ stampit();
+
+ ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_DISABLED, "rtc-bfin", dev);
+ if (unlikely(ret)) {
+ dev_err(dev, "request RTC IRQ failed with %d\n", ret);
+ return ret;
+ }
+
+ rtc_bfin_reset(rtc);
+
+ return ret;
+}
+
+static void bfin_rtc_release(struct device *dev)
+{
+ struct bfin_rtc *rtc = dev_get_drvdata(dev);
+ stampit();
+ rtc_bfin_reset(rtc);
+ free_irq(IRQ_RTC, dev);
+}
+
+static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+ struct bfin_rtc *rtc = dev_get_drvdata(dev);
+
+ stampit();
+
+ switch (cmd) {
+ case RTC_PIE_ON:
+ stampit();
+ spin_lock_irq(&rtc->lock);
+ rtc_bfin_sync_pending();
+ bfin_write_RTC_ISTAT(RTC_ISTAT_STOPWATCH);
+ bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq);
+ bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | RTC_ISTAT_STOPWATCH);
+ spin_unlock_irq(&rtc->lock);
+ return 0;
+ case RTC_PIE_OFF:
+ stampit();
+ spin_lock_irq(&rtc->lock);
+ rtc_bfin_sync_pending();
+ bfin_write_RTC_SWCNT(0);
+ bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~RTC_ISTAT_STOPWATCH);
+ spin_unlock_irq(&rtc->lock);
+ return 0;
+
+ case RTC_UIE_ON:
+ stampit();
+ spin_lock_irq(&rtc->lock);
+ rtc_bfin_sync_pending();
+ bfin_write_RTC_ISTAT(RTC_ISTAT_SEC);
+ bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | RTC_ISTAT_SEC);
+ spin_unlock_irq(&rtc->lock);
+ return 0;
+ case RTC_UIE_OFF:
+ stampit();
+ spin_lock_irq(&rtc->lock);
+ rtc_bfin_sync_pending();
+ bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~RTC_ISTAT_SEC);
+ spin_unlock_irq(&rtc->lock);
+ return 0;
+
+ case RTC_AIE_ON: {
+ unsigned long rtc_alarm;
+ u16 which_alarm;
+ int ret = 0;
+
+ stampit();
+
+ spin_lock_irq(&rtc->lock);
+
+ rtc_bfin_sync_pending();
+ if (rtc->rtc_alarm.tm_yday == -1) {
+ struct rtc_time now;
+ rtc_bfin_to_tm(bfin_read_RTC_STAT(), &now);
+ now.tm_sec = rtc->rtc_alarm.tm_sec;
+ now.tm_min = rtc->rtc_alarm.tm_min;
+ now.tm_hour = rtc->rtc_alarm.tm_hour;
+ ret = rtc_tm_to_time(&now, &rtc_alarm);
+ which_alarm = RTC_ISTAT_ALARM;
+ } else {
+ ret = rtc_tm_to_time(&rtc->rtc_alarm, &rtc_alarm);
+ which_alarm = RTC_ISTAT_ALARM_DAY;
+ }
+ if (ret == 0) {
+ bfin_write_RTC_ISTAT(which_alarm);
+ bfin_write_RTC_ALARM(rtc_time_to_bfin(rtc_alarm));
+ bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | which_alarm);
+ }
+
+ spin_unlock_irq(&rtc->lock);
+
+ return ret;
+ }
+ case RTC_AIE_OFF:
+ stampit();
+ spin_lock_irq(&rtc->lock);
+ rtc_bfin_sync_pending();
+ bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY));
+ spin_unlock_irq(&rtc->lock);
+ return 0;
+ }
+
+ return -ENOIOCTLCMD;
+}
+
+static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct bfin_rtc *rtc = dev_get_drvdata(dev);
+
+ stampit();
+
+ spin_lock_irq(&rtc->lock);
+ rtc_bfin_sync_pending();
+ rtc_bfin_to_tm(bfin_read_RTC_STAT(), tm);
+ spin_unlock_irq(&rtc->lock);
+
+ return 0;
+}
+
+static int bfin_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct bfin_rtc *rtc = dev_get_drvdata(dev);
+ int ret;
+ unsigned long now;
+
+ stampit();
+
+ spin_lock_irq(&rtc->lock);
+
+ ret = rtc_tm_to_time(tm, &now);
+ if (ret == 0) {
+ rtc_bfin_sync_pending();
+ bfin_write_RTC_STAT(rtc_time_to_bfin(now));
+ }
+
+ spin_unlock_irq(&rtc->lock);
+
+ return ret;
+}
+
+static int bfin_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct bfin_rtc *rtc = dev_get_drvdata(dev);
+ stampit();
+ memcpy(&alrm->time, &rtc->rtc_alarm, sizeof(struct rtc_time));
+ alrm->pending = !!(bfin_read_RTC_ICTL() & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY));
+ return 0;
+}
+
+static int bfin_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct bfin_rtc *rtc = dev_get_drvdata(dev);
+ stampit();
+ memcpy(&rtc->rtc_alarm, &alrm->time, sizeof(struct rtc_time));
+ return 0;
+}
+
+static int bfin_rtc_proc(struct device *dev, struct seq_file *seq)
+{
+#define yesno(x) (x ? "yes" : "no")
+ u16 ictl = bfin_read_RTC_ICTL();
+ stampit();
+ seq_printf(seq, "alarm_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_ALARM));
+ seq_printf(seq, "wkalarm_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_ALARM_DAY));
+ seq_printf(seq, "seconds_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_SEC));
+ seq_printf(seq, "periodic_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_STOPWATCH));
+#ifdef DEBUG
+ seq_printf(seq, "RTC_STAT\t: 0x%08X\n", bfin_read_RTC_STAT());
+ seq_printf(seq, "RTC_ICTL\t: 0x%04X\n", bfin_read_RTC_ICTL());
+ seq_printf(seq, "RTC_ISTAT\t: 0x%04X\n", bfin_read_RTC_ISTAT());
+ seq_printf(seq, "RTC_SWCNT\t: 0x%04X\n", bfin_read_RTC_SWCNT());
+ seq_printf(seq, "RTC_ALARM\t: 0x%08X\n", bfin_read_RTC_ALARM());
+ seq_printf(seq, "RTC_PREN\t: 0x%04X\n", bfin_read_RTC_PREN());
+#endif
+ return 0;
+}
+
+static int bfin_irq_set_freq(struct device *dev, int freq)
+{
+ struct bfin_rtc *rtc = dev_get_drvdata(dev);
+ stampit();
+ rtc->rtc_dev->irq_freq = freq;
+ return 0;
+}
+
+static struct rtc_class_ops bfin_rtc_ops = {
+ .open = bfin_rtc_open,
+ .release = bfin_rtc_release,
+ .ioctl = bfin_rtc_ioctl,
+ .read_time = bfin_rtc_read_time,
+ .set_time = bfin_rtc_set_time,
+ .read_alarm = bfin_rtc_read_alarm,
+ .set_alarm = bfin_rtc_set_alarm,
+ .proc = bfin_rtc_proc,
+ .irq_set_freq = bfin_irq_set_freq,
+};
+
+static int __devinit bfin_rtc_probe(struct platform_device *pdev)
+{
+ struct bfin_rtc *rtc;
+ int ret = 0;
+
+ stampit();
+
+ rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
+ if (unlikely(!rtc))
+ return -ENOMEM;
+
+ spin_lock_init(&rtc->lock);
+
+ rtc->rtc_dev = rtc_device_register(pdev->name, &pdev->dev, &bfin_rtc_ops, THIS_MODULE);
+ if (unlikely(IS_ERR(rtc))) {
+ ret = PTR_ERR(rtc->rtc_dev);
+ goto err;
+ }
+ rtc->rtc_dev->irq_freq = 0;
+ rtc->rtc_dev->max_user_freq = (2 << 16); /* stopwatch is an unsigned 16 bit reg */
+
+ platform_set_drvdata(pdev, rtc);
+
+ return 0;
+
+err:
+ kfree(rtc);
+ return ret;
+}
+
+static int __devexit bfin_rtc_remove(struct platform_device *pdev)
+{
+ struct bfin_rtc *rtc = platform_get_drvdata(pdev);
+
+ rtc_device_unregister(rtc->rtc_dev);
+ platform_set_drvdata(pdev, NULL);
+ kfree(rtc);
+
+ return 0;
+}
+
+static struct platform_driver bfin_rtc_driver = {
+ .driver = {
+ .name = "rtc-bfin",
+ .owner = THIS_MODULE,
+ },
+ .probe = bfin_rtc_probe,
+ .remove = __devexit_p(bfin_rtc_remove),
+};
+
+static int __init bfin_rtc_init(void)
+{
+ stampit();
+ return platform_driver_register(&bfin_rtc_driver);
+}
+
+static void __exit bfin_rtc_exit(void)
+{
+ platform_driver_unregister(&bfin_rtc_driver);
+}
+
+module_init(bfin_rtc_init);
+module_exit(bfin_rtc_exit);
+
+MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver");
+MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 7c0d609..6085261 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -46,6 +46,10 @@ struct cmos_rtc {
int irq;
struct resource *iomem;
+ void (*wake_on)(struct device *);
+ void (*wake_off)(struct device *);
+
+ u8 enabled_wake;
u8 suspend_ctrl;
/* newer hardware extends the original register set */
@@ -203,7 +207,7 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
if (is_intr(rtc_intr))
- rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
+ rtc_update_irq(cmos->rtc, 1, rtc_intr);
/* update alarm */
CMOS_WRITE(hrs, RTC_HOURS_ALARM);
@@ -223,7 +227,7 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
if (is_intr(rtc_intr))
- rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
+ rtc_update_irq(cmos->rtc, 1, rtc_intr);
}
spin_unlock_irq(&rtc_lock);
@@ -304,7 +308,7 @@ cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
if (is_intr(rtc_intr))
- rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
+ rtc_update_irq(cmos->rtc, 1, rtc_intr);
spin_unlock_irqrestore(&rtc_lock, flags);
return 0;
}
@@ -379,12 +383,12 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
return IRQ_NONE;
}
-#ifdef CONFIG_PNPACPI
-#define is_pnpacpi() 1
+#ifdef CONFIG_PNP
+#define is_pnp() 1
#define INITSECTION
#else
-#define is_pnpacpi() 0
+#define is_pnp() 0
#define INITSECTION __init
#endif
@@ -405,13 +409,20 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
cmos_rtc.irq = rtc_irq;
cmos_rtc.iomem = ports;
- /* For ACPI systems the info comes from the FADT. On others,
- * board specific setup provides it as appropriate.
+ /* For ACPI systems extension info comes from the FADT. On others,
+ * board specific setup provides it as appropriate. Systems where
+ * the alarm IRQ isn't automatically a wakeup IRQ (like ACPI, and
+ * some almost-clones) can provide hooks to make that behave.
*/
if (info) {
cmos_rtc.day_alrm = info->rtc_day_alarm;
cmos_rtc.mon_alrm = info->rtc_mon_alarm;
cmos_rtc.century = info->rtc_century;
+
+ if (info->wake_on && info->wake_off) {
+ cmos_rtc.wake_on = info->wake_on;
+ cmos_rtc.wake_off = info->wake_off;
+ }
}
cmos_rtc.rtc = rtc_device_register(driver_name, dev,
@@ -427,14 +438,14 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
* REVISIT for non-x86 systems we may need to handle io memory
* resources: ioremap them, and request_mem_region().
*/
- if (is_pnpacpi()) {
+ if (is_pnp()) {
retval = request_resource(&ioport_resource, ports);
if (retval < 0) {
dev_dbg(dev, "i/o registers already in use\n");
goto cleanup0;
}
}
- rename_region(ports, cmos_rtc.rtc->class_dev.class_id);
+ rename_region(ports, cmos_rtc.rtc->dev.bus_id);
spin_lock_irq(&rtc_lock);
@@ -470,8 +481,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
if (is_valid_irq(rtc_irq))
retval = request_irq(rtc_irq, cmos_interrupt, IRQF_DISABLED,
- cmos_rtc.rtc->class_dev.class_id,
- &cmos_rtc.rtc->class_dev);
+ cmos_rtc.rtc->dev.bus_id,
+ cmos_rtc.rtc);
if (retval < 0) {
dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
goto cleanup1;
@@ -483,7 +494,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
*/
pr_info("%s: alarms up to one %s%s\n",
- cmos_rtc.rtc->class_dev.class_id,
+ cmos_rtc.rtc->dev.bus_id,
is_valid_irq(rtc_irq)
? (cmos_rtc.mon_alrm
? "year"
@@ -520,12 +531,12 @@ static void __exit cmos_do_remove(struct device *dev)
cmos_do_shutdown();
- if (is_pnpacpi())
+ if (is_pnp())
release_resource(cmos->iomem);
rename_region(cmos->iomem, NULL);
if (is_valid_irq(cmos->irq))
- free_irq(cmos->irq, &cmos_rtc.rtc->class_dev);
+ free_irq(cmos->irq, cmos_rtc.rtc);
rtc_device_unregister(cmos_rtc.rtc);
@@ -555,16 +566,20 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg)
irqstat = CMOS_READ(RTC_INTR_FLAGS);
irqstat &= (tmp & RTC_IRQMASK) | RTC_IRQF;
if (is_intr(irqstat))
- rtc_update_irq(&cmos->rtc->class_dev, 1, irqstat);
+ rtc_update_irq(cmos->rtc, 1, irqstat);
}
spin_unlock_irq(&rtc_lock);
- /* ACPI HOOK: enable ACPI_EVENT_RTC when (tmp & RTC_AIE)
- * ... it'd be best if we could do that under rtc_lock.
- */
+ if (tmp & RTC_AIE) {
+ cmos->enabled_wake = 1;
+ if (cmos->wake_on)
+ cmos->wake_on(dev);
+ else
+ enable_irq_wake(cmos->irq);
+ }
pr_debug("%s: suspend%s, ctrl %02x\n",
- cmos_rtc.rtc->class_dev.class_id,
+ cmos_rtc.rtc->dev.bus_id,
(tmp & RTC_AIE) ? ", alarm may wake" : "",
tmp);
@@ -576,26 +591,28 @@ static int cmos_resume(struct device *dev)
struct cmos_rtc *cmos = dev_get_drvdata(dev);
unsigned char tmp = cmos->suspend_ctrl;
- /* REVISIT: a mechanism to resync the system clock (jiffies)
- * on resume should be portable between platforms ...
- */
-
/* re-enable any irqs previously active */
if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) {
- /* ACPI HOOK: disable ACPI_EVENT_RTC when (tmp & RTC_AIE) */
+ if (cmos->enabled_wake) {
+ if (cmos->wake_off)
+ cmos->wake_off(dev);
+ else
+ disable_irq_wake(cmos->irq);
+ cmos->enabled_wake = 0;
+ }
spin_lock_irq(&rtc_lock);
CMOS_WRITE(tmp, RTC_CONTROL);
tmp = CMOS_READ(RTC_INTR_FLAGS);
tmp &= (cmos->suspend_ctrl & RTC_IRQMASK) | RTC_IRQF;
if (is_intr(tmp))
- rtc_update_irq(&cmos->rtc->class_dev, 1, tmp);
+ rtc_update_irq(cmos->rtc, 1, tmp);
spin_unlock_irq(&rtc_lock);
}
pr_debug("%s: resume, ctrl %02x\n",
- cmos_rtc.rtc->class_dev.class_id,
+ cmos_rtc.rtc->dev.bus_id,
cmos->suspend_ctrl);
@@ -613,7 +630,7 @@ static int cmos_resume(struct device *dev)
* the device node will always be created as a PNPACPI device.
*/
-#ifdef CONFIG_PNPACPI
+#ifdef CONFIG_PNP
#include <linux/pnp.h>
@@ -684,11 +701,11 @@ static void __exit cmos_exit(void)
}
module_exit(cmos_exit);
-#else /* no PNPACPI */
+#else /* no PNP */
/*----------------------------------------------------------------*/
-/* Platform setup should have set up an RTC device, when PNPACPI is
+/* Platform setup should have set up an RTC device, when PNP is
* unavailable ... this could happen even on (older) PCs.
*/
@@ -734,7 +751,7 @@ static void __exit cmos_exit(void)
module_exit(cmos_exit);
-#endif /* !PNPACPI */
+#endif /* !PNP */
MODULE_AUTHOR("David Brownell");
MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs");
diff --git a/drivers/rtc/rtc-core.h b/drivers/rtc/rtc-core.h
new file mode 100644
index 0000000..5f9df74
--- /dev/null
+++ b/drivers/rtc/rtc-core.h
@@ -0,0 +1,70 @@
+#ifdef CONFIG_RTC_INTF_DEV
+
+extern void __init rtc_dev_init(void);
+extern void __exit rtc_dev_exit(void);
+extern void rtc_dev_prepare(struct rtc_device *rtc);
+extern void rtc_dev_add_device(struct rtc_device *rtc);
+extern void rtc_dev_del_device(struct rtc_device *rtc);
+
+#else
+
+static inline void rtc_dev_init(void)
+{
+}
+
+static inline void rtc_dev_exit(void)
+{
+}
+
+static inline void rtc_dev_prepare(struct rtc_device *rtc)
+{
+}
+
+static inline void rtc_dev_add_device(struct rtc_device *rtc)
+{
+}
+
+static inline void rtc_dev_del_device(struct rtc_device *rtc)
+{
+}
+
+#endif
+
+#ifdef CONFIG_RTC_INTF_PROC
+
+extern void rtc_proc_add_device(struct rtc_device *rtc);
+extern void rtc_proc_del_device(struct rtc_device *rtc);
+
+#else
+
+static inline void rtc_proc_add_device(struct rtc_device *rtc)
+{
+}
+
+static inline void rtc_proc_del_device(struct rtc_device *rtc)
+{
+}
+
+#endif
+
+#ifdef CONFIG_RTC_INTF_SYSFS
+
+extern void __init rtc_sysfs_init(struct class *);
+extern void rtc_sysfs_add_device(struct rtc_device *rtc);
+extern void rtc_sysfs_del_device(struct rtc_device *rtc);
+
+#else
+
+static inline void rtc_sysfs_init(struct class *rtc)
+{
+}
+
+static inline void rtc_sysfs_add_device(struct rtc_device *rtc)
+{
+}
+
+static inline void rtc_sysfs_del_device(struct rtc_device *rtc)
+{
+}
+
+#endif
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 137330b..f4e5f00 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -13,8 +13,8 @@
#include <linux/module.h>
#include <linux/rtc.h>
+#include "rtc-core.h"
-static struct class *rtc_dev_class;
static dev_t rtc_devt;
#define RTC_DEV_MAX 16 /* 16 RTCs should be enough for everyone... */
@@ -32,9 +32,9 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
if (!(mutex_trylock(&rtc->char_lock)))
return -EBUSY;
- file->private_data = &rtc->class_dev;
+ file->private_data = rtc;
- err = ops->open ? ops->open(rtc->class_dev.dev) : 0;
+ err = ops->open ? ops->open(rtc->dev.parent) : 0;
if (err == 0) {
spin_lock_irq(&rtc->irq_lock);
rtc->irq_data = 0;
@@ -61,7 +61,7 @@ static void rtc_uie_task(struct work_struct *work)
int num = 0;
int err;
- err = rtc_read_time(&rtc->class_dev, &tm);
+ err = rtc_read_time(rtc, &tm);
local_irq_disable();
spin_lock(&rtc->irq_lock);
@@ -79,7 +79,7 @@ static void rtc_uie_task(struct work_struct *work)
}
spin_unlock(&rtc->irq_lock);
if (num)
- rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF);
+ rtc_update_irq(rtc, num, RTC_UF | RTC_IRQF);
local_irq_enable();
}
static void rtc_uie_timer(unsigned long data)
@@ -121,7 +121,7 @@ static int set_uie(struct rtc_device *rtc)
struct rtc_time tm;
int err;
- err = rtc_read_time(&rtc->class_dev, &tm);
+ err = rtc_read_time(rtc, &tm);
if (err)
return err;
spin_lock_irq(&rtc->irq_lock);
@@ -180,7 +180,7 @@ rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
if (ret == 0) {
/* Check for any data updates */
if (rtc->ops->read_callback)
- data = rtc->ops->read_callback(rtc->class_dev.dev,
+ data = rtc->ops->read_callback(rtc->dev.parent,
data);
if (sizeof(int) != sizeof(long) &&
@@ -210,8 +210,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
int err = 0;
- struct class_device *class_dev = file->private_data;
- struct rtc_device *rtc = to_rtc_device(class_dev);
+ struct rtc_device *rtc = file->private_data;
const struct rtc_class_ops *ops = rtc->ops;
struct rtc_time tm;
struct rtc_wkalrm alarm;
@@ -252,7 +251,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
/* try the driver's ioctl interface */
if (ops->ioctl) {
- err = ops->ioctl(class_dev->dev, cmd, arg);
+ err = ops->ioctl(rtc->dev.parent, cmd, arg);
if (err != -ENOIOCTLCMD)
return err;
}
@@ -264,7 +263,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
case RTC_ALM_READ:
- err = rtc_read_alarm(class_dev, &alarm);
+ err = rtc_read_alarm(rtc, &alarm);
if (err < 0)
return err;
@@ -278,17 +277,53 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
alarm.enabled = 0;
alarm.pending = 0;
- alarm.time.tm_mday = -1;
- alarm.time.tm_mon = -1;
- alarm.time.tm_year = -1;
alarm.time.tm_wday = -1;
alarm.time.tm_yday = -1;
alarm.time.tm_isdst = -1;
- err = rtc_set_alarm(class_dev, &alarm);
+
+ /* RTC_ALM_SET alarms may be up to 24 hours in the future.
+ * Rather than expecting every RTC to implement "don't care"
+ * for day/month/year fields, just force the alarm to have
+ * the right values for those fields.
+ *
+ * RTC_WKALM_SET should be used instead. Not only does it
+ * eliminate the need for a separate RTC_AIE_ON call, it
+ * doesn't have the "alarm 23:59:59 in the future" race.
+ *
+ * NOTE: some legacy code may have used invalid fields as
+ * wildcards, exposing hardware "periodic alarm" capabilities.
+ * Not supported here.
+ */
+ {
+ unsigned long now, then;
+
+ err = rtc_read_time(rtc, &tm);
+ if (err < 0)
+ return err;
+ rtc_tm_to_time(&tm, &now);
+
+ alarm.time.tm_mday = tm.tm_mday;
+ alarm.time.tm_mon = tm.tm_mon;
+ alarm.time.tm_year = tm.tm_year;
+ err = rtc_valid_tm(&alarm.time);
+ if (err < 0)
+ return err;
+ rtc_tm_to_time(&alarm.time, &then);
+
+ /* alarm may need to wrap into tomorrow */
+ if (then < now) {
+ rtc_time_to_tm(now + 24 * 60 * 60, &tm);
+ alarm.time.tm_mday = tm.tm_mday;
+ alarm.time.tm_mon = tm.tm_mon;
+ alarm.time.tm_year = tm.tm_year;
+ }
+ }
+
+ err = rtc_set_alarm(rtc, &alarm);
break;
case RTC_RD_TIME:
- err = rtc_read_time(class_dev, &tm);
+ err = rtc_read_time(rtc, &tm);
if (err < 0)
return err;
@@ -300,7 +335,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
if (copy_from_user(&tm, uarg, sizeof(tm)))
return -EFAULT;
- err = rtc_set_time(class_dev, &tm);
+ err = rtc_set_time(rtc, &tm);
break;
case RTC_IRQP_READ:
@@ -310,7 +345,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
case RTC_IRQP_SET:
if (ops->irq_set_freq)
- err = rtc_irq_set_freq(class_dev, rtc->irq_task, arg);
+ err = rtc_irq_set_freq(rtc, rtc->irq_task, arg);
break;
#if 0
@@ -336,11 +371,11 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
if (copy_from_user(&alarm, uarg, sizeof(alarm)))
return -EFAULT;
- err = rtc_set_alarm(class_dev, &alarm);
+ err = rtc_set_alarm(rtc, &alarm);
break;
case RTC_WKALM_RD:
- err = rtc_read_alarm(class_dev, &alarm);
+ err = rtc_read_alarm(rtc, &alarm);
if (err < 0)
return err;
@@ -372,7 +407,7 @@ static int rtc_dev_release(struct inode *inode, struct file *file)
clear_uie(rtc);
#endif
if (rtc->ops->release)
- rtc->ops->release(rtc->class_dev.dev);
+ rtc->ops->release(rtc->dev.parent);
mutex_unlock(&rtc->char_lock);
return 0;
@@ -397,17 +432,18 @@ static const struct file_operations rtc_dev_fops = {
/* insertion/removal hooks */
-static int rtc_dev_add_device(struct class_device *class_dev,
- struct class_interface *class_intf)
+void rtc_dev_prepare(struct rtc_device *rtc)
{
- int err = 0;
- struct rtc_device *rtc = to_rtc_device(class_dev);
+ if (!rtc_devt)
+ return;
if (rtc->id >= RTC_DEV_MAX) {
- dev_err(class_dev->dev, "too many RTCs\n");
- return -EINVAL;
+ pr_debug("%s: too many RTC devices\n", rtc->name);
+ return;
}
+ rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id);
+
mutex_init(&rtc->char_lock);
spin_lock_init(&rtc->irq_lock);
init_waitqueue_head(&rtc->irq_queue);
@@ -418,100 +454,36 @@ static int rtc_dev_add_device(struct class_device *class_dev,
cdev_init(&rtc->char_dev, &rtc_dev_fops);
rtc->char_dev.owner = rtc->owner;
+}
- if (cdev_add(&rtc->char_dev, MKDEV(MAJOR(rtc_devt), rtc->id), 1)) {
- dev_err(class_dev->dev,
- "failed to add char device %d:%d\n",
+void rtc_dev_add_device(struct rtc_device *rtc)
+{
+ if (cdev_add(&rtc->char_dev, rtc->dev.devt, 1))
+ printk(KERN_WARNING "%s: failed to add char device %d:%d\n",
+ rtc->name, MAJOR(rtc_devt), rtc->id);
+ else
+ pr_debug("%s: dev (%d:%d)\n", rtc->name,
MAJOR(rtc_devt), rtc->id);
- return -ENODEV;
- }
-
- rtc->rtc_dev = class_device_create(rtc_dev_class, NULL,
- MKDEV(MAJOR(rtc_devt), rtc->id),
- class_dev->dev, "rtc%d", rtc->id);
- if (IS_ERR(rtc->rtc_dev)) {
- dev_err(class_dev->dev, "cannot create rtc_dev device\n");
- err = PTR_ERR(rtc->rtc_dev);
- goto err_cdev_del;
- }
-
- dev_dbg(class_dev->dev, "rtc intf: dev (%d:%d)\n",
- MAJOR(rtc->rtc_dev->devt),
- MINOR(rtc->rtc_dev->devt));
-
- return 0;
-
-err_cdev_del:
-
- cdev_del(&rtc->char_dev);
- return err;
}
-static void rtc_dev_remove_device(struct class_device *class_dev,
- struct class_interface *class_intf)
+void rtc_dev_del_device(struct rtc_device *rtc)
{
- struct rtc_device *rtc = to_rtc_device(class_dev);
-
- if (rtc->rtc_dev) {
- dev_dbg(class_dev->dev, "removing char %d:%d\n",
- MAJOR(rtc->rtc_dev->devt),
- MINOR(rtc->rtc_dev->devt));
-
- class_device_unregister(rtc->rtc_dev);
+ if (rtc->dev.devt)
cdev_del(&rtc->char_dev);
- }
}
-/* interface registration */
-
-static struct class_interface rtc_dev_interface = {
- .add = &rtc_dev_add_device,
- .remove = &rtc_dev_remove_device,
-};
-
-static int __init rtc_dev_init(void)
+void __init rtc_dev_init(void)
{
int err;
- rtc_dev_class = class_create(THIS_MODULE, "rtc-dev");
- if (IS_ERR(rtc_dev_class))
- return PTR_ERR(rtc_dev_class);
-
err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc");
- if (err < 0) {
+ if (err < 0)
printk(KERN_ERR "%s: failed to allocate char dev region\n",
__FILE__);
- goto err_destroy_class;
- }
-
- err = rtc_interface_register(&rtc_dev_interface);
- if (err < 0) {
- printk(KERN_ERR "%s: failed to register the interface\n",
- __FILE__);
- goto err_unregister_chrdev;
- }
-
- return 0;
-
-err_unregister_chrdev:
- unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
-
-err_destroy_class:
- class_destroy(rtc_dev_class);
-
- return err;
}
-static void __exit rtc_dev_exit(void)
+void __exit rtc_dev_exit(void)
{
- class_interface_unregister(&rtc_dev_interface);
- class_destroy(rtc_dev_class);
- unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
+ if (rtc_devt)
+ unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
}
-
-subsys_initcall(rtc_dev_init);
-module_exit(rtc_dev_exit);
-
-MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
-MODULE_DESCRIPTION("RTC class dev interface");
-MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index e27176c..afa64c7 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -203,7 +203,7 @@ static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id)
events |= RTC_UF;
else
events |= RTC_AF;
- rtc_update_irq(&pdata->rtc->class_dev, 1, events);
+ rtc_update_irq(pdata->rtc, 1, events);
return IRQ_HANDLED;
}
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
index 7bbc26a..ba795a4 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/rtc-lib.c
@@ -117,85 +117,4 @@ int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
}
EXPORT_SYMBOL(rtc_tm_to_time);
-
-/* Merge the valid (i.e. non-negative) fields of alarm into the current
- * time. If the valid alarm fields are earlier than the equivalent
- * fields in the time, carry one into the least significant invalid
- * field, so that the alarm expiry is in the future. It assumes that the
- * least significant invalid field is more significant than the most
- * significant valid field, and that the seconds field is valid.
- *
- * This is used by alarms that take relative (rather than absolute)
- * times, and/or have a simple binary second counter instead of
- * day/hour/minute/sec registers.
- */
-void rtc_merge_alarm(struct rtc_time *now, struct rtc_time *alarm)
-{
- int *alarmp = &alarm->tm_sec;
- int *timep = &now->tm_sec;
- int carry_into, i;
-
- /* Ignore everything past the 6th element (tm_year). */
- for (i = 5; i > 0; i--) {
- if (alarmp[i] < 0)
- alarmp[i] = timep[i];
- else
- break;
- }
-
- /* No carry needed if all fields are valid. */
- if (i == 5)
- return;
-
- for (carry_into = i + 1; i >= 0; i--) {
- if (alarmp[i] < timep[i])
- break;
-
- if (alarmp[i] > timep[i])
- return;
- }
-
- switch (carry_into) {
- case 1:
- alarm->tm_min++;
-
- if (alarm->tm_min < 60)
- return;
-
- alarm->tm_min = 0;
- /* fall-through */
-
- case 2:
- alarm->tm_hour++;
-
- if (alarm->tm_hour < 60)
- return;
-
- alarm->tm_hour = 0;
- /* fall-through */
-
- case 3:
- alarm->tm_mday++;
-
- if (alarm->tm_mday <= rtc_days_in_month[alarm->tm_mon])
- return;
-
- alarm->tm_mday = 1;
- /* fall-through */
-
- case 4:
- alarm->tm_mon++;
-
- if (alarm->tm_mon <= 12)
- return;
-
- alarm->tm_mon = 1;
- /* fall-through */
-
- case 5:
- alarm->tm_year++;
- }
-}
-EXPORT_SYMBOL(rtc_merge_alarm);
-
MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c
new file mode 100644
index 0000000..eee4ee5
--- /dev/null
+++ b/drivers/rtc/rtc-max6900.c
@@ -0,0 +1,311 @@
+/*
+ * rtc class driver for the Maxim MAX6900 chip
+ *
+ * Author: Dale Farnsworth <dale@farnsworth.org>
+ *
+ * based on previously existing rtc class drivers
+ *
+ * 2007 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/bcd.h>
+#include <linux/rtc.h>
+#include <linux/delay.h>
+
+#define DRV_NAME "max6900"
+#define DRV_VERSION "0.1"
+
+/*
+ * register indices
+ */
+#define MAX6900_REG_SC 0 /* seconds 00-59 */
+#define MAX6900_REG_MN 1 /* minutes 00-59 */
+#define MAX6900_REG_HR 2 /* hours 00-23 */
+#define MAX6900_REG_DT 3 /* day of month 00-31 */
+#define MAX6900_REG_MO 4 /* month 01-12 */
+#define MAX6900_REG_DW 5 /* day of week 1-7 */
+#define MAX6900_REG_YR 6 /* year 00-99 */
+#define MAX6900_REG_CT 7 /* control */
+#define MAX6900_REG_LEN 8
+
+#define MAX6900_REG_CT_WP (1 << 7) /* Write Protect */
+
+/*
+ * register read/write commands
+ */
+#define MAX6900_REG_CONTROL_WRITE 0x8e
+#define MAX6900_REG_BURST_READ 0xbf
+#define MAX6900_REG_BURST_WRITE 0xbe
+#define MAX6900_REG_RESERVED_READ 0x96
+
+#define MAX6900_IDLE_TIME_AFTER_WRITE 3 /* specification says 2.5 mS */
+
+#define MAX6900_I2C_ADDR 0xa0
+
+static unsigned short normal_i2c[] = {
+ MAX6900_I2C_ADDR >> 1,
+ I2C_CLIENT_END
+};
+
+I2C_CLIENT_INSMOD; /* defines addr_data */
+
+static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind);
+
+static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf)
+{
+ u8 reg_addr[1] = { MAX6900_REG_BURST_READ };
+ struct i2c_msg msgs[2] = {
+ {
+ .addr = client->addr,
+ .flags = 0, /* write */
+ .len = sizeof(reg_addr),
+ .buf = reg_addr
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = MAX6900_REG_LEN,
+ .buf = buf
+ }
+ };
+ int rc;
+
+ rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+ if (rc != ARRAY_SIZE(msgs)) {
+ dev_err(&client->dev, "%s: register read failed\n",
+ __FUNCTION__);
+ return -EIO;
+ }
+ return 0;
+}
+
+static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
+{
+ u8 i2c_buf[MAX6900_REG_LEN + 1] = { MAX6900_REG_BURST_WRITE };
+ struct i2c_msg msgs[1] = {
+ {
+ .addr = client->addr,
+ .flags = 0, /* write */
+ .len = MAX6900_REG_LEN + 1,
+ .buf = i2c_buf
+ }
+ };
+ int rc;
+
+ memcpy(&i2c_buf[1], buf, MAX6900_REG_LEN);
+
+ rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+ if (rc != ARRAY_SIZE(msgs)) {
+ dev_err(&client->dev, "%s: register write failed\n",
+ __FUNCTION__);
+ return -EIO;
+ }
+ msleep(MAX6900_IDLE_TIME_AFTER_WRITE);
+ return 0;
+}
+
+static int max6900_i2c_validate_client(struct i2c_client *client)
+{
+ u8 regs[MAX6900_REG_LEN];
+ u8 zero_mask[MAX6900_REG_LEN] = {
+ 0x80, /* seconds */
+ 0x80, /* minutes */
+ 0x40, /* hours */
+ 0xc0, /* day of month */
+ 0xe0, /* month */
+ 0xf8, /* day of week */
+ 0x00, /* year */
+ 0x7f, /* control */
+ };
+ int i;
+ int rc;
+ int reserved;
+
+ reserved = i2c_smbus_read_byte_data(client, MAX6900_REG_RESERVED_READ);
+ if (reserved != 0x07)
+ return -ENODEV;
+
+ rc = max6900_i2c_read_regs(client, regs);
+ if (rc < 0)
+ return rc;
+
+ for (i = 0; i < MAX6900_REG_LEN; ++i) {
+ if (regs[i] & zero_mask[i])
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
+{
+ int rc;
+ u8 regs[MAX6900_REG_LEN];
+
+ rc = max6900_i2c_read_regs(client, regs);
+ if (rc < 0)
+ return rc;
+
+ tm->tm_sec = BCD2BIN(regs[MAX6900_REG_SC]);
+ tm->tm_min = BCD2BIN(regs[MAX6900_REG_MN]);
+ tm->tm_hour = BCD2BIN(regs[MAX6900_REG_HR] & 0x3f);
+ tm->tm_mday = BCD2BIN(regs[MAX6900_REG_DT]);
+ tm->tm_mon = BCD2BIN(regs[MAX6900_REG_MO]) - 1;
+ tm->tm_year = BCD2BIN(regs[MAX6900_REG_YR]) + 100;
+ tm->tm_wday = BCD2BIN(regs[MAX6900_REG_DW]);
+
+ return 0;
+}
+
+static int max6900_i2c_clear_write_protect(struct i2c_client *client)
+{
+ int rc;
+ rc = i2c_smbus_write_byte_data (client, MAX6900_REG_CONTROL_WRITE, 0);
+ if (rc < 0) {
+ dev_err(&client->dev, "%s: control register write failed\n",
+ __FUNCTION__);
+ return -EIO;
+ }
+ return 0;
+}
+
+static int max6900_i2c_set_time(struct i2c_client *client,
+ struct rtc_time const *tm)
+{
+ u8 regs[MAX6900_REG_LEN];
+ int rc;
+
+ rc = max6900_i2c_clear_write_protect(client);
+ if (rc < 0)
+ return rc;
+
+ regs[MAX6900_REG_SC] = BIN2BCD(tm->tm_sec);
+ regs[MAX6900_REG_MN] = BIN2BCD(tm->tm_min);
+ regs[MAX6900_REG_HR] = BIN2BCD(tm->tm_hour);
+ regs[MAX6900_REG_DT] = BIN2BCD(tm->tm_mday);
+ regs[MAX6900_REG_MO] = BIN2BCD(tm->tm_mon + 1);
+ regs[MAX6900_REG_YR] = BIN2BCD(tm->tm_year - 100);
+ regs[MAX6900_REG_DW] = BIN2BCD(tm->tm_wday);
+ regs[MAX6900_REG_CT] = MAX6900_REG_CT_WP; /* set write protect */
+
+ rc = max6900_i2c_write_regs(client, regs);
+ if (rc < 0)
+ return rc;
+
+ return 0;
+}
+
+static int max6900_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ return max6900_i2c_read_time(to_i2c_client(dev), tm);
+}
+
+static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ return max6900_i2c_set_time(to_i2c_client(dev), tm);
+}
+
+static int max6900_attach_adapter(struct i2c_adapter *adapter)
+{
+ return i2c_probe(adapter, &addr_data, max6900_probe);
+}
+
+static int max6900_detach_client(struct i2c_client *client)
+{
+ struct rtc_device *const rtc = i2c_get_clientdata(client);
+
+ if (rtc)
+ rtc_device_unregister(rtc);
+
+ return i2c_detach_client(client);
+}
+
+static struct i2c_driver max6900_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ },
+ .id = I2C_DRIVERID_MAX6900,
+ .attach_adapter = max6900_attach_adapter,
+ .detach_client = max6900_detach_client,
+};
+
+static const struct rtc_class_ops max6900_rtc_ops = {
+ .read_time = max6900_rtc_read_time,
+ .set_time = max6900_rtc_set_time,
+};
+
+static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind)
+{
+ int rc = 0;
+ struct i2c_client *client = NULL;
+ struct rtc_device *rtc = NULL;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
+ rc = -ENODEV;
+ goto failout;
+ }
+
+ client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == NULL) {
+ rc = -ENOMEM;
+ goto failout;
+ }
+
+ client->addr = addr;
+ client->adapter = adapter;
+ client->driver = &max6900_driver;
+ strlcpy(client->name, DRV_NAME, I2C_NAME_SIZE);
+
+ if (kind < 0) {
+ rc = max6900_i2c_validate_client(client);
+ if (rc < 0)
+ goto failout;
+ }
+
+ rc = i2c_attach_client(client);
+ if (rc < 0)
+ goto failout;
+
+ dev_info(&client->dev,
+ "chip found, driver version " DRV_VERSION "\n");
+
+ rtc = rtc_device_register(max6900_driver.driver.name,
+ &client->dev,
+ &max6900_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc)) {
+ rc = PTR_ERR(rtc);
+ goto failout_detach;
+ }
+
+ i2c_set_clientdata(client, rtc);
+
+ return 0;
+
+failout_detach:
+ i2c_detach_client(client);
+failout:
+ kfree(client);
+ return rc;
+}
+
+static int __init max6900_init(void)
+{
+ return i2c_add_driver(&max6900_driver);
+}
+
+static void __exit max6900_exit(void)
+{
+ i2c_del_driver(&max6900_driver);
+}
+
+MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+module_init(max6900_init);
+module_exit(max6900_exit);
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 9de8d67..60a8a4b 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -124,7 +124,7 @@ static void rtc_wait_not_busy(void)
/* now we have ~15 usec to read/write various registers */
}
-static irqreturn_t rtc_irq(int irq, void *class_dev)
+static irqreturn_t rtc_irq(int irq, void *rtc)
{
unsigned long events = 0;
u8 irq_data;
@@ -141,7 +141,7 @@ static irqreturn_t rtc_irq(int irq, void *class_dev)
if (irq_data & OMAP_RTC_STATUS_1S_EVENT)
events |= RTC_IRQF | RTC_UF;
- rtc_update_irq(class_dev, 1, events);
+ rtc_update_irq(rtc, 1, events);
return IRQ_HANDLED;
}
@@ -289,34 +289,6 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
u8 reg;
- /* Much userspace code uses RTC_ALM_SET, thus "don't care" for
- * day/month/year specifies alarms up to 24 hours in the future.
- * So we need to handle that ... but let's ignore the "don't care"
- * values for hours/minutes/seconds.
- */
- if (alm->time.tm_mday <= 0
- && alm->time.tm_mon < 0
- && alm->time.tm_year < 0) {
- struct rtc_time tm;
- unsigned long now, then;
-
- omap_rtc_read_time(dev, &tm);
- rtc_tm_to_time(&tm, &now);
-
- alm->time.tm_mday = tm.tm_mday;
- alm->time.tm_mon = tm.tm_mon;
- alm->time.tm_year = tm.tm_year;
- rtc_tm_to_time(&alm->time, &then);
-
- /* sometimes the alarm wraps into tomorrow */
- if (then < now) {
- rtc_time_to_tm(now + 24 * 60 * 60, &tm);
- alm->time.tm_mday = tm.tm_mday;
- alm->time.tm_mon = tm.tm_mon;
- alm->time.tm_year = tm.tm_year;
- }
- }
-
if (tm2bcd(&alm->time) < 0)
return -EINVAL;
@@ -399,7 +371,7 @@ static int __devinit omap_rtc_probe(struct platform_device *pdev)
goto fail;
}
platform_set_drvdata(pdev, rtc);
- class_set_devdata(&rtc->class_dev, mem);
+ dev_set_devdata(&rtc->dev, mem);
/* clear pending irqs, and set 1/second periodic,
* which we'll use instead of update irqs
@@ -418,13 +390,13 @@ static int __devinit omap_rtc_probe(struct platform_device *pdev)
/* handle periodic and alarm irqs */
if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED,
- rtc->class_dev.class_id, &rtc->class_dev)) {
+ rtc->dev.bus_id, rtc)) {
pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
pdev->name, omap_rtc_timer);
goto fail0;
}
if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED,
- rtc->class_dev.class_id, &rtc->class_dev)) {
+ rtc->dev.bus_id, rtc)) {
pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
pdev->name, omap_rtc_alarm);
goto fail1;
@@ -481,26 +453,17 @@ static int __devexit omap_rtc_remove(struct platform_device *pdev)
free_irq(omap_rtc_timer, rtc);
free_irq(omap_rtc_alarm, rtc);
- release_resource(class_get_devdata(&rtc->class_dev));
+ release_resource(dev_get_devdata(&rtc->dev));
rtc_device_unregister(rtc);
return 0;
}
#ifdef CONFIG_PM
-static struct timespec rtc_delta;
static u8 irqstat;
static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct rtc_time rtc_tm;
- struct timespec time;
-
- time.tv_nsec = 0;
- omap_rtc_read_time(NULL, &rtc_tm);
- rtc_tm_to_time(&rtc_tm, &time.tv_sec);
-
- save_time_delta(&rtc_delta, &time);
irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG);
/* FIXME the RTC alarm is not currently acting as a wakeup event
@@ -517,14 +480,6 @@ static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state)
static int omap_rtc_resume(struct platform_device *pdev)
{
- struct rtc_time rtc_tm;
- struct timespec time;
-
- time.tv_nsec = 0;
- omap_rtc_read_time(NULL, &rtc_tm);
- rtc_tm_to_time(&rtc_tm, &time.tv_sec);
-
- restore_time_delta(&rtc_delta, &time);
if (device_may_wakeup(&pdev->dev))
disable_irq_wake(omap_rtc_alarm);
else
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index f13daa9..e4bf68c 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -51,7 +51,7 @@ static irqreturn_t pl031_interrupt(int irq, void *dev_id)
{
struct rtc_device *rtc = dev_id;
- rtc_update_irq(&rtc->class_dev, 1, RTC_AF);
+ rtc_update_irq(rtc, 1, RTC_AF);
return IRQ_HANDLED;
}
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c
index 1bd624f..8d300e6 100644
--- a/drivers/rtc/rtc-proc.c
+++ b/drivers/rtc/rtc-proc.c
@@ -16,18 +16,18 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-static struct class_device *rtc_dev = NULL;
-static DEFINE_MUTEX(rtc_lock);
+#include "rtc-core.h"
+
static int rtc_proc_show(struct seq_file *seq, void *offset)
{
int err;
- struct class_device *class_dev = seq->private;
- const struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops;
+ struct rtc_device *rtc = seq->private;
+ const struct rtc_class_ops *ops = rtc->ops;
struct rtc_wkalrm alrm;
struct rtc_time tm;
- err = rtc_read_time(class_dev, &tm);
+ err = rtc_read_time(rtc, &tm);
if (err == 0) {
seq_printf(seq,
"rtc_time\t: %02d:%02d:%02d\n"
@@ -36,7 +36,7 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
}
- err = rtc_read_alarm(class_dev, &alrm);
+ err = rtc_read_alarm(rtc, &alrm);
if (err == 0) {
seq_printf(seq, "alrm_time\t: ");
if ((unsigned int)alrm.time.tm_hour <= 24)
@@ -74,19 +74,19 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
seq_printf(seq, "24hr\t\t: yes\n");
if (ops->proc)
- ops->proc(class_dev->dev, seq);
+ ops->proc(rtc->dev.parent, seq);
return 0;
}
static int rtc_proc_open(struct inode *inode, struct file *file)
{
- struct class_device *class_dev = PDE(inode)->data;
+ struct rtc_device *rtc = PDE(inode)->data;
if (!try_module_get(THIS_MODULE))
return -ENODEV;
- return single_open(file, rtc_proc_show, class_dev);
+ return single_open(file, rtc_proc_show, rtc);
}
static int rtc_proc_release(struct inode *inode, struct file *file)
@@ -103,62 +103,22 @@ static const struct file_operations rtc_proc_fops = {
.release = rtc_proc_release,
};
-static int rtc_proc_add_device(struct class_device *class_dev,
- struct class_interface *class_intf)
+void rtc_proc_add_device(struct rtc_device *rtc)
{
- mutex_lock(&rtc_lock);
- if (rtc_dev == NULL) {
+ if (rtc->id == 0) {
struct proc_dir_entry *ent;
- rtc_dev = class_dev;
-
ent = create_proc_entry("driver/rtc", 0, NULL);
if (ent) {
- struct rtc_device *rtc = to_rtc_device(class_dev);
-
ent->proc_fops = &rtc_proc_fops;
ent->owner = rtc->owner;
- ent->data = class_dev;
-
- dev_dbg(class_dev->dev, "rtc intf: proc\n");
+ ent->data = rtc;
}
- else
- rtc_dev = NULL;
}
- mutex_unlock(&rtc_lock);
-
- return 0;
}
-static void rtc_proc_remove_device(struct class_device *class_dev,
- struct class_interface *class_intf)
+void rtc_proc_del_device(struct rtc_device *rtc)
{
- mutex_lock(&rtc_lock);
- if (rtc_dev == class_dev) {
+ if (rtc->id == 0)
remove_proc_entry("driver/rtc", NULL);
- rtc_dev = NULL;
- }
- mutex_unlock(&rtc_lock);
-}
-
-static struct class_interface rtc_proc_interface = {
- .add = &rtc_proc_add_device,
- .remove = &rtc_proc_remove_device,
-};
-
-static int __init rtc_proc_init(void)
-{
- return rtc_interface_register(&rtc_proc_interface);
}
-
-static void __exit rtc_proc_exit(void)
-{
- class_interface_unregister(&rtc_proc_interface);
-}
-
-subsys_initcall(rtc_proc_init);
-module_exit(rtc_proc_exit);
-
-MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
-MODULE_DESCRIPTION("RTC class proc interface");
-MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c
new file mode 100644
index 0000000..9d6de37
--- /dev/null
+++ b/drivers/rtc/rtc-rs5c313.c
@@ -0,0 +1,405 @@
+/*
+ * Ricoh RS5C313 RTC device/driver
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * 2005-09-19 modifed by kogiidena
+ *
+ * Based on the old drivers/char/rs5c313_rtc.c by:
+ * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
+ * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
+ *
+ * Based on code written by Paul Gortmaker.
+ * Copyright (C) 1996 Paul Gortmaker
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Based on other minimal char device drivers, like Alan's
+ * watchdog, Ted's random, etc. etc.
+ *
+ * 1.07 Paul Gortmaker.
+ * 1.08 Miquel van Smoorenburg: disallow certain things on the
+ * DEC Alpha as the CMOS clock is also used for other things.
+ * 1.09 Nikita Schmidt: epoch support and some Alpha cleanup.
+ * 1.09a Pete Zaitcev: Sun SPARC
+ * 1.09b Jeff Garzik: Modularize, init cleanup
+ * 1.09c Jeff Garzik: SMP cleanup
+ * 1.10 Paul Barton-Davis: add support for async I/O
+ * 1.10a Andrea Arcangeli: Alpha updates
+ * 1.10b Andrew Morton: SMP lock fix
+ * 1.10c Cesar Barros: SMP locking fixes and cleanup
+ * 1.10d Paul Gortmaker: delete paranoia check in rtc_exit
+ * 1.10e Maciej W. Rozycki: Handle DECstation's year weirdness.
+ * 1.11 Takashi Iwai: Kernel access functions
+ * rtc_register/rtc_unregister/rtc_control
+ * 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init
+ * 1.12 Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer
+ * CONFIG_HPET_EMULATE_RTC
+ * 1.13 Nobuhiro Iwamatsu: Updata driver.
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+#include <linux/bcd.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#define DRV_NAME "rs5c313"
+#define DRV_VERSION "1.13"
+
+#ifdef CONFIG_SH_LANDISK
+/*****************************************************/
+/* LANDISK dependence part of RS5C313 */
+/*****************************************************/
+
+#define SCSMR1 0xFFE00000
+#define SCSCR1 0xFFE00008
+#define SCSMR1_CA 0x80
+#define SCSCR1_CKE 0x03
+#define SCSPTR1 0xFFE0001C
+#define SCSPTR1_EIO 0x80
+#define SCSPTR1_SPB1IO 0x08
+#define SCSPTR1_SPB1DT 0x04
+#define SCSPTR1_SPB0IO 0x02
+#define SCSPTR1_SPB0DT 0x01
+
+#define SDA_OEN SCSPTR1_SPB1IO
+#define SDA SCSPTR1_SPB1DT
+#define SCL_OEN SCSPTR1_SPB0IO
+#define SCL SCSPTR1_SPB0DT
+
+/* RICOH RS5C313 CE port */
+#define RS5C313_CE 0xB0000003
+
+/* RICOH RS5C313 CE port bit */
+#define RS5C313_CE_RTCCE 0x02
+
+/* SCSPTR1 data */
+unsigned char scsptr1_data;
+
+#define RS5C313_CEENABLE ctrl_outb(RS5C313_CE_RTCCE, RS5C313_CE);
+#define RS5C313_CEDISABLE ctrl_outb(0x00, RS5C313_CE)
+#define RS5C313_MISCOP ctrl_outb(0x02, 0xB0000008)
+
+static void rs5c313_init_port(void)
+{
+ /* Set SCK as I/O port and Initialize SCSPTR1 data & I/O port. */
+ ctrl_outb(ctrl_inb(SCSMR1) & ~SCSMR1_CA, SCSMR1);
+ ctrl_outb(ctrl_inb(SCSCR1) & ~SCSCR1_CKE, SCSCR1);
+
+ /* And Initialize SCL for RS5C313 clock */
+ scsptr1_data = ctrl_inb(SCSPTR1) | SCL; /* SCL:H */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ scsptr1_data = ctrl_inb(SCSPTR1) | SCL_OEN; /* SCL output enable */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ RS5C313_CEDISABLE; /* CE:L */
+}
+
+static void rs5c313_write_data(unsigned char data)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ /* SDA:Write Data */
+ scsptr1_data = (scsptr1_data & ~SDA) |
+ ((((0x80 >> i) & data) >> (7 - i)) << 2);
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ if (i == 0) {
+ scsptr1_data |= SDA_OEN; /* SDA:output enable */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ }
+ ndelay(700);
+ scsptr1_data &= ~SCL; /* SCL:L */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ ndelay(700);
+ scsptr1_data |= SCL; /* SCL:H */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ }
+
+ scsptr1_data &= ~SDA_OEN; /* SDA:output disable */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+}
+
+static unsigned char rs5c313_read_data(void)
+{
+ int i;
+ unsigned char data;
+
+ for (i = 0; i < 8; i++) {
+ ndelay(700);
+ /* SDA:Read Data */
+ data |= ((ctrl_inb(SCSPTR1) & SDA) >> 2) << (7 - i);
+ scsptr1_data &= ~SCL; /* SCL:L */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ ndelay(700);
+ scsptr1_data |= SCL; /* SCL:H */
+ ctrl_outb(scsptr1_data, SCSPTR1);
+ }
+ return data & 0x0F;
+}
+
+#endif /* CONFIG_SH_LANDISK */
+
+/*****************************************************/
+/* machine independence part of RS5C313 */
+/*****************************************************/
+
+/* RICOH RS5C313 address */
+#define RS5C313_ADDR_SEC 0x00
+#define RS5C313_ADDR_SEC10 0x01
+#define RS5C313_ADDR_MIN 0x02
+#define RS5C313_ADDR_MIN10 0x03
+#define RS5C313_ADDR_HOUR 0x04
+#define RS5C313_ADDR_HOUR10 0x05
+#define RS5C313_ADDR_WEEK 0x06
+#define RS5C313_ADDR_INTINTVREG 0x07
+#define RS5C313_ADDR_DAY 0x08
+#define RS5C313_ADDR_DAY10 0x09
+#define RS5C313_ADDR_MON 0x0A
+#define RS5C313_ADDR_MON10 0x0B
+#define RS5C313_ADDR_YEAR 0x0C
+#define RS5C313_ADDR_YEAR10 0x0D
+#define RS5C313_ADDR_CNTREG 0x0E
+#define RS5C313_ADDR_TESTREG 0x0F
+
+/* RICOH RS5C313 control register */
+#define RS5C313_CNTREG_ADJ_BSY 0x01
+#define RS5C313_CNTREG_WTEN_XSTP 0x02
+#define RS5C313_CNTREG_12_24 0x04
+#define RS5C313_CNTREG_CTFG 0x08
+
+/* RICOH RS5C313 test register */
+#define RS5C313_TESTREG_TEST 0x01
+
+/* RICOH RS5C313 control bit */
+#define RS5C313_CNTBIT_READ 0x40
+#define RS5C313_CNTBIT_AD 0x20
+#define RS5C313_CNTBIT_DT 0x10
+
+static unsigned char rs5c313_read_reg(unsigned char addr)
+{
+
+ rs5c313_write_data(addr | RS5C313_CNTBIT_READ | RS5C313_CNTBIT_AD);
+ return rs5c313_read_data();
+}
+
+static void rs5c313_write_reg(unsigned char addr, unsigned char data)
+{
+ data &= 0x0f;
+ rs5c313_write_data(addr | RS5C313_CNTBIT_AD);
+ rs5c313_write_data(data | RS5C313_CNTBIT_DT);
+ return;
+}
+
+static inline unsigned char rs5c313_read_cntreg(unsigned char addr)
+{
+ return rs5c313_read_reg(RS5C313_ADDR_CNTREG);
+}
+
+static inline void rs5c313_write_cntreg(unsigned char data)
+{
+ rs5c313_write_reg(RS5C313_ADDR_CNTREG, data);
+}
+
+static inline void rs5c313_write_intintvreg(unsigned char data)
+{
+ rs5c313_write_reg(RS5C313_ADDR_INTINTVREG, data);
+}
+
+static int rs5c313_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ int data;
+
+ while (1) {
+ RS5C313_CEENABLE; /* CE:H */
+
+ /* Initialize control reg. 24 hour */
+ rs5c313_write_cntreg(0x04);
+
+ if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY))
+ break;
+
+ RS5C313_CEDISABLE;
+ ndelay(700); /* CE:L */
+
+ }
+
+ data = rs5c313_read_reg(RS5C313_ADDR_SEC);
+ data |= (rs5c313_read_reg(RS5C313_ADDR_SEC10) << 4);
+ tm->tm_sec = BCD2BIN(data);
+
+ data = rs5c313_read_reg(RS5C313_ADDR_MIN);
+ data |= (rs5c313_read_reg(RS5C313_ADDR_MIN10) << 4);
+ tm->tm_min = BCD2BIN(data);
+
+ data = rs5c313_read_reg(RS5C313_ADDR_HOUR);
+ data |= (rs5c313_read_reg(RS5C313_ADDR_HOUR10) << 4);
+ tm->tm_hour = BCD2BIN(data);
+
+ data = rs5c313_read_reg(RS5C313_ADDR_DAY);
+ data |= (rs5c313_read_reg(RS5C313_ADDR_DAY10) << 4);
+ tm->tm_mday = BCD2BIN(data);
+
+ data = rs5c313_read_reg(RS5C313_ADDR_MON);
+ data |= (rs5c313_read_reg(RS5C313_ADDR_MON10) << 4);
+ tm->tm_mon = BCD2BIN(data) - 1;
+
+ data = rs5c313_read_reg(RS5C313_ADDR_YEAR);
+ data |= (rs5c313_read_reg(RS5C313_ADDR_YEAR10) << 4);
+ tm->tm_year = BCD2BIN(data);
+
+ if (tm->tm_year < 70)
+ tm->tm_year += 100;
+
+ data = rs5c313_read_reg(RS5C313_ADDR_WEEK);
+ tm->tm_wday = BCD2BIN(data);
+
+ RS5C313_CEDISABLE;
+ ndelay(700); /* CE:L */
+
+ return 0;
+}
+
+static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ int data;
+
+ /* busy check. */
+ while (1) {
+ RS5C313_CEENABLE; /* CE:H */
+
+ /* Initiatlize control reg. 24 hour */
+ rs5c313_write_cntreg(0x04);
+
+ if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY))
+ break;
+ RS5C313_MISCOP;
+ RS5C313_CEDISABLE;
+ ndelay(700); /* CE:L */
+ }
+
+ data = BIN2BCD(tm->tm_sec);
+ rs5c313_write_reg(RS5C313_ADDR_SEC, data);
+ rs5c313_write_reg(RS5C313_ADDR_SEC10, (data >> 4));
+
+ data = BIN2BCD(tm->tm_min);
+ rs5c313_write_reg(RS5C313_ADDR_MIN, data );
+ rs5c313_write_reg(RS5C313_ADDR_MIN10, (data >> 4));
+
+ data = BIN2BCD(tm->tm_hour);
+ rs5c313_write_reg(RS5C313_ADDR_HOUR, data);
+ rs5c313_write_reg(RS5C313_ADDR_HOUR10, (data >> 4));
+
+ data = BIN2BCD(tm->tm_mday);
+ rs5c313_write_reg(RS5C313_ADDR_DAY, data);
+ rs5c313_write_reg(RS5C313_ADDR_DAY10, (data>> 4));
+
+ data = BIN2BCD(tm->tm_mon + 1);
+ rs5c313_write_reg(RS5C313_ADDR_MON, data);
+ rs5c313_write_reg(RS5C313_ADDR_MON10, (data >> 4));
+
+ data = BIN2BCD(tm->tm_year % 100);
+ rs5c313_write_reg(RS5C313_ADDR_YEAR, data);
+ rs5c313_write_reg(RS5C313_ADDR_YEAR10, (data >> 4));
+
+ data = BIN2BCD(tm->tm_wday);
+ rs5c313_write_reg(RS5C313_ADDR_WEEK, data);
+
+ RS5C313_CEDISABLE; /* CE:H */
+ ndelay(700);
+
+ return 0;
+}
+
+static void rs5c313_check_xstp_bit(void)
+{
+ struct rtc_time tm;
+
+ RS5C313_CEENABLE; /* CE:H */
+ if (rs5c313_read_cntreg() & RS5C313_CNTREG_WTEN_XSTP) {
+ /* INT interval reg. OFF */
+ rs5c313_write_intintvreg(0x00);
+ /* Initialize control reg. 24 hour & adjust */
+ rs5c313_write_cntreg(0x07);
+
+ /* busy check. */
+ while (rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY)
+ RS5C313_MISCOP;
+
+ memset(&tm, 0, sizeof(struct rtc_time));
+ tm.tm_mday = 1;
+ tm.tm_mon = 1;
+
+ rs5c313_rtc_set_time(NULL, &tm);
+ printk(KERN_ERR "RICHO RS5C313: invalid value, resetting to "
+ "1 Jan 2000\n");
+ }
+ RS5C313_CEDISABLE;
+ ndelay(700); /* CE:L */
+}
+
+static const struct rtc_class_ops rs5c313_rtc_ops = {
+ .read_time = rs5c313_rtc_read_time,
+ .set_time = rs5c313_rtc_set_time,
+};
+
+static int rs5c313_rtc_probe(struct platform_device *pdev)
+{
+ struct rtc_device *rtc = rtc_device_register("rs5c313", &pdev->dev,
+ &rs5c313_rtc_ops, THIS_MODULE);
+
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
+
+ platform_set_drvdata(pdev, rtc);
+
+ return err;
+}
+
+static int __devexit rs5c313_rtc_remove(struct platform_device *pdev)
+{
+ struct rtc_device *rtc = platform_get_drvdata( pdev );
+
+ rtc_device_unregister(rtc);
+
+ return 0;
+}
+
+static struct platform_driver rs5c313_rtc_platform_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = rs5c313_rtc_probe,
+ .remove = __devexit_p( rs5c313_rtc_remove ),
+};
+
+static int __init rs5c313_rtc_init(void)
+{
+ int err;
+
+ err = platform_driver_register(&rs5c313_rtc_platform_driver);
+ if (err)
+ return err;
+
+ rs5c313_init_port();
+ rs5c313_check_xstp_bit();
+
+ return 0;
+}
+
+static void __exit rs5c313_rtc_exit(void)
+{
+ platform_driver_unregister( &rs5c313_rtc_platform_driver );
+}
+
+module_init(rs5c313_rtc_init);
+module_exit(rs5c313_rtc_exit);
+
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu <iwamatsu@nigauri.org>");
+MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index 9a79a24..54b6130 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -50,7 +50,7 @@ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
{
struct rtc_device *rdev = id;
- rtc_update_irq(&rdev->class_dev, 1, RTC_AF | RTC_IRQF);
+ rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF);
return IRQ_HANDLED;
}
@@ -58,7 +58,7 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id)
{
struct rtc_device *rdev = id;
- rtc_update_irq(&rdev->class_dev, tick_count++, RTC_PF | RTC_IRQF);
+ rtc_update_irq(rdev, tick_count++, RTC_PF | RTC_IRQF);
return IRQ_HANDLED;
}
@@ -548,37 +548,15 @@ static int ticnt_save;
static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct rtc_time tm;
- struct timespec time;
-
- time.tv_nsec = 0;
-
/* save TICNT for anyone using periodic interrupts */
-
ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT);
-
- /* calculate time delta for suspend */
-
- s3c_rtc_gettime(&pdev->dev, &tm);
- rtc_tm_to_time(&tm, &time.tv_sec);
- save_time_delta(&s3c_rtc_delta, &time);
s3c_rtc_enable(pdev, 0);
-
return 0;
}
static int s3c_rtc_resume(struct platform_device *pdev)
{
- struct rtc_time tm;
- struct timespec time;
-
- time.tv_nsec = 0;
-
s3c_rtc_enable(pdev, 1);
- s3c_rtc_gettime(&pdev->dev, &tm);
- rtc_tm_to_time(&tm, &time.tv_sec);
- restore_time_delta(&s3c_rtc_delta, &time);
-
writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT);
return 0;
}
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index 677bae8..0918b78 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -93,7 +93,7 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
if (rtsr & RTSR_HZ)
events |= RTC_UF | RTC_IRQF;
- rtc_update_irq(&rtc->class_dev, 1, events);
+ rtc_update_irq(rtc, 1, events);
if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm))
rtc_update_alarm(&rtc_alarm);
@@ -119,7 +119,7 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id)
*/
OSSR = OSSR_M1; /* clear match on timer1 */
- rtc_update_irq(&rtc->class_dev, rtc_timer1_count, RTC_PF | RTC_IRQF);
+ rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF);
if (rtc_timer1_count == 1)
rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2)));
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 198b9f2..6abf481 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -104,7 +104,7 @@ static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id)
writeb(tmp, rtc->regbase + RCR1);
- rtc_update_irq(&rtc->rtc_dev->class_dev, 1, events);
+ rtc_update_irq(&rtc->rtc_dev, 1, events);
spin_unlock(&rtc->lock);
@@ -139,7 +139,7 @@ static irqreturn_t sh_rtc_alarm(int irq, void *dev_id)
rtc->rearm_aie = 1;
- rtc_update_irq(&rtc->rtc_dev->class_dev, 1, events);
+ rtc_update_irq(&rtc->rtc_dev, 1, events);
}
spin_unlock(&rtc->lock);
@@ -153,7 +153,7 @@ static irqreturn_t sh_rtc_periodic(int irq, void *dev_id)
spin_lock(&rtc->lock);
- rtc_update_irq(&rtc->rtc_dev->class_dev, 1, RTC_PF | RTC_IRQF);
+ rtc_update_irq(&rtc->rtc_dev, 1, RTC_PF | RTC_IRQF);
spin_unlock(&rtc->lock);
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 899ab8c..69df94b 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -12,20 +12,26 @@
#include <linux/module.h>
#include <linux/rtc.h>
+#include "rtc-core.h"
+
+
/* device attributes */
-static ssize_t rtc_sysfs_show_name(struct class_device *dev, char *buf)
+static ssize_t
+rtc_sysfs_show_name(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
return sprintf(buf, "%s\n", to_rtc_device(dev)->name);
}
-static CLASS_DEVICE_ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL);
-static ssize_t rtc_sysfs_show_date(struct class_device *dev, char *buf)
+static ssize_t
+rtc_sysfs_show_date(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
ssize_t retval;
struct rtc_time tm;
- retval = rtc_read_time(dev, &tm);
+ retval = rtc_read_time(to_rtc_device(dev), &tm);
if (retval == 0) {
retval = sprintf(buf, "%04d-%02d-%02d\n",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
@@ -33,14 +39,15 @@ static ssize_t rtc_sysfs_show_date(struct class_device *dev, char *buf)
return retval;
}
-static CLASS_DEVICE_ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL);
-static ssize_t rtc_sysfs_show_time(struct class_device *dev, char *buf)
+static ssize_t
+rtc_sysfs_show_time(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
ssize_t retval;
struct rtc_time tm;
- retval = rtc_read_time(dev, &tm);
+ retval = rtc_read_time(to_rtc_device(dev), &tm);
if (retval == 0) {
retval = sprintf(buf, "%02d:%02d:%02d\n",
tm.tm_hour, tm.tm_min, tm.tm_sec);
@@ -48,14 +55,15 @@ static ssize_t rtc_sysfs_show_time(struct class_device *dev, char *buf)
return retval;
}
-static CLASS_DEVICE_ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL);
-static ssize_t rtc_sysfs_show_since_epoch(struct class_device *dev, char *buf)
+static ssize_t
+rtc_sysfs_show_since_epoch(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
ssize_t retval;
struct rtc_time tm;
- retval = rtc_read_time(dev, &tm);
+ retval = rtc_read_time(to_rtc_device(dev), &tm);
if (retval == 0) {
unsigned long time;
rtc_tm_to_time(&tm, &time);
@@ -64,23 +72,18 @@ static ssize_t rtc_sysfs_show_since_epoch(struct class_device *dev, char *buf)
return retval;
}
-static CLASS_DEVICE_ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL);
-
-static struct attribute *rtc_attrs[] = {
- &class_device_attr_name.attr,
- &class_device_attr_date.attr,
- &class_device_attr_time.attr,
- &class_device_attr_since_epoch.attr,
- NULL,
-};
-static struct attribute_group rtc_attr_group = {
- .attrs = rtc_attrs,
+static struct device_attribute rtc_attrs[] = {
+ __ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL),
+ __ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL),
+ __ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL),
+ __ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL),
+ { },
};
-
static ssize_t
-rtc_sysfs_show_wakealarm(struct class_device *dev, char *buf)
+rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
ssize_t retval;
unsigned long alarm;
@@ -94,7 +97,7 @@ rtc_sysfs_show_wakealarm(struct class_device *dev, char *buf)
* REVISIT maybe we should require RTC implementations to
* disable the RTC alarm after it triggers, for uniformity.
*/
- retval = rtc_read_alarm(dev, &alm);
+ retval = rtc_read_alarm(to_rtc_device(dev), &alm);
if (retval == 0 && alm.enabled) {
rtc_tm_to_time(&alm.time, &alarm);
retval = sprintf(buf, "%lu\n", alarm);
@@ -104,16 +107,18 @@ rtc_sysfs_show_wakealarm(struct class_device *dev, char *buf)
}
static ssize_t
-rtc_sysfs_set_wakealarm(struct class_device *dev, const char *buf, size_t n)
+rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t n)
{
ssize_t retval;
unsigned long now, alarm;
struct rtc_wkalrm alm;
+ struct rtc_device *rtc = to_rtc_device(dev);
/* Only request alarms that trigger in the future. Disable them
* by writing another time, e.g. 0 meaning Jan 1 1970 UTC.
*/
- retval = rtc_read_time(dev, &alm.time);
+ retval = rtc_read_time(rtc, &alm.time);
if (retval < 0)
return retval;
rtc_tm_to_time(&alm.time, &now);
@@ -124,7 +129,7 @@ rtc_sysfs_set_wakealarm(struct class_device *dev, const char *buf, size_t n)
* entirely prevent that here, without even the minimal
* locking from the /dev/rtcN api.
*/
- retval = rtc_read_alarm(dev, &alm);
+ retval = rtc_read_alarm(rtc, &alm);
if (retval < 0)
return retval;
if (alm.enabled)
@@ -141,10 +146,10 @@ rtc_sysfs_set_wakealarm(struct class_device *dev, const char *buf, size_t n)
}
rtc_time_to_tm(alarm, &alm.time);
- retval = rtc_set_alarm(dev, &alm);
+ retval = rtc_set_alarm(rtc, &alm);
return (retval < 0) ? retval : n;
}
-static const CLASS_DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR,
+static DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR,
rtc_sysfs_show_wakealarm, rtc_sysfs_set_wakealarm);
@@ -153,71 +158,37 @@ static const CLASS_DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR,
* suspend-to-disk. So: no attribute unless that side effect is possible.
* (Userspace may disable that mechanism later.)
*/
-static inline int rtc_does_wakealarm(struct class_device *class_dev)
+static inline int rtc_does_wakealarm(struct rtc_device *rtc)
{
- struct rtc_device *rtc;
-
- if (!device_can_wakeup(class_dev->dev))
+ if (!device_can_wakeup(rtc->dev.parent))
return 0;
- rtc = to_rtc_device(class_dev);
return rtc->ops->set_alarm != NULL;
}
-static int rtc_sysfs_add_device(struct class_device *class_dev,
- struct class_interface *class_intf)
+void rtc_sysfs_add_device(struct rtc_device *rtc)
{
int err;
- dev_dbg(class_dev->dev, "rtc intf: sysfs\n");
+ /* not all RTCs support both alarms and wakeup */
+ if (!rtc_does_wakealarm(rtc))
+ return;
- err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group);
+ err = device_create_file(&rtc->dev, &dev_attr_wakealarm);
if (err)
- dev_err(class_dev->dev, "failed to create %s\n",
- "sysfs attributes");
- else if (rtc_does_wakealarm(class_dev)) {
- /* not all RTCs support both alarms and wakeup */
- err = class_device_create_file(class_dev,
- &class_device_attr_wakealarm);
- if (err) {
- dev_err(class_dev->dev, "failed to create %s\n",
- "alarm attribute");
- sysfs_remove_group(&class_dev->kobj, &rtc_attr_group);
- }
- }
-
- return err;
+ dev_err(rtc->dev.parent, "failed to create "
+ "alarm attribute, %d",
+ err);
}
-static void rtc_sysfs_remove_device(struct class_device *class_dev,
- struct class_interface *class_intf)
+void rtc_sysfs_del_device(struct rtc_device *rtc)
{
- if (rtc_does_wakealarm(class_dev))
- class_device_remove_file(class_dev,
- &class_device_attr_wakealarm);
- sysfs_remove_group(&class_dev->kobj, &rtc_attr_group);
+ /* REVISIT did we add it successfully? */
+ if (rtc_does_wakealarm(rtc))
+ device_remove_file(&rtc->dev, &dev_attr_wakealarm);
}
-/* interface registration */
-
-static struct class_interface rtc_sysfs_interface = {
- .add = &rtc_sysfs_add_device,
- .remove = &rtc_sysfs_remove_device,
-};
-
-static int __init rtc_sysfs_init(void)
+void __init rtc_sysfs_init(struct class *rtc_class)
{
- return rtc_interface_register(&rtc_sysfs_interface);
+ rtc_class->dev_attrs = rtc_attrs;
}
-
-static void __exit rtc_sysfs_exit(void)
-{
- class_interface_unregister(&rtc_sysfs_interface);
-}
-
-subsys_initcall(rtc_sysfs_init);
-module_exit(rtc_sysfs_exit);
-
-MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
-MODULE_DESCRIPTION("RTC class sysfs interface");
-MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c
index f50a1b8..254c9fc 100644
--- a/drivers/rtc/rtc-test.c
+++ b/drivers/rtc/rtc-test.c
@@ -101,11 +101,11 @@ static ssize_t test_irq_store(struct device *dev,
retval = count;
local_irq_disable();
if (strncmp(buf, "tick", 4) == 0)
- rtc_update_irq(&rtc->class_dev, 1, RTC_PF | RTC_IRQF);
+ rtc_update_irq(rtc, 1, RTC_PF | RTC_IRQF);
else if (strncmp(buf, "alarm", 5) == 0)
- rtc_update_irq(&rtc->class_dev, 1, RTC_AF | RTC_IRQF);
+ rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF);
else if (strncmp(buf, "update", 6) == 0)
- rtc_update_irq(&rtc->class_dev, 1, RTC_UF | RTC_IRQF);
+ rtc_update_irq(rtc, 1, RTC_UF | RTC_IRQF);
else
retval = -EINVAL;
local_irq_enable();
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index e40322b..af7596e 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -97,6 +97,7 @@ static DEFINE_SPINLOCK(rtc_lock);
static char rtc_name[] = "RTC";
static unsigned long periodic_frequency;
static unsigned long periodic_count;
+static unsigned int alarm_enabled;
struct resource rtc_resource[2] = {
{ .name = rtc_name,
@@ -188,6 +189,7 @@ static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
low = rtc1_read(ECMPLREG);
mid = rtc1_read(ECMPMREG);
high = rtc1_read(ECMPHREG);
+ wkalrm->enabled = alarm_enabled;
spin_unlock_irq(&rtc_lock);
@@ -206,10 +208,18 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
spin_lock_irq(&rtc_lock);
+ if (alarm_enabled)
+ disable_irq(ELAPSEDTIME_IRQ);
+
rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15));
rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1));
rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17));
+ if (wkalrm->enabled)
+ enable_irq(ELAPSEDTIME_IRQ);
+
+ alarm_enabled = wkalrm->enabled;
+
spin_unlock_irq(&rtc_lock);
return 0;
@@ -221,10 +231,24 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
switch (cmd) {
case RTC_AIE_ON:
- enable_irq(ELAPSEDTIME_IRQ);
+ spin_lock_irq(&rtc_lock);
+
+ if (!alarm_enabled) {
+ enable_irq(ELAPSEDTIME_IRQ);
+ alarm_enabled = 1;
+ }
+
+ spin_unlock_irq(&rtc_lock);
break;
case RTC_AIE_OFF:
- disable_irq(ELAPSEDTIME_IRQ);
+ spin_lock_irq(&rtc_lock);
+
+ if (alarm_enabled) {
+ disable_irq(ELAPSEDTIME_IRQ);
+ alarm_enabled = 0;
+ }
+
+ spin_unlock_irq(&rtc_lock);
break;
case RTC_PIE_ON:
enable_irq(RTCLONG1_IRQ);
@@ -275,7 +299,7 @@ static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id)
rtc2_write(RTCINTREG, ELAPSEDTIME_INT);
- rtc_update_irq(&rtc->class_dev, 1, RTC_AF);
+ rtc_update_irq(rtc, 1, RTC_AF);
return IRQ_HANDLED;
}
@@ -291,7 +315,7 @@ static irqreturn_t rtclong1_interrupt(int irq, void *dev_id)
rtc1_write(RTCL1LREG, count);
rtc1_write(RTCL1HREG, count >> 16);
- rtc_update_irq(&rtc->class_dev, 1, RTC_PF);
+ rtc_update_irq(rtc, 1, RTC_PF);
return IRQ_HANDLED;
}
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index cba64e4..f770018 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -996,18 +996,25 @@ __qdio_outbound_processing(struct qdio_q *q)
if (qdio_has_outbound_q_moved(q))
qdio_kick_outbound_handler(q);
- if (q->is_iqdio_q) {
+ if (q->queue_type == QDIO_ZFCP_QFMT) {
+ if ((!q->hydra_gives_outbound_pcis) &&
+ (!qdio_is_outbound_q_done(q)))
+ qdio_mark_q(q);
+ }
+ else if (((!q->is_iqdio_q) && (!q->is_pci_out)) ||
+ (q->queue_type == QDIO_IQDIO_QFMT_ASYNCH)) {
/*
- * for asynchronous queues, we better check, if the sent
- * buffer is already switched from PRIMED to EMPTY.
+ * make sure buffer switch from PRIMED to EMPTY is noticed
+ * and outbound_handler is called
*/
- if ((q->queue_type == QDIO_IQDIO_QFMT_ASYNCH) &&
- !qdio_is_outbound_q_done(q))
- qdio_mark_q(q);
-
- } else if (!q->hydra_gives_outbound_pcis)
- if (!qdio_is_outbound_q_done(q))
- qdio_mark_q(q);
+ if (qdio_is_outbound_q_done(q)) {
+ del_timer(&q->timer);
+ } else {
+ if (!timer_pending(&q->timer))
+ mod_timer(&q->timer, jiffies +
+ QDIO_FORCE_CHECK_TIMEOUT);
+ }
+ }
qdio_release_q(q);
}
@@ -1826,6 +1833,7 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
q->queue_type = QDIO_IQDIO_QFMT_ASYNCH;
q->int_parm=int_parm;
q->is_input_q=0;
+ q->is_pci_out = 0;
q->schid = irq_ptr->schid;
q->cdev = cdev;
q->irq_ptr = irq_ptr;
@@ -1838,6 +1846,10 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
q->tasklet.data=(unsigned long)q;
q->tasklet.func=(void(*)(unsigned long))
&qdio_outbound_processing;
+ q->timer.function=(void(*)(unsigned long))
+ &qdio_outbound_processing;
+ q->timer.data = (long)q;
+ init_timer(&q->timer);
atomic_set(&q->busy_siga_counter,0);
q->timing.busy_start=0;
@@ -2635,6 +2647,7 @@ qdio_shutdown(struct ccw_device *cdev, int how)
for (i=0;i<irq_ptr->no_output_qs;i++) {
tasklet_kill(&irq_ptr->output_qs[i]->tasklet);
+ del_timer(&irq_ptr->output_qs[i]->timer);
wait_event_interruptible_timeout(cdev->private->wait_q,
!atomic_read(&irq_ptr->
output_qs[i]->
@@ -3458,6 +3471,10 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags,
qdio_perf_stat_inc(&perf_stats.outbound_cnt);
return;
}
+ if (callflags & QDIO_FLAG_PCI_OUT)
+ q->is_pci_out = 1;
+ else
+ q->is_pci_out = 0;
if (q->is_iqdio_q) {
/* one siga for every sbal */
while (count--)
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 2895392..6d7aad1 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -60,6 +60,7 @@
#define QDIO_ACTIVATE_TIMEOUT ((5*HZ)>>10)
#define QDIO_CLEANUP_CLEAR_TIMEOUT (20*HZ)
#define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ)
+#define QDIO_FORCE_CHECK_TIMEOUT (10*HZ)
enum qdio_irq_states {
QDIO_IRQ_STATE_INACTIVE,
@@ -511,8 +512,8 @@ struct qdio_q {
void *irq_ptr;
-#ifdef QDIO_USE_TIMERS_FOR_POLLING
struct timer_list timer;
+#ifdef QDIO_USE_TIMERS_FOR_POLLING
atomic_t timer_already_set;
spinlock_t timer_lock;
#else /* QDIO_USE_TIMERS_FOR_POLLING */
@@ -558,6 +559,7 @@ struct qdio_q {
} timing;
atomic_t busy_siga_counter;
unsigned int queue_type;
+ unsigned int is_pci_out;
/* leave this member at the end. won't be cleared in qdio_fill_qs */
struct slib *slib; /* a page is allocated under this pointer,
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index e10e85e..c358764 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1862,12 +1862,14 @@ static void netiucv_remove_connection(struct iucv_connection *conn)
write_lock_bh(&iucv_connection_rwlock);
list_del_init(&conn->list);
write_unlock_bh(&iucv_connection_rwlock);
+ fsm_deltimer(&conn->timer);
+ netiucv_purge_skb_queue(&conn->collect_queue);
if (conn->path) {
iucv_path_sever(conn->path, iucvMagic);
kfree(conn->path);
conn->path = NULL;
}
- fsm_deltimer(&conn->timer);
+ netiucv_purge_skb_queue(&conn->commit_queue);
kfree_fsm(conn->fsm);
kfree_skb(conn->rx_buff);
kfree_skb(conn->tx_buff);
@@ -2115,7 +2117,6 @@ static void __exit netiucv_exit(void)
while (!list_empty(&iucv_connection_list)) {
cp = list_entry(iucv_connection_list.next,
struct iucv_connection, list);
- list_del(&cp->list);
ndev = cp->netdev;
priv = netdev_priv(ndev);
dev = priv->dev;
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index dd7034f..4640f32 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -620,10 +620,10 @@ qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb,
struct qeth_eddp_context *
qeth_eddp_create_context(struct qeth_card *card, struct sk_buff *skb,
- struct qeth_hdr *qhdr)
+ struct qeth_hdr *qhdr, unsigned char sk_protocol)
{
QETH_DBF_TEXT(trace, 5, "creddpc");
- switch (skb->sk->sk_protocol){
+ switch (sk_protocol) {
case IPPROTO_TCP:
return qeth_eddp_create_context_tcp(card, skb, qhdr);
default:
diff --git a/drivers/s390/net/qeth_eddp.h b/drivers/s390/net/qeth_eddp.h
index 103768d..52910c9 100644
--- a/drivers/s390/net/qeth_eddp.h
+++ b/drivers/s390/net/qeth_eddp.h
@@ -34,7 +34,8 @@ struct qeth_eddp_context_reference {
};
extern struct qeth_eddp_context *
-qeth_eddp_create_context(struct qeth_card *,struct sk_buff *,struct qeth_hdr *);
+qeth_eddp_create_context(struct qeth_card *,struct sk_buff *,
+ struct qeth_hdr *, unsigned char);
extern void
qeth_eddp_put_context(struct qeth_eddp_context *);
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 6fd8870..29d1760 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1682,6 +1682,21 @@ qeth_put_reply(struct qeth_reply *reply)
kfree(reply);
}
+static void
+qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, struct qeth_card *card)
+{
+ int rc;
+ int com;
+ char * ipa_name;
+
+ com = cmd->hdr.command;
+ rc = cmd->hdr.return_code;
+ ipa_name = qeth_get_ipa_cmd_name(com);
+
+ PRINT_ERR("%s(x%X) for %s returned x%X \"%s\"\n", ipa_name, com,
+ QETH_CARD_IFNAME(card), rc, qeth_get_ipa_msg(rc));
+}
+
static struct qeth_ipa_cmd *
qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
{
@@ -1690,8 +1705,11 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
QETH_DBF_TEXT(trace,5,"chkipad");
if (IS_IPA(iob->data)){
cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
- if (IS_IPA_REPLY(cmd))
+ if (IS_IPA_REPLY(cmd)) {
+ if (cmd->hdr.return_code)
+ qeth_issue_ipa_msg(cmd, card);
return cmd;
+ }
else {
switch (cmd->hdr.command) {
case IPA_CMD_STOPLAN:
@@ -2816,6 +2834,7 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
struct qeth_qdio_out_buffer *buf;
int rc;
int i;
+ unsigned int qdio_flags;
QETH_DBF_TEXT(trace, 6, "flushbuf");
@@ -2859,13 +2878,13 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
queue->card->perf_stats.outbound_do_qdio_start_time =
qeth_get_micros();
}
+ qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
if (under_int)
- rc = do_QDIO(CARD_DDEV(queue->card),
- QDIO_FLAG_SYNC_OUTPUT | QDIO_FLAG_UNDER_INTERRUPT,
- queue->queue_no, index, count, NULL);
- else
- rc = do_QDIO(CARD_DDEV(queue->card), QDIO_FLAG_SYNC_OUTPUT,
- queue->queue_no, index, count, NULL);
+ qdio_flags |= QDIO_FLAG_UNDER_INTERRUPT;
+ if (atomic_read(&queue->set_pci_flags_count))
+ qdio_flags |= QDIO_FLAG_PCI_OUT;
+ rc = do_QDIO(CARD_DDEV(queue->card), qdio_flags,
+ queue->queue_no, index, count, NULL);
if (queue->card->options.performance_stats)
queue->card->perf_stats.outbound_do_qdio_time +=
qeth_get_micros() -
@@ -4490,7 +4509,8 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
qeth_fill_header(card, hdr, new_skb, ipv, cast_type);
}
if (large_send == QETH_LARGE_SEND_EDDP) {
- ctx = qeth_eddp_create_context(card, new_skb, hdr);
+ ctx = qeth_eddp_create_context(card, new_skb, hdr,
+ skb->sk->sk_protocol);
if (ctx == NULL) {
__qeth_free_new_skb(skb, new_skb);
PRINT_WARN("could not create eddp context\n");
@@ -5948,9 +5968,6 @@ qeth_layer2_send_setmac_cb(struct qeth_card *card,
cmd = (struct qeth_ipa_cmd *) data;
if (cmd->hdr.return_code) {
QETH_DBF_TEXT_(trace, 2, "L2er%x", cmd->hdr.return_code);
- PRINT_WARN("Error in registering MAC address on " \
- "device %s: x%x\n", CARD_BUS_ID(card),
- cmd->hdr.return_code);
card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
cmd->hdr.return_code = -EIO;
} else {
@@ -5985,9 +6002,6 @@ qeth_layer2_send_delmac_cb(struct qeth_card *card,
QETH_DBF_TEXT(trace, 2, "L2Dmaccb");
cmd = (struct qeth_ipa_cmd *) data;
if (cmd->hdr.return_code) {
- PRINT_WARN("Error in deregistering MAC address on " \
- "device %s: x%x\n", CARD_BUS_ID(card),
- cmd->hdr.return_code);
QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code);
cmd->hdr.return_code = -EIO;
return 0;
@@ -6651,7 +6665,7 @@ qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
QETH_DBF_TEXT(trace,4,"chgmaccb");
cmd = (struct qeth_ipa_cmd *) data;
- if (!card->options.layer2 || card->info.guestlan ||
+ if (!card->options.layer2 ||
!(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
memcpy(card->dev->dev_addr,
&cmd->data.setadapterparms.data.change_addr.addr,
@@ -8497,6 +8511,7 @@ __qeth_reboot_event_card(struct device *dev, void *data)
card = (struct qeth_card *) dev->driver_data;
qeth_clear_ip_list(card, 0, 0);
qeth_qdio_clear_card(card, 0);
+ qeth_clear_qdio_buffers(card);
return 0;
}
diff --git a/drivers/s390/net/qeth_mpc.c b/drivers/s390/net/qeth_mpc.c
index 77c8320..f54fdfd 100644
--- a/drivers/s390/net/qeth_mpc.c
+++ b/drivers/s390/net/qeth_mpc.c
@@ -157,12 +157,113 @@ unsigned char READ_CCW[]={
};
+struct ipa_rc_msg {
+ enum qeth_ipa_return_codes rc;
+ char *msg;
+};
+struct ipa_rc_msg qeth_ipa_rc_msg[] = {
+ {IPA_RC_SUCCESS, "success"},
+ {IPA_RC_NOTSUPP, "Command not supported"},
+ {IPA_RC_IP_TABLE_FULL, "Add Addr IP Table Full - ipv6"},
+ {IPA_RC_UNKNOWN_ERROR, "IPA command failed - reason unknown"},
+ {IPA_RC_UNSUPPORTED_COMMAND, "Command not supported"},
+ {IPA_RC_DUP_IPV6_REMOTE,"ipv6 address already registered remote"},
+ {IPA_RC_DUP_IPV6_HOME, "ipv6 address already registered"},
+ {IPA_RC_UNREGISTERED_ADDR, "Address not registered"},
+ {IPA_RC_NO_ID_AVAILABLE, "No identifiers available"},
+ {IPA_RC_ID_NOT_FOUND, "Identifier not found"},
+ {IPA_RC_INVALID_IP_VERSION, "IP version incorrect"},
+ {IPA_RC_LAN_FRAME_MISMATCH, "LAN and frame mismatch"},
+ {IPA_RC_L2_UNSUPPORTED_CMD, "Unsupported layer 2 command"},
+ {IPA_RC_L2_DUP_MAC, "Duplicate MAC address"},
+ {IPA_RC_L2_ADDR_TABLE_FULL, "Layer2 address table full"},
+ {IPA_RC_L2_DUP_LAYER3_MAC, "Duplicate with layer 3 MAC"},
+ {IPA_RC_L2_GMAC_NOT_FOUND, "GMAC not found"},
+ {IPA_RC_L2_MAC_NOT_FOUND, "L2 mac address not found"},
+ {IPA_RC_L2_INVALID_VLAN_ID, "L2 invalid vlan id"},
+ {IPA_RC_L2_DUP_VLAN_ID, "L2 duplicate vlan id"},
+ {IPA_RC_L2_VLAN_ID_NOT_FOUND, "L2 vlan id not found"},
+ {IPA_RC_DATA_MISMATCH, "Data field mismatch (v4/v6 mixed)"},
+ {IPA_RC_INVALID_MTU_SIZE, "Invalid MTU size"},
+ {IPA_RC_INVALID_LANTYPE, "Invalid LAN type"},
+ {IPA_RC_INVALID_LANNUM, "Invalid LAN num"},
+ {IPA_RC_DUPLICATE_IP_ADDRESS, "Address already registered"},
+ {IPA_RC_IP_ADDR_TABLE_FULL, "IP address table full"},
+ {IPA_RC_LAN_PORT_STATE_ERROR, "LAN port state error"},
+ {IPA_RC_SETIP_NO_STARTLAN, "Setip no startlan received"},
+ {IPA_RC_SETIP_ALREADY_RECEIVED, "Setip already received"},
+ {IPA_RC_IP_ADDR_ALREADY_USED, "IP address already in use on LAN"},
+ {IPA_RC_MULTICAST_FULL, "No task available, multicast full"},
+ {IPA_RC_SETIP_INVALID_VERSION, "SETIP invalid IP version"},
+ {IPA_RC_UNSUPPORTED_SUBCMD, "Unsupported assist subcommand"},
+ {IPA_RC_ARP_ASSIST_NO_ENABLE, "Only partial success, no enable"},
+ {IPA_RC_PRIMARY_ALREADY_DEFINED,"Primary already defined"},
+ {IPA_RC_SECOND_ALREADY_DEFINED, "Secondary already defined"},
+ {IPA_RC_INVALID_SETRTG_INDICATOR,"Invalid SETRTG indicator"},
+ {IPA_RC_MC_ADDR_ALREADY_DEFINED,"Multicast address already defined"},
+ {IPA_RC_LAN_OFFLINE, "STRTLAN_LAN_DISABLED - LAN offline"},
+ {IPA_RC_INVALID_IP_VERSION2, "Invalid IP version"},
+ {IPA_RC_FFFF, "Unknown Error"}
+};
+char *
+qeth_get_ipa_msg(enum qeth_ipa_return_codes rc)
+{
+ int x = 0;
+ qeth_ipa_rc_msg[sizeof(qeth_ipa_rc_msg) /
+ sizeof(struct ipa_rc_msg) - 1].rc = rc;
+ while(qeth_ipa_rc_msg[x].rc != rc)
+ x++;
+ return qeth_ipa_rc_msg[x].msg;
+}
+struct ipa_cmd_names {
+ enum qeth_ipa_cmds cmd;
+ char *name;
+};
+
+struct ipa_cmd_names qeth_ipa_cmd_names[] = {
+ {IPA_CMD_STARTLAN, "startlan"},
+ {IPA_CMD_STOPLAN, "stoplan"},
+ {IPA_CMD_SETVMAC, "setvmac"},
+ {IPA_CMD_DELVMAC, "delvmca"},
+ {IPA_CMD_SETGMAC, "setgmac"},
+ {IPA_CMD_DELGMAC, "delgmac"},
+ {IPA_CMD_SETVLAN, "setvlan"},
+ {IPA_CMD_DELVLAN, "delvlan"},
+ {IPA_CMD_SETCCID, "setccid"},
+ {IPA_CMD_DELCCID, "delccid"},
+ {IPA_CMD_MODCCID, "setip"},
+ {IPA_CMD_SETIP, "setip"},
+ {IPA_CMD_QIPASSIST, "qipassist"},
+ {IPA_CMD_SETASSPARMS, "setassparms"},
+ {IPA_CMD_SETIPM, "setipm"},
+ {IPA_CMD_DELIPM, "delipm"},
+ {IPA_CMD_SETRTG, "setrtg"},
+ {IPA_CMD_DELIP, "delip"},
+ {IPA_CMD_SETADAPTERPARMS, "setadapterparms"},
+ {IPA_CMD_SET_DIAG_ASS, "set_diag_ass"},
+ {IPA_CMD_CREATE_ADDR, "create_addr"},
+ {IPA_CMD_DESTROY_ADDR, "destroy_addr"},
+ {IPA_CMD_REGISTER_LOCAL_ADDR, "register_local_addr"},
+ {IPA_CMD_UNREGISTER_LOCAL_ADDR, "unregister_local_addr"},
+ {IPA_CMD_UNKNOWN, "unknown"},
+};
+char *
+qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd)
+{
+ int x = 0;
+ qeth_ipa_cmd_names[
+ sizeof(qeth_ipa_cmd_names)/
+ sizeof(struct ipa_cmd_names)-1].cmd = cmd;
+ while(qeth_ipa_cmd_names[x].cmd != cmd)
+ x++;
+ return qeth_ipa_cmd_names[x].name;
+}
diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h
index d74bc43..1d8083c 100644
--- a/drivers/s390/net/qeth_mpc.h
+++ b/drivers/s390/net/qeth_mpc.h
@@ -25,14 +25,14 @@ extern unsigned char IPA_PDU_HEADER[];
#define IPA_CMD_LENGTH (IPA_PDU_HEADER_SIZE + sizeof(struct qeth_ipa_cmd))
-#define QETH_SEQ_NO_LENGTH 4
-#define QETH_MPC_TOKEN_LENGTH 4
+#define QETH_SEQ_NO_LENGTH 4
+#define QETH_MPC_TOKEN_LENGTH 4
#define QETH_MCL_LENGTH 4
#define OSA_ADDR_LEN 6
-#define QETH_TIMEOUT (10 * HZ)
-#define QETH_IPA_TIMEOUT (45 * HZ)
-#define QETH_IDX_COMMAND_SEQNO 0xffff0000
+#define QETH_TIMEOUT (10 * HZ)
+#define QETH_IPA_TIMEOUT (45 * HZ)
+#define QETH_IDX_COMMAND_SEQNO 0xffff0000
#define SR_INFO_LEN 16
#define QETH_CLEAR_CHANNEL_PARM -10
@@ -93,79 +93,107 @@ enum qeth_checksum_types {
*/
#define RESET_ROUTING_FLAG 0x10 /* indicate that routing type shall be set */
enum qeth_routing_types {
- NO_ROUTER = 0, /* TODO: set to bit flag used in IPA Command */
- PRIMARY_ROUTER = 1,
- SECONDARY_ROUTER = 2,
- MULTICAST_ROUTER = 3,
- PRIMARY_CONNECTOR = 4,
- SECONDARY_CONNECTOR = 5,
+ NO_ROUTER = 0, /* TODO: set to bit flag used in IPA Command */
+ PRIMARY_ROUTER = 1,
+ SECONDARY_ROUTER = 2,
+ MULTICAST_ROUTER = 3,
+ PRIMARY_CONNECTOR = 4,
+ SECONDARY_CONNECTOR = 5,
};
-
/* IPA Commands */
enum qeth_ipa_cmds {
- IPA_CMD_STARTLAN = 0x01,
- IPA_CMD_STOPLAN = 0x02,
- IPA_CMD_SETVMAC = 0x21,
- IPA_CMD_DELVMAC = 0x22,
- IPA_CMD_SETGMAC = 0x23,
- IPA_CMD_DELGMAC = 0x24,
- IPA_CMD_SETVLAN = 0x25,
- IPA_CMD_DELVLAN = 0x26,
- IPA_CMD_SETCCID = 0x41,
- IPA_CMD_DELCCID = 0x42,
- IPA_CMD_MODCCID = 0x43,
- IPA_CMD_SETIP = 0xb1,
- IPA_CMD_DELIP = 0xb7,
- IPA_CMD_QIPASSIST = 0xb2,
- IPA_CMD_SETASSPARMS = 0xb3,
- IPA_CMD_SETIPM = 0xb4,
- IPA_CMD_DELIPM = 0xb5,
- IPA_CMD_SETRTG = 0xb6,
- IPA_CMD_SETADAPTERPARMS = 0xb8,
- IPA_CMD_IPFRAME = 0xb9,
- IPA_CMD_ADD_ADDR_ENTRY = 0xc1,
- IPA_CMD_DELETE_ADDR_ENTRY = 0xc2,
- IPA_CMD_CREATE_ADDR = 0xc3,
- IPA_CMD_DESTROY_ADDR = 0xc4,
- IPA_CMD_REGISTER_LOCAL_ADDR = 0xd1,
- IPA_CMD_UNREGISTER_LOCAL_ADDR = 0xd2,
+ IPA_CMD_STARTLAN = 0x01,
+ IPA_CMD_STOPLAN = 0x02,
+ IPA_CMD_SETVMAC = 0x21,
+ IPA_CMD_DELVMAC = 0x22,
+ IPA_CMD_SETGMAC = 0x23,
+ IPA_CMD_DELGMAC = 0x24,
+ IPA_CMD_SETVLAN = 0x25,
+ IPA_CMD_DELVLAN = 0x26,
+ IPA_CMD_SETCCID = 0x41,
+ IPA_CMD_DELCCID = 0x42,
+ IPA_CMD_MODCCID = 0x43,
+ IPA_CMD_SETIP = 0xb1,
+ IPA_CMD_QIPASSIST = 0xb2,
+ IPA_CMD_SETASSPARMS = 0xb3,
+ IPA_CMD_SETIPM = 0xb4,
+ IPA_CMD_DELIPM = 0xb5,
+ IPA_CMD_SETRTG = 0xb6,
+ IPA_CMD_DELIP = 0xb7,
+ IPA_CMD_SETADAPTERPARMS = 0xb8,
+ IPA_CMD_SET_DIAG_ASS = 0xb9,
+ IPA_CMD_CREATE_ADDR = 0xc3,
+ IPA_CMD_DESTROY_ADDR = 0xc4,
+ IPA_CMD_REGISTER_LOCAL_ADDR = 0xd1,
+ IPA_CMD_UNREGISTER_LOCAL_ADDR = 0xd2,
+ IPA_CMD_UNKNOWN = 0x00
};
enum qeth_ip_ass_cmds {
IPA_CMD_ASS_START = 0x0001,
IPA_CMD_ASS_STOP = 0x0002,
- IPA_CMD_ASS_CONFIGURE = 0x0003,
- IPA_CMD_ASS_ENABLE = 0x0004,
+ IPA_CMD_ASS_CONFIGURE = 0x0003,
+ IPA_CMD_ASS_ENABLE = 0x0004,
};
enum qeth_arp_process_subcmds {
- IPA_CMD_ASS_ARP_SET_NO_ENTRIES = 0x0003,
- IPA_CMD_ASS_ARP_QUERY_CACHE = 0x0004,
- IPA_CMD_ASS_ARP_ADD_ENTRY = 0x0005,
- IPA_CMD_ASS_ARP_REMOVE_ENTRY = 0x0006,
- IPA_CMD_ASS_ARP_FLUSH_CACHE = 0x0007,
- IPA_CMD_ASS_ARP_QUERY_INFO = 0x0104,
- IPA_CMD_ASS_ARP_QUERY_STATS = 0x0204,
+ IPA_CMD_ASS_ARP_SET_NO_ENTRIES = 0x0003,
+ IPA_CMD_ASS_ARP_QUERY_CACHE = 0x0004,
+ IPA_CMD_ASS_ARP_ADD_ENTRY = 0x0005,
+ IPA_CMD_ASS_ARP_REMOVE_ENTRY = 0x0006,
+ IPA_CMD_ASS_ARP_FLUSH_CACHE = 0x0007,
+ IPA_CMD_ASS_ARP_QUERY_INFO = 0x0104,
+ IPA_CMD_ASS_ARP_QUERY_STATS = 0x0204,
};
-/* Return Codes for IPA Commands */
+
+/* Return Codes for IPA Commands
+ * according to OSA card Specs */
+
enum qeth_ipa_return_codes {
- IPA_RC_SUCCESS = 0x0000,
- IPA_RC_NOTSUPP = 0x0001,
- IPA_RC_NO_ACCESS = 0x0002,
- IPA_RC_FAILED = 0x0003,
- IPA_RC_DATA_MISMATCH = 0xe001,
- IPA_RC_INVALID_LAN_TYPE = 0xe003,
- IPA_RC_INVALID_LAN_NO = 0xe004,
- IPA_RC_IPADDR_ALREADY_REG = 0xe005,
- IPA_RC_IPADDR_TABLE_FULL = 0xe006,
- IPA_RC_IPADDR_ALREADY_USED = 0xe00a,
- IPA_RC_ASSNO_NOT_SUPP = 0xe00d,
- IPA_RC_ASSCMD_START_FAILED = 0xe00e,
- IPA_RC_ASSCMD_PART_SUCCESS = 0xe00f,
- IPA_RC_IPADDR_NOT_DEFINED = 0xe010,
- IPA_RC_LAN_OFFLINE = 0xe080,
+ IPA_RC_SUCCESS = 0x0000,
+ IPA_RC_NOTSUPP = 0x0001,
+ IPA_RC_IP_TABLE_FULL = 0x0002,
+ IPA_RC_UNKNOWN_ERROR = 0x0003,
+ IPA_RC_UNSUPPORTED_COMMAND = 0x0004,
+ IPA_RC_DUP_IPV6_REMOTE = 0x0008,
+ IPA_RC_DUP_IPV6_HOME = 0x0010,
+ IPA_RC_UNREGISTERED_ADDR = 0x0011,
+ IPA_RC_NO_ID_AVAILABLE = 0x0012,
+ IPA_RC_ID_NOT_FOUND = 0x0013,
+ IPA_RC_INVALID_IP_VERSION = 0x0020,
+ IPA_RC_LAN_FRAME_MISMATCH = 0x0040,
+ IPA_RC_L2_UNSUPPORTED_CMD = 0x2003,
+ IPA_RC_L2_DUP_MAC = 0x2005,
+ IPA_RC_L2_ADDR_TABLE_FULL = 0x2006,
+ IPA_RC_L2_DUP_LAYER3_MAC = 0x200a,
+ IPA_RC_L2_GMAC_NOT_FOUND = 0x200b,
+ IPA_RC_L2_MAC_NOT_FOUND = 0x2010,
+ IPA_RC_L2_INVALID_VLAN_ID = 0x2015,
+ IPA_RC_L2_DUP_VLAN_ID = 0x2016,
+ IPA_RC_L2_VLAN_ID_NOT_FOUND = 0x2017,
+ IPA_RC_DATA_MISMATCH = 0xe001,
+ IPA_RC_INVALID_MTU_SIZE = 0xe002,
+ IPA_RC_INVALID_LANTYPE = 0xe003,
+ IPA_RC_INVALID_LANNUM = 0xe004,
+ IPA_RC_DUPLICATE_IP_ADDRESS = 0xe005,
+ IPA_RC_IP_ADDR_TABLE_FULL = 0xe006,
+ IPA_RC_LAN_PORT_STATE_ERROR = 0xe007,
+ IPA_RC_SETIP_NO_STARTLAN = 0xe008,
+ IPA_RC_SETIP_ALREADY_RECEIVED = 0xe009,
+ IPA_RC_IP_ADDR_ALREADY_USED = 0xe00a,
+ IPA_RC_MULTICAST_FULL = 0xe00b,
+ IPA_RC_SETIP_INVALID_VERSION = 0xe00d,
+ IPA_RC_UNSUPPORTED_SUBCMD = 0xe00e,
+ IPA_RC_ARP_ASSIST_NO_ENABLE = 0xe00f,
+ IPA_RC_PRIMARY_ALREADY_DEFINED = 0xe010,
+ IPA_RC_SECOND_ALREADY_DEFINED = 0xe011,
+ IPA_RC_INVALID_SETRTG_INDICATOR = 0xe012,
+ IPA_RC_MC_ADDR_ALREADY_DEFINED = 0xe013,
+ IPA_RC_LAN_OFFLINE = 0xe080,
+ IPA_RC_INVALID_IP_VERSION2 = 0xf001,
+ IPA_RC_FFFF = 0xffff
};
/* IPA function flags; each flag marks availability of respective function */
@@ -183,7 +211,9 @@ enum qeth_ipa_funcs {
IPA_SETADAPTERPARMS = 0x00000400L,
IPA_VLAN_PRIO = 0x00000800L,
IPA_PASSTHRU = 0x00001000L,
+ IPA_FLUSH_ARP_SUPPORT = 0x00002000L,
IPA_FULL_VLAN = 0x00004000L,
+ IPA_INBOUND_PASSTHRU = 0x00008000L,
IPA_SOURCE_MAC = 0x00010000L,
IPA_OSA_MC_ROUTER = 0x00020000L,
IPA_QUERY_ARP_ASSIST = 0x00040000L,
@@ -204,31 +234,30 @@ enum qeth_ipa_setdelip_flags {
/* SETADAPTER IPA Command: ****************************************************/
enum qeth_ipa_setadp_cmd {
IPA_SETADP_QUERY_COMMANDS_SUPPORTED = 0x01,
- IPA_SETADP_ALTER_MAC_ADDRESS = 0x02,
- IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x04,
- IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x08,
- IPA_SETADP_SET_ADDRESSING_MODE = 0x10,
- IPA_SETADP_SET_CONFIG_PARMS = 0x20,
- IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x40,
- IPA_SETADP_SET_BROADCAST_MODE = 0x80,
- IPA_SETADP_SEND_OSA_MESSAGE = 0x0100,
- IPA_SETADP_SET_SNMP_CONTROL = 0x0200,
- IPA_SETADP_READ_SNMP_PARMS = 0x0400,
+ IPA_SETADP_ALTER_MAC_ADDRESS = 0x02,
+ IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x04,
+ IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x08,
+ IPA_SETADP_SET_ADDRESSING_MODE = 0x10,
+ IPA_SETADP_SET_CONFIG_PARMS = 0x20,
+ IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x40,
+ IPA_SETADP_SET_BROADCAST_MODE = 0x80,
+ IPA_SETADP_SEND_OSA_MESSAGE = 0x0100,
+ IPA_SETADP_SET_SNMP_CONTROL = 0x0200,
+ IPA_SETADP_QUERY_CARD_INFO = 0x0400,
IPA_SETADP_SET_PROMISC_MODE = 0x0800,
- IPA_SETADP_QUERY_CARD_INFO = 0x1000,
};
enum qeth_ipa_mac_ops {
- CHANGE_ADDR_READ_MAC = 0,
- CHANGE_ADDR_REPLACE_MAC = 1,
- CHANGE_ADDR_ADD_MAC = 2,
- CHANGE_ADDR_DEL_MAC = 4,
- CHANGE_ADDR_RESET_MAC = 8,
+ CHANGE_ADDR_READ_MAC = 0,
+ CHANGE_ADDR_REPLACE_MAC = 1,
+ CHANGE_ADDR_ADD_MAC = 2,
+ CHANGE_ADDR_DEL_MAC = 4,
+ CHANGE_ADDR_RESET_MAC = 8,
};
enum qeth_ipa_addr_ops {
- CHANGE_ADDR_READ_ADDR = 0,
- CHANGE_ADDR_ADD_ADDR = 1,
- CHANGE_ADDR_DEL_ADDR = 2,
- CHANGE_ADDR_FLUSH_ADDR_TABLE = 4,
+ CHANGE_ADDR_READ_ADDR = 0,
+ CHANGE_ADDR_ADD_ADDR = 1,
+ CHANGE_ADDR_DEL_ADDR = 2,
+ CHANGE_ADDR_FLUSH_ADDR_TABLE = 4,
};
enum qeth_ipa_promisc_modes {
SET_PROMISC_MODE_OFF = 0,
@@ -407,15 +436,15 @@ struct qeth_ipacmd_hdr {
struct qeth_ipa_cmd {
struct qeth_ipacmd_hdr hdr;
union {
- struct qeth_ipacmd_setdelip4 setdelip4;
- struct qeth_ipacmd_setdelip6 setdelip6;
+ struct qeth_ipacmd_setdelip4 setdelip4;
+ struct qeth_ipacmd_setdelip6 setdelip6;
struct qeth_ipacmd_setdelipm setdelipm;
- struct qeth_ipacmd_setassparms setassparms;
- struct qeth_ipacmd_layer2setdelmac setdelmac;
- struct qeth_ipacmd_layer2setdelvlan setdelvlan;
- struct qeth_create_destroy_address create_destroy_addr;
- struct qeth_ipacmd_setadpparms setadapterparms;
- struct qeth_set_routing setrtg;
+ struct qeth_ipacmd_setassparms setassparms;
+ struct qeth_ipacmd_layer2setdelmac setdelmac;
+ struct qeth_ipacmd_layer2setdelvlan setdelvlan;
+ struct qeth_create_destroy_address create_destroy_addr;
+ struct qeth_ipacmd_setadpparms setadapterparms;
+ struct qeth_set_routing setrtg;
} data;
} __attribute__ ((packed));
@@ -433,6 +462,12 @@ enum qeth_ipa_arp_return_codes {
QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008,
};
+
+extern char *
+qeth_get_ipa_msg(enum qeth_ipa_return_codes rc);
+extern char *
+qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);
+
#define QETH_SETASS_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
sizeof(struct qeth_ipacmd_setassparms_hdr))
#define QETH_IPA_ARP_DATA_POS(buffer) (buffer + IPA_PDU_HEADER_SIZE + \
@@ -521,7 +556,7 @@ extern unsigned char DM_ACT[];
extern unsigned char IDX_ACTIVATE_READ[];
extern unsigned char IDX_ACTIVATE_WRITE[];
-#define IDX_ACTIVATE_SIZE 0x22
+#define IDX_ACTIVATE_SIZE 0x22
#define QETH_IDX_ACT_ISSUER_RM_TOKEN(buffer) (buffer+0x0c)
#define QETH_IDX_NO_PORTNAME_REQUIRED(buffer) ((buffer)[0x0b]&0x80)
#define QETH_IDX_ACT_FUNC_LEVEL(buffer) (buffer+0x10)
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index d518419..65ffc21 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -384,8 +384,6 @@ qeth_dev_route_store(struct qeth_card *card, struct qeth_routing_info *route,
route->type = PRIMARY_CONNECTOR;
} else if (!strcmp(tmp, "secondary_connector")) {
route->type = SECONDARY_CONNECTOR;
- } else if (!strcmp(tmp, "multicast_router")) {
- route->type = MULTICAST_ROUTER;
} else if (!strcmp(tmp, "primary_router")) {
route->type = PRIMARY_ROUTER;
} else if (!strcmp(tmp, "secondary_router")) {
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index a39ee80..74b999d 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -15,7 +15,6 @@
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <linux/ioport.h>
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index 94d1858..18d18f1 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -19,7 +19,6 @@
#include <linux/fcntl.h>
#include <linux/poll.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/mostek.h>
#include <asm/system.h>
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index c3135e2..6afc7e5 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -20,7 +20,6 @@
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 58c811d2..e62d23f 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -170,7 +170,7 @@ config CHR_DEV_SCH
If you want to compile this as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
- say M here and read <file:Documentation/modules.txt> and
+ say M here and read <file:Documentation/kbuild/modules.txt> and
<file:Documentation/scsi.txt>. The module will be called ch.o.
If unsure, say N.
@@ -1783,7 +1783,7 @@ config ZFCP
This driver is also available as a module. This module will be
called zfcp. If you want to compile it as a module, say M here
- and read <file:Documentation/modules.txt>.
+ and read <file:Documentation/kbuild/modules.txt>.
config SCSI_SRP
tristate "SCSI RDMA Protocol helper library"
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 9218f29..ad9761b 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -47,7 +47,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/pci.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index 85ae5d8..8fee7ed 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -64,7 +64,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/pci.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 6c384ab..8c7d2bb 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -55,7 +55,6 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
#include <linux/sched.h>
#include <linux/reboot.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/dma-mapping.h>
#include <linux/timer.h>
diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c
index 99ce033..ec71061 100644
--- a/drivers/scsi/esp_scsi.c
+++ b/drivers/scsi/esp_scsi.c
@@ -2212,7 +2212,7 @@ static void __devinit esp_init_swstate(struct esp *esp)
}
/* This places the ESP into a known state at boot time. */
-static void __devinit esp_bootup_reset(struct esp *esp)
+static void esp_bootup_reset(struct esp *esp)
{
u8 val;
diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c
index 6d223dd..8ba7dd0 100644
--- a/drivers/scsi/ibmvscsi/ibmvstgt.c
+++ b/drivers/scsi/ibmvscsi/ibmvstgt.c
@@ -892,16 +892,16 @@ static int get_system_info(void)
if (!rootdn)
return -ENOENT;
- model = get_property(rootdn, "model", NULL);
- id = get_property(rootdn, "system-id", NULL);
+ model = of_get_property(rootdn, "model", NULL);
+ id = of_get_property(rootdn, "system-id", NULL);
if (model && id)
snprintf(system_id, sizeof(system_id), "%s-%s", model, id);
- name = get_property(rootdn, "ibm,partition-name", NULL);
+ name = of_get_property(rootdn, "ibm,partition-name", NULL);
if (name)
strncpy(partition_name, name, sizeof(partition_name));
- num = get_property(rootdn, "ibm,partition-no", NULL);
+ num = of_get_property(rootdn, "ibm,partition-no", NULL);
if (num)
partition_number = *num;
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c
index 0a533f3..d8700aa 100644
--- a/drivers/scsi/ibmvscsi/rpa_vscsi.c
+++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c
@@ -162,11 +162,11 @@ static void gather_partition_info(void)
return;
}
- ppartition_name = get_property(rootdn, "ibm,partition-name", NULL);
+ ppartition_name = of_get_property(rootdn, "ibm,partition-name", NULL);
if (ppartition_name)
strncpy(partition_name, ppartition_name,
sizeof(partition_name));
- p_number_ptr = get_property(rootdn, "ibm,partition-no", NULL);
+ p_number_ptr = of_get_property(rootdn, "ibm,partition-no", NULL);
if (p_number_ptr)
partition_number = *p_number_ptr;
of_node_put(rootdn);
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index 753d883..5806ede 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -471,7 +471,7 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat
goto out_free;
}
- clkprop = get_property(node, "clock-frequency", &proplen);
+ clkprop = of_get_property(node, "clock-frequency", &proplen);
if (clkprop == NULL || proplen != sizeof(int)) {
printk(KERN_ERR "%s: can't get clock frequency, "
"assuming 25MHz\n", node->full_name);
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index 6f50a5b..e64d1a1 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1947,7 +1947,7 @@ static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
ms->tgts[tgt].current_req = NULL;
}
- if ((cfp = get_property(mesh, "clock-frequency", NULL)))
+ if ((cfp = of_get_property(mesh, "clock-frequency", NULL)))
ms->clk_freq = *cfp;
else {
printk(KERN_INFO "mesh: assuming 50MHz clock frequency\n");
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 3e2930b..06229f2 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -36,7 +36,6 @@
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/moduleparam.h>
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 570977c..0c691a6 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -41,7 +41,6 @@ static int sg_version_num = 30534; /* 2 digits for each component */
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include <linux/moduleparam.h>
#include <linux/cdev.h>
#include <linux/seq_file.h>
diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c
index 6bc5051..a7dfb65 100644
--- a/drivers/scsi/sni_53c710.c
+++ b/drivers/scsi/sni_53c710.c
@@ -98,7 +98,7 @@ static int __init snirm710_probe(struct platform_device *dev)
host->this_id = 7;
host->base = base;
host->irq = platform_get_irq(dev, 0);
- if(request_irq(host->irq, NCR_700_intr, SA_SHIRQ, "snirm710", host)) {
+ if(request_irq(host->irq, NCR_700_intr, IRQF_SHARED, "snirm710", host)) {
printk(KERN_ERR "snirm710: request_irq failed!\n");
goto out_put_host;
}
diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c
index 8c766bc..bbeb245 100644
--- a/drivers/scsi/sun_esp.c
+++ b/drivers/scsi/sun_esp.c
@@ -5,6 +5,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/delay.h>
#include <linux/module.h>
#include <linux/init.h>
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 90621c3..48e259a 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -251,9 +251,16 @@ static const struct serial8250_config uart_config[] = {
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
.flags = UART_CAP_FIFO | UART_CAP_UUE,
},
+ [PORT_RM9000] = {
+ .name = "RM9000",
+ .fifo_size = 16,
+ .tx_loadsz = 16,
+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+ .flags = UART_CAP_FIFO,
+ },
};
-#ifdef CONFIG_SERIAL_8250_AU1X00
+#if defined (CONFIG_SERIAL_8250_AU1X00)
/* Au1x00 UART hardware has a weird register layout */
static const u8 au_io_in_map[] = {
@@ -289,6 +296,44 @@ static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
return au_io_out_map[offset];
}
+#elif defined (CONFIG_SERIAL_8250_RM9K)
+
+static const u8
+ regmap_in[8] = {
+ [UART_RX] = 0x00,
+ [UART_IER] = 0x0c,
+ [UART_IIR] = 0x14,
+ [UART_LCR] = 0x1c,
+ [UART_MCR] = 0x20,
+ [UART_LSR] = 0x24,
+ [UART_MSR] = 0x28,
+ [UART_SCR] = 0x2c
+ },
+ regmap_out[8] = {
+ [UART_TX] = 0x04,
+ [UART_IER] = 0x0c,
+ [UART_FCR] = 0x18,
+ [UART_LCR] = 0x1c,
+ [UART_MCR] = 0x20,
+ [UART_LSR] = 0x24,
+ [UART_MSR] = 0x28,
+ [UART_SCR] = 0x2c
+ };
+
+static inline int map_8250_in_reg(struct uart_8250_port *up, int offset)
+{
+ if (up->port.iotype != UPIO_RM9000)
+ return offset;
+ return regmap_in[offset];
+}
+
+static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
+{
+ if (up->port.iotype != UPIO_RM9000)
+ return offset;
+ return regmap_out[offset];
+}
+
#else
/* sane hardware needs no mapping */
@@ -308,8 +353,10 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset)
return inb(up->port.iobase + 1);
case UPIO_MEM:
+ case UPIO_DWAPB:
return readb(up->port.membase + offset);
+ case UPIO_RM9000:
case UPIO_MEM32:
return readl(up->port.membase + offset);
@@ -333,6 +380,8 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset)
static void
serial_out(struct uart_8250_port *up, int offset, int value)
{
+ /* Save the offset before it's remapped */
+ int save_offset = offset;
offset = map_8250_out_reg(up, offset) << up->port.regshift;
switch (up->port.iotype) {
@@ -345,6 +394,7 @@ serial_out(struct uart_8250_port *up, int offset, int value)
writeb(value, up->port.membase + offset);
break;
+ case UPIO_RM9000:
case UPIO_MEM32:
writel(value, up->port.membase + offset);
break;
@@ -359,6 +409,18 @@ serial_out(struct uart_8250_port *up, int offset, int value)
writeb(value, up->port.membase + offset);
break;
+ case UPIO_DWAPB:
+ /* Save the LCR value so it can be re-written when a
+ * Busy Detect interrupt occurs. */
+ if (save_offset == UART_LCR)
+ up->lcr = value;
+ writeb(value, up->port.membase + offset);
+ /* Read the IER to ensure any interrupt is cleared before
+ * returning from ISR. */
+ if (save_offset == UART_TX || save_offset == UART_IER)
+ value = serial_in(up, UART_IER);
+ break;
+
default:
outb(value, up->port.iobase + offset);
}
@@ -373,6 +435,7 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value)
#ifdef CONFIG_SERIAL_8250_AU1X00
case UPIO_AU:
#endif
+ case UPIO_DWAPB:
serial_out(up, offset, value);
serial_in(up, UART_LCR); /* safe, no side-effects */
break;
@@ -403,7 +466,7 @@ static inline void _serial_dl_write(struct uart_8250_port *up, int value)
serial_outp(up, UART_DLM, value >> 8 & 0xff);
}
-#ifdef CONFIG_SERIAL_8250_AU1X00
+#if defined (CONFIG_SERIAL_8250_AU1X00)
/* Au1x00 haven't got a standard divisor latch */
static int serial_dl_read(struct uart_8250_port *up)
{
@@ -420,6 +483,24 @@ static void serial_dl_write(struct uart_8250_port *up, int value)
else
_serial_dl_write(up, value);
}
+#elif defined (CONFIG_SERIAL_8250_RM9K)
+static int serial_dl_read(struct uart_8250_port *up)
+{
+ return (up->port.iotype == UPIO_RM9000) ?
+ (((__raw_readl(up->port.membase + 0x10) << 8) |
+ (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) :
+ _serial_dl_read(up);
+}
+
+static void serial_dl_write(struct uart_8250_port *up, int value)
+{
+ if (up->port.iotype == UPIO_RM9000) {
+ __raw_writel(value, up->port.membase + 0x08);
+ __raw_writel(value >> 8, up->port.membase + 0x10);
+ } else {
+ _serial_dl_write(up, value);
+ }
+}
#else
#define serial_dl_read(up) _serial_dl_read(up)
#define serial_dl_write(up, value) _serial_dl_write(up, value)
@@ -621,7 +702,7 @@ static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
* its clones. (We treat the broken original StarTech 16650 V1 as a
* 16550, and why not? Startech doesn't seem to even acknowledge its
* existence.)
- *
+ *
* What evil have men's minds wrought...
*/
static void autoconfig_has_efr(struct uart_8250_port *up)
@@ -674,7 +755,7 @@ static void autoconfig_has_efr(struct uart_8250_port *up)
up->bugs |= UART_BUG_QUOT;
return;
}
-
+
/*
* We check for a XR16C850 by setting DLL and DLM to 0, and then
* reading back DLL and DLM. The chip type depends on the DLM
@@ -817,7 +898,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */
serial_outp(up, 0x04, status1);
-
+
serial_dl_write(up, quot);
serial_outp(up, UART_LCR, 0);
@@ -913,7 +994,6 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
* be frobbing the chips IRQ enable register to see if it exists.
*/
spin_lock_irqsave(&up->port.lock, flags);
-// save_flags(flags); cli();
up->capabilities = 0;
up->bugs = 0;
@@ -922,7 +1002,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
/*
* Do a simple existence test first; if we fail this,
* there's no point trying anything else.
- *
+ *
* 0x80 is used as a nonsense port to prevent against
* false positives due to ISA bus float. The
* assumption is that 0x80 is a non-existent port;
@@ -961,7 +1041,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
save_mcr = serial_in(up, UART_MCR);
save_lcr = serial_in(up, UART_LCR);
- /*
+ /*
* Check to see if a UART is really there. Certain broken
* internal modems based on the Rockwell chipset fail this
* test, because they apparently don't implement the loopback
@@ -1068,9 +1148,8 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
else
serial_outp(up, UART_IER, 0);
- out:
+ out:
spin_unlock_irqrestore(&up->port.lock, flags);
-// restore_flags(flags);
DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
}
@@ -1094,7 +1173,7 @@ static void autoconfig_irq(struct uart_8250_port *up)
save_mcr = serial_inp(up, UART_MCR);
save_ier = serial_inp(up, UART_IER);
serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
-
+
irqs = probe_irq_on();
serial_outp(up, UART_MCR, 0);
udelay (10);
@@ -1159,8 +1238,11 @@ static void serial8250_start_tx(struct uart_port *port)
if (up->bugs & UART_BUG_TXEN) {
unsigned char lsr, iir;
lsr = serial_in(up, UART_LSR);
- iir = serial_in(up, UART_IIR);
- if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT)
+ iir = serial_in(up, UART_IIR) & 0x0f;
+ if ((up->port.type == PORT_RM9000) ?
+ (lsr & UART_LSR_THRE &&
+ (iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) :
+ (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT))
transmit_chars(up);
}
}
@@ -1389,6 +1471,19 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
handled = 1;
end = NULL;
+ } else if (up->port.iotype == UPIO_DWAPB &&
+ (iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
+ /* The DesignWare APB UART has an Busy Detect (0x07)
+ * interrupt meaning an LCR write attempt occured while the
+ * UART was busy. The interrupt must be cleared by reading
+ * the UART status register (USR) and the LCR re-written. */
+ unsigned int status;
+ status = *(volatile u32 *)up->port.private_data;
+ serial_out(up, UART_LCR, up->lcr);
+
+ handled = 1;
+
+ end = NULL;
} else if (end == NULL)
end = l;
@@ -1928,7 +2023,7 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
/*
* Ask the core to calculate the divisor for us.
*/
- baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
+ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
quot = serial8250_get_divisor(port, baud);
/*
@@ -2090,6 +2185,7 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
case UPIO_TSI:
case UPIO_MEM32:
case UPIO_MEM:
+ case UPIO_DWAPB:
if (!up->port.mapbase)
break;
@@ -2127,6 +2223,7 @@ static void serial8250_release_std_resource(struct uart_8250_port *up)
case UPIO_TSI:
case UPIO_MEM32:
case UPIO_MEM:
+ case UPIO_DWAPB:
if (!up->port.mapbase)
break;
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index ad9f321..e8efe93 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -73,17 +73,21 @@ config SERIAL_8250_PCI
depends on SERIAL_8250 && PCI
default SERIAL_8250
help
- This builds standard PCI serial support. You may be able to
- disable this feature if you only need legacy serial support.
- Saves about 9K.
+ Say Y here if you have PCI serial ports.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_pci.
config SERIAL_8250_PNP
tristate "8250/16550 PNP device support" if EMBEDDED
depends on SERIAL_8250 && PNP
default SERIAL_8250
help
- This builds standard PNP serial support. You may be able to
- disable this feature if you only need legacy serial support.
+ Say Y here if you have serial ports described by PNPBIOS or ACPI.
+ These are typically ports built into the system board.
+
+ To compile this driver as a module, choose M here: the module
+ will be called 8250_pnp.
config SERIAL_8250_HP300
tristate
@@ -254,6 +258,15 @@ config SERIAL_8250_AU1X00
to this option. The driver can handle 1 or 2 serial ports.
If unsure, say N.
+config SERIAL_8250_RM9K
+ bool "Support for MIPS RM9xxx integrated serial port"
+ depends on SERIAL_8250 != n && SERIAL_RM9000
+ select SERIAL_8250_SHARE_IRQ
+ help
+ Selecting this option will add support for the integrated serial
+ port hardware found on MIPS RM9122 and similar processors.
+ If unsure, say N.
+
comment "Non-8250 serial port support"
config SERIAL_AMBA_PL010
@@ -499,6 +512,100 @@ config SERIAL_SA1100_CONSOLE
your boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time.)
+config SERIAL_BFIN
+ tristate "Blackfin serial port support"
+ depends on BFIN
+ select SERIAL_CORE
+ select SERIAL_BFIN_UART0 if (BF531 || BF532 || BF533 || BF561)
+ help
+ Add support for the built-in UARTs on the Blackfin.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bfin_5xx.
+
+config SERIAL_BFIN_CONSOLE
+ bool "Console on Blackfin serial port"
+ depends on SERIAL_BFIN
+ select SERIAL_CORE_CONSOLE
+
+choice
+ prompt "UART Mode"
+ depends on SERIAL_BFIN
+ default SERIAL_BFIN_DMA
+ help
+ This driver supports the built-in serial ports of the Blackfin family
+ of CPUs
+
+config SERIAL_BFIN_DMA
+ bool "DMA mode"
+ depends on DMA_UNCACHED_1M
+ help
+ This driver works under DMA mode. If this option is selected, the
+ blackfin simple dma driver is also enabled.
+
+config SERIAL_BFIN_PIO
+ bool "PIO mode"
+ help
+ This driver works under PIO mode.
+
+endchoice
+
+config SERIAL_BFIN_UART0
+ bool "Enable UART0"
+ depends on SERIAL_BFIN
+ help
+ Enable UART0
+
+config BFIN_UART0_CTSRTS
+ bool "Enable UART0 hardware flow control"
+ depends on SERIAL_BFIN_UART0
+ help
+ Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
+ signal.
+
+config UART0_CTS_PIN
+ int "UART0 CTS pin"
+ depends on BFIN_UART0_CTSRTS
+ default 23
+ help
+ The default pin is GPIO_GP7.
+ Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+
+config UART0_RTS_PIN
+ int "UART0 RTS pin"
+ depends on BFIN_UART0_CTSRTS
+ default 22
+ help
+ The default pin is GPIO_GP6.
+ Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+
+config SERIAL_BFIN_UART1
+ bool "Enable UART1"
+ depends on SERIAL_BFIN && (BF534 || BF536 || BF537)
+ help
+ Enable UART1
+
+config BFIN_UART1_CTSRTS
+ bool "Enable UART1 hardware flow control"
+ depends on SERIAL_BFIN_UART1
+ help
+ Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
+ signal.
+
+config UART1_CTS_PIN
+ int "UART1 CTS pin"
+ depends on BFIN_UART1_CTSRTS
+ default -1
+ help
+ Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+
+config UART1_RTS_PIN
+ int "UART1 RTS pin"
+ depends on BFIN_UART1_CTSRTS
+ default -1
+ help
+ Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+
config SERIAL_IMX
bool "IMX serial port support"
depends on ARM && ARCH_IMX
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 6b3560c..4959bcb 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
obj-$(CONFIG_SERIAL_PXA) += pxa.o
obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
+obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o
obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o
obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index f69bd09..1a9a24b 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -48,6 +48,7 @@
#include <linux/serial.h>
#include <linux/amba/bus.h>
#include <linux/amba/serial.h>
+#include <linux/clk.h>
#include <asm/io.h>
@@ -70,6 +71,7 @@
*/
struct uart_amba_port {
struct uart_port port;
+ struct clk *clk;
struct amba_device *dev;
struct amba_pl010_data *data;
unsigned int old_status;
@@ -77,73 +79,77 @@ struct uart_amba_port {
static void pl010_stop_tx(struct uart_port *port)
{
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
unsigned int cr;
- cr = readb(port->membase + UART010_CR);
+ cr = readb(uap->port.membase + UART010_CR);
cr &= ~UART010_CR_TIE;
- writel(cr, port->membase + UART010_CR);
+ writel(cr, uap->port.membase + UART010_CR);
}
static void pl010_start_tx(struct uart_port *port)
{
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
unsigned int cr;
- cr = readb(port->membase + UART010_CR);
+ cr = readb(uap->port.membase + UART010_CR);
cr |= UART010_CR_TIE;
- writel(cr, port->membase + UART010_CR);
+ writel(cr, uap->port.membase + UART010_CR);
}
static void pl010_stop_rx(struct uart_port *port)
{
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
unsigned int cr;
- cr = readb(port->membase + UART010_CR);
+ cr = readb(uap->port.membase + UART010_CR);
cr &= ~(UART010_CR_RIE | UART010_CR_RTIE);
- writel(cr, port->membase + UART010_CR);
+ writel(cr, uap->port.membase + UART010_CR);
}
static void pl010_enable_ms(struct uart_port *port)
{
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
unsigned int cr;
- cr = readb(port->membase + UART010_CR);
+ cr = readb(uap->port.membase + UART010_CR);
cr |= UART010_CR_MSIE;
- writel(cr, port->membase + UART010_CR);
+ writel(cr, uap->port.membase + UART010_CR);
}
-static void pl010_rx_chars(struct uart_port *port)
+static void pl010_rx_chars(struct uart_amba_port *uap)
{
- struct tty_struct *tty = port->info->tty;
+ struct tty_struct *tty = uap->port.info->tty;
unsigned int status, ch, flag, rsr, max_count = 256;
- status = readb(port->membase + UART01x_FR);
+ status = readb(uap->port.membase + UART01x_FR);
while (UART_RX_DATA(status) && max_count--) {
- ch = readb(port->membase + UART01x_DR);
+ ch = readb(uap->port.membase + UART01x_DR);
flag = TTY_NORMAL;
- port->icount.rx++;
+ uap->port.icount.rx++;
/*
* Note that the error handling code is
* out of the main execution path
*/
- rsr = readb(port->membase + UART01x_RSR) | UART_DUMMY_RSR_RX;
+ rsr = readb(uap->port.membase + UART01x_RSR) | UART_DUMMY_RSR_RX;
if (unlikely(rsr & UART01x_RSR_ANY)) {
- writel(0, port->membase + UART01x_ECR);
+ writel(0, uap->port.membase + UART01x_ECR);
if (rsr & UART01x_RSR_BE) {
rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE);
- port->icount.brk++;
- if (uart_handle_break(port))
+ uap->port.icount.brk++;
+ if (uart_handle_break(&uap->port))
goto ignore_char;
} else if (rsr & UART01x_RSR_PE)
- port->icount.parity++;
+ uap->port.icount.parity++;
else if (rsr & UART01x_RSR_FE)
- port->icount.frame++;
+ uap->port.icount.frame++;
if (rsr & UART01x_RSR_OE)
- port->icount.overrun++;
+ uap->port.icount.overrun++;
- rsr &= port->read_status_mask;
+ rsr &= uap->port.read_status_mask;
if (rsr & UART01x_RSR_BE)
flag = TTY_BREAK;
@@ -153,53 +159,52 @@ static void pl010_rx_chars(struct uart_port *port)
flag = TTY_FRAME;
}
- if (uart_handle_sysrq_char(port, ch))
+ if (uart_handle_sysrq_char(&uap->port, ch))
goto ignore_char;
- uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag);
+ uart_insert_char(&uap->port, rsr, UART01x_RSR_OE, ch, flag);
ignore_char:
- status = readb(port->membase + UART01x_FR);
+ status = readb(uap->port.membase + UART01x_FR);
}
tty_flip_buffer_push(tty);
return;
}
-static void pl010_tx_chars(struct uart_port *port)
+static void pl010_tx_chars(struct uart_amba_port *uap)
{
- struct circ_buf *xmit = &port->info->xmit;
+ struct circ_buf *xmit = &uap->port.info->xmit;
int count;
- if (port->x_char) {
- writel(port->x_char, port->membase + UART01x_DR);
- port->icount.tx++;
- port->x_char = 0;
+ if (uap->port.x_char) {
+ writel(uap->port.x_char, uap->port.membase + UART01x_DR);
+ uap->port.icount.tx++;
+ uap->port.x_char = 0;
return;
}
- if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
- pl010_stop_tx(port);
+ if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) {
+ pl010_stop_tx(&uap->port);
return;
}
- count = port->fifosize >> 1;
+ count = uap->port.fifosize >> 1;
do {
- writel(xmit->buf[xmit->tail], port->membase + UART01x_DR);
+ writel(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
- port->icount.tx++;
+ uap->port.icount.tx++;
if (uart_circ_empty(xmit))
break;
} while (--count > 0);
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_write_wakeup(port);
+ uart_write_wakeup(&uap->port);
if (uart_circ_empty(xmit))
- pl010_stop_tx(port);
+ pl010_stop_tx(&uap->port);
}
-static void pl010_modem_status(struct uart_port *port)
+static void pl010_modem_status(struct uart_amba_port *uap)
{
- struct uart_amba_port *uap = (struct uart_amba_port *)port;
unsigned int status, delta;
writel(0, uap->port.membase + UART010_ICR);
@@ -226,47 +231,50 @@ static void pl010_modem_status(struct uart_port *port)
static irqreturn_t pl010_int(int irq, void *dev_id)
{
- struct uart_port *port = dev_id;
+ struct uart_amba_port *uap = dev_id;
unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
int handled = 0;
- spin_lock(&port->lock);
+ spin_lock(&uap->port.lock);
- status = readb(port->membase + UART010_IIR);
+ status = readb(uap->port.membase + UART010_IIR);
if (status) {
do {
if (status & (UART010_IIR_RTIS | UART010_IIR_RIS))
- pl010_rx_chars(port);
+ pl010_rx_chars(uap);
if (status & UART010_IIR_MIS)
- pl010_modem_status(port);
+ pl010_modem_status(uap);
if (status & UART010_IIR_TIS)
- pl010_tx_chars(port);
+ pl010_tx_chars(uap);
if (pass_counter-- == 0)
break;
- status = readb(port->membase + UART010_IIR);
+ status = readb(uap->port.membase + UART010_IIR);
} while (status & (UART010_IIR_RTIS | UART010_IIR_RIS |
UART010_IIR_TIS));
handled = 1;
}
- spin_unlock(&port->lock);
+ spin_unlock(&uap->port.lock);
return IRQ_RETVAL(handled);
}
static unsigned int pl010_tx_empty(struct uart_port *port)
{
- return readb(port->membase + UART01x_FR) & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT;
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
+ unsigned int status = readb(uap->port.membase + UART01x_FR);
+ return status & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT;
}
static unsigned int pl010_get_mctrl(struct uart_port *port)
{
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
unsigned int result = 0;
unsigned int status;
- status = readb(port->membase + UART01x_FR);
+ status = readb(uap->port.membase + UART01x_FR);
if (status & UART01x_FR_DCD)
result |= TIOCM_CAR;
if (status & UART01x_FR_DSR)
@@ -287,17 +295,18 @@ static void pl010_set_mctrl(struct uart_port *port, unsigned int mctrl)
static void pl010_break_ctl(struct uart_port *port, int break_state)
{
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
unsigned long flags;
unsigned int lcr_h;
- spin_lock_irqsave(&port->lock, flags);
- lcr_h = readb(port->membase + UART010_LCRH);
+ spin_lock_irqsave(&uap->port.lock, flags);
+ lcr_h = readb(uap->port.membase + UART010_LCRH);
if (break_state == -1)
lcr_h |= UART01x_LCRH_BRK;
else
lcr_h &= ~UART01x_LCRH_BRK;
- writel(lcr_h, port->membase + UART010_LCRH);
- spin_unlock_irqrestore(&port->lock, flags);
+ writel(lcr_h, uap->port.membase + UART010_LCRH);
+ spin_unlock_irqrestore(&uap->port.lock, flags);
}
static int pl010_startup(struct uart_port *port)
@@ -306,48 +315,70 @@ static int pl010_startup(struct uart_port *port)
int retval;
/*
+ * Try to enable the clock producer.
+ */
+ retval = clk_enable(uap->clk);
+ if (retval)
+ goto out;
+
+ uap->port.uartclk = clk_get_rate(uap->clk);
+
+ /*
* Allocate the IRQ
*/
- retval = request_irq(port->irq, pl010_int, 0, "uart-pl010", port);
+ retval = request_irq(uap->port.irq, pl010_int, 0, "uart-pl010", uap);
if (retval)
- return retval;
+ goto clk_dis;
/*
* initialise the old status of the modem signals
*/
- uap->old_status = readb(port->membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
+ uap->old_status = readb(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
/*
* Finally, enable interrupts
*/
writel(UART01x_CR_UARTEN | UART010_CR_RIE | UART010_CR_RTIE,
- port->membase + UART010_CR);
+ uap->port.membase + UART010_CR);
return 0;
+
+ clk_dis:
+ clk_disable(uap->clk);
+ out:
+ return retval;
}
static void pl010_shutdown(struct uart_port *port)
{
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
+
/*
* Free the interrupt
*/
- free_irq(port->irq, port);
+ free_irq(uap->port.irq, uap);
/*
* disable all interrupts, disable the port
*/
- writel(0, port->membase + UART010_CR);
+ writel(0, uap->port.membase + UART010_CR);
/* disable break condition and fifos */
- writel(readb(port->membase + UART010_LCRH) &
+ writel(readb(uap->port.membase + UART010_LCRH) &
~(UART01x_LCRH_BRK | UART01x_LCRH_FEN),
- port->membase + UART010_LCRH);
+ uap->port.membase + UART010_LCRH);
+
+ /*
+ * Shut down the clock producer
+ */
+ clk_disable(uap->clk);
}
static void
pl010_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
unsigned int lcr_h, old_cr;
unsigned long flags;
unsigned int baud, quot;
@@ -355,7 +386,7 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios,
/*
* Ask the core to calculate the divisor for us.
*/
- baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
+ baud = uart_get_baud_rate(port, termios, old, 0, uap->port.uartclk/16);
quot = uart_get_divisor(port, baud);
switch (termios->c_cflag & CSIZE) {
@@ -379,66 +410,66 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios,
if (!(termios->c_cflag & PARODD))
lcr_h |= UART01x_LCRH_EPS;
}
- if (port->fifosize > 1)
+ if (uap->port.fifosize > 1)
lcr_h |= UART01x_LCRH_FEN;
- spin_lock_irqsave(&port->lock, flags);
+ spin_lock_irqsave(&uap->port.lock, flags);
/*
* Update the per-port timeout.
*/
uart_update_timeout(port, termios->c_cflag, baud);
- port->read_status_mask = UART01x_RSR_OE;
+ uap->port.read_status_mask = UART01x_RSR_OE;
if (termios->c_iflag & INPCK)
- port->read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
+ uap->port.read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
if (termios->c_iflag & (BRKINT | PARMRK))
- port->read_status_mask |= UART01x_RSR_BE;
+ uap->port.read_status_mask |= UART01x_RSR_BE;
/*
* Characters to ignore
*/
- port->ignore_status_mask = 0;
+ uap->port.ignore_status_mask = 0;
if (termios->c_iflag & IGNPAR)
- port->ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
+ uap->port.ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
if (termios->c_iflag & IGNBRK) {
- port->ignore_status_mask |= UART01x_RSR_BE;
+ uap->port.ignore_status_mask |= UART01x_RSR_BE;
/*
* If we're ignoring parity and break indicators,
* ignore overruns too (for real raw support).
*/
if (termios->c_iflag & IGNPAR)
- port->ignore_status_mask |= UART01x_RSR_OE;
+ uap->port.ignore_status_mask |= UART01x_RSR_OE;
}
/*
* Ignore all characters if CREAD is not set.
*/
if ((termios->c_cflag & CREAD) == 0)
- port->ignore_status_mask |= UART_DUMMY_RSR_RX;
+ uap->port.ignore_status_mask |= UART_DUMMY_RSR_RX;
/* first, disable everything */
- old_cr = readb(port->membase + UART010_CR) & ~UART010_CR_MSIE;
+ old_cr = readb(uap->port.membase + UART010_CR) & ~UART010_CR_MSIE;
if (UART_ENABLE_MS(port, termios->c_cflag))
old_cr |= UART010_CR_MSIE;
- writel(0, port->membase + UART010_CR);
+ writel(0, uap->port.membase + UART010_CR);
/* Set baud rate */
quot -= 1;
- writel((quot & 0xf00) >> 8, port->membase + UART010_LCRM);
- writel(quot & 0xff, port->membase + UART010_LCRL);
+ writel((quot & 0xf00) >> 8, uap->port.membase + UART010_LCRM);
+ writel(quot & 0xff, uap->port.membase + UART010_LCRL);
/*
* ----------v----------v----------v----------v-----
* NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
* ----------^----------^----------^----------^-----
*/
- writel(lcr_h, port->membase + UART010_LCRH);
- writel(old_cr, port->membase + UART010_CR);
+ writel(lcr_h, uap->port.membase + UART010_LCRH);
+ writel(old_cr, uap->port.membase + UART010_CR);
- spin_unlock_irqrestore(&port->lock, flags);
+ spin_unlock_irqrestore(&uap->port.lock, flags);
}
static const char *pl010_type(struct uart_port *port)
@@ -514,47 +545,52 @@ static struct uart_amba_port *amba_ports[UART_NR];
static void pl010_console_putchar(struct uart_port *port, int ch)
{
+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
unsigned int status;
do {
- status = readb(port->membase + UART01x_FR);
+ status = readb(uap->port.membase + UART01x_FR);
barrier();
} while (!UART_TX_READY(status));
- writel(ch, port->membase + UART01x_DR);
+ writel(ch, uap->port.membase + UART01x_DR);
}
static void
pl010_console_write(struct console *co, const char *s, unsigned int count)
{
- struct uart_port *port = &amba_ports[co->index]->port;
+ struct uart_amba_port *uap = amba_ports[co->index];
unsigned int status, old_cr;
+ clk_enable(uap->clk);
+
/*
* First save the CR then disable the interrupts
*/
- old_cr = readb(port->membase + UART010_CR);
- writel(UART01x_CR_UARTEN, port->membase + UART010_CR);
+ old_cr = readb(uap->port.membase + UART010_CR);
+ writel(UART01x_CR_UARTEN, uap->port.membase + UART010_CR);
- uart_console_write(port, s, count, pl010_console_putchar);
+ uart_console_write(&uap->port, s, count, pl010_console_putchar);
/*
* Finally, wait for transmitter to become empty
* and restore the TCR
*/
do {
- status = readb(port->membase + UART01x_FR);
+ status = readb(uap->port.membase + UART01x_FR);
barrier();
} while (status & UART01x_FR_BUSY);
- writel(old_cr, port->membase + UART010_CR);
+ writel(old_cr, uap->port.membase + UART010_CR);
+
+ clk_disable(uap->clk);
}
static void __init
-pl010_console_get_options(struct uart_port *port, int *baud,
+pl010_console_get_options(struct uart_amba_port *uap, int *baud,
int *parity, int *bits)
{
- if (readb(port->membase + UART010_CR) & UART01x_CR_UARTEN) {
+ if (readb(uap->port.membase + UART010_CR) & UART01x_CR_UARTEN) {
unsigned int lcr_h, quot;
- lcr_h = readb(port->membase + UART010_LCRH);
+ lcr_h = readb(uap->port.membase + UART010_LCRH);
*parity = 'n';
if (lcr_h & UART01x_LCRH_PEN) {
@@ -569,14 +605,15 @@ pl010_console_get_options(struct uart_port *port, int *baud,
else
*bits = 8;
- quot = readb(port->membase + UART010_LCRL) | readb(port->membase + UART010_LCRM) << 8;
- *baud = port->uartclk / (16 * (quot + 1));
+ quot = readb(uap->port.membase + UART010_LCRL) |
+ readb(uap->port.membase + UART010_LCRM) << 8;
+ *baud = uap->port.uartclk / (16 * (quot + 1));
}
}
static int __init pl010_console_setup(struct console *co, char *options)
{
- struct uart_port *port;
+ struct uart_amba_port *uap;
int baud = 38400;
int bits = 8;
int parity = 'n';
@@ -589,16 +626,18 @@ static int __init pl010_console_setup(struct console *co, char *options)
*/
if (co->index >= UART_NR)
co->index = 0;
- if (!amba_ports[co->index])
+ uap = amba_ports[co->index];
+ if (!uap)
return -ENODEV;
- port = &amba_ports[co->index]->port;
+
+ uap->port.uartclk = clk_get_rate(uap->clk);
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
else
- pl010_console_get_options(port, &baud, &parity, &bits);
+ pl010_console_get_options(uap, &baud, &parity, &bits);
- return uart_set_options(port, co, baud, parity, bits, flow);
+ return uart_set_options(&uap->port, co, baud, parity, bits, flow);
}
static struct uart_driver amba_reg;
@@ -629,7 +668,7 @@ static struct uart_driver amba_reg = {
static int pl010_probe(struct amba_device *dev, void *id)
{
- struct uart_amba_port *port;
+ struct uart_amba_port *uap;
void __iomem *base;
int i, ret;
@@ -642,8 +681,8 @@ static int pl010_probe(struct amba_device *dev, void *id)
goto out;
}
- port = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
- if (!port) {
+ uap = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
+ if (!uap) {
ret = -ENOMEM;
goto out;
}
@@ -654,51 +693,57 @@ static int pl010_probe(struct amba_device *dev, void *id)
goto free;
}
- port->port.dev = &dev->dev;
- port->port.mapbase = dev->res.start;
- port->port.membase = base;
- port->port.iotype = UPIO_MEM;
- port->port.irq = dev->irq[0];
- port->port.uartclk = 14745600;
- port->port.fifosize = 16;
- port->port.ops = &amba_pl010_pops;
- port->port.flags = UPF_BOOT_AUTOCONF;
- port->port.line = i;
- port->dev = dev;
- port->data = dev->dev.platform_data;
-
- amba_ports[i] = port;
-
- amba_set_drvdata(dev, port);
- ret = uart_add_one_port(&amba_reg, &port->port);
+ uap->clk = clk_get(&dev->dev, "UARTCLK");
+ if (IS_ERR(uap->clk)) {
+ ret = PTR_ERR(uap->clk);
+ goto unmap;
+ }
+
+ uap->port.dev = &dev->dev;
+ uap->port.mapbase = dev->res.start;
+ uap->port.membase = base;
+ uap->port.iotype = UPIO_MEM;
+ uap->port.irq = dev->irq[0];
+ uap->port.fifosize = 16;
+ uap->port.ops = &amba_pl010_pops;
+ uap->port.flags = UPF_BOOT_AUTOCONF;
+ uap->port.line = i;
+ uap->dev = dev;
+ uap->data = dev->dev.platform_data;
+
+ amba_ports[i] = uap;
+
+ amba_set_drvdata(dev, uap);
+ ret = uart_add_one_port(&amba_reg, &uap->port);
if (ret) {
amba_set_drvdata(dev, NULL);
amba_ports[i] = NULL;
+ clk_put(uap->clk);
+ unmap:
iounmap(base);
free:
- kfree(port);
+ kfree(uap);
}
-
out:
return ret;
}
static int pl010_remove(struct amba_device *dev)
{
- struct uart_amba_port *port = amba_get_drvdata(dev);
+ struct uart_amba_port *uap = amba_get_drvdata(dev);
int i;
amba_set_drvdata(dev, NULL);
- uart_remove_one_port(&amba_reg, &port->port);
+ uart_remove_one_port(&amba_reg, &uap->port);
for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
- if (amba_ports[i] == port)
+ if (amba_ports[i] == uap)
amba_ports[i] = NULL;
- iounmap(port->port.membase);
- kfree(port);
-
+ iounmap(uap->port.membase);
+ clk_put(uap->clk);
+ kfree(uap);
return 0;
}
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 935f48f..3320bcd 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -484,11 +484,16 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios * termios,
unsigned long flags;
unsigned int mode, imr, quot, baud;
+ /* Get current mode register */
+ mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL | ATMEL_US_NBSTOP | ATMEL_US_PAR);
+
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
quot = uart_get_divisor(port, baud);
- /* Get current mode register */
- mode = UART_GET_MR(port) & ~(ATMEL_US_CHRL | ATMEL_US_NBSTOP | ATMEL_US_PAR);
+ if (quot > 65535) { /* BRGR is 16-bit, so switch to slower clock */
+ quot /= 8;
+ mode |= ATMEL_US_USCLKS_MCK_DIV8;
+ }
/* byte size */
switch (termios->c_cflag & CSIZE) {
diff --git a/drivers/serial/atmel_serial.h b/drivers/serial/atmel_serial.h
index 11b4436..e014177 100644
--- a/drivers/serial/atmel_serial.h
+++ b/drivers/serial/atmel_serial.h
@@ -46,6 +46,9 @@
#define ATMEL_US_USMODE_ISO7816_T1 6
#define ATMEL_US_USMODE_IRDA 8
#define ATMEL_US_USCLKS (3 << 4) /* Clock Selection */
+#define ATMEL_US_USCLKS_MCK (0 << 4)
+#define ATMEL_US_USCLKS_MCK_DIV8 (1 << 4)
+#define ATMEL_US_USCLKS_SCK (3 << 4)
#define ATMEL_US_CHRL (3 << 6) /* Character Length */
#define ATMEL_US_CHRL_5 (0 << 6)
#define ATMEL_US_CHRL_6 (1 << 6)
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
new file mode 100644
index 0000000..408390f
--- /dev/null
+++ b/drivers/serial/bfin_5xx.c
@@ -0,0 +1,1012 @@
+/*
+ * File: drivers/serial/bfin_5xx.c
+ * Based on: Based on drivers/serial/sa1100.c
+ * Author: Aubrey Li <aubrey.li@analog.com>
+ *
+ * Created:
+ * Description: Driver for blackfin 5xx serial ports
+ *
+ * Rev: $Id: bfin_5xx.c,v 1.19 2006/09/24 02:33:53 aubrey Exp $
+ *
+ * Modified:
+ * Copyright 2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/platform_device.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial_core.h>
+
+#include <asm/gpio.h>
+#include <asm/mach/bfin_serial_5xx.h>
+
+#ifdef CONFIG_SERIAL_BFIN_DMA
+#include <linux/dma-mapping.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/cacheflush.h>
+#endif
+
+/* UART name and device definitions */
+#define BFIN_SERIAL_NAME "ttyBF"
+#define BFIN_SERIAL_MAJOR 204
+#define BFIN_SERIAL_MINOR 64
+
+/*
+ * Setup for console. Argument comes from the menuconfig
+ */
+#define DMA_RX_XCOUNT 512
+#define DMA_RX_YCOUNT (PAGE_SIZE / DMA_RX_XCOUNT)
+
+#define DMA_RX_FLUSH_JIFFIES 5
+
+#ifdef CONFIG_SERIAL_BFIN_DMA
+static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart);
+#else
+static void bfin_serial_do_work(struct work_struct *work);
+static void bfin_serial_tx_chars(struct bfin_serial_port *uart);
+static void local_put_char(struct bfin_serial_port *uart, char ch);
+#endif
+
+static void bfin_serial_mctrl_check(struct bfin_serial_port *uart);
+
+/*
+ * interrupts are disabled on entry
+ */
+static void bfin_serial_stop_tx(struct uart_port *port)
+{
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ disable_dma(uart->tx_dma_channel);
+#else
+ unsigned short ier;
+
+ ier = UART_GET_IER(uart);
+ ier &= ~ETBEI;
+ UART_PUT_IER(uart, ier);
+#endif
+}
+
+/*
+ * port is locked and interrupts are disabled
+ */
+static void bfin_serial_start_tx(struct uart_port *port)
+{
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ bfin_serial_dma_tx_chars(uart);
+#else
+ unsigned short ier;
+ ier = UART_GET_IER(uart);
+ ier |= ETBEI;
+ UART_PUT_IER(uart, ier);
+ bfin_serial_tx_chars(uart);
+#endif
+}
+
+/*
+ * Interrupts are enabled
+ */
+static void bfin_serial_stop_rx(struct uart_port *port)
+{
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+ unsigned short ier;
+
+ ier = UART_GET_IER(uart);
+ ier &= ~ERBFI;
+ UART_PUT_IER(uart, ier);
+}
+
+/*
+ * Set the modem control timer to fire immediately.
+ */
+static void bfin_serial_enable_ms(struct uart_port *port)
+{
+}
+
+#ifdef CONFIG_SERIAL_BFIN_PIO
+static void local_put_char(struct bfin_serial_port *uart, char ch)
+{
+ unsigned short status;
+ int flags = 0;
+
+ spin_lock_irqsave(&uart->port.lock, flags);
+
+ do {
+ status = UART_GET_LSR(uart);
+ } while (!(status & THRE));
+
+ UART_PUT_CHAR(uart, ch);
+ SSYNC();
+
+ spin_unlock_irqrestore(&uart->port.lock, flags);
+}
+
+static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
+{
+ struct tty_struct *tty = uart->port.info?uart->port.info->tty:0;
+ unsigned int status, ch, flg;
+#ifdef BF533_FAMILY
+ static int in_break = 0;
+#endif
+
+ status = UART_GET_LSR(uart);
+ ch = UART_GET_CHAR(uart);
+ uart->port.icount.rx++;
+
+#ifdef BF533_FAMILY
+ /* The BF533 family of processors have a nice misbehavior where
+ * they continuously generate characters for a "single" break.
+ * We have to basically ignore this flood until the "next" valid
+ * character comes across. All other Blackfin families operate
+ * properly though.
+ */
+ if (in_break) {
+ if (ch != 0) {
+ in_break = 0;
+ ch = UART_GET_CHAR(uart);
+ }
+ return;
+ }
+#endif
+
+ if (status & BI) {
+#ifdef BF533_FAMILY
+ in_break = 1;
+#endif
+ uart->port.icount.brk++;
+ if (uart_handle_break(&uart->port))
+ goto ignore_char;
+ flg = TTY_BREAK;
+ } else if (status & PE) {
+ flg = TTY_PARITY;
+ uart->port.icount.parity++;
+ } else if (status & OE) {
+ flg = TTY_OVERRUN;
+ uart->port.icount.overrun++;
+ } else if (status & FE) {
+ flg = TTY_FRAME;
+ uart->port.icount.frame++;
+ } else
+ flg = TTY_NORMAL;
+
+ if (uart_handle_sysrq_char(&uart->port, ch))
+ goto ignore_char;
+ if (tty)
+ uart_insert_char(&uart->port, status, 2, ch, flg);
+
+ignore_char:
+ if (tty)
+ tty_flip_buffer_push(tty);
+}
+
+static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
+{
+ struct circ_buf *xmit = &uart->port.info->xmit;
+
+ if (uart->port.x_char) {
+ UART_PUT_CHAR(uart, uart->port.x_char);
+ uart->port.icount.tx++;
+ uart->port.x_char = 0;
+ return;
+ }
+ /*
+ * Check the modem control lines before
+ * transmitting anything.
+ */
+ bfin_serial_mctrl_check(uart);
+
+ if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
+ bfin_serial_stop_tx(&uart->port);
+ return;
+ }
+
+ local_put_char(uart, xmit->buf[xmit->tail]);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ uart->port.icount.tx++;
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&uart->port);
+
+ if (uart_circ_empty(xmit))
+ bfin_serial_stop_tx(&uart->port);
+}
+
+static irqreturn_t bfin_serial_int(int irq, void *dev_id)
+{
+ struct bfin_serial_port *uart = dev_id;
+ unsigned short status;
+
+ spin_lock(&uart->port.lock);
+ status = UART_GET_IIR(uart);
+ do {
+ if ((status & IIR_STATUS) == IIR_TX_READY)
+ bfin_serial_tx_chars(uart);
+ if ((status & IIR_STATUS) == IIR_RX_READY)
+ bfin_serial_rx_chars(uart);
+ status = UART_GET_IIR(uart);
+ } while (status & (IIR_TX_READY | IIR_RX_READY));
+ spin_unlock(&uart->port.lock);
+ return IRQ_HANDLED;
+}
+
+static void bfin_serial_do_work(struct work_struct *work)
+{
+ struct bfin_serial_port *uart = container_of(work, struct bfin_serial_port, cts_workqueue);
+
+ bfin_serial_mctrl_check(uart);
+}
+
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_DMA
+static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
+{
+ struct circ_buf *xmit = &uart->port.info->xmit;
+ unsigned short ier;
+ int flags = 0;
+
+ if (!uart->tx_done)
+ return;
+
+ uart->tx_done = 0;
+
+ if (uart->port.x_char) {
+ UART_PUT_CHAR(uart, uart->port.x_char);
+ uart->port.icount.tx++;
+ uart->port.x_char = 0;
+ uart->tx_done = 1;
+ return;
+ }
+ /*
+ * Check the modem control lines before
+ * transmitting anything.
+ */
+ bfin_serial_mctrl_check(uart);
+
+ if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
+ bfin_serial_stop_tx(&uart->port);
+ uart->tx_done = 1;
+ return;
+ }
+
+ spin_lock_irqsave(&uart->port.lock, flags);
+ uart->tx_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE);
+ if (uart->tx_count > (UART_XMIT_SIZE - xmit->tail))
+ uart->tx_count = UART_XMIT_SIZE - xmit->tail;
+ blackfin_dcache_flush_range((unsigned long)(xmit->buf+xmit->tail),
+ (unsigned long)(xmit->buf+xmit->tail+uart->tx_count));
+ set_dma_config(uart->tx_dma_channel,
+ set_bfin_dma_config(DIR_READ, DMA_FLOW_STOP,
+ INTR_ON_BUF,
+ DIMENSION_LINEAR,
+ DATA_SIZE_8));
+ set_dma_start_addr(uart->tx_dma_channel, (unsigned long)(xmit->buf+xmit->tail));
+ set_dma_x_count(uart->tx_dma_channel, uart->tx_count);
+ set_dma_x_modify(uart->tx_dma_channel, 1);
+ enable_dma(uart->tx_dma_channel);
+ ier = UART_GET_IER(uart);
+ ier |= ETBEI;
+ UART_PUT_IER(uart, ier);
+ spin_unlock_irqrestore(&uart->port.lock, flags);
+}
+
+static void bfin_serial_dma_rx_chars(struct bfin_serial_port * uart)
+{
+ struct tty_struct *tty = uart->port.info->tty;
+ int i, flg, status;
+
+ status = UART_GET_LSR(uart);
+ uart->port.icount.rx += CIRC_CNT(uart->rx_dma_buf.head, uart->rx_dma_buf.tail, UART_XMIT_SIZE);;
+
+ if (status & BI) {
+ uart->port.icount.brk++;
+ if (uart_handle_break(&uart->port))
+ goto dma_ignore_char;
+ flg = TTY_BREAK;
+ } else if (status & PE) {
+ flg = TTY_PARITY;
+ uart->port.icount.parity++;
+ } else if (status & OE) {
+ flg = TTY_OVERRUN;
+ uart->port.icount.overrun++;
+ } else if (status & FE) {
+ flg = TTY_FRAME;
+ uart->port.icount.frame++;
+ } else
+ flg = TTY_NORMAL;
+
+ for (i = uart->rx_dma_buf.head; i < uart->rx_dma_buf.tail; i++) {
+ if (uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i]))
+ goto dma_ignore_char;
+ uart_insert_char(&uart->port, status, 2, uart->rx_dma_buf.buf[i], flg);
+ }
+dma_ignore_char:
+ tty_flip_buffer_push(tty);
+}
+
+void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
+{
+ int x_pos, pos;
+ int flags = 0;
+
+ bfin_serial_dma_tx_chars(uart);
+
+ spin_lock_irqsave(&uart->port.lock, flags);
+ x_pos = DMA_RX_XCOUNT - get_dma_curr_xcount(uart->rx_dma_channel);
+ if (x_pos == DMA_RX_XCOUNT)
+ x_pos = 0;
+
+ pos = uart->rx_dma_nrows * DMA_RX_XCOUNT + x_pos;
+
+ if (pos>uart->rx_dma_buf.tail) {
+ uart->rx_dma_buf.tail = pos;
+ bfin_serial_dma_rx_chars(uart);
+ uart->rx_dma_buf.head = uart->rx_dma_buf.tail;
+ }
+ spin_unlock_irqrestore(&uart->port.lock, flags);
+ uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES;
+ add_timer(&(uart->rx_dma_timer));
+}
+
+static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
+{
+ struct bfin_serial_port *uart = dev_id;
+ struct circ_buf *xmit = &uart->port.info->xmit;
+ unsigned short ier;
+
+ spin_lock(&uart->port.lock);
+ if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) {
+ clear_dma_irqstat(uart->tx_dma_channel);
+ disable_dma(uart->tx_dma_channel);
+ ier = UART_GET_IER(uart);
+ ier &= ~ETBEI;
+ UART_PUT_IER(uart, ier);
+ xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1);
+ uart->port.icount.tx+=uart->tx_count;
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&uart->port);
+
+ if (uart_circ_empty(xmit))
+ bfin_serial_stop_tx(&uart->port);
+ uart->tx_done = 1;
+ }
+
+ spin_unlock(&uart->port.lock);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id)
+{
+ struct bfin_serial_port *uart = dev_id;
+ unsigned short irqstat;
+
+ uart->rx_dma_nrows++;
+ if (uart->rx_dma_nrows == DMA_RX_YCOUNT) {
+ uart->rx_dma_nrows = 0;
+ uart->rx_dma_buf.tail = DMA_RX_XCOUNT*DMA_RX_YCOUNT;
+ bfin_serial_dma_rx_chars(uart);
+ uart->rx_dma_buf.head = uart->rx_dma_buf.tail = 0;
+ }
+ spin_lock(&uart->port.lock);
+ irqstat = get_dma_curr_irqstat(uart->rx_dma_channel);
+ clear_dma_irqstat(uart->rx_dma_channel);
+
+ spin_unlock(&uart->port.lock);
+ return IRQ_HANDLED;
+}
+#endif
+
+/*
+ * Return TIOCSER_TEMT when transmitter is not busy.
+ */
+static unsigned int bfin_serial_tx_empty(struct uart_port *port)
+{
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+ unsigned short lsr;
+
+ lsr = UART_GET_LSR(uart);
+ if (lsr & TEMT)
+ return TIOCSER_TEMT;
+ else
+ return 0;
+}
+
+static unsigned int bfin_serial_get_mctrl(struct uart_port *port)
+{
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+ if (uart->cts_pin < 0)
+ return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+
+ if (gpio_get_value(uart->cts_pin))
+ return TIOCM_DSR | TIOCM_CAR;
+ else
+#endif
+ return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+}
+
+static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+ if (uart->rts_pin < 0)
+ return;
+
+ if (mctrl & TIOCM_RTS)
+ gpio_set_value(uart->rts_pin, 0);
+ else
+ gpio_set_value(uart->rts_pin, 1);
+#endif
+}
+
+/*
+ * Handle any change of modem status signal since we were last called.
+ */
+static void bfin_serial_mctrl_check(struct bfin_serial_port *uart)
+{
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ unsigned int status;
+# ifdef CONFIG_SERIAL_BFIN_DMA
+ struct uart_info *info = uart->port.info;
+ struct tty_struct *tty = info->tty;
+
+ status = bfin_serial_get_mctrl(&uart->port);
+ if (!(status & TIOCM_CTS)) {
+ tty->hw_stopped = 1;
+ } else {
+ tty->hw_stopped = 0;
+ }
+# else
+ status = bfin_serial_get_mctrl(&uart->port);
+ uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
+ if (!(status & TIOCM_CTS))
+ schedule_work(&uart->cts_workqueue);
+# endif
+#endif
+}
+
+/*
+ * Interrupts are always disabled.
+ */
+static void bfin_serial_break_ctl(struct uart_port *port, int break_state)
+{
+}
+
+static int bfin_serial_startup(struct uart_port *port)
+{
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ dma_addr_t dma_handle;
+
+ if (request_dma(uart->rx_dma_channel, "BFIN_UART_RX") < 0) {
+ printk(KERN_NOTICE "Unable to attach Blackfin UART RX DMA channel\n");
+ return -EBUSY;
+ }
+
+ if (request_dma(uart->tx_dma_channel, "BFIN_UART_TX") < 0) {
+ printk(KERN_NOTICE "Unable to attach Blackfin UART TX DMA channel\n");
+ free_dma(uart->rx_dma_channel);
+ return -EBUSY;
+ }
+
+ set_dma_callback(uart->rx_dma_channel, bfin_serial_dma_rx_int, uart);
+ set_dma_callback(uart->tx_dma_channel, bfin_serial_dma_tx_int, uart);
+
+ uart->rx_dma_buf.buf = (unsigned char *)dma_alloc_coherent(NULL, PAGE_SIZE, &dma_handle, GFP_DMA);
+ uart->rx_dma_buf.head = 0;
+ uart->rx_dma_buf.tail = 0;
+ uart->rx_dma_nrows = 0;
+
+ set_dma_config(uart->rx_dma_channel,
+ set_bfin_dma_config(DIR_WRITE, DMA_FLOW_AUTO,
+ INTR_ON_ROW, DIMENSION_2D,
+ DATA_SIZE_8));
+ set_dma_x_count(uart->rx_dma_channel, DMA_RX_XCOUNT);
+ set_dma_x_modify(uart->rx_dma_channel, 1);
+ set_dma_y_count(uart->rx_dma_channel, DMA_RX_YCOUNT);
+ set_dma_y_modify(uart->rx_dma_channel, 1);
+ set_dma_start_addr(uart->rx_dma_channel, (unsigned long)uart->rx_dma_buf.buf);
+ enable_dma(uart->rx_dma_channel);
+
+ uart->rx_dma_timer.data = (unsigned long)(uart);
+ uart->rx_dma_timer.function = (void *)bfin_serial_rx_dma_timeout;
+ uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES;
+ add_timer(&(uart->rx_dma_timer));
+#else
+ if (request_irq
+ (uart->port.irq, bfin_serial_int, IRQF_DISABLED,
+ "BFIN_UART_RX", uart)) {
+ printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n");
+ return -EBUSY;
+ }
+
+ if (request_irq
+ (uart->port.irq+1, bfin_serial_int, IRQF_DISABLED,
+ "BFIN_UART_TX", uart)) {
+ printk(KERN_NOTICE "Unable to attach BlackFin UART TX interrupt\n");
+ free_irq(uart->port.irq, uart);
+ return -EBUSY;
+ }
+#endif
+ UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);
+ return 0;
+}
+
+static void bfin_serial_shutdown(struct uart_port *port)
+{
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ disable_dma(uart->tx_dma_channel);
+ free_dma(uart->tx_dma_channel);
+ disable_dma(uart->rx_dma_channel);
+ free_dma(uart->rx_dma_channel);
+ del_timer(&(uart->rx_dma_timer));
+#else
+ free_irq(uart->port.irq, uart);
+ free_irq(uart->port.irq+1, uart);
+#endif
+}
+
+static void
+bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
+ struct ktermios *old)
+{
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+ unsigned long flags;
+ unsigned int baud, quot;
+ unsigned short val, ier, lsr, lcr = 0;
+
+ switch (termios->c_cflag & CSIZE) {
+ case CS8:
+ lcr = WLS(8);
+ break;
+ case CS7:
+ lcr = WLS(7);
+ break;
+ case CS6:
+ lcr = WLS(6);
+ break;
+ case CS5:
+ lcr = WLS(5);
+ break;
+ default:
+ printk(KERN_ERR "%s: word lengh not supported\n",
+ __FUNCTION__);
+ }
+
+ if (termios->c_cflag & CSTOPB)
+ lcr |= STB;
+ if (termios->c_cflag & PARENB) {
+ lcr |= PEN;
+ if (!(termios->c_cflag & PARODD))
+ lcr |= EPS;
+ }
+
+ /* These controls are not implemented for this port */
+ termios->c_iflag |= INPCK | BRKINT | PARMRK;
+ termios->c_iflag &= ~(IGNPAR | IGNBRK);
+
+ /* These controls are not implemented for this port */
+ termios->c_iflag |= INPCK | BRKINT | PARMRK;
+ termios->c_iflag &= ~(IGNPAR | IGNBRK);
+
+ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
+ quot = uart_get_divisor(port, baud);
+ spin_lock_irqsave(&uart->port.lock, flags);
+
+ do {
+ lsr = UART_GET_LSR(uart);
+ } while (!(lsr & TEMT));
+
+ /* Disable UART */
+ ier = UART_GET_IER(uart);
+ UART_PUT_IER(uart, 0);
+
+ /* Set DLAB in LCR to Access DLL and DLH */
+ val = UART_GET_LCR(uart);
+ val |= DLAB;
+ UART_PUT_LCR(uart, val);
+ SSYNC();
+
+ UART_PUT_DLL(uart, quot & 0xFF);
+ SSYNC();
+ UART_PUT_DLH(uart, (quot >> 8) & 0xFF);
+ SSYNC();
+
+ /* Clear DLAB in LCR to Access THR RBR IER */
+ val = UART_GET_LCR(uart);
+ val &= ~DLAB;
+ UART_PUT_LCR(uart, val);
+ SSYNC();
+
+ UART_PUT_LCR(uart, lcr);
+
+ /* Enable UART */
+ UART_PUT_IER(uart, ier);
+
+ val = UART_GET_GCTL(uart);
+ val |= UCEN;
+ UART_PUT_GCTL(uart, val);
+
+ spin_unlock_irqrestore(&uart->port.lock, flags);
+}
+
+static const char *bfin_serial_type(struct uart_port *port)
+{
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+
+ return uart->port.type == PORT_BFIN ? "BFIN-UART" : NULL;
+}
+
+/*
+ * Release the memory region(s) being used by 'port'.
+ */
+static void bfin_serial_release_port(struct uart_port *port)
+{
+}
+
+/*
+ * Request the memory region(s) being used by 'port'.
+ */
+static int bfin_serial_request_port(struct uart_port *port)
+{
+ return 0;
+}
+
+/*
+ * Configure/autoconfigure the port.
+ */
+static void bfin_serial_config_port(struct uart_port *port, int flags)
+{
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+
+ if (flags & UART_CONFIG_TYPE &&
+ bfin_serial_request_port(&uart->port) == 0)
+ uart->port.type = PORT_BFIN;
+}
+
+/*
+ * Verify the new serial_struct (for TIOCSSERIAL).
+ * The only change we allow are to the flags and type, and
+ * even then only between PORT_BFIN and PORT_UNKNOWN
+ */
+static int
+bfin_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+ return 0;
+}
+
+static struct uart_ops bfin_serial_pops = {
+ .tx_empty = bfin_serial_tx_empty,
+ .set_mctrl = bfin_serial_set_mctrl,
+ .get_mctrl = bfin_serial_get_mctrl,
+ .stop_tx = bfin_serial_stop_tx,
+ .start_tx = bfin_serial_start_tx,
+ .stop_rx = bfin_serial_stop_rx,
+ .enable_ms = bfin_serial_enable_ms,
+ .break_ctl = bfin_serial_break_ctl,
+ .startup = bfin_serial_startup,
+ .shutdown = bfin_serial_shutdown,
+ .set_termios = bfin_serial_set_termios,
+ .type = bfin_serial_type,
+ .release_port = bfin_serial_release_port,
+ .request_port = bfin_serial_request_port,
+ .config_port = bfin_serial_config_port,
+ .verify_port = bfin_serial_verify_port,
+};
+
+static void __init bfin_serial_init_ports(void)
+{
+ static int first = 1;
+ int i;
+
+ if (!first)
+ return;
+ first = 0;
+
+ for (i = 0; i < nr_ports; i++) {
+ bfin_serial_ports[i].port.uartclk = get_sclk();
+ bfin_serial_ports[i].port.ops = &bfin_serial_pops;
+ bfin_serial_ports[i].port.line = i;
+ bfin_serial_ports[i].port.iotype = UPIO_MEM;
+ bfin_serial_ports[i].port.membase =
+ (void __iomem *)bfin_serial_resource[i].uart_base_addr;
+ bfin_serial_ports[i].port.mapbase =
+ bfin_serial_resource[i].uart_base_addr;
+ bfin_serial_ports[i].port.irq =
+ bfin_serial_resource[i].uart_irq;
+ bfin_serial_ports[i].port.flags = UPF_BOOT_AUTOCONF;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ bfin_serial_ports[i].tx_done = 1;
+ bfin_serial_ports[i].tx_count = 0;
+ bfin_serial_ports[i].tx_dma_channel =
+ bfin_serial_resource[i].uart_tx_dma_channel;
+ bfin_serial_ports[i].rx_dma_channel =
+ bfin_serial_resource[i].uart_rx_dma_channel;
+ init_timer(&(bfin_serial_ports[i].rx_dma_timer));
+#else
+ INIT_WORK(&bfin_serial_ports[i].cts_workqueue, bfin_serial_do_work);
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ bfin_serial_ports[i].cts_pin =
+ bfin_serial_resource[i].uart_cts_pin;
+ bfin_serial_ports[i].rts_pin =
+ bfin_serial_resource[i].uart_rts_pin;
+#endif
+ bfin_serial_hw_init(&bfin_serial_ports[i]);
+
+ }
+}
+
+#ifdef CONFIG_SERIAL_BFIN_CONSOLE
+static void bfin_serial_console_putchar(struct uart_port *port, int ch)
+{
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+ while (!(UART_GET_LSR(uart)))
+ barrier();
+ UART_PUT_CHAR(uart, ch);
+ SSYNC();
+}
+
+/*
+ * Interrupts are disabled on entering
+ */
+static void
+bfin_serial_console_write(struct console *co, const char *s, unsigned int count)
+{
+ struct bfin_serial_port *uart = &bfin_serial_ports[co->index];
+ int flags = 0;
+
+ spin_lock_irqsave(&uart->port.lock, flags);
+ uart_console_write(&uart->port, s, count, bfin_serial_console_putchar);
+ spin_unlock_irqrestore(&uart->port.lock, flags);
+
+}
+
+/*
+ * If the port was already initialised (eg, by a boot loader),
+ * try to determine the current setup.
+ */
+static void __init
+bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
+ int *parity, int *bits)
+{
+ unsigned short status;
+
+ status = UART_GET_IER(uart) & (ERBFI | ETBEI);
+ if (status == (ERBFI | ETBEI)) {
+ /* ok, the port was enabled */
+ unsigned short lcr, val;
+ unsigned short dlh, dll;
+
+ lcr = UART_GET_LCR(uart);
+
+ *parity = 'n';
+ if (lcr & PEN) {
+ if (lcr & EPS)
+ *parity = 'e';
+ else
+ *parity = 'o';
+ }
+ switch (lcr & 0x03) {
+ case 0: *bits = 5; break;
+ case 1: *bits = 6; break;
+ case 2: *bits = 7; break;
+ case 3: *bits = 8; break;
+ }
+ /* Set DLAB in LCR to Access DLL and DLH */
+ val = UART_GET_LCR(uart);
+ val |= DLAB;
+ UART_PUT_LCR(uart, val);
+
+ dll = UART_GET_DLL(uart);
+ dlh = UART_GET_DLH(uart);
+
+ /* Clear DLAB in LCR to Access THR RBR IER */
+ val = UART_GET_LCR(uart);
+ val &= ~DLAB;
+ UART_PUT_LCR(uart, val);
+
+ *baud = get_sclk() / (16*(dll | dlh << 8));
+ }
+ pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __FUNCTION__, *baud, *parity, *bits);
+}
+
+static int __init
+bfin_serial_console_setup(struct console *co, char *options)
+{
+ struct bfin_serial_port *uart;
+ int baud = 57600;
+ int bits = 8;
+ int parity = 'n';
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ int flow = 'r';
+#else
+ int flow = 'n';
+#endif
+
+ /*
+ * Check whether an invalid uart number has been specified, and
+ * if so, search for the first available port that does have
+ * console support.
+ */
+ if (co->index == -1 || co->index >= nr_ports)
+ co->index = 0;
+ uart = &bfin_serial_ports[co->index];
+
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+ else
+ bfin_serial_console_get_options(uart, &baud, &parity, &bits);
+
+ return uart_set_options(&uart->port, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver bfin_serial_reg;
+static struct console bfin_serial_console = {
+ .name = BFIN_SERIAL_NAME,
+ .write = bfin_serial_console_write,
+ .device = uart_console_device,
+ .setup = bfin_serial_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+ .data = &bfin_serial_reg,
+};
+
+static int __init bfin_serial_rs_console_init(void)
+{
+ bfin_serial_init_ports();
+ register_console(&bfin_serial_console);
+ return 0;
+}
+console_initcall(bfin_serial_rs_console_init);
+
+#define BFIN_SERIAL_CONSOLE &bfin_serial_console
+#else
+#define BFIN_SERIAL_CONSOLE NULL
+#endif
+
+static struct uart_driver bfin_serial_reg = {
+ .owner = THIS_MODULE,
+ .driver_name = "bfin-uart",
+ .dev_name = BFIN_SERIAL_NAME,
+ .major = BFIN_SERIAL_MAJOR,
+ .minor = BFIN_SERIAL_MINOR,
+ .nr = NR_PORTS,
+ .cons = BFIN_SERIAL_CONSOLE,
+};
+
+static int bfin_serial_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct bfin_serial_port *uart = platform_get_drvdata(dev);
+
+ if (uart)
+ uart_suspend_port(&bfin_serial_reg, &uart->port);
+
+ return 0;
+}
+
+static int bfin_serial_resume(struct platform_device *dev)
+{
+ struct bfin_serial_port *uart = platform_get_drvdata(dev);
+
+ if (uart)
+ uart_resume_port(&bfin_serial_reg, &uart->port);
+
+ return 0;
+}
+
+static int bfin_serial_probe(struct platform_device *dev)
+{
+ struct resource *res = dev->resource;
+ int i;
+
+ for (i = 0; i < dev->num_resources; i++, res++)
+ if (res->flags & IORESOURCE_MEM)
+ break;
+
+ if (i < dev->num_resources) {
+ for (i = 0; i < nr_ports; i++, res++) {
+ if (bfin_serial_ports[i].port.mapbase != res->start)
+ continue;
+ bfin_serial_ports[i].port.dev = &dev->dev;
+ uart_add_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port);
+ platform_set_drvdata(dev, &bfin_serial_ports[i]);
+ }
+ }
+
+ return 0;
+}
+
+static int bfin_serial_remove(struct platform_device *pdev)
+{
+ struct bfin_serial_port *uart = platform_get_drvdata(pdev);
+
+
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ gpio_free(uart->cts_pin);
+ gpio_free(uart->rts_pin);
+#endif
+
+ platform_set_drvdata(pdev, NULL);
+
+ if (uart)
+ uart_remove_one_port(&bfin_serial_reg, &uart->port);
+
+ return 0;
+}
+
+static struct platform_driver bfin_serial_driver = {
+ .probe = bfin_serial_probe,
+ .remove = bfin_serial_remove,
+ .suspend = bfin_serial_suspend,
+ .resume = bfin_serial_resume,
+ .driver = {
+ .name = "bfin-uart",
+ },
+};
+
+static int __init bfin_serial_init(void)
+{
+ int ret;
+
+ pr_info("Serial: Blackfin serial driver\n");
+
+ bfin_serial_init_ports();
+
+ ret = uart_register_driver(&bfin_serial_reg);
+ if (ret == 0) {
+ ret = platform_driver_register(&bfin_serial_driver);
+ if (ret) {
+ pr_debug("uart register failed\n");
+ uart_unregister_driver(&bfin_serial_reg);
+ }
+ }
+ return ret;
+}
+
+static void __exit bfin_serial_exit(void)
+{
+ platform_driver_unregister(&bfin_serial_driver);
+ uart_unregister_driver(&bfin_serial_reg);
+}
+
+module_init(bfin_serial_init);
+module_exit(bfin_serial_exit);
+
+MODULE_AUTHOR("Aubrey.Li <aubrey.li@analog.com>");
+MODULE_DESCRIPTION("Blackfin generic serial port driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(BFIN_SERIAL_MAJOR);
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 7a3b97f..f23972b 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -934,7 +934,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
.irq = SMC1_IRQ,
.ops = &cpm_uart_pops,
.iotype = UPIO_MEM,
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC1].port.lock),
},
.flags = FLAG_SMC,
.tx_nrfifos = TX_NUM_FIFO,
@@ -948,7 +948,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
.irq = SMC2_IRQ,
.ops = &cpm_uart_pops,
.iotype = UPIO_MEM,
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC2].port.lock),
},
.flags = FLAG_SMC,
.tx_nrfifos = TX_NUM_FIFO,
@@ -965,7 +965,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
.irq = SCC1_IRQ,
.ops = &cpm_uart_pops,
.iotype = UPIO_MEM,
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC1].port.lock),
},
.tx_nrfifos = TX_NUM_FIFO,
.tx_fifosize = TX_BUF_SIZE,
@@ -979,7 +979,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
.irq = SCC2_IRQ,
.ops = &cpm_uart_pops,
.iotype = UPIO_MEM,
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC2].port.lock),
},
.tx_nrfifos = TX_NUM_FIFO,
.tx_fifosize = TX_BUF_SIZE,
@@ -993,7 +993,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
.irq = SCC3_IRQ,
.ops = &cpm_uart_pops,
.iotype = UPIO_MEM,
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC3].port.lock),
},
.tx_nrfifos = TX_NUM_FIFO,
.tx_fifosize = TX_BUF_SIZE,
@@ -1007,7 +1007,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
.irq = SCC4_IRQ,
.ops = &cpm_uart_pops,
.iotype = UPIO_MEM,
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC4].port.lock),
},
.tx_nrfifos = TX_NUM_FIFO,
.tx_fifosize = TX_BUF_SIZE,
diff --git a/drivers/serial/crisv10.h b/drivers/serial/crisv10.h
deleted file mode 100644
index 4a23340..0000000
--- a/drivers/serial/crisv10.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * serial.h: Arch-dep definitions for the Etrax100 serial driver.
- *
- * Copyright (C) 1998, 1999, 2000 Axis Communications AB
- */
-
-#ifndef _ETRAX_SERIAL_H
-#define _ETRAX_SERIAL_H
-
-#include <linux/circ_buf.h>
-#include <asm/termios.h>
-
-/* Software state per channel */
-
-#ifdef __KERNEL__
-/*
- * This is our internal structure for each serial port's state.
- *
- * Many fields are paralleled by the structure used by the serial_struct
- * structure.
- *
- * For definitions of the flags field, see tty.h
- */
-
-#define SERIAL_RECV_DESCRIPTORS 8
-
-struct etrax_recv_buffer {
- struct etrax_recv_buffer *next;
- unsigned short length;
- unsigned char error;
- unsigned char pad;
-
- unsigned char buffer[0];
-};
-
-struct e100_serial {
- int baud;
- volatile u8 *port; /* R_SERIALx_CTRL */
- u32 irq; /* bitnr in R_IRQ_MASK2 for dmaX_descr */
-
- /* Output registers */
- volatile u8 *oclrintradr; /* adr to R_DMA_CHx_CLR_INTR */
- volatile u32 *ofirstadr; /* adr to R_DMA_CHx_FIRST */
- volatile u8 *ocmdadr; /* adr to R_DMA_CHx_CMD */
- const volatile u8 *ostatusadr; /* adr to R_DMA_CHx_STATUS */
-
- /* Input registers */
- volatile u8 *iclrintradr; /* adr to R_DMA_CHx_CLR_INTR */
- volatile u32 *ifirstadr; /* adr to R_DMA_CHx_FIRST */
- volatile u8 *icmdadr; /* adr to R_DMA_CHx_CMD */
- volatile u32 *idescradr; /* adr to R_DMA_CHx_DESCR */
-
- int flags; /* defined in tty.h */
-
- u8 rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */
- u8 tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */
- u8 iseteop; /* bit number for R_SET_EOP for the input dma */
- int enabled; /* Set to 1 if the port is enabled in HW config */
-
- u8 dma_out_enabled:1; /* Set to 1 if DMA should be used */
- u8 dma_in_enabled:1; /* Set to 1 if DMA should be used */
-
- /* end of fields defined in rs_table[] in .c-file */
- u8 uses_dma_in; /* Set to 1 if DMA is used */
- u8 uses_dma_out; /* Set to 1 if DMA is used */
- u8 forced_eop; /* a fifo eop has been forced */
- int baud_base; /* For special baudrates */
- int custom_divisor; /* For special baudrates */
- struct etrax_dma_descr tr_descr;
- struct etrax_dma_descr rec_descr[SERIAL_RECV_DESCRIPTORS];
- int cur_rec_descr;
-
- volatile int tr_running; /* 1 if output is running */
-
- struct tty_struct *tty;
- int read_status_mask;
- int ignore_status_mask;
- int x_char; /* xon/xoff character */
- int close_delay;
- unsigned short closing_wait;
- unsigned short closing_wait2;
- unsigned long event;
- unsigned long last_active;
- int line;
- int type; /* PORT_ETRAX */
- int count; /* # of fd on device */
- int blocked_open; /* # of blocked opens */
- struct circ_buf xmit;
- struct etrax_recv_buffer *first_recv_buffer;
- struct etrax_recv_buffer *last_recv_buffer;
- unsigned int recv_cnt;
- unsigned int max_recv_cnt;
-
- struct work_struct work;
- struct async_icount icount; /* error-statistics etc.*/
- struct ktermios normal_termios;
- struct ktermios callout_termios;
-#ifdef DECLARE_WAITQUEUE
- wait_queue_head_t open_wait;
- wait_queue_head_t close_wait;
-#else
- struct wait_queue *open_wait;
- struct wait_queue *close_wait;
-#endif
-
- unsigned long char_time_usec; /* The time for 1 char, in usecs */
- unsigned long flush_time_usec; /* How often we should flush */
- unsigned long last_tx_active_usec; /* Last tx usec in the jiffies */
- unsigned long last_tx_active; /* Last tx time in jiffies */
- unsigned long last_rx_active_usec; /* Last rx usec in the jiffies */
- unsigned long last_rx_active; /* Last rx time in jiffies */
-
- int break_detected_cnt;
- int errorcode;
-
-#ifdef CONFIG_ETRAX_RS485
- struct rs485_control rs485; /* RS-485 support */
-#endif
-};
-
-/* this PORT is not in the standard serial.h. it's not actually used for
- * anything since we only have one type of async serial-port anyway in this
- * system.
- */
-
-#define PORT_ETRAX 1
-
-/*
- * Events are used to schedule things to happen at timer-interrupt
- * time, instead of at rs interrupt time.
- */
-#define RS_EVENT_WRITE_WAKEUP 0
-
-#endif /* __KERNEL__ */
-
-#endif /* !_ETRAX_SERIAL_H */
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index 246c557..6202995 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -47,7 +47,6 @@
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/kobject.h>
#include <linux/firmware.h>
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 04cc88c..e42faa4 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -46,6 +46,122 @@
#include <asm/hardware.h>
#include <asm/arch/imx-uart.h>
+/* Register definitions */
+#define URXD0 0x0 /* Receiver Register */
+#define URTX0 0x40 /* Transmitter Register */
+#define UCR1 0x80 /* Control Register 1 */
+#define UCR2 0x84 /* Control Register 2 */
+#define UCR3 0x88 /* Control Register 3 */
+#define UCR4 0x8c /* Control Register 4 */
+#define UFCR 0x90 /* FIFO Control Register */
+#define USR1 0x94 /* Status Register 1 */
+#define USR2 0x98 /* Status Register 2 */
+#define UESC 0x9c /* Escape Character Register */
+#define UTIM 0xa0 /* Escape Timer Register */
+#define UBIR 0xa4 /* BRM Incremental Register */
+#define UBMR 0xa8 /* BRM Modulator Register */
+#define UBRC 0xac /* Baud Rate Count Register */
+#define BIPR1 0xb0 /* Incremental Preset Register 1 */
+#define BIPR2 0xb4 /* Incremental Preset Register 2 */
+#define BIPR3 0xb8 /* Incremental Preset Register 3 */
+#define BIPR4 0xbc /* Incremental Preset Register 4 */
+#define BMPR1 0xc0 /* BRM Modulator Register 1 */
+#define BMPR2 0xc4 /* BRM Modulator Register 2 */
+#define BMPR3 0xc8 /* BRM Modulator Register 3 */
+#define BMPR4 0xcc /* BRM Modulator Register 4 */
+#define UTS 0xd0 /* UART Test Register */
+
+/* UART Control Register Bit Fields.*/
+#define URXD_CHARRDY (1<<15)
+#define URXD_ERR (1<<14)
+#define URXD_OVRRUN (1<<13)
+#define URXD_FRMERR (1<<12)
+#define URXD_BRK (1<<11)
+#define URXD_PRERR (1<<10)
+#define UCR1_ADEN (1<<15) /* Auto dectect interrupt */
+#define UCR1_ADBR (1<<14) /* Auto detect baud rate */
+#define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */
+#define UCR1_IDEN (1<<12) /* Idle condition interrupt */
+#define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */
+#define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */
+#define UCR1_IREN (1<<7) /* Infrared interface enable */
+#define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */
+#define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */
+#define UCR1_SNDBRK (1<<4) /* Send break */
+#define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */
+#define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */
+#define UCR1_DOZE (1<<1) /* Doze */
+#define UCR1_UARTEN (1<<0) /* UART enabled */
+#define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */
+#define UCR2_IRTS (1<<14) /* Ignore RTS pin */
+#define UCR2_CTSC (1<<13) /* CTS pin control */
+#define UCR2_CTS (1<<12) /* Clear to send */
+#define UCR2_ESCEN (1<<11) /* Escape enable */
+#define UCR2_PREN (1<<8) /* Parity enable */
+#define UCR2_PROE (1<<7) /* Parity odd/even */
+#define UCR2_STPB (1<<6) /* Stop */
+#define UCR2_WS (1<<5) /* Word size */
+#define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */
+#define UCR2_TXEN (1<<2) /* Transmitter enabled */
+#define UCR2_RXEN (1<<1) /* Receiver enabled */
+#define UCR2_SRST (1<<0) /* SW reset */
+#define UCR3_DTREN (1<<13) /* DTR interrupt enable */
+#define UCR3_PARERREN (1<<12) /* Parity enable */
+#define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */
+#define UCR3_DSR (1<<10) /* Data set ready */
+#define UCR3_DCD (1<<9) /* Data carrier detect */
+#define UCR3_RI (1<<8) /* Ring indicator */
+#define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */
+#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */
+#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */
+#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
+#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */
+#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */
+#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */
+#define UCR3_BPEN (1<<0) /* Preset registers enable */
+#define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */
+#define UCR4_INVR (1<<9) /* Inverted infrared reception */
+#define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */
+#define UCR4_WKEN (1<<7) /* Wake interrupt enable */
+#define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */
+#define UCR4_IRSC (1<<5) /* IR special case */
+#define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */
+#define UCR4_BKEN (1<<2) /* Break condition interrupt enable */
+#define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */
+#define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */
+#define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */
+#define UFCR_RFDIV (7<<7) /* Reference freq divider mask */
+#define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */
+#define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */
+#define USR1_RTSS (1<<14) /* RTS pin status */
+#define USR1_TRDY (1<<13) /* Transmitter ready interrupt/dma flag */
+#define USR1_RTSD (1<<12) /* RTS delta */
+#define USR1_ESCF (1<<11) /* Escape seq interrupt flag */
+#define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */
+#define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */
+#define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */
+#define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */
+#define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */
+#define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */
+#define USR2_ADET (1<<15) /* Auto baud rate detect complete */
+#define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */
+#define USR2_DTRF (1<<13) /* DTR edge interrupt flag */
+#define USR2_IDLE (1<<12) /* Idle condition */
+#define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */
+#define USR2_WAKE (1<<7) /* Wake */
+#define USR2_RTSF (1<<4) /* RTS edge interrupt flag */
+#define USR2_TXDC (1<<3) /* Transmitter complete */
+#define USR2_BRCD (1<<2) /* Break condition */
+#define USR2_ORE (1<<1) /* Overrun error */
+#define USR2_RDR (1<<0) /* Recv data ready */
+#define UTS_FRCPERR (1<<13) /* Force parity error */
+#define UTS_LOOP (1<<12) /* Loop tx and rx */
+#define UTS_TXEMPTY (1<<6) /* TxFIFO empty */
+#define UTS_RXEMPTY (1<<5) /* RxFIFO empty */
+#define UTS_TXFULL (1<<4) /* TxFIFO full */
+#define UTS_RXFULL (1<<3) /* RxFIFO full */
+#define UTS_SOFTRST (1<<0) /* Software reset */
+
/* We've been assigned a range on the "Low-density serial ports" major */
#define SERIAL_IMX_MAJOR 204
#define MINOR_START 41
@@ -128,7 +244,10 @@ static void imx_timeout(unsigned long data)
static void imx_stop_tx(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
- UCR1((u32)sport->port.membase) &= ~UCR1_TXMPTYEN;
+ unsigned long temp;
+
+ temp = readl(sport->port.membase + UCR1);
+ writel(temp & ~UCR1_TXMPTYEN, sport->port.membase + UCR1);
}
/*
@@ -137,7 +256,10 @@ static void imx_stop_tx(struct uart_port *port)
static void imx_stop_rx(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
- UCR2((u32)sport->port.membase) &= ~UCR2_RXEN;
+ unsigned long temp;
+
+ temp = readl(sport->port.membase + UCR2);
+ writel(temp &~ UCR2_RXEN, sport->port.membase + UCR2);
}
/*
@@ -154,10 +276,10 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
{
struct circ_buf *xmit = &sport->port.info->xmit;
- while (!(UTS((u32)sport->port.membase) & UTS_TXFULL)) {
+ while (!(readl(sport->port.membase + UTS) & UTS_TXFULL)) {
/* send xmit->buf[xmit->tail]
* out the port here */
- URTX0((u32)sport->port.membase) = xmit->buf[xmit->tail];
+ writel(xmit->buf[xmit->tail], sport->port.membase + URTX0);
xmit->tail = (xmit->tail + 1) &
(UART_XMIT_SIZE - 1);
sport->port.icount.tx++;
@@ -175,21 +297,24 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
static void imx_start_tx(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
+ unsigned long temp;
- UCR1((u32)sport->port.membase) |= UCR1_TXMPTYEN;
+ temp = readl(sport->port.membase + UCR1);
+ writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1);
- imx_transmit_buffer(sport);
+ if (readl(sport->port.membase + UTS) & UTS_TXEMPTY)
+ imx_transmit_buffer(sport);
}
static irqreturn_t imx_rtsint(int irq, void *dev_id)
{
struct imx_port *sport = (struct imx_port *)dev_id;
- unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS;
+ unsigned int val = readl(sport->port.membase + USR1) & USR1_RTSS;
unsigned long flags;
spin_lock_irqsave(&sport->port.lock, flags);
- USR1((u32)sport->port.membase) = USR1_RTSD;
+ writel(USR1_RTSD, sport->port.membase + USR1);
uart_handle_cts_change(&sport->port, !!val);
wake_up_interruptible(&sport->port.info->delta_msr_wait);
@@ -207,7 +332,7 @@ static irqreturn_t imx_txint(int irq, void *dev_id)
if (sport->port.x_char)
{
/* Send next char */
- URTX0((u32)sport->port.membase) = sport->port.x_char;
+ writel(sport->port.x_char, sport->port.membase + URTX0);
goto out;
}
@@ -231,17 +356,18 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
struct imx_port *sport = dev_id;
unsigned int rx,flg,ignored = 0;
struct tty_struct *tty = sport->port.info->tty;
- unsigned long flags;
+ unsigned long flags, temp;
- rx = URXD0((u32)sport->port.membase);
+ rx = readl(sport->port.membase + URXD0);
spin_lock_irqsave(&sport->port.lock,flags);
do {
flg = TTY_NORMAL;
sport->port.icount.rx++;
- if( USR2((u32)sport->port.membase) & USR2_BRCD ) {
- USR2((u32)sport->port.membase) |= USR2_BRCD;
+ temp = readl(sport->port.membase + USR2);
+ if( temp & USR2_BRCD ) {
+ writel(temp | USR2_BRCD, sport->port.membase + USR2);
if(uart_handle_break(&sport->port))
goto ignore_char;
}
@@ -257,7 +383,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
tty_insert_flip_char(tty, rx, flg);
ignore_char:
- rx = URXD0((u32)sport->port.membase);
+ rx = readl(sport->port.membase + URXD0);
} while(rx & URXD_CHARRDY);
out:
@@ -301,7 +427,7 @@ static unsigned int imx_tx_empty(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
- return USR2((u32)sport->port.membase) & USR2_TXDC ? TIOCSER_TEMT : 0;
+ return (readl(sport->port.membase + USR2) & USR2_TXDC) ? TIOCSER_TEMT : 0;
}
/*
@@ -312,10 +438,10 @@ static unsigned int imx_get_mctrl(struct uart_port *port)
struct imx_port *sport = (struct imx_port *)port;
unsigned int tmp = TIOCM_DSR | TIOCM_CAR;
- if (USR1((u32)sport->port.membase) & USR1_RTSS)
+ if (readl(sport->port.membase + USR1) & USR1_RTSS)
tmp |= TIOCM_CTS;
- if (UCR2((u32)sport->port.membase) & UCR2_CTS)
+ if (readl(sport->port.membase + UCR2) & UCR2_CTS)
tmp |= TIOCM_RTS;
return tmp;
@@ -324,11 +450,14 @@ static unsigned int imx_get_mctrl(struct uart_port *port)
static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
struct imx_port *sport = (struct imx_port *)port;
+ unsigned long temp;
+
+ temp = readl(sport->port.membase + UCR2) & ~UCR2_CTS;
if (mctrl & TIOCM_RTS)
- UCR2((u32)sport->port.membase) |= UCR2_CTS;
- else
- UCR2((u32)sport->port.membase) &= ~UCR2_CTS;
+ temp |= UCR2_CTS;
+
+ writel(temp, sport->port.membase + UCR2);
}
/*
@@ -337,14 +466,16 @@ static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl)
static void imx_break_ctl(struct uart_port *port, int break_state)
{
struct imx_port *sport = (struct imx_port *)port;
- unsigned long flags;
+ unsigned long flags, temp;
spin_lock_irqsave(&sport->port.lock, flags);
+ temp = readl(sport->port.membase + UCR1) & ~UCR1_SNDBRK;
+
if ( break_state != 0 )
- UCR1((u32)sport->port.membase) |= UCR1_SNDBRK;
- else
- UCR1((u32)sport->port.membase) &= ~UCR1_SNDBRK;
+ temp |= UCR1_SNDBRK;
+
+ writel(temp, sport->port.membase + UCR1);
spin_unlock_irqrestore(&sport->port.lock, flags);
}
@@ -360,7 +491,7 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
/* set receiver / transmitter trigger level.
* RFDIV is set such way to satisfy requested uartclk value
*/
- val = TXTL<<10 | RXTL;
+ val = TXTL << 10 | RXTL;
ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk;
if(!ufcr_rfdiv)
@@ -373,7 +504,7 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
val |= UFCR_RFDIV & (ufcr_rfdiv << 7);
- UFCR((u32)sport->port.membase) = val;
+ writel(val, sport->port.membase + UFCR);
return 0;
}
@@ -382,14 +513,15 @@ static int imx_startup(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
int retval;
- unsigned long flags;
+ unsigned long flags, temp;
imx_setup_ufcr(sport, 0);
/* disable the DREN bit (Data Ready interrupt enable) before
* requesting IRQs
*/
- UCR4((u32)sport->port.membase) &= ~UCR4_DREN;
+ temp = readl(sport->port.membase + UCR4);
+ writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
/*
* Allocate the IRQ
@@ -411,12 +543,16 @@ static int imx_startup(struct uart_port *port)
/*
* Finally, clear and enable interrupts
*/
+ writel(USR1_RTSD, sport->port.membase + USR1);
+
+ temp = readl(sport->port.membase + UCR1);
+ temp |= (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
+ writel(temp, sport->port.membase + UCR1);
- USR1((u32)sport->port.membase) = USR1_RTSD;
- UCR1((u32)sport->port.membase) |=
- (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
+ temp = readl(sport->port.membase + UCR2);
+ temp |= (UCR2_RXEN | UCR2_TXEN);
+ writel(temp, sport->port.membase + UCR2);
- UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN);
/*
* Enable modem status interrupts
*/
@@ -437,6 +573,7 @@ error_out1:
static void imx_shutdown(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
+ unsigned long temp;
/*
* Stop our timer.
@@ -454,8 +591,9 @@ static void imx_shutdown(struct uart_port *port)
* Disable all interrupts, port and break condition.
*/
- UCR1((u32)sport->port.membase) &=
- ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
+ temp = readl(sport->port.membase + UCR1);
+ temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
+ writel(temp, sport->port.membase + UCR1);
}
static void
@@ -548,18 +686,18 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
/*
* disable interrupts and drain transmitter
*/
- old_ucr1 = UCR1((u32)sport->port.membase);
- UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
+ old_ucr1 = readl(sport->port.membase + UCR1);
+ writel(old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN),
+ sport->port.membase + UCR1);
- while ( !(USR2((u32)sport->port.membase) & USR2_TXDC))
+ while ( !(readl(sport->port.membase + USR2) & USR2_TXDC))
barrier();
/* then, disable everything */
- old_txrxen = UCR2((u32)sport->port.membase) & ( UCR2_TXEN | UCR2_RXEN );
- UCR2((u32)sport->port.membase) &= ~( UCR2_TXEN | UCR2_RXEN);
-
- /* set the parity, stop bits and data size */
- UCR2((u32)sport->port.membase) = ucr2;
+ old_txrxen = readl(sport->port.membase + UCR2);
+ writel(old_txrxen & ~( UCR2_TXEN | UCR2_RXEN),
+ sport->port.membase + UCR2);
+ old_txrxen &= (UCR2_TXEN | UCR2_RXEN);
/* set the baud rate. We assume uartclk = 16 MHz
*
@@ -567,11 +705,13 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
* --------- = --------
* uartclk UBMR - 1
*/
- UBIR((u32)sport->port.membase) = (baud / 100) - 1;
- UBMR((u32)sport->port.membase) = 10000 - 1;
+ writel((baud / 100) - 1, sport->port.membase + UBIR);
+ writel(10000 - 1, sport->port.membase + UBMR);
+
+ writel(old_ucr1, sport->port.membase + UCR1);
- UCR1((u32)sport->port.membase) = old_ucr1;
- UCR2((u32)sport->port.membase) |= old_txrxen;
+ /* set the parity, stop bits and data size */
+ writel(ucr2 | old_txrxen, sport->port.membase + UCR2);
if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
imx_enable_ms(&sport->port);
@@ -730,9 +870,11 @@ static void __init imx_init_ports(void)
static void imx_console_putchar(struct uart_port *port, int ch)
{
struct imx_port *sport = (struct imx_port *)port;
- while ((UTS((u32)sport->port.membase) & UTS_TXFULL))
+
+ while (readl(sport->port.membase + UTS) & UTS_TXFULL)
barrier();
- URTX0((u32)sport->port.membase) = ch;
+
+ writel(ch, sport->port.membase + URTX0);
}
/*
@@ -747,13 +889,14 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
/*
* First, save UCR1/2 and then disable interrupts
*/
- old_ucr1 = UCR1((u32)sport->port.membase);
- old_ucr2 = UCR2((u32)sport->port.membase);
+ old_ucr1 = readl(sport->port.membase + UCR1);
+ old_ucr2 = readl(sport->port.membase + UCR2);
- UCR1((u32)sport->port.membase) =
- (old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN)
- & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
- UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN;
+ writel((old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN) &
+ ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN),
+ sport->port.membase + UCR1);
+
+ writel(old_ucr2 | UCR2_TXEN, sport->port.membase + UCR2);
uart_console_write(&sport->port, s, count, imx_console_putchar);
@@ -761,10 +904,10 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
* Finally, wait for transmitter to become empty
* and restore UCR1/2
*/
- while (!(USR2((u32)sport->port.membase) & USR2_TXDC));
+ while (!(readl(sport->port.membase + USR2) & USR2_TXDC));
- UCR1((u32)sport->port.membase) = old_ucr1;
- UCR2((u32)sport->port.membase) = old_ucr2;
+ writel(old_ucr1, sport->port.membase + UCR1);
+ writel(old_ucr2, sport->port.membase + UCR2);
}
/*
@@ -776,13 +919,13 @@ imx_console_get_options(struct imx_port *sport, int *baud,
int *parity, int *bits)
{
- if ( UCR1((u32)sport->port.membase) | UCR1_UARTEN ) {
+ if ( readl(sport->port.membase + UCR1) | UCR1_UARTEN ) {
/* ok, the port was enabled */
unsigned int ucr2, ubir,ubmr, uartclk;
unsigned int baud_raw;
unsigned int ucfr_rfdiv;
- ucr2 = UCR2((u32)sport->port.membase);
+ ucr2 = readl(sport->port.membase + UCR2);
*parity = 'n';
if (ucr2 & UCR2_PREN) {
@@ -797,11 +940,10 @@ imx_console_get_options(struct imx_port *sport, int *baud,
else
*bits = 7;
- ubir = UBIR((u32)sport->port.membase) & 0xffff;
- ubmr = UBMR((u32)sport->port.membase) & 0xffff;
-
+ ubir = readl(sport->port.membase + UBIR) & 0xffff;
+ ubmr = readl(sport->port.membase + UBMR) & 0xffff;
- ucfr_rfdiv = (UFCR((u32)sport->port.membase) & UFCR_RFDIV) >> 7;
+ ucfr_rfdiv = (readl(sport->port.membase + UFCR) & UFCR_RFDIV) >> 7;
if (ucfr_rfdiv == 6)
ucfr_rfdiv = 7;
else
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index 8be8da3..b2d6f5b 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -581,8 +581,13 @@ static void neo_parse_modem(struct jsm_channel *ch, u8 signals)
return;
/* Scrub off lower bits. They signify delta's, which I don't care about */
- msignals &= 0xf0;
+ /* Keep DDCD and DDSR though */
+ msignals &= 0xf8;
+ if (msignals & UART_MSR_DDCD)
+ uart_handle_dcd_change(&ch->uart_port, msignals & UART_MSR_DCD);
+ if (msignals & UART_MSR_DDSR)
+ uart_handle_cts_change(&ch->uart_port, msignals & UART_MSR_CTS);
if (msignals & UART_MSR_DCD)
ch->ch_mistat |= UART_MSR_DCD;
else
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index be22bbd..281f23a 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -448,6 +448,7 @@ int jsm_uart_port_init(struct jsm_board *brd)
continue;
brd->channels[i]->uart_port.irq = brd->irq;
+ brd->channels[i]->uart_port.uartclk = 14745600;
brd->channels[i]->uart_port.type = PORT_JSM;
brd->channels[i]->uart_port.iotype = UPIO_MEM;
brd->channels[i]->uart_port.membase = brd->re_map_membase;
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 8d24cd5..35f8b86 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -257,9 +257,10 @@ mpc52xx_uart_shutdown(struct uart_port *port)
{
struct mpc52xx_psc __iomem *psc = PSC(port);
- /* Shut down the port, interrupt and all */
+ /* Shut down the port. Leave TX active if on a console port */
out_8(&psc->command,MPC52xx_PSC_RST_RX);
- out_8(&psc->command,MPC52xx_PSC_RST_TX);
+ if (!uart_console(port))
+ out_8(&psc->command,MPC52xx_PSC_RST_TX);
port->read_status_mask = 0;
out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask);
@@ -1069,7 +1070,7 @@ mpc52xx_uart_of_enumerate(void)
continue;
/* Is a particular device number requested? */
- devno = get_property(np, "port-number", NULL);
+ devno = of_get_property(np, "port-number", NULL);
mpc52xx_uart_of_assign(of_node_get(np), devno ? *devno : -1);
}
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index 3d2fcc5..d09f209 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -183,6 +183,7 @@ struct mpsc_port_info {
u8 *txb_p; /* Phys addr of txb */
int txr_head; /* Where new data goes */
int txr_tail; /* Where sent data comes off */
+ spinlock_t tx_lock; /* transmit lock */
/* Mirrored values of regs we can't read (if 'mirror_regs' set) */
u32 MPSC_MPCR_m;
@@ -1212,6 +1213,9 @@ mpsc_tx_intr(struct mpsc_port_info *pi)
{
struct mpsc_tx_desc *txre;
int rc = 0;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&pi->tx_lock, iflags);
if (!mpsc_sdma_tx_active(pi)) {
txre = (struct mpsc_tx_desc *)(pi->txr +
@@ -1248,6 +1252,7 @@ mpsc_tx_intr(struct mpsc_port_info *pi)
mpsc_sdma_start_tx(pi); /* start next desc if ready */
}
+ spin_unlock_irqrestore(&pi->tx_lock, iflags);
return rc;
}
@@ -1338,11 +1343,16 @@ static void
mpsc_start_tx(struct uart_port *port)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&pi->tx_lock, iflags);
mpsc_unfreeze(pi);
mpsc_copy_tx_data(pi);
mpsc_sdma_start_tx(pi);
+ spin_unlock_irqrestore(&pi->tx_lock, iflags);
+
pr_debug("mpsc_start_tx[%d]\n", port->line);
return;
}
@@ -1625,6 +1635,16 @@ mpsc_console_write(struct console *co, const char *s, uint count)
struct mpsc_port_info *pi = &mpsc_ports[co->index];
u8 *bp, *dp, add_cr = 0;
int i;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&pi->tx_lock, iflags);
+
+ while (pi->txr_head != pi->txr_tail) {
+ while (mpsc_sdma_tx_active(pi))
+ udelay(100);
+ mpsc_sdma_intr_ack(pi);
+ mpsc_tx_intr(pi);
+ }
while (mpsc_sdma_tx_active(pi))
udelay(100);
@@ -1668,6 +1688,7 @@ mpsc_console_write(struct console *co, const char *s, uint count)
pi->txr_tail = (pi->txr_tail + 1) & (MPSC_TXR_ENTRIES - 1);
}
+ spin_unlock_irqrestore(&pi->tx_lock, iflags);
return;
}
@@ -2005,7 +2026,8 @@ mpsc_drv_probe(struct platform_device *dev)
if (!(rc = mpsc_drv_map_regs(pi, dev))) {
mpsc_drv_get_platform_data(pi, dev, dev->id);
- if (!(rc = mpsc_make_ready(pi)))
+ if (!(rc = mpsc_make_ready(pi))) {
+ spin_lock_init(&pi->tx_lock);
if (!(rc = uart_add_one_port(&mpsc_reg,
&pi->port)))
rc = 0;
@@ -2014,6 +2036,7 @@ mpsc_drv_probe(struct platform_device *dev)
(struct uart_port *)pi);
mpsc_drv_unmap_regs(pi);
}
+ }
else
mpsc_drv_unmap_regs(pi);
}
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c
index 09b0b73..7ffdaea 100644
--- a/drivers/serial/of_serial.c
+++ b/drivers/serial/of_serial.c
@@ -29,8 +29,8 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev,
int ret;
memset(port, 0, sizeof *port);
- spd = get_property(np, "current-speed", NULL);
- clk = get_property(np, "clock-frequency", NULL);
+ spd = of_get_property(np, "current-speed", NULL);
+ clk = of_get_property(np, "clock-frequency", NULL);
if (!clk) {
dev_warn(&ofdev->dev, "no clock-frequency property set\n");
return -ENODEV;
@@ -48,7 +48,8 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev,
port->iotype = UPIO_MEM;
port->type = type;
port->uartclk = *clk;
- port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP;
+ port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP
+ | UPF_FIXED_PORT;
port->dev = &ofdev->dev;
port->custom_divisor = *clk / (16 * (*spd));
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index be8d757..0fa9f67 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -1450,14 +1450,14 @@ no_dma:
/*
* Detect port type
*/
- if (device_is_compatible(np, "cobalt"))
+ if (of_device_is_compatible(np, "cobalt"))
uap->flags |= PMACZILOG_FLAG_IS_INTMODEM;
- conn = get_property(np, "AAPL,connector", &len);
+ conn = of_get_property(np, "AAPL,connector", &len);
if (conn && (strcmp(conn, "infrared") == 0))
uap->flags |= PMACZILOG_FLAG_IS_IRDA;
uap->port_type = PMAC_SCC_ASYNC;
/* 1999 Powerbook G3 has slot-names property instead */
- slots = get_property(np, "slot-names", &len);
+ slots = of_get_property(np, "slot-names", &len);
if (slots && slots->count > 0) {
if (strcmp(slots->name, "IrDA") == 0)
uap->flags |= PMACZILOG_FLAG_IS_IRDA;
@@ -1471,7 +1471,7 @@ no_dma:
of_find_node_by_name(NULL, "i2c-modem");
if (i2c_modem) {
const char* mid =
- get_property(i2c_modem, "modem-id", NULL);
+ of_get_property(i2c_modem, "modem-id", NULL);
if (mid) switch(*mid) {
case 0x04 :
case 0x05 :
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index d403aaa..e9c6cb3 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -717,7 +717,7 @@ struct uart_ops serial_pxa_pops = {
static struct uart_pxa_port serial_pxa_ports[] = {
{ /* FFUART */
.name = "FFUART",
- .cken = CKEN6_FFUART,
+ .cken = CKEN_FFUART,
.port = {
.type = PORT_PXA,
.iotype = UPIO_MEM,
@@ -731,7 +731,7 @@ static struct uart_pxa_port serial_pxa_ports[] = {
},
}, { /* BTUART */
.name = "BTUART",
- .cken = CKEN7_BTUART,
+ .cken = CKEN_BTUART,
.port = {
.type = PORT_PXA,
.iotype = UPIO_MEM,
@@ -745,7 +745,7 @@ static struct uart_pxa_port serial_pxa_ports[] = {
},
}, { /* STUART */
.name = "STUART",
- .cken = CKEN5_STUART,
+ .cken = CKEN_STUART,
.port = {
.type = PORT_PXA,
.iotype = UPIO_MEM,
@@ -759,7 +759,7 @@ static struct uart_pxa_port serial_pxa_ports[] = {
},
}, { /* HWUART */
.name = "HWUART",
- .cken = CKEN4_HWUART,
+ .cken = CKEN_HWUART,
.port = {
.type = PORT_PXA,
.iotype = UPIO_MEM,
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 3ba9208..10bc020 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -957,7 +957,7 @@ static struct uart_driver s3c24xx_uart_drv = {
static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = {
[0] = {
.port = {
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),
.iotype = UPIO_MEM,
.irq = IRQ_S3CUART_RX0,
.uartclk = 0,
@@ -969,7 +969,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = {
},
[1] = {
.port = {
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock),
.iotype = UPIO_MEM,
.irq = IRQ_S3CUART_RX1,
.uartclk = 0,
@@ -983,7 +983,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = {
[2] = {
.port = {
- .lock = SPIN_LOCK_UNLOCKED,
+ .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock),
.iotype = UPIO_MEM,
.irq = IRQ_S3CUART_RX2,
.uartclk = 0,
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 0422c0f..326020f 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -37,13 +37,6 @@
#include <asm/irq.h>
#include <asm/uaccess.h>
-#undef DEBUG
-#ifdef DEBUG
-#define DPRINTK(x...) printk(x)
-#else
-#define DPRINTK(x...) do { } while (0)
-#endif
-
/*
* This is used to lock changes in serial line configuration.
*/
@@ -552,7 +545,7 @@ static void uart_flush_buffer(struct tty_struct *tty)
return;
}
- DPRINTK("uart_flush_buffer(%d) called\n", tty->index);
+ pr_debug("uart_flush_buffer(%d) called\n", tty->index);
spin_lock_irqsave(&port->lock, flags);
uart_circ_clear(&state->info->xmit);
@@ -672,19 +665,21 @@ static int uart_set_info(struct uart_state *state,
*/
mutex_lock(&state->mutex);
- change_irq = new_serial.irq != port->irq;
+ change_irq = !(port->flags & UPF_FIXED_PORT)
+ && new_serial.irq != port->irq;
/*
* Since changing the 'type' of the port changes its resource
* allocations, we should treat type changes the same as
* IO port changes.
*/
- change_port = new_port != port->iobase ||
- (unsigned long)new_serial.iomem_base != port->mapbase ||
- new_serial.hub6 != port->hub6 ||
- new_serial.io_type != port->iotype ||
- new_serial.iomem_reg_shift != port->regshift ||
- new_serial.type != port->type;
+ change_port = !(port->flags & UPF_FIXED_PORT)
+ && (new_port != port->iobase ||
+ (unsigned long)new_serial.iomem_base != port->mapbase ||
+ new_serial.hub6 != port->hub6 ||
+ new_serial.io_type != port->iotype ||
+ new_serial.iomem_reg_shift != port->regshift ||
+ new_serial.type != port->type);
old_flags = port->flags;
new_flags = new_serial.flags;
@@ -796,8 +791,10 @@ static int uart_set_info(struct uart_state *state,
}
}
- port->irq = new_serial.irq;
- port->uartclk = new_serial.baud_base * 16;
+ if (change_irq)
+ port->irq = new_serial.irq;
+ if (!(port->flags & UPF_FIXED_PORT))
+ port->uartclk = new_serial.baud_base * 16;
port->flags = (port->flags & ~UPF_CHANGE_MASK) |
(new_flags & UPF_CHANGE_MASK);
port->custom_divisor = new_serial.custom_divisor;
@@ -1220,7 +1217,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
port = state->port;
- DPRINTK("uart_close(%d) called\n", port->line);
+ pr_debug("uart_close(%d) called\n", port->line);
mutex_lock(&state->mutex);
@@ -1339,7 +1336,7 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
expire = jiffies + timeout;
- DPRINTK("uart_wait_until_sent(%d), jiffies=%lu, expire=%lu...\n",
+ pr_debug("uart_wait_until_sent(%d), jiffies=%lu, expire=%lu...\n",
port->line, jiffies, expire);
/*
@@ -1368,7 +1365,7 @@ static void uart_hangup(struct tty_struct *tty)
struct uart_state *state = tty->driver_data;
BUG_ON(!kernel_locked());
- DPRINTK("uart_hangup(%d)\n", state->port->line);
+ pr_debug("uart_hangup(%d)\n", state->port->line);
mutex_lock(&state->mutex);
if (state->info && state->info->flags & UIF_NORMAL_ACTIVE) {
@@ -1566,7 +1563,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
int retval, line = tty->index;
BUG_ON(!kernel_locked());
- DPRINTK("uart_open(%d) called\n", line);
+ pr_debug("uart_open(%d) called\n", line);
/*
* tty->driver->num won't change, so we won't fail here with
@@ -2064,6 +2061,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
case UPIO_MEM32:
case UPIO_AU:
case UPIO_TSI:
+ case UPIO_DWAPB:
snprintf(address, sizeof(address),
"MMIO 0x%lx", port->mapbase);
break;
@@ -2409,6 +2407,7 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2)
case UPIO_MEM32:
case UPIO_AU:
case UPIO_TSI:
+ case UPIO_DWAPB:
return (port1->mapbase == port2->mapbase);
}
return 0;
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 509ace7..1deb576 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -15,31 +15,6 @@
* published by the Free Software Foundation.
*
* Serial driver for TX3927/TX4927/TX4925/TX4938 internal SIO controller
- *
- * Revision History:
- * 0.30 Initial revision. (Renamed from serial_txx927.c)
- * 0.31 Use save_flags instead of local_irq_save.
- * 0.32 Support SCLK.
- * 0.33 Switch TXX9_TTY_NAME by CONFIG_SERIAL_TXX9_STDSERIAL.
- * Support TIOCSERGETLSR.
- * 0.34 Support slow baudrate.
- * 0.40 Merge codes from mainstream kernel (2.4.22).
- * 0.41 Fix console checking in rs_shutdown_port().
- * Disable flow-control in serial_console_write().
- * 0.42 Fix minor compiler warning.
- * 1.00 Kernel 2.6. Converted to new serial core (based on 8250.c).
- * 1.01 Set fifosize to make tx_empry called properly.
- * Use standard uart_get_divisor.
- * 1.02 Cleanup. (import 8250.c changes)
- * 1.03 Fix low-latency mode. (import 8250.c changes)
- * 1.04 Remove usage of deprecated functions, cleanup.
- * 1.05 More strict check in verify_port. Cleanup.
- * 1.06 Do not insert a char caused previous overrun.
- * Fix some spin_locks.
- * Do not call uart_add_one_port for absent ports.
- * 1.07 Use CONFIG_SERIAL_TXX9_NR_UARTS. Cleanup.
- * 1.08 Use platform_device.
- * Fix and cleanup suspend/resume/initialization codes.
*/
#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -62,7 +37,7 @@
#include <asm/io.h>
-static char *serial_version = "1.08";
+static char *serial_version = "1.09";
static char *serial_name = "TX39/49 Serial driver";
#define PASS_LIMIT 256
@@ -70,13 +45,14 @@ static char *serial_name = "TX39/49 Serial driver";
#if !defined(CONFIG_SERIAL_TXX9_STDSERIAL)
/* "ttyS" is used for standard serial driver */
#define TXX9_TTY_NAME "ttyTX"
-#define TXX9_TTY_MINOR_START (64 + 64) /* ttyTX0(128), ttyTX1(129) */
+#define TXX9_TTY_MINOR_START 196
+#define TXX9_TTY_MAJOR 204
#else
/* acts like standard serial driver */
#define TXX9_TTY_NAME "ttyS"
#define TXX9_TTY_MINOR_START 64
-#endif
#define TXX9_TTY_MAJOR TTY_MAJOR
+#endif
/* flag aliases */
#define UPF_TXX9_HAVE_CTS_LINE UPF_BUGGY_UART
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 46c40bb..1f89496 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -46,6 +46,7 @@
#endif
#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+#include <linux/ctype.h>
#include <asm/clock.h>
#include <asm/sh_bios.h>
#include <asm/kgdb.h>
@@ -61,7 +62,7 @@ struct sci_port {
unsigned int type;
/* Port IRQs: ERI, RXI, TXI, BRI (optional) */
- unsigned int irqs[SCIx_NR_IRQS];
+ unsigned int irqs[SCIx_NR_IRQS];
/* Port pin configuration */
void (*init_pins)(struct uart_port *port,
@@ -76,6 +77,11 @@ struct sci_port {
/* Break timer */
struct timer_list break_timer;
int break_flag;
+
+#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+ /* Port clock */
+ struct clk *clk;
+#endif
};
#ifdef CONFIG_SH_KGDB
@@ -163,7 +169,7 @@ static void put_string(struct sci_port *sci_port, const char *buffer, int count)
usegdb |= sh_bios_in_gdb_mode();
#endif
#ifdef CONFIG_SH_KGDB
- usegdb |= (kgdb_in_gdb_mode && (port == kgdb_sci_port));
+ usegdb |= (kgdb_in_gdb_mode && (sci_port == kgdb_sci_port));
#endif
if (usegdb) {
@@ -204,7 +210,7 @@ static int kgdb_sci_getchar(void)
int c;
/* Keep trying to read a character, this could be neater */
- while ((c = get_char(kgdb_sci_port)) < 0)
+ while ((c = get_char(&kgdb_sci_port->port)) < 0)
cpu_relax();
return c;
@@ -212,7 +218,7 @@ static int kgdb_sci_getchar(void)
static inline void kgdb_sci_putchar(int c)
{
- put_char(kgdb_sci_port, c);
+ put_char(&kgdb_sci_port->port, c);
}
#endif /* CONFIG_SH_KGDB */
@@ -283,12 +289,23 @@ static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag)
#endif
#if defined(SCIF_ONLY) || defined(SCI_AND_SCIF)
-#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7710)
+#if defined(CONFIG_CPU_SUBTYPE_SH7300)
/* SH7300 doesn't use RTS/CTS */
static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
{
sci_out(port, SCFCR, 0);
}
+#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
+static void sci_init_pins_scif(struct uart_port* port, unsigned int cflag)
+{
+ unsigned int fcr_val = 0;
+
+ set_sh771x_scif_pfc(port);
+ if (cflag & CRTSCTS) {
+ fcr_val |= SCFCR_MCE;
+ }
+ sci_out(port, SCFCR, fcr_val);
+}
#elif defined(CONFIG_CPU_SH3)
/* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */
static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
@@ -350,7 +367,7 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
} else {
#ifdef CONFIG_CPU_SUBTYPE_SH7343
/* Nothing */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785)
ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */
#else
ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */
@@ -360,7 +377,9 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
}
#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780)
+#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7785)
static inline int scif_txroom(struct uart_port *port)
{
return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0x7f);
@@ -735,12 +754,6 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr)
/* Handle BREAKs */
sci_handle_breaks(port);
-
-#ifdef CONFIG_SH_KGDB
- /* Break into the debugger if a break is detected */
- BREAKPOINT();
-#endif
-
sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
return IRQ_HANDLED;
@@ -947,6 +960,10 @@ static int sci_startup(struct uart_port *port)
if (s->enable)
s->enable(port);
+#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+ s->clk = clk_get(NULL, "module_clk");
+#endif
+
sci_request_irq(s);
sci_start_tx(port);
sci_start_rx(port, 1);
@@ -964,6 +981,11 @@ static void sci_shutdown(struct uart_port *port)
if (s->disable)
s->disable(port);
+
+#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+ clk_put(s->clk);
+ s->clk = NULL;
+#endif
}
static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
@@ -971,7 +993,6 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
{
struct sci_port *s = &sci_ports[port->line];
unsigned int status, baud, smr_val;
- unsigned long flags;
int t;
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
@@ -983,18 +1004,14 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
default:
{
#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
- struct clk *clk = clk_get(NULL, "module_clk");
- t = SCBRR_VALUE(baud, clk_get_rate(clk));
- clk_put(clk);
+ t = SCBRR_VALUE(baud, clk_get_rate(s->clk));
#else
t = SCBRR_VALUE(baud);
#endif
- }
break;
+ }
}
- spin_lock_irqsave(&port->lock, flags);
-
do {
status = sci_in(port, SCxSR);
} while (!(status & SCxSR_TEND(port)));
@@ -1038,8 +1055,6 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
if ((termios->c_cflag & CREAD) != 0)
sci_start_rx(port,0);
-
- spin_unlock_irqrestore(&port->lock, flags);
}
static const char *sci_type(struct uart_port *port)
@@ -1220,10 +1235,13 @@ static int __init serial_console_setup(struct console *co, char *options)
if (!port->membase || !port->mapbase)
return -ENODEV;
- spin_lock_init(&port->lock);
-
port->type = serial_console_port->type;
+#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+ if (!serial_console_port->clk)
+ serial_console_port->clk = clk_get(NULL, "module_clk");
+#endif
+
if (port->flags & UPF_IOREMAP)
sci_config_port(port, 0);
@@ -1247,7 +1265,7 @@ static struct console serial_console = {
.device = uart_console_device,
.write = serial_console_write,
.setup = serial_console_setup,
- .flags = CON_PRINTBUFFER,
+ .flags = CON_PRINTBUFFER,
.index = -1,
.data = &sci_uart_driver,
};
@@ -1292,11 +1310,23 @@ int __init kgdb_console_setup(struct console *co, char *options)
int parity = 'n';
int flow = 'n';
- spin_lock_init(&port->lock);
-
if (co->index != kgdb_portnum)
co->index = kgdb_portnum;
+ kgdb_sci_port = &sci_ports[co->index];
+ port = &kgdb_sci_port->port;
+
+ /*
+ * Also need to check port->type, we don't actually have any
+ * UPIO_PORT ports, but uart_report_port() handily misreports
+ * it anyways if we don't have a port available by the time this is
+ * called.
+ */
+ if (!port->type)
+ return -ENODEV;
+ if (!port->membase || !port->mapbase)
+ return -ENODEV;
+
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
else
@@ -1311,11 +1341,12 @@ int __init kgdb_console_setup(struct console *co, char *options)
#ifdef CONFIG_SH_KGDB_CONSOLE
static struct console kgdb_console = {
- .name = "ttySC",
- .write = kgdb_console_write,
- .setup = kgdb_console_setup,
- .flags = CON_PRINTBUFFER | CON_ENABLED,
- .index = -1,
+ .name = "ttySC",
+ .device = uart_console_device,
+ .write = kgdb_console_write,
+ .setup = kgdb_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
.data = &sci_uart_driver,
};
@@ -1361,9 +1392,19 @@ static int __devinit sci_probe(struct platform_device *dev)
struct plat_sci_port *p = dev->dev.platform_data;
int i;
- for (i = 0; p && p->flags != 0 && i < SCI_NPORTS; p++, i++) {
+ for (i = 0; p && p->flags != 0; p++, i++) {
struct sci_port *sciport = &sci_ports[i];
+ /* Sanity check */
+ if (unlikely(i == SCI_NPORTS)) {
+ dev_notice(&dev->dev, "Attempting to register port "
+ "%d when only %d are available.\n",
+ i+1, SCI_NPORTS);
+ dev_notice(&dev->dev, "Consider bumping "
+ "CONFIG_SERIAL_SH_SCI_NR_UARTS!\n");
+ break;
+ }
+
sciport->port.mapbase = p->mapbase;
/*
@@ -1386,6 +1427,12 @@ static int __devinit sci_probe(struct platform_device *dev)
uart_add_one_port(&sci_uart_driver, &sciport->port);
}
+#if defined(CONFIG_SH_KGDB) && !defined(CONFIG_SH_KGDB_CONSOLE)
+ kgdb_sci_port = &sci_ports[kgdb_portnum];
+ kgdb_getchar = kgdb_sci_getchar;
+ kgdb_putchar = kgdb_sci_putchar;
+#endif
+
#ifdef CONFIG_CPU_FREQ
cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER);
dev_info(&dev->dev, "sci: CPU frequency notifier registered\n");
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 77f7d63..fb04fb5 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -73,9 +73,13 @@
# define SCPDR 0xA4050136 /* 16 bit SCIF */
# define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */
# define SCIF_ONLY
-#elif defined(CONFIG_CPU_SUBTYPE_SH7710)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
# define SCSPTR0 0xA4400000 /* 16 bit SCIF */
-# define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */
+# define SCI_NPORTS 2
+# define SCIF_ORER 0x0001 /* overrun error bit */
+# define PACR 0xa4050100
+# define PBCR 0xa4050102
+# define SCSCR_INIT(port) 0x3B
# define SCIF_ONLY
#elif defined(CONFIG_CPU_SUBTYPE_SH73180)
# define SCPDR 0xA4050138 /* 16 bit SCIF */
@@ -140,6 +144,16 @@
# define SCIF_ORER 0x0001 /* Overrun error bit */
# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
# define SCIF_ONLY
+#elif defined(CONFIG_CPU_SUBTYPE_SH7785)
+# define SCSPTR0 0xffea0024 /* 16 bit SCIF */
+# define SCSPTR1 0xffeb0024 /* 16 bit SCIF */
+# define SCSPTR2 0xffec0024 /* 16 bit SCIF */
+# define SCSPTR3 0xffed0024 /* 16 bit SCIF */
+# define SCSPTR4 0xffee0024 /* 16 bit SCIF */
+# define SCSPTR5 0xffef0024 /* 16 bit SCIF */
+# define SCIF_OPER 0x0001 /* Overrun error bit */
+# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+# define SCIF_ONLY
#elif defined(CONFIG_CPU_SUBTYPE_SH7206)
# define SCSPTR0 0xfffe8020 /* 16 bit SCIF */
# define SCSPTR1 0xfffe8820 /* 16 bit SCIF */
@@ -163,7 +177,10 @@
#define SCI_CTRL_FLAGS_RIE 0x40 /* all */
#define SCI_CTRL_FLAGS_TE 0x20 /* all */
#define SCI_CTRL_FLAGS_RE 0x10 /* all */
-#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7780)
+#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7751) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7785)
#define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */
#else
#define SCI_CTRL_FLAGS_REIE 0
@@ -333,9 +350,15 @@
}
#ifdef CONFIG_CPU_SH3
-#if defined(CONFIG_CPU_SUBTYPE_SH7300) || \
- defined(CONFIG_CPU_SUBTYPE_SH7705) || \
- defined(CONFIG_CPU_SUBTYPE_SH7710)
+#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
+#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \
+ sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \
+ h8_sci_offset, h8_sci_size) \
+ CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size)
+#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \
+ CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7300) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7705)
#define SCIF_FNS(name, scif_offset, scif_size) \
CPU_SCIF_FNS(name, scif_offset, scif_size)
#else
@@ -362,8 +385,8 @@
#endif
#if defined(CONFIG_CPU_SUBTYPE_SH7300) || \
- defined(CONFIG_CPU_SUBTYPE_SH7705) || \
- defined(CONFIG_CPU_SUBTYPE_SH7710)
+ defined(CONFIG_CPU_SUBTYPE_SH7705)
+
SCIF_FNS(SCSMR, 0x00, 16)
SCIF_FNS(SCBRR, 0x04, 8)
SCIF_FNS(SCSCR, 0x08, 16)
@@ -385,7 +408,9 @@ SCIx_FNS(SCxTDR, 0x06, 8, 0x0c, 8, 0x06, 8, 0x0C, 8, 0x03, 8)
SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8)
SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8)
SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16)
-#if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780)
+#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7785)
SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16)
SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16)
SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16)
@@ -471,13 +496,24 @@ static inline int sci_rxd_in(struct uart_port *port)
return ctrl_inb(SCPDR)&0x10 ? 1 : 0; /* SCIF */
return 1;
}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7710)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
static inline int sci_rxd_in(struct uart_port *port)
{
- if (port->mapbase == SCSPTR0)
- return ctrl_inw(SCSPTR0 + 0x10) & 0x01 ? 1 : 0;
- return 1;
+ return sci_in(port,SCxSR)&0x0010 ? 1 : 0;
+}
+static inline void set_sh771x_scif_pfc(struct uart_port *port)
+{
+ if (port->mapbase == 0xA4400000){
+ ctrl_outw(ctrl_inw(PACR)&0xffc0,PACR);
+ ctrl_outw(ctrl_inw(PBCR)&0x0fff,PBCR);
+ return;
+ }
+ if (port->mapbase == 0xA4410000){
+ ctrl_outw(ctrl_inw(PBCR)&0xf003,PBCR);
+ return;
+ }
}
+
#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \
defined(CONFIG_CPU_SUBTYPE_SH7751) || \
defined(CONFIG_CPU_SUBTYPE_SH4_202)
@@ -576,6 +612,23 @@ static inline int sci_rxd_in(struct uart_port *port)
return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
return 1;
}
+#elif defined(CONFIG_CPU_SUBTYPE_SH7785)
+static inline int sci_rxd_in(struct uart_port *port)
+{
+ if (port->mapbase == 0xffea0000)
+ return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xffeb0000)
+ return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xffec0000)
+ return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xffed0000)
+ return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xffee0000)
+ return ctrl_inw(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF */
+ if (port->mapbase == 0xffef0000)
+ return ctrl_inw(SCSPTR5) & 0x0001 ? 1 : 0; /* SCIF */
+ return 1;
+}
#elif defined(CONFIG_CPU_SUBTYPE_SH7206)
static inline int sci_rxd_in(struct uart_port *port)
{
@@ -634,7 +687,9 @@ static inline int sci_rxd_in(struct uart_port *port)
* -- Mitch Davis - 15 Jul 2000
*/
-#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7780)
+#if defined(CONFIG_CPU_SUBTYPE_SH7300) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7785)
#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1)
#elif defined(CONFIG_CPU_SUBTYPE_SH7705)
#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1)
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index bfd4417..2a63cdb 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1312,7 +1312,7 @@ static void sunsu_console_write(struct console *co, const char *s,
* - initialize the serial port
* Return non-zero if we didn't find a serial port.
*/
-static int sunsu_console_setup(struct console *co, char *options)
+static int __init sunsu_console_setup(struct console *co, char *options)
{
struct uart_port *port;
int baud = 9600;
@@ -1343,7 +1343,7 @@ static int sunsu_console_setup(struct console *co, char *options)
return uart_set_options(port, co, baud, parity, bits, flow);
}
-static struct console sunsu_cons = {
+static struct console sunsu_console = {
.name = "ttyS",
.write = sunsu_console_write,
.device = uart_console_device,
@@ -1373,9 +1373,9 @@ static inline struct console *SUNSU_CONSOLE(int num_uart)
if (i == num_uart)
return NULL;
- sunsu_cons.index = i;
+ sunsu_console.index = i;
- return &sunsu_cons;
+ return &sunsu_console;
}
#else
#define SUNSU_CONSOLE(num_uart) (NULL)
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 7e54e48e..07c587e 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -58,6 +58,23 @@ config SPI_ATMEL
This selects a driver for the Atmel SPI Controller, present on
many AT32 (AVR32) and AT91 (ARM) chips.
+config SPI_BFIN
+ tristate "SPI controller driver for ADI Blackfin5xx"
+ depends on SPI_MASTER && BFIN
+ help
+ This is the SPI controller master driver for Blackfin 5xx processor.
+
+config SPI_AU1550
+ tristate "Au1550/Au12x0 SPI Controller"
+ depends on SPI_MASTER && (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL
+ select SPI_BITBANG
+ help
+ If you say yes to this option, support will be included for the
+ Au1550 SPI controller (may also work with Au1200,Au1210,Au1250).
+
+ This driver can also be built as a module. If so, the module
+ will be called au1550_spi.
+
config SPI_BITBANG
tristate "Bitbanging SPI master"
depends on SPI_MASTER && EXPERIMENTAL
@@ -153,11 +170,19 @@ config SPI_AT25
This driver can also be built as a module. If so, the module
will be called at25.
+config SPI_SPIDEV
+ tristate "User mode SPI device driver support"
+ depends on SPI_MASTER && EXPERIMENTAL
+ help
+ This supports user mode SPI protocol drivers.
+
+ Note that this application programming interface is EXPERIMENTAL
+ and hence SUBJECT TO CHANGE WITHOUT NOTICE while it stabilizes.
+
#
# Add new SPI protocol masters in alphabetical order above this line
#
-
# (slave support would go here)
endmenu # "SPI support"
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 3c280ad..624b636 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -11,8 +11,10 @@ endif
obj-$(CONFIG_SPI_MASTER) += spi.o
# SPI master controller drivers (bus)
-obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o
+obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o
+obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
+obj-$(CONFIG_SPI_AU1550) += au1550_spi.o
obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
obj-$(CONFIG_SPI_IMX) += spi_imx.o
obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o
@@ -24,6 +26,7 @@ obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
# SPI protocol drivers (device/link on bus)
obj-$(CONFIG_SPI_AT25) += at25.o
+obj-$(CONFIG_SPI_SPIDEV) += spidev.o
# ... add above this line ...
# SPI slave controller drivers (upstream link)
diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c
new file mode 100644
index 0000000..ae2b1af
--- /dev/null
+++ b/drivers/spi/au1550_spi.c
@@ -0,0 +1,974 @@
+/*
+ * au1550_spi.c - au1550 psc spi controller driver
+ * may work also with au1200, au1210, au1250
+ * will not work on au1000, au1100 and au1500 (no full spi controller there)
+ *
+ * Copyright (c) 2006 ATRON electronic GmbH
+ * Author: Jan Nikitenko <jan.nikitenko@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/dma-mapping.h>
+#include <linux/completion.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_psc.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+
+#include <asm/mach-au1x00/au1550_spi.h>
+
+static unsigned usedma = 1;
+module_param(usedma, uint, 0644);
+
+/*
+#define AU1550_SPI_DEBUG_LOOPBACK
+*/
+
+
+#define AU1550_SPI_DBDMA_DESCRIPTORS 1
+#define AU1550_SPI_DMA_RXTMP_MINSIZE 2048U
+
+struct au1550_spi {
+ struct spi_bitbang bitbang;
+
+ volatile psc_spi_t __iomem *regs;
+ int irq;
+ unsigned freq_max;
+ unsigned freq_min;
+
+ unsigned len;
+ unsigned tx_count;
+ unsigned rx_count;
+ const u8 *tx;
+ u8 *rx;
+
+ void (*rx_word)(struct au1550_spi *hw);
+ void (*tx_word)(struct au1550_spi *hw);
+ int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t);
+ irqreturn_t (*irq_callback)(struct au1550_spi *hw);
+
+ struct completion master_done;
+
+ unsigned usedma;
+ u32 dma_tx_id;
+ u32 dma_rx_id;
+ u32 dma_tx_ch;
+ u32 dma_rx_ch;
+
+ u8 *dma_rx_tmpbuf;
+ unsigned dma_rx_tmpbuf_size;
+ u32 dma_rx_tmpbuf_addr;
+
+ struct spi_master *master;
+ struct device *dev;
+ struct au1550_spi_info *pdata;
+};
+
+
+/* we use an 8-bit memory device for dma transfers to/from spi fifo */
+static dbdev_tab_t au1550_spi_mem_dbdev =
+{
+ .dev_id = DBDMA_MEM_CHAN,
+ .dev_flags = DEV_FLAGS_ANYUSE|DEV_FLAGS_SYNC,
+ .dev_tsize = 0,
+ .dev_devwidth = 8,
+ .dev_physaddr = 0x00000000,
+ .dev_intlevel = 0,
+ .dev_intpolarity = 0
+};
+
+static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw);
+
+
+/**
+ * compute BRG and DIV bits to setup spi clock based on main input clock rate
+ * that was specified in platform data structure
+ * according to au1550 datasheet:
+ * psc_tempclk = psc_mainclk / (2 << DIV)
+ * spiclk = psc_tempclk / (2 * (BRG + 1))
+ * BRG valid range is 4..63
+ * DIV valid range is 0..3
+ */
+static u32 au1550_spi_baudcfg(struct au1550_spi *hw, unsigned speed_hz)
+{
+ u32 mainclk_hz = hw->pdata->mainclk_hz;
+ u32 div, brg;
+
+ for (div = 0; div < 4; div++) {
+ brg = mainclk_hz / speed_hz / (4 << div);
+ /* now we have BRG+1 in brg, so count with that */
+ if (brg < (4 + 1)) {
+ brg = (4 + 1); /* speed_hz too big */
+ break; /* set lowest brg (div is == 0) */
+ }
+ if (brg <= (63 + 1))
+ break; /* we have valid brg and div */
+ }
+ if (div == 4) {
+ div = 3; /* speed_hz too small */
+ brg = (63 + 1); /* set highest brg and div */
+ }
+ brg--;
+ return PSC_SPICFG_SET_BAUD(brg) | PSC_SPICFG_SET_DIV(div);
+}
+
+static inline void au1550_spi_mask_ack_all(struct au1550_spi *hw)
+{
+ hw->regs->psc_spimsk =
+ PSC_SPIMSK_MM | PSC_SPIMSK_RR | PSC_SPIMSK_RO
+ | PSC_SPIMSK_RU | PSC_SPIMSK_TR | PSC_SPIMSK_TO
+ | PSC_SPIMSK_TU | PSC_SPIMSK_SD | PSC_SPIMSK_MD;
+ au_sync();
+
+ hw->regs->psc_spievent =
+ PSC_SPIEVNT_MM | PSC_SPIEVNT_RR | PSC_SPIEVNT_RO
+ | PSC_SPIEVNT_RU | PSC_SPIEVNT_TR | PSC_SPIEVNT_TO
+ | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD | PSC_SPIEVNT_MD;
+ au_sync();
+}
+
+static void au1550_spi_reset_fifos(struct au1550_spi *hw)
+{
+ u32 pcr;
+
+ hw->regs->psc_spipcr = PSC_SPIPCR_RC | PSC_SPIPCR_TC;
+ au_sync();
+ do {
+ pcr = hw->regs->psc_spipcr;
+ au_sync();
+ } while (pcr != 0);
+}
+
+/*
+ * dma transfers are used for the most common spi word size of 8-bits
+ * we cannot easily change already set up dma channels' width, so if we wanted
+ * dma support for more than 8-bit words (up to 24 bits), we would need to
+ * setup dma channels from scratch on each spi transfer, based on bits_per_word
+ * instead we have pre set up 8 bit dma channels supporting spi 4 to 8 bits
+ * transfers, and 9 to 24 bits spi transfers will be done in pio irq based mode
+ * callbacks to handle dma or pio are set up in au1550_spi_bits_handlers_set()
+ */
+static void au1550_spi_chipsel(struct spi_device *spi, int value)
+{
+ struct au1550_spi *hw = spi_master_get_devdata(spi->master);
+ unsigned cspol = spi->mode & SPI_CS_HIGH ? 1 : 0;
+ u32 cfg, stat;
+
+ switch (value) {
+ case BITBANG_CS_INACTIVE:
+ if (hw->pdata->deactivate_cs)
+ hw->pdata->deactivate_cs(hw->pdata, spi->chip_select,
+ cspol);
+ break;
+
+ case BITBANG_CS_ACTIVE:
+ au1550_spi_bits_handlers_set(hw, spi->bits_per_word);
+
+ cfg = hw->regs->psc_spicfg;
+ au_sync();
+ hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE;
+ au_sync();
+
+ if (spi->mode & SPI_CPOL)
+ cfg |= PSC_SPICFG_BI;
+ else
+ cfg &= ~PSC_SPICFG_BI;
+ if (spi->mode & SPI_CPHA)
+ cfg &= ~PSC_SPICFG_CDE;
+ else
+ cfg |= PSC_SPICFG_CDE;
+
+ if (spi->mode & SPI_LSB_FIRST)
+ cfg |= PSC_SPICFG_MLF;
+ else
+ cfg &= ~PSC_SPICFG_MLF;
+
+ if (hw->usedma && spi->bits_per_word <= 8)
+ cfg &= ~PSC_SPICFG_DD_DISABLE;
+ else
+ cfg |= PSC_SPICFG_DD_DISABLE;
+ cfg = PSC_SPICFG_CLR_LEN(cfg);
+ cfg |= PSC_SPICFG_SET_LEN(spi->bits_per_word);
+
+ cfg = PSC_SPICFG_CLR_BAUD(cfg);
+ cfg &= ~PSC_SPICFG_SET_DIV(3);
+ cfg |= au1550_spi_baudcfg(hw, spi->max_speed_hz);
+
+ hw->regs->psc_spicfg = cfg | PSC_SPICFG_DE_ENABLE;
+ au_sync();
+ do {
+ stat = hw->regs->psc_spistat;
+ au_sync();
+ } while ((stat & PSC_SPISTAT_DR) == 0);
+
+ if (hw->pdata->activate_cs)
+ hw->pdata->activate_cs(hw->pdata, spi->chip_select,
+ cspol);
+ break;
+ }
+}
+
+static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
+{
+ struct au1550_spi *hw = spi_master_get_devdata(spi->master);
+ unsigned bpw, hz;
+ u32 cfg, stat;
+
+ bpw = t ? t->bits_per_word : spi->bits_per_word;
+ hz = t ? t->speed_hz : spi->max_speed_hz;
+
+ if (bpw < 4 || bpw > 24) {
+ dev_err(&spi->dev, "setupxfer: invalid bits_per_word=%d\n",
+ bpw);
+ return -EINVAL;
+ }
+ if (hz > spi->max_speed_hz || hz > hw->freq_max || hz < hw->freq_min) {
+ dev_err(&spi->dev, "setupxfer: clock rate=%d out of range\n",
+ hz);
+ return -EINVAL;
+ }
+
+ au1550_spi_bits_handlers_set(hw, spi->bits_per_word);
+
+ cfg = hw->regs->psc_spicfg;
+ au_sync();
+ hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE;
+ au_sync();
+
+ if (hw->usedma && bpw <= 8)
+ cfg &= ~PSC_SPICFG_DD_DISABLE;
+ else
+ cfg |= PSC_SPICFG_DD_DISABLE;
+ cfg = PSC_SPICFG_CLR_LEN(cfg);
+ cfg |= PSC_SPICFG_SET_LEN(bpw);
+
+ cfg = PSC_SPICFG_CLR_BAUD(cfg);
+ cfg &= ~PSC_SPICFG_SET_DIV(3);
+ cfg |= au1550_spi_baudcfg(hw, hz);
+
+ hw->regs->psc_spicfg = cfg;
+ au_sync();
+
+ if (cfg & PSC_SPICFG_DE_ENABLE) {
+ do {
+ stat = hw->regs->psc_spistat;
+ au_sync();
+ } while ((stat & PSC_SPISTAT_DR) == 0);
+ }
+
+ au1550_spi_reset_fifos(hw);
+ au1550_spi_mask_ack_all(hw);
+ return 0;
+}
+
+static int au1550_spi_setup(struct spi_device *spi)
+{
+ struct au1550_spi *hw = spi_master_get_devdata(spi->master);
+
+ if (spi->bits_per_word == 0)
+ spi->bits_per_word = 8;
+ if (spi->bits_per_word < 4 || spi->bits_per_word > 24) {
+ dev_err(&spi->dev, "setup: invalid bits_per_word=%d\n",
+ spi->bits_per_word);
+ return -EINVAL;
+ }
+
+ if (spi->max_speed_hz == 0)
+ spi->max_speed_hz = hw->freq_max;
+ if (spi->max_speed_hz > hw->freq_max
+ || spi->max_speed_hz < hw->freq_min)
+ return -EINVAL;
+ /*
+ * NOTE: cannot change speed and other hw settings immediately,
+ * otherwise sharing of spi bus is not possible,
+ * so do not call setupxfer(spi, NULL) here
+ */
+ return 0;
+}
+
+/*
+ * for dma spi transfers, we have to setup rx channel, otherwise there is
+ * no reliable way how to recognize that spi transfer is done
+ * dma complete callbacks are called before real spi transfer is finished
+ * and if only tx dma channel is set up (and rx fifo overflow event masked)
+ * spi master done event irq is not generated unless rx fifo is empty (emptied)
+ * so we need rx tmp buffer to use for rx dma if user does not provide one
+ */
+static int au1550_spi_dma_rxtmp_alloc(struct au1550_spi *hw, unsigned size)
+{
+ hw->dma_rx_tmpbuf = kmalloc(size, GFP_KERNEL);
+ if (!hw->dma_rx_tmpbuf)
+ return -ENOMEM;
+ hw->dma_rx_tmpbuf_size = size;
+ hw->dma_rx_tmpbuf_addr = dma_map_single(hw->dev, hw->dma_rx_tmpbuf,
+ size, DMA_FROM_DEVICE);
+ if (dma_mapping_error(hw->dma_rx_tmpbuf_addr)) {
+ kfree(hw->dma_rx_tmpbuf);
+ hw->dma_rx_tmpbuf = 0;
+ hw->dma_rx_tmpbuf_size = 0;
+ return -EFAULT;
+ }
+ return 0;
+}
+
+static void au1550_spi_dma_rxtmp_free(struct au1550_spi *hw)
+{
+ dma_unmap_single(hw->dev, hw->dma_rx_tmpbuf_addr,
+ hw->dma_rx_tmpbuf_size, DMA_FROM_DEVICE);
+ kfree(hw->dma_rx_tmpbuf);
+ hw->dma_rx_tmpbuf = 0;
+ hw->dma_rx_tmpbuf_size = 0;
+}
+
+static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t)
+{
+ struct au1550_spi *hw = spi_master_get_devdata(spi->master);
+ dma_addr_t dma_tx_addr;
+ dma_addr_t dma_rx_addr;
+ u32 res;
+
+ hw->len = t->len;
+ hw->tx_count = 0;
+ hw->rx_count = 0;
+
+ hw->tx = t->tx_buf;
+ hw->rx = t->rx_buf;
+ dma_tx_addr = t->tx_dma;
+ dma_rx_addr = t->rx_dma;
+
+ /*
+ * check if buffers are already dma mapped, map them otherwise
+ * use rx buffer in place of tx if tx buffer was not provided
+ * use temp rx buffer (preallocated or realloc to fit) for rx dma
+ */
+ if (t->rx_buf) {
+ if (t->rx_dma == 0) { /* if DMA_ADDR_INVALID, map it */
+ dma_rx_addr = dma_map_single(hw->dev,
+ (void *)t->rx_buf,
+ t->len, DMA_FROM_DEVICE);
+ if (dma_mapping_error(dma_rx_addr))
+ dev_err(hw->dev, "rx dma map error\n");
+ }
+ } else {
+ if (t->len > hw->dma_rx_tmpbuf_size) {
+ int ret;
+
+ au1550_spi_dma_rxtmp_free(hw);
+ ret = au1550_spi_dma_rxtmp_alloc(hw, max(t->len,
+ AU1550_SPI_DMA_RXTMP_MINSIZE));
+ if (ret < 0)
+ return ret;
+ }
+ hw->rx = hw->dma_rx_tmpbuf;
+ dma_rx_addr = hw->dma_rx_tmpbuf_addr;
+ dma_sync_single_for_device(hw->dev, dma_rx_addr,
+ t->len, DMA_FROM_DEVICE);
+ }
+ if (t->tx_buf) {
+ if (t->tx_dma == 0) { /* if DMA_ADDR_INVALID, map it */
+ dma_tx_addr = dma_map_single(hw->dev,
+ (void *)t->tx_buf,
+ t->len, DMA_TO_DEVICE);
+ if (dma_mapping_error(dma_tx_addr))
+ dev_err(hw->dev, "tx dma map error\n");
+ }
+ } else {
+ dma_sync_single_for_device(hw->dev, dma_rx_addr,
+ t->len, DMA_BIDIRECTIONAL);
+ hw->tx = hw->rx;
+ }
+
+ /* put buffers on the ring */
+ res = au1xxx_dbdma_put_dest(hw->dma_rx_ch, hw->rx, t->len);
+ if (!res)
+ dev_err(hw->dev, "rx dma put dest error\n");
+
+ res = au1xxx_dbdma_put_source(hw->dma_tx_ch, (void *)hw->tx, t->len);
+ if (!res)
+ dev_err(hw->dev, "tx dma put source error\n");
+
+ au1xxx_dbdma_start(hw->dma_rx_ch);
+ au1xxx_dbdma_start(hw->dma_tx_ch);
+
+ /* by default enable nearly all events interrupt */
+ hw->regs->psc_spimsk = PSC_SPIMSK_SD;
+ au_sync();
+
+ /* start the transfer */
+ hw->regs->psc_spipcr = PSC_SPIPCR_MS;
+ au_sync();
+
+ wait_for_completion(&hw->master_done);
+
+ au1xxx_dbdma_stop(hw->dma_tx_ch);
+ au1xxx_dbdma_stop(hw->dma_rx_ch);
+
+ if (!t->rx_buf) {
+ /* using the temporal preallocated and premapped buffer */
+ dma_sync_single_for_cpu(hw->dev, dma_rx_addr, t->len,
+ DMA_FROM_DEVICE);
+ }
+ /* unmap buffers if mapped above */
+ if (t->rx_buf && t->rx_dma == 0 )
+ dma_unmap_single(hw->dev, dma_rx_addr, t->len,
+ DMA_FROM_DEVICE);
+ if (t->tx_buf && t->tx_dma == 0 )
+ dma_unmap_single(hw->dev, dma_tx_addr, t->len,
+ DMA_TO_DEVICE);
+
+ return hw->rx_count < hw->tx_count ? hw->rx_count : hw->tx_count;
+}
+
+static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw)
+{
+ u32 stat, evnt;
+
+ stat = hw->regs->psc_spistat;
+ evnt = hw->regs->psc_spievent;
+ au_sync();
+ if ((stat & PSC_SPISTAT_DI) == 0) {
+ dev_err(hw->dev, "Unexpected IRQ!\n");
+ return IRQ_NONE;
+ }
+
+ if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO
+ | PSC_SPIEVNT_RU | PSC_SPIEVNT_TO
+ | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD))
+ != 0) {
+ /*
+ * due to an spi error we consider transfer as done,
+ * so mask all events until before next transfer start
+ * and stop the possibly running dma immediatelly
+ */
+ au1550_spi_mask_ack_all(hw);
+ au1xxx_dbdma_stop(hw->dma_rx_ch);
+ au1xxx_dbdma_stop(hw->dma_tx_ch);
+
+ /* get number of transfered bytes */
+ hw->rx_count = hw->len - au1xxx_get_dma_residue(hw->dma_rx_ch);
+ hw->tx_count = hw->len - au1xxx_get_dma_residue(hw->dma_tx_ch);
+
+ au1xxx_dbdma_reset(hw->dma_rx_ch);
+ au1xxx_dbdma_reset(hw->dma_tx_ch);
+ au1550_spi_reset_fifos(hw);
+
+ dev_err(hw->dev,
+ "Unexpected SPI error: event=0x%x stat=0x%x!\n",
+ evnt, stat);
+
+ complete(&hw->master_done);
+ return IRQ_HANDLED;
+ }
+
+ if ((evnt & PSC_SPIEVNT_MD) != 0) {
+ /* transfer completed successfully */
+ au1550_spi_mask_ack_all(hw);
+ hw->rx_count = hw->len;
+ hw->tx_count = hw->len;
+ complete(&hw->master_done);
+ }
+ return IRQ_HANDLED;
+}
+
+
+/* routines to handle different word sizes in pio mode */
+#define AU1550_SPI_RX_WORD(size, mask) \
+static void au1550_spi_rx_word_##size(struct au1550_spi *hw) \
+{ \
+ u32 fifoword = hw->regs->psc_spitxrx & (u32)(mask); \
+ au_sync(); \
+ if (hw->rx) { \
+ *(u##size *)hw->rx = (u##size)fifoword; \
+ hw->rx += (size) / 8; \
+ } \
+ hw->rx_count += (size) / 8; \
+}
+
+#define AU1550_SPI_TX_WORD(size, mask) \
+static void au1550_spi_tx_word_##size(struct au1550_spi *hw) \
+{ \
+ u32 fifoword = 0; \
+ if (hw->tx) { \
+ fifoword = *(u##size *)hw->tx & (u32)(mask); \
+ hw->tx += (size) / 8; \
+ } \
+ hw->tx_count += (size) / 8; \
+ if (hw->tx_count >= hw->len) \
+ fifoword |= PSC_SPITXRX_LC; \
+ hw->regs->psc_spitxrx = fifoword; \
+ au_sync(); \
+}
+
+AU1550_SPI_RX_WORD(8,0xff)
+AU1550_SPI_RX_WORD(16,0xffff)
+AU1550_SPI_RX_WORD(32,0xffffff)
+AU1550_SPI_TX_WORD(8,0xff)
+AU1550_SPI_TX_WORD(16,0xffff)
+AU1550_SPI_TX_WORD(32,0xffffff)
+
+static int au1550_spi_pio_txrxb(struct spi_device *spi, struct spi_transfer *t)
+{
+ u32 stat, mask;
+ struct au1550_spi *hw = spi_master_get_devdata(spi->master);
+
+ hw->tx = t->tx_buf;
+ hw->rx = t->rx_buf;
+ hw->len = t->len;
+ hw->tx_count = 0;
+ hw->rx_count = 0;
+
+ /* by default enable nearly all events after filling tx fifo */
+ mask = PSC_SPIMSK_SD;
+
+ /* fill the transmit FIFO */
+ while (hw->tx_count < hw->len) {
+
+ hw->tx_word(hw);
+
+ if (hw->tx_count >= hw->len) {
+ /* mask tx fifo request interrupt as we are done */
+ mask |= PSC_SPIMSK_TR;
+ }
+
+ stat = hw->regs->psc_spistat;
+ au_sync();
+ if (stat & PSC_SPISTAT_TF)
+ break;
+ }
+
+ /* enable event interrupts */
+ hw->regs->psc_spimsk = mask;
+ au_sync();
+
+ /* start the transfer */
+ hw->regs->psc_spipcr = PSC_SPIPCR_MS;
+ au_sync();
+
+ wait_for_completion(&hw->master_done);
+
+ return hw->rx_count < hw->tx_count ? hw->rx_count : hw->tx_count;
+}
+
+static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
+{
+ int busy;
+ u32 stat, evnt;
+
+ stat = hw->regs->psc_spistat;
+ evnt = hw->regs->psc_spievent;
+ au_sync();
+ if ((stat & PSC_SPISTAT_DI) == 0) {
+ dev_err(hw->dev, "Unexpected IRQ!\n");
+ return IRQ_NONE;
+ }
+
+ if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO
+ | PSC_SPIEVNT_RU | PSC_SPIEVNT_TO
+ | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD))
+ != 0) {
+ dev_err(hw->dev,
+ "Unexpected SPI error: event=0x%x stat=0x%x!\n",
+ evnt, stat);
+ /*
+ * due to an error we consider transfer as done,
+ * so mask all events until before next transfer start
+ */
+ au1550_spi_mask_ack_all(hw);
+ au1550_spi_reset_fifos(hw);
+ complete(&hw->master_done);
+ return IRQ_HANDLED;
+ }
+
+ /*
+ * while there is something to read from rx fifo
+ * or there is a space to write to tx fifo:
+ */
+ do {
+ busy = 0;
+ stat = hw->regs->psc_spistat;
+ au_sync();
+
+ if ((stat & PSC_SPISTAT_RE) == 0 && hw->rx_count < hw->len) {
+ hw->rx_word(hw);
+ /* ack the receive request event */
+ hw->regs->psc_spievent = PSC_SPIEVNT_RR;
+ au_sync();
+ busy = 1;
+ }
+
+ if ((stat & PSC_SPISTAT_TF) == 0 && hw->tx_count < hw->len) {
+ hw->tx_word(hw);
+ /* ack the transmit request event */
+ hw->regs->psc_spievent = PSC_SPIEVNT_TR;
+ au_sync();
+ busy = 1;
+ }
+ } while (busy);
+
+ evnt = hw->regs->psc_spievent;
+ au_sync();
+
+ if (hw->rx_count >= hw->len || (evnt & PSC_SPIEVNT_MD) != 0) {
+ /* transfer completed successfully */
+ au1550_spi_mask_ack_all(hw);
+ complete(&hw->master_done);
+ }
+ return IRQ_HANDLED;
+}
+
+static int au1550_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
+{
+ struct au1550_spi *hw = spi_master_get_devdata(spi->master);
+ return hw->txrx_bufs(spi, t);
+}
+
+static irqreturn_t au1550_spi_irq(int irq, void *dev, struct pt_regs *regs)
+{
+ struct au1550_spi *hw = dev;
+ return hw->irq_callback(hw);
+}
+
+static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw)
+{
+ if (bpw <= 8) {
+ if (hw->usedma) {
+ hw->txrx_bufs = &au1550_spi_dma_txrxb;
+ hw->irq_callback = &au1550_spi_dma_irq_callback;
+ } else {
+ hw->rx_word = &au1550_spi_rx_word_8;
+ hw->tx_word = &au1550_spi_tx_word_8;
+ hw->txrx_bufs = &au1550_spi_pio_txrxb;
+ hw->irq_callback = &au1550_spi_pio_irq_callback;
+ }
+ } else if (bpw <= 16) {
+ hw->rx_word = &au1550_spi_rx_word_16;
+ hw->tx_word = &au1550_spi_tx_word_16;
+ hw->txrx_bufs = &au1550_spi_pio_txrxb;
+ hw->irq_callback = &au1550_spi_pio_irq_callback;
+ } else {
+ hw->rx_word = &au1550_spi_rx_word_32;
+ hw->tx_word = &au1550_spi_tx_word_32;
+ hw->txrx_bufs = &au1550_spi_pio_txrxb;
+ hw->irq_callback = &au1550_spi_pio_irq_callback;
+ }
+}
+
+static void __init au1550_spi_setup_psc_as_spi(struct au1550_spi *hw)
+{
+ u32 stat, cfg;
+
+ /* set up the PSC for SPI mode */
+ hw->regs->psc_ctrl = PSC_CTRL_DISABLE;
+ au_sync();
+ hw->regs->psc_sel = PSC_SEL_PS_SPIMODE;
+ au_sync();
+
+ hw->regs->psc_spicfg = 0;
+ au_sync();
+
+ hw->regs->psc_ctrl = PSC_CTRL_ENABLE;
+ au_sync();
+
+ do {
+ stat = hw->regs->psc_spistat;
+ au_sync();
+ } while ((stat & PSC_SPISTAT_SR) == 0);
+
+
+ cfg = hw->usedma ? 0 : PSC_SPICFG_DD_DISABLE;
+ cfg |= PSC_SPICFG_SET_LEN(8);
+ cfg |= PSC_SPICFG_RT_FIFO8 | PSC_SPICFG_TT_FIFO8;
+ /* use minimal allowed brg and div values as initial setting: */
+ cfg |= PSC_SPICFG_SET_BAUD(4) | PSC_SPICFG_SET_DIV(0);
+
+#ifdef AU1550_SPI_DEBUG_LOOPBACK
+ cfg |= PSC_SPICFG_LB;
+#endif
+
+ hw->regs->psc_spicfg = cfg;
+ au_sync();
+
+ au1550_spi_mask_ack_all(hw);
+
+ hw->regs->psc_spicfg |= PSC_SPICFG_DE_ENABLE;
+ au_sync();
+
+ do {
+ stat = hw->regs->psc_spistat;
+ au_sync();
+ } while ((stat & PSC_SPISTAT_DR) == 0);
+}
+
+
+static int __init au1550_spi_probe(struct platform_device *pdev)
+{
+ struct au1550_spi *hw;
+ struct spi_master *master;
+ int err = 0;
+
+ master = spi_alloc_master(&pdev->dev, sizeof(struct au1550_spi));
+ if (master == NULL) {
+ dev_err(&pdev->dev, "No memory for spi_master\n");
+ err = -ENOMEM;
+ goto err_nomem;
+ }
+
+ hw = spi_master_get_devdata(master);
+
+ hw->master = spi_master_get(master);
+ hw->pdata = pdev->dev.platform_data;
+ hw->dev = &pdev->dev;
+
+ if (hw->pdata == NULL) {
+ dev_err(&pdev->dev, "No platform data supplied\n");
+ err = -ENOENT;
+ goto err_no_pdata;
+ }
+
+ platform_set_drvdata(pdev, hw);
+
+ init_completion(&hw->master_done);
+
+ hw->bitbang.master = hw->master;
+ hw->bitbang.setup_transfer = au1550_spi_setupxfer;
+ hw->bitbang.chipselect = au1550_spi_chipsel;
+ hw->bitbang.master->setup = au1550_spi_setup;
+ hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs;
+
+ switch (hw->pdata->bus_num) {
+ case 0:
+ hw->irq = AU1550_PSC0_INT;
+ hw->regs = (volatile psc_spi_t *)PSC0_BASE_ADDR;
+ hw->dma_rx_id = DSCR_CMD0_PSC0_RX;
+ hw->dma_tx_id = DSCR_CMD0_PSC0_TX;
+ break;
+ case 1:
+ hw->irq = AU1550_PSC1_INT;
+ hw->regs = (volatile psc_spi_t *)PSC1_BASE_ADDR;
+ hw->dma_rx_id = DSCR_CMD0_PSC1_RX;
+ hw->dma_tx_id = DSCR_CMD0_PSC1_TX;
+ break;
+ case 2:
+ hw->irq = AU1550_PSC2_INT;
+ hw->regs = (volatile psc_spi_t *)PSC2_BASE_ADDR;
+ hw->dma_rx_id = DSCR_CMD0_PSC2_RX;
+ hw->dma_tx_id = DSCR_CMD0_PSC2_TX;
+ break;
+ case 3:
+ hw->irq = AU1550_PSC3_INT;
+ hw->regs = (volatile psc_spi_t *)PSC3_BASE_ADDR;
+ hw->dma_rx_id = DSCR_CMD0_PSC3_RX;
+ hw->dma_tx_id = DSCR_CMD0_PSC3_TX;
+ break;
+ default:
+ dev_err(&pdev->dev, "Wrong bus_num of SPI\n");
+ err = -ENOENT;
+ goto err_no_pdata;
+ }
+
+ if (request_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t),
+ pdev->name) == NULL) {
+ dev_err(&pdev->dev, "Cannot reserve iomem region\n");
+ err = -ENXIO;
+ goto err_no_iores;
+ }
+
+
+ if (usedma) {
+ if (pdev->dev.dma_mask == NULL)
+ dev_warn(&pdev->dev, "no dma mask\n");
+ else
+ hw->usedma = 1;
+ }
+
+ if (hw->usedma) {
+ /*
+ * create memory device with 8 bits dev_devwidth
+ * needed for proper byte ordering to spi fifo
+ */
+ int memid = au1xxx_ddma_add_device(&au1550_spi_mem_dbdev);
+ if (!memid) {
+ dev_err(&pdev->dev,
+ "Cannot create dma 8 bit mem device\n");
+ err = -ENXIO;
+ goto err_dma_add_dev;
+ }
+
+ hw->dma_tx_ch = au1xxx_dbdma_chan_alloc(memid,
+ hw->dma_tx_id, NULL, (void *)hw);
+ if (hw->dma_tx_ch == 0) {
+ dev_err(&pdev->dev,
+ "Cannot allocate tx dma channel\n");
+ err = -ENXIO;
+ goto err_no_txdma;
+ }
+ au1xxx_dbdma_set_devwidth(hw->dma_tx_ch, 8);
+ if (au1xxx_dbdma_ring_alloc(hw->dma_tx_ch,
+ AU1550_SPI_DBDMA_DESCRIPTORS) == 0) {
+ dev_err(&pdev->dev,
+ "Cannot allocate tx dma descriptors\n");
+ err = -ENXIO;
+ goto err_no_txdma_descr;
+ }
+
+
+ hw->dma_rx_ch = au1xxx_dbdma_chan_alloc(hw->dma_rx_id,
+ memid, NULL, (void *)hw);
+ if (hw->dma_rx_ch == 0) {
+ dev_err(&pdev->dev,
+ "Cannot allocate rx dma channel\n");
+ err = -ENXIO;
+ goto err_no_rxdma;
+ }
+ au1xxx_dbdma_set_devwidth(hw->dma_rx_ch, 8);
+ if (au1xxx_dbdma_ring_alloc(hw->dma_rx_ch,
+ AU1550_SPI_DBDMA_DESCRIPTORS) == 0) {
+ dev_err(&pdev->dev,
+ "Cannot allocate rx dma descriptors\n");
+ err = -ENXIO;
+ goto err_no_rxdma_descr;
+ }
+
+ err = au1550_spi_dma_rxtmp_alloc(hw,
+ AU1550_SPI_DMA_RXTMP_MINSIZE);
+ if (err < 0) {
+ dev_err(&pdev->dev,
+ "Cannot allocate initial rx dma tmp buffer\n");
+ goto err_dma_rxtmp_alloc;
+ }
+ }
+
+ au1550_spi_bits_handlers_set(hw, 8);
+
+ err = request_irq(hw->irq, au1550_spi_irq, 0, pdev->name, hw);
+ if (err) {
+ dev_err(&pdev->dev, "Cannot claim IRQ\n");
+ goto err_no_irq;
+ }
+
+ master->bus_num = hw->pdata->bus_num;
+ master->num_chipselect = hw->pdata->num_chipselect;
+
+ /*
+ * precompute valid range for spi freq - from au1550 datasheet:
+ * psc_tempclk = psc_mainclk / (2 << DIV)
+ * spiclk = psc_tempclk / (2 * (BRG + 1))
+ * BRG valid range is 4..63
+ * DIV valid range is 0..3
+ * round the min and max frequencies to values that would still
+ * produce valid brg and div
+ */
+ {
+ int min_div = (2 << 0) * (2 * (4 + 1));
+ int max_div = (2 << 3) * (2 * (63 + 1));
+ hw->freq_max = hw->pdata->mainclk_hz / min_div;
+ hw->freq_min = hw->pdata->mainclk_hz / (max_div + 1) + 1;
+ }
+
+ au1550_spi_setup_psc_as_spi(hw);
+
+ err = spi_bitbang_start(&hw->bitbang);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to register SPI master\n");
+ goto err_register;
+ }
+
+ dev_info(&pdev->dev,
+ "spi master registered: bus_num=%d num_chipselect=%d\n",
+ master->bus_num, master->num_chipselect);
+
+ return 0;
+
+err_register:
+ free_irq(hw->irq, hw);
+
+err_no_irq:
+ au1550_spi_dma_rxtmp_free(hw);
+
+err_dma_rxtmp_alloc:
+err_no_rxdma_descr:
+ if (hw->usedma)
+ au1xxx_dbdma_chan_free(hw->dma_rx_ch);
+
+err_no_rxdma:
+err_no_txdma_descr:
+ if (hw->usedma)
+ au1xxx_dbdma_chan_free(hw->dma_tx_ch);
+
+err_no_txdma:
+err_dma_add_dev:
+ release_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t));
+
+err_no_iores:
+err_no_pdata:
+ spi_master_put(hw->master);
+
+err_nomem:
+ return err;
+}
+
+static int __exit au1550_spi_remove(struct platform_device *pdev)
+{
+ struct au1550_spi *hw = platform_get_drvdata(pdev);
+
+ dev_info(&pdev->dev, "spi master remove: bus_num=%d\n",
+ hw->master->bus_num);
+
+ spi_bitbang_stop(&hw->bitbang);
+ free_irq(hw->irq, hw);
+ release_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t));
+
+ if (hw->usedma) {
+ au1550_spi_dma_rxtmp_free(hw);
+ au1xxx_dbdma_chan_free(hw->dma_rx_ch);
+ au1xxx_dbdma_chan_free(hw->dma_tx_ch);
+ }
+
+ platform_set_drvdata(pdev, NULL);
+
+ spi_master_put(hw->master);
+ return 0;
+}
+
+static struct platform_driver au1550_spi_drv = {
+ .remove = __exit_p(au1550_spi_remove),
+ .driver = {
+ .name = "au1550-spi",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init au1550_spi_init(void)
+{
+ return platform_driver_probe(&au1550_spi_drv, au1550_spi_probe);
+}
+module_init(au1550_spi_init);
+
+static void __exit au1550_spi_exit(void)
+{
+ platform_driver_unregister(&au1550_spi_drv);
+}
+module_exit(au1550_spi_exit);
+
+MODULE_DESCRIPTION("Au1550 PSC SPI Driver");
+MODULE_AUTHOR("Jan Nikitenko <jan.nikitenko@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 6657331..c3219b2 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -152,6 +152,11 @@ static void spi_drv_shutdown(struct device *dev)
sdrv->shutdown(to_spi_device(dev));
}
+/**
+ * spi_register_driver - register a SPI driver
+ * @sdrv: the driver to register
+ * Context: can sleep
+ */
int spi_register_driver(struct spi_driver *sdrv)
{
sdrv->driver.bus = &spi_bus_type;
@@ -183,7 +188,13 @@ static LIST_HEAD(board_list);
static DECLARE_MUTEX(board_lock);
-/* On typical mainboards, this is purely internal; and it's not needed
+/**
+ * spi_new_device - instantiate one new SPI device
+ * @master: Controller to which device is connected
+ * @chip: Describes the SPI device
+ * Context: can sleep
+ *
+ * On typical mainboards, this is purely internal; and it's not needed
* after board init creates the hard-wired devices. Some development
* platforms may not be able to use spi_register_board_info though, and
* this is exported so that for example a USB or parport based adapter
@@ -251,7 +262,12 @@ fail:
}
EXPORT_SYMBOL_GPL(spi_new_device);
-/*
+/**
+ * spi_register_board_info - register SPI devices for a given board
+ * @info: array of chip descriptors
+ * @n: how many descriptors are provided
+ * Context: can sleep
+ *
* Board-specific early init code calls this (probably during arch_initcall)
* with segments of the SPI device table. Any device nodes are created later,
* after the relevant parent SPI controller (bus_num) is defined. We keep
@@ -337,9 +353,10 @@ static struct class spi_master_class = {
/**
* spi_alloc_master - allocate SPI master controller
* @dev: the controller, possibly using the platform_bus
- * @size: how much driver-private data to preallocate; the pointer to this
+ * @size: how much zeroed driver-private data to allocate; the pointer to this
* memory is in the class_data field of the returned class_device,
* accessible with spi_master_get_devdata().
+ * Context: can sleep
*
* This call is used only by SPI master controller drivers, which are the
* only ones directly touching chip registers. It's how they allocate
@@ -375,6 +392,7 @@ EXPORT_SYMBOL_GPL(spi_alloc_master);
/**
* spi_register_master - register SPI master controller
* @master: initialized master, originally from spi_alloc_master()
+ * Context: can sleep
*
* SPI master controllers connect to their drivers using some non-SPI bus,
* such as the platform bus. The final stage of probe() in that code
@@ -437,6 +455,7 @@ static int __unregister(struct device *dev, void *unused)
/**
* spi_unregister_master - unregister SPI master controller
* @master: the master being unregistered
+ * Context: can sleep
*
* This call is used only by SPI master controller drivers, which are the
* only ones directly touching chip registers.
@@ -455,6 +474,7 @@ EXPORT_SYMBOL_GPL(spi_unregister_master);
/**
* spi_busnum_to_master - look up master associated with bus_num
* @bus_num: the master's bus number
+ * Context: can sleep
*
* This call may be used with devices that are registered after
* arch init time. It returns a refcounted pointer to the relevant
@@ -492,6 +512,7 @@ static void spi_complete(void *arg)
* spi_sync - blocking/synchronous SPI data transfers
* @spi: device with which data will be exchanged
* @message: describes the data transfers
+ * Context: can sleep
*
* This call may only be used from a context that may sleep. The sleep
* is non-interruptible, and has no timeout. Low-overhead controller
@@ -508,7 +529,7 @@ static void spi_complete(void *arg)
*
* The return value is a negative error code if the message could not be
* submitted, else zero. When the value is zero, then message->status is
- * also defined: it's the completion code for the transfer, either zero
+ * also defined; it's the completion code for the transfer, either zero
* or a negative error code from the controller driver.
*/
int spi_sync(struct spi_device *spi, struct spi_message *message)
@@ -538,6 +559,7 @@ static u8 *buf;
* @n_tx: size of txbuf, in bytes
* @rxbuf: buffer into which data will be read
* @n_rx: size of rxbuf, in bytes (need not be dma-safe)
+ * Context: can sleep
*
* This performs a half duplex MicroWire style transaction with the
* device, sending txbuf and then reading rxbuf. The return value
@@ -545,7 +567,8 @@ static u8 *buf;
* This call may only be used from a context that may sleep.
*
* Parameters to this routine are always copied using a small buffer;
- * performance-sensitive or bulk transfer code should instead use
+ * portable code should never use this for more than 32 bytes.
+ * Performance-sensitive or bulk transfer code should instead use
* spi_{async,sync}() calls with dma-safe buffers.
*/
int spi_write_then_read(struct spi_device *spi,
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
new file mode 100644
index 0000000..ce3c0ce
--- /dev/null
+++ b/drivers/spi/spi_bfin5xx.c
@@ -0,0 +1,1313 @@
+/*
+ * File: drivers/spi/bfin5xx_spi.c
+ * Based on: N/A
+ * Author: Luke Yang (Analog Devices Inc.)
+ *
+ * Created: March. 10th 2006
+ * Description: SPI controller driver for Blackfin 5xx
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Modified:
+ * March 10, 2006 bfin5xx_spi.c Created. (Luke Yang)
+ * August 7, 2006 added full duplex mode (Axel Weiss & Luke Yang)
+ *
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * This program is free software ; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation ; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY ; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program ; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/spi/spi.h>
+#include <linux/workqueue.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
+#include <asm/dma.h>
+
+#include <asm/bfin5xx_spi.h>
+
+MODULE_AUTHOR("Luke Yang");
+MODULE_DESCRIPTION("Blackfin 5xx SPI Contoller");
+MODULE_LICENSE("GPL");
+
+#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
+
+#define DEFINE_SPI_REG(reg, off) \
+static inline u16 read_##reg(void) \
+ { return *(volatile unsigned short*)(SPI0_REGBASE + off); } \
+static inline void write_##reg(u16 v) \
+ {*(volatile unsigned short*)(SPI0_REGBASE + off) = v;\
+ SSYNC();}
+
+DEFINE_SPI_REG(CTRL, 0x00)
+DEFINE_SPI_REG(FLAG, 0x04)
+DEFINE_SPI_REG(STAT, 0x08)
+DEFINE_SPI_REG(TDBR, 0x0C)
+DEFINE_SPI_REG(RDBR, 0x10)
+DEFINE_SPI_REG(BAUD, 0x14)
+DEFINE_SPI_REG(SHAW, 0x18)
+#define START_STATE ((void*)0)
+#define RUNNING_STATE ((void*)1)
+#define DONE_STATE ((void*)2)
+#define ERROR_STATE ((void*)-1)
+#define QUEUE_RUNNING 0
+#define QUEUE_STOPPED 1
+int dma_requested;
+
+struct driver_data {
+ /* Driver model hookup */
+ struct platform_device *pdev;
+
+ /* SPI framework hookup */
+ struct spi_master *master;
+
+ /* BFIN hookup */
+ struct bfin5xx_spi_master *master_info;
+
+ /* Driver message queue */
+ struct workqueue_struct *workqueue;
+ struct work_struct pump_messages;
+ spinlock_t lock;
+ struct list_head queue;
+ int busy;
+ int run;
+
+ /* Message Transfer pump */
+ struct tasklet_struct pump_transfers;
+
+ /* Current message transfer state info */
+ struct spi_message *cur_msg;
+ struct spi_transfer *cur_transfer;
+ struct chip_data *cur_chip;
+ size_t len_in_bytes;
+ size_t len;
+ void *tx;
+ void *tx_end;
+ void *rx;
+ void *rx_end;
+ int dma_mapped;
+ dma_addr_t rx_dma;
+ dma_addr_t tx_dma;
+ size_t rx_map_len;
+ size_t tx_map_len;
+ u8 n_bytes;
+ void (*write) (struct driver_data *);
+ void (*read) (struct driver_data *);
+ void (*duplex) (struct driver_data *);
+};
+
+struct chip_data {
+ u16 ctl_reg;
+ u16 baud;
+ u16 flag;
+
+ u8 chip_select_num;
+ u8 n_bytes;
+ u32 width; /* 0 or 1 */
+ u8 enable_dma;
+ u8 bits_per_word; /* 8 or 16 */
+ u8 cs_change_per_word;
+ u8 cs_chg_udelay;
+ void (*write) (struct driver_data *);
+ void (*read) (struct driver_data *);
+ void (*duplex) (struct driver_data *);
+};
+
+void bfin_spi_enable(struct driver_data *drv_data)
+{
+ u16 cr;
+
+ cr = read_CTRL();
+ write_CTRL(cr | BIT_CTL_ENABLE);
+ SSYNC();
+}
+
+void bfin_spi_disable(struct driver_data *drv_data)
+{
+ u16 cr;
+
+ cr = read_CTRL();
+ write_CTRL(cr & (~BIT_CTL_ENABLE));
+ SSYNC();
+}
+
+/* Caculate the SPI_BAUD register value based on input HZ */
+static u16 hz_to_spi_baud(u32 speed_hz)
+{
+ u_long sclk = get_sclk();
+ u16 spi_baud = (sclk / (2 * speed_hz));
+
+ if ((sclk % (2 * speed_hz)) > 0)
+ spi_baud++;
+
+ pr_debug("sclk = %ld, speed_hz = %d, spi_baud = %d\n", sclk, speed_hz,
+ spi_baud);
+
+ return spi_baud;
+}
+
+static int flush(struct driver_data *drv_data)
+{
+ unsigned long limit = loops_per_jiffy << 1;
+
+ /* wait for stop and clear stat */
+ while (!(read_STAT() & BIT_STAT_SPIF) && limit--)
+ continue;
+
+ write_STAT(BIT_STAT_CLR);
+
+ return limit;
+}
+
+/* stop controller and re-config current chip*/
+static void restore_state(struct driver_data *drv_data)
+{
+ struct chip_data *chip = drv_data->cur_chip;
+
+ /* Clear status and disable clock */
+ write_STAT(BIT_STAT_CLR);
+ bfin_spi_disable(drv_data);
+ pr_debug("restoring spi ctl state\n");
+
+#if defined(CONFIG_BF534) || defined(CONFIG_BF536) || defined(CONFIG_BF537)
+ pr_debug("chip select number is %d\n", chip->chip_select_num);
+
+ switch (chip->chip_select_num) {
+ case 1:
+ bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3c00);
+ SSYNC();
+ break;
+
+ case 2:
+ case 3:
+ bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PJSE_SPI);
+ SSYNC();
+ bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3800);
+ SSYNC();
+ break;
+
+ case 4:
+ bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PFS4E_SPI);
+ SSYNC();
+ bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3840);
+ SSYNC();
+ break;
+
+ case 5:
+ bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PFS5E_SPI);
+ SSYNC();
+ bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3820);
+ SSYNC();
+ break;
+
+ case 6:
+ bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PFS6E_SPI);
+ SSYNC();
+ bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3810);
+ SSYNC();
+ break;
+
+ case 7:
+ bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PJCE_SPI);
+ SSYNC();
+ bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3800);
+ SSYNC();
+ break;
+ }
+#endif
+
+ /* Load the registers */
+ write_CTRL(chip->ctl_reg);
+ write_BAUD(chip->baud);
+ write_FLAG(chip->flag);
+}
+
+/* used to kick off transfer in rx mode */
+static unsigned short dummy_read(void)
+{
+ unsigned short tmp;
+ tmp = read_RDBR();
+ return tmp;
+}
+
+static void null_writer(struct driver_data *drv_data)
+{
+ u8 n_bytes = drv_data->n_bytes;
+
+ while (drv_data->tx < drv_data->tx_end) {
+ write_TDBR(0);
+ while ((read_STAT() & BIT_STAT_TXS))
+ continue;
+ drv_data->tx += n_bytes;
+ }
+}
+
+static void null_reader(struct driver_data *drv_data)
+{
+ u8 n_bytes = drv_data->n_bytes;
+ dummy_read();
+
+ while (drv_data->rx < drv_data->rx_end) {
+ while (!(read_STAT() & BIT_STAT_RXS))
+ continue;
+ dummy_read();
+ drv_data->rx += n_bytes;
+ }
+}
+
+static void u8_writer(struct driver_data *drv_data)
+{
+ pr_debug("cr8-s is 0x%x\n", read_STAT());
+ while (drv_data->tx < drv_data->tx_end) {
+ write_TDBR(*(u8 *) (drv_data->tx));
+ while (read_STAT() & BIT_STAT_TXS)
+ continue;
+ ++drv_data->tx;
+ }
+
+ /* poll for SPI completion before returning */
+ while (!(read_STAT() & BIT_STAT_SPIF))
+ continue;
+}
+
+static void u8_cs_chg_writer(struct driver_data *drv_data)
+{
+ struct chip_data *chip = drv_data->cur_chip;
+
+ while (drv_data->tx < drv_data->tx_end) {
+ write_FLAG(chip->flag);
+ SSYNC();
+
+ write_TDBR(*(u8 *) (drv_data->tx));
+ while (read_STAT() & BIT_STAT_TXS)
+ continue;
+ while (!(read_STAT() & BIT_STAT_SPIF))
+ continue;
+ write_FLAG(0xFF00 | chip->flag);
+ SSYNC();
+ if (chip->cs_chg_udelay)
+ udelay(chip->cs_chg_udelay);
+ ++drv_data->tx;
+ }
+ write_FLAG(0xFF00);
+ SSYNC();
+}
+
+static void u8_reader(struct driver_data *drv_data)
+{
+ pr_debug("cr-8 is 0x%x\n", read_STAT());
+
+ /* clear TDBR buffer before read(else it will be shifted out) */
+ write_TDBR(0xFFFF);
+
+ dummy_read();
+
+ while (drv_data->rx < drv_data->rx_end - 1) {
+ while (!(read_STAT() & BIT_STAT_RXS))
+ continue;
+ *(u8 *) (drv_data->rx) = read_RDBR();
+ ++drv_data->rx;
+ }
+
+ while (!(read_STAT() & BIT_STAT_RXS))
+ continue;
+ *(u8 *) (drv_data->rx) = read_SHAW();
+ ++drv_data->rx;
+}
+
+static void u8_cs_chg_reader(struct driver_data *drv_data)
+{
+ struct chip_data *chip = drv_data->cur_chip;
+
+ while (drv_data->rx < drv_data->rx_end) {
+ write_FLAG(chip->flag);
+ SSYNC();
+
+ read_RDBR(); /* kick off */
+ while (!(read_STAT() & BIT_STAT_RXS))
+ continue;
+ while (!(read_STAT() & BIT_STAT_SPIF))
+ continue;
+ *(u8 *) (drv_data->rx) = read_SHAW();
+ write_FLAG(0xFF00 | chip->flag);
+ SSYNC();
+ if (chip->cs_chg_udelay)
+ udelay(chip->cs_chg_udelay);
+ ++drv_data->rx;
+ }
+ write_FLAG(0xFF00);
+ SSYNC();
+}
+
+static void u8_duplex(struct driver_data *drv_data)
+{
+ /* in duplex mode, clk is triggered by writing of TDBR */
+ while (drv_data->rx < drv_data->rx_end) {
+ write_TDBR(*(u8 *) (drv_data->tx));
+ while (!(read_STAT() & BIT_STAT_SPIF))
+ continue;
+ while (!(read_STAT() & BIT_STAT_RXS))
+ continue;
+ *(u8 *) (drv_data->rx) = read_RDBR();
+ ++drv_data->rx;
+ ++drv_data->tx;
+ }
+}
+
+static void u8_cs_chg_duplex(struct driver_data *drv_data)
+{
+ struct chip_data *chip = drv_data->cur_chip;
+
+ while (drv_data->rx < drv_data->rx_end) {
+ write_FLAG(chip->flag);
+ SSYNC();
+
+ write_TDBR(*(u8 *) (drv_data->tx));
+ while (!(read_STAT() & BIT_STAT_SPIF))
+ continue;
+ while (!(read_STAT() & BIT_STAT_RXS))
+ continue;
+ *(u8 *) (drv_data->rx) = read_RDBR();
+ write_FLAG(0xFF00 | chip->flag);
+ SSYNC();
+ if (chip->cs_chg_udelay)
+ udelay(chip->cs_chg_udelay);
+ ++drv_data->rx;
+ ++drv_data->tx;
+ }
+ write_FLAG(0xFF00);
+ SSYNC();
+}
+
+static void u16_writer(struct driver_data *drv_data)
+{
+ pr_debug("cr16 is 0x%x\n", read_STAT());
+ while (drv_data->tx < drv_data->tx_end) {
+ write_TDBR(*(u16 *) (drv_data->tx));
+ while ((read_STAT() & BIT_STAT_TXS))
+ continue;
+ drv_data->tx += 2;
+ }
+
+ /* poll for SPI completion before returning */
+ while (!(read_STAT() & BIT_STAT_SPIF))
+ continue;
+}
+
+static void u16_cs_chg_writer(struct driver_data *drv_data)
+{
+ struct chip_data *chip = drv_data->cur_chip;
+
+ while (drv_data->tx < drv_data->tx_end) {
+ write_FLAG(chip->flag);
+ SSYNC();
+
+ write_TDBR(*(u16 *) (drv_data->tx));
+ while ((read_STAT() & BIT_STAT_TXS))
+ continue;
+ while (!(read_STAT() & BIT_STAT_SPIF))
+ continue;
+ write_FLAG(0xFF00 | chip->flag);
+ SSYNC();
+ if (chip->cs_chg_udelay)
+ udelay(chip->cs_chg_udelay);
+ drv_data->tx += 2;
+ }
+ write_FLAG(0xFF00);
+ SSYNC();
+}
+
+static void u16_reader(struct driver_data *drv_data)
+{
+ pr_debug("cr-16 is 0x%x\n", read_STAT());
+ dummy_read();
+
+ while (drv_data->rx < (drv_data->rx_end - 2)) {
+ while (!(read_STAT() & BIT_STAT_RXS))
+ continue;
+ *(u16 *) (drv_data->rx) = read_RDBR();
+ drv_data->rx += 2;
+ }
+
+ while (!(read_STAT() & BIT_STAT_RXS))
+ continue;
+ *(u16 *) (drv_data->rx) = read_SHAW();
+ drv_data->rx += 2;
+}
+
+static void u16_cs_chg_reader(struct driver_data *drv_data)
+{
+ struct chip_data *chip = drv_data->cur_chip;
+
+ while (drv_data->rx < drv_data->rx_end) {
+ write_FLAG(chip->flag);
+ SSYNC();
+
+ read_RDBR(); /* kick off */
+ while (!(read_STAT() & BIT_STAT_RXS))
+ continue;
+ while (!(read_STAT() & BIT_STAT_SPIF))
+ continue;
+ *(u16 *) (drv_data->rx) = read_SHAW();
+ write_FLAG(0xFF00 | chip->flag);
+ SSYNC();
+ if (chip->cs_chg_udelay)
+ udelay(chip->cs_chg_udelay);
+ drv_data->rx += 2;
+ }
+ write_FLAG(0xFF00);
+ SSYNC();
+}
+
+static void u16_duplex(struct driver_data *drv_data)
+{
+ /* in duplex mode, clk is triggered by writing of TDBR */
+ while (drv_data->tx < drv_data->tx_end) {
+ write_TDBR(*(u16 *) (drv_data->tx));
+ while (!(read_STAT() & BIT_STAT_SPIF))
+ continue;
+ while (!(read_STAT() & BIT_STAT_RXS))
+ continue;
+ *(u16 *) (drv_data->rx) = read_RDBR();
+ drv_data->rx += 2;
+ drv_data->tx += 2;
+ }
+}
+
+static void u16_cs_chg_duplex(struct driver_data *drv_data)
+{
+ struct chip_data *chip = drv_data->cur_chip;
+
+ while (drv_data->tx < drv_data->tx_end) {
+ write_FLAG(chip->flag);
+ SSYNC();
+
+ write_TDBR(*(u16 *) (drv_data->tx));
+ while (!(read_STAT() & BIT_STAT_SPIF))
+ continue;
+ while (!(read_STAT() & BIT_STAT_RXS))
+ continue;
+ *(u16 *) (drv_data->rx) = read_RDBR();
+ write_FLAG(0xFF00 | chip->flag);
+ SSYNC();
+ if (chip->cs_chg_udelay)
+ udelay(chip->cs_chg_udelay);
+ drv_data->rx += 2;
+ drv_data->tx += 2;
+ }
+ write_FLAG(0xFF00);
+ SSYNC();
+}
+
+/* test if ther is more transfer to be done */
+static void *next_transfer(struct driver_data *drv_data)
+{
+ struct spi_message *msg = drv_data->cur_msg;
+ struct spi_transfer *trans = drv_data->cur_transfer;
+
+ /* Move to next transfer */
+ if (trans->transfer_list.next != &msg->transfers) {
+ drv_data->cur_transfer =
+ list_entry(trans->transfer_list.next,
+ struct spi_transfer, transfer_list);
+ return RUNNING_STATE;
+ } else
+ return DONE_STATE;
+}
+
+/*
+ * caller already set message->status;
+ * dma and pio irqs are blocked give finished message back
+ */
+static void giveback(struct driver_data *drv_data)
+{
+ struct spi_transfer *last_transfer;
+ unsigned long flags;
+ struct spi_message *msg;
+
+ spin_lock_irqsave(&drv_data->lock, flags);
+ msg = drv_data->cur_msg;
+ drv_data->cur_msg = NULL;
+ drv_data->cur_transfer = NULL;
+ drv_data->cur_chip = NULL;
+ queue_work(drv_data->workqueue, &drv_data->pump_messages);
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+
+ last_transfer = list_entry(msg->transfers.prev,
+ struct spi_transfer, transfer_list);
+
+ msg->state = NULL;
+
+ /* disable chip select signal. And not stop spi in autobuffer mode */
+ if (drv_data->tx_dma != 0xFFFF) {
+ write_FLAG(0xFF00);
+ bfin_spi_disable(drv_data);
+ }
+
+ if (msg->complete)
+ msg->complete(msg->context);
+}
+
+static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct driver_data *drv_data = (struct driver_data *)dev_id;
+ struct spi_message *msg = drv_data->cur_msg;
+
+ pr_debug("in dma_irq_handler\n");
+ clear_dma_irqstat(CH_SPI);
+
+ /*
+ * wait for the last transaction shifted out. yes, these two
+ * while loops are supposed to be the same (see the HRM).
+ */
+ if (drv_data->tx != NULL) {
+ while (bfin_read_SPI_STAT() & TXS)
+ continue;
+ while (bfin_read_SPI_STAT() & TXS)
+ continue;
+ }
+
+ while (!(bfin_read_SPI_STAT() & SPIF))
+ continue;
+
+ bfin_spi_disable(drv_data);
+
+ msg->actual_length += drv_data->len_in_bytes;
+
+ /* Move to next transfer */
+ msg->state = next_transfer(drv_data);
+
+ /* Schedule transfer tasklet */
+ tasklet_schedule(&drv_data->pump_transfers);
+
+ /* free the irq handler before next transfer */
+ pr_debug("disable dma channel irq%d\n", CH_SPI);
+ dma_disable_irq(CH_SPI);
+
+ return IRQ_HANDLED;
+}
+
+static void pump_transfers(unsigned long data)
+{
+ struct driver_data *drv_data = (struct driver_data *)data;
+ struct spi_message *message = NULL;
+ struct spi_transfer *transfer = NULL;
+ struct spi_transfer *previous = NULL;
+ struct chip_data *chip = NULL;
+ u16 cr, width, dma_width, dma_config;
+ u32 tranf_success = 1;
+
+ /* Get current state information */
+ message = drv_data->cur_msg;
+ transfer = drv_data->cur_transfer;
+ chip = drv_data->cur_chip;
+
+ /*
+ * if msg is error or done, report it back using complete() callback
+ */
+
+ /* Handle for abort */
+ if (message->state == ERROR_STATE) {
+ message->status = -EIO;
+ giveback(drv_data);
+ return;
+ }
+
+ /* Handle end of message */
+ if (message->state == DONE_STATE) {
+ message->status = 0;
+ giveback(drv_data);
+ return;
+ }
+
+ /* Delay if requested at end of transfer */
+ if (message->state == RUNNING_STATE) {
+ previous = list_entry(transfer->transfer_list.prev,
+ struct spi_transfer, transfer_list);
+ if (previous->delay_usecs)
+ udelay(previous->delay_usecs);
+ }
+
+ /* Setup the transfer state based on the type of transfer */
+ if (flush(drv_data) == 0) {
+ dev_err(&drv_data->pdev->dev, "pump_transfers: flush failed\n");
+ message->status = -EIO;
+ giveback(drv_data);
+ return;
+ }
+
+ if (transfer->tx_buf != NULL) {
+ drv_data->tx = (void *)transfer->tx_buf;
+ drv_data->tx_end = drv_data->tx + transfer->len;
+ pr_debug("tx_buf is %p, tx_end is %p\n", transfer->tx_buf,
+ drv_data->tx_end);
+ } else {
+ drv_data->tx = NULL;
+ }
+
+ if (transfer->rx_buf != NULL) {
+ drv_data->rx = transfer->rx_buf;
+ drv_data->rx_end = drv_data->rx + transfer->len;
+ pr_debug("rx_buf is %p, rx_end is %p\n", transfer->rx_buf,
+ drv_data->rx_end);
+ } else {
+ drv_data->rx = NULL;
+ }
+
+ drv_data->rx_dma = transfer->rx_dma;
+ drv_data->tx_dma = transfer->tx_dma;
+ drv_data->len_in_bytes = transfer->len;
+
+ width = chip->width;
+ if (width == CFG_SPI_WORDSIZE16) {
+ drv_data->len = (transfer->len) >> 1;
+ } else {
+ drv_data->len = transfer->len;
+ }
+ drv_data->write = drv_data->tx ? chip->write : null_writer;
+ drv_data->read = drv_data->rx ? chip->read : null_reader;
+ drv_data->duplex = chip->duplex ? chip->duplex : null_writer;
+ pr_debug
+ ("transfer: drv_data->write is %p, chip->write is %p, null_wr is %p\n",
+ drv_data->write, chip->write, null_writer);
+
+ /* speed and width has been set on per message */
+ message->state = RUNNING_STATE;
+ dma_config = 0;
+
+ /* restore spi status for each spi transfer */
+ if (transfer->speed_hz) {
+ write_BAUD(hz_to_spi_baud(transfer->speed_hz));
+ } else {
+ write_BAUD(chip->baud);
+ }
+ write_FLAG(chip->flag);
+
+ pr_debug("now pumping a transfer: width is %d, len is %d\n", width,
+ transfer->len);
+
+ /*
+ * Try to map dma buffer and do a dma transfer if
+ * successful use different way to r/w according to
+ * drv_data->cur_chip->enable_dma
+ */
+ if (drv_data->cur_chip->enable_dma && drv_data->len > 6) {
+
+ write_STAT(BIT_STAT_CLR);
+ disable_dma(CH_SPI);
+ clear_dma_irqstat(CH_SPI);
+ bfin_spi_disable(drv_data);
+
+ /* config dma channel */
+ pr_debug("doing dma transfer\n");
+ if (width == CFG_SPI_WORDSIZE16) {
+ set_dma_x_count(CH_SPI, drv_data->len);
+ set_dma_x_modify(CH_SPI, 2);
+ dma_width = WDSIZE_16;
+ } else {
+ set_dma_x_count(CH_SPI, drv_data->len);
+ set_dma_x_modify(CH_SPI, 1);
+ dma_width = WDSIZE_8;
+ }
+
+ /* set transfer width,direction. And enable spi */
+ cr = (read_CTRL() & (~BIT_CTL_TIMOD));
+
+ /* dirty hack for autobuffer DMA mode */
+ if (drv_data->tx_dma == 0xFFFF) {
+ pr_debug("doing autobuffer DMA out.\n");
+
+ /* no irq in autobuffer mode */
+ dma_config =
+ (DMAFLOW_AUTO | RESTART | dma_width | DI_EN);
+ set_dma_config(CH_SPI, dma_config);
+ set_dma_start_addr(CH_SPI, (unsigned long)drv_data->tx);
+ enable_dma(CH_SPI);
+ write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) |
+ (CFG_SPI_ENABLE << 14));
+
+ /* just return here, there can only be one transfer in this mode */
+ message->status = 0;
+ giveback(drv_data);
+ return;
+ }
+
+ /* In dma mode, rx or tx must be NULL in one transfer */
+ if (drv_data->rx != NULL) {
+ /* set transfer mode, and enable SPI */
+ pr_debug("doing DMA in.\n");
+
+ /* disable SPI before write to TDBR */
+ write_CTRL(cr & ~BIT_CTL_ENABLE);
+
+ /* clear tx reg soformer data is not shifted out */
+ write_TDBR(0xFF);
+
+ set_dma_x_count(CH_SPI, drv_data->len);
+
+ /* start dma */
+ dma_enable_irq(CH_SPI);
+ dma_config = (WNR | RESTART | dma_width | DI_EN);
+ set_dma_config(CH_SPI, dma_config);
+ set_dma_start_addr(CH_SPI, (unsigned long)drv_data->rx);
+ enable_dma(CH_SPI);
+
+ cr |=
+ CFG_SPI_DMAREAD | (width << 8) | (CFG_SPI_ENABLE <<
+ 14);
+ /* set transfer mode, and enable SPI */
+ write_CTRL(cr);
+ } else if (drv_data->tx != NULL) {
+ pr_debug("doing DMA out.\n");
+
+ /* start dma */
+ dma_enable_irq(CH_SPI);
+ dma_config = (RESTART | dma_width | DI_EN);
+ set_dma_config(CH_SPI, dma_config);
+ set_dma_start_addr(CH_SPI, (unsigned long)drv_data->tx);
+ enable_dma(CH_SPI);
+
+ write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) |
+ (CFG_SPI_ENABLE << 14));
+
+ }
+ } else {
+ /* IO mode write then read */
+ pr_debug("doing IO transfer\n");
+
+ write_STAT(BIT_STAT_CLR);
+
+ if (drv_data->tx != NULL && drv_data->rx != NULL) {
+ /* full duplex mode */
+ BUG_ON((drv_data->tx_end - drv_data->tx) !=
+ (drv_data->rx_end - drv_data->rx));
+ cr = (read_CTRL() & (~BIT_CTL_TIMOD)); /* clear the TIMOD bits */
+ cr |=
+ CFG_SPI_WRITE | (width << 8) | (CFG_SPI_ENABLE <<
+ 14);
+ pr_debug("IO duplex: cr is 0x%x\n", cr);
+
+ write_CTRL(cr);
+ SSYNC();
+
+ drv_data->duplex(drv_data);
+
+ if (drv_data->tx != drv_data->tx_end)
+ tranf_success = 0;
+ } else if (drv_data->tx != NULL) {
+ /* write only half duplex */
+ cr = (read_CTRL() & (~BIT_CTL_TIMOD)); /* clear the TIMOD bits */
+ cr |=
+ CFG_SPI_WRITE | (width << 8) | (CFG_SPI_ENABLE <<
+ 14);
+ pr_debug("IO write: cr is 0x%x\n", cr);
+
+ write_CTRL(cr);
+ SSYNC();
+
+ drv_data->write(drv_data);
+
+ if (drv_data->tx != drv_data->tx_end)
+ tranf_success = 0;
+ } else if (drv_data->rx != NULL) {
+ /* read only half duplex */
+ cr = (read_CTRL() & (~BIT_CTL_TIMOD)); /* cleare the TIMOD bits */
+ cr |=
+ CFG_SPI_READ | (width << 8) | (CFG_SPI_ENABLE <<
+ 14);
+ pr_debug("IO read: cr is 0x%x\n", cr);
+
+ write_CTRL(cr);
+ SSYNC();
+
+ drv_data->read(drv_data);
+ if (drv_data->rx != drv_data->rx_end)
+ tranf_success = 0;
+ }
+
+ if (!tranf_success) {
+ pr_debug("IO write error!\n");
+ message->state = ERROR_STATE;
+ } else {
+ /* Update total byte transfered */
+ message->actual_length += drv_data->len;
+
+ /* Move to next transfer of this msg */
+ message->state = next_transfer(drv_data);
+ }
+
+ /* Schedule next transfer tasklet */
+ tasklet_schedule(&drv_data->pump_transfers);
+
+ }
+}
+
+/* pop a msg from queue and kick off real transfer */
+static void pump_messages(struct work_struct *work)
+{
+ struct driver_data *drv_data = container_of(work, struct driver_data, pump_messages);
+ unsigned long flags;
+
+ /* Lock queue and check for queue work */
+ spin_lock_irqsave(&drv_data->lock, flags);
+ if (list_empty(&drv_data->queue) || drv_data->run == QUEUE_STOPPED) {
+ /* pumper kicked off but no work to do */
+ drv_data->busy = 0;
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+ return;
+ }
+
+ /* Make sure we are not already running a message */
+ if (drv_data->cur_msg) {
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+ return;
+ }
+
+ /* Extract head of queue */
+ drv_data->cur_msg = list_entry(drv_data->queue.next,
+ struct spi_message, queue);
+ list_del_init(&drv_data->cur_msg->queue);
+
+ /* Initial message state */
+ drv_data->cur_msg->state = START_STATE;
+ drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
+ struct spi_transfer, transfer_list);
+
+ /* Setup the SSP using the per chip configuration */
+ drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
+ restore_state(drv_data);
+ pr_debug
+ ("got a message to pump, state is set to: baud %d, flag 0x%x, ctl 0x%x\n",
+ drv_data->cur_chip->baud, drv_data->cur_chip->flag,
+ drv_data->cur_chip->ctl_reg);
+ pr_debug("the first transfer len is %d\n", drv_data->cur_transfer->len);
+
+ /* Mark as busy and launch transfers */
+ tasklet_schedule(&drv_data->pump_transfers);
+
+ drv_data->busy = 1;
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+}
+
+/*
+ * got a msg to transfer, queue it in drv_data->queue.
+ * And kick off message pumper
+ */
+static int transfer(struct spi_device *spi, struct spi_message *msg)
+{
+ struct driver_data *drv_data = spi_master_get_devdata(spi->master);
+ unsigned long flags;
+
+ spin_lock_irqsave(&drv_data->lock, flags);
+
+ if (drv_data->run == QUEUE_STOPPED) {
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+ return -ESHUTDOWN;
+ }
+
+ msg->actual_length = 0;
+ msg->status = -EINPROGRESS;
+ msg->state = START_STATE;
+
+ pr_debug("adding an msg in transfer() \n");
+ list_add_tail(&msg->queue, &drv_data->queue);
+
+ if (drv_data->run == QUEUE_RUNNING && !drv_data->busy)
+ queue_work(drv_data->workqueue, &drv_data->pump_messages);
+
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+
+ return 0;
+}
+
+/* first setup for new devices */
+static int setup(struct spi_device *spi)
+{
+ struct bfin5xx_spi_chip *chip_info = NULL;
+ struct chip_data *chip;
+ struct driver_data *drv_data = spi_master_get_devdata(spi->master);
+ u8 spi_flg;
+
+ /* Abort device setup if requested features are not supported */
+ if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST)) {
+ dev_err(&spi->dev, "requested mode not fully supported\n");
+ return -EINVAL;
+ }
+
+ /* Zero (the default) here means 8 bits */
+ if (!spi->bits_per_word)
+ spi->bits_per_word = 8;
+
+ if (spi->bits_per_word != 8 && spi->bits_per_word != 16)
+ return -EINVAL;
+
+ /* Only alloc (or use chip_info) on first setup */
+ chip = spi_get_ctldata(spi);
+ if (chip == NULL) {
+ chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
+ if (!chip)
+ return -ENOMEM;
+
+ chip->enable_dma = 0;
+ chip_info = spi->controller_data;
+ }
+
+ /* chip_info isn't always needed */
+ if (chip_info) {
+ chip->enable_dma = chip_info->enable_dma != 0
+ && drv_data->master_info->enable_dma;
+ chip->ctl_reg = chip_info->ctl_reg;
+ chip->bits_per_word = chip_info->bits_per_word;
+ chip->cs_change_per_word = chip_info->cs_change_per_word;
+ chip->cs_chg_udelay = chip_info->cs_chg_udelay;
+ }
+
+ /* translate common spi framework into our register */
+ if (spi->mode & SPI_CPOL)
+ chip->ctl_reg |= CPOL;
+ if (spi->mode & SPI_CPHA)
+ chip->ctl_reg |= CPHA;
+ if (spi->mode & SPI_LSB_FIRST)
+ chip->ctl_reg |= LSBF;
+ /* we dont support running in slave mode (yet?) */
+ chip->ctl_reg |= MSTR;
+
+ /*
+ * if any one SPI chip is registered and wants DMA, request the
+ * DMA channel for it
+ */
+ if (chip->enable_dma && !dma_requested) {
+ /* register dma irq handler */
+ if (request_dma(CH_SPI, "BF53x_SPI_DMA") < 0) {
+ pr_debug
+ ("Unable to request BlackFin SPI DMA channel\n");
+ return -ENODEV;
+ }
+ if (set_dma_callback(CH_SPI, (void *)dma_irq_handler, drv_data)
+ < 0) {
+ pr_debug("Unable to set dma callback\n");
+ return -EPERM;
+ }
+ dma_disable_irq(CH_SPI);
+ dma_requested = 1;
+ }
+
+ /*
+ * Notice: for blackfin, the speed_hz is the value of register
+ * SPI_BAUD, not the real baudrate
+ */
+ chip->baud = hz_to_spi_baud(spi->max_speed_hz);
+ spi_flg = ~(1 << (spi->chip_select));
+ chip->flag = ((u16) spi_flg << 8) | (1 << (spi->chip_select));
+ chip->chip_select_num = spi->chip_select;
+
+ switch (chip->bits_per_word) {
+ case 8:
+ chip->n_bytes = 1;
+ chip->width = CFG_SPI_WORDSIZE8;
+ chip->read = chip->cs_change_per_word ?
+ u8_cs_chg_reader : u8_reader;
+ chip->write = chip->cs_change_per_word ?
+ u8_cs_chg_writer : u8_writer;
+ chip->duplex = chip->cs_change_per_word ?
+ u8_cs_chg_duplex : u8_duplex;
+ break;
+
+ case 16:
+ chip->n_bytes = 2;
+ chip->width = CFG_SPI_WORDSIZE16;
+ chip->read = chip->cs_change_per_word ?
+ u16_cs_chg_reader : u16_reader;
+ chip->write = chip->cs_change_per_word ?
+ u16_cs_chg_writer : u16_writer;
+ chip->duplex = chip->cs_change_per_word ?
+ u16_cs_chg_duplex : u16_duplex;
+ break;
+
+ default:
+ dev_err(&spi->dev, "%d bits_per_word is not supported\n",
+ chip->bits_per_word);
+ kfree(chip);
+ return -ENODEV;
+ }
+
+ pr_debug("setup spi chip %s, width is %d, dma is %d,",
+ spi->modalias, chip->width, chip->enable_dma);
+ pr_debug("ctl_reg is 0x%x, flag_reg is 0x%x\n",
+ chip->ctl_reg, chip->flag);
+
+ spi_set_ctldata(spi, chip);
+
+ return 0;
+}
+
+/*
+ * callback for spi framework.
+ * clean driver specific data
+ */
+static void cleanup(const struct spi_device *spi)
+{
+ struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi);
+
+ kfree(chip);
+}
+
+static inline int init_queue(struct driver_data *drv_data)
+{
+ INIT_LIST_HEAD(&drv_data->queue);
+ spin_lock_init(&drv_data->lock);
+
+ drv_data->run = QUEUE_STOPPED;
+ drv_data->busy = 0;
+
+ /* init transfer tasklet */
+ tasklet_init(&drv_data->pump_transfers,
+ pump_transfers, (unsigned long)drv_data);
+
+ /* init messages workqueue */
+ INIT_WORK(&drv_data->pump_messages, pump_messages);
+ drv_data->workqueue =
+ create_singlethread_workqueue(drv_data->master->cdev.dev->bus_id);
+ if (drv_data->workqueue == NULL)
+ return -EBUSY;
+
+ return 0;
+}
+
+static inline int start_queue(struct driver_data *drv_data)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&drv_data->lock, flags);
+
+ if (drv_data->run == QUEUE_RUNNING || drv_data->busy) {
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+ return -EBUSY;
+ }
+
+ drv_data->run = QUEUE_RUNNING;
+ drv_data->cur_msg = NULL;
+ drv_data->cur_transfer = NULL;
+ drv_data->cur_chip = NULL;
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+
+ queue_work(drv_data->workqueue, &drv_data->pump_messages);
+
+ return 0;
+}
+
+static inline int stop_queue(struct driver_data *drv_data)
+{
+ unsigned long flags;
+ unsigned limit = 500;
+ int status = 0;
+
+ spin_lock_irqsave(&drv_data->lock, flags);
+
+ /*
+ * This is a bit lame, but is optimized for the common execution path.
+ * A wait_queue on the drv_data->busy could be used, but then the common
+ * execution path (pump_messages) would be required to call wake_up or
+ * friends on every SPI message. Do this instead
+ */
+ drv_data->run = QUEUE_STOPPED;
+ while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+ msleep(10);
+ spin_lock_irqsave(&drv_data->lock, flags);
+ }
+
+ if (!list_empty(&drv_data->queue) || drv_data->busy)
+ status = -EBUSY;
+
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+
+ return status;
+}
+
+static inline int destroy_queue(struct driver_data *drv_data)
+{
+ int status;
+
+ status = stop_queue(drv_data);
+ if (status != 0)
+ return status;
+
+ destroy_workqueue(drv_data->workqueue);
+
+ return 0;
+}
+
+static int __init bfin5xx_spi_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct bfin5xx_spi_master *platform_info;
+ struct spi_master *master;
+ struct driver_data *drv_data = 0;
+ int status = 0;
+
+ platform_info = dev->platform_data;
+
+ /* Allocate master with space for drv_data */
+ master = spi_alloc_master(dev, sizeof(struct driver_data) + 16);
+ if (!master) {
+ dev_err(&pdev->dev, "can not alloc spi_master\n");
+ return -ENOMEM;
+ }
+ drv_data = spi_master_get_devdata(master);
+ drv_data->master = master;
+ drv_data->master_info = platform_info;
+ drv_data->pdev = pdev;
+
+ master->bus_num = pdev->id;
+ master->num_chipselect = platform_info->num_chipselect;
+ master->cleanup = cleanup;
+ master->setup = setup;
+ master->transfer = transfer;
+
+ /* Initial and start queue */
+ status = init_queue(drv_data);
+ if (status != 0) {
+ dev_err(&pdev->dev, "problem initializing queue\n");
+ goto out_error_queue_alloc;
+ }
+ status = start_queue(drv_data);
+ if (status != 0) {
+ dev_err(&pdev->dev, "problem starting queue\n");
+ goto out_error_queue_alloc;
+ }
+
+ /* Register with the SPI framework */
+ platform_set_drvdata(pdev, drv_data);
+ status = spi_register_master(master);
+ if (status != 0) {
+ dev_err(&pdev->dev, "problem registering spi master\n");
+ goto out_error_queue_alloc;
+ }
+ pr_debug("controller probe successfully\n");
+ return status;
+
+ out_error_queue_alloc:
+ destroy_queue(drv_data);
+ spi_master_put(master);
+ return status;
+}
+
+/* stop hardware and remove the driver */
+static int __devexit bfin5xx_spi_remove(struct platform_device *pdev)
+{
+ struct driver_data *drv_data = platform_get_drvdata(pdev);
+ int status = 0;
+
+ if (!drv_data)
+ return 0;
+
+ /* Remove the queue */
+ status = destroy_queue(drv_data);
+ if (status != 0)
+ return status;
+
+ /* Disable the SSP at the peripheral and SOC level */
+ bfin_spi_disable(drv_data);
+
+ /* Release DMA */
+ if (drv_data->master_info->enable_dma) {
+ if (dma_channel_active(CH_SPI))
+ free_dma(CH_SPI);
+ }
+
+ /* Disconnect from the SPI framework */
+ spi_unregister_master(drv_data->master);
+
+ /* Prevent double remove */
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int bfin5xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct driver_data *drv_data = platform_get_drvdata(pdev);
+ int status = 0;
+
+ status = stop_queue(drv_data);
+ if (status != 0)
+ return status;
+
+ /* stop hardware */
+ bfin_spi_disable(drv_data);
+
+ return 0;
+}
+
+static int bfin5xx_spi_resume(struct platform_device *pdev)
+{
+ struct driver_data *drv_data = platform_get_drvdata(pdev);
+ int status = 0;
+
+ /* Enable the SPI interface */
+ bfin_spi_enable(drv_data);
+
+ /* Start the queue running */
+ status = start_queue(drv_data);
+ if (status != 0) {
+ dev_err(&pdev->dev, "problem starting queue (%d)\n", status);
+ return status;
+ }
+
+ return 0;
+}
+#else
+#define bfin5xx_spi_suspend NULL
+#define bfin5xx_spi_resume NULL
+#endif /* CONFIG_PM */
+
+static struct platform_driver bfin5xx_spi_driver = {
+ .driver = {
+ .name = "bfin-spi-master",
+ .bus = &platform_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = bfin5xx_spi_probe,
+ .remove = __devexit_p(bfin5xx_spi_remove),
+ .suspend = bfin5xx_spi_suspend,
+ .resume = bfin5xx_spi_resume,
+};
+
+static int __init bfin5xx_spi_init(void)
+{
+ return platform_driver_register(&bfin5xx_spi_driver);
+}
+
+module_init(bfin5xx_spi_init);
+
+static void __exit bfin5xx_spi_exit(void)
+{
+ platform_driver_unregister(&bfin5xx_spi_driver);
+}
+
+module_exit(bfin5xx_spi_exit);
diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c
index 312987a..0ee2b20 100644
--- a/drivers/spi/spi_butterfly.c
+++ b/drivers/spi/spi_butterfly.c
@@ -20,7 +20,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/platform_device.h>
+#include <linux/device.h>
#include <linux/parport.h>
#include <linux/sched.h>
@@ -40,8 +40,6 @@
* and use this custom parallel port cable.
*/
-#undef HAVE_USI /* nyet */
-
/* DATA output bits (pins 2..9 == D0..D7) */
#define butterfly_nreset (1 << 1) /* pin 3 */
@@ -49,19 +47,13 @@
#define spi_sck_bit (1 << 0) /* pin 2 */
#define spi_mosi_bit (1 << 7) /* pin 9 */
-#define usi_sck_bit (1 << 3) /* pin 5 */
-#define usi_mosi_bit (1 << 4) /* pin 6 */
-
#define vcc_bits ((1 << 6) | (1 << 5)) /* pins 7, 8 */
/* STATUS input bits */
#define spi_miso_bit PARPORT_STATUS_BUSY /* pin 11 */
-#define usi_miso_bit PARPORT_STATUS_PAPEROUT /* pin 12 */
-
/* CONTROL output bits */
#define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */
-/* USI uses no chipselect */
@@ -70,15 +62,6 @@ static inline struct butterfly *spidev_to_pp(struct spi_device *spi)
return spi->controller_data;
}
-static inline int is_usidev(struct spi_device *spi)
-{
-#ifdef HAVE_USI
- return spi->chip_select != 1;
-#else
- return 0;
-#endif
-}
-
struct butterfly {
/* REVISIT ... for now, this must be first */
@@ -97,23 +80,13 @@ struct butterfly {
/*----------------------------------------------------------------------*/
-/*
- * these routines may be slower than necessary because they're hiding
- * the fact that there are two different SPI busses on this cable: one
- * to the DataFlash chip (or AVR SPI controller), the other to the
- * AVR USI controller.
- */
-
static inline void
setsck(struct spi_device *spi, int is_on)
{
struct butterfly *pp = spidev_to_pp(spi);
u8 bit, byte = pp->lastbyte;
- if (is_usidev(spi))
- bit = usi_sck_bit;
- else
- bit = spi_sck_bit;
+ bit = spi_sck_bit;
if (is_on)
byte |= bit;
@@ -129,10 +102,7 @@ setmosi(struct spi_device *spi, int is_on)
struct butterfly *pp = spidev_to_pp(spi);
u8 bit, byte = pp->lastbyte;
- if (is_usidev(spi))
- bit = usi_mosi_bit;
- else
- bit = spi_mosi_bit;
+ bit = spi_mosi_bit;
if (is_on)
byte |= bit;
@@ -148,10 +118,7 @@ static inline int getmiso(struct spi_device *spi)
int value;
u8 bit;
- if (is_usidev(spi))
- bit = usi_miso_bit;
- else
- bit = spi_miso_bit;
+ bit = spi_miso_bit;
/* only STATUS_BUSY is NOT negated */
value = !(parport_read_status(pp->port) & bit);
@@ -166,10 +133,6 @@ static void butterfly_chipselect(struct spi_device *spi, int value)
if (value != BITBANG_CS_INACTIVE)
setsck(spi, spi->mode & SPI_CPOL);
- /* no chipselect on this USI link config */
- if (is_usidev(spi))
- return;
-
/* here, value == "activate or not";
* most PARPORT_CONTROL_* bits are negated, so we must
* morph it to value == "bit value to write in control register"
@@ -237,24 +200,16 @@ static void butterfly_attach(struct parport *p)
int status;
struct butterfly *pp;
struct spi_master *master;
- struct platform_device *pdev;
+ struct device *dev = p->physport->dev;
- if (butterfly)
+ if (butterfly || !dev)
return;
/* REVISIT: this just _assumes_ a butterfly is there ... no probe,
* and no way to be selective about what it binds to.
*/
- /* FIXME where should master->cdev.dev come from?
- * e.g. /sys/bus/pnp0/00:0b, some PCI thing, etc
- * setting up a platform device like this is an ugly kluge...
- */
- pdev = platform_device_register_simple("butterfly", -1, NULL, 0);
- if (IS_ERR(pdev))
- return;
-
- master = spi_alloc_master(&pdev->dev, sizeof *pp);
+ master = spi_alloc_master(dev, sizeof *pp);
if (!master) {
status = -ENOMEM;
goto done;
@@ -300,7 +255,7 @@ static void butterfly_attach(struct parport *p)
parport_frob_control(pp->port, spi_cs_bit, 0);
/* stabilize power with chip in reset (nRESET), and
- * both spi_sck_bit and usi_sck_bit clear (CPOL=0)
+ * spi_sck_bit clear (CPOL=0)
*/
pp->lastbyte |= vcc_bits;
parport_write_data(pp->port, pp->lastbyte);
@@ -334,23 +289,6 @@ static void butterfly_attach(struct parport *p)
pr_debug("%s: dataflash at %s\n", p->name,
pp->dataflash->dev.bus_id);
-#ifdef HAVE_USI
- /* Bus 2 is only for talking to the AVR, and it can work no
- * matter who masters bus 1; needs appropriate AVR firmware.
- */
- pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000;
- strcpy(pp->info[1].modalias, "butterfly");
- // pp->info[1].platform_data = ... TBD ... ;
- pp->info[1].chip_select = 2,
- pp->info[1].controller_data = pp;
- pp->butterfly = spi_new_device(pp->bitbang.master, &pp->info[1]);
- if (pp->butterfly)
- pr_debug("%s: butterfly at %s\n", p->name,
- pp->butterfly->dev.bus_id);
-
- /* FIXME setup ACK for the IRQ line ... */
-#endif
-
// dev_info(_what?_, ...)
pr_info("%s: AVR Butterfly\n", p->name);
butterfly = pp;
@@ -366,14 +304,12 @@ clean1:
clean0:
(void) spi_master_put(pp->bitbang.master);
done:
- platform_device_unregister(pdev);
pr_debug("%s: butterfly probe, fail %d\n", p->name, status);
}
static void butterfly_detach(struct parport *p)
{
struct butterfly *pp;
- struct platform_device *pdev;
int status;
/* FIXME this global is ugly ... but, how to quickly get from
@@ -386,7 +322,6 @@ static void butterfly_detach(struct parport *p)
butterfly = NULL;
/* stop() unregisters child devices too */
- pdev = to_platform_device(pp->bitbang.master->cdev.dev);
status = spi_bitbang_stop(&pp->bitbang);
/* turn off VCC */
@@ -397,8 +332,6 @@ static void butterfly_detach(struct parport *p)
parport_unregister_device(pp->pd);
(void) spi_master_put(pp->bitbang.master);
-
- platform_device_unregister(pdev);
}
static struct parport_driver butterfly_driver = {
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index b10211c..d5a710f 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -342,8 +342,6 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)
goto err_register;
}
- dev_dbg(hw->dev, "shutdown=%d\n", hw->bitbang.shutdown);
-
/* register all the devices associated */
bi = &hw->pdata->board_info[0];
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
new file mode 100644
index 0000000..c0a6dce
--- /dev/null
+++ b/drivers/spi/spidev.c
@@ -0,0 +1,584 @@
+/*
+ * spidev.c -- simple synchronous userspace interface to SPI devices
+ *
+ * Copyright (C) 2006 SWAPP
+ * Andrea Paterniani <a.paterniani@swapp-eng.it>
+ * Copyright (C) 2007 David Brownell (simplification, cleanup)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ioctl.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/spidev.h>
+
+#include <asm/uaccess.h>
+
+
+/*
+ * This supports acccess to SPI devices using normal userspace I/O calls.
+ * Note that while traditional UNIX/POSIX I/O semantics are half duplex,
+ * and often mask message boundaries, full SPI support requires full duplex
+ * transfers. There are several kinds of of internal message boundaries to
+ * handle chipselect management and other protocol options.
+ *
+ * SPI has a character major number assigned. We allocate minor numbers
+ * dynamically using a bitmask. You must use hotplug tools, such as udev
+ * (or mdev with busybox) to create and destroy the /dev/spidevB.C device
+ * nodes, since there is no fixed association of minor numbers with any
+ * particular SPI bus or device.
+ */
+#define SPIDEV_MAJOR 153 /* assigned */
+#define N_SPI_MINORS 32 /* ... up to 256 */
+
+static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG];
+
+
+/* Bit masks for spi_device.mode management */
+#define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL)
+
+
+struct spidev_data {
+ struct device dev;
+ struct spi_device *spi;
+ struct list_head device_entry;
+
+ struct mutex buf_lock;
+ unsigned users;
+ u8 *buffer;
+};
+
+static LIST_HEAD(device_list);
+static DEFINE_MUTEX(device_list_lock);
+
+static unsigned bufsiz = 4096;
+module_param(bufsiz, uint, S_IRUGO);
+MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message");
+
+/*-------------------------------------------------------------------------*/
+
+/* Read-only message with current device setup */
+static ssize_t
+spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+ struct spidev_data *spidev;
+ struct spi_device *spi;
+ ssize_t status = 0;
+
+ /* chipselect only toggles at start or end of operation */
+ if (count > bufsiz)
+ return -EMSGSIZE;
+
+ spidev = filp->private_data;
+ spi = spidev->spi;
+
+ mutex_lock(&spidev->buf_lock);
+ status = spi_read(spi, spidev->buffer, count);
+ if (status == 0) {
+ unsigned long missing;
+
+ missing = copy_to_user(buf, spidev->buffer, count);
+ if (count && missing == count)
+ status = -EFAULT;
+ else
+ status = count - missing;
+ }
+ mutex_unlock(&spidev->buf_lock);
+
+ return status;
+}
+
+/* Write-only message with current device setup */
+static ssize_t
+spidev_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ struct spidev_data *spidev;
+ struct spi_device *spi;
+ ssize_t status = 0;
+ unsigned long missing;
+
+ /* chipselect only toggles at start or end of operation */
+ if (count > bufsiz)
+ return -EMSGSIZE;
+
+ spidev = filp->private_data;
+ spi = spidev->spi;
+
+ mutex_lock(&spidev->buf_lock);
+ missing = copy_from_user(spidev->buffer, buf, count);
+ if (missing == 0) {
+ status = spi_write(spi, spidev->buffer, count);
+ if (status == 0)
+ status = count;
+ } else
+ status = -EFAULT;
+ mutex_unlock(&spidev->buf_lock);
+
+ return status;
+}
+
+static int spidev_message(struct spidev_data *spidev,
+ struct spi_ioc_transfer *u_xfers, unsigned n_xfers)
+{
+ struct spi_message msg;
+ struct spi_transfer *k_xfers;
+ struct spi_transfer *k_tmp;
+ struct spi_ioc_transfer *u_tmp;
+ struct spi_device *spi = spidev->spi;
+ unsigned n, total;
+ u8 *buf;
+ int status = -EFAULT;
+
+ spi_message_init(&msg);
+ k_xfers = kcalloc(n_xfers, sizeof(*k_tmp), GFP_KERNEL);
+ if (k_xfers == NULL)
+ return -ENOMEM;
+
+ /* Construct spi_message, copying any tx data to bounce buffer.
+ * We walk the array of user-provided transfers, using each one
+ * to initialize a kernel version of the same transfer.
+ */
+ mutex_lock(&spidev->buf_lock);
+ buf = spidev->buffer;
+ total = 0;
+ for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers;
+ n;
+ n--, k_tmp++, u_tmp++) {
+ k_tmp->len = u_tmp->len;
+
+ if (u_tmp->rx_buf) {
+ k_tmp->rx_buf = buf;
+ if (!access_ok(VERIFY_WRITE, u_tmp->rx_buf, u_tmp->len))
+ goto done;
+ }
+ if (u_tmp->tx_buf) {
+ k_tmp->tx_buf = buf;
+ if (copy_from_user(buf, (const u8 __user *)u_tmp->tx_buf,
+ u_tmp->len))
+ goto done;
+ }
+
+ total += k_tmp->len;
+ if (total > bufsiz) {
+ status = -EMSGSIZE;
+ goto done;
+ }
+ buf += k_tmp->len;
+
+ k_tmp->cs_change = !!u_tmp->cs_change;
+ k_tmp->bits_per_word = u_tmp->bits_per_word;
+ k_tmp->delay_usecs = u_tmp->delay_usecs;
+ k_tmp->speed_hz = u_tmp->speed_hz;
+#ifdef VERBOSE
+ dev_dbg(&spi->dev,
+ " xfer len %zd %s%s%s%dbits %u usec %uHz\n",
+ u_tmp->len,
+ u_tmp->rx_buf ? "rx " : "",
+ u_tmp->tx_buf ? "tx " : "",
+ u_tmp->cs_change ? "cs " : "",
+ u_tmp->bits_per_word ? : spi->bits_per_word,
+ u_tmp->delay_usecs,
+ u_tmp->speed_hz ? : spi->max_speed_hz);
+#endif
+ spi_message_add_tail(k_tmp, &msg);
+ }
+
+ status = spi_sync(spi, &msg);
+ if (status < 0)
+ goto done;
+
+ /* copy any rx data out of bounce buffer */
+ buf = spidev->buffer;
+ for (n = n_xfers, u_tmp = u_xfers; n; n--, u_tmp++) {
+ if (u_tmp->rx_buf) {
+ if (__copy_to_user((u8 __user *)u_tmp->rx_buf, buf,
+ u_tmp->len)) {
+ status = -EFAULT;
+ goto done;
+ }
+ }
+ buf += u_tmp->len;
+ }
+ status = total;
+
+done:
+ mutex_unlock(&spidev->buf_lock);
+ kfree(k_xfers);
+ return status;
+}
+
+static int
+spidev_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+ int retval = 0;
+ struct spidev_data *spidev;
+ struct spi_device *spi;
+ u32 tmp;
+ unsigned n_ioc;
+ struct spi_ioc_transfer *ioc;
+
+ /* Check type and command number */
+ if (_IOC_TYPE(cmd) != SPI_IOC_MAGIC)
+ return -ENOTTY;
+
+ /* Check access direction once here; don't repeat below.
+ * IOC_DIR is from the user perspective, while access_ok is
+ * from the kernel perspective; so they look reversed.
+ */
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE,
+ (void __user *)arg, _IOC_SIZE(cmd));
+ if (err == 0 && _IOC_DIR(cmd) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ,
+ (void __user *)arg, _IOC_SIZE(cmd));
+ if (err)
+ return -EFAULT;
+
+ spidev = filp->private_data;
+ spi = spidev->spi;
+
+ switch (cmd) {
+ /* read requests */
+ case SPI_IOC_RD_MODE:
+ retval = __put_user(spi->mode & SPI_MODE_MASK,
+ (__u8 __user *)arg);
+ break;
+ case SPI_IOC_RD_LSB_FIRST:
+ retval = __put_user((spi->mode & SPI_LSB_FIRST) ? 1 : 0,
+ (__u8 __user *)arg);
+ break;
+ case SPI_IOC_RD_BITS_PER_WORD:
+ retval = __put_user(spi->bits_per_word, (__u8 __user *)arg);
+ break;
+ case SPI_IOC_RD_MAX_SPEED_HZ:
+ retval = __put_user(spi->max_speed_hz, (__u32 __user *)arg);
+ break;
+
+ /* write requests */
+ case SPI_IOC_WR_MODE:
+ retval = __get_user(tmp, (u8 __user *)arg);
+ if (retval == 0) {
+ u8 save = spi->mode;
+
+ if (tmp & ~SPI_MODE_MASK) {
+ retval = -EINVAL;
+ break;
+ }
+
+ tmp |= spi->mode & ~SPI_MODE_MASK;
+ spi->mode = (u8)tmp;
+ retval = spi_setup(spi);
+ if (retval < 0)
+ spi->mode = save;
+ else
+ dev_dbg(&spi->dev, "spi mode %02x\n", tmp);
+ }
+ break;
+ case SPI_IOC_WR_LSB_FIRST:
+ retval = __get_user(tmp, (__u8 __user *)arg);
+ if (retval == 0) {
+ u8 save = spi->mode;
+
+ if (tmp)
+ spi->mode |= SPI_LSB_FIRST;
+ else
+ spi->mode &= ~SPI_LSB_FIRST;
+ retval = spi_setup(spi);
+ if (retval < 0)
+ spi->mode = save;
+ else
+ dev_dbg(&spi->dev, "%csb first\n",
+ tmp ? 'l' : 'm');
+ }
+ break;
+ case SPI_IOC_WR_BITS_PER_WORD:
+ retval = __get_user(tmp, (__u8 __user *)arg);
+ if (retval == 0) {
+ u8 save = spi->bits_per_word;
+
+ spi->bits_per_word = tmp;
+ retval = spi_setup(spi);
+ if (retval < 0)
+ spi->bits_per_word = save;
+ else
+ dev_dbg(&spi->dev, "%d bits per word\n", tmp);
+ }
+ break;
+ case SPI_IOC_WR_MAX_SPEED_HZ:
+ retval = __get_user(tmp, (__u32 __user *)arg);
+ if (retval == 0) {
+ u32 save = spi->max_speed_hz;
+
+ spi->max_speed_hz = tmp;
+ retval = spi_setup(spi);
+ if (retval < 0)
+ spi->max_speed_hz = save;
+ else
+ dev_dbg(&spi->dev, "%d Hz (max)\n", tmp);
+ }
+ break;
+
+ default:
+ /* segmented and/or full-duplex I/O request */
+ if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0))
+ || _IOC_DIR(cmd) != _IOC_WRITE)
+ return -ENOTTY;
+
+ tmp = _IOC_SIZE(cmd);
+ if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) {
+ retval = -EINVAL;
+ break;
+ }
+ n_ioc = tmp / sizeof(struct spi_ioc_transfer);
+ if (n_ioc == 0)
+ break;
+
+ /* copy into scratch area */
+ ioc = kmalloc(tmp, GFP_KERNEL);
+ if (!ioc) {
+ retval = -ENOMEM;
+ break;
+ }
+ if (__copy_from_user(ioc, (void __user *)arg, tmp)) {
+ retval = -EFAULT;
+ break;
+ }
+
+ /* translate to spi_message, execute */
+ retval = spidev_message(spidev, ioc, n_ioc);
+ kfree(ioc);
+ break;
+ }
+ return retval;
+}
+
+static int spidev_open(struct inode *inode, struct file *filp)
+{
+ struct spidev_data *spidev;
+ int status = -ENXIO;
+
+ mutex_lock(&device_list_lock);
+
+ list_for_each_entry(spidev, &device_list, device_entry) {
+ if (spidev->dev.devt == inode->i_rdev) {
+ status = 0;
+ break;
+ }
+ }
+ if (status == 0) {
+ if (!spidev->buffer) {
+ spidev->buffer = kmalloc(bufsiz, GFP_KERNEL);
+ if (!spidev->buffer) {
+ dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
+ status = -ENOMEM;
+ }
+ }
+ if (status == 0) {
+ spidev->users++;
+ filp->private_data = spidev;
+ nonseekable_open(inode, filp);
+ }
+ } else
+ pr_debug("spidev: nothing for minor %d\n", iminor(inode));
+
+ mutex_unlock(&device_list_lock);
+ return status;
+}
+
+static int spidev_release(struct inode *inode, struct file *filp)
+{
+ struct spidev_data *spidev;
+ int status = 0;
+
+ mutex_lock(&device_list_lock);
+ spidev = filp->private_data;
+ filp->private_data = NULL;
+ spidev->users--;
+ if (!spidev->users) {
+ kfree(spidev->buffer);
+ spidev->buffer = NULL;
+ }
+ mutex_unlock(&device_list_lock);
+
+ return status;
+}
+
+static struct file_operations spidev_fops = {
+ .owner = THIS_MODULE,
+ /* REVISIT switch to aio primitives, so that userspace
+ * gets more complete API coverage. It'll simplify things
+ * too, except for the locking.
+ */
+ .write = spidev_write,
+ .read = spidev_read,
+ .ioctl = spidev_ioctl,
+ .open = spidev_open,
+ .release = spidev_release,
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* The main reason to have this class is to make mdev/udev create the
+ * /dev/spidevB.C character device nodes exposing our userspace API.
+ * It also simplifies memory management.
+ */
+
+static void spidev_classdev_release(struct device *dev)
+{
+ struct spidev_data *spidev;
+
+ spidev = container_of(dev, struct spidev_data, dev);
+ kfree(spidev);
+}
+
+static struct class spidev_class = {
+ .name = "spidev",
+ .owner = THIS_MODULE,
+ .dev_release = spidev_classdev_release,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int spidev_probe(struct spi_device *spi)
+{
+ struct spidev_data *spidev;
+ int status;
+ unsigned long minor;
+
+ /* Allocate driver data */
+ spidev = kzalloc(sizeof(*spidev), GFP_KERNEL);
+ if (!spidev)
+ return -ENOMEM;
+
+ /* Initialize the driver data */
+ spidev->spi = spi;
+ mutex_init(&spidev->buf_lock);
+
+ INIT_LIST_HEAD(&spidev->device_entry);
+
+ /* If we can allocate a minor number, hook up this device.
+ * Reusing minors is fine so long as udev or mdev is working.
+ */
+ mutex_lock(&device_list_lock);
+ minor = find_first_zero_bit(minors, ARRAY_SIZE(minors));
+ if (minor < N_SPI_MINORS) {
+ spidev->dev.parent = &spi->dev;
+ spidev->dev.class = &spidev_class;
+ spidev->dev.devt = MKDEV(SPIDEV_MAJOR, minor);
+ snprintf(spidev->dev.bus_id, sizeof spidev->dev.bus_id,
+ "spidev%d.%d",
+ spi->master->bus_num, spi->chip_select);
+ status = device_register(&spidev->dev);
+ } else {
+ dev_dbg(&spi->dev, "no minor number available!\n");
+ status = -ENODEV;
+ }
+ if (status == 0) {
+ set_bit(minor, minors);
+ dev_set_drvdata(&spi->dev, spidev);
+ list_add(&spidev->device_entry, &device_list);
+ }
+ mutex_unlock(&device_list_lock);
+
+ if (status != 0)
+ kfree(spidev);
+
+ return status;
+}
+
+static int spidev_remove(struct spi_device *spi)
+{
+ struct spidev_data *spidev = dev_get_drvdata(&spi->dev);
+
+ mutex_lock(&device_list_lock);
+
+ list_del(&spidev->device_entry);
+ dev_set_drvdata(&spi->dev, NULL);
+ clear_bit(MINOR(spidev->dev.devt), minors);
+ device_unregister(&spidev->dev);
+
+ mutex_unlock(&device_list_lock);
+
+ return 0;
+}
+
+static struct spi_driver spidev_spi = {
+ .driver = {
+ .name = "spidev",
+ .owner = THIS_MODULE,
+ },
+ .probe = spidev_probe,
+ .remove = __devexit_p(spidev_remove),
+
+ /* NOTE: suspend/resume methods are not necessary here.
+ * We don't do anything except pass the requests to/from
+ * the underlying controller. The refrigerator handles
+ * most issues; the controller driver handles the rest.
+ */
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int __init spidev_init(void)
+{
+ int status;
+
+ /* Claim our 256 reserved device numbers. Then register a class
+ * that will key udev/mdev to add/remove /dev nodes. Last, register
+ * the driver which manages those device numbers.
+ */
+ BUILD_BUG_ON(N_SPI_MINORS > 256);
+ status = register_chrdev(SPIDEV_MAJOR, "spi", &spidev_fops);
+ if (status < 0)
+ return status;
+
+ status = class_register(&spidev_class);
+ if (status < 0) {
+ unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);
+ return status;
+ }
+
+ status = spi_register_driver(&spidev_spi);
+ if (status < 0) {
+ class_unregister(&spidev_class);
+ unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);
+ }
+ return status;
+}
+module_init(spidev_init);
+
+static void __exit spidev_exit(void)
+{
+ spi_unregister_driver(&spidev_spi);
+ class_unregister(&spidev_class);
+ unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);
+}
+module_exit(spidev_exit);
+
+MODULE_AUTHOR("Andrea Paterniani, <a.paterniani@swapp-eng.it>");
+MODULE_DESCRIPTION("User mode SPI device interface");
+MODULE_LICENSE("GPL");
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index 71cb64e..c7b0a35 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -7692,7 +7692,7 @@ static int __init ixj_probe_pci(int *cnt)
IXJ *j = NULL;
for (i = 0; i < IXJMAX - *cnt; i++) {
- pci = pci_find_device(PCI_VENDOR_ID_QUICKNET,
+ pci = pci_get_device(PCI_VENDOR_ID_QUICKNET,
PCI_DEVICE_ID_QUICKNET_XJ, pci);
if (!pci)
break;
@@ -7712,6 +7712,7 @@ static int __init ixj_probe_pci(int *cnt)
printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase);
++*cnt;
}
+ pci_dev_put(pci);
return probe;
}
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 9980a4d..b847bbc 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -85,8 +85,6 @@ source "drivers/usb/class/Kconfig"
source "drivers/usb/storage/Kconfig"
-source "drivers/usb/input/Kconfig"
-
source "drivers/usb/image/Kconfig"
source "drivers/usb/net/Kconfig"
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index f5de58a..0ef090b 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -23,15 +23,6 @@ obj-$(CONFIG_USB_PRINTER) += class/
obj-$(CONFIG_USB_STORAGE) += storage/
obj-$(CONFIG_USB) += storage/
-obj-$(CONFIG_USB_ACECAD) += input/
-obj-$(CONFIG_USB_AIPTEK) += input/
-obj-$(CONFIG_USB_ATI_REMOTE) += input/
-obj-$(CONFIG_USB_KBTAB) += input/
-obj-$(CONFIG_USB_MTOUCH) += input/
-obj-$(CONFIG_USB_POWERMATE) += input/
-obj-$(CONFIG_USB_WACOM) += input/
-obj-$(CONFIG_USB_XPAD) += input/
-
obj-$(CONFIG_USB_CATC) += net/
obj-$(CONFIG_USB_KAWETH) += net/
obj-$(CONFIG_USB_PEGASUS) += net/
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index b3f779f..b082d95 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -77,7 +77,6 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/stat.h>
#include <linux/timer.h>
#include <linux/wait.h>
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 14de3b1..0081c1d 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -59,7 +59,6 @@
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 6584cf0..15e740e 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -49,7 +49,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/signal.h>
#include <linux/poll.h>
#include <linux/init.h>
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index bde29ab..f6b74a6 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -16,7 +16,6 @@
#include <linux/sched.h>
#include <linux/list.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/ioctl.h>
#include <linux/usb.h>
#include <linux/usbdevice_fs.h>
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index cddfc62..cd4f111 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -36,7 +36,6 @@
#include <linux/usb.h>
#include <linux/namei.h>
#include <linux/usbdevice_fs.h>
-#include <linux/smp_lock.h>
#include <linux/parser.h>
#include <linux/notifier.h>
#include <asm/byteorder.h>
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index dfd1b5c..18ddc5e 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -31,7 +31,6 @@
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
-#include <linux/smp_lock.h>
#include <linux/usb.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 2a6e316..ba163f3 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -31,7 +31,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/list.h>
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 7d7909c..fcb5526 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -41,7 +41,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 1dd8b57..325bf7c 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -28,7 +28,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 65c91d3..ae931af 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -30,7 +30,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 49d7377..52779c5 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -54,7 +54,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 2c043a1..84392e8 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -1483,7 +1483,7 @@ static void udc_disable(struct pxa2xx_udc *dev)
#ifdef CONFIG_ARCH_PXA
/* Disable clock for USB device */
- pxa_set_cken(CKEN11_USB, 0);
+ pxa_set_cken(CKEN_USB, 0);
#endif
ep0_idle (dev);
@@ -1529,7 +1529,7 @@ static void udc_enable (struct pxa2xx_udc *dev)
#ifdef CONFIG_ARCH_PXA
/* Enable clock for USB device */
- pxa_set_cken(CKEN11_USB, 1);
+ pxa_set_cken(CKEN_USB, 1);
udelay(5);
#endif
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index e552668..f847c34 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -22,7 +22,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 8c85e33..7078374 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -67,7 +67,6 @@
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index c7458f7..099aff6 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -24,7 +24,6 @@
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
index 4d781a2..37b83ba 100644
--- a/drivers/usb/host/ehci-ps3.c
+++ b/drivers/usb/host/ehci-ps3.c
@@ -73,13 +73,6 @@ static const struct hc_driver ps3_ehci_hc_driver = {
#endif
};
-#if !defined(DEBUG)
-#undef dev_dbg
-static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg(
- const struct device *_dev, const char *fmt, ...) {return 0;}
-#endif
-
-
static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
{
int result;
@@ -104,7 +97,7 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
__LINE__, dev->m_region->lpar_addr);
- result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq);
+ result = ps3_io_irq_setup(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq);
if (result) {
dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n",
@@ -162,7 +155,7 @@ fail_add_hcd:
fail_ioremap:
usb_put_hcd(hcd);
fail_create_hcd:
- ps3_free_io_irq(virq);
+ ps3_io_irq_destroy(virq);
fail_irq:
ps3_free_mmio_region(dev->m_region);
fail_mmio:
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index e8bbe8b..a66637e 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -26,7 +26,6 @@
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c
index 08e237c..c43b66a 100644
--- a/drivers/usb/host/ohci-ppc-of.c
+++ b/drivers/usb/host/ohci-ppc-of.c
@@ -97,8 +97,8 @@ ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match)
return -ENODEV;
is_bigendian =
- device_is_compatible(dn, "ohci-bigendian") ||
- device_is_compatible(dn, "ohci-be");
+ of_device_is_compatible(dn, "ohci-bigendian") ||
+ of_device_is_compatible(dn, "ohci-be");
dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n");
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index 62283a3..d7cf072 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -75,14 +75,6 @@ static const struct hc_driver ps3_ohci_hc_driver = {
#endif
};
-/* redefine dev_dbg to do a syntax check */
-
-#if !defined(DEBUG)
-#undef dev_dbg
-static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg(
- const struct device *_dev, const char *fmt, ...) {return 0;}
-#endif
-
static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
{
int result;
@@ -107,7 +99,7 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
__LINE__, dev->m_region->lpar_addr);
- result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq);
+ result = ps3_io_irq_setup(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq);
if (result) {
dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n",
@@ -165,7 +157,7 @@ fail_add_hcd:
fail_ioremap:
usb_put_hcd(hcd);
fail_create_hcd:
- ps3_free_io_irq(virq);
+ ps3_io_irq_destroy(virq);
fail_irq:
ps3_free_mmio_region(dev->m_region);
fail_mmio:
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index f1563dc..23d2fe5 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -80,7 +80,7 @@ static int pxa27x_start_hc(struct device *dev)
inf = dev->platform_data;
- pxa_set_cken(CKEN10_USBHOST, 1);
+ pxa_set_cken(CKEN_USBHOST, 1);
UHCHR |= UHCHR_FHR;
udelay(11);
@@ -123,7 +123,7 @@ static void pxa27x_stop_hc(struct device *dev)
UHCCOMS |= 1;
udelay(10);
- pxa_set_cken(CKEN10_USBHOST, 0);
+ pxa_set_cken(CKEN_USBHOST, 0);
}
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index 5fa5647..4cfa3ff 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -38,7 +38,6 @@
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index a7fa0d7..ff0dba0 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -43,7 +43,6 @@
#include <linux/pci_ids.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
index d308afd..36502a0 100644
--- a/drivers/usb/image/mdc800.c
+++ b/drivers/usb/image/mdc800.c
@@ -94,7 +94,6 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/wait.h>
#include <linux/mutex.h>
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index 896cb2b..51bd80d 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -128,7 +128,6 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/usb.h>
#include <linux/proc_fs.h>
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
deleted file mode 100644
index a792e42..0000000
--- a/drivers/usb/input/Kconfig
+++ /dev/null
@@ -1,225 +0,0 @@
-#
-# USB Input driver configuration
-#
-comment "USB Input Devices"
- depends on USB
-
-config USB_AIPTEK
- tristate "Aiptek 6000U/8000U tablet support"
- depends on USB && INPUT
- help
- Say Y here if you want to use the USB version of the Aiptek 6000U
- or Aiptek 8000U tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called aiptek.
-
-config USB_WACOM
- tristate "Wacom Intuos/Graphire tablet support"
- depends on USB && INPUT
- help
- Say Y here if you want to use the USB version of the Wacom Intuos
- or Graphire tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called wacom.
-
-config USB_ACECAD
- tristate "Acecad Flair tablet support"
- depends on USB && INPUT
- help
- Say Y here if you want to use the USB version of the Acecad Flair
- tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called acecad.
-
-config USB_KBTAB
- tristate "KB Gear JamStudio tablet support"
- depends on USB && INPUT
- help
- Say Y here if you want to use the USB version of the KB Gear
- JamStudio tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called kbtab.
-
-config USB_POWERMATE
- tristate "Griffin PowerMate and Contour Jog support"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use Griffin PowerMate or Contour Jog devices.
- These are aluminum dials which can measure clockwise and anticlockwise
- rotation. The dial also acts as a pushbutton. The base contains an LED
- which can be instructed to pulse or to switch to a particular intensity.
-
- You can download userspace tools from
- <http://sowerbutts.com/powermate/>.
-
- To compile this driver as a module, choose M here: the
- module will be called powermate.
-
-config USB_TOUCHSCREEN
- tristate "USB Touchscreen Driver"
- depends on USB && INPUT
- ---help---
- USB Touchscreen driver for:
- - eGalax Touchkit USB (also includes eTurboTouch CT-410/510/700)
- - PanJit TouchSet USB
- - 3M MicroTouch USB (EX II series)
- - ITM
- - some other eTurboTouch
- - Gunze AHL61
- - DMC TSC-10/25
-
- Have a look at <http://linux.chapter7.ch/touchkit/> for
- a usage description and the required user-space stuff.
-
- To compile this driver as a module, choose M here: the
- module will be called usbtouchscreen.
-
-config USB_TOUCHSCREEN_EGALAX
- default y
- bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_PANJIT
- default y
- bool "PanJit device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_3M
- default y
- bool "3M/Microtouch EX II series device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_ITM
- default y
- bool "ITM device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_ETURBO
- default y
- bool "eTurboTouch (non-eGalax compatible) device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_GUNZE
- default y
- bool "Gunze AHL61 device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_DMC_TSC10
- default y
- bool "DMC TSC-10/25 device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_YEALINK
- tristate "Yealink usb-p1k voip phone"
- depends on USB && INPUT && EXPERIMENTAL
- ---help---
- Say Y here if you want to enable keyboard and LCD functions of the
- Yealink usb-p1k usb phones. The audio part is enabled by the generic
- usb sound driver, so you might want to enable that as well.
-
- For information about how to use these additional functions, see
- <file:Documentation/input/yealink.txt>.
-
- To compile this driver as a module, choose M here: the module will be
- called yealink.
-
-config USB_XPAD
- tristate "X-Box gamepad support"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use the X-Box pad with your computer.
- Make sure to say Y to "Joystick support" (CONFIG_INPUT_JOYDEV)
- and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well.
-
- For information about how to connect the X-Box pad to USB, see
- <file:Documentation/input/xpad.txt>.
-
- To compile this driver as a module, choose M here: the
- module will be called xpad.
-
-config USB_ATI_REMOTE
- tristate "ATI / X10 USB RF remote control"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use an ATI or X10 "Lola" USB remote control.
- These are RF remotes with USB receivers.
- The ATI remote comes with many of ATI's All-In-Wonder video cards.
- The X10 "Lola" remote is available at:
- <http://www.x10.com/products/lola_sg1.htm>
- This driver provides mouse pointer, left and right mouse buttons,
- and maps all the other remote buttons to keypress events.
-
- To compile this driver as a module, choose M here: the module will be
- called ati_remote.
-
-config USB_ATI_REMOTE2
- tristate "ATI / Philips USB RF remote control"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use an ATI or Philips USB RF remote control.
- These are RF remotes with USB receivers.
- ATI Remote Wonder II comes with some ATI's All-In-Wonder video cards
- and is also available as a separate product.
- This driver provides mouse pointer, left and right mouse buttons,
- and maps all the other remote buttons to keypress events.
-
- To compile this driver as a module, choose M here: the module will be
- called ati_remote2.
-
-config USB_KEYSPAN_REMOTE
- tristate "Keyspan DMR USB remote control (EXPERIMENTAL)"
- depends on USB && INPUT && EXPERIMENTAL
- ---help---
- Say Y here if you want to use a Keyspan DMR USB remote control.
- Currently only the UIA-11 type of receiver has been tested. The tag
- on the receiver that connects to the USB port should have a P/N that
- will tell you what type of DMR you have. The UIA-10 type is not
- supported at this time. This driver maps all buttons to keypress
- events.
-
- To compile this driver as a module, choose M here: the module will
- be called keyspan_remote.
-
-config USB_APPLETOUCH
- tristate "Apple USB Touchpad support"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use an Apple USB Touchpad.
-
- These are the touchpads that can be found on post-February 2005
- Apple Powerbooks (prior models have a Synaptics touchpad connected
- to the ADB bus).
-
- This driver provides a basic mouse driver but can be interfaced
- with the synaptics X11 driver to provide acceleration and
- scrolling in X11.
-
- For further information, see
- <file:Documentation/input/appletouch.txt>.
-
- To compile this driver as a module, choose M here: the
- module will be called appletouch.
-
-config USB_GTCO
- tristate "GTCO CalComp/InterWrite USB Support"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use the USB version of the GTCO
- CalComp/InterWrite Tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called gtco.
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
deleted file mode 100644
index 284a073..0000000
--- a/drivers/usb/input/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Makefile for the USB input drivers
-#
-
-# Multipart objects.
-wacom-objs := wacom_wac.o wacom_sys.o
-
-obj-$(CONFIG_USB_AIPTEK) += aiptek.o
-obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o
-obj-$(CONFIG_USB_ATI_REMOTE2) += ati_remote2.o
-obj-$(CONFIG_USB_KBTAB) += kbtab.o
-obj-$(CONFIG_USB_KEYSPAN_REMOTE) += keyspan_remote.o
-obj-$(CONFIG_USB_TOUCHSCREEN) += usbtouchscreen.o
-obj-$(CONFIG_USB_POWERMATE) += powermate.o
-obj-$(CONFIG_USB_WACOM) += wacom.o
-obj-$(CONFIG_USB_ACECAD) += acecad.o
-obj-$(CONFIG_USB_YEALINK) += yealink.o
-obj-$(CONFIG_USB_XPAD) += xpad.o
-obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o
-obj-$(CONFIG_USB_GTCO) += gtco.o
-
-ifeq ($(CONFIG_USB_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
index 15c70bd..8d0e360 100644
--- a/drivers/usb/misc/idmouse.c
+++ b/drivers/usb/misc/idmouse.c
@@ -22,7 +22,6 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index 5dce797..1713e19 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -80,7 +80,6 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index fdf6847..88f6abe 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -39,7 +39,6 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
-#include <linux/smp_lock.h>
#include <linux/wait.h>
#include "rio500_usb.h"
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index 1730d86..5947afb 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -62,7 +62,6 @@
#include <linux/selection.h>
#include <linux/spinlock.h>
#include <linux/kref.h>
-#include <linux/smp_lock.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
@@ -322,7 +321,7 @@ sisusbcon_deinit(struct vc_data *c)
/* interface routine */
static u8
sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity,
- u8 blink, u8 underline, u8 reverse)
+ u8 blink, u8 underline, u8 reverse, u8 unused)
{
u8 attr = color;
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c
index 8a1df2c..8977ec0 100644
--- a/drivers/usb/mon/mon_main.c
+++ b/drivers/usb/mon/mon_main.c
@@ -9,7 +9,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/usb.h>
-#include <linux/smp_lock.h>
#include <linux/notifier.h>
#include <linux/mutex.h>
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 7639022..87f3788 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -28,7 +28,6 @@
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/list.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 21f3ddb..6dac1ff 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -47,7 +47,6 @@
#include <linux/usb.h>
#include <linux/usb_usual.h>
#include <linux/blkdev.h>
-#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/mutex.h>
#include <scsi/scsi_host.h>
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d18b51f..1132ba5 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -5,6 +5,11 @@
menu "Graphics support"
source "drivers/video/backlight/Kconfig"
+source "drivers/video/display/Kconfig"
+
+config VGASTATE
+ tristate
+ default n
config FB
tristate "Support for frame buffer devices"
@@ -90,6 +95,43 @@ config FB_CFB_IMAGEBLIT
blitting. This is used by drivers that don't provide their own
(accelerated) version.
+config FB_SYS_FILLRECT
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the sys_fillrect function for generic software rectangle
+ filling. This is used by drivers that don't provide their own
+ (accelerated) version and the framebuffer is in system RAM.
+
+config FB_SYS_COPYAREA
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the sys_copyarea function for generic software area copying.
+ This is used by drivers that don't provide their own (accelerated)
+ version and the framebuffer is in system RAM.
+
+config FB_SYS_IMAGEBLIT
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the sys_imageblit function for generic software image
+ blitting. This is used by drivers that don't provide their own
+ (accelerated) version and the framebuffer is in system RAM.
+
+config FB_SYS_FOPS
+ tristate
+ depends on FB
+ default n
+
+config FB_DEFERRED_IO
+ bool
+ depends on FB
+ default y
+
config FB_SVGALIB
tristate
depends on FB
@@ -191,7 +233,7 @@ config FB_ARMCLCD
If you want to compile this as a module (=code which can be
inserted into and removed from the running kernel), say M
- here and read <file:Documentation/modules.txt>. The module
+ here and read <file:Documentation/kbuild/modules.txt>. The module
will be called amba-clcd.
choice
@@ -375,9 +417,10 @@ config FB_FM2
config FB_ARC
tristate "Arc Monochrome LCD board support"
depends on FB && X86
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
help
This enables support for the Arc Monochrome LCD board. The board
is based on the KS-108 lcd controller and is typically a matrix
@@ -475,6 +518,8 @@ config FB_VGA16
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select VGASTATE
+ select FONT_8x16 if FRAMEBUFFER_CONSOLE
help
This is the frame buffer device driver for VGA 16 color graphic
cards. Say Y if you have such a card.
@@ -519,15 +564,25 @@ config FB_HP300
default y
config FB_TGA
- tristate "TGA framebuffer support"
- depends on FB && ALPHA
+ tristate "TGA/SFB+ framebuffer support"
+ depends on FB && (ALPHA || TC)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select BITREVERSE
- help
- This is the frame buffer device driver for generic TGA graphic
- cards. Say Y if you have one of those.
+ ---help---
+ This is the frame buffer device driver for generic TGA and SFB+
+ graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards,
+ also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3
+ TURBOchannel cards, also known as PMAGD-A, -B and -C.
+
+ Due to hardware limitations ZLX-E2 and E3 cards are not supported
+ for DECstation 5000/200 systems. Additionally due to firmware
+ limitations these cards may cause troubles with booting DECstation
+ 5000/240 and /260 systems, but are fully supported under Linux if
+ you manage to get it going. ;-)
+
+ Say Y if you have one of those.
config FB_VESA
bool "VESA VGA graphics support"
@@ -551,6 +606,21 @@ config FB_IMAC
help
This is the frame buffer device driver for the Intel-based Macintosh
+config FB_HECUBA
+ tristate "Hecuba board support"
+ depends on FB && X86 && MMU
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ help
+ This enables support for the Hecuba board. This driver was tested
+ with an E-Ink 800x600 display and x86 SBCs through a 16 bit GPIO
+ interface (8 bit data, 4 bit control). If you anticpate using
+ this driver, say Y or M; otherwise say N. You must specify the
+ GPIO IO address to be used for setting control and data.
+
config FB_HGA
tristate "Hercules mono graphics support"
depends on FB && X86
@@ -686,6 +756,7 @@ config FB_NVIDIA
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select BITREVERSE
+ select VGASTATE
help
This driver supports graphics boards with the nVidia chips, TNT
and newer. For very old chipsets, such as the RIVA128, then use
@@ -724,6 +795,7 @@ config FB_RIVA
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select BITREVERSE
+ select VGASTATE
help
This driver supports graphics boards with the nVidia Riva/Geforce
chips.
@@ -770,6 +842,7 @@ config FB_I810
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select VGASTATE
help
This driver supports the on-board graphics built in to the Intel 810
and 815 chipsets. Say Y if you have and plan to use such a board.
@@ -809,6 +882,22 @@ config FB_I810_I2C
select FB_DDC
help
+config FB_LE80578
+ tristate "Intel LE80578 (Vermilion) support"
+ depends on FB && PCI && X86
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This driver supports the LE80578 (Vermilion Range) chipset
+
+config FB_CARILLO_RANCH
+ tristate "Intel Carillo Ranch support"
+ depends on FB_LE80578 && FB && PCI && X86
+ help
+ This driver supports the LE80578 (Carillo Ranch) board
+
config FB_INTEL
tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G support (EXPERIMENTAL)"
depends on FB && EXPERIMENTAL && PCI && X86
@@ -1120,6 +1209,8 @@ config FB_S3
select FB_CFB_IMAGEBLIT
select FB_TILEBLITTING
select FB_SVGALIB
+ select VGASTATE
+ select FONT_8x16 if FRAMEBUFFER_CONSOLE
---help---
Driver for graphics boards with S3 Trio / S3 Virge chip.
@@ -1130,6 +1221,7 @@ config FB_SAVAGE
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select VGASTATE
help
This driver supports notebooks and computers with S3 Savage PCI/AGP
chips.
@@ -1196,6 +1288,7 @@ config FB_NEOMAGIC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select VGASTATE
help
This driver supports notebooks with NeoMagic PCI chips.
Say Y if you have such a graphics card.
@@ -1383,6 +1476,32 @@ config FB_LEO
This is the frame buffer device driver for the SBUS-based Sun ZX
(leo) frame buffer cards.
+config FB_XVR500
+ bool "Sun XVR-500 3DLABS Wildcat support"
+ depends on FB && PCI && SPARC64
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the Sun XVR-500 and similar
+ graphics cards based upon the 3DLABS Wildcat chipset. The driver
+ only works on sparc64 systems where the system firwmare has
+ mostly initialized the card already. It is treated as a
+ completely dumb framebuffer device.
+
+config FB_XVR2500
+ bool "Sun XVR-2500 3DLABS Wildcat support"
+ depends on FB && PCI && SPARC64
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the Sun XVR-2500 and similar
+ graphics cards based upon the 3DLABS Wildcat chipset. The driver
+ only works on sparc64 systems where the system firwmare has
+ mostly initialized the card already. It is treated as a
+ completely dumb framebuffer device.
+
config FB_PCI
bool "PCI framebuffers"
depends on (FB = y) && PCI && SPARC
@@ -1494,7 +1613,7 @@ config FB_PXA
This driver is also available as a module ( = code which can be
inserted and removed from the running kernel whenever you want). The
module will be called pxafb. If you want to compile it as a module,
- say M here and read <file:Documentation/modules.txt>.
+ say M here and read <file:Documentation/kbuild/modules.txt>.
If unsure, say N.
@@ -1547,7 +1666,7 @@ config FB_W100
This driver is also available as a module ( = code which can be
inserted and removed from the running kernel whenever you want). The
module will be called w100fb. If you want to compile it as a module,
- say M here and read <file:Documentation/modules.txt>.
+ say M here and read <file:Documentation/kbuild/modules.txt>.
If unsure, say N.
@@ -1564,7 +1683,7 @@ config FB_S3C2410
This driver is also available as a module ( = code which can be
inserted and removed from the running kernel whenever you want). The
module will be called s3c2410fb. If you want to compile it as a module,
- say M here and read <file:Documentation/modules.txt>.
+ say M here and read <file:Documentation/kbuild/modules.txt>.
If unsure, say N.
config FB_S3C2410_DEBUG
@@ -1636,13 +1755,25 @@ config FB_PS3_DEFAULT_SIZE_M
The default value can be overridden on the kernel command line
using the "ps3fb" option (e.g. "ps3fb=9M");
-config FB_VIRTUAL
- tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
- depends on FB
+config FB_XILINX
+ tristate "Xilinx frame buffer support"
+ depends on FB && XILINX_VIRTEX
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
---help---
+ Include support for the Xilinx ML300/ML403 reference design
+ framebuffer. ML300 carries a 640*480 LCD display on the board,
+ ML403 uses a standard DB15 VGA connector.
+
+config FB_VIRTUAL
+ tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
+ depends on FB
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ ---help---
This is a `virtual' frame buffer device. It operates on a chunk of
unswappable kernel memory instead of on the memory of a graphics
board. This means you cannot see any output sent to this frame
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 8693517..a916c20 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -4,6 +4,7 @@
# Each configuration option enables a list of files.
+obj-$(CONFIG_VGASTATE) += vgastate.o
obj-y += fb_notify.o
obj-$(CONFIG_FB) += fb.o
fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
@@ -12,14 +13,19 @@ fb-objs := $(fb-y)
obj-$(CONFIG_VT) += console/
obj-$(CONFIG_LOGO) += logo/
-obj-y += backlight/
+obj-y += backlight/ display/
obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
+obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o
+obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o
+obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
+obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o
obj-$(CONFIG_FB_SVGALIB) += svgalib.o
obj-$(CONFIG_FB_MACMODES) += macmodes.o
obj-$(CONFIG_FB_DDC) += fb_ddc.o
+obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
# Hardware specific drivers go first
obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o
@@ -30,7 +36,7 @@ obj-$(CONFIG_FB_PM2) += pm2fb.o
obj-$(CONFIG_FB_PM3) += pm3fb.o
obj-$(CONFIG_FB_MATROX) += matrox/
-obj-$(CONFIG_FB_RIVA) += riva/ vgastate.o
+obj-$(CONFIG_FB_RIVA) += riva/
obj-$(CONFIG_FB_NVIDIA) += nvidia/
obj-$(CONFIG_FB_ATY) += aty/ macmodes.o
obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o
@@ -40,8 +46,7 @@ obj-$(CONFIG_FB_KYRO) += kyro/
obj-$(CONFIG_FB_SAVAGE) += savage/
obj-$(CONFIG_FB_GEODE) += geode/
obj-$(CONFIG_FB_MBX) += mbx/
-obj-$(CONFIG_FB_I810) += vgastate.o
-obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o
+obj-$(CONFIG_FB_NEOMAGIC) += neofb.o
obj-$(CONFIG_FB_3DFX) += tdfxfb.o
obj-$(CONFIG_FB_CONTROL) += controlfb.o
obj-$(CONFIG_FB_PLATINUM) += platinumfb.o
@@ -51,7 +56,8 @@ obj-$(CONFIG_FB_IMSTT) += imsttfb.o
obj-$(CONFIG_FB_FM2) += fm2fb.o
obj-$(CONFIG_FB_CYBLA) += cyblafb.o
obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
-obj-$(CONFIG_FB_S3) += s3fb.o vgastate.o
+obj-$(CONFIG_FB_LE80578) += vermilion/
+obj-$(CONFIG_FB_S3) += s3fb.o
obj-$(CONFIG_FB_STI) += stifb.o
obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o
obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o
@@ -66,7 +72,10 @@ obj-$(CONFIG_FB_ACORN) += acornfb.o
obj-$(CONFIG_FB_ATARI) += atafb.o c2p.o atafb_mfb.o \
atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
obj-$(CONFIG_FB_MAC) += macfb.o
+obj-$(CONFIG_FB_HECUBA) += hecubafb.o
obj-$(CONFIG_FB_HGA) += hgafb.o
+obj-$(CONFIG_FB_XVR500) += sunxvr500.o
+obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o
obj-$(CONFIG_FB_IGA) += igafb.o
obj-$(CONFIG_FB_APOLLO) += dnfb.o
obj-$(CONFIG_FB_Q40) += q40fb.o
@@ -100,11 +109,12 @@ obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/
obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
obj-$(CONFIG_FB_PS3) += ps3fb.o
obj-$(CONFIG_FB_SM501) += sm501fb.o
+obj-$(CONFIG_FB_XILINX) += xilinxfb.o
# Platform or fallback drivers go here
obj-$(CONFIG_FB_VESA) += vesafb.o
obj-$(CONFIG_FB_IMAC) += imacfb.o
-obj-$(CONFIG_FB_VGA16) += vga16fb.o vgastate.o
+obj-$(CONFIG_FB_VGA16) += vga16fb.o
obj-$(CONFIG_FB_OF) += offb.o
# the test framebuffer is last
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index 30a83697..db15bac 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -262,7 +262,8 @@ static void arcfb_lcd_update_page(struct arcfb_par *par, unsigned int upper,
ks108_set_yaddr(par, chipindex, upper/8);
linesize = par->info->var.xres/8;
- src = par->info->screen_base + (left/8) + (upper * linesize);
+ src = (unsigned char __force *) par->info->screen_base + (left/8) +
+ (upper * linesize);
ks108_set_xaddr(par, chipindex, left);
bitmask=1;
@@ -368,7 +369,7 @@ static void arcfb_fillrect(struct fb_info *info,
{
struct arcfb_par *par = info->par;
- cfb_fillrect(info, rect);
+ sys_fillrect(info, rect);
/* update the physical lcd */
arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height);
@@ -379,7 +380,7 @@ static void arcfb_copyarea(struct fb_info *info,
{
struct arcfb_par *par = info->par;
- cfb_copyarea(info, area);
+ sys_copyarea(info, area);
/* update the physical lcd */
arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height);
@@ -389,7 +390,7 @@ static void arcfb_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct arcfb_par *par = info->par;
- cfb_imageblit(info, image);
+ sys_imageblit(info, image);
/* update the physical lcd */
arcfb_lcd_update(par, image->dx, image->dy, image->width,
@@ -439,14 +440,11 @@ static int arcfb_ioctl(struct fb_info *info,
* the fb. it's inefficient for them to do anything less than 64*8
* writes since we update the lcd in each write() anyway.
*/
-static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t count,
- loff_t *ppos)
+static ssize_t arcfb_write(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos)
{
/* modded from epson 1355 */
- struct inode *inode;
- int fbidx;
- struct fb_info *info;
unsigned long p;
int err=-EINVAL;
unsigned int fbmemlength,x,y,w,h, bitppos, startpos, endpos, bitcount;
@@ -454,13 +452,6 @@ static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t cou
unsigned int xres;
p = *ppos;
- inode = file->f_path.dentry->d_inode;
- fbidx = iminor(inode);
- info = registered_fb[fbidx];
-
- if (!info || !info->screen_base)
- return -ENODEV;
-
par = info->par;
xres = info->var.xres;
fbmemlength = (xres * info->var.yres)/8;
@@ -477,7 +468,7 @@ static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t cou
if (count) {
char *base_addr;
- base_addr = info->screen_base;
+ base_addr = (char __force *)info->screen_base;
count -= copy_from_user(base_addr + p, buf, count);
*ppos += count;
err = -EFAULT;
@@ -503,6 +494,7 @@ static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t cou
static struct fb_ops arcfb_ops = {
.owner = THIS_MODULE,
.fb_open = arcfb_open,
+ .fb_read = fb_sys_read,
.fb_write = arcfb_write,
.fb_release = arcfb_release,
.fb_pan_display = arcfb_pan_display,
@@ -603,7 +595,7 @@ static int arcfb_remove(struct platform_device *dev)
if (info) {
unregister_framebuffer(info);
- vfree(info->screen_base);
+ vfree((void __force *)info->screen_base);
framebuffer_release(info);
}
return 0;
diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/aty/ati_ids.h
index 39ab483..90e7df2 100644
--- a/drivers/video/aty/ati_ids.h
+++ b/drivers/video/aty/ati_ids.h
@@ -209,4 +209,4 @@
#define PCI_CHIP_R423_5D57 0x5D57
#define PCI_CHIP_RS350_7834 0x7834
#define PCI_CHIP_RS350_7835 0x7835
-
+#define PCI_CHIP_RS480_5955 0x5955
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index e86d7e0..7fea4d8 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -2165,18 +2165,29 @@ static void __devexit aty128_remove(struct pci_dev *pdev)
static int aty128fb_blank(int blank, struct fb_info *fb)
{
struct aty128fb_par *par = fb->par;
- u8 state = 0;
+ u8 state;
if (par->lock_blank || par->asleep)
return 0;
- if (blank & FB_BLANK_VSYNC_SUSPEND)
- state |= 2;
- if (blank & FB_BLANK_HSYNC_SUSPEND)
- state |= 1;
- if (blank & FB_BLANK_POWERDOWN)
- state |= 4;
-
+ switch (blank) {
+ case FB_BLANK_NORMAL:
+ state = 4;
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ state = 6;
+ break;
+ case FB_BLANK_HSYNC_SUSPEND:
+ state = 5;
+ break;
+ case FB_BLANK_POWERDOWN:
+ state = 7;
+ break;
+ case FB_BLANK_UNBLANK:
+ default:
+ state = 0;
+ break;
+ }
aty_st_8(CRTC_EXT_CNTL+1, state);
if (par->chip_gen == rage_M3) {
@@ -2430,7 +2441,7 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state)
wait_for_idle(par);
/* Blank display and LCD */
- aty128fb_blank(VESA_POWERDOWN, info);
+ aty128fb_blank(FB_BLANK_POWERDOWN, info);
/* Sleep */
par->asleep = 1;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 8514f2a..ea67dd9 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2297,20 +2297,6 @@ static int __devinit aty_init(struct fb_info *info)
par->pll_limits.xclk = 53;
}
#endif
- if (pll)
- par->pll_limits.pll_max = pll;
- if (mclk)
- par->pll_limits.mclk = mclk;
- if (xclk)
- par->pll_limits.xclk = xclk;
-
- aty_calc_mem_refresh(par, par->pll_limits.xclk);
- par->pll_per = 1000000/par->pll_limits.pll_max;
- par->mclk_per = 1000000/par->pll_limits.mclk;
- par->xclk_per = 1000000/par->pll_limits.xclk;
-
- par->ref_clk_per = 1000000000000ULL / 14318180;
- xtal = "14.31818";
#ifdef CONFIG_FB_ATY_GX
if (!M64_HAS(INTEGRATED)) {
@@ -2338,6 +2324,7 @@ static int __devinit aty_init(struct fb_info *info)
case DAC_IBMRGB514:
par->dac_ops = &aty_dac_ibm514;
break;
+#ifdef CONFIG_ATARI
case DAC_ATI68860_B:
case DAC_ATI68860_C:
par->dac_ops = &aty_dac_ati68860b;
@@ -2346,6 +2333,7 @@ static int __devinit aty_init(struct fb_info *info)
case DAC_ATT21C498:
par->dac_ops = &aty_dac_att21c498;
break;
+#endif
default:
PRINTKI("aty_init: DAC type not implemented yet!\n");
par->dac_ops = &aty_dac_unsupported;
@@ -2389,8 +2377,29 @@ static int __devinit aty_init(struct fb_info *info)
/* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
par->pll_limits.mclk = 63;
+ /* Mobility + 32bit memory interface need halved XCLK. */
+ if (M64_HAS(MOBIL_BUS) && par->ram_type == SDRAM32)
+ par->pll_limits.xclk = (par->pll_limits.xclk + 1) >> 1;
}
+#endif
+ /* Allow command line to override clocks. */
+ if (pll)
+ par->pll_limits.pll_max = pll;
+ if (mclk)
+ par->pll_limits.mclk = mclk;
+ if (xclk)
+ par->pll_limits.xclk = xclk;
+
+ aty_calc_mem_refresh(par, par->pll_limits.xclk);
+ par->pll_per = 1000000/par->pll_limits.pll_max;
+ par->mclk_per = 1000000/par->pll_limits.mclk;
+ par->xclk_per = 1000000/par->pll_limits.xclk;
+
+ par->ref_clk_per = 1000000000000ULL / 14318180;
+ xtal = "14.31818";
+
+#ifdef CONFIG_FB_ATY_CT
if (M64_HAS(GTB_DSP)) {
u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par);
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
index 1fdcfdb..cc9e977 100644
--- a/drivers/video/aty/mach64_ct.c
+++ b/drivers/video/aty/mach64_ct.c
@@ -608,12 +608,10 @@ static void aty_resume_pll_ct(const struct fb_info *info,
aty_st_pll_ct(SCLK_FB_DIV, pll->ct.sclk_fb_div, par);
aty_st_pll_ct(SPLL_CNTL2, pll->ct.spll_cntl2, par);
/*
- * The sclk has been started. However, I believe the first clock
- * ticks it generates are not very stable. Hope this primitive loop
- * helps for Rage Mobilities that sometimes crash when
- * we switch to sclk. (Daniel Mantione, 13-05-2003)
+ * SCLK has been started. Wait for the PLL to lock. 5 ms
+ * should be enough according to mach64 programmer's guide.
*/
- udelay(500);
+ mdelay(5);
}
aty_st_pll_ct(PLL_REF_DIV, pll->ct.pll_ref_div, par);
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index a4b3fd1..2ce0501 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -100,6 +100,8 @@
{ PCI_VENDOR_ID_ATI, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (flags) | (CHIP_FAMILY_##family) }
static struct pci_device_id radeonfb_pci_table[] = {
+ /* Radeon Xpress 200m */
+ CHIP_DEF(PCI_CHIP_RS480_5955, RS480, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
/* Mobility M6 */
CHIP_DEF(PCI_CHIP_RADEON_LY, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
CHIP_DEF(PCI_CHIP_RADEON_LZ, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
@@ -422,7 +424,7 @@ static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo)
if (dp == NULL)
return -ENODEV;
- val = get_property(dp, "ATY,RefCLK", NULL);
+ val = of_get_property(dp, "ATY,RefCLK", NULL);
if (!val || !*val) {
printk(KERN_WARNING "radeonfb: No ATY,RefCLK property !\n");
return -EINVAL;
@@ -430,11 +432,11 @@ static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo)
rinfo->pll.ref_clk = (*val) / 10;
- val = get_property(dp, "ATY,SCLK", NULL);
+ val = of_get_property(dp, "ATY,SCLK", NULL);
if (val && *val)
rinfo->pll.sclk = (*val) / 10;
- val = get_property(dp, "ATY,MCLK", NULL);
+ val = of_get_property(dp, "ATY,MCLK", NULL);
if (val && *val)
rinfo->pll.mclk = (*val) / 10;
@@ -1994,7 +1996,8 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
/* framebuffer size */
if ((rinfo->family == CHIP_FAMILY_RS100) ||
(rinfo->family == CHIP_FAMILY_RS200) ||
- (rinfo->family == CHIP_FAMILY_RS300)) {
+ (rinfo->family == CHIP_FAMILY_RS300) ||
+ (rinfo->family == CHIP_FAMILY_RS480) ) {
u32 tom = INREG(NB_TOM);
tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c
index 737b5c0..2030ed8 100644
--- a/drivers/video/aty/radeon_monitor.c
+++ b/drivers/video/aty/radeon_monitor.c
@@ -70,7 +70,7 @@ static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_
int i, mt = MT_NONE;
RTRACE("analyzing OF properties...\n");
- pmt = get_property(dp, "display-type", NULL);
+ pmt = of_get_property(dp, "display-type", NULL);
if (!pmt)
return MT_NONE;
RTRACE("display-type: %s\n", pmt);
@@ -89,7 +89,7 @@ static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_
}
for (i = 0; propnames[i] != NULL; ++i) {
- pedid = get_property(dp, propnames[i], NULL);
+ pedid = of_get_property(dp, propnames[i], NULL);
if (pedid != NULL)
break;
}
@@ -98,9 +98,10 @@ static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_
* single-head cards have hdno == -1 and skip this step
*/
if (pedid == NULL && dp->parent && (hdno != -1))
- pedid = get_property(dp->parent, (hdno == 0) ? "EDID1" : "EDID2", NULL);
+ pedid = of_get_property(dp->parent,
+ (hdno == 0) ? "EDID1" : "EDID2", NULL);
if (pedid == NULL && dp->parent && (hdno == 0))
- pedid = get_property(dp->parent, "EDID", NULL);
+ pedid = of_get_property(dp->parent, "EDID", NULL);
if (pedid == NULL)
return mt;
@@ -130,7 +131,7 @@ static int __devinit radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_
do {
if (!dp)
return MT_NONE;
- pname = get_property(dp, "name", NULL);
+ pname = of_get_property(dp, "name", NULL);
if (!pname)
return MT_NONE;
len = strlen(pname);
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index c411293..be1d57b 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -1290,7 +1290,7 @@ static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)
if (rinfo->of_node != NULL) {
int size;
- mrtable = get_property(rinfo->of_node, "ATY,MRT", &size);
+ mrtable = of_get_property(rinfo->of_node, "ATY,MRT", &size);
if (mrtable)
mrtable_size = size >> 2;
else
@@ -2826,11 +2826,15 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlis
rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM);
/* Enable/Disable dynamic clocks: TODO add sysfs access */
- rinfo->dynclk = dynclk;
- if (dynclk == 1) {
+ if (rinfo->family == CHIP_FAMILY_RS480)
+ rinfo->dynclk = -1;
+ else
+ rinfo->dynclk = dynclk;
+
+ if (rinfo->dynclk == 1) {
radeon_pm_enable_dynamic_mode(rinfo);
printk("radeonfb: Dynamic Clock Power Management enabled\n");
- } else if (dynclk == 0) {
+ } else if (rinfo->dynclk == 0) {
radeon_pm_disable_dynamic_mode(rinfo);
printk("radeonfb: Dynamic Clock Power Management disabled\n");
}
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 3190003..7ebffcd 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -48,6 +48,7 @@ enum radeon_family {
CHIP_FAMILY_RV350,
CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */
CHIP_FAMILY_R420, /* R420/R423/M18 */
+ CHIP_FAMILY_RS480,
CHIP_FAMILY_LAST,
};
@@ -64,7 +65,8 @@ enum radeon_family {
((rinfo)->family == CHIP_FAMILY_RV350) || \
((rinfo)->family == CHIP_FAMILY_R350) || \
((rinfo)->family == CHIP_FAMILY_RV380) || \
- ((rinfo)->family == CHIP_FAMILY_R420))
+ ((rinfo)->family == CHIP_FAMILY_R420) || \
+ ((rinfo)->family == CHIP_FAMILY_RS480) )
/*
* Chip flags
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 47d15b5..fbef663 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -63,3 +63,11 @@ config BACKLIGHT_PROGEAR
help
If you have a Frontpath ProGear say Y to enable the
backlight driver.
+
+config BACKLIGHT_CARILLO_RANCH
+ tristate "Intel Carillo Ranch Backlight Driver"
+ depends on BACKLIGHT_CLASS_DEVICE && LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578
+ default n
+ help
+ If you have a Intel LE80578 (Carillo Ranch) say Y to enable the
+ backlight driver.
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 0c3ce46..c6e2266 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
+obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
new file mode 100644
index 0000000..e9bbc34
--- /dev/null
+++ b/drivers/video/backlight/cr_bllcd.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * This file is part of the Carillo Ranch video subsystem driver.
+ * The Carillo Ranch video subsystem driver is free software;
+ * you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Carillo Ranch video subsystem driver is distributed
+ * in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ * Alan Hourihane <alanh-at-tungstengraphics-dot-com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <linux/pci.h>
+#include <asm/uaccess.h>
+
+/* The LVDS- and panel power controls sits on the
+ * GPIO port of the ISA bridge.
+ */
+
+#define CRVML_DEVICE_LPC 0x27B8
+#define CRVML_REG_GPIOBAR 0x48
+#define CRVML_REG_GPIOEN 0x4C
+#define CRVML_GPIOEN_BIT (1 << 4)
+#define CRVML_PANEL_PORT 0x38
+#define CRVML_LVDS_ON 0x00000001
+#define CRVML_PANEL_ON 0x00000002
+#define CRVML_BACKLIGHT_OFF 0x00000004
+
+/* The PLL Clock register sits on Host bridge */
+#define CRVML_DEVICE_MCH 0x5001
+#define CRVML_REG_MCHBAR 0x44
+#define CRVML_REG_MCHEN 0x54
+#define CRVML_MCHEN_BIT (1 << 28)
+#define CRVML_MCHMAP_SIZE 4096
+#define CRVML_REG_CLOCK 0xc3c
+#define CRVML_CLOCK_SHIFT 8
+#define CRVML_CLOCK_MASK 0x00000f00
+
+static struct pci_dev *lpc_dev;
+static u32 gpio_bar;
+
+struct cr_panel {
+ struct backlight_device *cr_backlight_device;
+ struct lcd_device *cr_lcd_device;
+};
+
+static int cr_backlight_set_intensity(struct backlight_device *bd)
+{
+ int intensity = bd->props.brightness;
+ u32 addr = gpio_bar + CRVML_PANEL_PORT;
+ u32 cur = inl(addr);
+
+ if (bd->props.power == FB_BLANK_UNBLANK)
+ intensity = FB_BLANK_UNBLANK;
+ if (bd->props.fb_blank == FB_BLANK_UNBLANK)
+ intensity = FB_BLANK_UNBLANK;
+ if (bd->props.power == FB_BLANK_POWERDOWN)
+ intensity = FB_BLANK_POWERDOWN;
+ if (bd->props.fb_blank == FB_BLANK_POWERDOWN)
+ intensity = FB_BLANK_POWERDOWN;
+
+ if (intensity == FB_BLANK_UNBLANK) { /* FULL ON */
+ cur &= ~CRVML_BACKLIGHT_OFF;
+ outl(cur, addr);
+ } else if (intensity == FB_BLANK_POWERDOWN) { /* OFF */
+ cur |= CRVML_BACKLIGHT_OFF;
+ outl(cur, addr);
+ } /* anything else, don't bother */
+
+ return 0;
+}
+
+static int cr_backlight_get_intensity(struct backlight_device *bd)
+{
+ u32 addr = gpio_bar + CRVML_PANEL_PORT;
+ u32 cur = inl(addr);
+ u8 intensity;
+
+ if (cur & CRVML_BACKLIGHT_OFF)
+ intensity = FB_BLANK_POWERDOWN;
+ else
+ intensity = FB_BLANK_UNBLANK;
+
+ return intensity;
+}
+
+static struct backlight_ops cr_backlight_ops = {
+ .get_brightness = cr_backlight_get_intensity,
+ .update_status = cr_backlight_set_intensity,
+};
+
+static void cr_panel_on(void)
+{
+ u32 addr = gpio_bar + CRVML_PANEL_PORT;
+ u32 cur = inl(addr);
+
+ if (!(cur & CRVML_PANEL_ON)) {
+ /* Make sure LVDS controller is down. */
+ if (cur & 0x00000001) {
+ cur &= ~CRVML_LVDS_ON;
+ outl(cur, addr);
+ }
+ /* Power up Panel */
+ schedule_timeout(HZ / 10);
+ cur |= CRVML_PANEL_ON;
+ outl(cur, addr);
+ }
+
+ /* Power up LVDS controller */
+
+ if (!(cur & CRVML_LVDS_ON)) {
+ schedule_timeout(HZ / 10);
+ outl(cur | CRVML_LVDS_ON, addr);
+ }
+}
+
+static void cr_panel_off(void)
+{
+ u32 addr = gpio_bar + CRVML_PANEL_PORT;
+ u32 cur = inl(addr);
+
+ /* Power down LVDS controller first to avoid high currents */
+ if (cur & CRVML_LVDS_ON) {
+ cur &= ~CRVML_LVDS_ON;
+ outl(cur, addr);
+ }
+ if (cur & CRVML_PANEL_ON) {
+ schedule_timeout(HZ / 10);
+ outl(cur & ~CRVML_PANEL_ON, addr);
+ }
+}
+
+static int cr_lcd_set_power(struct lcd_device *ld, int power)
+{
+ if (power == FB_BLANK_UNBLANK)
+ cr_panel_on();
+ if (power == FB_BLANK_POWERDOWN)
+ cr_panel_off();
+
+ return 0;
+}
+
+static struct lcd_ops cr_lcd_ops = {
+ .set_power = cr_lcd_set_power,
+};
+
+static int cr_backlight_probe(struct platform_device *pdev)
+{
+ struct cr_panel *crp;
+ u8 dev_en;
+
+ crp = kzalloc(sizeof(crp), GFP_KERNEL);
+ if (crp == NULL)
+ return -ENOMEM;
+
+ lpc_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
+ CRVML_DEVICE_LPC, NULL);
+ if (!lpc_dev) {
+ printk("INTEL CARILLO RANCH LPC not found.\n");
+ return -ENODEV;
+ }
+
+ pci_read_config_byte(lpc_dev, CRVML_REG_GPIOEN, &dev_en);
+ if (!(dev_en & CRVML_GPIOEN_BIT)) {
+ printk(KERN_ERR
+ "Carillo Ranch GPIO device was not enabled.\n");
+ pci_dev_put(lpc_dev);
+ return -ENODEV;
+ }
+
+ crp->cr_backlight_device = backlight_device_register("cr-backlight",
+ &pdev->dev, NULL,
+ &cr_backlight_ops);
+ if (IS_ERR(crp->cr_backlight_device)) {
+ pci_dev_put(lpc_dev);
+ return PTR_ERR(crp->cr_backlight_device);
+ }
+
+ crp->cr_lcd_device = lcd_device_register("cr-lcd",
+ &pdev->dev,
+ &cr_lcd_ops);
+
+ if (IS_ERR(crp->cr_lcd_device)) {
+ pci_dev_put(lpc_dev);
+ return PTR_ERR(crp->cr_backlight_device);
+ }
+
+ pci_read_config_dword(lpc_dev, CRVML_REG_GPIOBAR,
+ &gpio_bar);
+ gpio_bar &= ~0x3F;
+
+ crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK;
+ crp->cr_backlight_device->props.brightness = 0;
+ crp->cr_backlight_device->props.max_brightness = 0;
+ cr_backlight_set_intensity(crp->cr_backlight_device);
+
+ cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK);
+
+ platform_set_drvdata(pdev, crp);
+
+ return 0;
+}
+
+static int cr_backlight_remove(struct platform_device *pdev)
+{
+ struct cr_panel *crp = platform_get_drvdata(pdev);
+ crp->cr_backlight_device->props.power = FB_BLANK_POWERDOWN;
+ crp->cr_backlight_device->props.brightness = 0;
+ crp->cr_backlight_device->props.max_brightness = 0;
+ cr_backlight_set_intensity(crp->cr_backlight_device);
+ cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_POWERDOWN);
+ backlight_device_unregister(crp->cr_backlight_device);
+ lcd_device_unregister(crp->cr_lcd_device);
+ pci_dev_put(lpc_dev);
+
+ return 0;
+}
+
+static struct platform_driver cr_backlight_driver = {
+ .probe = cr_backlight_probe,
+ .remove = cr_backlight_remove,
+ .driver = {
+ .name = "cr_backlight",
+ },
+};
+
+static struct platform_device *crp;
+
+static int __init cr_backlight_init(void)
+{
+ int ret = platform_driver_register(&cr_backlight_driver);
+
+ if (!ret) {
+ crp = platform_device_alloc("cr_backlight", -1);
+ if (!crp)
+ return -ENOMEM;
+
+ ret = platform_device_add(crp);
+
+ if (ret) {
+ platform_device_put(crp);
+ platform_driver_unregister(&cr_backlight_driver);
+ }
+ }
+
+ printk("Carillo Ranch Backlight Driver Initialized.\n");
+
+ return ret;
+}
+
+static void __exit cr_backlight_exit(void)
+{
+ platform_device_unregister(crp);
+ platform_driver_unregister(&cr_backlight_driver);
+}
+
+module_init(cr_backlight_init);
+module_exit(cr_backlight_exit);
+
+MODULE_AUTHOR("Tungsten Graphics Inc.");
+MODULE_DESCRIPTION("Carillo Ranch Backlight Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index 6faea40..032210f 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -22,8 +22,6 @@
* help moving some redundant computations and branches out of the loop, too.
*/
-
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
@@ -31,6 +29,7 @@
#include <linux/slab.h>
#include <asm/types.h>
#include <asm/io.h>
+#include "fb_draw.h"
#if BITS_PER_LONG == 32
# define FB_WRITEL fb_writel
@@ -41,17 +40,6 @@
#endif
/*
- * Compose two values, using a bitmask as decision value
- * This is equivalent to (a & mask) | (b & ~mask)
- */
-
-static inline unsigned long
-comp(unsigned long a, unsigned long b, unsigned long mask)
-{
- return ((a ^ b) & mask) ^ b;
-}
-
- /*
* Generic bitwise copy algorithm
*/
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
index f00b50a..71623b4 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/cfbfillrect.c
@@ -21,6 +21,7 @@
#include <linux/string.h>
#include <linux/fb.h>
#include <asm/types.h>
+#include "fb_draw.h"
#if BITS_PER_LONG == 32
# define FB_WRITEL fb_writel
@@ -31,73 +32,6 @@
#endif
/*
- * Compose two values, using a bitmask as decision value
- * This is equivalent to (a & mask) | (b & ~mask)
- */
-
-static inline unsigned long
-comp(unsigned long a, unsigned long b, unsigned long mask)
-{
- return ((a ^ b) & mask) ^ b;
-}
-
- /*
- * Create a pattern with the given pixel's color
- */
-
-#if BITS_PER_LONG == 64
-static inline unsigned long
-pixel_to_pat( u32 bpp, u32 pixel)
-{
- switch (bpp) {
- case 1:
- return 0xfffffffffffffffful*pixel;
- case 2:
- return 0x5555555555555555ul*pixel;
- case 4:
- return 0x1111111111111111ul*pixel;
- case 8:
- return 0x0101010101010101ul*pixel;
- case 12:
- return 0x0001001001001001ul*pixel;
- case 16:
- return 0x0001000100010001ul*pixel;
- case 24:
- return 0x0000000001000001ul*pixel;
- case 32:
- return 0x0000000100000001ul*pixel;
- default:
- panic("pixel_to_pat(): unsupported pixelformat\n");
- }
-}
-#else
-static inline unsigned long
-pixel_to_pat( u32 bpp, u32 pixel)
-{
- switch (bpp) {
- case 1:
- return 0xfffffffful*pixel;
- case 2:
- return 0x55555555ul*pixel;
- case 4:
- return 0x11111111ul*pixel;
- case 8:
- return 0x01010101ul*pixel;
- case 12:
- return 0x00001001ul*pixel;
- case 16:
- return 0x00010001ul*pixel;
- case 24:
- return 0x00000001ul*pixel;
- case 32:
- return 0x00000001ul*pixel;
- default:
- panic("pixel_to_pat(): unsupported pixelformat\n");
- }
-}
-#endif
-
- /*
* Aligned pattern fill using 32/64-bit memory accesses
*/
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 2c4bc62..8269d70 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -98,15 +98,6 @@
#define assert(expr)
#endif
-#ifdef TRUE
-#undef TRUE
-#endif
-#ifdef FALSE
-#undef FALSE
-#endif
-#define TRUE 1
-#define FALSE 0
-
#define MB_ (1024*1024)
#define KB_ (1024)
@@ -146,9 +137,9 @@ static const struct cirrusfb_board_info_rec {
char *name; /* ASCII name of chipset */
long maxclock[5]; /* maximum video clock */
/* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */
- unsigned init_sr07 : 1; /* init SR07 during init_vgachip() */
- unsigned init_sr1f : 1; /* write SR1F during init_vgachip() */
- unsigned scrn_start_bit19 : 1; /* construct bit 19 of screen start address */
+ bool init_sr07 : 1; /* init SR07 during init_vgachip() */
+ bool init_sr1f : 1; /* write SR1F during init_vgachip() */
+ bool scrn_start_bit19 : 1; /* construct bit 19 of screen start address */
/* initial SR07 value, then for each mode */
unsigned char sr07;
@@ -166,9 +157,9 @@ static const struct cirrusfb_board_info_rec {
/* the SD64/P4 have a higher max. videoclock */
140000, 140000, 140000, 140000, 140000,
},
- .init_sr07 = TRUE,
- .init_sr1f = TRUE,
- .scrn_start_bit19 = TRUE,
+ .init_sr07 = true,
+ .init_sr1f = true,
+ .scrn_start_bit19 = true,
.sr07 = 0xF0,
.sr07_1bpp = 0xF0,
.sr07_8bpp = 0xF1,
@@ -180,9 +171,9 @@ static const struct cirrusfb_board_info_rec {
/* guess */
90000, 90000, 90000, 90000, 90000
},
- .init_sr07 = TRUE,
- .init_sr1f = TRUE,
- .scrn_start_bit19 = FALSE,
+ .init_sr07 = true,
+ .init_sr1f = true,
+ .scrn_start_bit19 = false,
.sr07 = 0x80,
.sr07_1bpp = 0x80,
.sr07_8bpp = 0x81,
@@ -194,9 +185,9 @@ static const struct cirrusfb_board_info_rec {
/* guess */
90000, 90000, 90000, 90000, 90000
},
- .init_sr07 = TRUE,
- .init_sr1f = TRUE,
- .scrn_start_bit19 = FALSE,
+ .init_sr07 = true,
+ .init_sr1f = true,
+ .scrn_start_bit19 = false,
.sr07 = 0x20,
.sr07_1bpp = 0x20,
.sr07_8bpp = 0x21,
@@ -208,9 +199,9 @@ static const struct cirrusfb_board_info_rec {
/* guess */
90000, 90000, 90000, 90000, 90000
},
- .init_sr07 = TRUE,
- .init_sr1f = TRUE,
- .scrn_start_bit19 = FALSE,
+ .init_sr07 = true,
+ .init_sr1f = true,
+ .scrn_start_bit19 = false,
.sr07 = 0x80,
.sr07_1bpp = 0x80,
.sr07_8bpp = 0x81,
@@ -221,9 +212,9 @@ static const struct cirrusfb_board_info_rec {
.maxclock = {
135100, 135100, 85500, 85500, 0
},
- .init_sr07 = TRUE,
- .init_sr1f = FALSE,
- .scrn_start_bit19 = TRUE,
+ .init_sr07 = true,
+ .init_sr1f = false,
+ .scrn_start_bit19 = true,
.sr07 = 0x20,
.sr07_1bpp = 0x20,
.sr07_8bpp = 0x21,
@@ -235,9 +226,9 @@ static const struct cirrusfb_board_info_rec {
/* for the GD5430. GD5446 can do more... */
85500, 85500, 50000, 28500, 0
},
- .init_sr07 = TRUE,
- .init_sr1f = TRUE,
- .scrn_start_bit19 = TRUE,
+ .init_sr07 = true,
+ .init_sr1f = true,
+ .scrn_start_bit19 = true,
.sr07 = 0xA0,
.sr07_1bpp = 0xA1,
.sr07_1bpp_mux = 0xA7,
@@ -250,9 +241,9 @@ static const struct cirrusfb_board_info_rec {
.maxclock = {
135100, 200000, 200000, 135100, 135100
},
- .init_sr07 = TRUE,
- .init_sr1f = TRUE,
- .scrn_start_bit19 = TRUE,
+ .init_sr07 = true,
+ .init_sr1f = true,
+ .scrn_start_bit19 = true,
.sr07 = 0x10,
.sr07_1bpp = 0x11,
.sr07_8bpp = 0x11,
@@ -264,9 +255,9 @@ static const struct cirrusfb_board_info_rec {
/* guess */
135100, 135100, 135100, 135100, 135100,
},
- .init_sr07 = FALSE,
- .init_sr1f = FALSE,
- .scrn_start_bit19 = TRUE,
+ .init_sr07 = false,
+ .init_sr1f = false,
+ .scrn_start_bit19 = true,
}
};
@@ -815,7 +806,7 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
default:
DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
- assert (FALSE);
+ assert(false);
/* should never occur */
break;
}
@@ -886,7 +877,7 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
default:
DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
- assert (FALSE);
+ assert(false);
/* should never occur */
break;
}
@@ -3203,7 +3194,7 @@ void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_clas
break;
default:
/* should never occur */
- assert (FALSE);
+ assert(false);
break;
}
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 0429fd2..73813c6 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -107,7 +107,9 @@ static struct display fb_display[MAX_NR_CONSOLES];
static signed char con2fb_map[MAX_NR_CONSOLES];
static signed char con2fb_map_boot[MAX_NR_CONSOLES];
+#ifndef MODULE
static int logo_height;
+#endif
static int logo_lines;
/* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO
enums. */
@@ -576,6 +578,13 @@ static int fbcon_takeover(int show_logo)
return err;
}
+#ifdef MODULE
+static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
+ int cols, int rows, int new_cols, int new_rows)
+{
+ logo_shown = FBCON_LOGO_DONTSHOW;
+}
+#else
static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
int cols, int rows, int new_cols, int new_rows)
{
@@ -584,6 +593,11 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
int cnt, erase = vc->vc_video_erase_char, step;
unsigned short *save = NULL, *r, *q;
+ if (info->flags & FBINFO_MODULE) {
+ logo_shown = FBCON_LOGO_DONTSHOW;
+ return;
+ }
+
/*
* remove underline attribute from erase character
* if black and white framebuffer.
@@ -618,8 +632,13 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
r -= cols;
}
if (!save) {
- vc->vc_y += logo_lines;
- vc->vc_pos += logo_lines * vc->vc_size_row;
+ int lines;
+ if (vc->vc_y + logo_lines >= rows)
+ lines = rows - vc->vc_y - 1;
+ else
+ lines = logo_lines;
+ vc->vc_y += lines;
+ vc->vc_pos += lines * vc->vc_size_row;
}
}
scr_memsetw((unsigned short *) vc->vc_origin,
@@ -650,6 +669,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
vc->vc_top = logo_lines;
}
}
+#endif /* MODULE */
#ifdef CONFIG_FB_TILEBLITTING
static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
@@ -665,6 +685,17 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
fbcon_set_bitops(ops);
}
}
+
+static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount)
+{
+ int err = 0;
+
+ if (info->flags & FBINFO_MISC_TILEBLITTING &&
+ info->tileops->fb_get_tilemax(info) < charcount)
+ err = 1;
+
+ return err;
+}
#else
static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
{
@@ -675,6 +706,12 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
fbcon_set_rotation(info);
fbcon_set_bitops(ops);
}
+
+static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount)
+{
+ return 0;
+}
+
#endif /* CONFIG_MISC_TILEBLITTING */
@@ -968,7 +1005,9 @@ static const char *fbcon_startup(void)
if (!p->fontdata) {
if (!fontname[0] || !(font = find_font(fontname)))
font = get_default_font(info->var.xres,
- info->var.yres);
+ info->var.yres,
+ info->pixmap.blit_x,
+ info->pixmap.blit_y);
vc->vc_font.width = font->width;
vc->vc_font.height = font->height;
vc->vc_font.data = (void *)(p->fontdata = font->data);
@@ -1088,7 +1127,9 @@ static void fbcon_init(struct vc_data *vc, int init)
if (!fontname[0] || !(font = find_font(fontname)))
font = get_default_font(info->var.xres,
- info->var.yres);
+ info->var.yres,
+ info->pixmap.blit_x,
+ info->pixmap.blit_y);
vc->vc_font.width = font->width;
vc->vc_font.height = font->height;
vc->vc_font.data = (void *)(p->fontdata = font->data);
@@ -1305,7 +1346,7 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
int y;
int c = scr_readw((u16 *) vc->vc_pos);
- if (fbcon_is_inactive(vc, info))
+ if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1)
return;
ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1;
@@ -2475,6 +2516,7 @@ static int fbcon_copy_font(struct vc_data *vc, int con)
static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigned flags)
{
+ struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
unsigned charcount = font->charcount;
int w = font->width;
int h = font->height;
@@ -2488,6 +2530,15 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne
if (charcount != 256 && charcount != 512)
return -EINVAL;
+ /* Make sure drawing engine can handle the font */
+ if (!(info->pixmap.blit_x & (1 << (font->width - 1))) ||
+ !(info->pixmap.blit_y & (1 << (font->height - 1))))
+ return -EINVAL;
+
+ /* Make sure driver can handle the font length */
+ if (fbcon_invalid_charcount(info, charcount))
+ return -EINVAL;
+
size = h * pitch * charcount;
new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER);
@@ -2532,7 +2583,8 @@ static int fbcon_set_def_font(struct vc_data *vc, struct console_font *font, cha
const struct font_desc *f;
if (!name)
- f = get_default_font(info->var.xres, info->var.yres);
+ f = get_default_font(info->var.xres, info->var.yres,
+ info->pixmap.blit_x, info->pixmap.blit_y);
else if (!(f = find_font(name)))
return -ENOENT;
@@ -2829,7 +2881,7 @@ static void fbcon_set_all_vcs(struct fb_info *info)
struct fbcon_ops *ops = info->fbcon_par;
struct vc_data *vc;
struct display *p;
- int i, rows, cols;
+ int i, rows, cols, fg = -1;
if (!ops || ops->currcon < 0)
return;
@@ -2840,34 +2892,23 @@ static void fbcon_set_all_vcs(struct fb_info *info)
registered_fb[con2fb_map[i]] != info)
continue;
+ if (CON_IS_VISIBLE(vc)) {
+ fg = i;
+ continue;
+ }
+
p = &fb_display[vc->vc_num];
set_blitting_type(vc, info);
var_to_display(p, &info->var, info);
- cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
- rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ cols = FBCON_SWAP(p->rotate, info->var.xres, info->var.yres);
+ rows = FBCON_SWAP(p->rotate, info->var.yres, info->var.xres);
cols /= vc->vc_font.width;
rows /= vc->vc_font.height;
vc_resize(vc, cols, rows);
-
- if (CON_IS_VISIBLE(vc)) {
- updatescrollmode(p, info, vc);
- scrollback_max = 0;
- scrollback_current = 0;
-
- if (!fbcon_is_inactive(vc, info)) {
- ops->var.xoffset = ops->var.yoffset =
- p->yscroll = 0;
- ops->update_start(info);
- }
-
- fbcon_set_palette(vc, color_table);
- update_screen(vc);
- if (softback_buf)
- fbcon_update_softback(vc);
- }
}
- ops->p = &fb_display[ops->currcon];
+ if (fg != -1)
+ fbcon_modechanged(info);
}
static int fbcon_mode_deleted(struct fb_info *info,
@@ -3002,6 +3043,42 @@ static void fbcon_new_modelist(struct fb_info *info)
}
}
+static void fbcon_get_requirement(struct fb_info *info,
+ struct fb_blit_caps *caps)
+{
+ struct vc_data *vc;
+ struct display *p;
+
+ if (caps->flags) {
+ int i, charcnt;
+
+ for (i = first_fb_vc; i <= last_fb_vc; i++) {
+ vc = vc_cons[i].d;
+ if (vc && vc->vc_mode == KD_TEXT &&
+ info->node == con2fb_map[i]) {
+ p = &fb_display[i];
+ caps->x |= 1 << (vc->vc_font.width - 1);
+ caps->y |= 1 << (vc->vc_font.height - 1);
+ charcnt = (p->userfont) ?
+ FNTCHARCNT(p->fontdata) : 256;
+ if (caps->len < charcnt)
+ caps->len = charcnt;
+ }
+ }
+ } else {
+ vc = vc_cons[fg_console].d;
+
+ if (vc && vc->vc_mode == KD_TEXT &&
+ info->node == con2fb_map[fg_console]) {
+ p = &fb_display[fg_console];
+ caps->x = 1 << (vc->vc_font.width - 1);
+ caps->y = 1 << (vc->vc_font.height - 1);
+ caps->len = (p->userfont) ?
+ FNTCHARCNT(p->fontdata) : 256;
+ }
+ }
+}
+
static int fbcon_event_notify(struct notifier_block *self,
unsigned long action, void *data)
{
@@ -3009,6 +3086,7 @@ static int fbcon_event_notify(struct notifier_block *self,
struct fb_info *info = event->info;
struct fb_videomode *mode;
struct fb_con2fbmap *con2fb;
+ struct fb_blit_caps *caps;
int ret = 0;
/*
@@ -3057,6 +3135,10 @@ static int fbcon_event_notify(struct notifier_block *self,
case FB_EVENT_NEW_MODELIST:
fbcon_new_modelist(info);
break;
+ case FB_EVENT_GET_REQ:
+ caps = event->data;
+ fbcon_get_requirement(info, caps);
+ break;
}
done:
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
index c960728..a6828d0 100644
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -98,6 +98,8 @@ const struct font_desc *find_font(const char *name)
* get_default_font - get default font
* @xres: screen size of X
* @yres: screen size of Y
+ * @font_w: bit array of supported widths (1 - 32)
+ * @font_h: bit array of supported heights (1 - 32)
*
* Get the default font for a specified screen size.
* Dimensions are in pixels.
@@ -107,7 +109,8 @@ const struct font_desc *find_font(const char *name)
*
*/
-const struct font_desc *get_default_font(int xres, int yres)
+const struct font_desc *get_default_font(int xres, int yres, u32 font_w,
+ u32 font_h)
{
int i, c, cc;
const struct font_desc *f, *g;
@@ -129,6 +132,11 @@ const struct font_desc *get_default_font(int xres, int yres)
#endif
if ((yres < 400) == (f->height <= 8))
c += 1000;
+
+ if (!(font_w & (1 << (f->width - 1))) ||
+ !(font_w & (1 << (f->height - 1))))
+ c += 1000;
+
if (c > cc) {
cc = c;
g = f;
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index 124ecbe..bd8d995 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -384,7 +384,7 @@ static inline u16 mda_convert_attr(u16 ch)
}
static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
- u8 blink, u8 underline, u8 reverse)
+ u8 blink, u8 underline, u8 reverse, u8 italic)
{
/* The attribute is just a bit vector:
*
@@ -397,6 +397,7 @@ static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
return (intensity & 3) |
((underline & 1) << 2) |
((reverse & 1) << 3) |
+ (!!italic << 4) |
((blink & 1) << 7);
}
diff --git a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c
index b78eac6..ae02e4e 100644
--- a/drivers/video/console/promcon.c
+++ b/drivers/video/console/promcon.c
@@ -548,7 +548,8 @@ promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
}
#if !(PROMCON_COLOR)
-static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse)
+static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity,
+ u8 _blink, u8 _underline, u8 _reverse, u8 _italic)
{
return (_reverse) ? 0xf : 0x7;
}
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 57b21e5..67a682d 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -314,7 +314,7 @@ static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos,
}
static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens,
- u8 blink, u8 underline, u8 reverse)
+ u8 blink, u8 underline, u8 reverse, u8 italic)
{
u8 attr = ((color & 0x70) >> 1) | ((color & 7));
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index 88e7038..717b360 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c
@@ -495,7 +495,7 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
return NULL;
fbfont = find_font(fbfont_name);
if (!fbfont)
- fbfont = get_default_font(1024,768);
+ fbfont = get_default_font(1024,768, ~(u32)0, ~(u32)0);
if (!fbfont)
return NULL;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 3e67c34..2460b82 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -86,8 +86,6 @@ static int vgacon_set_origin(struct vc_data *c);
static void vgacon_save_screen(struct vc_data *c);
static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
int lines);
-static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
- u8 blink, u8 underline, u8 reverse);
static void vgacon_invert_region(struct vc_data *c, u16 * p, int count);
static unsigned long vgacon_uni_pagedir[2];
@@ -578,12 +576,14 @@ static void vgacon_deinit(struct vc_data *c)
}
static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
- u8 blink, u8 underline, u8 reverse)
+ u8 blink, u8 underline, u8 reverse, u8 italic)
{
u8 attr = color;
if (vga_can_do_color) {
- if (underline)
+ if (italic)
+ attr = (attr & 0xF0) | c->vc_itcolor;
+ else if (underline)
attr = (attr & 0xf0) | c->vc_ulcolor;
else if (intensity == 0)
attr = (attr & 0xf0) | c->vc_halfcolor;
@@ -597,7 +597,9 @@ static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
if (intensity == 2)
attr ^= 0x08;
if (!vga_can_do_color) {
- if (underline)
+ if (italic)
+ attr = (attr & 0xF8) | 0x02;
+ else if (underline)
attr = (attr & 0xf8) | 0x01;
else if (intensity == 0)
attr = (attr & 0xf0) | 0x08;
@@ -658,6 +660,9 @@ static void vgacon_set_cursor_size(int xpos, int from, int to)
static void vgacon_cursor(struct vc_data *c, int mode)
{
+ if (c->vc_mode != KD_TEXT)
+ return;
+
vgacon_restore_screen(c);
switch (mode) {
@@ -1316,7 +1321,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
unsigned long oldo;
unsigned int delta;
- if (t || b != c->vc_rows || vga_is_gfx)
+ if (t || b != c->vc_rows || vga_is_gfx || c->vc_mode != KD_TEXT)
return 0;
if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2)
diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig
new file mode 100644
index 0000000..f99af93
--- /dev/null
+++ b/drivers/video/display/Kconfig
@@ -0,0 +1,24 @@
+#
+# Display drivers configuration
+#
+
+menu "Display device support"
+
+config DISPLAY_SUPPORT
+ tristate "Display panel/monitor support"
+ ---help---
+ This framework adds support for low-level control of a display.
+ This includes support for power.
+
+ Enable this to be able to choose the drivers for controlling the
+ physical display panel/monitor on some platforms. This not only
+ covers LCD displays for PDAs but also other types of displays
+ such as CRT, TVout etc.
+
+ To have support for your specific display panel you will have to
+ select the proper drivers which depend on this option.
+
+comment "Display hardware drivers"
+ depends on DISPLAY_SUPPORT
+
+endmenu
diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile
new file mode 100644
index 0000000..c0ea832
--- /dev/null
+++ b/drivers/video/display/Makefile
@@ -0,0 +1,6 @@
+# Display drivers
+
+display-objs := display-sysfs.o
+
+obj-$(CONFIG_DISPLAY_SUPPORT) += display.o
+
diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c
new file mode 100644
index 0000000..3547717
--- /dev/null
+++ b/drivers/video/display/display-sysfs.c
@@ -0,0 +1,217 @@
+/*
+ * display-sysfs.c - Display output driver sysfs interface
+ *
+ * Copyright (C) 2007 James Simmons <jsimmons@infradead.org>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <linux/module.h>
+#include <linux/display.h>
+#include <linux/ctype.h>
+#include <linux/idr.h>
+#include <linux/err.h>
+
+static ssize_t display_show_name(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct display_device *dsp = dev_get_drvdata(dev);
+ return snprintf(buf, PAGE_SIZE, "%s\n", dsp->name);
+}
+
+static ssize_t display_show_type(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct display_device *dsp = dev_get_drvdata(dev);
+ return snprintf(buf, PAGE_SIZE, "%s\n", dsp->type);
+}
+
+static ssize_t display_show_contrast(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct display_device *dsp = dev_get_drvdata(dev);
+ ssize_t rc = -ENXIO;
+
+ mutex_lock(&dsp->lock);
+ if (likely(dsp->driver) && dsp->driver->get_contrast)
+ rc = sprintf(buf, "%d\n", dsp->driver->get_contrast(dsp));
+ mutex_unlock(&dsp->lock);
+ return rc;
+}
+
+static ssize_t display_store_contrast(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct display_device *dsp = dev_get_drvdata(dev);
+ ssize_t ret = -EINVAL, size;
+ int contrast;
+ char *endp;
+
+ contrast = simple_strtoul(buf, &endp, 0);
+ size = endp - buf;
+
+ if (*endp && isspace(*endp))
+ size++;
+
+ if (size != count)
+ return ret;
+
+ mutex_lock(&dsp->lock);
+ if (likely(dsp->driver && dsp->driver->set_contrast)) {
+ pr_debug("display: set contrast to %d\n", contrast);
+ dsp->driver->set_contrast(dsp, contrast);
+ ret = count;
+ }
+ mutex_unlock(&dsp->lock);
+ return ret;
+}
+
+static ssize_t display_show_max_contrast(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct display_device *dsp = dev_get_drvdata(dev);
+ ssize_t rc = -ENXIO;
+
+ mutex_lock(&dsp->lock);
+ if (likely(dsp->driver))
+ rc = sprintf(buf, "%d\n", dsp->driver->max_contrast);
+ mutex_unlock(&dsp->lock);
+ return rc;
+}
+
+static struct device_attribute display_attrs[] = {
+ __ATTR(name, S_IRUGO, display_show_name, NULL),
+ __ATTR(type, S_IRUGO, display_show_type, NULL),
+ __ATTR(contrast, S_IRUGO | S_IWUSR, display_show_contrast, display_store_contrast),
+ __ATTR(max_contrast, S_IRUGO, display_show_max_contrast, NULL),
+};
+
+static int display_suspend(struct device *dev, pm_message_t state)
+{
+ struct display_device *dsp = dev_get_drvdata(dev);
+
+ mutex_lock(&dsp->lock);
+ if (likely(dsp->driver->suspend))
+ dsp->driver->suspend(dsp, state);
+ mutex_unlock(&dsp->lock);
+ return 0;
+};
+
+static int display_resume(struct device *dev)
+{
+ struct display_device *dsp = dev_get_drvdata(dev);
+
+ mutex_lock(&dsp->lock);
+ if (likely(dsp->driver->resume))
+ dsp->driver->resume(dsp);
+ mutex_unlock(&dsp->lock);
+ return 0;
+};
+
+static struct mutex allocated_dsp_lock;
+static DEFINE_IDR(allocated_dsp);
+static struct class *display_class;
+
+struct display_device *display_device_register(struct display_driver *driver,
+ struct device *parent, void *devdata)
+{
+ struct display_device *new_dev = NULL;
+ int ret = -EINVAL;
+
+ if (unlikely(!driver))
+ return ERR_PTR(ret);
+
+ mutex_lock(&allocated_dsp_lock);
+ ret = idr_pre_get(&allocated_dsp, GFP_KERNEL);
+ mutex_unlock(&allocated_dsp_lock);
+ if (!ret)
+ return ERR_PTR(ret);
+
+ new_dev = kzalloc(sizeof(struct display_device), GFP_KERNEL);
+ if (likely(new_dev) && unlikely(driver->probe(new_dev, devdata))) {
+ // Reserve the index for this display
+ mutex_lock(&allocated_dsp_lock);
+ ret = idr_get_new(&allocated_dsp, new_dev, &new_dev->idx);
+ mutex_unlock(&allocated_dsp_lock);
+
+ if (!ret) {
+ new_dev->dev = device_create(display_class, parent, 0,
+ "display%d", new_dev->idx);
+ if (!IS_ERR(new_dev->dev)) {
+ dev_set_drvdata(new_dev->dev, new_dev);
+ new_dev->parent = parent;
+ new_dev->driver = driver;
+ mutex_init(&new_dev->lock);
+ return new_dev;
+ }
+ mutex_lock(&allocated_dsp_lock);
+ idr_remove(&allocated_dsp, new_dev->idx);
+ mutex_unlock(&allocated_dsp_lock);
+ ret = -EINVAL;
+ }
+ }
+ kfree(new_dev);
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(display_device_register);
+
+void display_device_unregister(struct display_device *ddev)
+{
+ if (!ddev)
+ return;
+ // Free device
+ mutex_lock(&ddev->lock);
+ device_unregister(ddev->dev);
+ mutex_unlock(&ddev->lock);
+ // Mark device index as avaliable
+ mutex_lock(&allocated_dsp_lock);
+ idr_remove(&allocated_dsp, ddev->idx);
+ mutex_unlock(&allocated_dsp_lock);
+ kfree(ddev);
+}
+EXPORT_SYMBOL(display_device_unregister);
+
+static int __init display_class_init(void)
+{
+ display_class = class_create(THIS_MODULE, "display");
+ if (IS_ERR(display_class)) {
+ printk(KERN_ERR "Failed to create display class\n");
+ display_class = NULL;
+ return -EINVAL;
+ }
+ display_class->dev_attrs = display_attrs;
+ display_class->suspend = display_suspend;
+ display_class->resume = display_resume;
+ mutex_init(&allocated_dsp_lock);
+ return 0;
+}
+
+static void __exit display_class_exit(void)
+{
+ class_destroy(display_class);
+}
+
+module_init(display_class_init);
+module_exit(display_class_exit);
+
+MODULE_DESCRIPTION("Display Hardware handling");
+MODULE_AUTHOR("James Simmons <jsimmons@infradead.org>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 29e07c1..ca2c54c 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -403,17 +403,10 @@ static inline unsigned long copy_to_user16(void *to, const void *from,
static ssize_t
-epson1355fb_read(struct file *file, char *buf, size_t count, loff_t * ppos)
+epson1355fb_read(struct fb_info *info, char *buf, size_t count, loff_t * ppos)
{
- struct inode *inode = file->f_path.dentry->d_inode;
- int fbidx = iminor(inode);
- struct fb_info *info = registered_fb[fbidx];
unsigned long p = *ppos;
- /* from fbmem.c except for our own copy_*_user */
- if (!info || !info->screen_base)
- return -ENODEV;
-
if (p >= info->fix.smem_len)
return 0;
if (count >= info->fix.smem_len)
@@ -434,20 +427,13 @@ epson1355fb_read(struct file *file, char *buf, size_t count, loff_t * ppos)
}
static ssize_t
-epson1355fb_write(struct file *file, const char *buf,
+epson1355fb_write(struct fb_info *info, const char *buf,
size_t count, loff_t * ppos)
{
- struct inode *inode = file->f_path.dentry->d_inode;
- int fbidx = iminor(inode);
- struct fb_info *info = registered_fb[fbidx];
unsigned long p = *ppos;
int err;
/* from fbmem.c except for our own copy_*_user */
- if (!info || !info->screen_base)
- return -ENODEV;
-
- /* from fbmem.c except for our own copy_*_user */
if (p > info->fix.smem_len)
return -ENOSPC;
if (count >= info->fix.smem_len)
@@ -650,9 +636,10 @@ int __init epson1355fb_probe(struct platform_device *dev)
}
info = framebuffer_alloc(sizeof(struct epson1355_par) + sizeof(u32) * 256, &dev->dev);
- if (!info)
+ if (!info) {
rc = -ENOMEM;
goto bail;
+ }
default_par = info->par;
default_par->reg_addr = (unsigned long) ioremap(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN);
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
new file mode 100644
index 0000000..1a8643f
--- /dev/null
+++ b/drivers/video/fb_defio.c
@@ -0,0 +1,151 @@
+/*
+ * linux/drivers/video/fb_defio.c
+ *
+ * Copyright (C) 2006 Jaya Kumar
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/list.h>
+#include <asm/uaccess.h>
+
+/* to support deferred IO */
+#include <linux/rmap.h>
+#include <linux/pagemap.h>
+
+/* this is to find and return the vmalloc-ed fb pages */
+static struct page* fb_deferred_io_nopage(struct vm_area_struct *vma,
+ unsigned long vaddr, int *type)
+{
+ unsigned long offset;
+ struct page *page;
+ struct fb_info *info = vma->vm_private_data;
+ /* info->screen_base is in System RAM */
+ void *screen_base = (void __force *) info->screen_base;
+
+ offset = (vaddr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT);
+ if (offset >= info->fix.smem_len)
+ return NOPAGE_SIGBUS;
+
+ page = vmalloc_to_page(screen_base + offset);
+ if (!page)
+ return NOPAGE_OOM;
+
+ get_page(page);
+ if (type)
+ *type = VM_FAULT_MINOR;
+ return page;
+}
+
+int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+ struct fb_info *info = file->private_data;
+
+ /* Kill off the delayed work */
+ cancel_rearming_delayed_work(&info->deferred_work);
+
+ /* Run it immediately */
+ return schedule_delayed_work(&info->deferred_work, 0);
+}
+EXPORT_SYMBOL_GPL(fb_deferred_io_fsync);
+
+/* vm_ops->page_mkwrite handler */
+static int fb_deferred_io_mkwrite(struct vm_area_struct *vma,
+ struct page *page)
+{
+ struct fb_info *info = vma->vm_private_data;
+ struct fb_deferred_io *fbdefio = info->fbdefio;
+
+ /* this is a callback we get when userspace first tries to
+ write to the page. we schedule a workqueue. that workqueue
+ will eventually mkclean the touched pages and execute the
+ deferred framebuffer IO. then if userspace touches a page
+ again, we repeat the same scheme */
+
+ /* protect against the workqueue changing the page list */
+ mutex_lock(&fbdefio->lock);
+ list_add(&page->lru, &fbdefio->pagelist);
+ mutex_unlock(&fbdefio->lock);
+
+ /* come back after delay to process the deferred IO */
+ schedule_delayed_work(&info->deferred_work, fbdefio->delay);
+ return 0;
+}
+
+static struct vm_operations_struct fb_deferred_io_vm_ops = {
+ .nopage = fb_deferred_io_nopage,
+ .page_mkwrite = fb_deferred_io_mkwrite,
+};
+
+static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ vma->vm_ops = &fb_deferred_io_vm_ops;
+ vma->vm_flags |= ( VM_IO | VM_RESERVED | VM_DONTEXPAND );
+ vma->vm_private_data = info;
+ return 0;
+}
+
+/* workqueue callback */
+static void fb_deferred_io_work(struct work_struct *work)
+{
+ struct fb_info *info = container_of(work, struct fb_info,
+ deferred_work.work);
+ struct list_head *node, *next;
+ struct page *cur;
+ struct fb_deferred_io *fbdefio = info->fbdefio;
+
+ /* here we mkclean the pages, then do all deferred IO */
+ mutex_lock(&fbdefio->lock);
+ list_for_each_entry(cur, &fbdefio->pagelist, lru) {
+ lock_page(cur);
+ page_mkclean(cur);
+ unlock_page(cur);
+ }
+
+ /* driver's callback with pagelist */
+ fbdefio->deferred_io(info, &fbdefio->pagelist);
+
+ /* clear the list */
+ list_for_each_safe(node, next, &fbdefio->pagelist) {
+ list_del(node);
+ }
+ mutex_unlock(&fbdefio->lock);
+}
+
+void fb_deferred_io_init(struct fb_info *info)
+{
+ struct fb_deferred_io *fbdefio = info->fbdefio;
+
+ BUG_ON(!fbdefio);
+ mutex_init(&fbdefio->lock);
+ info->fbops->fb_mmap = fb_deferred_io_mmap;
+ INIT_DELAYED_WORK(&info->deferred_work, fb_deferred_io_work);
+ INIT_LIST_HEAD(&fbdefio->pagelist);
+ if (fbdefio->delay == 0) /* set a default of 1 s */
+ fbdefio->delay = HZ;
+}
+EXPORT_SYMBOL_GPL(fb_deferred_io_init);
+
+void fb_deferred_io_cleanup(struct fb_info *info)
+{
+ struct fb_deferred_io *fbdefio = info->fbdefio;
+
+ BUG_ON(!fbdefio);
+ cancel_delayed_work(&info->deferred_work);
+ flush_scheduled_work();
+}
+EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fb_draw.h b/drivers/video/fb_draw.h
new file mode 100644
index 0000000..c5c4520
--- /dev/null
+++ b/drivers/video/fb_draw.h
@@ -0,0 +1,72 @@
+#ifndef _FB_DRAW_H
+#define _FB_DRAW_H
+
+#include <asm/types.h>
+
+ /*
+ * Compose two values, using a bitmask as decision value
+ * This is equivalent to (a & mask) | (b & ~mask)
+ */
+
+static inline unsigned long
+comp(unsigned long a, unsigned long b, unsigned long mask)
+{
+ return ((a ^ b) & mask) ^ b;
+}
+
+ /*
+ * Create a pattern with the given pixel's color
+ */
+
+#if BITS_PER_LONG == 64
+static inline unsigned long
+pixel_to_pat( u32 bpp, u32 pixel)
+{
+ switch (bpp) {
+ case 1:
+ return 0xfffffffffffffffful*pixel;
+ case 2:
+ return 0x5555555555555555ul*pixel;
+ case 4:
+ return 0x1111111111111111ul*pixel;
+ case 8:
+ return 0x0101010101010101ul*pixel;
+ case 12:
+ return 0x0001001001001001ul*pixel;
+ case 16:
+ return 0x0001000100010001ul*pixel;
+ case 24:
+ return 0x0000000001000001ul*pixel;
+ case 32:
+ return 0x0000000100000001ul*pixel;
+ default:
+ panic("pixel_to_pat(): unsupported pixelformat\n");
+ }
+}
+#else
+static inline unsigned long
+pixel_to_pat( u32 bpp, u32 pixel)
+{
+ switch (bpp) {
+ case 1:
+ return 0xfffffffful*pixel;
+ case 2:
+ return 0x55555555ul*pixel;
+ case 4:
+ return 0x11111111ul*pixel;
+ case 8:
+ return 0x01010101ul*pixel;
+ case 12:
+ return 0x00001001ul*pixel;
+ case 16:
+ return 0x00010001ul*pixel;
+ case 24:
+ return 0x00000001ul*pixel;
+ case 32:
+ return 0x00000001ul*pixel;
+ default:
+ panic("pixel_to_pat(): unsupported pixelformat\n");
+ }
+}
+#endif
+#endif /* FB_DRAW_H */
diff --git a/drivers/video/fb_sys_fops.c b/drivers/video/fb_sys_fops.c
new file mode 100644
index 0000000..cf2538d
--- /dev/null
+++ b/drivers/video/fb_sys_fops.c
@@ -0,0 +1,104 @@
+/*
+ * linux/drivers/video/fb_sys_read.c - Generic file operations where
+ * framebuffer is in system RAM
+ *
+ * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ */
+#include <linux/fb.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ unsigned long p = *ppos;
+ void *src;
+ int err = 0;
+ unsigned long total_size;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return -EPERM;
+
+ total_size = info->screen_size;
+
+ if (total_size == 0)
+ total_size = info->fix.smem_len;
+
+ if (p >= total_size)
+ return 0;
+
+ if (count >= total_size)
+ count = total_size;
+
+ if (count + p > total_size)
+ count = total_size - p;
+
+ src = (void __force *)(info->screen_base + p);
+
+ if (info->fbops->fb_sync)
+ info->fbops->fb_sync(info);
+
+ if (copy_to_user(buf, src, count))
+ err = -EFAULT;
+
+ if (!err)
+ *ppos += count;
+
+ return (err) ? err : count;
+}
+EXPORT_SYMBOL_GPL(fb_sys_read);
+
+ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long p = *ppos;
+ void *dst;
+ int err = 0;
+ unsigned long total_size;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return -EPERM;
+
+ total_size = info->screen_size;
+
+ if (total_size == 0)
+ total_size = info->fix.smem_len;
+
+ if (p > total_size)
+ return -EFBIG;
+
+ if (count > total_size) {
+ err = -EFBIG;
+ count = total_size;
+ }
+
+ if (count + p > total_size) {
+ if (!err)
+ err = -ENOSPC;
+
+ count = total_size - p;
+ }
+
+ dst = (void __force *) (info->screen_base + p);
+
+ if (info->fbops->fb_sync)
+ info->fbops->fb_sync(info);
+
+ if (copy_from_user(dst, buf, count))
+ err = -EFAULT;
+
+ if (!err)
+ *ppos += count;
+
+ return (err) ? err : count;
+}
+EXPORT_SYMBOL_GPL(fb_sys_write);
+
+MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
+MODULE_DESCRIPTION("Generic file read (fb in system RAM)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 2822526..08d4e11 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -354,59 +354,59 @@ static void fb_rotate_logo(struct fb_info *info, u8 *dst,
if (rotate == FB_ROTATE_UD) {
fb_rotate_logo_ud(image->data, dst, image->width,
image->height);
- image->dx = info->var.xres - image->width;
- image->dy = info->var.yres - image->height;
+ image->dx = info->var.xres - image->width - image->dx;
+ image->dy = info->var.yres - image->height - image->dy;
} else if (rotate == FB_ROTATE_CW) {
fb_rotate_logo_cw(image->data, dst, image->width,
image->height);
tmp = image->width;
image->width = image->height;
image->height = tmp;
- image->dx = info->var.xres - image->width;
+ tmp = image->dy;
+ image->dy = image->dx;
+ image->dx = info->var.xres - image->width - tmp;
} else if (rotate == FB_ROTATE_CCW) {
fb_rotate_logo_ccw(image->data, dst, image->width,
image->height);
tmp = image->width;
image->width = image->height;
image->height = tmp;
- image->dy = info->var.yres - image->height;
+ tmp = image->dx;
+ image->dx = image->dy;
+ image->dy = info->var.yres - image->height - tmp;
}
image->data = dst;
}
static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
- int rotate)
+ int rotate, unsigned int num)
{
- int x;
+ unsigned int x;
if (rotate == FB_ROTATE_UR) {
- for (x = 0; x < num_online_cpus() &&
- x * (fb_logo.logo->width + 8) <=
- info->var.xres - fb_logo.logo->width; x++) {
+ for (x = 0;
+ x < num && image->dx + image->width <= info->var.xres;
+ x++) {
info->fbops->fb_imageblit(info, image);
- image->dx += fb_logo.logo->width + 8;
+ image->dx += image->width + 8;
}
} else if (rotate == FB_ROTATE_UD) {
- for (x = 0; x < num_online_cpus() &&
- x * (fb_logo.logo->width + 8) <=
- info->var.xres - fb_logo.logo->width; x++) {
+ for (x = 0; x < num && image->dx >= 0; x++) {
info->fbops->fb_imageblit(info, image);
- image->dx -= fb_logo.logo->width + 8;
+ image->dx -= image->width + 8;
}
} else if (rotate == FB_ROTATE_CW) {
- for (x = 0; x < num_online_cpus() &&
- x * (fb_logo.logo->width + 8) <=
- info->var.yres - fb_logo.logo->width; x++) {
+ for (x = 0;
+ x < num && image->dy + image->height <= info->var.yres;
+ x++) {
info->fbops->fb_imageblit(info, image);
- image->dy += fb_logo.logo->width + 8;
+ image->dy += image->height + 8;
}
} else if (rotate == FB_ROTATE_CCW) {
- for (x = 0; x < num_online_cpus() &&
- x * (fb_logo.logo->width + 8) <=
- info->var.yres - fb_logo.logo->width; x++) {
+ for (x = 0; x < num && image->dy >= 0; x++) {
info->fbops->fb_imageblit(info, image);
- image->dy -= fb_logo.logo->width + 8;
+ image->dy -= image->height + 8;
}
}
}
@@ -418,7 +418,8 @@ int fb_prepare_logo(struct fb_info *info, int rotate)
memset(&fb_logo, 0, sizeof(struct logo_data));
- if (info->flags & FBINFO_MISC_TILEBLITTING)
+ if (info->flags & FBINFO_MISC_TILEBLITTING ||
+ info->flags & FBINFO_MODULE)
return 0;
if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
@@ -483,7 +484,8 @@ int fb_show_logo(struct fb_info *info, int rotate)
struct fb_image image;
/* Return if the frame buffer is not mapped or suspended */
- if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING)
+ if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING ||
+ info->flags & FBINFO_MODULE)
return 0;
image.depth = 8;
@@ -532,7 +534,7 @@ int fb_show_logo(struct fb_info *info, int rotate)
fb_rotate_logo(info, logo_rotate, &image, rotate);
}
- fb_do_show_logo(info, &image, rotate);
+ fb_do_show_logo(info, &image, rotate, num_online_cpus());
kfree(palette);
if (saved_pseudo_palette != NULL)
@@ -586,7 +588,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
return -EPERM;
if (info->fbops->fb_read)
- return info->fbops->fb_read(file, buf, count, ppos);
+ return info->fbops->fb_read(info, buf, count, ppos);
total_size = info->screen_size;
@@ -661,7 +663,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
return -EPERM;
if (info->fbops->fb_write)
- return info->fbops->fb_write(file, buf, count, ppos);
+ return info->fbops->fb_write(info, buf, count, ppos);
total_size = info->screen_size;
@@ -771,14 +773,37 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
return 0;
}
+static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var,
+ u32 activate)
+{
+ struct fb_event event;
+ struct fb_blit_caps caps, fbcaps;
+ int err = 0;
+
+ memset(&caps, 0, sizeof(caps));
+ memset(&fbcaps, 0, sizeof(fbcaps));
+ caps.flags = (activate & FB_ACTIVATE_ALL) ? 1 : 0;
+ event.info = info;
+ event.data = &caps;
+ fb_notifier_call_chain(FB_EVENT_GET_REQ, &event);
+ info->fbops->fb_get_caps(info, &fbcaps, var);
+
+ if (((fbcaps.x ^ caps.x) & caps.x) ||
+ ((fbcaps.y ^ caps.y) & caps.y) ||
+ (fbcaps.len < caps.len))
+ err = -EINVAL;
+
+ return err;
+}
+
int
fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
{
- int err, flags = info->flags;
+ int flags = info->flags;
+ int ret = 0;
if (var->activate & FB_ACTIVATE_INV_MODE) {
struct fb_videomode mode1, mode2;
- int ret = 0;
fb_var_to_videomode(&mode1, var);
fb_var_to_videomode(&mode2, &info->var);
@@ -796,40 +821,51 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
if (!ret)
fb_delete_videomode(&mode1, &info->modelist);
- return ret;
+
+ ret = (ret) ? -EINVAL : 0;
+ goto done;
}
if ((var->activate & FB_ACTIVATE_FORCE) ||
memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) {
+ u32 activate = var->activate;
+
if (!info->fbops->fb_check_var) {
*var = info->var;
- return 0;
+ goto done;
}
- if ((err = info->fbops->fb_check_var(var, info)))
- return err;
+ ret = info->fbops->fb_check_var(var, info);
+
+ if (ret)
+ goto done;
if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
struct fb_videomode mode;
- int err = 0;
+
+ if (info->fbops->fb_get_caps) {
+ ret = fb_check_caps(info, var, activate);
+
+ if (ret)
+ goto done;
+ }
info->var = *var;
+
if (info->fbops->fb_set_par)
info->fbops->fb_set_par(info);
fb_pan_display(info, &info->var);
-
fb_set_cmap(&info->cmap, info);
-
fb_var_to_videomode(&mode, &info->var);
if (info->modelist.prev && info->modelist.next &&
!list_empty(&info->modelist))
- err = fb_add_videomode(&mode, &info->modelist);
+ ret = fb_add_videomode(&mode, &info->modelist);
- if (!err && (flags & FBINFO_MISC_USEREVENT)) {
+ if (!ret && (flags & FBINFO_MISC_USEREVENT)) {
struct fb_event event;
- int evnt = (var->activate & FB_ACTIVATE_ALL) ?
+ int evnt = (activate & FB_ACTIVATE_ALL) ?
FB_EVENT_MODE_CHANGE_ALL :
FB_EVENT_MODE_CHANGE;
@@ -839,7 +875,9 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
}
}
}
- return 0;
+
+ done:
+ return ret;
}
int
@@ -1266,6 +1304,9 @@ static const struct file_operations fb_fops = {
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
.get_unmapped_area = get_fb_unmapped_area,
#endif
+#ifdef CONFIG_FB_DEFERRED_IO
+ .fsync = fb_deferred_io_fsync,
+#endif
};
struct class *fb_class;
@@ -1316,6 +1357,12 @@ register_framebuffer(struct fb_info *fb_info)
}
fb_info->pixmap.offset = 0;
+ if (!fb_info->pixmap.blit_x)
+ fb_info->pixmap.blit_x = ~(u32)0;
+
+ if (!fb_info->pixmap.blit_y)
+ fb_info->pixmap.blit_y = ~(u32)0;
+
if (!fb_info->modelist.prev || !fb_info->modelist.next)
INIT_LIST_HEAD(&fb_info->modelist);
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 6b385c3..438b941 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -48,8 +48,9 @@
#define DPRINTK(fmt, args...)
#endif
-#define FBMON_FIX_HEADER 1
-#define FBMON_FIX_INPUT 2
+#define FBMON_FIX_HEADER 1
+#define FBMON_FIX_INPUT 2
+#define FBMON_FIX_TIMINGS 3
#ifdef CONFIG_FB_MODE_HELPERS
struct broken_edid {
@@ -71,6 +72,12 @@ static const struct broken_edid brokendb[] = {
.model = 0x5a44,
.fix = FBMON_FIX_INPUT,
},
+ /* Sharp UXGA? */
+ {
+ .manufacturer = "SHP",
+ .model = 0x138e,
+ .fix = FBMON_FIX_TIMINGS,
+ },
};
static const unsigned char edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff,
@@ -87,6 +94,55 @@ static void copy_string(unsigned char *c, unsigned char *s)
while (i-- && (*--s == 0x20)) *s = 0;
}
+static int edid_is_serial_block(unsigned char *block)
+{
+ if ((block[0] == 0x00) && (block[1] == 0x00) &&
+ (block[2] == 0x00) && (block[3] == 0xff) &&
+ (block[4] == 0x00))
+ return 1;
+ else
+ return 0;
+}
+
+static int edid_is_ascii_block(unsigned char *block)
+{
+ if ((block[0] == 0x00) && (block[1] == 0x00) &&
+ (block[2] == 0x00) && (block[3] == 0xfe) &&
+ (block[4] == 0x00))
+ return 1;
+ else
+ return 0;
+}
+
+static int edid_is_limits_block(unsigned char *block)
+{
+ if ((block[0] == 0x00) && (block[1] == 0x00) &&
+ (block[2] == 0x00) && (block[3] == 0xfd) &&
+ (block[4] == 0x00))
+ return 1;
+ else
+ return 0;
+}
+
+static int edid_is_monitor_block(unsigned char *block)
+{
+ if ((block[0] == 0x00) && (block[1] == 0x00) &&
+ (block[2] == 0x00) && (block[3] == 0xfc) &&
+ (block[4] == 0x00))
+ return 1;
+ else
+ return 0;
+}
+
+static int edid_is_timing_block(unsigned char *block)
+{
+ if ((block[0] != 0x00) || (block[1] != 0x00) ||
+ (block[2] != 0x00) || (block[4] != 0x00))
+ return 1;
+ else
+ return 0;
+}
+
static int check_edid(unsigned char *edid)
{
unsigned char *block = edid + ID_MANUFACTURER_NAME, manufacturer[4];
@@ -104,9 +160,6 @@ static int check_edid(unsigned char *edid)
for (i = 0; i < ARRAY_SIZE(brokendb); i++) {
if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) &&
brokendb[i].model == model) {
- printk("fbmon: The EDID Block of "
- "Manufacturer: %s Model: 0x%x is known to "
- "be broken,\n", manufacturer, model);
fix = brokendb[i].fix;
break;
}
@@ -115,8 +168,10 @@ static int check_edid(unsigned char *edid)
switch (fix) {
case FBMON_FIX_HEADER:
for (i = 0; i < 8; i++) {
- if (edid[i] != edid_v1_header[i])
+ if (edid[i] != edid_v1_header[i]) {
ret = fix;
+ break;
+ }
}
break;
case FBMON_FIX_INPUT:
@@ -126,14 +181,34 @@ static int check_edid(unsigned char *edid)
if (b[4] & 0x01 && b[0] & 0x80)
ret = fix;
break;
+ case FBMON_FIX_TIMINGS:
+ b = edid + DETAILED_TIMING_DESCRIPTIONS_START;
+ ret = fix;
+
+ for (i = 0; i < 4; i++) {
+ if (edid_is_limits_block(b)) {
+ ret = 0;
+ break;
+ }
+
+ b += DETAILED_TIMING_DESCRIPTION_SIZE;
+ }
+
+ break;
}
+ if (ret)
+ printk("fbmon: The EDID Block of "
+ "Manufacturer: %s Model: 0x%x is known to "
+ "be broken,\n", manufacturer, model);
+
return ret;
}
static void fix_edid(unsigned char *edid, int fix)
{
- unsigned char *b;
+ int i;
+ unsigned char *b, csum = 0;
switch (fix) {
case FBMON_FIX_HEADER:
@@ -145,6 +220,37 @@ static void fix_edid(unsigned char *edid, int fix)
b = edid + EDID_STRUCT_DISPLAY;
b[0] &= ~0x80;
edid[127] += 0x80;
+ break;
+ case FBMON_FIX_TIMINGS:
+ printk("fbmon: trying to fix monitor timings\n");
+ b = edid + DETAILED_TIMING_DESCRIPTIONS_START;
+ for (i = 0; i < 4; i++) {
+ if (!(edid_is_serial_block(b) ||
+ edid_is_ascii_block(b) ||
+ edid_is_monitor_block(b) ||
+ edid_is_timing_block(b))) {
+ b[0] = 0x00;
+ b[1] = 0x00;
+ b[2] = 0x00;
+ b[3] = 0xfd;
+ b[4] = 0x00;
+ b[5] = 60; /* vfmin */
+ b[6] = 60; /* vfmax */
+ b[7] = 30; /* hfmin */
+ b[8] = 75; /* hfmax */
+ b[9] = 17; /* pixclock - 170 MHz*/
+ b[10] = 0; /* GTF */
+ break;
+ }
+
+ b += DETAILED_TIMING_DESCRIPTION_SIZE;
+ }
+
+ for (i = 0; i < EDID_LENGTH - 1; i++)
+ csum += edid[i];
+
+ edid[127] = 256 - csum;
+ break;
}
}
@@ -273,46 +379,6 @@ static void get_chroma(unsigned char *block, struct fb_monspecs *specs)
DPRINTK("WhiteY: 0.%03d\n", specs->chroma.whitey);
}
-static int edid_is_serial_block(unsigned char *block)
-{
- if ((block[0] == 0x00) && (block[1] == 0x00) &&
- (block[2] == 0x00) && (block[3] == 0xff) &&
- (block[4] == 0x00))
- return 1;
- else
- return 0;
-}
-
-static int edid_is_ascii_block(unsigned char *block)
-{
- if ((block[0] == 0x00) && (block[1] == 0x00) &&
- (block[2] == 0x00) && (block[3] == 0xfe) &&
- (block[4] == 0x00))
- return 1;
- else
- return 0;
-}
-
-static int edid_is_limits_block(unsigned char *block)
-{
- if ((block[0] == 0x00) && (block[1] == 0x00) &&
- (block[2] == 0x00) && (block[3] == 0xfd) &&
- (block[4] == 0x00))
- return 1;
- else
- return 0;
-}
-
-static int edid_is_monitor_block(unsigned char *block)
-{
- if ((block[0] == 0x00) && (block[1] == 0x00) &&
- (block[2] == 0x00) && (block[3] == 0xfc) &&
- (block[4] == 0x00))
- return 1;
- else
- return 0;
-}
-
static void calc_mode_timings(int xres, int yres, int refresh,
struct fb_videomode *mode)
{
@@ -795,15 +861,6 @@ static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs)
}
}
-static int edid_is_timing_block(unsigned char *block)
-{
- if ((block[0] != 0x00) || (block[1] != 0x00) ||
- (block[2] != 0x00) || (block[4] != 0x00))
- return 1;
- else
- return 0;
-}
-
int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
{
int i;
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 40c80c8..d4a2c11 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -376,7 +376,7 @@ static ssize_t show_pan(struct device *device,
{
struct fb_info *fb_info = dev_get_drvdata(device);
return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset,
- fb_info->var.xoffset);
+ fb_info->var.yoffset);
}
static ssize_t show_name(struct device *device,
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
new file mode 100644
index 0000000..abfcb50
--- /dev/null
+++ b/drivers/video/hecubafb.c
@@ -0,0 +1,471 @@
+/*
+ * linux/drivers/video/hecubafb.c -- FB driver for Hecuba controller
+ *
+ * Copyright (C) 2006, Jaya Kumar
+ * This work was sponsored by CIS(M) Sdn Bhd
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven.
+ * This work was possible because of apollo display code from E-Ink's website
+ * http://support.eink.com/community
+ * All information used to write this code is from public material made
+ * available by E-Ink on its support site. Some commands such as 0xA4
+ * were found by looping through cmd=0x00 thru 0xFF and supplying random
+ * values. There are other commands that the display is capable of,
+ * beyond the 5 used here but they are more complex.
+ *
+ * This driver is written to be used with the Hecuba display controller
+ * board, and tested with the EInk 800x600 display in 1 bit mode.
+ * The interface between Hecuba and the host is TTL based GPIO. The
+ * GPIO requirements are 8 writable data lines and 6 lines for control.
+ * Only 4 of the controls are actually used here but 6 for future use.
+ * The driver requires the IO addresses for data and control GPIO at
+ * load time. It is also possible to use this display with a standard
+ * PC parallel port.
+ *
+ * General notes:
+ * - User must set hecubafb_enable=1 to enable it
+ * - User must set dio_addr=0xIOADDR cio_addr=0xIOADDR c2io_addr=0xIOADDR
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/list.h>
+#include <asm/uaccess.h>
+
+/* Apollo controller specific defines */
+#define APOLLO_START_NEW_IMG 0xA0
+#define APOLLO_STOP_IMG_DATA 0xA1
+#define APOLLO_DISPLAY_IMG 0xA2
+#define APOLLO_ERASE_DISPLAY 0xA3
+#define APOLLO_INIT_DISPLAY 0xA4
+
+/* Hecuba interface specific defines */
+/* WUP is inverted, CD is inverted, DS is inverted */
+#define HCB_NWUP_BIT 0x01
+#define HCB_NDS_BIT 0x02
+#define HCB_RW_BIT 0x04
+#define HCB_NCD_BIT 0x08
+#define HCB_ACK_BIT 0x80
+
+/* Display specific information */
+#define DPY_W 600
+#define DPY_H 800
+
+struct hecubafb_par {
+ unsigned long dio_addr;
+ unsigned long cio_addr;
+ unsigned long c2io_addr;
+ unsigned char ctl;
+ struct fb_info *info;
+ unsigned int irq;
+};
+
+static struct fb_fix_screeninfo hecubafb_fix __devinitdata = {
+ .id = "hecubafb",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_MONO01,
+ .xpanstep = 0,
+ .ypanstep = 0,
+ .ywrapstep = 0,
+ .accel = FB_ACCEL_NONE,
+};
+
+static struct fb_var_screeninfo hecubafb_var __devinitdata = {
+ .xres = DPY_W,
+ .yres = DPY_H,
+ .xres_virtual = DPY_W,
+ .yres_virtual = DPY_H,
+ .bits_per_pixel = 1,
+ .nonstd = 1,
+};
+
+static unsigned long dio_addr;
+static unsigned long cio_addr;
+static unsigned long c2io_addr;
+static unsigned long splashval;
+static unsigned int nosplash;
+static unsigned int hecubafb_enable;
+static unsigned int irq;
+
+static DECLARE_WAIT_QUEUE_HEAD(hecubafb_waitq);
+
+static void hcb_set_ctl(struct hecubafb_par *par)
+{
+ outb(par->ctl, par->cio_addr);
+}
+
+static unsigned char hcb_get_ctl(struct hecubafb_par *par)
+{
+ return inb(par->c2io_addr);
+}
+
+static void hcb_set_data(struct hecubafb_par *par, unsigned char value)
+{
+ outb(value, par->dio_addr);
+}
+
+static int __devinit apollo_init_control(struct hecubafb_par *par)
+{
+ unsigned char ctl;
+ /* for init, we want the following setup to be set:
+ WUP = lo
+ ACK = hi
+ DS = hi
+ RW = hi
+ CD = lo
+ */
+
+ /* write WUP to lo, DS to hi, RW to hi, CD to lo */
+ par->ctl = HCB_NWUP_BIT | HCB_RW_BIT | HCB_NCD_BIT ;
+ par->ctl &= ~HCB_NDS_BIT;
+ hcb_set_ctl(par);
+
+ /* check ACK is not lo */
+ ctl = hcb_get_ctl(par);
+ if ((ctl & HCB_ACK_BIT)) {
+ printk(KERN_ERR "Fail because ACK is already low\n");
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static void hcb_wait_for_ack(struct hecubafb_par *par)
+{
+
+ int timeout;
+ unsigned char ctl;
+
+ timeout=500;
+ do {
+ ctl = hcb_get_ctl(par);
+ if ((ctl & HCB_ACK_BIT))
+ return;
+ udelay(1);
+ } while (timeout--);
+ printk(KERN_ERR "timed out waiting for ack\n");
+}
+
+static void hcb_wait_for_ack_clear(struct hecubafb_par *par)
+{
+
+ int timeout;
+ unsigned char ctl;
+
+ timeout=500;
+ do {
+ ctl = hcb_get_ctl(par);
+ if (!(ctl & HCB_ACK_BIT))
+ return;
+ udelay(1);
+ } while (timeout--);
+ printk(KERN_ERR "timed out waiting for clear\n");
+}
+
+static void apollo_send_data(struct hecubafb_par *par, unsigned char data)
+{
+ /* set data */
+ hcb_set_data(par, data);
+
+ /* set DS low */
+ par->ctl |= HCB_NDS_BIT;
+ hcb_set_ctl(par);
+
+ hcb_wait_for_ack(par);
+
+ /* set DS hi */
+ par->ctl &= ~(HCB_NDS_BIT);
+ hcb_set_ctl(par);
+
+ hcb_wait_for_ack_clear(par);
+}
+
+static void apollo_send_command(struct hecubafb_par *par, unsigned char data)
+{
+ /* command so set CD to high */
+ par->ctl &= ~(HCB_NCD_BIT);
+ hcb_set_ctl(par);
+
+ /* actually strobe with command */
+ apollo_send_data(par, data);
+
+ /* clear CD back to low */
+ par->ctl |= (HCB_NCD_BIT);
+ hcb_set_ctl(par);
+}
+
+/* main hecubafb functions */
+
+static void hecubafb_dpy_update(struct hecubafb_par *par)
+{
+ int i;
+ unsigned char *buf = (unsigned char __force *)par->info->screen_base;
+
+ apollo_send_command(par, 0xA0);
+
+ for (i=0; i < (DPY_W*DPY_H/8); i++) {
+ apollo_send_data(par, *(buf++));
+ }
+
+ apollo_send_command(par, 0xA1);
+ apollo_send_command(par, 0xA2);
+}
+
+/* this is called back from the deferred io workqueue */
+static void hecubafb_dpy_deferred_io(struct fb_info *info,
+ struct list_head *pagelist)
+{
+ hecubafb_dpy_update(info->par);
+}
+
+static void hecubafb_fillrect(struct fb_info *info,
+ const struct fb_fillrect *rect)
+{
+ struct hecubafb_par *par = info->par;
+
+ sys_fillrect(info, rect);
+
+ hecubafb_dpy_update(par);
+}
+
+static void hecubafb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area)
+{
+ struct hecubafb_par *par = info->par;
+
+ sys_copyarea(info, area);
+
+ hecubafb_dpy_update(par);
+}
+
+static void hecubafb_imageblit(struct fb_info *info,
+ const struct fb_image *image)
+{
+ struct hecubafb_par *par = info->par;
+
+ sys_imageblit(info, image);
+
+ hecubafb_dpy_update(par);
+}
+
+/*
+ * this is the slow path from userspace. they can seek and write to
+ * the fb. it's inefficient to do anything less than a full screen draw
+ */
+static ssize_t hecubafb_write(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long p;
+ int err=-EINVAL;
+ struct hecubafb_par *par;
+ unsigned int xres;
+ unsigned int fbmemlength;
+
+ p = *ppos;
+ par = info->par;
+ xres = info->var.xres;
+ fbmemlength = (xres * info->var.yres)/8;
+
+ if (p > fbmemlength)
+ return -ENOSPC;
+
+ err = 0;
+ if ((count + p) > fbmemlength) {
+ count = fbmemlength - p;
+ err = -ENOSPC;
+ }
+
+ if (count) {
+ char *base_addr;
+
+ base_addr = (char __force *)info->screen_base;
+ count -= copy_from_user(base_addr + p, buf, count);
+ *ppos += count;
+ err = -EFAULT;
+ }
+
+ hecubafb_dpy_update(par);
+
+ if (count)
+ return count;
+
+ return err;
+}
+
+static struct fb_ops hecubafb_ops = {
+ .owner = THIS_MODULE,
+ .fb_read = fb_sys_read,
+ .fb_write = hecubafb_write,
+ .fb_fillrect = hecubafb_fillrect,
+ .fb_copyarea = hecubafb_copyarea,
+ .fb_imageblit = hecubafb_imageblit,
+};
+
+static struct fb_deferred_io hecubafb_defio = {
+ .delay = HZ,
+ .deferred_io = hecubafb_dpy_deferred_io,
+};
+
+static int __devinit hecubafb_probe(struct platform_device *dev)
+{
+ struct fb_info *info;
+ int retval = -ENOMEM;
+ int videomemorysize;
+ unsigned char *videomemory;
+ struct hecubafb_par *par;
+
+ videomemorysize = (DPY_W*DPY_H)/8;
+
+ if (!(videomemory = vmalloc(videomemorysize)))
+ return retval;
+
+ memset(videomemory, 0, videomemorysize);
+
+ info = framebuffer_alloc(sizeof(struct hecubafb_par), &dev->dev);
+ if (!info)
+ goto err;
+
+ info->screen_base = (char __iomem *) videomemory;
+ info->fbops = &hecubafb_ops;
+
+ info->var = hecubafb_var;
+ info->fix = hecubafb_fix;
+ info->fix.smem_len = videomemorysize;
+ par = info->par;
+ par->info = info;
+
+ if (!dio_addr || !cio_addr || !c2io_addr) {
+ printk(KERN_WARNING "no IO addresses supplied\n");
+ goto err1;
+ }
+ par->dio_addr = dio_addr;
+ par->cio_addr = cio_addr;
+ par->c2io_addr = c2io_addr;
+ info->flags = FBINFO_FLAG_DEFAULT;
+
+ info->fbdefio = &hecubafb_defio;
+ fb_deferred_io_init(info);
+
+ retval = register_framebuffer(info);
+ if (retval < 0)
+ goto err1;
+ platform_set_drvdata(dev, info);
+
+ printk(KERN_INFO
+ "fb%d: Hecuba frame buffer device, using %dK of video memory\n",
+ info->node, videomemorysize >> 10);
+
+ /* this inits the dpy */
+ apollo_init_control(par);
+
+ apollo_send_command(par, APOLLO_INIT_DISPLAY);
+ apollo_send_data(par, 0x81);
+
+ /* have to wait while display resets */
+ udelay(1000);
+
+ /* if we were told to splash the screen, we just clear it */
+ if (!nosplash) {
+ apollo_send_command(par, APOLLO_ERASE_DISPLAY);
+ apollo_send_data(par, splashval);
+ }
+
+ return 0;
+err1:
+ framebuffer_release(info);
+err:
+ vfree(videomemory);
+ return retval;
+}
+
+static int __devexit hecubafb_remove(struct platform_device *dev)
+{
+ struct fb_info *info = platform_get_drvdata(dev);
+
+ if (info) {
+ fb_deferred_io_cleanup(info);
+ unregister_framebuffer(info);
+ vfree((void __force *)info->screen_base);
+ framebuffer_release(info);
+ }
+ return 0;
+}
+
+static struct platform_driver hecubafb_driver = {
+ .probe = hecubafb_probe,
+ .remove = hecubafb_remove,
+ .driver = {
+ .name = "hecubafb",
+ },
+};
+
+static struct platform_device *hecubafb_device;
+
+static int __init hecubafb_init(void)
+{
+ int ret;
+
+ if (!hecubafb_enable) {
+ printk(KERN_ERR "Use hecubafb_enable to enable the device\n");
+ return -ENXIO;
+ }
+
+ ret = platform_driver_register(&hecubafb_driver);
+ if (!ret) {
+ hecubafb_device = platform_device_alloc("hecubafb", 0);
+ if (hecubafb_device)
+ ret = platform_device_add(hecubafb_device);
+ else
+ ret = -ENOMEM;
+
+ if (ret) {
+ platform_device_put(hecubafb_device);
+ platform_driver_unregister(&hecubafb_driver);
+ }
+ }
+ return ret;
+
+}
+
+static void __exit hecubafb_exit(void)
+{
+ platform_device_unregister(hecubafb_device);
+ platform_driver_unregister(&hecubafb_driver);
+}
+
+module_param(nosplash, uint, 0);
+MODULE_PARM_DESC(nosplash, "Disable doing the splash screen");
+module_param(hecubafb_enable, uint, 0);
+MODULE_PARM_DESC(hecubafb_enable, "Enable communication with Hecuba board");
+module_param(dio_addr, ulong, 0);
+MODULE_PARM_DESC(dio_addr, "IO address for data, eg: 0x480");
+module_param(cio_addr, ulong, 0);
+MODULE_PARM_DESC(cio_addr, "IO address for control, eg: 0x400");
+module_param(c2io_addr, ulong, 0);
+MODULE_PARM_DESC(c2io_addr, "IO address for secondary control, eg: 0x408");
+module_param(splashval, ulong, 0);
+MODULE_PARM_DESC(splashval, "Splash pattern: 0x00 is black, 0x01 is white");
+module_param(irq, uint, 0);
+MODULE_PARM_DESC(irq, "IRQ for the Hecuba board");
+
+module_init(hecubafb_init);
+module_exit(hecubafb_exit);
+
+MODULE_DESCRIPTION("fbdev driver for Hecuba board");
+MODULE_AUTHOR("Jaya Kumar");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h
index aa65ffc..889e4ea 100644
--- a/drivers/video/i810/i810.h
+++ b/drivers/video/i810/i810.h
@@ -133,7 +133,7 @@
/* Masks (AND ops) and OR's */
#define FB_START_MASK (0x3f << (32 - 6))
#define MMIO_ADDR_MASK (0x1FFF << (32 - 13))
-#define FREQ_MASK 0x1EF
+#define FREQ_MASK (1 << 4)
#define SCR_OFF 0x20
#define DRAM_ON 0x08
#define DRAM_OFF 0xE7
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index c1eb18b..16bc8d7 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -1428,6 +1428,24 @@ static void refresh_ring(struct intelfb_info *dinfo);
static void reset_state(struct intelfb_info *dinfo);
static void do_flush(struct intelfb_info *dinfo);
+static u32 get_ring_space(struct intelfb_info *dinfo)
+{
+ u32 ring_space;
+
+ if (dinfo->ring_tail >= dinfo->ring_head)
+ ring_space = dinfo->ring.size -
+ (dinfo->ring_tail - dinfo->ring_head);
+ else
+ ring_space = dinfo->ring_head - dinfo->ring_tail;
+
+ if (ring_space > RING_MIN_FREE)
+ ring_space -= RING_MIN_FREE;
+ else
+ ring_space = 0;
+
+ return ring_space;
+}
+
static int
wait_ring(struct intelfb_info *dinfo, int n)
{
@@ -1442,13 +1460,8 @@ wait_ring(struct intelfb_info *dinfo, int n)
end = jiffies + (HZ * 3);
while (dinfo->ring_space < n) {
dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
- if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head)
- dinfo->ring_space = dinfo->ring_head
- - (dinfo->ring_tail + RING_MIN_FREE);
- else
- dinfo->ring_space = (dinfo->ring.size +
- dinfo->ring_head)
- - (dinfo->ring_tail + RING_MIN_FREE);
+ dinfo->ring_space = get_ring_space(dinfo);
+
if (dinfo->ring_head != last_head) {
end = jiffies + (HZ * 3);
last_head = dinfo->ring_head;
@@ -1513,12 +1526,7 @@ refresh_ring(struct intelfb_info *dinfo)
dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK;
- if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head)
- dinfo->ring_space = dinfo->ring_head
- - (dinfo->ring_tail + RING_MIN_FREE);
- else
- dinfo->ring_space = (dinfo->ring.size + dinfo->ring_head)
- - (dinfo->ring_tail + RING_MIN_FREE);
+ dinfo->ring_space = get_ring_space(dinfo);
}
static void
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index f0e6512..9397bce 100644
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -2,73 +2,69 @@
# Logo configuration
#
-menu "Logo configuration"
-
-config LOGO
+menuconfig LOGO
bool "Bootup logo"
depends on FB || SGI_NEWPORT_CONSOLE
help
Enable and select frame buffer bootup logos.
+if LOGO
+
config LOGO_LINUX_MONO
bool "Standard black and white Linux logo"
- depends on LOGO
default y
config LOGO_LINUX_VGA16
bool "Standard 16-color Linux logo"
- depends on LOGO
default y
config LOGO_LINUX_CLUT224
bool "Standard 224-color Linux logo"
- depends on LOGO
default y
config LOGO_DEC_CLUT224
bool "224-color Digital Equipment Corporation Linux logo"
- depends on LOGO && (MACH_DECSTATION || ALPHA)
+ depends on MACH_DECSTATION || ALPHA
default y
config LOGO_MAC_CLUT224
bool "224-color Macintosh Linux logo"
- depends on LOGO && MAC
+ depends on MAC
default y
config LOGO_PARISC_CLUT224
bool "224-color PA-RISC Linux logo"
- depends on LOGO && PARISC
+ depends on PARISC
default y
config LOGO_SGI_CLUT224
bool "224-color SGI Linux logo"
- depends on LOGO && (SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS)
+ depends on SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS
default y
config LOGO_SUN_CLUT224
bool "224-color Sun Linux logo"
- depends on LOGO && SPARC
+ depends on SPARC
default y
config LOGO_SUPERH_MONO
bool "Black and white SuperH Linux logo"
- depends on LOGO && SUPERH
+ depends on SUPERH
default y
config LOGO_SUPERH_VGA16
bool "16-color SuperH Linux logo"
- depends on LOGO && SUPERH
+ depends on SUPERH
default y
config LOGO_SUPERH_CLUT224
bool "224-color SuperH Linux logo"
- depends on LOGO && SUPERH
+ depends on SUPERH
default y
config LOGO_M32R_CLUT224
bool "224-color M32R Linux logo"
- depends on LOGO && M32R
+ depends on M32R
default y
-endmenu
-
+endif # LOGO
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 3e51794..3741ad7 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -395,7 +395,7 @@ static int my_atoi(const char *name)
for (;; name++) {
switch (*name) {
- case '0'...'9':
+ case '0' ... '9':
val = 10*val+(*name-'0');
break;
default:
@@ -548,7 +548,7 @@ int fb_find_mode(struct fb_var_screeninfo *var,
} else
goto done;
break;
- case '0'...'9':
+ case '0' ... '9':
break;
case 'M':
if (!yres_specified)
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 395cced..bd30aba 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -665,6 +665,7 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
var->red.msb_right = 0;
var->green.msb_right = 0;
var->blue.msb_right = 0;
+ var->transp.msb_right = 0;
switch (var->bits_per_pixel) {
case 8: /* PSEUDOCOLOUR, 256 */
diff --git a/drivers/video/nvidia/nv_accel.c b/drivers/video/nvidia/nv_accel.c
index 9efb8a3..fa4821c 100644
--- a/drivers/video/nvidia/nv_accel.c
+++ b/drivers/video/nvidia/nv_accel.c
@@ -69,27 +69,38 @@ static const int NVCopyROP_PM[16] = {
0x5A, /* invert */
};
-static inline void NVFlush(struct nvidia_par *par)
+static inline void nvidiafb_safe_mode(struct fb_info *info)
{
+ struct nvidia_par *par = info->par;
+
+ touch_softlockup_watchdog();
+ info->pixmap.scan_align = 1;
+ par->lockup = 1;
+}
+
+static inline void NVFlush(struct fb_info *info)
+{
+ struct nvidia_par *par = info->par;
int count = 1000000000;
while (--count && READ_GET(par) != par->dmaPut) ;
if (!count) {
printk("nvidiafb: DMA Flush lockup\n");
- par->lockup = 1;
+ nvidiafb_safe_mode(info);
}
}
-static inline void NVSync(struct nvidia_par *par)
+static inline void NVSync(struct fb_info *info)
{
+ struct nvidia_par *par = info->par;
int count = 1000000000;
while (--count && NV_RD32(par->PGRAPH, 0x0700)) ;
if (!count) {
printk("nvidiafb: DMA Sync lockup\n");
- par->lockup = 1;
+ nvidiafb_safe_mode(info);
}
}
@@ -101,8 +112,9 @@ static void NVDmaKickoff(struct nvidia_par *par)
}
}
-static void NVDmaWait(struct nvidia_par *par, int size)
+static void NVDmaWait(struct fb_info *info, int size)
{
+ struct nvidia_par *par = info->par;
int dmaGet;
int count = 1000000000, cnt;
size++;
@@ -135,34 +147,38 @@ static void NVDmaWait(struct nvidia_par *par, int size)
}
if (!count) {
- printk("DMA Wait Lockup\n");
- par->lockup = 1;
+ printk("nvidiafb: DMA Wait Lockup\n");
+ nvidiafb_safe_mode(info);
}
}
-static void NVSetPattern(struct nvidia_par *par, u32 clr0, u32 clr1,
+static void NVSetPattern(struct fb_info *info, u32 clr0, u32 clr1,
u32 pat0, u32 pat1)
{
- NVDmaStart(par, PATTERN_COLOR_0, 4);
+ struct nvidia_par *par = info->par;
+
+ NVDmaStart(info, par, PATTERN_COLOR_0, 4);
NVDmaNext(par, clr0);
NVDmaNext(par, clr1);
NVDmaNext(par, pat0);
NVDmaNext(par, pat1);
}
-static void NVSetRopSolid(struct nvidia_par *par, u32 rop, u32 planemask)
+static void NVSetRopSolid(struct fb_info *info, u32 rop, u32 planemask)
{
+ struct nvidia_par *par = info->par;
+
if (planemask != ~0) {
- NVSetPattern(par, 0, planemask, ~0, ~0);
+ NVSetPattern(info, 0, planemask, ~0, ~0);
if (par->currentRop != (rop + 32)) {
- NVDmaStart(par, ROP_SET, 1);
+ NVDmaStart(info, par, ROP_SET, 1);
NVDmaNext(par, NVCopyROP_PM[rop]);
par->currentRop = rop + 32;
}
} else if (par->currentRop != rop) {
if (par->currentRop >= 16)
- NVSetPattern(par, ~0, ~0, ~0, ~0);
- NVDmaStart(par, ROP_SET, 1);
+ NVSetPattern(info, ~0, ~0, ~0, ~0);
+ NVDmaStart(info, par, ROP_SET, 1);
NVDmaNext(par, NVCopyROP[rop]);
par->currentRop = rop;
}
@@ -175,7 +191,7 @@ static void NVSetClippingRectangle(struct fb_info *info, int x1, int y1,
int h = y2 - y1 + 1;
int w = x2 - x1 + 1;
- NVDmaStart(par, CLIP_POINT, 2);
+ NVDmaStart(info, par, CLIP_POINT, 2);
NVDmaNext(par, (y1 << 16) | x1);
NVDmaNext(par, (h << 16) | w);
}
@@ -237,23 +253,23 @@ void NVResetGraphics(struct fb_info *info)
break;
}
- NVDmaStart(par, SURFACE_FORMAT, 4);
+ NVDmaStart(info, par, SURFACE_FORMAT, 4);
NVDmaNext(par, surfaceFormat);
NVDmaNext(par, pitch | (pitch << 16));
NVDmaNext(par, 0);
NVDmaNext(par, 0);
- NVDmaStart(par, PATTERN_FORMAT, 1);
+ NVDmaStart(info, par, PATTERN_FORMAT, 1);
NVDmaNext(par, patternFormat);
- NVDmaStart(par, RECT_FORMAT, 1);
+ NVDmaStart(info, par, RECT_FORMAT, 1);
NVDmaNext(par, rectFormat);
- NVDmaStart(par, LINE_FORMAT, 1);
+ NVDmaStart(info, par, LINE_FORMAT, 1);
NVDmaNext(par, lineFormat);
par->currentRop = ~0; /* set to something invalid */
- NVSetRopSolid(par, ROP_COPY, ~0);
+ NVSetRopSolid(info, ROP_COPY, ~0);
NVSetClippingRectangle(info, 0, 0, info->var.xres_virtual,
info->var.yres_virtual);
@@ -269,10 +285,10 @@ int nvidiafb_sync(struct fb_info *info)
return 0;
if (!par->lockup)
- NVFlush(par);
+ NVFlush(info);
if (!par->lockup)
- NVSync(par);
+ NVSync(info);
return 0;
}
@@ -287,7 +303,7 @@ void nvidiafb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
if (par->lockup)
return cfb_copyarea(info, region);
- NVDmaStart(par, BLIT_POINT_SRC, 3);
+ NVDmaStart(info, par, BLIT_POINT_SRC, 3);
NVDmaNext(par, (region->sy << 16) | region->sx);
NVDmaNext(par, (region->dy << 16) | region->dx);
NVDmaNext(par, (region->height << 16) | region->width);
@@ -312,19 +328,19 @@ void nvidiafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
color = ((u32 *) info->pseudo_palette)[rect->color];
if (rect->rop != ROP_COPY)
- NVSetRopSolid(par, rect->rop, ~0);
+ NVSetRopSolid(info, rect->rop, ~0);
- NVDmaStart(par, RECT_SOLID_COLOR, 1);
+ NVDmaStart(info, par, RECT_SOLID_COLOR, 1);
NVDmaNext(par, color);
- NVDmaStart(par, RECT_SOLID_RECTS(0), 2);
+ NVDmaStart(info, par, RECT_SOLID_RECTS(0), 2);
NVDmaNext(par, (rect->dx << 16) | rect->dy);
NVDmaNext(par, (rect->width << 16) | rect->height);
NVDmaKickoff(par);
if (rect->rop != ROP_COPY)
- NVSetRopSolid(par, ROP_COPY, ~0);
+ NVSetRopSolid(info, ROP_COPY, ~0);
}
static void nvidiafb_mono_color_expand(struct fb_info *info,
@@ -346,7 +362,7 @@ static void nvidiafb_mono_color_expand(struct fb_info *info,
bg = ((u32 *) info->pseudo_palette)[image->bg_color] | mask;
}
- NVDmaStart(par, RECT_EXPAND_TWO_COLOR_CLIP, 7);
+ NVDmaStart(info, par, RECT_EXPAND_TWO_COLOR_CLIP, 7);
NVDmaNext(par, (image->dy << 16) | (image->dx & 0xffff));
NVDmaNext(par, ((image->dy + image->height) << 16) |
((image->dx + image->width) & 0xffff));
@@ -357,7 +373,7 @@ static void nvidiafb_mono_color_expand(struct fb_info *info,
NVDmaNext(par, (image->dy << 16) | (image->dx & 0xffff));
while (dsize >= RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS) {
- NVDmaStart(par, RECT_EXPAND_TWO_COLOR_DATA(0),
+ NVDmaStart(info, par, RECT_EXPAND_TWO_COLOR_DATA(0),
RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS);
for (j = RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS; j--;) {
@@ -370,7 +386,7 @@ static void nvidiafb_mono_color_expand(struct fb_info *info,
}
if (dsize) {
- NVDmaStart(par, RECT_EXPAND_TWO_COLOR_DATA(0), dsize);
+ NVDmaStart(info, par, RECT_EXPAND_TWO_COLOR_DATA(0), dsize);
for (j = dsize; j--;) {
tmp = data[k++];
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c
index ea42611..f297c7b 100644
--- a/drivers/video/nvidia/nv_hw.c
+++ b/drivers/video/nvidia/nv_hw.c
@@ -686,7 +686,7 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
if ((par->Chipset & 0x0FF0) == 0x01A0) {
unsigned int uMClkPostDiv;
- dev = pci_find_slot(0, 3);
+ dev = pci_get_bus_and_slot(0, 3);
pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
@@ -694,11 +694,11 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
uMClkPostDiv = 4;
MClk = 400000 / uMClkPostDiv;
} else {
- dev = pci_find_slot(0, 5);
+ dev = pci_get_bus_and_slot(0, 5);
pci_read_config_dword(dev, 0x4c, &MClk);
MClk /= 1000;
}
-
+ pci_dev_put(dev);
pll = NV_RD32(par->PRAMDAC0, 0x0500);
M = (pll >> 0) & 0xFF;
N = (pll >> 8) & 0xFF;
@@ -707,19 +707,21 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
sim_data.pix_bpp = (char)pixelDepth;
sim_data.enable_video = 0;
sim_data.enable_mp = 0;
- pci_find_slot(0, 1);
+ dev = pci_get_bus_and_slot(0, 1);
pci_read_config_dword(dev, 0x7C, &sim_data.memory_type);
+ pci_dev_put(dev);
sim_data.memory_type = (sim_data.memory_type >> 12) & 1;
sim_data.memory_width = 64;
- dev = pci_find_slot(0, 3);
+ dev = pci_get_bus_and_slot(0, 3);
pci_read_config_dword(dev, 0, &memctrl);
+ pci_dev_put(dev);
memctrl >>= 16;
if ((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) {
int dimm[3];
- pci_find_slot(0, 2);
+ dev = pci_get_bus_and_slot(0, 2);
pci_read_config_dword(dev, 0x40, &dimm[0]);
dimm[0] = (dimm[0] >> 8) & 0x4f;
pci_read_config_dword(dev, 0x44, &dimm[1]);
@@ -731,6 +733,7 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
printk("nvidiafb: your nForce DIMMs are not arranged "
"in optimal banks!\n");
}
+ pci_dev_put(dev);
}
sim_data.mem_latency = 3;
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index b858897..afe4567 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -30,16 +30,14 @@ static void nvidia_gpio_setscl(void *data, int state)
struct nvidia_par *par = chan->par;
u32 val;
- VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1);
- val = VGA_RD08(par->PCIO, 0x3d5) & 0xf0;
+ val = NVReadCrtc(par, chan->ddc_base + 1) & 0xf0;
if (state)
val |= 0x20;
else
val &= ~0x20;
- VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1);
- VGA_WR08(par->PCIO, 0x3d5, val | 0x1);
+ NVWriteCrtc(par, chan->ddc_base + 1, val | 0x01);
}
static void nvidia_gpio_setsda(void *data, int state)
@@ -48,16 +46,14 @@ static void nvidia_gpio_setsda(void *data, int state)
struct nvidia_par *par = chan->par;
u32 val;
- VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1);
- val = VGA_RD08(par->PCIO, 0x3d5) & 0xf0;
+ val = NVReadCrtc(par, chan->ddc_base + 1) & 0xf0;
if (state)
val |= 0x10;
else
val &= ~0x10;
- VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1);
- VGA_WR08(par->PCIO, 0x3d5, val | 0x1);
+ NVWriteCrtc(par, chan->ddc_base + 1, val | 0x01);
}
static int nvidia_gpio_getscl(void *data)
@@ -66,12 +62,9 @@ static int nvidia_gpio_getscl(void *data)
struct nvidia_par *par = chan->par;
u32 val = 0;
- VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base);
- if (VGA_RD08(par->PCIO, 0x3d5) & 0x04)
+ if (NVReadCrtc(par, chan->ddc_base) & 0x04)
val = 1;
- val = VGA_RD08(par->PCIO, 0x3d5);
-
return val;
}
@@ -81,20 +74,21 @@ static int nvidia_gpio_getsda(void *data)
struct nvidia_par *par = chan->par;
u32 val = 0;
- VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base);
- if (VGA_RD08(par->PCIO, 0x3d5) & 0x08)
+ if (NVReadCrtc(par, chan->ddc_base) & 0x08)
val = 1;
return val;
}
-static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name)
+static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name,
+ unsigned int i2c_class)
{
int rc;
strcpy(chan->adapter.name, name);
chan->adapter.owner = THIS_MODULE;
chan->adapter.id = I2C_HW_B_NVIDIA;
+ chan->adapter.class = i2c_class;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->par->pci_dev->dev;
chan->algo.setsda = nvidia_gpio_setsda;
@@ -127,83 +121,39 @@ static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name)
void nvidia_create_i2c_busses(struct nvidia_par *par)
{
- par->bus = 3;
-
par->chan[0].par = par;
par->chan[1].par = par;
par->chan[2].par = par;
- par->chan[0].ddc_base = 0x3e;
- nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0");
+ par->chan[0].ddc_base = 0x36;
+ nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0", I2C_CLASS_HWMON);
- par->chan[1].ddc_base = 0x36;
- nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1");
+ par->chan[1].ddc_base = 0x3e;
+ nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1", 0);
par->chan[2].ddc_base = 0x50;
- nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2");
+ nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2", 0);
}
void nvidia_delete_i2c_busses(struct nvidia_par *par)
{
- if (par->chan[0].par)
- i2c_del_adapter(&par->chan[0].adapter);
- par->chan[0].par = NULL;
-
- if (par->chan[1].par)
- i2c_del_adapter(&par->chan[1].adapter);
- par->chan[1].par = NULL;
-
- if (par->chan[2].par)
- i2c_del_adapter(&par->chan[2].adapter);
- par->chan[2].par = NULL;
-
-}
+ int i;
-static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan)
-{
- u8 start = 0x0;
- struct i2c_msg msgs[] = {
- {
- .addr = 0x50,
- .len = 1,
- .buf = &start,
- }, {
- .addr = 0x50,
- .flags = I2C_M_RD,
- .len = EDID_LENGTH,
- },
- };
- u8 *buf;
-
- if (!chan->par)
- return NULL;
-
- buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
- if (!buf) {
- dev_warn(&chan->par->pci_dev->dev, "Out of memory!\n");
- return NULL;
+ for (i = 0; i < 3; i++) {
+ if (!par->chan[i].par)
+ continue;
+ i2c_del_adapter(&par->chan[i].adapter);
+ par->chan[i].par = NULL;
}
- msgs[1].buf = buf;
-
- if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
- return buf;
- dev_dbg(&chan->par->pci_dev->dev, "Unable to read EDID block.\n");
- kfree(buf);
- return NULL;
}
int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
{
struct nvidia_par *par = info->par;
u8 *edid = NULL;
- int i;
- for (i = 0; i < 3; i++) {
- /* Do the real work */
- edid = nvidia_do_probe_i2c_edid(&par->chan[conn - 1]);
- if (edid)
- break;
- }
+ if (par->chan[conn - 1].par)
+ edid = fb_ddc_read(&par->chan[conn - 1].adapter);
if (!edid && conn == 1) {
/* try to get from firmware */
diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/nvidia/nv_local.h
index e009d24..68e508d 100644
--- a/drivers/video/nvidia/nv_local.h
+++ b/drivers/video/nvidia/nv_local.h
@@ -73,9 +73,9 @@
#define NVDmaNext(par, data) \
NV_WR32(&(par)->dmaBase[(par)->dmaCurrent++], 0, (data))
-#define NVDmaStart(par, tag, size) { \
+#define NVDmaStart(info, par, tag, size) { \
if((par)->dmaFree <= (size)) \
- NVDmaWait(par, size); \
+ NVDmaWait(info, size); \
NVDmaNext(par, ((size) << 18) | (tag)); \
(par)->dmaFree -= ((size) + 1); \
}
diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/nvidia/nv_of.c
index 163a774..73afd7e 100644
--- a/drivers/video/nvidia/nv_of.c
+++ b/drivers/video/nvidia/nv_of.c
@@ -46,15 +46,15 @@ int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
for (dp = NULL;
(dp = of_get_next_child(parent, dp)) != NULL;) {
- pname = get_property(dp, "name", NULL);
+ pname = of_get_property(dp, "name", NULL);
if (!pname)
continue;
len = strlen(pname);
if ((pname[len-1] == 'A' && conn == 1) ||
(pname[len-1] == 'B' && conn == 2)) {
for (i = 0; propnames[i] != NULL; ++i) {
- pedid = get_property(dp, propnames[i],
- NULL);
+ pedid = of_get_property(dp,
+ propnames[i], NULL);
if (pedid != NULL)
break;
}
@@ -65,7 +65,7 @@ int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
}
if (pedid == NULL) {
for (i = 0; propnames[i] != NULL; ++i) {
- pedid = get_property(parent, propnames[i], NULL);
+ pedid = of_get_property(parent, propnames[i], NULL);
if (pedid != NULL)
break;
}
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index eab3e28..707e2c8 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -261,7 +261,7 @@ static void nv10GetConfig(struct nvidia_par *par)
}
#endif
- dev = pci_find_slot(0, 1);
+ dev = pci_get_bus_and_slot(0, 1);
if ((par->Chipset & 0xffff) == 0x01a0) {
int amt = 0;
@@ -276,6 +276,7 @@ static void nv10GetConfig(struct nvidia_par *par)
par->RamAmountKBytes =
(NV_RD32(par->PFB, 0x020C) & 0xFFF00000) >> 10;
}
+ pci_dev_put(dev);
par->CrystalFreqKHz = (NV_RD32(par->PEXTDEV, 0x0000) & (1 << 6)) ?
14318 : 13500;
@@ -656,7 +657,7 @@ int NVCommonSetup(struct fb_info *info)
par->LVDS = 0;
if (par->FlatPanel && par->twoHeads) {
NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004);
- if (par->PRAMDAC0[0x08b4] & 1)
+ if (NV_RD32(par->PRAMDAC0, 0x08b4) & 1)
par->LVDS = 1;
printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS");
}
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h
index 86e65de..38f7cc0 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/nvidia/nv_type.h
@@ -4,8 +4,9 @@
#include <linux/fb.h>
#include <linux/types.h>
#include <linux/i2c.h>
-#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h>
+#include <linux/mutex.h>
+#include <video/vga.h>
#define NV_ARCH_04 0x04
#define NV_ARCH_10 0x10
@@ -94,13 +95,15 @@ struct riva_regs {
struct nvidia_par {
RIVA_HW_STATE SavedReg;
RIVA_HW_STATE ModeReg;
+ RIVA_HW_STATE initial_state;
RIVA_HW_STATE *CurrentState;
+ struct vgastate vgastate;
+ struct mutex open_lock;
u32 pseudo_palette[16];
struct pci_dev *pci_dev;
u32 Architecture;
u32 CursorStart;
int Chipset;
- int bus;
unsigned long FbAddress;
u8 __iomem *FbStart;
u32 FbMapSize;
@@ -143,6 +146,7 @@ struct nvidia_par {
int BlendingPossible;
u32 paletteEnabled;
u32 forceCRTC;
+ u32 open_count;
u8 DDCBase;
#ifdef CONFIG_MTRR
struct {
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index b97ec69..7c36b5f 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -200,7 +200,7 @@ static int nvidia_panel_tweak(struct nvidia_par *par,
return tweak;
}
-static void nvidia_vga_protect(struct nvidia_par *par, int on)
+static void nvidia_screen_off(struct nvidia_par *par, int on)
{
unsigned char tmp;
@@ -649,7 +649,7 @@ static int nvidiafb_set_par(struct fb_info *info)
NVLockUnlock(par, 0);
}
- nvidia_vga_protect(par, 1);
+ nvidia_screen_off(par, 1);
nvidia_write_regs(par, &par->ModeReg);
NVSetStartAddress(par, 0);
@@ -687,7 +687,7 @@ static int nvidiafb_set_par(struct fb_info *info)
par->cursor_reset = 1;
- nvidia_vga_protect(par, 0);
+ nvidia_screen_off(par, 0);
#ifdef CONFIG_BOOTX_TEXT
/* Update debug text engine */
@@ -696,6 +696,7 @@ static int nvidiafb_set_par(struct fb_info *info)
info->var.bits_per_pixel, info->fix.line_length);
#endif
+ NVLockUnlock(par, 0);
NVTRACE_LEAVE();
return 0;
}
@@ -948,8 +949,80 @@ static int nvidiafb_blank(int blank, struct fb_info *info)
return 0;
}
+/*
+ * Because the VGA registers are not mapped linearly in its MMIO space,
+ * restrict VGA register saving and restore to x86 only, where legacy VGA IO
+ * access is legal. Consequently, we must also check if the device is the
+ * primary display.
+ */
+#ifdef CONFIG_X86
+static void save_vga_x86(struct nvidia_par *par)
+{
+ struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE];
+
+ if (res && res->flags & IORESOURCE_ROM_SHADOW) {
+ memset(&par->vgastate, 0, sizeof(par->vgastate));
+ par->vgastate.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS |
+ VGA_SAVE_CMAP;
+ save_vga(&par->vgastate);
+ }
+}
+
+static void restore_vga_x86(struct nvidia_par *par)
+{
+ struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE];
+
+ if (res && res->flags & IORESOURCE_ROM_SHADOW)
+ restore_vga(&par->vgastate);
+}
+#else
+#define save_vga_x86(x) do {} while (0)
+#define restore_vga_x86(x) do {} while (0)
+#endif /* X86 */
+
+static int nvidiafb_open(struct fb_info *info, int user)
+{
+ struct nvidia_par *par = info->par;
+
+ mutex_lock(&par->open_lock);
+
+ if (!par->open_count) {
+ save_vga_x86(par);
+ nvidia_save_vga(par, &par->initial_state);
+ }
+
+ par->open_count++;
+ mutex_unlock(&par->open_lock);
+ return 0;
+}
+
+static int nvidiafb_release(struct fb_info *info, int user)
+{
+ struct nvidia_par *par = info->par;
+ int err = 0;
+
+ mutex_lock(&par->open_lock);
+
+ if (!par->open_count) {
+ err = -EINVAL;
+ goto done;
+ }
+
+ if (par->open_count == 1) {
+ nvidia_write_regs(par, &par->initial_state);
+ restore_vga_x86(par);
+ }
+
+ par->open_count--;
+done:
+ mutex_unlock(&par->open_lock);
+ return err;
+}
+
static struct fb_ops nvidia_fb_ops = {
.owner = THIS_MODULE,
+ .fb_open = nvidiafb_open,
+ .fb_release = nvidiafb_release,
.fb_check_var = nvidiafb_check_var,
.fb_set_par = nvidiafb_set_par,
.fb_setcolreg = nvidiafb_setcolreg,
@@ -1207,7 +1280,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
par = info->par;
par->pci_dev = pd;
-
+ mutex_init(&par->open_lock);
info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
if (info->pixmap.addr == NULL)
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 9576a55..885b428 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -322,8 +322,8 @@ static void __init offb_init_fb(const char *name, const char *full_name,
ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
par->cmap_data = par->cmap_adr + 1;
par->cmap_type = cmap_m64;
- } else if (dp && (device_is_compatible(dp, "pci1014,b7") ||
- device_is_compatible(dp, "pci1014,21c"))) {
+ } else if (dp && (of_device_is_compatible(dp, "pci1014,b7") ||
+ of_device_is_compatible(dp, "pci1014,21c"))) {
par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
if (par->cmap_adr)
par->cmap_type = cmap_gxt2000;
@@ -425,27 +425,27 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)
const u32 *pp, *addrp, *up;
u64 asize;
- pp = get_property(dp, "linux,bootx-depth", &len);
+ pp = of_get_property(dp, "linux,bootx-depth", &len);
if (pp == NULL)
- pp = get_property(dp, "depth", &len);
+ pp = of_get_property(dp, "depth", &len);
if (pp && len == sizeof(u32))
depth = *pp;
- pp = get_property(dp, "linux,bootx-width", &len);
+ pp = of_get_property(dp, "linux,bootx-width", &len);
if (pp == NULL)
- pp = get_property(dp, "width", &len);
+ pp = of_get_property(dp, "width", &len);
if (pp && len == sizeof(u32))
width = *pp;
- pp = get_property(dp, "linux,bootx-height", &len);
+ pp = of_get_property(dp, "linux,bootx-height", &len);
if (pp == NULL)
- pp = get_property(dp, "height", &len);
+ pp = of_get_property(dp, "height", &len);
if (pp && len == sizeof(u32))
height = *pp;
- pp = get_property(dp, "linux,bootx-linebytes", &len);
+ pp = of_get_property(dp, "linux,bootx-linebytes", &len);
if (pp == NULL)
- pp = get_property(dp, "linebytes", &len);
+ pp = of_get_property(dp, "linebytes", &len);
if (pp && len == sizeof(u32) && (*pp != 0xffffffffu))
pitch = *pp;
else
@@ -463,9 +463,9 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)
* ranges and pick one that is both big enough and if possible encloses
* the "address" property. If none match, we pick the biggest
*/
- up = get_property(dp, "linux,bootx-addr", &len);
+ up = of_get_property(dp, "linux,bootx-addr", &len);
if (up == NULL)
- up = get_property(dp, "address", &len);
+ up = of_get_property(dp, "address", &len);
if (up && len == sizeof(u32))
addr_prop = *up;
@@ -521,7 +521,7 @@ static int __init offb_init(void)
return -ENODEV;
/* Check if we have a MacOS display without a node spec */
- if (get_property(of_chosen, "linux,bootx-noscreen", NULL) != NULL) {
+ if (of_get_property(of_chosen, "linux,bootx-noscreen", NULL) != NULL) {
/* The old code tried to work out which node was the MacOS
* display based on the address. I'm dropping that since the
* lack of a node spec only happens with old BootX versions
@@ -532,14 +532,14 @@ static int __init offb_init(void)
}
for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
- if (get_property(dp, "linux,opened", NULL) &&
- get_property(dp, "linux,boot-display", NULL)) {
+ if (of_get_property(dp, "linux,opened", NULL) &&
+ of_get_property(dp, "linux,boot-display", NULL)) {
boot_disp = dp;
offb_init_nodriver(dp, 0);
}
}
for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
- if (get_property(dp, "linux,opened", NULL) &&
+ if (of_get_property(dp, "linux,opened", NULL) &&
dp != boot_disp)
offb_init_nodriver(dp, 0);
}
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index a560a22..1ac5264 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -81,8 +81,6 @@ static int lowvsync;
struct pm2fb_par
{
pm2type_t type; /* Board type */
- u32 fb_size; /* framebuffer memory size */
- unsigned char __iomem *v_fb; /* virtual address of frame buffer */
unsigned char __iomem *v_regs;/* virtual address of p_regs */
u32 memclock; /* memclock */
u32 video; /* video flags before blanking */
@@ -103,7 +101,7 @@ static struct fb_fix_screeninfo pm2fb_fix __devinitdata = {
.xpanstep = 1,
.ypanstep = 1,
.ywrapstep = 0,
- .accel = FB_ACCEL_NONE,
+ .accel = FB_ACCEL_3DLABS_PERMEDIA2,
};
/*
@@ -206,6 +204,17 @@ static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a)
}
#endif
+static void wait_pm2(struct pm2fb_par* par) {
+
+ WAIT_FIFO(par, 1);
+ pm2_WR(par, PM2R_SYNC, 0);
+ mb();
+ do {
+ while (pm2_RD(par, PM2R_OUT_FIFO_WORDS) == 0);
+ rmb();
+ } while (pm2_RD(par, PM2R_OUT_FIFO) != PM2TAG(PM2R_SYNC));
+}
+
/*
* partial products for the supported horizontal resolutions.
*/
@@ -302,10 +311,10 @@ static void pm2v_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
s32 delta = 1000;
*mm = *nn = *pp = 0;
- for (n = 1; n; n++) {
- for ( m = 1; m; m++) {
+ for ( m = 1; m < 128; m++) {
+ for (n = 2 * m + 1; n; n++) {
for ( p = 0; p < 2; p++) {
- f = PM2_REFERENCE_CLOCK * n / (m * (1 << (p + 1)));
+ f = ( PM2_REFERENCE_CLOCK >> ( p + 1 )) * n / m;
if ( clk > f - delta && clk < f + delta ) {
delta = ( clk > f ) ? clk - f : f - clk;
*mm=m;
@@ -462,21 +471,43 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
int i;
unsigned char m, n, p;
- pm2_mnp(clk, &m, &n, &p);
- WAIT_FIFO(par, 10);
- pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 6);
- wmb();
- pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_1, m);
- pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_2, n);
- wmb();
- pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p);
- wmb();
- pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS);
- rmb();
- for (i = 256;
- i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED);
- i--)
- ;
+ switch (par->type) {
+ case PM2_TYPE_PERMEDIA2V:
+ pm2v_mnp(clk/2, &m, &n, &p);
+ WAIT_FIFO(par, 8);
+ pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8);
+ pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0);
+ wmb();
+ pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m);
+ pm2v_RDAC_WR(par, PM2VI_RD_MCLK_FEEDBACK, n);
+ pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p);
+ wmb();
+ pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1);
+ rmb();
+ for (i = 256;
+ i && !(pm2_RDAC_RD(par, PM2VI_RD_MCLK_CONTROL) & 2);
+ i--)
+ ;
+ pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
+ break;
+ case PM2_TYPE_PERMEDIA2:
+ pm2_mnp(clk, &m, &n, &p);
+ WAIT_FIFO(par, 10);
+ pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 6);
+ wmb();
+ pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_1, m);
+ pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_2, n);
+ wmb();
+ pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p);
+ wmb();
+ pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS);
+ rmb();
+ for (i = 256;
+ i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED);
+ i--)
+ ;
+ break;
+ }
}
static void set_pixclock(struct pm2fb_par* par, u32 clk)
@@ -623,6 +654,8 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
return -EINVAL;
}
+ var->transp.offset = 0;
+ var->transp.length = 0;
switch(var->bits_per_pixel) {
case 8:
var->red.length = var->green.length = var->blue.length = 8;
@@ -1017,6 +1050,117 @@ static int pm2fb_blank(int blank_mode, struct fb_info *info)
return 0;
}
+/*
+ * block operation. copy=0: rectangle fill, copy=1: rectangle copy.
+ */
+static void pm2fb_block_op(struct pm2fb_par* par, int copy,
+ s32 xsrc, s32 ysrc,
+ s32 x, s32 y, s32 w, s32 h,
+ u32 color) {
+
+ if (!w || !h)
+ return;
+ WAIT_FIFO(par, 6);
+ pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE |
+ PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
+ pm2_WR(par, PM2R_FB_PIXEL_OFFSET, 0);
+ if (copy)
+ pm2_WR(par, PM2R_FB_SOURCE_DELTA,
+ ((ysrc-y) & 0xfff) << 16 | ((xsrc-x) & 0xfff));
+ else
+ pm2_WR(par, PM2R_FB_BLOCK_COLOR, color);
+ pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (y << 16) | x);
+ pm2_WR(par, PM2R_RECTANGLE_SIZE, (h << 16) | w);
+ wmb();
+ pm2_WR(par, PM2R_RENDER,PM2F_RENDER_RECTANGLE |
+ (x<xsrc ? PM2F_INCREASE_X : 0) |
+ (y<ysrc ? PM2F_INCREASE_Y : 0) |
+ (copy ? 0 : PM2F_RENDER_FASTFILL));
+ wait_pm2(par);
+}
+
+static void pm2fb_fillrect (struct fb_info *info,
+ const struct fb_fillrect *region)
+{
+ struct pm2fb_par *par = info->par;
+ struct fb_fillrect modded;
+ int vxres, vyres;
+ u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
+ ((u32*)info->pseudo_palette)[region->color] : region->color;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return;
+ if ((info->flags & FBINFO_HWACCEL_DISABLED) ||
+ region->rop != ROP_COPY ) {
+ cfb_fillrect(info, region);
+ return;
+ }
+
+ vxres = info->var.xres_virtual;
+ vyres = info->var.yres_virtual;
+
+ memcpy(&modded, region, sizeof(struct fb_fillrect));
+
+ if(!modded.width || !modded.height ||
+ modded.dx >= vxres || modded.dy >= vyres)
+ return;
+
+ if(modded.dx + modded.width > vxres)
+ modded.width = vxres - modded.dx;
+ if(modded.dy + modded.height > vyres)
+ modded.height = vyres - modded.dy;
+
+ if(info->var.bits_per_pixel == 8)
+ color |= color << 8;
+ if(info->var.bits_per_pixel <= 16)
+ color |= color << 16;
+
+ if(info->var.bits_per_pixel != 24)
+ pm2fb_block_op(par, 0, 0, 0,
+ modded.dx, modded.dy,
+ modded.width, modded.height, color);
+ else
+ cfb_fillrect(info, region);
+}
+
+static void pm2fb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area)
+{
+ struct pm2fb_par *par = info->par;
+ struct fb_copyarea modded;
+ u32 vxres, vyres;
+
+ if (info->state != FBINFO_STATE_RUNNING)
+ return;
+ if (info->flags & FBINFO_HWACCEL_DISABLED) {
+ cfb_copyarea(info, area);
+ return;
+ }
+
+ memcpy(&modded, area, sizeof(struct fb_copyarea));
+
+ vxres = info->var.xres_virtual;
+ vyres = info->var.yres_virtual;
+
+ if(!modded.width || !modded.height ||
+ modded.sx >= vxres || modded.sy >= vyres ||
+ modded.dx >= vxres || modded.dy >= vyres)
+ return;
+
+ if(modded.sx + modded.width > vxres)
+ modded.width = vxres - modded.sx;
+ if(modded.dx + modded.width > vxres)
+ modded.width = vxres - modded.dx;
+ if(modded.sy + modded.height > vyres)
+ modded.height = vyres - modded.sy;
+ if(modded.dy + modded.height > vyres)
+ modded.height = vyres - modded.dy;
+
+ pm2fb_block_op(par, 1, modded.sx, modded.sy,
+ modded.dx, modded.dy,
+ modded.width, modded.height, 0);
+}
+
/* ------------ Hardware Independent Functions ------------ */
/*
@@ -1030,8 +1174,8 @@ static struct fb_ops pm2fb_ops = {
.fb_setcolreg = pm2fb_setcolreg,
.fb_blank = pm2fb_blank,
.fb_pan_display = pm2fb_pan_display,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
+ .fb_fillrect = pm2fb_fillrect,
+ .fb_copyarea = pm2fb_copyarea,
.fb_imageblit = cfb_imageblit,
};
@@ -1119,38 +1263,47 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
if(default_par->mem_control == 0 &&
default_par->boot_address == 0x31 &&
- default_par->mem_config == 0x259fffff &&
- pdev->subsystem_vendor == 0x1048 &&
- pdev->subsystem_device == 0x0a31) {
- DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
- pdev->subsystem_vendor, pdev->subsystem_device);
- DPRINTK("We have not been initialized by VGA BIOS "
- "and are running on an Elsa Winner 2000 Office\n");
- DPRINTK("Initializing card timings manually...\n");
+ default_par->mem_config == 0x259fffff) {
+ default_par->memclock = CVPPC_MEMCLOCK;
default_par->mem_control=0;
default_par->boot_address=0x20;
default_par->mem_config=0xe6002021;
- default_par->memclock=100000;
+ if (pdev->subsystem_vendor == 0x1048 &&
+ pdev->subsystem_device == 0x0a31) {
+ DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
+ pdev->subsystem_vendor, pdev->subsystem_device);
+ DPRINTK("We have not been initialized by VGA BIOS "
+ "and are running on an Elsa Winner 2000 Office\n");
+ DPRINTK("Initializing card timings manually...\n");
+ default_par->memclock=70000;
+ }
+ if (pdev->subsystem_vendor == 0x3d3d &&
+ pdev->subsystem_device == 0x0100) {
+ DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
+ pdev->subsystem_vendor, pdev->subsystem_device);
+ DPRINTK("We have not been initialized by VGA BIOS "
+ "and are running on an 3dlabs reference board\n");
+ DPRINTK("Initializing card timings manually...\n");
+ default_par->memclock=74894;
+ }
}
/* Now work out how big lfb is going to be. */
switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
case PM2F_MEM_BANKS_1:
- default_par->fb_size=0x200000;
+ pm2fb_fix.smem_len=0x200000;
break;
case PM2F_MEM_BANKS_2:
- default_par->fb_size=0x400000;
+ pm2fb_fix.smem_len=0x400000;
break;
case PM2F_MEM_BANKS_3:
- default_par->fb_size=0x600000;
+ pm2fb_fix.smem_len=0x600000;
break;
case PM2F_MEM_BANKS_4:
- default_par->fb_size=0x800000;
+ pm2fb_fix.smem_len=0x800000;
break;
}
- default_par->memclock = CVPPC_MEMCLOCK;
pm2fb_fix.smem_start = pci_resource_start(pdev, 1);
- pm2fb_fix.smem_len = default_par->fb_size;
/* Linear frame buffer - request region and map it. */
if ( !request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len,
@@ -1158,9 +1311,9 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
printk(KERN_WARNING "pm2fb: Can't reserve smem.\n");
goto err_exit_mmio;
}
- info->screen_base = default_par->v_fb =
+ info->screen_base =
ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
- if ( !default_par->v_fb ) {
+ if ( !info->screen_base ) {
printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n");
release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
goto err_exit_mmio;
@@ -1170,7 +1323,9 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
info->fix = pm2fb_fix;
info->pseudo_palette = default_par->palette;
info->flags = FBINFO_DEFAULT |
- FBINFO_HWACCEL_YPAN;
+ FBINFO_HWACCEL_YPAN |
+ FBINFO_HWACCEL_COPYAREA |
+ FBINFO_HWACCEL_FILLRECT;
if (!mode)
mode = "640x480@60";
@@ -1180,13 +1335,13 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
info->var = pm2fb_var;
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)
- goto err_exit_all;
+ goto err_exit_both;
if (register_framebuffer(info) < 0)
- goto err_exit_both;
+ goto err_exit_all;
printk(KERN_INFO "fb%d: %s frame buffer device, memory = %dK.\n",
- info->node, info->fix.id, default_par->fb_size / 1024);
+ info->node, info->fix.id, pm2fb_fix.smem_len / 1024);
/*
* Our driver data
@@ -1242,6 +1397,9 @@ static struct pci_device_id pm2fb_id_table[] = {
{ PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
0xff0000, 0 },
+ { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NOT_DEFINED_VGA << 8,
+ 0xff00, 0 },
{ 0, }
};
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 07d1979..9756a72 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -898,8 +898,8 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
}
ps3fb.dev = dev;
- error = ps3_alloc_irq(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
- &ps3fb.irq_no);
+ error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
+ &ps3fb.irq_no);
if (error) {
printk(KERN_ERR "%s: ps3_alloc_irq failed %d\n", __func__,
error);
@@ -911,7 +911,7 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
if (error) {
printk(KERN_ERR "%s: request_irq failed %d\n", __func__,
error);
- ps3_free_irq(ps3fb.irq_no);
+ ps3_irq_plug_destroy(ps3fb.irq_no);
return error;
}
@@ -1083,7 +1083,7 @@ err_framebuffer_release:
framebuffer_release(info);
err_free_irq:
free_irq(ps3fb.irq_no, ps3fb.dev);
- ps3_free_irq(ps3fb.irq_no);
+ ps3_irq_plug_destroy(ps3fb.irq_no);
err_iounmap_dinfo:
iounmap((u8 __iomem *)ps3fb.dinfo);
err_gpu_context_free:
@@ -1099,7 +1099,7 @@ static void ps3fb_shutdown(struct platform_device *dev)
ps3fb_flip_ctl(0); /* flip off */
ps3fb.dinfo->irq.mask = 0;
free_irq(ps3fb.irq_no, ps3fb.dev);
- ps3_free_irq(ps3fb.irq_no);
+ ps3_irq_plug_destroy(ps3fb.irq_no);
iounmap((u8 __iomem *)ps3fb.dinfo);
}
@@ -1114,7 +1114,7 @@ void ps3fb_cleanup(void)
}
if (ps3fb.irq_no) {
free_irq(ps3fb.irq_no, ps3fb.dev);
- ps3_free_irq(ps3fb.irq_no);
+ ps3_irq_plug_destroy(ps3fb.irq_no);
}
iounmap((u8 __iomem *)ps3fb.dinfo);
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index a93618b..df2909a 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -214,7 +214,7 @@ static int pvr2_init_cable(void);
static int pvr2_get_param(const struct pvr2_params *p, const char *s,
int val, int size);
#ifdef CONFIG_SH_DMA
-static ssize_t pvr2fb_write(struct file *file, const char *buf,
+static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
size_t count, loff_t *ppos);
#endif
@@ -674,7 +674,7 @@ static int pvr2_init_cable(void)
}
#ifdef CONFIG_SH_DMA
-static ssize_t pvr2fb_write(struct file *file, const char *buf,
+static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
size_t count, loff_t *ppos)
{
unsigned long dst, start, end, len;
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index b4947c8..81e571d 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -803,7 +803,7 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
pr_debug("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3);
/* enable LCD controller clock */
- pxa_set_cken(CKEN16_LCD, 1);
+ pxa_set_cken(CKEN_LCD, 1);
/* Sequence from 11.7.10 */
LCCR3 = fbi->reg_lccr3;
@@ -840,7 +840,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi)
remove_wait_queue(&fbi->ctrlr_wait, &wait);
/* disable LCD controller clock */
- pxa_set_cken(CKEN16_LCD, 0);
+ pxa_set_cken(CKEN_LCD, 0);
}
/*
@@ -1203,7 +1203,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
} else
goto done;
break;
- case '0'...'9':
+ case '0' ... '9':
break;
default:
goto done;
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index d7ece8d..0fe5478 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -317,15 +317,15 @@ static int riva_bl_update_status(struct backlight_device *bd)
else
level = bd->props.brightness;
- tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF;
- tmp_pcrt = par->riva.PCRTC0[0x081C/4] & 0xFFFFFFFC;
+ tmp_pmc = NV_RD32(par->riva.PMC, 0x10F0) & 0x0000FFFF;
+ tmp_pcrt = NV_RD32(par->riva.PCRTC0, 0x081C) & 0xFFFFFFFC;
if(level > 0) {
tmp_pcrt |= 0x1;
tmp_pmc |= (1 << 31); /* backlight bit */
tmp_pmc |= riva_bl_get_level_brightness(par, level) << 16; /* level */
}
- par->riva.PCRTC0[0x081C/4] = tmp_pcrt;
- par->riva.PMC[0x10F0/4] = tmp_pmc;
+ NV_WR32(par->riva.PCRTC0, 0x081C, tmp_pcrt);
+ NV_WR32(par->riva.PMC, 0x10F0, tmp_pmc);
return 0;
}
@@ -1760,13 +1760,13 @@ static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd)
NVTRACE_ENTER();
dp = pci_device_to_OF_node(pd);
for (; dp != NULL; dp = dp->child) {
- disptype = get_property(dp, "display-type", NULL);
+ disptype = of_get_property(dp, "display-type", NULL);
if (disptype == NULL)
continue;
if (strncmp(disptype, "LCD", 3) != 0)
continue;
for (i = 0; propnames[i] != NULL; ++i) {
- pedid = get_property(dp, propnames[i], NULL);
+ pedid = of_get_property(dp, propnames[i], NULL);
if (pedid != NULL) {
par->EDID = (unsigned char *)pedid;
NVTRACE("LCD found.\n");
@@ -1788,8 +1788,10 @@ static int __devinit riva_get_EDID_i2c(struct fb_info *info)
NVTRACE_ENTER();
riva_create_i2c_busses(par);
- for (i = 0; i < par->bus; i++) {
- riva_probe_i2c_connector(par, i+1, &par->EDID);
+ for (i = 0; i < 3; i++) {
+ if (!par->chan[i].par)
+ continue;
+ riva_probe_i2c_connector(par, i, &par->EDID);
if (par->EDID && !fb_parse_edid(par->EDID, &var)) {
printk(PFX "Found EDID Block from BUS %i\n", i);
break;
@@ -2104,7 +2106,7 @@ err_ret:
return ret;
}
-static void __exit rivafb_remove(struct pci_dev *pd)
+static void __devexit rivafb_remove(struct pci_dev *pd)
{
struct fb_info *info = pci_get_drvdata(pd);
struct riva_par *par = info->par;
@@ -2185,7 +2187,7 @@ static struct pci_driver rivafb_driver = {
.name = "rivafb",
.id_table = rivafb_pci_tbl,
.probe = rivafb_probe,
- .remove = __exit_p(rivafb_remove),
+ .remove = __devexit_p(rivafb_remove),
};
diff --git a/drivers/video/riva/nv4ref.h b/drivers/video/riva/nv4ref.h
deleted file mode 100644
index 3b5f911..0000000
--- a/drivers/video/riva/nv4ref.h
+++ /dev/null
@@ -1,2445 +0,0 @@
- /***************************************************************************\
-|* *|
-|* Copyright 1993-1998 NVIDIA, Corporation. All rights reserved. *|
-|* *|
-|* NOTICE TO USER: The source code is copyrighted under U.S. and *|
-|* international laws. Users and possessors of this source code are *|
-|* hereby granted a nonexclusive, royalty-free copyright license to *|
-|* use this code in individual and commercial software. *|
-|* *|
-|* Any use of this source code must include, in the user documenta- *|
-|* tion and internal comments to the code, notices to the end user *|
-|* as follows: *|
-|* *|
-|* Copyright 1993-1998 NVIDIA, Corporation. All rights reserved. *|
-|* *|
-|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
-|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
-|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
-|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
-|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
-|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
-|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
-|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
-|* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
-|* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
-|* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
-|* *|
-|* U.S. Government End Users. This source code is a "commercial *|
-|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
-|* consisting of "commercial computer software" and "commercial *|
-|* computer software documentation," as such terms are used in *|
-|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
-|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
-|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
-|* all U.S. Government End Users acquire the source code with only *|
-|* those rights set forth herein. *|
-|* *|
- \***************************************************************************/
-
-/*
- * GPL licensing note -- nVidia is allowing a liberal interpretation of
- * the documentation restriction above, to merely say that this nVidia's
- * copyright and disclaimer should be included with all code derived
- * from this source. -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99
- */
-
- /***************************************************************************\
-|* Modified 1999 by Fredrik Reite (fredrik@reite.com) *|
- \***************************************************************************/
-
-
-#ifndef __NV4REF_H__
-#define __NV4REF_H__
-
-/* Magic values to lock/unlock extended regs */
-#define NV_CIO_SR_LOCK_INDEX 0x0000001F /* */
-#define NV_CIO_SR_UNLOCK_RW_VALUE 0x00000057 /* */
-#define NV_CIO_SR_UNLOCK_RO_VALUE 0x00000075 /* */
-#define NV_CIO_SR_LOCK_VALUE 0x00000099 /* */
-
-#define UNLOCK_EXT_MAGIC 0x57
-#define LOCK_EXT_MAGIC 0x99 /* Any value other than 0x57 will do */
-
-#define LOCK_EXT_INDEX 0x6
-
-#define NV_PCRTC_HORIZ_TOTAL 0x00
-#define NV_PCRTC_HORIZ_DISPLAY_END 0x01
-#define NV_PCRTC_HORIZ_BLANK_START 0x02
-
-#define NV_PCRTC_HORIZ_BLANK_END 0x03
-#define NV_PCRTC_HORIZ_BLANK_END_EVRA 7:7
-#define NV_PCRTC_HORIZ_BLANK_END_DISPLAY_END_SKEW 6:5
-#define NV_PCRTC_HORIZ_BLANK_END_HORIZ_BLANK_END 4:0
-
-#define NV_PCRTC_HORIZ_RETRACE_START 0x04
-
-#define NV_PCRTC_HORIZ_RETRACE_END 0x05
-#define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_BLANK_END_5 7:7
-#define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_RETRACE_SKEW 6:5
-#define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_RETRACE_END 4:0
-
-#define NV_PCRTC_VERT_TOTAL 0x06
-
-#define NV_PCRTC_OVERFLOW 0x07
-#define NV_PCRTC_OVERFLOW_VERT_RETRACE_START_9 7:7
-#define NV_PCRTC_OVERFLOW_VERT_DISPLAY_END_9 6:6
-#define NV_PCRTC_OVERFLOW_VERT_TOTAL_9 5:5
-#define NV_PCRTC_OVERFLOW_LINE_COMPARE_8 4:4
-#define NV_PCRTC_OVERFLOW_VERT_BLANK_START_8 3:3
-#define NV_PCRTC_OVERFLOW_VERT_RETRACE_START_8 2:2
-#define NV_PCRTC_OVERFLOW_VERT_DISPLAY_END_8 1:1
-#define NV_PCRTC_OVERFLOW_VERT_TOTAL_8 0:0
-
-#define NV_PCRTC_PRESET_ROW_SCAN 0x08
-
-#define NV_PCRTC_MAX_SCAN_LINE 0x09
-#define NV_PCRTC_MAX_SCAN_LINE_DOUBLE_SCAN 7:7
-#define NV_PCRTC_MAX_SCAN_LINE_LINE_COMPARE_9 6:6
-#define NV_PCRTC_MAX_SCAN_LINE_VERT_BLANK_START_9 5:5
-#define NV_PCRTC_MAX_SCAN_LINE_MAX_SCAN_LINE 4:0
-
-#define NV_PCRTC_CURSOR_START 0x0A
-#define NV_PCRTC_CURSOR_END 0x0B
-#define NV_PCRTC_START_ADDR_HIGH 0x0C
-#define NV_PCRTC_START_ADDR_LOW 0x0D
-#define NV_PCRTC_CURSOR_LOCATION_HIGH 0x0E
-#define NV_PCRTC_CURSOR_LOCATION_LOW 0x0F
-
-#define NV_PCRTC_VERT_RETRACE_START 0x10
-#define NV_PCRTC_VERT_RETRACE_END 0x11
-#define NV_PCRTC_VERT_DISPLAY_END 0x12
-#define NV_PCRTC_OFFSET 0x13
-#define NV_PCRTC_UNDERLINE_LOCATION 0x14
-#define NV_PCRTC_VERT_BLANK_START 0x15
-#define NV_PCRTC_VERT_BLANK_END 0x16
-#define NV_PCRTC_MODE_CONTROL 0x17
-#define NV_PCRTC_LINE_COMPARE 0x18
-
-/* Extended offset and start address */
-#define NV_PCRTC_REPAINT0 0x19
-#define NV_PCRTC_REPAINT0_OFFSET_10_8 7:5
-#define NV_PCRTC_REPAINT0_START_ADDR_20_16 4:0
-
-/* Horizonal extended bits */
-#define NV_PCRTC_HORIZ_EXTRA 0x2d
-#define NV_PCRTC_HORIZ_EXTRA_INTER_HALF_START_8 4:4
-#define NV_PCRTC_HORIZ_EXTRA_HORIZ_RETRACE_START_8 3:3
-#define NV_PCRTC_HORIZ_EXTRA_HORIZ_BLANK_START_8 2:2
-#define NV_PCRTC_HORIZ_EXTRA_DISPLAY_END_8 1:1
-#define NV_PCRTC_HORIZ_EXTRA_DISPLAY_TOTAL_8 0:0
-
-/* Assorted extra bits */
-#define NV_PCRTC_EXTRA 0x25
-#define NV_PCRTC_EXTRA_OFFSET_11 5:5
-#define NV_PCRTC_EXTRA_HORIZ_BLANK_END_6 4:4
-#define NV_PCRTC_EXTRA_VERT_BLANK_START_10 3:3
-#define NV_PCRTC_EXTRA_VERT_RETRACE_START_10 2:2
-#define NV_PCRTC_EXTRA_VERT_DISPLAY_END_10 1:1
-#define NV_PCRTC_EXTRA_VERT_TOTAL_10 0:0
-
-/* Controls how much data the refresh fifo requests */
-#define NV_PCRTC_FIFO_CONTROL 0x1b
-#define NV_PCRTC_FIFO_CONTROL_UNDERFLOW_WARN 7:7
-#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH 2:0
-#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_8 0x0
-#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_32 0x1
-#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_64 0x2
-#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_128 0x3
-#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_256 0x4
-
-/* When the fifo occupancy falls below *twice* the watermark,
- * the refresh fifo will start to be refilled. If this value is
- * too low, you will get junk on the screen. Too high, and performance
- * will suffer. Watermark in units of 8 bytes
- */
-#define NV_PCRTC_FIFO 0x20
-#define NV_PCRTC_FIFO_RESET 7:7
-#define NV_PCRTC_FIFO_WATERMARK 5:0
-
-/* Various flags */
-#define NV_PCRTC_REPAINT1 0x1a
-#define NV_PCRTC_REPAINT1_HSYNC 7:7
-#define NV_PCRTC_REPAINT1_HYSNC_DISABLE 0x01
-#define NV_PCRTC_REPAINT1_HYSNC_ENABLE 0x00
-#define NV_PCRTC_REPAINT1_VSYNC 6:6
-#define NV_PCRTC_REPAINT1_VYSNC_DISABLE 0x01
-#define NV_PCRTC_REPAINT1_VYSNC_ENABLE 0x00
-#define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT 4:4
-#define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT_ENABLE 0x01
-#define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT_DISABLE 0x00
-#define NV_PCRTC_REPAINT1_LARGE_SCREEN 2:2
-#define NV_PCRTC_REPAINT1_LARGE_SCREEN_DISABLE 0x01
-#define NV_PCRTC_REPAINT1_LARGE_SCREEN_ENABLE 0x00 /* >=1280 */
-#define NV_PCRTC_REPAINT1_PALETTE_WIDTH 1:1
-#define NV_PCRTC_REPAINT1_PALETTE_WIDTH_8BITS 0x00
-#define NV_PCRTC_REPAINT1_PALETTE_WIDTH_6BITS 0x01
-
-#define NV_PCRTC_GRCURSOR0 0x30
-#define NV_PCRTC_GRCURSOR0_START_ADDR_21_16 5:0
-
-#define NV_PCRTC_GRCURSOR1 0x31
-#define NV_PCRTC_GRCURSOR1_START_ADDR_15_11 7:3
-#define NV_PCRTC_GRCURSOR1_SCAN_DBL 1:1
-#define NV_PCRTC_GRCURSOR1_SCAN_DBL_DISABLE 0
-#define NV_PCRTC_GRCURSOR1_SCAN_DBL_ENABLE 1
-#define NV_PCRTC_GRCURSOR1_CURSOR 0:0
-#define NV_PCRTC_GRCURSOR1_CURSOR_DISABLE 0
-#define NV_PCRTC_GRCURSOR1_CURSOR_ENABLE 1
-
-/* Controls what the format of the framebuffer is */
-#define NV_PCRTC_PIXEL 0x28
-#define NV_PCRTC_PIXEL_MODE 7:7
-#define NV_PCRTC_PIXEL_MODE_TV 0x01
-#define NV_PCRTC_PIXEL_MODE_VGA 0x00
-#define NV_PCRTC_PIXEL_TV_MODE 6:6
-#define NV_PCRTC_PIXEL_TV_MODE_NTSC 0x00
-#define NV_PCRTC_PIXEL_TV_MODE_PAL 0x01
-#define NV_PCRTC_PIXEL_TV_HORIZ_ADJUST 5:3
-#define NV_PCRTC_PIXEL_FORMAT 1:0
-#define NV_PCRTC_PIXEL_FORMAT_VGA 0x00
-#define NV_PCRTC_PIXEL_FORMAT_8BPP 0x01
-#define NV_PCRTC_PIXEL_FORMAT_16BPP 0x02
-#define NV_PCRTC_PIXEL_FORMAT_32BPP 0x03
-
-/* RAMDAC registers and fields */
-#define NV_PRAMDAC 0x00680FFF:0x00680000 /* RW--D */
-#define NV_PRAMDAC_GRCURSOR_START_POS 0x00680300 /* RW-4R */
-#define NV_PRAMDAC_GRCURSOR_START_POS_X 11:0 /* RWXSF */
-#define NV_PRAMDAC_GRCURSOR_START_POS_Y 27:16 /* RWXSF */
-#define NV_PRAMDAC_NVPLL_COEFF 0x00680500 /* RW-4R */
-#define NV_PRAMDAC_NVPLL_COEFF_MDIV 7:0 /* RWIUF */
-#define NV_PRAMDAC_NVPLL_COEFF_NDIV 15:8 /* RWIUF */
-#define NV_PRAMDAC_NVPLL_COEFF_PDIV 18:16 /* RWIVF */
-#define NV_PRAMDAC_MPLL_COEFF 0x00680504 /* RW-4R */
-#define NV_PRAMDAC_MPLL_COEFF_MDIV 7:0 /* RWIUF */
-#define NV_PRAMDAC_MPLL_COEFF_NDIV 15:8 /* RWIUF */
-#define NV_PRAMDAC_MPLL_COEFF_PDIV 18:16 /* RWIVF */
-#define NV_PRAMDAC_VPLL_COEFF 0x00680508 /* RW-4R */
-#define NV_PRAMDAC_VPLL_COEFF_MDIV 7:0 /* RWIUF */
-#define NV_PRAMDAC_VPLL_COEFF_NDIV 15:8 /* RWIUF */
-#define NV_PRAMDAC_VPLL_COEFF_PDIV 18:16 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT 0x0068050C /* RW-4R */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS 4:4 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS_FALSE 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS_TRUE 0x00000001 /* RW--V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE 8:8 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE_DEFAULT 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE_PROG 0x00000001 /* RW--V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS 12:12 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS_FALSE 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS_TRUE 0x00000001 /* RW--V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE 16:16 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE_DEFAULT 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE_PROG 0x00000001 /* RW--V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS 20:20 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS_FALSE 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS_TRUE 0x00000001 /* RW--V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE 25:24 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_VPLL 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_VIP 0x00000001 /* RW--V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_XTALOSC 0x00000002 /* RW--V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO 28:28 /* RWIVF */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB1 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL 0x00680600 /* RW-4R */
-#define NV_PRAMDAC_GENERAL_CONTROL_FF_COEFF 1:0 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_FF_COEFF_DEF 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE 4:4 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE_GAMMA 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE_INDEX 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE 8:8 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_NOTSE 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL_565_MODE 12:12 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_565_MODE_NOTSEL 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_565_MODE_SEL 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL 16:16 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL_OFF 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL_ON 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION 17:17 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_37OHM 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL_BPC 20:20 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_BPC_6BITS 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP 24:24 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP_DIS 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP_EN 0x00000001 /* RW--V */
-#define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK 28:28 /* RWIVF */
-#define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK_EN 0x00000000 /* RWI-V */
-#define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK_DIS 0x00000001 /* RW--V */
-
-/* Master Control */
-#define NV_PMC 0x00000FFF:0x00000000 /* RW--D */
-#define NV_PMC_BOOT_0 0x00000000 /* R--4R */
-#define NV_PMC_BOOT_0_MINOR_REVISION 3:0 /* C--VF */
-#define NV_PMC_BOOT_0_MINOR_REVISION_0 0x00000000 /* C---V */
-#define NV_PMC_BOOT_0_MAJOR_REVISION 7:4 /* C--VF */
-#define NV_PMC_BOOT_0_MAJOR_REVISION_A 0x00000000 /* C---V */
-#define NV_PMC_BOOT_0_MAJOR_REVISION_B 0x00000001 /* ----V */
-#define NV_PMC_BOOT_0_IMPLEMENTATION 11:8 /* C--VF */
-#define NV_PMC_BOOT_0_IMPLEMENTATION_NV4_0 0x00000000 /* C---V */
-#define NV_PMC_BOOT_0_ARCHITECTURE 15:12 /* C--VF */
-#define NV_PMC_BOOT_0_ARCHITECTURE_NV0 0x00000000 /* ----V */
-#define NV_PMC_BOOT_0_ARCHITECTURE_NV1 0x00000001 /* ----V */
-#define NV_PMC_BOOT_0_ARCHITECTURE_NV2 0x00000002 /* ----V */
-#define NV_PMC_BOOT_0_ARCHITECTURE_NV3 0x00000003 /* ----V */
-#define NV_PMC_BOOT_0_ARCHITECTURE_NV4 0x00000004 /* C---V */
-#define NV_PMC_BOOT_0_FIB_REVISION 19:16 /* C--VF */
-#define NV_PMC_BOOT_0_FIB_REVISION_0 0x00000000 /* C---V */
-#define NV_PMC_BOOT_0_MASK_REVISION 23:20 /* C--VF */
-#define NV_PMC_BOOT_0_MASK_REVISION_A 0x00000000 /* C---V */
-#define NV_PMC_BOOT_0_MASK_REVISION_B 0x00000001 /* ----V */
-#define NV_PMC_BOOT_0_MANUFACTURER 27:24 /* C--UF */
-#define NV_PMC_BOOT_0_MANUFACTURER_NVIDIA 0x00000000 /* C---V */
-#define NV_PMC_BOOT_0_FOUNDRY 31:28 /* C--VF */
-#define NV_PMC_BOOT_0_FOUNDRY_SGS 0x00000000 /* ----V */
-#define NV_PMC_BOOT_0_FOUNDRY_HELIOS 0x00000001 /* ----V */
-#define NV_PMC_BOOT_0_FOUNDRY_TSMC 0x00000002 /* C---V */
-#define NV_PMC_INTR_0 0x00000100 /* RW-4R */
-#define NV_PMC_INTR_0_PMEDIA 4:4 /* R--VF */
-#define NV_PMC_INTR_0_PMEDIA_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PMC_INTR_0_PMEDIA_PENDING 0x00000001 /* R---V */
-#define NV_PMC_INTR_0_PFIFO 8:8 /* R--VF */
-#define NV_PMC_INTR_0_PFIFO_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PMC_INTR_0_PFIFO_PENDING 0x00000001 /* R---V */
-#define NV_PMC_INTR_0_PGRAPH 12:12 /* R--VF */
-#define NV_PMC_INTR_0_PGRAPH_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PMC_INTR_0_PGRAPH_PENDING 0x00000001 /* R---V */
-#define NV_PMC_INTR_0_PVIDEO 16:16 /* R--VF */
-#define NV_PMC_INTR_0_PVIDEO_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PMC_INTR_0_PVIDEO_PENDING 0x00000001 /* R---V */
-#define NV_PMC_INTR_0_PTIMER 20:20 /* R--VF */
-#define NV_PMC_INTR_0_PTIMER_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PMC_INTR_0_PTIMER_PENDING 0x00000001 /* R---V */
-#define NV_PMC_INTR_0_PCRTC 24:24 /* R--VF */
-#define NV_PMC_INTR_0_PCRTC_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PMC_INTR_0_PCRTC_PENDING 0x00000001 /* R---V */
-#define NV_PMC_INTR_0_PBUS 28:28 /* R--VF */
-#define NV_PMC_INTR_0_PBUS_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PMC_INTR_0_PBUS_PENDING 0x00000001 /* R---V */
-#define NV_PMC_INTR_0_SOFTWARE 31:31 /* RWIVF */
-#define NV_PMC_INTR_0_SOFTWARE_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PMC_INTR_0_SOFTWARE_PENDING 0x00000001 /* RW--V */
-#define NV_PMC_INTR_EN_0 0x00000140 /* RW-4R */
-#define NV_PMC_INTR_EN_0_INTA 1:0 /* RWIVF */
-#define NV_PMC_INTR_EN_0_INTA_DISABLED 0x00000000 /* RWI-V */
-#define NV_PMC_INTR_EN_0_INTA_HARDWARE 0x00000001 /* RW--V */
-#define NV_PMC_INTR_EN_0_INTA_SOFTWARE 0x00000002 /* RW--V */
-#define NV_PMC_INTR_READ_0 0x00000160 /* R--4R */
-#define NV_PMC_INTR_READ_0_INTA 0:0 /* R--VF */
-#define NV_PMC_INTR_READ_0_INTA_LOW 0x00000000 /* R---V */
-#define NV_PMC_INTR_READ_0_INTA_HIGH 0x00000001 /* R---V */
-#define NV_PMC_ENABLE 0x00000200 /* RW-4R */
-#define NV_PMC_ENABLE_PMEDIA 4:4 /* RWIVF */
-#define NV_PMC_ENABLE_PMEDIA_DISABLED 0x00000000 /* RWI-V */
-#define NV_PMC_ENABLE_PMEDIA_ENABLED 0x00000001 /* RW--V */
-#define NV_PMC_ENABLE_PFIFO 8:8 /* RWIVF */
-#define NV_PMC_ENABLE_PFIFO_DISABLED 0x00000000 /* RWI-V */
-#define NV_PMC_ENABLE_PFIFO_ENABLED 0x00000001 /* RW--V */
-#define NV_PMC_ENABLE_PGRAPH 12:12 /* RWIVF */
-#define NV_PMC_ENABLE_PGRAPH_DISABLED 0x00000000 /* RWI-V */
-#define NV_PMC_ENABLE_PGRAPH_ENABLED 0x00000001 /* RW--V */
-#define NV_PMC_ENABLE_PPMI 16:16 /* RWIVF */
-#define NV_PMC_ENABLE_PPMI_DISABLED 0x00000000 /* RWI-V */
-#define NV_PMC_ENABLE_PPMI_ENABLED 0x00000001 /* RW--V */
-#define NV_PMC_ENABLE_PFB 20:20 /* RWIVF */
-#define NV_PMC_ENABLE_PFB_DISABLED 0x00000000 /* RW--V */
-#define NV_PMC_ENABLE_PFB_ENABLED 0x00000001 /* RWI-V */
-#define NV_PMC_ENABLE_PCRTC 24:24 /* RWIVF */
-#define NV_PMC_ENABLE_PCRTC_DISABLED 0x00000000 /* RW--V */
-#define NV_PMC_ENABLE_PCRTC_ENABLED 0x00000001 /* RWI-V */
-#define NV_PMC_ENABLE_PVIDEO 28:28 /* RWIVF */
-#define NV_PMC_ENABLE_PVIDEO_DISABLED 0x00000000 /* RWI-V */
-#define NV_PMC_ENABLE_PVIDEO_ENABLED 0x00000001 /* RW--V */
-
-/* dev_timer.ref */
-#define NV_PTIMER 0x00009FFF:0x00009000 /* RW--D */
-#define NV_PTIMER_INTR_0 0x00009100 /* RW-4R */
-#define NV_PTIMER_INTR_0_ALARM 0:0 /* RWXVF */
-#define NV_PTIMER_INTR_0_ALARM_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PTIMER_INTR_0_ALARM_PENDING 0x00000001 /* R---V */
-#define NV_PTIMER_INTR_0_ALARM_RESET 0x00000001 /* -W--V */
-#define NV_PTIMER_INTR_EN_0 0x00009140 /* RW-4R */
-#define NV_PTIMER_INTR_EN_0_ALARM 0:0 /* RWIVF */
-#define NV_PTIMER_INTR_EN_0_ALARM_DISABLED 0x00000000 /* RWI-V */
-#define NV_PTIMER_INTR_EN_0_ALARM_ENABLED 0x00000001 /* RW--V */
-#define NV_PTIMER_NUMERATOR 0x00009200 /* RW-4R */
-#define NV_PTIMER_NUMERATOR_VALUE 15:0 /* RWIUF */
-#define NV_PTIMER_NUMERATOR_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PTIMER_DENOMINATOR 0x00009210 /* RW-4R */
-#define NV_PTIMER_DENOMINATOR_VALUE 15:0 /* RWIUF */
-#define NV_PTIMER_DENOMINATOR_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PTIMER_TIME_0 0x00009400 /* RW-4R */
-#define NV_PTIMER_TIME_0_NSEC 31:5 /* RWXUF */
-#define NV_PTIMER_TIME_1 0x00009410 /* RW-4R */
-#define NV_PTIMER_TIME_1_NSEC 28:0 /* RWXUF */
-#define NV_PTIMER_ALARM_0 0x00009420 /* RW-4R */
-#define NV_PTIMER_ALARM_0_NSEC 31:5 /* RWXUF */
-
-/* dev_fifo.ref */
-#define NV_PFIFO 0x00003FFF:0x00002000 /* RW--D */
-#define NV_PFIFO_DELAY_0 0x00002040 /* RW-4R */
-#define NV_PFIFO_DELAY_0_WAIT_RETRY 9:0 /* RWIUF */
-#define NV_PFIFO_DELAY_0_WAIT_RETRY_0 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_TIMESLICE 0x00002044 /* RW-4R */
-#define NV_PFIFO_DMA_TIMESLICE_SELECT 16:0 /* RWIUF */
-#define NV_PFIFO_DMA_TIMESLICE_SELECT_1 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_TIMESLICE_SELECT_16K 0x00003fff /* RW--V */
-#define NV_PFIFO_DMA_TIMESLICE_SELECT_32K 0x00007fff /* RW--V */
-#define NV_PFIFO_DMA_TIMESLICE_SELECT_64K 0x0000ffff /* RW--V */
-#define NV_PFIFO_DMA_TIMESLICE_SELECT_128K 0x0001ffff /* RW--V */
-#define NV_PFIFO_DMA_TIMESLICE_TIMEOUT 24:24 /* RWIUF */
-#define NV_PFIFO_DMA_TIMESLICE_TIMEOUT_DISABLED 0x00000000 /* RW--V */
-#define NV_PFIFO_DMA_TIMESLICE_TIMEOUT_ENABLED 0x00000001 /* RWI-V */
-#define NV_PFIFO_PIO_TIMESLICE 0x00002048 /* RW-4R */
-#define NV_PFIFO_PIO_TIMESLICE_SELECT 16:0 /* RWIUF */
-#define NV_PFIFO_PIO_TIMESLICE_SELECT_1 0x00000000 /* RWI-V */
-#define NV_PFIFO_PIO_TIMESLICE_SELECT_16K 0x00003fff /* RW--V */
-#define NV_PFIFO_PIO_TIMESLICE_SELECT_32K 0x00007fff /* RW--V */
-#define NV_PFIFO_PIO_TIMESLICE_SELECT_64K 0x0000ffff /* RW--V */
-#define NV_PFIFO_PIO_TIMESLICE_SELECT_128K 0x0001ffff /* RW--V */
-#define NV_PFIFO_PIO_TIMESLICE_TIMEOUT 24:24 /* RWIUF */
-#define NV_PFIFO_PIO_TIMESLICE_TIMEOUT_DISABLED 0x00000000 /* RW--V */
-#define NV_PFIFO_PIO_TIMESLICE_TIMEOUT_ENABLED 0x00000001 /* RWI-V */
-#define NV_PFIFO_TIMESLICE 0x0000204C /* RW-4R */
-#define NV_PFIFO_TIMESLICE_TIMER 17:0 /* RWIUF */
-#define NV_PFIFO_TIMESLICE_TIMER_EXPIRED 0x0003FFFF /* RWI-V */
-#define NV_PFIFO_NEXT_CHANNEL 0x00002050 /* RW-4R */
-#define NV_PFIFO_NEXT_CHANNEL_CHID 3:0 /* RWXUF */
-#define NV_PFIFO_NEXT_CHANNEL_MODE 8:8 /* RWXVF */
-#define NV_PFIFO_NEXT_CHANNEL_MODE_PIO 0x00000000 /* RW--V */
-#define NV_PFIFO_NEXT_CHANNEL_MODE_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_NEXT_CHANNEL_SWITCH 12:12 /* RWIVF */
-#define NV_PFIFO_NEXT_CHANNEL_SWITCH_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_NEXT_CHANNEL_SWITCH_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DEBUG_0 0x00002080 /* R--4R */
-#define NV_PFIFO_DEBUG_0_CACHE_ERROR0 0:0 /* R-XVF */
-#define NV_PFIFO_DEBUG_0_CACHE_ERROR0_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PFIFO_DEBUG_0_CACHE_ERROR0_PENDING 0x00000001 /* R---V */
-#define NV_PFIFO_DEBUG_0_CACHE_ERROR1 4:4 /* R-XVF */
-#define NV_PFIFO_DEBUG_0_CACHE_ERROR1_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PFIFO_DEBUG_0_CACHE_ERROR1_PENDING 0x00000001 /* R---V */
-#define NV_PFIFO_INTR_0 0x00002100 /* RW-4R */
-#define NV_PFIFO_INTR_0_CACHE_ERROR 0:0 /* RWXVF */
-#define NV_PFIFO_INTR_0_CACHE_ERROR_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PFIFO_INTR_0_CACHE_ERROR_PENDING 0x00000001 /* R---V */
-#define NV_PFIFO_INTR_0_CACHE_ERROR_RESET 0x00000001 /* -W--V */
-#define NV_PFIFO_INTR_0_RUNOUT 4:4 /* RWXVF */
-#define NV_PFIFO_INTR_0_RUNOUT_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PFIFO_INTR_0_RUNOUT_PENDING 0x00000001 /* R---V */
-#define NV_PFIFO_INTR_0_RUNOUT_RESET 0x00000001 /* -W--V */
-#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW 8:8 /* RWXVF */
-#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_PENDING 0x00000001 /* R---V */
-#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_RESET 0x00000001 /* -W--V */
-#define NV_PFIFO_INTR_0_DMA_PUSHER 12:12 /* RWXVF */
-#define NV_PFIFO_INTR_0_DMA_PUSHER_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PFIFO_INTR_0_DMA_PUSHER_PENDING 0x00000001 /* R---V */
-#define NV_PFIFO_INTR_0_DMA_PUSHER_RESET 0x00000001 /* -W--V */
-#define NV_PFIFO_INTR_0_DMA_PT 16:16 /* RWXVF */
-#define NV_PFIFO_INTR_0_DMA_PT_NOT_PENDING 0x00000000 /* R---V */
-#define NV_PFIFO_INTR_0_DMA_PT_PENDING 0x00000001 /* R---V */
-#define NV_PFIFO_INTR_0_DMA_PT_RESET 0x00000001 /* -W--V */
-#define NV_PFIFO_INTR_EN_0 0x00002140 /* RW-4R */
-#define NV_PFIFO_INTR_EN_0_CACHE_ERROR 0:0 /* RWIVF */
-#define NV_PFIFO_INTR_EN_0_CACHE_ERROR_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_INTR_EN_0_CACHE_ERROR_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_INTR_EN_0_RUNOUT 4:4 /* RWIVF */
-#define NV_PFIFO_INTR_EN_0_RUNOUT_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_INTR_EN_0_RUNOUT_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW 8:8 /* RWIVF */
-#define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_INTR_EN_0_DMA_PUSHER 12:12 /* RWIVF */
-#define NV_PFIFO_INTR_EN_0_DMA_PUSHER_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_INTR_EN_0_DMA_PUSHER_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_INTR_EN_0_DMA_PT 16:16 /* RWIVF */
-#define NV_PFIFO_INTR_EN_0_DMA_PT_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_INTR_EN_0_DMA_PT_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_RAMHT 0x00002210 /* RW-4R */
-#define NV_PFIFO_RAMHT_BASE_ADDRESS 8:4 /* RWIUF */
-#define NV_PFIFO_RAMHT_BASE_ADDRESS_10000 0x00000010 /* RWI-V */
-#define NV_PFIFO_RAMHT_SIZE 17:16 /* RWIUF */
-#define NV_PFIFO_RAMHT_SIZE_4K 0x00000000 /* RWI-V */
-#define NV_PFIFO_RAMHT_SIZE_8K 0x00000001 /* RW--V */
-#define NV_PFIFO_RAMHT_SIZE_16K 0x00000002 /* RW--V */
-#define NV_PFIFO_RAMHT_SIZE_32K 0x00000003 /* RW--V */
-#define NV_PFIFO_RAMHT_SEARCH 25:24 /* RWIUF */
-#define NV_PFIFO_RAMHT_SEARCH_16 0x00000000 /* RWI-V */
-#define NV_PFIFO_RAMHT_SEARCH_32 0x00000001 /* RW--V */
-#define NV_PFIFO_RAMHT_SEARCH_64 0x00000002 /* RW--V */
-#define NV_PFIFO_RAMHT_SEARCH_128 0x00000003 /* RW--V */
-#define NV_PFIFO_RAMFC 0x00002214 /* RW-4R */
-#define NV_PFIFO_RAMFC_BASE_ADDRESS 8:1 /* RWIUF */
-#define NV_PFIFO_RAMFC_BASE_ADDRESS_11000 0x00000088 /* RWI-V */
-#define NV_PFIFO_RAMRO 0x00002218 /* RW-4R */
-#define NV_PFIFO_RAMRO_BASE_ADDRESS 8:1 /* RWIUF */
-#define NV_PFIFO_RAMRO_BASE_ADDRESS_11200 0x00000089 /* RWI-V */
-#define NV_PFIFO_RAMRO_BASE_ADDRESS_12000 0x00000090 /* RW--V */
-#define NV_PFIFO_RAMRO_SIZE 16:16 /* RWIVF */
-#define NV_PFIFO_RAMRO_SIZE_512 0x00000000 /* RWI-V */
-#define NV_PFIFO_RAMRO_SIZE_8K 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHES 0x00002500 /* RW-4R */
-#define NV_PFIFO_CACHES_REASSIGN 0:0 /* RWIVF */
-#define NV_PFIFO_CACHES_REASSIGN_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHES_REASSIGN_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHES_DMA_SUSPEND 4:4 /* R--VF */
-#define NV_PFIFO_CACHES_DMA_SUSPEND_IDLE 0x00000000 /* R---V */
-#define NV_PFIFO_CACHES_DMA_SUSPEND_BUSY 0x00000001 /* R---V */
-#define NV_PFIFO_MODE 0x00002504 /* RW-4R */
-#define NV_PFIFO_MODE_CHANNEL_0 0:0 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_0_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_0_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_1 1:1 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_1_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_1_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_2 2:2 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_2_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_2_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_3 3:3 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_3_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_3_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_4 4:4 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_4_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_4_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_5 5:5 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_5_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_5_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_6 6:6 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_6_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_6_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_7 7:7 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_7_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_7_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_8 8:8 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_8_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_8_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_9 9:9 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_9_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_9_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_10 10:10 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_10_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_10_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_11 11:11 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_11_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_11_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_12 12:12 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_12_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_12_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_13 13:13 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_13_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_13_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_14 14:14 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_14_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_14_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_MODE_CHANNEL_15 15:15 /* RWIVF */
-#define NV_PFIFO_MODE_CHANNEL_15_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_MODE_CHANNEL_15_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA 0x00002508 /* RW-4R */
-#define NV_PFIFO_DMA_CHANNEL_0 0:0 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_0_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_0_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_1 1:1 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_1_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_1_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_2 2:2 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_2_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_2_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_3 3:3 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_3_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_3_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_4 4:4 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_4_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_4_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_5 5:5 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_5_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_5_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_6 6:6 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_6_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_6_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_7 7:7 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_7_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_7_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_8 8:8 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_8_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_8_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_9 9:9 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_9_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_9_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_10 10:10 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_10_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_10_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_11 11:11 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_11_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_11_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_12 12:12 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_12_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_12_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_13 13:13 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_13_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_13_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_14 14:14 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_14_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_14_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_DMA_CHANNEL_15 15:15 /* RWIVF */
-#define NV_PFIFO_DMA_CHANNEL_15_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PFIFO_DMA_CHANNEL_15_PENDING 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE 0x0000250C /* RW-4R */
-#define NV_PFIFO_SIZE_CHANNEL_0 0:0 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_0_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_0_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_1 1:1 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_1_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_1_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_2 2:2 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_2_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_2_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_3 3:3 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_3_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_3_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_4 4:4 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_4_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_4_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_5 5:5 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_5_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_5_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_6 6:6 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_6_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_6_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_7 7:7 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_7_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_7_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_8 8:8 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_8_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_8_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_9 9:9 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_9_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_9_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_10 10:10 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_10_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_10_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_11 11:11 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_11_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_11_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_12 12:12 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_12_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_12_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_13 13:13 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_13_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_13_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_14 14:14 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_14_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_14_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_SIZE_CHANNEL_15 15:15 /* RWIVF */
-#define NV_PFIFO_SIZE_CHANNEL_15_124_BYTES 0x00000000 /* RWI-V */
-#define NV_PFIFO_SIZE_CHANNEL_15_512_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_PUSH0 0x00003000 /* RW-4R */
-#define NV_PFIFO_CACHE0_PUSH0_ACCESS 0:0 /* RWIVF */
-#define NV_PFIFO_CACHE0_PUSH0_ACCESS_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE0_PUSH0_ACCESS_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_PUSH0 0x00003200 /* RW-4R */
-#define NV_PFIFO_CACHE1_PUSH0_ACCESS 0:0 /* RWIVF */
-#define NV_PFIFO_CACHE1_PUSH0_ACCESS_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_PUSH0_ACCESS_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_PUSH1 0x00003004 /* RW-4R */
-#define NV_PFIFO_CACHE0_PUSH1_CHID 3:0 /* RWXUF */
-#define NV_PFIFO_CACHE1_PUSH1 0x00003204 /* RW-4R */
-#define NV_PFIFO_CACHE1_PUSH1_CHID 3:0 /* RWXUF */
-#define NV_PFIFO_CACHE1_PUSH1_MODE 8:8 /* RWIVF */
-#define NV_PFIFO_CACHE1_PUSH1_MODE_PIO 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_PUSH1_MODE_DMA 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_PUSH 0x00003220 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS 0:0 /* RWIVF */
-#define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_PUSH_STATE 4:4 /* R--VF */
-#define NV_PFIFO_CACHE1_DMA_PUSH_STATE_IDLE 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_DMA_PUSH_STATE_BUSY 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER 8:8 /* R--VF */
-#define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER_NOT_EMPTY 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER_EMPTY 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_DMA_PUSH_STATUS 12:12 /* RWIVF */
-#define NV_PFIFO_CACHE1_DMA_PUSH_STATUS_RUNNING 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_PUSH_STATUS_SUSPENDED 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH 0x00003224 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG 7:3 /* RWIUF */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_16_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_24_BYTES 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_32_BYTES 0x00000003 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_40_BYTES 0x00000004 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_48_BYTES 0x00000005 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_56_BYTES 0x00000006 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_64_BYTES 0x00000007 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_72_BYTES 0x00000008 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_80_BYTES 0x00000009 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_88_BYTES 0x0000000A /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_96_BYTES 0x0000000B /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_104_BYTES 0x0000000C /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES 0x0000000D /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_120_BYTES 0x0000000E /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES 0x0000000F /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_136_BYTES 0x00000010 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_144_BYTES 0x00000011 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_152_BYTES 0x00000012 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_160_BYTES 0x00000013 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_168_BYTES 0x00000014 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_176_BYTES 0x00000015 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_184_BYTES 0x00000016 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_192_BYTES 0x00000017 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_200_BYTES 0x00000018 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_208_BYTES 0x00000019 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_216_BYTES 0x0000001A /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_224_BYTES 0x0000001B /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_232_BYTES 0x0000001C /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_240_BYTES 0x0000001D /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_248_BYTES 0x0000001E /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_256_BYTES 0x0000001F /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE 15:13 /* RWIUF */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_32_BYTES 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_64_BYTES 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_96_BYTES 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES 0x00000003 /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_160_BYTES 0x00000004 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_192_BYTES 0x00000005 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_224_BYTES 0x00000006 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_256_BYTES 0x00000007 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS 19:16 /* RWIUF */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_0 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_1 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_2 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_3 0x00000003 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 0x00000004 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_5 0x00000005 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_6 0x00000006 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_7 0x00000007 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 0x00000008 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_9 0x00000009 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_10 0x0000000A /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_11 0x0000000B /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_12 0x0000000C /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_13 0x0000000D /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_14 0x0000000E /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15 0x0000000F /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_PUT 0x00003240 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_PUT_OFFSET 28:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_GET 0x00003244 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_GET_OFFSET 28:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_STATE 0x00003228 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_STATE_METHOD 12:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_STATE_SUBCHANNEL 15:13 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT 28:18 /* RWIUF */
-#define NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT_0 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_STATE_ERROR 31:30 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_NONE 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_NON_CACHE 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_RESERVED_CMD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_PROTECTION 0x00000003 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_INSTANCE 0x0000322C /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS 15:0 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_CTL 0x00003230 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_CTL_ADJUST 11:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE 12:12 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE_NOT_PRESENT 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE_PRESENT 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY 13:13 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY_NOT_LINEAR 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY_LINEAR 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE 17:16 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE_PCI 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE_AGP 0x00000003 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO 31:31 /* RWIUF */
-#define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO_INVALID 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO_VALID 0x00000001 /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_LIMIT 0x00003234 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_LIMIT_OFFSET 28:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_TLB_TAG 0x00003238 /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_TLB_TAG_ADDRESS 28:12 /* RWXUF */
-#define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE 0:0 /* RWIUF */
-#define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE_INVALID 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE_VALID 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_DMA_TLB_PTE 0x0000323C /* RW-4R */
-#define NV_PFIFO_CACHE1_DMA_TLB_PTE_FRAME_ADDRESS 31:12 /* RWXUF */
-#define NV_PFIFO_CACHE0_PULL0 0x00003050 /* RW-4R */
-#define NV_PFIFO_CACHE0_PULL0_ACCESS 0:0 /* RWIVF */
-#define NV_PFIFO_CACHE0_PULL0_ACCESS_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE0_PULL0_ACCESS_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_PULL0_HASH 4:4 /* R-XVF */
-#define NV_PFIFO_CACHE0_PULL0_HASH_SUCCEEDED 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE0_PULL0_HASH_FAILED 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE0_PULL0_DEVICE 8:8 /* R-XVF */
-#define NV_PFIFO_CACHE0_PULL0_DEVICE_HARDWARE 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE0_PULL0_DEVICE_SOFTWARE 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE0_PULL0_HASH_STATE 12:12 /* R-XVF */
-#define NV_PFIFO_CACHE0_PULL0_HASH_STATE_IDLE 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE0_PULL0_HASH_STATE_BUSY 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_PULL0 0x00003250 /* RW-4R */
-#define NV_PFIFO_CACHE1_PULL0_ACCESS 0:0 /* RWIVF */
-#define NV_PFIFO_CACHE1_PULL0_ACCESS_DISABLED 0x00000000 /* RWI-V */
-#define NV_PFIFO_CACHE1_PULL0_ACCESS_ENABLED 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_PULL0_HASH 4:4 /* R-XVF */
-#define NV_PFIFO_CACHE1_PULL0_HASH_SUCCEEDED 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_PULL0_HASH_FAILED 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_PULL0_DEVICE 8:8 /* R-XVF */
-#define NV_PFIFO_CACHE1_PULL0_DEVICE_HARDWARE 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_PULL0_DEVICE_SOFTWARE 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_PULL0_HASH_STATE 12:12 /* R-XVF */
-#define NV_PFIFO_CACHE1_PULL0_HASH_STATE_IDLE 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_PULL0_HASH_STATE_BUSY 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE0_PULL1 0x00003054 /* RW-4R */
-#define NV_PFIFO_CACHE0_PULL1_ENGINE 1:0 /* RWXUF */
-#define NV_PFIFO_CACHE0_PULL1_ENGINE_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_PULL1_ENGINE_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_PULL1_ENGINE_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_PULL1 0x00003254 /* RW-4R */
-#define NV_PFIFO_CACHE1_PULL1_ENGINE 1:0 /* RWXUF */
-#define NV_PFIFO_CACHE1_PULL1_ENGINE_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_PULL1_ENGINE_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_PULL1_ENGINE_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_HASH 0x00003058 /* RW-4R */
-#define NV_PFIFO_CACHE0_HASH_INSTANCE 15:0 /* RWXUF */
-#define NV_PFIFO_CACHE0_HASH_VALID 16:16 /* RWXVF */
-#define NV_PFIFO_CACHE1_HASH 0x00003258 /* RW-4R */
-#define NV_PFIFO_CACHE1_HASH_INSTANCE 15:0 /* RWXUF */
-#define NV_PFIFO_CACHE1_HASH_VALID 16:16 /* RWXVF */
-#define NV_PFIFO_CACHE0_STATUS 0x00003014 /* R--4R */
-#define NV_PFIFO_CACHE0_STATUS_LOW_MARK 4:4 /* R--VF */
-#define NV_PFIFO_CACHE0_STATUS_LOW_MARK_NOT_EMPTY 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE0_STATUS_LOW_MARK_EMPTY 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE0_STATUS_HIGH_MARK 8:8 /* R--VF */
-#define NV_PFIFO_CACHE0_STATUS_HIGH_MARK_NOT_FULL 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE0_STATUS_HIGH_MARK_FULL 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_STATUS 0x00003214 /* R--4R */
-#define NV_PFIFO_CACHE1_STATUS_LOW_MARK 4:4 /* R--VF */
-#define NV_PFIFO_CACHE1_STATUS_LOW_MARK_NOT_EMPTY 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_STATUS_LOW_MARK_EMPTY 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_STATUS_HIGH_MARK 8:8 /* R--VF */
-#define NV_PFIFO_CACHE1_STATUS_HIGH_MARK_NOT_FULL 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_STATUS_HIGH_MARK_FULL 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE1_STATUS1 0x00003218 /* R--4R */
-#define NV_PFIFO_CACHE1_STATUS1_RANOUT 0:0 /* R-XVF */
-#define NV_PFIFO_CACHE1_STATUS1_RANOUT_FALSE 0x00000000 /* R---V */
-#define NV_PFIFO_CACHE1_STATUS1_RANOUT_TRUE 0x00000001 /* R---V */
-#define NV_PFIFO_CACHE0_PUT 0x00003010 /* RW-4R */
-#define NV_PFIFO_CACHE0_PUT_ADDRESS 2:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_PUT 0x00003210 /* RW-4R */
-#define NV_PFIFO_CACHE1_PUT_ADDRESS 9:2 /* RWXUF */
-#define NV_PFIFO_CACHE0_GET 0x00003070 /* RW-4R */
-#define NV_PFIFO_CACHE0_GET_ADDRESS 2:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_GET 0x00003270 /* RW-4R */
-#define NV_PFIFO_CACHE1_GET_ADDRESS 9:2 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE 0x00003080 /* RW-4R */
-#define NV_PFIFO_CACHE0_ENGINE_0 1:0 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_0_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_0_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_0_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_1 5:4 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_1_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_1_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_1_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_2 9:8 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_2_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_2_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_2_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_3 13:12 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_3_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_3_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_3_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_4 17:16 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_4_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_4_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_4_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_5 21:20 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_5_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_5_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_5_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_6 25:24 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_6_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_6_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_6_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_7 29:28 /* RWXUF */
-#define NV_PFIFO_CACHE0_ENGINE_7_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_7_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE0_ENGINE_7_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE 0x00003280 /* RW-4R */
-#define NV_PFIFO_CACHE1_ENGINE_0 1:0 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_0_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_0_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_0_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_1 5:4 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_1_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_1_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_1_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_2 9:8 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_2_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_2_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_2_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_3 13:12 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_3_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_3_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_3_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_4 17:16 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_4_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_4_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_4_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_5 21:20 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_5_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_5_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_5_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_6 25:24 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_6_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_6_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_6_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_7 29:28 /* RWXUF */
-#define NV_PFIFO_CACHE1_ENGINE_7_SW 0x00000000 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_7_GRAPHICS 0x00000001 /* RW--V */
-#define NV_PFIFO_CACHE1_ENGINE_7_DVD 0x00000002 /* RW--V */
-#define NV_PFIFO_CACHE0_METHOD(i) (0x00003100+(i)*8) /* RW-4A */
-#define NV_PFIFO_CACHE0_METHOD__SIZE_1 1 /* */
-#define NV_PFIFO_CACHE0_METHOD_ADDRESS 12:2 /* RWXUF */
-#define NV_PFIFO_CACHE0_METHOD_SUBCHANNEL 15:13 /* RWXUF */
-#define NV_PFIFO_CACHE1_METHOD(i) (0x00003800+(i)*8) /* RW-4A */
-#define NV_PFIFO_CACHE1_METHOD__SIZE_1 128 /* */
-#define NV_PFIFO_CACHE1_METHOD_ADDRESS 12:2 /* RWXUF */
-#define NV_PFIFO_CACHE1_METHOD_SUBCHANNEL 15:13 /* RWXUF */
-#define NV_PFIFO_CACHE1_METHOD_ALIAS(i) (0x00003C00+(i)*8) /* RW-4A */
-#define NV_PFIFO_CACHE1_METHOD_ALIAS__SIZE_1 128 /* */
-#define NV_PFIFO_CACHE0_DATA(i) (0x00003104+(i)*8) /* RW-4A */
-#define NV_PFIFO_CACHE0_DATA__SIZE_1 1 /* */
-#define NV_PFIFO_CACHE0_DATA_VALUE 31:0 /* RWXVF */
-#define NV_PFIFO_CACHE1_DATA(i) (0x00003804+(i)*8) /* RW-4A */
-#define NV_PFIFO_CACHE1_DATA__SIZE_1 128 /* */
-#define NV_PFIFO_CACHE1_DATA_VALUE 31:0 /* RWXVF */
-#define NV_PFIFO_CACHE1_DATA_ALIAS(i) (0x00003C04+(i)*8) /* RW-4A */
-#define NV_PFIFO_CACHE1_DATA_ALIAS__SIZE_1 128 /* */
-#define NV_PFIFO_DEVICE(i) (0x00002800+(i)*4) /* R--4A */
-#define NV_PFIFO_DEVICE__SIZE_1 128 /* */
-#define NV_PFIFO_DEVICE_CHID 3:0 /* R--UF */
-#define NV_PFIFO_DEVICE_SWITCH 24:24 /* R--VF */
-#define NV_PFIFO_DEVICE_SWITCH_UNAVAILABLE 0x00000000 /* R---V */
-#define NV_PFIFO_DEVICE_SWITCH_AVAILABLE 0x00000001 /* R---V */
-#define NV_PFIFO_RUNOUT_STATUS 0x00002400 /* R--4R */
-#define NV_PFIFO_RUNOUT_STATUS_RANOUT 0:0 /* R--VF */
-#define NV_PFIFO_RUNOUT_STATUS_RANOUT_FALSE 0x00000000 /* R---V */
-#define NV_PFIFO_RUNOUT_STATUS_RANOUT_TRUE 0x00000001 /* R---V */
-#define NV_PFIFO_RUNOUT_STATUS_LOW_MARK 4:4 /* R--VF */
-#define NV_PFIFO_RUNOUT_STATUS_LOW_MARK_NOT_EMPTY 0x00000000 /* R---V */
-#define NV_PFIFO_RUNOUT_STATUS_LOW_MARK_EMPTY 0x00000001 /* R---V */
-#define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK 8:8 /* R--VF */
-#define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK_NOT_FULL 0x00000000 /* R---V */
-#define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK_FULL 0x00000001 /* R---V */
-#define NV_PFIFO_RUNOUT_PUT 0x00002410 /* RW-4R */
-#define NV_PFIFO_RUNOUT_PUT_ADDRESS 12:3 /* RWXUF */
-#define NV_PFIFO_RUNOUT_PUT_ADDRESS__SIZE_0 8:3 /* RWXUF */
-#define NV_PFIFO_RUNOUT_PUT_ADDRESS__SIZE_1 12:3 /* RWXUF */
-#define NV_PFIFO_RUNOUT_GET 0x00002420 /* RW-4R */
-#define NV_PFIFO_RUNOUT_GET_ADDRESS 13:3 /* RWXUF */
-/* dev_graphics.ref */
-#define NV_PGRAPH 0x00401FFF:0x00400000 /* RW--D */
-#define NV_PGRAPH_DEBUG_0 0x00400080 /* RW-4R */
-#define NV_PGRAPH_DEBUG_1 0x00400084 /* RW-4R */
-#define NV_PGRAPH_DEBUG_2 0x00400088 /* RW-4R */
-#define NV_PGRAPH_DEBUG_3 0x0040008C /* RW-4R */
-#define NV_PGRAPH_INTR 0x00400100 /* RW-4R */
-#define NV_PGRAPH_INTR_NOTIFY 0:0 /* RWIVF */
-#define NV_PGRAPH_INTR_NOTIFY_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_INTR_NOTIFY_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_INTR_NOTIFY_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_INTR_MISSING_HW 4:4 /* RWIVF */
-#define NV_PGRAPH_INTR_MISSING_HW_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_INTR_MISSING_HW_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_INTR_MISSING_HW_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_INTR_TLB_PRESENT_A 8:8 /* RWIVF */
-#define NV_PGRAPH_INTR_TLB_PRESENT_A_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_INTR_TLB_PRESENT_A_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_INTR_TLB_PRESENT_A_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_INTR_TLB_PRESENT_B 9:9 /* RWIVF */
-#define NV_PGRAPH_INTR_TLB_PRESENT_B_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_INTR_TLB_PRESENT_B_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_INTR_TLB_PRESENT_B_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_INTR_CONTEXT_SWITCH 12:12 /* RWIVF */
-#define NV_PGRAPH_INTR_CONTEXT_SWITCH_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_INTR_CONTEXT_SWITCH_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_INTR_CONTEXT_SWITCH_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_INTR_BUFFER_NOTIFY 16:16 /* RWIVF */
-#define NV_PGRAPH_INTR_BUFFER_NOTIFY_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_INTR_BUFFER_NOTIFY_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_INTR_BUFFER_NOTIFY_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_NSTATUS 0x00400104 /* RW-4R */
-#define NV_PGRAPH_NSTATUS_STATE_IN_USE 11:11 /* RWIVF */
-#define NV_PGRAPH_NSTATUS_STATE_IN_USE_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NSTATUS_STATE_IN_USE_PENDING 0x00000001 /* RW--V */
-#define NV_PGRAPH_NSTATUS_INVALID_STATE 12:12 /* RWIVF */
-#define NV_PGRAPH_NSTATUS_INVALID_STATE_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NSTATUS_INVALID_STATE_PENDING 0x00000001 /* RW--V */
-#define NV_PGRAPH_NSTATUS_BAD_ARGUMENT 13:13 /* RWIVF */
-#define NV_PGRAPH_NSTATUS_BAD_ARGUMENT_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NSTATUS_BAD_ARGUMENT_PENDING 0x00000001 /* RW--V */
-#define NV_PGRAPH_NSTATUS_PROTECTION_FAULT 14:14 /* RWIVF */
-#define NV_PGRAPH_NSTATUS_PROTECTION_FAULT_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NSTATUS_PROTECTION_FAULT_PENDING 0x00000001 /* RW--V */
-#define NV_PGRAPH_NSOURCE 0x00400108 /* R--4R */
-#define NV_PGRAPH_NSOURCE_NOTIFICATION 0:0 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_NOTIFICATION_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_NOTIFICATION_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_DATA_ERROR 1:1 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_DATA_ERROR_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_DATA_ERROR_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_PROTECTION_ERROR 2:2 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_PROTECTION_ERROR_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_PROTECTION_ERROR_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION 3:3 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_LIMIT_COLOR 4:4 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_LIMIT_COLOR_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_LIMIT_COLOR_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_LIMIT_ZETA_ 5:5 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_LIMIT_ZETA_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_LIMIT_ZETA_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD 6:6 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION 7:7 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION 8:8 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION 9:9 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION 10:10 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_STATE_INVALID 11:11 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_STATE_INVALID_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_STATE_INVALID_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY 12:12 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE 13:13 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_METHOD_CNT 14:14 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_METHOD_CNT_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_METHOD_CNT_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION 15:15 /* R-IVF */
-#define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_INTR_EN 0x00400140 /* RW-4R */
-#define NV_PGRAPH_INTR_EN_NOTIFY 0:0 /* RWIVF */
-#define NV_PGRAPH_INTR_EN_NOTIFY_DISABLED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_INTR_EN_NOTIFY_ENABLED 0x00000001 /* RW--V */
-#define NV_PGRAPH_INTR_EN_MISSING_HW 4:4 /* RWIVF */
-#define NV_PGRAPH_INTR_EN_MISSING_HW_DISABLED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_INTR_EN_MISSING_HW_ENABLED 0x00000001 /* RW--V */
-#define NV_PGRAPH_INTR_EN_TLB_PRESENT_A 8:8 /* RWIVF */
-#define NV_PGRAPH_INTR_EN_TLB_PRESENT_A_DISABLED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_INTR_EN_TLB_PRESENT_A_ENABLED 0x00000001 /* RW--V */
-#define NV_PGRAPH_INTR_EN_TLB_PRESENT_B 9:9 /* RWIVF */
-#define NV_PGRAPH_INTR_EN_TLB_PRESENT_B_DISABLED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_INTR_EN_TLB_PRESENT_B_ENABLED 0x00000001 /* RW--V */
-#define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH 12:12 /* RWIVF */
-#define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH_DISABLED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH_ENABLED 0x00000001 /* RW--V */
-#define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY 16:16 /* RWIVF */
-#define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY_DISABLED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY_ENABLED 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1 0x00400160 /* RW-4R */
-#define NV_PGRAPH_CTX_SWITCH1_GRCLASS 7:0 /* RWXVF */
-#define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY 12:12 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY_DISABLE 0x00000000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY_ENABLE 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_USER_CLIP 13:13 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH1_USER_CLIP_DISABLE 0x00000000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_USER_CLIP_ENABLE 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_SWIZZLE 14:14 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH1_SWIZZLE_DISABLE 0x00000000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_SWIZZLE_ENABLE 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG 17:15 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY_AND 0x00000000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_ROP_AND 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_BLEND_AND 0x00000002 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY 0x00000003 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY_PRE 0x00000004 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_BLEND_PRE 0x00000005 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS 24:24 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS_INVALID 0x00000000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE 25:25 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE_INVALID 0x00000000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET 31:31 /* CWIVF */
-#define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET_IGNORE 0x00000000 /* CWI-V */
-#define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET_ENABLED 0x00000001 /* -W--T */
-#define NV_PGRAPH_CTX_SWITCH2 0x00400164 /* RW-4R */
-#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT 1:0 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_INVALID 0x00 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_CGA6_M1 0x01 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_LE_M1 0x02 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT 13:8 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_INVALID 0x00 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y8 0x01 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16A8Y8 0x02 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X24Y8 0x03 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A1R5G5B5 0x06 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X1R5G5B5 0x07 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16A1R5G5B5 0x08 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X17R5G5B5 0x09 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_R5G6B5 0x0A /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A16R5G6B5 0x0B /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16R5G6B5 0x0C /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A8R8G8B8 0x0D /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X8R8G8B8 0x0E /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y16 0x0F /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A16Y16 0x10 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16Y16 0x11 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_V8YB8U8YA8 0x12 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_YB8V8YA8U8 0x13 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y32 0x14 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH2_NOTIFY_INSTANCE 31:16 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH2_NOTIFY_INSTANCE_INVALID 0x0000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH3 0x00400168 /* RW-4R */
-#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_0 15:0 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_0_INVALID 0x0000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_1 31:16 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_1_INVALID 0x0000 /* RW--V */
-#define NV_PGRAPH_CTX_SWITCH4 0x0040016C /* RW-4R */
-#define NV_PGRAPH_CTX_SWITCH4_USER_INSTANCE 15:0 /* RWXUF */
-#define NV_PGRAPH_CTX_SWITCH4_USER_INSTANCE_INVALID 0x0000 /* RW--V */
-#define NV_PGRAPH_CTX_CACHE1(i) (0x00400180+(i)*4) /* RW-4A */
-#define NV_PGRAPH_CTX_CACHE1__SIZE_1 8 /* */
-#define NV_PGRAPH_CTX_CACHE1_GRCLASS 7:0 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE1_CHROMA_KEY 12:12 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE1_USER_CLIP 13:13 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE1_SWIZZLE 14:14 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE1_PATCH_CONFIG 19:15 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE1_SPARE1 20:20 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE1_PATCH_STATUS 24:24 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE1_CONTEXT_SURFACE 25:25 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE2(i) (0x004001a0+(i)*4) /* RW-4A */
-#define NV_PGRAPH_CTX_CACHE2__SIZE_1 8 /* */
-#define NV_PGRAPH_CTX_CACHE2_MONO_FORMAT 1:0 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE2_COLOR_FORMAT 13:8 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE2_NOTIFY_INSTANCE 31:16 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE3(i) (0x004001c0+(i)*4) /* RW-4A */
-#define NV_PGRAPH_CTX_CACHE3__SIZE_1 8 /* */
-#define NV_PGRAPH_CTX_CACHE3_DMA_INSTANCE_0 15:0 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE3_DMA_INSTANCE_1 31:16 /* RWXVF */
-#define NV_PGRAPH_CTX_CACHE4(i) (0x004001e0+(i)*4) /* RW-4A */
-#define NV_PGRAPH_CTX_CACHE4__SIZE_1 8 /* */
-#define NV_PGRAPH_CTX_CACHE4_USER_INSTANCE 15:0 /* RWXVF */
-#define NV_PGRAPH_CTX_CONTROL 0x00400170 /* RW-4R */
-#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME 1:0 /* RWIVF */
-#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_33US 0x00000000 /* RWI-V */
-#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_262US 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_2MS 0x00000002 /* RW--V */
-#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_17MS 0x00000003 /* RW--V */
-#define NV_PGRAPH_CTX_CONTROL_TIME 8:8 /* RWIVF */
-#define NV_PGRAPH_CTX_CONTROL_TIME_EXPIRED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_CTX_CONTROL_TIME_NOT_EXPIRED 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_CONTROL_CHID 16:16 /* RWIVF */
-#define NV_PGRAPH_CTX_CONTROL_CHID_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_CTX_CONTROL_CHID_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_CONTROL_CHANGE 20:20 /* R--VF */
-#define NV_PGRAPH_CTX_CONTROL_CHANGE_UNAVAILABLE 0x00000000 /* R---V */
-#define NV_PGRAPH_CTX_CONTROL_CHANGE_AVAILABLE 0x00000001 /* R---V */
-#define NV_PGRAPH_CTX_CONTROL_SWITCHING 24:24 /* RWIVF */
-#define NV_PGRAPH_CTX_CONTROL_SWITCHING_IDLE 0x00000000 /* RWI-V */
-#define NV_PGRAPH_CTX_CONTROL_SWITCHING_BUSY 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_CONTROL_DEVICE 28:28 /* RWIVF */
-#define NV_PGRAPH_CTX_CONTROL_DEVICE_DISABLED 0x00000000 /* RWI-V */
-#define NV_PGRAPH_CTX_CONTROL_DEVICE_ENABLED 0x00000001 /* RW--V */
-#define NV_PGRAPH_CTX_USER 0x00400174 /* RW-4R */
-#define NV_PGRAPH_CTX_USER_SUBCH 15:13 /* RWIVF */
-#define NV_PGRAPH_CTX_USER_SUBCH_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_CTX_USER_CHID 27:24 /* RWIVF */
-#define NV_PGRAPH_CTX_USER_CHID_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FIFO 0x00400720 /* RW-4R */
-#define NV_PGRAPH_FIFO_ACCESS 0:0 /* RWIVF */
-#define NV_PGRAPH_FIFO_ACCESS_DISABLED 0x00000000 /* RW--V */
-#define NV_PGRAPH_FIFO_ACCESS_ENABLED 0x00000001 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_FIFO_0(i) (0x00400730+(i)*4) /* RW-4A */
-#define NV_PGRAPH_FFINTFC_FIFO_0__SIZE_1 4 /* */
-#define NV_PGRAPH_FFINTFC_FIFO_0_TAG 0:0 /* RWXVF */
-#define NV_PGRAPH_FFINTFC_FIFO_0_TAG_MTHD 0x00000000 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_TAG_CHSW 0x00000001 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH 3:1 /* RWXVF */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_0 0x00000000 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_1 0x00000001 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_2 0x00000002 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_3 0x00000003 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_4 0x00000004 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_5 0x00000005 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_6 0x00000006 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_7 0x00000007 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_0_MTHD 14:4 /* RWXVF */
-#define NV_PGRAPH_FFINTFC_FIFO_0_MTHD_CTX_SWITCH 0x00000000 /* RW--V */
-#define NV_PGRAPH_FFINTFC_FIFO_1(i) (0x00400740+(i)*4) /* RW-4A */
-#define NV_PGRAPH_FFINTFC_FIFO_1__SIZE_1 4 /* */
-#define NV_PGRAPH_FFINTFC_FIFO_1_ARGUMENT 31:0 /* RWXVF */
-#define NV_PGRAPH_FFINTFC_FIFO_PTR 0x00400750 /* RW-4R */
-#define NV_PGRAPH_FFINTFC_FIFO_PTR_WRITE 2:0 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_FIFO_PTR_WRITE_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_FIFO_PTR_READ 6:4 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_FIFO_PTR_READ_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_ST2 0x00400754 /* RW-4R */
-#define NV_PGRAPH_FFINTFC_ST2_STATUS 0:0 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_ST2_STATUS_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_ST2_STATUS_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_MTHD 11:1 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_ST2_MTHD_CTX_SWITCH 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH 14:12 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_1 0x00000001 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_2 0x00000002 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_3 0x00000003 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_4 0x00000004 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_5 0x00000005 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_6 0x00000006 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_SUBCH_7 0x00000007 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID 18:15 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_1 0x00000001 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_2 0x00000002 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_3 0x00000003 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_4 0x00000004 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_5 0x00000005 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_6 0x00000006 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_7 0x00000007 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_8 0x00000008 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_9 0x00000009 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_10 0x0000000A /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_11 0x0000000B /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_12 0x0000000C /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_13 0x0000000D /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_14 0x0000000E /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_15 0x0000000F /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS 19:19 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_FFINTFC_ST2_D 0x00400758 /* RW-4R */
-#define NV_PGRAPH_FFINTFC_ST2_D_ARGUMENT 31:0 /* RWIVF */
-#define NV_PGRAPH_FFINTFC_ST2_D_ARGUMENT_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATUS 0x00400700 /* R--4R */
-#define NV_PGRAPH_STATUS_STATE 0:0 /* R-IVF */
-#define NV_PGRAPH_STATUS_STATE_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_STATE_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_XY_LOGIC 4:4 /* R-IVF */
-#define NV_PGRAPH_STATUS_XY_LOGIC_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_XY_LOGIC_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_FE 5:5 /* R-IVF */
-#define NV_PGRAPH_STATUS_FE_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_FE_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_RASTERIZER 6:6 /* R-IVF */
-#define NV_PGRAPH_STATUS_RASTERIZER_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_RASTERIZER_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_PORT_NOTIFY 8:8 /* R-IVF */
-#define NV_PGRAPH_STATUS_PORT_NOTIFY_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_PORT_NOTIFY_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_PORT_REGISTER 12:12 /* R-IVF */
-#define NV_PGRAPH_STATUS_PORT_REGISTER_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_PORT_REGISTER_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_PORT_DMA 16:16 /* R-IVF */
-#define NV_PGRAPH_STATUS_PORT_DMA_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_PORT_DMA_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_DMA_ENGINE 17:17 /* R-IVF */
-#define NV_PGRAPH_STATUS_DMA_ENGINE_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_DMA_ENGINE_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_DMA_NOTIFY 20:20 /* R-IVF */
-#define NV_PGRAPH_STATUS_DMA_NOTIFY_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_DMA_NOTIFY_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY 21:21 /* R-IVF */
-#define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_D3D 24:24 /* R-IVF */
-#define NV_PGRAPH_STATUS_D3D_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_D3D_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_CACHE 25:25 /* R-IVF */
-#define NV_PGRAPH_STATUS_CACHE_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_CACHE_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_LIGHTING 26:26 /* R-IVF */
-#define NV_PGRAPH_STATUS_LIGHTING_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_LIGHTING_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_PREROP 27:27 /* R-IVF */
-#define NV_PGRAPH_STATUS_PREROP_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_PREROP_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_ROP 28:28 /* R-IVF */
-#define NV_PGRAPH_STATUS_ROP_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_ROP_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_STATUS_PORT_USER 29:29 /* R-IVF */
-#define NV_PGRAPH_STATUS_PORT_USER_IDLE 0x00000000 /* R-I-V */
-#define NV_PGRAPH_STATUS_PORT_USER_BUSY 0x00000001 /* R---V */
-#define NV_PGRAPH_TRAPPED_ADDR 0x00400704 /* R--4R */
-#define NV_PGRAPH_TRAPPED_ADDR_MTHD 12:2 /* R-XUF */
-#define NV_PGRAPH_TRAPPED_ADDR_SUBCH 15:13 /* R-XUF */
-#define NV_PGRAPH_TRAPPED_ADDR_CHID 27:24 /* R-XUF */
-#define NV_PGRAPH_TRAPPED_DATA 0x00400708 /* R--4R */
-#define NV_PGRAPH_TRAPPED_DATA_VALUE 31:0 /* R-XVF */
-#define NV_PGRAPH_SURFACE 0x0040070C /* RW-4R */
-#define NV_PGRAPH_SURFACE_TYPE 1:0 /* RWIVF */
-#define NV_PGRAPH_SURFACE_TYPE_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_SURFACE_TYPE_NON_SWIZZLE 0x00000001 /* RW--V */
-#define NV_PGRAPH_SURFACE_TYPE_SWIZZLE 0x00000002 /* RW--V */
-#define NV_PGRAPH_NOTIFY 0x00400714 /* RW-4R */
-#define NV_PGRAPH_NOTIFY_BUFFER_REQ 0:0 /* RWIVF */
-#define NV_PGRAPH_NOTIFY_BUFFER_REQ_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NOTIFY_BUFFER_REQ_PENDING 0x00000001 /* RW--V */
-#define NV_PGRAPH_NOTIFY_BUFFER_STYLE 8:8 /* RWIVF */
-#define NV_PGRAPH_NOTIFY_BUFFER_STYLE_WRITE_ONLY 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NOTIFY_BUFFER_STYLE_WRITE_THEN_AWAKEN 0x00000001 /* RW--V */
-#define NV_PGRAPH_NOTIFY_REQ 16:16 /* RWIVF */
-#define NV_PGRAPH_NOTIFY_REQ_NOT_PENDING 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NOTIFY_REQ_PENDING 0x00000001 /* RW--V */
-#define NV_PGRAPH_NOTIFY_STYLE 20:20 /* RWIVF */
-#define NV_PGRAPH_NOTIFY_STYLE_WRITE_ONLY 0x00000000 /* RWI-V */
-#define NV_PGRAPH_NOTIFY_STYLE_WRITE_THEN_AWAKEN 0x00000001 /* RW--V */
-#define NV_PGRAPH_BOFFSET(i) (0x00400640+(i)*4) /* RW-4A */
-#define NV_PGRAPH_BOFFSET__SIZE_1 6 /* */
-#define NV_PGRAPH_BOFFSET_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BOFFSET_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BOFFSET0 0x00400640 /* RW-4R */
-#define NV_PGRAPH_BOFFSET0__ALIAS_1 NV_PGRAPH_BOFFSET(0) /* */
-#define NV_PGRAPH_BOFFSET0_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BOFFSET0_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BOFFSET1 0x00400644 /* RW-4R */
-#define NV_PGRAPH_BOFFSET1__ALIAS_1 NV_PGRAPH_BOFFSET(1) /* */
-#define NV_PGRAPH_BOFFSET1_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BOFFSET1_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BOFFSET2 0x00400648 /* RW-4R */
-#define NV_PGRAPH_BOFFSET2__ALIAS_1 NV_PGRAPH_BOFFSET(2) /* */
-#define NV_PGRAPH_BOFFSET2_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BOFFSET2_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BOFFSET3 0x0040064C /* RW-4R */
-#define NV_PGRAPH_BOFFSET3__ALIAS_1 NV_PGRAPH_BOFFSET(3) /* */
-#define NV_PGRAPH_BOFFSET3_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BOFFSET3_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BOFFSET4 0x00400650 /* RW-4R */
-#define NV_PGRAPH_BOFFSET4__ALIAS_1 NV_PGRAPH_BOFFSET(4) /* */
-#define NV_PGRAPH_BOFFSET4_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BOFFSET4_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BOFFSET5 0x00400654 /* RW-4R */
-#define NV_PGRAPH_BOFFSET5__ALIAS_1 NV_PGRAPH_BOFFSET(5) /* */
-#define NV_PGRAPH_BOFFSET5_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BOFFSET5_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BBASE(i) (0x00400658+(i)*4) /* RW-4A */
-#define NV_PGRAPH_BBASE__SIZE_1 6 /* */
-#define NV_PGRAPH_BBASE_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BBASE_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BBASE0 0x00400658 /* RW-4R */
-#define NV_PGRAPH_BBASE0__ALIAS_1 NV_PGRAPH_BBASE(0) /* */
-#define NV_PGRAPH_BBASE0_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BBASE0_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BBASE1 0x0040065c /* RW-4R */
-#define NV_PGRAPH_BBASE1__ALIAS_1 NV_PGRAPH_BBASE(1) /* */
-#define NV_PGRAPH_BBASE1_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BBASE1_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BBASE2 0x00400660 /* RW-4R */
-#define NV_PGRAPH_BBASE2__ALIAS_1 NV_PGRAPH_BBASE(2) /* */
-#define NV_PGRAPH_BBASE2_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BBASE2_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BBASE3 0x00400664 /* RW-4R */
-#define NV_PGRAPH_BBASE3__ALIAS_1 NV_PGRAPH_BBASE(3) /* */
-#define NV_PGRAPH_BBASE3_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BBASE3_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BBASE4 0x00400668 /* RW-4R */
-#define NV_PGRAPH_BBASE4__ALIAS_1 NV_PGRAPH_BBASE(4) /* */
-#define NV_PGRAPH_BBASE4_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BBASE4_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BBASE5 0x0040066C /* RW-4R */
-#define NV_PGRAPH_BBASE5__ALIAS_1 NV_PGRAPH_BBASE(5) /* */
-#define NV_PGRAPH_BBASE5_LINADRS 23:0 /* RWIUF */
-#define NV_PGRAPH_BBASE5_LINADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPITCH(i) (0x00400670+(i)*4) /* RW-4A */
-#define NV_PGRAPH_BPITCH__SIZE_1 5 /* */
-#define NV_PGRAPH_BPITCH_VALUE 12:0 /* RWIUF */
-#define NV_PGRAPH_BPITCH_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPITCH0 0x00400670 /* RW-4R */
-#define NV_PGRAPH_BPITCH0__ALIAS_1 NV_PGRAPH_BPITCH(0) /* */
-#define NV_PGRAPH_BPITCH0_VALUE 12:0 /* RWIUF */
-#define NV_PGRAPH_BPITCH0_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPITCH1 0x00400674 /* RW-4R */
-#define NV_PGRAPH_BPITCH1__ALIAS_1 NV_PGRAPH_BPITCH(1) /* */
-#define NV_PGRAPH_BPITCH1_VALUE 12:0 /* RWIUF */
-#define NV_PGRAPH_BPITCH1_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPITCH2 0x00400678 /* RW-4R */
-#define NV_PGRAPH_BPITCH2__ALIAS_1 NV_PGRAPH_BPITCH(2) /* */
-#define NV_PGRAPH_BPITCH2_VALUE 12:0 /* RWIUF */
-#define NV_PGRAPH_BPITCH2_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPITCH3 0x0040067C /* RW-4R */
-#define NV_PGRAPH_BPITCH3__ALIAS_1 NV_PGRAPH_BPITCH(3) /* */
-#define NV_PGRAPH_BPITCH3_VALUE 12:0 /* RWIUF */
-#define NV_PGRAPH_BPITCH3_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPITCH4 0x00400680 /* RW-4R */
-#define NV_PGRAPH_BPITCH4__ALIAS_1 NV_PGRAPH_BPITCH(4) /* */
-#define NV_PGRAPH_BPITCH4_VALUE 12:0 /* RWIUF */
-#define NV_PGRAPH_BPITCH4_VALUE_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BLIMIT(i) (0x00400684+(i)*4) /* RW-4A */
-#define NV_PGRAPH_BLIMIT__SIZE_1 6 /* */
-#define NV_PGRAPH_BLIMIT_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_BLIMIT_TYPE 31:31 /* RWIVF */
-#define NV_PGRAPH_BLIMIT_TYPE_IN_MEMORY 0x00000000 /* RW--V */
-#define NV_PGRAPH_BLIMIT_TYPE_NULL 0x00000001 /* RWI-V */
-#define NV_PGRAPH_BLIMIT0 0x00400684 /* RW-4R */
-#define NV_PGRAPH_BLIMIT0__ALIAS_1 NV_PGRAPH_BLIMIT(0) /* */
-#define NV_PGRAPH_BLIMIT0_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_BLIMIT0_TYPE 31:31 /* RWIVF */
-#define NV_PGRAPH_BLIMIT0_TYPE_IN_MEMORY 0x00000000 /* RW--V */
-#define NV_PGRAPH_BLIMIT0_TYPE_NULL 0x00000001 /* RWI-V */
-#define NV_PGRAPH_BLIMIT1 0x00400688 /* RW-4R */
-#define NV_PGRAPH_BLIMIT1__ALIAS_1 NV_PGRAPH_BLIMIT(1) /* */
-#define NV_PGRAPH_BLIMIT1_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_BLIMIT1_TYPE 31:31 /* RWIVF */
-#define NV_PGRAPH_BLIMIT1_TYPE_IN_MEMORY 0x00000000 /* RW--V */
-#define NV_PGRAPH_BLIMIT1_TYPE_NULL 0x00000001 /* RWI-V */
-#define NV_PGRAPH_BLIMIT2 0x0040068c /* RW-4R */
-#define NV_PGRAPH_BLIMIT2__ALIAS_1 NV_PGRAPH_BLIMIT(2) /* */
-#define NV_PGRAPH_BLIMIT2_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_BLIMIT2_TYPE 31:31 /* RWIVF */
-#define NV_PGRAPH_BLIMIT2_TYPE_IN_MEMORY 0x00000000 /* RW--V */
-#define NV_PGRAPH_BLIMIT2_TYPE_NULL 0x00000001 /* RWI-V */
-#define NV_PGRAPH_BLIMIT3 0x00400690 /* RW-4R */
-#define NV_PGRAPH_BLIMIT3__ALIAS_1 NV_PGRAPH_BLIMIT(3) /* */
-#define NV_PGRAPH_BLIMIT3_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_BLIMIT3_TYPE 31:31 /* RWIVF */
-#define NV_PGRAPH_BLIMIT3_TYPE_IN_MEMORY 0x00000000 /* RW--V */
-#define NV_PGRAPH_BLIMIT3_TYPE_NULL 0x00000001 /* RWI-V */
-#define NV_PGRAPH_BLIMIT4 0x00400694 /* RW-4R */
-#define NV_PGRAPH_BLIMIT4__ALIAS_1 NV_PGRAPH_BLIMIT(4) /* */
-#define NV_PGRAPH_BLIMIT4_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_BLIMIT4_TYPE 31:31 /* RWIVF */
-#define NV_PGRAPH_BLIMIT4_TYPE_IN_MEMORY 0x00000000 /* RW--V */
-#define NV_PGRAPH_BLIMIT4_TYPE_NULL 0x00000001 /* RWI-V */
-#define NV_PGRAPH_BLIMIT5 0x00400698 /* RW-4R */
-#define NV_PGRAPH_BLIMIT5__ALIAS_1 NV_PGRAPH_BLIMIT(5) /* */
-#define NV_PGRAPH_BLIMIT5_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_BLIMIT5_TYPE 31:31 /* RWIVF */
-#define NV_PGRAPH_BLIMIT5_TYPE_IN_MEMORY 0x00000000 /* RW--V */
-#define NV_PGRAPH_BLIMIT5_TYPE_NULL 0x00000001 /* RWI-V */
-#define NV_PGRAPH_BSWIZZLE2 0x0040069c /* RW-4R */
-#define NV_PGRAPH_BSWIZZLE2_WIDTH 19:16 /* RWIUF */
-#define NV_PGRAPH_BSWIZZLE2_WIDTH_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BSWIZZLE2_HEIGHT 27:24 /* RWIUF */
-#define NV_PGRAPH_BSWIZZLE2_HEIGHT_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BSWIZZLE5 0x004006a0 /* RW-4R */
-#define NV_PGRAPH_BSWIZZLE5_WIDTH 19:16 /* RWIUF */
-#define NV_PGRAPH_BSWIZZLE5_WIDTH_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BSWIZZLE5_HEIGHT 27:24 /* RWIUF */
-#define NV_PGRAPH_BSWIZZLE5_HEIGHT_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPIXEL 0x00400724 /* RW-4R */
-#define NV_PGRAPH_BPIXEL_DEPTH0 3:0 /* RWIVF */
-#define NV_PGRAPH_BPIXEL_DEPTH0_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_A1R5G5B5 0x00000004 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_R5G6B5 0x00000005 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_Y16 0x00000006 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_A8R8G8B8 0x0000000c /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_Y32 0x0000000d /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_V8YB8U8YA8 0x0000000e /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH0_YB8V8YA8U8 0x0000000f /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1 7:4 /* RWIVF */
-#define NV_PGRAPH_BPIXEL_DEPTH1_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_A1R5G5B5 0x00000004 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_R5G6B5 0x00000005 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_Y16 0x00000006 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_A8R8G8B8 0x0000000c /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_Y32 0x0000000d /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_V8YB8U8YA8 0x0000000e /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH1_YB8V8YA8U8 0x0000000f /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2 11:8 /* RWIVF */
-#define NV_PGRAPH_BPIXEL_DEPTH2_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_A1R5G5B5 0x00000004 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_R5G6B5 0x00000005 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_Y16 0x00000006 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_A8R8G8B8 0x0000000c /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_Y32 0x0000000d /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_V8YB8U8YA8 0x0000000e /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH2_YB8V8YA8U8 0x0000000f /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3 15:12 /* RWIVF */
-#define NV_PGRAPH_BPIXEL_DEPTH3_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_A1R5G5B5 0x00000004 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_R5G6B5 0x00000005 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_Y16 0x00000006 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_A8R8G8B8 0x0000000c /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_Y32 0x0000000d /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_V8YB8U8YA8 0x0000000e /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH3_YB8V8YA8U8 0x0000000f /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4 19:16 /* RWIVF */
-#define NV_PGRAPH_BPIXEL_DEPTH4_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_A1R5G5B5 0x00000004 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_R5G6B5 0x00000005 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_Y16 0x00000006 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_A8R8G8B8 0x0000000c /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_Y32 0x0000000d /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_V8YB8U8YA8 0x0000000e /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH4_YB8V8YA8U8 0x0000000f /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5 23:20 /* RWIVF */
-#define NV_PGRAPH_BPIXEL_DEPTH5_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_A1R5G5B5 0x00000004 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_R5G6B5 0x00000005 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_Y16 0x00000006 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_A8R8G8B8 0x0000000c /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_Y32 0x0000000d /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_V8YB8U8YA8 0x0000000e /* RW--V */
-#define NV_PGRAPH_BPIXEL_DEPTH5_YB8V8YA8U8 0x0000000f /* RW--V */
-#define NV_PGRAPH_LIMIT_VIOL_PIX 0x00400610 /* RW-4R */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_ADRS 23:0 /* RWIVF */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_ADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT 29:29 /* RWIVF */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT_NO_VIOL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT_VIOL 0x00000001 /* RW--V */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT 30:30 /* RWIVF */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT_NO_VIOL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT_VIOL 0x00000001 /* RW--V */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW 31:31 /* RWIVF */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW_NO_VIOL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW_VIOL 0x00000001 /* RW--V */
-#define NV_PGRAPH_LIMIT_VIOL_Z 0x00400614 /* RW-4R */
-#define NV_PGRAPH_LIMIT_VIOL_Z_ADRS 23:0 /* RWIVF */
-#define NV_PGRAPH_LIMIT_VIOL_Z_ADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT 30:30 /* RWIVF */
-#define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT_NO_VIOL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT_VIOL 0x00000001 /* RW--V */
-#define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW 31:31 /* RWIVF */
-#define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW_NO_VIOL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW_VIOL 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE 0x00400710 /* RW-4R */
-#define NV_PGRAPH_STATE_BUFFER_0 0:0 /* RWIVF */
-#define NV_PGRAPH_STATE_BUFFER_0_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_BUFFER_0_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_BUFFER_1 1:1 /* RWIVF */
-#define NV_PGRAPH_STATE_BUFFER_1_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_BUFFER_1_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_BUFFER_2 2:2 /* RWIVF */
-#define NV_PGRAPH_STATE_BUFFER_2_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_BUFFER_2_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_BUFFER_3 3:3 /* RWIVF */
-#define NV_PGRAPH_STATE_BUFFER_3_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_BUFFER_3_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_BUFFER_4 4:4 /* RWIVF */
-#define NV_PGRAPH_STATE_BUFFER_4_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_BUFFER_4_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_BUFFER_5 5:5 /* RWIVF */
-#define NV_PGRAPH_STATE_BUFFER_5_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_BUFFER_5_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PITCH_0 8:8 /* RWIVF */
-#define NV_PGRAPH_STATE_PITCH_0_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PITCH_0_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PITCH_1 9:9 /* RWIVF */
-#define NV_PGRAPH_STATE_PITCH_1_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PITCH_1_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PITCH_2 10:10 /* RWIVF */
-#define NV_PGRAPH_STATE_PITCH_2_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PITCH_2_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PITCH_3 11:11 /* RWIVF */
-#define NV_PGRAPH_STATE_PITCH_3_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PITCH_3_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PITCH_4 12:12 /* RWIVF */
-#define NV_PGRAPH_STATE_PITCH_4_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PITCH_4_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_CHROMA_COLOR 16:16 /* RWIVF */
-#define NV_PGRAPH_STATE_CHROMA_COLOR_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_CHROMA_COLOR_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_CHROMA_COLORFMT 17:17 /* RWIVF */
-#define NV_PGRAPH_STATE_CHROMA_COLORFMT_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_CHROMA_COLORFMT_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_CPATTERN_COLORFMT 20:20 /* RWIVF */
-#define NV_PGRAPH_STATE_CPATTERN_COLORFMT_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_CPATTERN_COLORFMT_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_CPATTERN_MONOFMT 21:21 /* RWIVF */
-#define NV_PGRAPH_STATE_CPATTERN_MONOFMT_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_CPATTERN_MONOFMT_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_CPATTERN_SELECT 22:22 /* RWIVF */
-#define NV_PGRAPH_STATE_CPATTERN_SELECT_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_CPATTERN_SELECT_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PATTERN_COLOR0 24:24 /* RWIVF */
-#define NV_PGRAPH_STATE_PATTERN_COLOR0_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PATTERN_COLOR0_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PATTERN_COLOR1 25:25 /* RWIVF */
-#define NV_PGRAPH_STATE_PATTERN_COLOR1_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PATTERN_COLOR1_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PATTERN_PATT0 26:26 /* RWIVF */
-#define NV_PGRAPH_STATE_PATTERN_PATT0_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PATTERN_PATT0_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_STATE_PATTERN_PATT1 27:27 /* RWIVF */
-#define NV_PGRAPH_STATE_PATTERN_PATT1_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_STATE_PATTERN_PATT1_VALID 0x00000001 /* RW--V */
-#define NV_PGRAPH_CACHE_INDEX 0x00400728 /* RW-4R */
-#define NV_PGRAPH_CACHE_INDEX_BANK 2:2 /* RWXVF */
-#define NV_PGRAPH_CACHE_INDEX_BANK_10 0x00000000 /* RW--V */
-#define NV_PGRAPH_CACHE_INDEX_BANK_32 0x00000001 /* RW--V */
-#define NV_PGRAPH_CACHE_INDEX_ADRS 12:3 /* RWXVF */
-#define NV_PGRAPH_CACHE_INDEX_ADRS_0 0x00000000 /* RW--V */
-#define NV_PGRAPH_CACHE_INDEX_ADRS_1024 0x00000400 /* RW--V */
-#define NV_PGRAPH_CACHE_INDEX_OP 14:13 /* RWXVF */
-#define NV_PGRAPH_CACHE_INDEX_OP_WR_CACHE 0x00000000 /* RW--V */
-#define NV_PGRAPH_CACHE_INDEX_OP_RD_CACHE 0x00000001 /* RW--V */
-#define NV_PGRAPH_CACHE_INDEX_OP_RD_INDEX 0x00000002 /* RW--V */
-#define NV_PGRAPH_CACHE_RAM 0x0040072c /* RW-4R */
-#define NV_PGRAPH_CACHE_RAM_VALUE 31:0 /* RWXVF */
-#define NV_PGRAPH_DMA_PITCH 0x00400760 /* RW-4R */
-#define NV_PGRAPH_DMA_PITCH_S0 15:0 /* RWXSF */
-#define NV_PGRAPH_DMA_PITCH_S1 31:16 /* RWXSF */
-#define NV_PGRAPH_DVD_COLORFMT 0x00400764 /* RW-4R */
-#define NV_PGRAPH_DVD_COLORFMT_IMAGE 5:0 /* RWNVF */
-#define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_INVALID 0x00 /* RWN-V */
-#define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_LE_V8YB8U8YA8 0x12 /* RW--V */
-#define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_LE_YB8V8YA8U8 0x13 /* RW--V */
-#define NV_PGRAPH_DVD_COLORFMT_OVLY 9:8 /* RWNVF */
-#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_INVALID 0x00 /* RWN-V */
-#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_LE_A8Y8U8V8 0x01 /* RW--V */
-#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_LE_A4V6YB6A4U6YA6 0x02 /* RW--V */
-#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_TRANSPARENT 0x03 /* RW--V */
-#define NV_PGRAPH_SCALED_FORMAT 0x00400768 /* RW-4R */
-#define NV_PGRAPH_SCALED_FORMAT_ORIGIN 17:16 /* RWIVF */
-#define NV_PGRAPH_SCALED_FORMAT_ORIGIN_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_SCALED_FORMAT_ORIGIN_CENTER 0x00000001 /* RW--V */
-#define NV_PGRAPH_SCALED_FORMAT_ORIGIN_CORNER 0x00000002 /* RW--V */
-#define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR 24:24 /* RWIVF */
-#define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR_ZOH 0x00000000 /* RWI-V */
-#define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR_FOH 0x00000001 /* RW--V */
-#define NV_PGRAPH_PATT_COLOR0 0x00400800 /* RW-4R */
-#define NV_PGRAPH_PATT_COLOR0_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_PATT_COLOR1 0x00400804 /* RW-4R */
-#define NV_PGRAPH_PATT_COLOR1_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_PATT_COLORRAM(i) (0x00400900+(i)*4) /* R--4A */
-#define NV_PGRAPH_PATT_COLORRAM__SIZE_1 64 /* */
-#define NV_PGRAPH_PATT_COLORRAM_VALUE 23:0 /* R--UF */
-#define NV_PGRAPH_PATTERN(i) (0x00400808+(i)*4) /* RW-4A */
-#define NV_PGRAPH_PATTERN__SIZE_1 2 /* */
-#define NV_PGRAPH_PATTERN_BITMAP 31:0 /* RWXVF */
-#define NV_PGRAPH_PATTERN_SHAPE 0x00400810 /* RW-4R */
-#define NV_PGRAPH_PATTERN_SHAPE_VALUE 1:0 /* RWXVF */
-#define NV_PGRAPH_PATTERN_SHAPE_VALUE_8X_8Y 0x00000000 /* RW--V */
-#define NV_PGRAPH_PATTERN_SHAPE_VALUE_64X_1Y 0x00000001 /* RW--V */
-#define NV_PGRAPH_PATTERN_SHAPE_VALUE_1X_64Y 0x00000002 /* RW--V */
-#define NV_PGRAPH_PATTERN_SHAPE_SELECT 4:4 /* RWXVF */
-#define NV_PGRAPH_PATTERN_SHAPE_SELECT_2COLOR 0x00000000 /* RW--V */
-#define NV_PGRAPH_PATTERN_SHAPE_SELECT_FULLCOLOR 0x00000001 /* RW--V */
-#define NV_PGRAPH_MONO_COLOR0 0x00400600 /* RW-4R */
-#define NV_PGRAPH_MONO_COLOR0_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_ROP3 0x00400604 /* RW-4R */
-#define NV_PGRAPH_ROP3_VALUE 7:0 /* RWXVF */
-#define NV_PGRAPH_CHROMA 0x00400814 /* RW-4R */
-#define NV_PGRAPH_CHROMA_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_BETA_AND 0x00400608 /* RW-4R */
-#define NV_PGRAPH_BETA_AND_VALUE_FRACTION 30:23 /* RWXUF */
-#define NV_PGRAPH_BETA_PREMULT 0x0040060c /* RW-4R */
-#define NV_PGRAPH_BETA_PREMULT_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_CONTROL0 0x00400818 /* RW-4R */
-#define NV_PGRAPH_CONTROL1 0x0040081c /* RW-4R */
-#define NV_PGRAPH_CONTROL2 0x00400820 /* RW-4R */
-#define NV_PGRAPH_BLEND 0x00400824 /* RW-4R */
-#define NV_PGRAPH_DPRAM_INDEX 0x00400828 /* RW-4R */
-#define NV_PGRAPH_DPRAM_INDEX_ADRS 6:0 /* RWIVF */
-#define NV_PGRAPH_DPRAM_INDEX_ADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT 10:8 /* RWIVF */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_ADRS_0 0x00000000 /* RWI-V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_ADRS_1 0x00000001 /* RW--V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_DATA_0 0x00000002 /* RW--V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_DATA_1 0x00000003 /* RW--V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_WE_0 0x00000004 /* RW--V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_WE_1 0x00000005 /* RW--V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_ALPHA_0 0x00000006 /* RW--V */
-#define NV_PGRAPH_DPRAM_INDEX_SELECT_ALPHA_1 0x00000007 /* RW--V */
-#define NV_PGRAPH_DPRAM_DATA 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_DATA_VALUE 31:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_ADRS_0 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_ADRS_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_ADRS_0_VALUE 19:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_ADRS_1 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_ADRS_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_ADRS_1_VALUE 19:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_DATA_0 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_DATA_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_DATA_0_VALUE 31:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_DATA_1 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_DATA_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_DATA_1_VALUE 31:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_WE_0 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_WE_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_WE_0_VALUE 23:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_WE_1 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_WE_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_WE_1_VALUE 23:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_ALPHA_0 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_ALPHA_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_ALPHA_0_VALUE 31:0 /* RWXVF */
-#define NV_PGRAPH_DPRAM_ALPHA_1 0x0040082c /* RW-4R */
-#define NV_PGRAPH_DPRAM_ALPHA_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
-#define NV_PGRAPH_DPRAM_ALPHA_1_VALUE 31:0 /* RWXVF */
-#define NV_PGRAPH_STORED_FMT 0x00400830 /* RW-4R */
-#define NV_PGRAPH_STORED_FMT_MONO0 5:0 /* RWXVF */
-#define NV_PGRAPH_STORED_FMT_PATT0 13:8 /* RWXVF */
-#define NV_PGRAPH_STORED_FMT_PATT1 21:16 /* RWXVF */
-#define NV_PGRAPH_STORED_FMT_CHROMA 29:24 /* RWXVF */
-#define NV_PGRAPH_FORMATS 0x00400618 /* RW-4R */
-#define NV_PGRAPH_FORMATS_ROP 2:0 /* R-XVF */
-#define NV_PGRAPH_FORMATS_ROP_Y8 0x00000000 /* -W--V */
-#define NV_PGRAPH_FORMATS_ROP_RGB15 0x00000001 /* -W--V */
-#define NV_PGRAPH_FORMATS_ROP_RGB16 0x00000002 /* -W--V */
-#define NV_PGRAPH_FORMATS_ROP_Y16 0x00000003 /* -W--V */
-#define NV_PGRAPH_FORMATS_ROP_INVALID 0x00000004 /* -W--V */
-#define NV_PGRAPH_FORMATS_ROP_RGB24 0x00000005 /* -W--V */
-#define NV_PGRAPH_FORMATS_ROP_RGB30 0x00000006 /* -W--V */
-#define NV_PGRAPH_FORMATS_ROP_Y32 0x00000007 /* -W--V */
-#define NV_PGRAPH_FORMATS_SRC 9:4 /* R-XVF */
-#define NV_PGRAPH_FORMATS_SRC_INVALID 0x00000000 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X16A8Y8 0x00000002 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X24Y8 0x00000003 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_A1R5G5B5 0x00000006 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X1R5G5B5 0x00000007 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X16A1R5G5B5 0x00000008 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X17R5G5B5 0x00000009 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_R5G6B5 0x0000000A /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_A16R5G6B5 0x0000000B /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X16R5G6B5 0x0000000C /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_A8R8G8B8 0x0000000D /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X8R8G8B8 0x0000000E /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_Y16 0x0000000F /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_A16Y16 0x00000010 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_X16Y16 0x00000011 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_V8YB8U8YA8 0x00000012 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_YB8V8YA8U8 0x00000013 /* RW--V */
-#define NV_PGRAPH_FORMATS_SRC_LE_Y32 0x00000014 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB 15:12 /* R-XVF */
-#define NV_PGRAPH_FORMATS_FB_INVALID 0x00000000 /* RWI-V */
-#define NV_PGRAPH_FORMATS_FB_Y8 0x00000001 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_A1R5G5B5 0x00000004 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_R5G6B5 0x00000005 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_Y16 0x00000006 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_A8R8G8B8 0x0000000c /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_Y32 0x0000000d /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_V8YB8U8YA8 0x0000000e /* RW--V */
-#define NV_PGRAPH_FORMATS_FB_YB8V8YA8U8 0x0000000f /* RW--V */
-#define NV_PGRAPH_ABS_X_RAM(i) (0x00400400+(i)*4) /* RW-4A */
-#define NV_PGRAPH_ABS_X_RAM__SIZE_1 32 /* */
-#define NV_PGRAPH_ABS_X_RAM_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_X_RAM_BPORT(i) (0x00400c00+(i)*4) /* R--4A */
-#define NV_PGRAPH_X_RAM_BPORT__SIZE_1 32 /* */
-#define NV_PGRAPH_X_RAM_BPORT_VALUE 31:0 /* R--UF */
-#define NV_PGRAPH_ABS_Y_RAM(i) (0x00400480+(i)*4) /* RW-4A */
-#define NV_PGRAPH_ABS_Y_RAM__SIZE_1 32 /* */
-#define NV_PGRAPH_ABS_Y_RAM_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_Y_RAM_BPORT(i) (0x00400c80+(i)*4) /* R--4A */
-#define NV_PGRAPH_Y_RAM_BPORT__SIZE_1 32 /* */
-#define NV_PGRAPH_Y_RAM_BPORT_VALUE 31:0 /* R--UF */
-#define NV_PGRAPH_XY_LOGIC_MISC0 0x00400514 /* RW-4R */
-#define NV_PGRAPH_XY_LOGIC_MISC0_COUNTER 17:0 /* RWBUF */
-#define NV_PGRAPH_XY_LOGIC_MISC0_COUNTER_0 0x00000000 /* RWB-V */
-#define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION 20:20 /* RWVVF */
-#define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION_NONZERO 0x00000000 /* RWV-V */
-#define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION_ZERO 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC0_INDEX 31:28 /* RWBUF */
-#define NV_PGRAPH_XY_LOGIC_MISC0_INDEX_0 0x00000000 /* RWB-V */
-#define NV_PGRAPH_XY_LOGIC_MISC1 0x00400518 /* RW-4R */
-#define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL 0:0 /* RWNVF */
-#define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL_NEEDED 0x00000000 /* RWN-V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL_DONE 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX 4:4 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX_NOTNULL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX_NULL 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY 5:5 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY_NOTNULL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY_NULL 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX 12:12 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX_UUMAX 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX_IMAGEMAX 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX 16:16 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX_UUMAX 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX_IMAGEMAX 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA 20:20 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA_CLIPMAX 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA_IMAGEMAX 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC2 0x0040051C /* RW-4R */
-#define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF 0:0 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF_DISABLE 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF_ENABLE 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX 4:4 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX_NOTNULL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX_NULL 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY 5:5 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY_NOTNULL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY_NULL 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX 12:12 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX_UCMAX 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX_IMAGEMAX 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX 16:16 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX_UCMAX 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX_IMAGEMAX 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA 20:20 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA_CLIPMAX 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA_IMAGEMAX 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3 0x00400520 /* RW-4R */
-#define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0 0:0 /* RWXVF */
-#define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0_NULL 0x00000000 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0_TRUE 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY 4:4 /* RWXVF */
-#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY_NULL 0x00000000 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY_TRUE 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX 8:8 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX_NULL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX_TRUE 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG 12:12 /* RWIVF */
-#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG_NULL 0x00000000 /* RWI-V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG_TRUE 0x00000001 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_DIMX 22:16 /* RWXUF */
-#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_DIMX_0 0x00000000 /* RW--V */
-#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_WDIMX 30:24 /* RWXUF */
-#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_WDIMX_0 0x00000000 /* RW--V */
-#define NV_PGRAPH_X_MISC 0x00400500 /* RW-4R */
-#define NV_PGRAPH_X_MISC_BIT33_0 0:0 /* RWNVF */
-#define NV_PGRAPH_X_MISC_BIT33_0_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_BIT33_1 1:1 /* RWNVF */
-#define NV_PGRAPH_X_MISC_BIT33_1_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_BIT33_2 2:2 /* RWNVF */
-#define NV_PGRAPH_X_MISC_BIT33_2_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_BIT33_3 3:3 /* RWNVF */
-#define NV_PGRAPH_X_MISC_BIT33_3_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_RANGE_0 4:4 /* RWNVF */
-#define NV_PGRAPH_X_MISC_RANGE_0_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_RANGE_1 5:5 /* RWNVF */
-#define NV_PGRAPH_X_MISC_RANGE_1_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_RANGE_2 6:6 /* RWNVF */
-#define NV_PGRAPH_X_MISC_RANGE_2_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_RANGE_3 7:7 /* RWNVF */
-#define NV_PGRAPH_X_MISC_RANGE_3_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_X_MISC_ADDER_OUTPUT 29:28 /* RWXVF */
-#define NV_PGRAPH_X_MISC_ADDER_OUTPUT_EQ_0 0x00000000 /* RW--V */
-#define NV_PGRAPH_X_MISC_ADDER_OUTPUT_LT_0 0x00000001 /* RW--V */
-#define NV_PGRAPH_X_MISC_ADDER_OUTPUT_GT_0 0x00000002 /* RW--V */
-#define NV_PGRAPH_Y_MISC 0x00400504 /* RW-4R */
-#define NV_PGRAPH_Y_MISC_BIT33_0 0:0 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_BIT33_0_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_BIT33_1 1:1 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_BIT33_1_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_BIT33_2 2:2 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_BIT33_2_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_BIT33_3 3:3 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_BIT33_3_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_RANGE_0 4:4 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_RANGE_0_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_RANGE_1 5:5 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_RANGE_1_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_RANGE_2 6:6 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_RANGE_2_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_RANGE_3 7:7 /* RWNVF */
-#define NV_PGRAPH_Y_MISC_RANGE_3_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT 29:28 /* RWXVF */
-#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_EQ_0 0x00000000 /* RW--V */
-#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_LT_0 0x00000001 /* RW--V */
-#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_GT_0 0x00000002 /* RW--V */
-#define NV_PGRAPH_ABS_UCLIP_XMIN 0x0040053C /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIP_XMIN_VALUE 15:0 /* RWXSF */
-#define NV_PGRAPH_ABS_UCLIP_XMAX 0x00400544 /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIP_XMAX_VALUE 17:0 /* RWXSF */
-#define NV_PGRAPH_ABS_UCLIP_YMIN 0x00400540 /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIP_YMIN_VALUE 15:0 /* RWXSF */
-#define NV_PGRAPH_ABS_UCLIP_YMAX 0x00400548 /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIP_YMAX_VALUE 17:0 /* RWXSF */
-#define NV_PGRAPH_ABS_UCLIPA_XMIN 0x00400560 /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIPA_XMIN_VALUE 15:0 /* RWXSF */
-#define NV_PGRAPH_ABS_UCLIPA_XMAX 0x00400568 /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIPA_XMAX_VALUE 17:0 /* RWXSF */
-#define NV_PGRAPH_ABS_UCLIPA_YMIN 0x00400564 /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIPA_YMIN_VALUE 15:0 /* RWXSF */
-#define NV_PGRAPH_ABS_UCLIPA_YMAX 0x0040056C /* RW-4R */
-#define NV_PGRAPH_ABS_UCLIPA_YMAX_VALUE 17:0 /* RWXSF */
-#define NV_PGRAPH_SOURCE_COLOR 0x0040050C /* RW-4R */
-#define NV_PGRAPH_SOURCE_COLOR_VALUE 31:0 /* RWNVF */
-#define NV_PGRAPH_SOURCE_COLOR_VALUE_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_VALID1 0x00400508 /* RW-4R */
-#define NV_PGRAPH_VALID1_VLD 22:0 /* RWNVF */
-#define NV_PGRAPH_VALID1_VLD_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_VALID1_CLIP_MIN 28:28 /* RWIVF */
-#define NV_PGRAPH_VALID1_CLIP_MIN_NO_ERROR 0x00000000 /* RWI-V */
-#define NV_PGRAPH_VALID1_CLIP_MIN_ONLY 0x00000001 /* RW--V */
-#define NV_PGRAPH_VALID1_CLIPA_MIN 29:29 /* RWIVF */
-#define NV_PGRAPH_VALID1_CLIPA_MIN_NO_ERROR 0x00000000 /* RWI-V */
-#define NV_PGRAPH_VALID1_CLIPA_MIN_ONLY 0x00000001 /* RW--V */
-#define NV_PGRAPH_VALID1_CLIP_MAX 30:30 /* RWIVF */
-#define NV_PGRAPH_VALID1_CLIP_MAX_NO_ERROR 0x00000000 /* RWI-V */
-#define NV_PGRAPH_VALID1_CLIP_MAX_ONLY 0x00000001 /* RW--V */
-#define NV_PGRAPH_VALID1_CLIPA_MAX 31:31 /* RWIVF */
-#define NV_PGRAPH_VALID1_CLIPA_MAX_NO_ERROR 0x00000000 /* RWI-V */
-#define NV_PGRAPH_VALID1_CLIPA_MAX_ONLY 0x00000001 /* RW--V */
-#define NV_PGRAPH_VALID2 0x00400578 /* RW-4R */
-#define NV_PGRAPH_VALID2_VLD2 28:0 /* RWNVF */
-#define NV_PGRAPH_VALID2_VLD2_0 0x00000000 /* RWN-V */
-#define NV_PGRAPH_ABS_ICLIP_XMAX 0x00400534 /* RW-4R */
-#define NV_PGRAPH_ABS_ICLIP_XMAX_VALUE 17:0 /* RWXSF */
-#define NV_PGRAPH_ABS_ICLIP_YMAX 0x00400538 /* RW-4R */
-#define NV_PGRAPH_ABS_ICLIP_YMAX_VALUE 17:0 /* RWXSF */
-#define NV_PGRAPH_CLIPX_0 0x00400524 /* RW-4R */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MIN 1:0 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MAX 3:2 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP0_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MIN 5:4 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MAX 7:6 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP1_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MIN 9:8 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MAX 11:10 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP2_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MIN 13:12 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MAX 15:14 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP3_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MIN 17:16 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MAX 19:18 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP4_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MIN 21:20 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MAX 23:22 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP5_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MIN 25:24 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MAX 27:26 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP6_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MIN 29:28 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MAX 31:30 /* RWNVF */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_0_CLIP7_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1 0x00400528 /* RW-4R */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MIN 1:0 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MAX 3:2 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP8_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MIN 5:4 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MAX 7:6 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP9_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MIN 9:8 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MAX 11:10 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP10_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP11_MIN 13:12 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP11_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP11_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP11MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP11_MAX 15:14 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP11_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP11_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP11_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MIN 17:16 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MAX 19:18 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP12_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MIN 21:20 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MAX 23:22 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP13_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MIN 25:24 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MAX 27:26 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP14_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MIN 29:28 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MAX 31:30 /* RWNVF */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPX_1_CLIP15_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0 0x0040052c /* RW-4R */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MIN 1:0 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MAX 3:2 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP0_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MIN 5:4 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MAX 7:6 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP1_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MIN 9:8 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MAX 11:10 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP2_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MIN 13:12 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MAX 15:14 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP3_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MIN 17:16 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MAX 19:18 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP4_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MIN 21:20 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MAX 23:22 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP5_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MIN 25:24 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MAX 27:26 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP6_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MIN 29:28 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MAX 31:30 /* RWNVF */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_0_CLIP7_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1 0x00400530 /* RW-4R */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MIN 1:0 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MAX 3:2 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP8_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MIN 5:4 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MAX 7:6 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP9_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MIN 9:8 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MAX 11:10 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP10_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP11_MIN 13:12 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP11_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP11_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP11MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP11_MAX 15:14 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP11_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP11_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP11_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MIN 17:16 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MAX 19:18 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP12_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MIN 21:20 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MAX 23:22 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP13_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MIN 25:24 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MAX 27:26 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP14_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MIN 29:28 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MIN_GT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MIN_LT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MIN_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MAX 31:30 /* RWNVF */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MAX_LT 0x00000000 /* RW--V */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MAX_GT 0x00000001 /* RWN-V */
-#define NV_PGRAPH_CLIPY_1_CLIP15_MAX_EQ 0x00000002 /* RW--V */
-#define NV_PGRAPH_MISC24_0 0x00400510 /* RW-4R */
-#define NV_PGRAPH_MISC24_0_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_MISC24_1 0x00400570 /* RW-4R */
-#define NV_PGRAPH_MISC24_1_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_MISC24_2 0x00400574 /* RW-4R */
-#define NV_PGRAPH_MISC24_2_VALUE 23:0 /* RWXUF */
-#define NV_PGRAPH_PASSTHRU_0 0x0040057C /* RW-4R */
-#define NV_PGRAPH_PASSTHRU_0_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_PASSTHRU_1 0x00400580 /* RW-4R */
-#define NV_PGRAPH_PASSTHRU_1_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_PASSTHRU_2 0x00400584 /* RW-4R */
-#define NV_PGRAPH_PASSTHRU_2_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_U_RAM(i) (0x00400d00+(i)*4) /* RW-4A */
-#define NV_PGRAPH_U_RAM__SIZE_1 16 /* */
-#define NV_PGRAPH_U_RAM_VALUE 31:6 /* RWXFF */
-#define NV_PGRAPH_V_RAM(i) (0x00400d40+(i)*4) /* RW-4A */
-#define NV_PGRAPH_V_RAM__SIZE_1 16 /* */
-#define NV_PGRAPH_V_RAM_VALUE 31:6 /* RWXFF */
-#define NV_PGRAPH_M_RAM(i) (0x00400d80+(i)*4) /* RW-4A */
-#define NV_PGRAPH_M_RAM__SIZE_1 16 /* */
-#define NV_PGRAPH_M_RAM_VALUE 31:6 /* RWXFF */
-#define NV_PGRAPH_DMA_START_0 0x00401000 /* RW-4R */
-#define NV_PGRAPH_DMA_START_0_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_START_1 0x00401004 /* RW-4R */
-#define NV_PGRAPH_DMA_START_1_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_LENGTH 0x00401008 /* RW-4R */
-#define NV_PGRAPH_DMA_LENGTH_VALUE 21:0 /* RWXUF */
-#define NV_PGRAPH_DMA_MISC 0x0040100C /* RW-4R */
-#define NV_PGRAPH_DMA_MISC_COUNT 15:0 /* RWXUF */
-#define NV_PGRAPH_DMA_MISC_FMT_SRC 18:16 /* RWXVF */
-#define NV_PGRAPH_DMA_MISC_FMT_DST 22:20 /* RWXVF */
-#define NV_PGRAPH_DMA_DATA_0 0x00401020 /* RW-4R */
-#define NV_PGRAPH_DMA_DATA_0_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_DATA_1 0x00401024 /* RW-4R */
-#define NV_PGRAPH_DMA_DATA_1_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_RM 0x00401030 /* RW-4R */
-#define NV_PGRAPH_DMA_RM_ASSIST_A 0:0 /* RWIVF */
-#define NV_PGRAPH_DMA_RM_ASSIST_A_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_DMA_RM_ASSIST_A_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_DMA_RM_ASSIST_A_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_DMA_RM_ASSIST_B 1:1 /* RWIVF */
-#define NV_PGRAPH_DMA_RM_ASSIST_B_NOT_PENDING 0x00000000 /* R-I-V */
-#define NV_PGRAPH_DMA_RM_ASSIST_B_PENDING 0x00000001 /* R---V */
-#define NV_PGRAPH_DMA_RM_ASSIST_B_RESET 0x00000001 /* -W--C */
-#define NV_PGRAPH_DMA_RM_WRITE_REQ 4:4 /* CWIVF */
-#define NV_PGRAPH_DMA_RM_WRITE_REQ_NOT_PENDING 0x00000000 /* CWI-V */
-#define NV_PGRAPH_DMA_RM_WRITE_REQ_PENDING 0x00000001 /* -W--T */
-#define NV_PGRAPH_DMA_A_XLATE_INST 0x00401040 /* RW-4R */
-#define NV_PGRAPH_DMA_A_XLATE_INST_VALUE 15:0 /* RWXUF */
-#define NV_PGRAPH_DMA_A_CONTROL 0x00401044 /* RW-4R */
-#define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE 12:12 /* RWIVF */
-#define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE_NOT_PRESENT 0x00000000 /* RWI-V */
-#define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE_PRESENT 0x00000001 /* RW--V */
-#define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY 13:13 /* RWXVF */
-#define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY_NOT_LINEAR 0x00000000 /* RW--V */
-#define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY_LINEAR 0x00000001 /* RW--V */
-#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE 17:16 /* RWXUF */
-#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_NVM 0x00000000 /* RW--V */
-#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_PCI 0x00000002 /* RW--V */
-#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_AGP 0x00000003 /* RW--V */
-#define NV_PGRAPH_DMA_A_CONTROL_ADJUST 31:20 /* RWXUF */
-#define NV_PGRAPH_DMA_A_LIMIT 0x00401048 /* RW-4R */
-#define NV_PGRAPH_DMA_A_LIMIT_OFFSET 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_A_TLB_PTE 0x0040104C /* RW-4R */
-#define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS 1:1 /* RWXVF */
-#define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS_READ_ONLY 0x00000000 /* RW--V */
-#define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS_READ_WRITE 0x00000001 /* RW--V */
-#define NV_PGRAPH_DMA_A_TLB_PTE_FRAME_ADDRESS 31:12 /* RWXUF */
-#define NV_PGRAPH_DMA_A_TLB_TAG 0x00401050 /* RW-4R */
-#define NV_PGRAPH_DMA_A_TLB_TAG_ADDRESS 31:12 /* RWXUF */
-#define NV_PGRAPH_DMA_A_ADJ_OFFSET 0x00401054 /* RW-4R */
-#define NV_PGRAPH_DMA_A_ADJ_OFFSET_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_A_OFFSET 0x00401058 /* RW-4R */
-#define NV_PGRAPH_DMA_A_OFFSET_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_A_SIZE 0x0040105C /* RW-4R */
-#define NV_PGRAPH_DMA_A_SIZE_VALUE 24:0 /* RWXUF */
-#define NV_PGRAPH_DMA_A_Y_SIZE 0x00401060 /* RW-4R */
-#define NV_PGRAPH_DMA_A_Y_SIZE_VALUE 10:0 /* RWXUF */
-#define NV_PGRAPH_DMA_B_XLATE_INST 0x00401080 /* RW-4R */
-#define NV_PGRAPH_DMA_B_XLATE_INST_VALUE 15:0 /* RWXUF */
-#define NV_PGRAPH_DMA_B_CONTROL 0x00401084 /* RW-4R */
-#define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE 12:12 /* RWIVF */
-#define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE_NOT_PRESENT 0x00000000 /* RWI-V */
-#define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE_PRESENT 0x00000001 /* RW--V */
-#define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY 13:13 /* RWXVF */
-#define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY_NOT_LINEAR 0x00000000 /* RW--V */
-#define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY_LINEAR 0x00000001 /* RW--V */
-#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE 17:16 /* RWXUF */
-#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_NVM 0x00000000 /* RW--V */
-#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_PCI 0x00000002 /* RW--V */
-#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_AGP 0x00000003 /* RW--V */
-#define NV_PGRAPH_DMA_B_CONTROL_ADJUST 31:20 /* RWXUF */
-#define NV_PGRAPH_DMA_B_LIMIT 0x00401088 /* RW-4R */
-#define NV_PGRAPH_DMA_B_LIMIT_OFFSET 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_B_TLB_PTE 0x0040108C /* RW-4R */
-#define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS 1:1 /* RWXVF */
-#define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS_READ_ONLY 0x00000000 /* RW--V */
-#define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS_READ_WRITE 0x00000001 /* RW--V */
-#define NV_PGRAPH_DMA_B_TLB_PTE_FRAME_ADDRESS 31:12 /* RWXUF */
-#define NV_PGRAPH_DMA_B_TLB_TAG 0x00401090 /* RW-4R */
-#define NV_PGRAPH_DMA_B_TLB_TAG_ADDRESS 31:12 /* RWXUF */
-#define NV_PGRAPH_DMA_B_ADJ_OFFSET 0x00401094 /* RW-4R */
-#define NV_PGRAPH_DMA_B_ADJ_OFFSET_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_B_OFFSET 0x00401098 /* RW-4R */
-#define NV_PGRAPH_DMA_B_OFFSET_VALUE 31:0 /* RWXUF */
-#define NV_PGRAPH_DMA_B_SIZE 0x0040109C /* RW-4R */
-#define NV_PGRAPH_DMA_B_SIZE_VALUE 24:0 /* RWXUF */
-#define NV_PGRAPH_DMA_B_Y_SIZE 0x004010A0 /* RW-4R */
-#define NV_PGRAPH_DMA_B_Y_SIZE_VALUE 10:0 /* RWXUF */
-
-/* Framebuffer registers */
-#define NV_PFB 0x00100FFF:0x00100000 /* RW--D */
-#define NV_PFB_BOOT_0 0x00100000 /* RW-4R */
-#define NV_PFB_BOOT_0_RAM_AMOUNT 1:0 /* RW-VF */
-#define NV_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_WIDTH_128 2:2 /* RW-VF */
-#define NV_PFB_BOOT_0_RAM_WIDTH_128_OFF 0x00000000 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_WIDTH_128_ON 0x00000001 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_TYPE 4:3 /* RW-VF */
-#define NV_PFB_BOOT_0_RAM_TYPE_256K 0x00000000 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_TYPE_512K_2BANK 0x00000001 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_TYPE_512K_4BANK 0x00000002 /* RW--V */
-#define NV_PFB_BOOT_0_RAM_TYPE_1024K_2BANK 0x00000003 /* RW--V */
-#define NV_PFB_CONFIG_0 0x00100200 /* RW-4R */
-#define NV_PFB_CONFIG_0_TYPE 14:0 /* RWIVF */
-#define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_8BPP 0x00000120 /* RW--V */
-#define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_16BPP 0x00000220 /* RW--V */
-#define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_32BPP 0x00000320 /* RW--V */
-#define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_8BPP 0x00004120 /* RW--V */
-#define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_16BPP 0x00004220 /* RW--V */
-#define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_32BPP 0x00004320 /* RW--V */
-#define NV_PFB_CONFIG_0_TYPE_TETRIS 0x00002000 /* RW--V */
-#define NV_PFB_CONFIG_0_TYPE_NOTILING 0x00001114 /* RWI-V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE 17:15 /* RWI-F */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_PASS 0x00000000 /* RWI-V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_1 0x00000001 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_2 0x00000002 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_3 0x00000003 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_4 0x00000004 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_5 0x00000005 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_6 0x00000006 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_MODE_7 0x00000007 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_SHIFT 19:18 /* RWI-F */
-#define NV_PFB_CONFIG_0_TETRIS_SHIFT_0 0x00000000 /* RWI-V */
-#define NV_PFB_CONFIG_0_TETRIS_SHIFT_1 0x00000001 /* RW--V */
-#define NV_PFB_CONFIG_0_TETRIS_SHIFT_2 0x00000002 /* RW--V */
-#define NV_PFB_CONFIG_0_BANK_SWAP 22:20 /* RWI-F */
-#define NV_PFB_CONFIG_0_BANK_SWAP_OFF 0x00000000 /* RWI-V */
-#define NV_PFB_CONFIG_0_BANK_SWAP_1M 0x00000001 /* RW--V */
-#define NV_PFB_CONFIG_0_BANK_SWAP_2M 0x00000005 /* RW--V */
-#define NV_PFB_CONFIG_0_BANK_SWAP_4M 0x00000007 /* RW--V */
-#define NV_PFB_CONFIG_0_UNUSED 23:23 /* RW-VF */
-#define NV_PFB_CONFIG_0_SCRAMBLE_EN 29:29 /* RWIVF */
-#define NV_PFB_CONFIG_0_SCRAMBLE_EN_INIT 0x00000000 /* RW--V */
-#define NV_PFB_CONFIG_0_SCRAMBLE_ACTIVE 0x00000001 /* RW--V */
-#define NV_PFB_CONFIG_0_PRAMIN_WR 28:28 /* RWIVF */
-#define NV_PFB_CONFIG_0_PRAMIN_WR_INIT 0x00000000 /* RW--V */
-#define NV_PFB_CONFIG_0_PRAMIN_WR_DISABLED 0x00000001 /* RW--V */
-#define NV_PFB_CONFIG_0_PRAMIN_WR_MASK 27:24 /* RWIVF */
-#define NV_PFB_CONFIG_0_PRAMIN_WR_MASK_INIT 0x00000000 /* RWI-V */
-#define NV_PFB_CONFIG_0_PRAMIN_WR_MASK_CLEAR 0x0000000f /* RWI-V */
-#define NV_PFB_CONFIG_1 0x00100204 /* RW-4R */
-#define NV_PFB_RTL 0x00100300 /* RW-4R */
-#define NV_PFB_RTL_H 0:0 /* RWIUF */
-#define NV_PFB_RTL_H_DEFAULT 0x00000000 /* RWI-V */
-#define NV_PFB_RTL_MC 1:1 /* RWIUF */
-#define NV_PFB_RTL_MC_DEFAULT 0x00000000 /* RWI-V */
-#define NV_PFB_RTL_V 2:2 /* RWIUF */
-#define NV_PFB_RTL_V_DEFAULT 0x00000000 /* RWI-V */
-#define NV_PFB_RTL_G 3:3 /* RWIUF */
-#define NV_PFB_RTL_G_DEFAULT 0x00000000 /* RWI-V */
-#define NV_PFB_RTL_GB 4:4 /* RWIUF */
-#define NV_PFB_RTL_GB_DEFAULT 0x00000000 /* RWI-V */
-#define NV_PFB_CONFIG_0_RESOLUTION 5:0 /* RWIVF */
-#define NV_PFB_CONFIG_0_RESOLUTION_320_PIXELS 0x0000000a /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_400_PIXELS 0x0000000d /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_480_PIXELS 0x0000000f /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_512_PIXELS 0x00000010 /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_640_PIXELS 0x00000014 /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_800_PIXELS 0x00000019 /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_960_PIXELS 0x0000001e /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_1024_PIXELS 0x00000020 /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_1152_PIXELS 0x00000024 /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_1280_PIXELS 0x00000028 /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_1600_PIXELS 0x00000032 /* RW--V */
-#define NV_PFB_CONFIG_0_RESOLUTION_DEFAULT 0x00000014 /* RWI-V */
-#define NV_PFB_CONFIG_0_PIXEL_DEPTH 9:8 /* RWIVF */
-#define NV_PFB_CONFIG_0_PIXEL_DEPTH_8_BITS 0x00000001 /* RW--V */
-#define NV_PFB_CONFIG_0_PIXEL_DEPTH_16_BITS 0x00000002 /* RW--V */
-#define NV_PFB_CONFIG_0_PIXEL_DEPTH_32_BITS 0x00000003 /* RW--V */
-#define NV_PFB_CONFIG_0_PIXEL_DEPTH_DEFAULT 0x00000001 /* RWI-V */
-#define NV_PFB_CONFIG_0_TILING 12:12 /* RWIVF */
-#define NV_PFB_CONFIG_0_TILING_ENABLED 0x00000000 /* RW--V */
-#define NV_PFB_CONFIG_0_TILING_DISABLED 0x00000001 /* RWI-V */
-#define NV_PFB_CONFIG_1_SGRAM100 3:3 /* RWIVF */
-#define NV_PFB_CONFIG_1_SGRAM100_ENABLED 0x00000000 /* RWI-V */
-#define NV_PFB_CONFIG_1_SGRAM100_DISABLED 0x00000001 /* RW--V */
-#define NV_PFB_DEBUG_0_CKE_ALWAYSON 29:29 /* RWIVF */
-#define NV_PFB_DEBUG_0_CKE_ALWAYSON_OFF 0x00000000 /* RW--V */
-#define NV_PFB_DEBUG_0_CKE_ALWAYSON_ON 0x00000001 /* RWI-V */
-
-#define NV_PEXTDEV 0x00101FFF:0x00101000 /* RW--D */
-#define NV_PEXTDEV_BOOT_0 0x00101000 /* R--4R */
-#define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED 0:0 /* R-XVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED_33MHZ 0x00000000 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED_66MHZ 0x00000001 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR 1:1 /* R-XVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR_NO_BIOS 0x00000000 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR_BIOS 0x00000001 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE 3:2 /* R-XVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_256K 0x00000000 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_512K_2BANK 0x00000001 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_512K_4BANK 0x00000002 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_1024K_2BANK 0x00000003 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH 4:4 /* R-XVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH_64 0x00000000 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH_128 0x00000001 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE 5:5 /* R-XVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE_PCI 0x00000000 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE_AGP 0x00000001 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL 6:6 /* R-XVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL_13500K 0x00000000 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL_14318180 0x00000001 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE 8:7 /* R-XVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_SECAM 0x00000000 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_NTSC 0x00000001 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_PAL 0x00000002 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_DISABLED 0x00000003 /* R---V */
-#define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE 11:11 /* RWIVF */
-#define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE_DISABLED 0x00000000 /* RWI-V */
-#define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE_ENABLED 0x00000001 /* RW--V */
-
-/* Extras */
-#define NV_PRAMIN 0x007FFFFF:0x00700000 /* RW--M */
-/*#define NV_PRAMIN 0x00FFFFFF:0x00C00000*/
-#define NV_PNVM 0x01FFFFFF:0x01000000 /* RW--M */
-/*#define NV_PNVM 0x00BFFFFF:0x00800000*/
-#define NV_CHAN0 0x0080ffff:0x00800000
-
-/* FIFO subchannels */
-#define NV_UROP 0x43
-#define NV_UCHROMA 0x57
-#define NV_UCLIP 0x19
-#define NV_UPATT 0x18
-#define NV_ULIN 0x5C
-#define NV_UTRI 0x5D
-#define NV_URECT 0x5E
-#define NV_UBLIT 0x5F
-#define NV_UGLYPH 0x4B
-
-#endif /*__NV4REF_H__*/
-
diff --git a/drivers/video/riva/nv_driver.c b/drivers/video/riva/nv_driver.c
index be630a0..a110268 100644
--- a/drivers/video/riva/nv_driver.c
+++ b/drivers/video/riva/nv_driver.c
@@ -231,12 +231,14 @@ unsigned long riva_get_memlen(struct riva_par *par)
case NV_ARCH_30:
if(chipset == NV_CHIP_IGEFORCE2) {
- dev = pci_find_slot(0, 1);
+ dev = pci_get_bus_and_slot(0, 1);
pci_read_config_dword(dev, 0x7C, &amt);
+ pci_dev_put(dev);
memlen = (((amt >> 6) & 31) + 1) * 1024;
} else if (chipset == NV_CHIP_0x01F0) {
- dev = pci_find_slot(0, 1);
+ dev = pci_get_bus_and_slot(0, 1);
pci_read_config_dword(dev, 0x84, &amt);
+ pci_dev_put(dev);
memlen = (((amt >> 4) & 127) + 1) * 1024;
} else {
switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) &
diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/riva/riva_hw.c
index e0b8c52..70bfd78 100644
--- a/drivers/video/riva/riva_hw.c
+++ b/drivers/video/riva/riva_hw.c
@@ -1118,8 +1118,9 @@ static void nForceUpdateArbitrationSettings
unsigned int uMClkPostDiv;
struct pci_dev *dev;
- dev = pci_find_slot(0, 3);
+ dev = pci_get_bus_and_slot(0, 3);
pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
+ pci_dev_put(dev);
uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
if(!uMClkPostDiv) uMClkPostDiv = 4;
@@ -1132,8 +1133,9 @@ static void nForceUpdateArbitrationSettings
sim_data.enable_video = 0;
sim_data.enable_mp = 0;
- dev = pci_find_slot(0, 1);
+ dev = pci_get_bus_and_slot(0, 1);
pci_read_config_dword(dev, 0x7C, &sim_data.memory_type);
+ pci_dev_put(dev);
sim_data.memory_type = (sim_data.memory_type >> 12) & 1;
sim_data.memory_width = 64;
@@ -2112,12 +2114,14 @@ static void nv10GetConfig
* Fill in chip configuration.
*/
if(chipset == NV_CHIP_IGEFORCE2) {
- dev = pci_find_slot(0, 1);
+ dev = pci_get_bus_and_slot(0, 1);
pci_read_config_dword(dev, 0x7C, &amt);
+ pci_dev_put(dev);
chip->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024;
} else if(chipset == NV_CHIP_0x01F0) {
- dev = pci_find_slot(0, 1);
+ dev = pci_get_bus_and_slot(0, 1);
pci_read_config_dword(dev, 0x84, &amt);
+ pci_dev_put(dev);
chip->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024;
} else {
switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) & 0x000000FF)
diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c
index 0405e83..76e6ce3 100644
--- a/drivers/video/riva/rivafb-i2c.c
+++ b/drivers/video/riva/rivafb-i2c.c
@@ -88,13 +88,16 @@ static int riva_gpio_getsda(void* data)
return val;
}
-static int riva_setup_i2c_bus(struct riva_i2c_chan *chan, const char *name)
+static int __devinit riva_setup_i2c_bus(struct riva_i2c_chan *chan,
+ const char *name,
+ unsigned int i2c_class)
{
int rc;
strcpy(chan->adapter.name, name);
chan->adapter.owner = THIS_MODULE;
chan->adapter.id = I2C_HW_B_RIVA;
+ chan->adapter.class = i2c_class;
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->par->pdev->dev;
chan->algo.setsda = riva_gpio_setsda;
@@ -124,42 +127,38 @@ static int riva_setup_i2c_bus(struct riva_i2c_chan *chan, const char *name)
return rc;
}
-void riva_create_i2c_busses(struct riva_par *par)
+void __devinit riva_create_i2c_busses(struct riva_par *par)
{
- par->bus = 3;
-
par->chan[0].par = par;
par->chan[1].par = par;
par->chan[2].par = par;
- par->chan[0].ddc_base = 0x3e;
- par->chan[1].ddc_base = 0x36;
+ par->chan[0].ddc_base = 0x36;
+ par->chan[1].ddc_base = 0x3e;
par->chan[2].ddc_base = 0x50;
- riva_setup_i2c_bus(&par->chan[0], "BUS1");
- riva_setup_i2c_bus(&par->chan[1], "BUS2");
- riva_setup_i2c_bus(&par->chan[2], "BUS3");
+ riva_setup_i2c_bus(&par->chan[0], "BUS1", I2C_CLASS_HWMON);
+ riva_setup_i2c_bus(&par->chan[1], "BUS2", 0);
+ riva_setup_i2c_bus(&par->chan[2], "BUS3", 0);
}
void riva_delete_i2c_busses(struct riva_par *par)
{
- if (par->chan[0].par)
- i2c_del_adapter(&par->chan[0].adapter);
- par->chan[0].par = NULL;
-
- if (par->chan[1].par)
- i2c_del_adapter(&par->chan[1].adapter);
- par->chan[1].par = NULL;
+ int i;
- if (par->chan[2].par)
- i2c_del_adapter(&par->chan[2].adapter);
- par->chan[2].par = NULL;
+ for (i = 0; i < 3; i++) {
+ if (!par->chan[i].par)
+ continue;
+ i2c_del_adapter(&par->chan[i].adapter);
+ par->chan[i].par = NULL;
+ }
}
-int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid)
+int __devinit riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid)
{
u8 *edid = NULL;
- edid = fb_ddc_read(&par->chan[conn-1].adapter);
+ if (par->chan[conn].par)
+ edid = fb_ddc_read(&par->chan[conn].adapter);
if (out_edid)
*out_edid = edid;
diff --git a/drivers/video/riva/rivafb.h b/drivers/video/riva/rivafb.h
index 48ead6d..d9f107b 100644
--- a/drivers/video/riva/rivafb.h
+++ b/drivers/video/riva/rivafb.h
@@ -4,7 +4,6 @@
#include <linux/fb.h>
#include <video/vga.h>
#include <linux/i2c.h>
-#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h>
#include "riva_hw.h"
@@ -61,7 +60,6 @@ struct riva_par {
Bool SecondCRTC;
int FlatPanel;
struct pci_dev *pdev;
- int bus;
int cursor_reset;
#ifdef CONFIG_MTRR
struct { int vram; int vram_valid; } mtrr;
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 3091b20..756fafb 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -65,7 +65,7 @@ static const struct svga_fb_format s3fb_formats[] = {
static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3,
- 60000, 240000, 14318};
+ 35000, 240000, 14318};
static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512};
@@ -164,7 +164,7 @@ MODULE_PARM_DESC(fasttext, "Enable S3 fast text mode (1=enable, 0=disable, defau
static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)
{
const u8 *font = map->data;
- u8* fb = (u8 *) info->screen_base;
+ u8 __iomem *fb = (u8 __iomem *) info->screen_base;
int i, c;
if ((map->width != 8) || (map->height != 16) ||
@@ -177,20 +177,19 @@ static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)
fb += 2;
for (i = 0; i < map->height; i++) {
for (c = 0; c < map->length; c++) {
- fb[c * 4] = font[c * map->height + i];
+ fb_writeb(font[c * map->height + i], fb + c * 4);
}
fb += 1024;
}
}
-
-
static struct fb_tile_ops s3fb_tile_ops = {
.fb_settile = svga_settile,
.fb_tilecopy = svga_tilecopy,
.fb_tilefill = svga_tilefill,
.fb_tileblit = svga_tileblit,
.fb_tilecursor = svga_tilecursor,
+ .fb_get_tilemax = svga_get_tilemax,
};
static struct fb_tile_ops s3fb_fast_tile_ops = {
@@ -199,6 +198,7 @@ static struct fb_tile_ops s3fb_fast_tile_ops = {
.fb_tilefill = svga_tilefill,
.fb_tileblit = svga_tileblit,
.fb_tilecursor = svga_tilecursor,
+ .fb_get_tilemax = svga_get_tilemax,
};
@@ -326,8 +326,13 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock)
{
u16 m, n, r;
u8 regval;
+ int rv;
- svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node);
+ rv = svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node);
+ if (rv < 0) {
+ printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node);
+ return;
+ }
/* Set VGA misc register */
regval = vga_r(NULL, VGA_MIS_R);
@@ -449,6 +454,10 @@ static int s3fb_set_par(struct fb_info *info)
info->flags &= ~FBINFO_MISC_TILEBLITTING;
info->tileops = NULL;
+ /* in 4bpp supports 8p wide tiles only, any tiles otherwise */
+ info->pixmap.blit_x = (bpp == 4) ? (1 << (8 - 1)) : (~(u32)0);
+ info->pixmap.blit_y = ~(u32)0;
+
offset_value = (info->var.xres_virtual * bpp) / 64;
screen_size = info->var.yres_virtual * info->fix.line_length;
} else {
@@ -458,6 +467,10 @@ static int s3fb_set_par(struct fb_info *info)
info->flags |= FBINFO_MISC_TILEBLITTING;
info->tileops = fasttext ? &s3fb_fast_tile_ops : &s3fb_tile_ops;
+ /* supports 8x16 tiles only */
+ info->pixmap.blit_x = 1 << (8 - 1);
+ info->pixmap.blit_y = 1 << (16 - 1);
+
offset_value = info->var.xres_virtual / 16;
screen_size = (info->var.xres_virtual * info->var.yres_virtual) / 64;
}
@@ -656,7 +669,7 @@ static int s3fb_set_par(struct fb_info *info)
value = ((value * hmul) / 8) - 5;
vga_wcrt(NULL, 0x3C, (value + 1) / 2);
- memset((u8*)info->screen_base, 0x00, screen_size);
+ memset_io(info->screen_base, 0x00, screen_size);
/* Device and screen back on */
svga_wcrt_mask(0x17, 0x80, 0x80);
svga_wseq_mask(0x01, 0x00, 0x20);
@@ -699,7 +712,7 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
break;
case 16:
if (regno >= 16)
- return -EINVAL;
+ return 0;
if (fb->var.green.length == 5)
((u32*)fb->pseudo_palette)[regno] = ((red & 0xF800) >> 1) |
@@ -712,9 +725,9 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
case 24:
case 32:
if (regno >= 16)
- return -EINVAL;
+ return 0;
- ((u32*)fb->pseudo_palette)[regno] = ((transp & 0xFF00) << 16) | ((red & 0xFF00) << 8) |
+ ((u32*)fb->pseudo_palette)[regno] = ((red & 0xFF00) << 8) |
(green & 0xFF00) | ((blue & 0xFF00) >> 8);
break;
default:
@@ -767,12 +780,6 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
unsigned int offset;
- /* Validate the offsets */
- if ((var->xoffset + var->xres) > var->xres_virtual)
- return -EINVAL;
- if ((var->yoffset + var->yres) > var->yres_virtual)
- return -EINVAL;
-
/* Calculate the offset */
if (var->bits_per_pixel == 0) {
offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2);
@@ -789,6 +796,23 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
return 0;
}
+/* Get capabilities of accelerator based on the mode */
+
+static void s3fb_get_caps(struct fb_info *info, struct fb_blit_caps *caps,
+ struct fb_var_screeninfo *var)
+{
+ if (var->bits_per_pixel == 0) {
+ /* can only support 256 8x16 bitmap */
+ caps->x = 1 << (8 - 1);
+ caps->y = 1 << (16 - 1);
+ caps->len = 256;
+ } else {
+ caps->x = ~(u32)0;
+ caps->y = ~(u32)0;
+ caps->len = ~(u32)0;
+ }
+}
+
/* ------------------------------------------------------------------------- */
/* Frame buffer operations */
@@ -805,6 +829,7 @@ static struct fb_ops s3fb_ops = {
.fb_fillrect = s3fb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = s3fb_imageblit,
+ .fb_get_caps = s3fb_get_caps,
};
/* ------------------------------------------------------------------------- */
@@ -1061,6 +1086,7 @@ static int s3_pci_resume(struct pci_dev* dev)
{
struct fb_info *info = pci_get_drvdata(dev);
struct s3fb_info *par = info->par;
+ int err;
dev_info(&(dev->dev), "resume\n");
@@ -1075,7 +1101,13 @@ static int s3_pci_resume(struct pci_dev* dev)
pci_set_power_state(dev, PCI_D0);
pci_restore_state(dev);
- pci_enable_device(dev);
+ err = pci_enable_device(dev);
+ if (err) {
+ mutex_unlock(&(par->open_lock));
+ release_console_sem();
+ dev_err(&(dev->dev), "error %d enabling device for resume\n", err);
+ return err;
+ }
pci_set_master(dev);
s3fb_set_par(info);
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index 8db066c..35c1ce6 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -41,10 +41,6 @@
#define SAVAGE4_I2C_SCL_IN 0x00000008
#define SAVAGE4_I2C_SDA_IN 0x00000010
-#define SET_CR_IX(base, val) writeb((val), base + 0x8000 + VGA_CR_IX)
-#define SET_CR_DATA(base, val) writeb((val), base + 0x8000 + VGA_CR_DATA)
-#define GET_CR_DATA(base) readb(base + 0x8000 + VGA_CR_DATA)
-
static void savage4_gpio_setscl(void *data, int val)
{
struct savagefb_i2c_chan *chan = data;
@@ -92,15 +88,15 @@ static void prosavage_gpio_setscl(void* data, int val)
struct savagefb_i2c_chan *chan = data;
u32 r;
- SET_CR_IX(chan->ioaddr, chan->reg);
- r = GET_CR_DATA(chan->ioaddr);
+ r = VGArCR(chan->reg, chan->par);
r |= PROSAVAGE_I2C_ENAB;
if (val) {
r |= PROSAVAGE_I2C_SCL_OUT;
} else {
r &= ~PROSAVAGE_I2C_SCL_OUT;
}
- SET_CR_DATA(chan->ioaddr, r);
+
+ VGAwCR(chan->reg, r, chan->par);
}
static void prosavage_gpio_setsda(void* data, int val)
@@ -108,31 +104,29 @@ static void prosavage_gpio_setsda(void* data, int val)
struct savagefb_i2c_chan *chan = data;
unsigned int r;
- SET_CR_IX(chan->ioaddr, chan->reg);
- r = GET_CR_DATA(chan->ioaddr);
+ r = VGArCR(chan->reg, chan->par);
r |= PROSAVAGE_I2C_ENAB;
if (val) {
r |= PROSAVAGE_I2C_SDA_OUT;
} else {
r &= ~PROSAVAGE_I2C_SDA_OUT;
}
- SET_CR_DATA(chan->ioaddr, r);
+
+ VGAwCR(chan->reg, r, chan->par);
}
static int prosavage_gpio_getscl(void* data)
{
struct savagefb_i2c_chan *chan = data;
- SET_CR_IX(chan->ioaddr, chan->reg);
- return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SCL_IN));
+ return (VGArCR(chan->reg, chan->par) & PROSAVAGE_I2C_SCL_IN) ? 1 : 0;
}
static int prosavage_gpio_getsda(void* data)
{
struct savagefb_i2c_chan *chan = data;
- SET_CR_IX(chan->ioaddr, chan->reg);
- return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SDA_IN));
+ return (VGArCR(chan->reg, chan->par) & PROSAVAGE_I2C_SDA_IN) ? 1 : 0;
}
static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h
index e648a6c..8bfdfc3 100644
--- a/drivers/video/savage/savagefb.h
+++ b/drivers/video/savage/savagefb.h
@@ -15,6 +15,8 @@
#include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h>
+#include <linux/mutex.h>
+#include <video/vga.h>
#include "../edid.h"
#ifdef SAVAGEFB_DEBUG
@@ -189,8 +191,12 @@ struct savagefb_par {
struct savagefb_i2c_chan chan;
struct savage_reg state;
struct savage_reg save;
+ struct savage_reg initial;
+ struct vgastate vgastate;
+ struct mutex open_lock;
unsigned char *edid;
u32 pseudo_palette[16];
+ u32 open_count;
int paletteEnabled;
int pm_state;
int display_type;
@@ -203,7 +209,7 @@ struct savagefb_par {
int clock[4];
int MCLK, REFCLK, LCDclk;
struct {
- u8 __iomem *vbase;
+ void __iomem *vbase;
u32 pbase;
u32 len;
#ifdef CONFIG_MTRR
@@ -212,7 +218,7 @@ struct savagefb_par {
} video;
struct {
- volatile u8 __iomem *vbase;
+ void __iomem *vbase;
u32 pbase;
u32 len;
} mmio;
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 0166ec2..3d7507a 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -1623,8 +1623,46 @@ static void savagefb_restore_state(struct fb_info *info)
savagefb_blank(FB_BLANK_UNBLANK, info);
}
+static int savagefb_open(struct fb_info *info, int user)
+{
+ struct savagefb_par *par = info->par;
+
+ mutex_lock(&par->open_lock);
+
+ if (!par->open_count) {
+ memset(&par->vgastate, 0, sizeof(par->vgastate));
+ par->vgastate.flags = VGA_SAVE_CMAP | VGA_SAVE_FONTS |
+ VGA_SAVE_MODE;
+ par->vgastate.vgabase = par->mmio.vbase + 0x8000;
+ save_vga(&par->vgastate);
+ savage_get_default_par(par, &par->initial);
+ }
+
+ par->open_count++;
+ mutex_unlock(&par->open_lock);
+ return 0;
+}
+
+static int savagefb_release(struct fb_info *info, int user)
+{
+ struct savagefb_par *par = info->par;
+
+ mutex_lock(&par->open_lock);
+
+ if (par->open_count == 1) {
+ savage_set_default_par(par, &par->initial);
+ restore_vga(&par->vgastate);
+ }
+
+ par->open_count--;
+ mutex_unlock(&par->open_lock);
+ return 0;
+}
+
static struct fb_ops savagefb_ops = {
.owner = THIS_MODULE,
+ .fb_open = savagefb_open,
+ .fb_release = savagefb_release,
.fb_check_var = savagefb_check_var,
.fb_set_par = savagefb_set_par,
.fb_setcolreg = savagefb_setcolreg,
@@ -2173,6 +2211,7 @@ static int __devinit savagefb_probe(struct pci_dev* dev,
if (!info)
return -ENOMEM;
par = info->par;
+ mutex_init(&par->open_lock);
err = pci_enable_device(dev);
if (err)
goto failed_enable;
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
index d048bd3..c149278 100644
--- a/drivers/video/sis/osdef.h
+++ b/drivers/video/sis/osdef.h
@@ -58,9 +58,6 @@
#define SIS_LINUX_KERNEL /* Linux kernel framebuffer */
#undef SIS_XORG_XF86 /* XFree86/X.org */
-#undef SIS_LINUX_KERNEL_24
-#undef SIS_LINUX_KERNEL_26
-
#ifdef OutPortByte
#undef OutPortByte
#endif
@@ -100,8 +97,6 @@
#define SIS315H
#endif
-#define SIS_LINUX_KERNEL_26
-
#if !defined(SIS300) && !defined(SIS315H)
#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
#warning sisfb will not work!
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index 7d5ee21..d5e2d9c 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -27,11 +27,7 @@
#include <linux/version.h>
#include "osdef.h"
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#include <video/sisfb.h>
-#else
-#include <linux/sisfb.h>
-#endif
#include "vgatypes.h"
#include "vstruct.h"
@@ -40,33 +36,17 @@
#define VER_MINOR 8
#define VER_LEVEL 9
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#include <linux/spinlock.h>
-#define SIS_PCI_GET_CLASS(a, b) pci_get_class(a, b)
-#define SIS_PCI_GET_DEVICE(a,b,c) pci_get_device(a,b,c)
-#define SIS_PCI_GET_SLOT(a,b) pci_get_slot(a,b)
-#define SIS_PCI_PUT_DEVICE(a) pci_dev_put(a)
+
#ifdef CONFIG_COMPAT
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)
#include <linux/ioctl32.h>
#define SIS_OLD_CONFIG_COMPAT
#else
-#include <linux/smp_lock.h>
#define SIS_NEW_CONFIG_COMPAT
#endif
#endif /* CONFIG_COMPAT */
-#else /* 2.4 */
-#define SIS_PCI_GET_CLASS(a, b) pci_find_class(a, b)
-#define SIS_PCI_GET_DEVICE(a,b,c) pci_find_device(a,b,c)
-#define SIS_PCI_GET_SLOT(a,b) pci_find_slot(a,b)
-#define SIS_PCI_PUT_DEVICE(a)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19)
-#ifdef __x86_64__ /* Shouldn't we check for CONFIG_IA32_EMULATION here? */
-#include <asm/ioctl32.h>
-#define SIS_OLD_CONFIG_COMPAT
-#endif
-#endif
-#endif /* 2.4 */
+
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
#define SIS_IOTYPE1 void __iomem
#define SIS_IOTYPE2 __iomem
@@ -498,26 +478,8 @@ struct sis_video_info {
struct fb_var_screeninfo default_var;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
struct fb_fix_screeninfo sisfb_fix;
u32 pseudo_palette[17];
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- struct display sis_disp;
- struct display_switch sisfb_sw;
- struct {
- u16 red, green, blue, pad;
- } sis_palette[256];
- union {
-#ifdef FBCON_HAS_CFB16
- u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
- u32 cfb32[16];
-#endif
- } sis_fbcon_cmap;
-#endif
struct sisfb_monitor {
u16 hmin;
@@ -538,10 +500,6 @@ struct sis_video_info {
int mni; /* Mode number index */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- int currcon;
-#endif
-
unsigned long video_size;
unsigned long video_base;
unsigned long mmio_size;
@@ -578,9 +536,6 @@ struct sis_video_info {
int sisfb_tvplug;
int sisfb_tvstd;
int sisfb_nocrt2rate;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- int sisfb_inverse;
-#endif
u32 heapstart; /* offset */
SIS_IOTYPE1 *sisfb_heap_start; /* address */
@@ -646,9 +601,7 @@ struct sis_video_info {
int modechanged;
unsigned char modeprechange;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
u8 sisfb_lastrates[128];
-#endif
int newrom;
int haveXGIROM;
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 01197d7..a30e1e1 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -37,7 +37,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/string.h>
@@ -1948,7 +1947,7 @@ sisfb_get_northbridge(int basechipid)
default: return NULL;
}
for(i = 0; i < nbridgenum; i++) {
- if((pdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI,
+ if((pdev = pci_get_device(PCI_VENDOR_ID_SI,
nbridgeids[nbridgeidx+i], NULL)))
break;
}
@@ -4613,9 +4612,9 @@ sisfb_find_host_bridge(struct sis_video_info *ivideo, struct pci_dev *mypdev,
unsigned short temp;
int ret = 0;
- while((pdev = SIS_PCI_GET_CLASS(PCI_CLASS_BRIDGE_HOST, pdev))) {
+ while((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST, pdev))) {
temp = pdev->vendor;
- SIS_PCI_PUT_DEVICE(pdev);
+ pci_dev_put(pdev);
if(temp == pcivendor) {
ret = 1;
break;
@@ -5154,24 +5153,24 @@ sisfb_post_xgi(struct pci_dev *pdev)
if(reg & 0x80) v2 |= 0x80;
v2 |= 0x01;
- if((mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0730, NULL))) {
- SIS_PCI_PUT_DEVICE(mypdev);
+ if((mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0730, NULL))) {
+ pci_dev_put(mypdev);
if(((v2 & 0x06) == 2) || ((v2 & 0x06) == 4))
v2 &= 0xf9;
v2 |= 0x08;
v1 &= 0xfe;
} else {
- mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0735, NULL);
+ mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0735, NULL);
if(!mypdev)
- mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0645, NULL);
+ mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0645, NULL);
if(!mypdev)
- mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0650, NULL);
+ mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0650, NULL);
if(mypdev) {
pci_read_config_dword(mypdev, 0x94, &regd);
regd &= 0xfffffeff;
pci_write_config_dword(mypdev, 0x94, regd);
v1 &= 0xfe;
- SIS_PCI_PUT_DEVICE(mypdev);
+ pci_dev_put(mypdev);
} else if(sisfb_find_host_bridge(ivideo, pdev, PCI_VENDOR_ID_SI)) {
v1 &= 0xfe;
} else if(sisfb_find_host_bridge(ivideo, pdev, 0x1106) ||
@@ -5194,13 +5193,13 @@ sisfb_post_xgi(struct pci_dev *pdev)
if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) )
setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01);
- if((mypdev = SIS_PCI_GET_DEVICE(0x10de, 0x01e0, NULL))) {
+ if((mypdev = pci_get_device(0x10de, 0x01e0, NULL))) {
/* TODO: set CR5f &0xf1 | 0x01 for version 6570
* of nforce 2 ROM
*/
if(0)
setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01);
- SIS_PCI_PUT_DEVICE(mypdev);
+ pci_dev_put(mypdev);
}
}
@@ -5236,9 +5235,9 @@ sisfb_post_xgi(struct pci_dev *pdev)
setSISIDXREG(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f);
setSISIDXREG(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f);
v1 = bios[0x501];
- if((mypdev = SIS_PCI_GET_DEVICE(0x8086, 0x2530, NULL))) {
+ if((mypdev = pci_get_device(0x8086, 0x2530, NULL))) {
v1 = 0xf0;
- SIS_PCI_PUT_DEVICE(mypdev);
+ pci_dev_put(mypdev);
}
outSISIDXREG(SISCR, 0x77, v1);
}
@@ -5947,7 +5946,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if(!ivideo->sisvga_enabled) {
if(pci_enable_device(pdev)) {
- if(ivideo->nbridge) SIS_PCI_PUT_DEVICE(ivideo->nbridge);
+ if(ivideo->nbridge) pci_dev_put(ivideo->nbridge);
pci_set_drvdata(pdev, NULL);
kfree(sis_fb_info);
return -EIO;
@@ -5974,7 +5973,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
"requiring Chrontel/GPIO setup\n",
mychswtable[i].vendorName,
mychswtable[i].cardName);
- ivideo->lpcdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0008, NULL);
+ ivideo->lpcdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0008, NULL);
break;
}
i++;
@@ -5984,7 +5983,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
#ifdef CONFIG_FB_SIS_315
if((ivideo->chip == SIS_760) && (ivideo->nbridge)) {
- ivideo->lpcdev = SIS_PCI_GET_SLOT(ivideo->nbridge->bus, (2 << 3));
+ ivideo->lpcdev = pci_get_slot(ivideo->nbridge->bus, (2 << 3));
}
#endif
@@ -6149,9 +6148,9 @@ error_1: release_mem_region(ivideo->video_base, ivideo->video_size);
error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
error_3: vfree(ivideo->bios_abase);
if(ivideo->lpcdev)
- SIS_PCI_PUT_DEVICE(ivideo->lpcdev);
+ pci_dev_put(ivideo->lpcdev);
if(ivideo->nbridge)
- SIS_PCI_PUT_DEVICE(ivideo->nbridge);
+ pci_dev_put(ivideo->nbridge);
pci_set_drvdata(pdev, NULL);
if(!ivideo->sisvga_enabled)
pci_disable_device(pdev);
@@ -6331,70 +6330,6 @@ error_3: vfree(ivideo->bios_abase);
sisfb_set_vparms(ivideo);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-
- /* ---------------- For 2.4: Now switch the mode ------------------ */
-
- printk(KERN_INFO "sisfb: Setting mode %dx%dx%d (%dHz)\n",
- ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
- ivideo->refresh_rate);
-
- /* Determine whether or not acceleration is to be
- * used. Need to know before pre/post_set_mode()
- */
- ivideo->accel = 0;
- ivideo->default_var.accel_flags &= ~FB_ACCELF_TEXT;
- if(ivideo->sisfb_accel) {
- ivideo->accel = -1;
- ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
- }
-
- /* Now switch the mode */
- sisfb_pre_setmode(ivideo);
-
- if(SiSSetMode(&ivideo->SiS_Pr, ivideo->mode_no) == 0) {
- printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n",
- ivideo->mode_no);
- ret = -EINVAL;
- iounmap(ivideo->mmio_vbase);
- goto error_0;
- }
-
- outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
-
- sisfb_post_setmode(ivideo);
-
- /* Maximize regardless of sisfb_max at startup */
- ivideo->default_var.yres_virtual = 32767;
-
- /* Force reset of x virtual in crtc_to_var */
- ivideo->default_var.xres_virtual = 0;
-
- /* Copy mode timing to var */
- sisfb_crtc_to_var(ivideo, &ivideo->default_var);
-
- /* Find out about screen pitch */
- sisfb_calc_pitch(ivideo, &ivideo->default_var);
- sisfb_set_pitch(ivideo);
-
- /* Init the accelerator (does nothing currently) */
- sisfb_initaccel(ivideo);
-
- /* Init some fbinfo entries */
- sis_fb_info->node = -1;
- sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
- sis_fb_info->fbops = &sisfb_ops;
- sis_fb_info->disp = &ivideo->sis_disp;
- sis_fb_info->blank = &sisfb_blank;
- sis_fb_info->switch_con = &sisfb_switch;
- sis_fb_info->updatevar = &sisfb_update_var;
- sis_fb_info->changevar = NULL;
- strcpy(sis_fb_info->fontname, sisfb_fontname);
-
- sisfb_set_disp(-1, &ivideo->default_var, sis_fb_info);
-
-#else /* --------- For 2.6: Setup a somewhat sane default var ------------ */
-
printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
ivideo->refresh_rate);
@@ -6454,7 +6389,6 @@ error_3: vfree(ivideo->bios_abase);
sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0);
-#endif /* 2.6 */
printk(KERN_DEBUG "sisfb: Initial vbflags 0x%x\n", (int)ivideo->vbflags);
@@ -6564,10 +6498,10 @@ static void __devexit sisfb_remove(struct pci_dev *pdev)
vfree(ivideo->bios_abase);
if(ivideo->lpcdev)
- SIS_PCI_PUT_DEVICE(ivideo->lpcdev);
+ pci_dev_put(ivideo->lpcdev);
if(ivideo->nbridge)
- SIS_PCI_PUT_DEVICE(ivideo->nbridge);
+ pci_dev_put(ivideo->nbridge);
#ifdef CONFIG_MTRR
/* Release MTRR region */
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index bb96cb6..842b5cd 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -51,6 +51,7 @@
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
+#include <linux/pci.h>
/*
* This is just simple sample code.
@@ -60,6 +61,11 @@
*/
/*
+ * Driver data
+ */
+static char *mode_option __devinitdata;
+
+/*
* If your driver supports multiple boards, you should make the
* below data types arrays, or allocate them dynamically (using kmalloc()).
*/
@@ -78,7 +84,7 @@ struct xxx_par;
* if we don't use modedb. If we do use modedb see xxxfb_init how to use it
* to get a fb_var_screeninfo. Otherwise define a default var as well.
*/
-static struct fb_fix_screeninfo xxxfb_fix __initdata = {
+static struct fb_fix_screeninfo xxxfb_fix __devinitdata = {
.id = "FB's name",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -142,7 +148,7 @@ int xxxfb_setup(char*);
*
* Returns negative errno on error, or zero on success.
*/
-static int xxxfb_open(const struct fb_info *info, int user)
+static int xxxfb_open(struct fb_info *info, int user)
{
return 0;
}
@@ -161,7 +167,7 @@ static int xxxfb_open(const struct fb_info *info, int user)
*
* Returns negative errno on error, or zero on success.
*/
-static int xxxfb_release(const struct fb_info *info, int user)
+static int xxxfb_release(struct fb_info *info, int user)
{
return 0;
}
@@ -278,7 +284,7 @@ static int xxxfb_set_par(struct fb_info *info)
*/
static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
- const struct fb_info *info)
+ struct fb_info *info)
{
if (regno >= 256) /* no. of hw registers */
return -EINVAL;
@@ -416,7 +422,7 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
* Returns negative errno on error, or zero on success.
*/
static int xxxfb_pan_display(struct fb_var_screeninfo *var,
- const struct fb_info *info)
+ struct fb_info *info)
{
/*
* If your hardware does not support panning, _do_ _not_ implement this
@@ -454,7 +460,7 @@ static int xxxfb_pan_display(struct fb_var_screeninfo *var,
* Return !0 for any modes that are unimplemented.
*
*/
-static int xxxfb_blank(int blank_mode, const struct fb_info *info)
+static int xxxfb_blank(int blank_mode, struct fb_info *info)
{
/* ... */
return 0;
@@ -483,7 +489,7 @@ static int xxxfb_blank(int blank_mode, const struct fb_info *info)
* depending on the rastering operation with the value of color which
* is in the current color depth format.
*/
-void xxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region)
+void xxxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region)
{
/* Meaning of struct fb_fillrect
*
@@ -623,19 +629,6 @@ void xxxfb_rotate(struct fb_info *info, int angle)
}
/**
- * xxxfb_poll - NOT a required function. The purpose of this
- * function is to provide a way for some process
- * to wait until a specific hardware event occurs
- * for the framebuffer device.
- *
- * @info: frame buffer structure that represents a single frame buffer
- * @wait: poll table where we store process that await a event.
- */
-void xxxfb_poll(struct fb_info *info, poll_table *wait)
-{
-}
-
-/**
* xxxfb_sync - NOT a required function. Normally the accel engine
* for a graphics card take a specific amount of time.
* Often we have to wait for the accelerator to finish
@@ -647,21 +640,49 @@ void xxxfb_poll(struct fb_info *info, poll_table *wait)
* If the driver has implemented its own hardware-based drawing function,
* implementing this function is highly recommended.
*/
-void xxxfb_sync(struct fb_info *info)
+int xxxfb_sync(struct fb_info *info)
{
+ return 0;
}
/*
+ * Frame buffer operations
+ */
+
+static struct fb_ops xxxfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_open = xxxfb_open,
+ .fb_read = xxxfb_read,
+ .fb_write = xxxfb_write,
+ .fb_release = xxxfb_release,
+ .fb_check_var = xxxfb_check_var,
+ .fb_set_par = xxxfb_set_par,
+ .fb_setcolreg = xxxfb_setcolreg,
+ .fb_blank = xxxfb_blank,
+ .fb_pan_display = xxxfb_pan_display,
+ .fb_fillrect = xxxfb_fillrect, /* Needed !!! */
+ .fb_copyarea = xxxfb_copyarea, /* Needed !!! */
+ .fb_imageblit = xxxfb_imageblit, /* Needed !!! */
+ .fb_cursor = xxxfb_cursor, /* Optional !!! */
+ .fb_rotate = xxxfb_rotate,
+ .fb_sync = xxxfb_sync,
+ .fb_ioctl = xxxfb_ioctl,
+ .fb_mmap = xxxfb_mmap,
+};
+
+/* ------------------------------------------------------------------------- */
+
+ /*
* Initialization
*/
/* static int __init xxfb_probe (struct device *device) -- for platform devs */
-static int __init xxxfb_probe(struct pci_dev *dev,
- const_struct pci_device_id *ent)
+static int __devinit xxxfb_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
{
struct fb_info *info;
struct xxx_par *par;
- struct device = &dev->dev; /* for pci drivers */
+ struct device* device = &dev->dev; /* for pci drivers */
int cmap_len, retval;
/*
@@ -684,7 +705,7 @@ static int __init xxxfb_probe(struct pci_dev *dev,
info->screen_base = framebuffer_virtual_memory;
info->fbops = &xxxfb_ops;
info->fix = xxxfb_fix; /* this will be the only time xxxfb_fix will be
- * used, so mark it as __initdata
+ * used, so mark it as __devinitdata
*/
info->pseudo_palette = pseudo_palette; /* The pseudopalette is an
* 16-member array
@@ -760,7 +781,7 @@ static int __init xxxfb_probe(struct pci_dev *dev,
*
* NOTE: This field is currently unused.
*/
- info->pixmap.scan_align = 32
+ info->pixmap.scan_align = 32;
/***************************** End optional stage ***************************/
/*
@@ -770,13 +791,13 @@ static int __init xxxfb_probe(struct pci_dev *dev,
if (!mode_option)
mode_option = "640x480@60";
- retval = fb_find_mode(info->var, info, mode_option, NULL, 0, NULL, 8);
+ retval = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
if (!retval || retval == 4)
return -EINVAL;
/* This has to been done !!! */
- fb_alloc_cmap(info->cmap, cmap_len, 0);
+ fb_alloc_cmap(&info->cmap, cmap_len, 0);
/*
* The following is done in the case of having hardware with a static
@@ -811,34 +832,77 @@ static int __init xxxfb_probe(struct pci_dev *dev,
/*
* Cleanup
*/
-/* static void __exit xxxfb_remove(struct device *device) */
-static void __exit xxxfb_remove(struct pci_dev *dev)
+/* static void __devexit xxxfb_remove(struct device *device) */
+static void __devexit xxxfb_remove(struct pci_dev *dev)
{
- struct fb_info *info = pci_get_drv_data(dev);
- /* or dev_get_drv_data(device); */
+ struct fb_info *info = pci_get_drvdata(dev);
+ /* or dev_get_drvdata(device); */
if (info) {
unregister_framebuffer(info);
- fb_dealloc_cmap(&info.cmap);
+ fb_dealloc_cmap(&info->cmap);
/* ... */
framebuffer_release(info);
}
+}
+
+#ifdef CONFIG_PCI
+#ifdef CONFIG_PM
+/**
+ * xxxfb_suspend - Optional but recommended function. Suspend the device.
+ * @dev: PCI device
+ * @msg: the suspend event code.
+ *
+ * See Documentation/power/devices.txt for more information
+ */
+static int xxxfb_suspend(struct pci_dev *dev, pm_message_t msg)
+{
+ struct fb_info *info = pci_get_drvdata(dev);
+ struct xxxfb_par *par = info->par;
+
+ /* suspend here */
+ return 0;
+}
+
+/**
+ * xxxfb_resume - Optional but recommended function. Resume the device.
+ * @dev: PCI device
+ *
+ * See Documentation/power/devices.txt for more information
+ */
+static int xxxfb_resume(struct pci_dev *dev)
+{
+ struct fb_info *info = pci_get_drvdata(dev);
+ struct xxxfb_par *par = info->par;
+ /* resume here */
return 0;
}
+#else
+#define xxxfb_suspend NULL
+#define xxxfb_resume NULL
+#endif /* CONFIG_PM */
+
+static struct pci_device_id xxxfb_id_table[] = {
+ { PCI_VENDOR_ID_XXX, PCI_DEVICE_ID_XXX,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
+ PCI_CLASS_MASK, 0 },
+ { 0, }
+};
-#if CONFIG_PCI
/* For PCI drivers */
static struct pci_driver xxxfb_driver = {
.name = "xxxfb",
- .id_table = xxxfb_devices,
+ .id_table = xxxfb_id_table,
.probe = xxxfb_probe,
.remove = __devexit_p(xxxfb_remove),
- .suspend = xxxfb_suspend, /* optional */
- .resume = xxxfb_resume, /* optional */
+ .suspend = xxxfb_suspend, /* optional but recommended */
+ .resume = xxxfb_resume, /* optional but recommended */
};
-static int __init xxxfb_init(void)
+MODULE_DEVICE_TABLE(pci, xxxfb_id_table);
+
+int __init xxxfb_init(void)
{
/*
* For kernel boot options (in 'video=xxxfb:<options>' format)
@@ -858,16 +922,53 @@ static void __exit xxxfb_exit(void)
{
pci_unregister_driver(&xxxfb_driver);
}
-#else
+#else /* non PCI, platform drivers */
#include <linux/platform_device.h>
/* for platform devices */
+
+#ifdef CONFIG_PM
+/**
+ * xxxfb_suspend - Optional but recommended function. Suspend the device.
+ * @dev: platform device
+ * @msg: the suspend event code.
+ *
+ * See Documentation/power/devices.txt for more information
+ */
+static int xxxfb_suspend(struct platform_device *dev, pm_message_t msg)
+{
+ struct fb_info *info = platform_get_drvdata(dev);
+ struct xxxfb_par *par = info->par;
+
+ /* suspend here */
+ return 0;
+}
+
+/**
+ * xxxfb_resume - Optional but recommended function. Resume the device.
+ * @dev: platform device
+ *
+ * See Documentation/power/devices.txt for more information
+ */
+static int xxxfb_resume(struct platform_dev *dev)
+{
+ struct fb_info *info = platform_get_drvdata(dev);
+ struct xxxfb_par *par = info->par;
+
+ /* resume here */
+ return 0;
+}
+#else
+#define xxxfb_suspend NULL
+#define xxxfb_resume NULL
+#endif /* CONFIG_PM */
+
static struct device_driver xxxfb_driver = {
.name = "xxxfb",
.bus = &platform_bus_type,
.probe = xxxfb_probe,
.remove = xxxfb_remove,
- .suspend = xxxfb_suspend, /* optional */
- .resume = xxxfb_resume, /* optional */
+ .suspend = xxxfb_suspend, /* optional but recommended */
+ .resume = xxxfb_resume, /* optional but recommended */
};
static struct platform_device xxxfb_device = {
@@ -903,8 +1004,9 @@ static void __exit xxxfb_exit(void)
platform_device_unregister(&xxxfb_device);
driver_unregister(&xxxfb_driver);
}
-#endif
+#endif /* CONFIG_PCI */
+#ifdef MODULE
/*
* Setup
*/
@@ -917,34 +1019,7 @@ int __init xxxfb_setup(char *options)
{
/* Parse user speficied options (`video=xxxfb:') */
}
-
-/* ------------------------------------------------------------------------- */
-
- /*
- * Frame buffer operations
- */
-
-static struct fb_ops xxxfb_ops = {
- .owner = THIS_MODULE,
- .fb_open = xxxfb_open,
- .fb_read = xxxfb_read,
- .fb_write = xxxfb_write,
- .fb_release = xxxfb_release,
- .fb_check_var = xxxfb_check_var,
- .fb_set_par = xxxfb_set_par,
- .fb_setcolreg = xxxfb_setcolreg,
- .fb_blank = xxxfb_blank,
- .fb_pan_display = xxxfb_pan_display,
- .fb_fillrect = xxxfb_fillrect, /* Needed !!! */
- .fb_copyarea = xxxfb_copyarea, /* Needed !!! */
- .fb_imageblit = xxxfb_imageblit, /* Needed !!! */
- .fb_cursor = xxxfb_cursor, /* Optional !!! */
- .fb_rotate = xxxfb_rotate,
- .fb_poll = xxxfb_poll,
- .fb_sync = xxxfb_sync,
- .fb_ioctl = xxxfb_ioctl,
- .fb_mmap = xxxfb_mmap,
-};
+#endif /* MODULE */
/* ------------------------------------------------------------------------- */
@@ -954,6 +1029,6 @@ static struct fb_ops xxxfb_ops = {
*/
module_init(xxxfb_init);
-module_exit(xxxfb_cleanup);
+module_exit(xxxfb_remove);
MODULE_LICENSE("GPL");
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index 0a44c44..c86df12 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -989,7 +989,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
((info->cmap.green[fg_col] & 0xFC) << 3) |
((info->cmap.blue[fg_col] & 0xF8) >> 3);
- dev_dbg(fbi->dev, "fgcol %08x, bgcol %08x\n", fg, bg);
+ dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg);
writel(bg, base + SM501_OFF_HWC_COLOR_1_2);
writel(fg, base + SM501_OFF_HWC_COLOR_3);
diff --git a/drivers/video/sunxvr2500.c b/drivers/video/sunxvr2500.c
new file mode 100644
index 0000000..4316c7f
--- /dev/null
+++ b/drivers/video/sunxvr2500.c
@@ -0,0 +1,277 @@
+/* s3d.c: Sun 3DLABS XVR-2500 et al. driver for sparc64 systems
+ *
+ * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
+
+struct s3d_info {
+ struct fb_info *info;
+ struct pci_dev *pdev;
+
+ char __iomem *fb_base;
+ unsigned long fb_base_phys;
+
+ struct device_node *of_node;
+
+ unsigned int width;
+ unsigned int height;
+ unsigned int depth;
+ unsigned int fb_size;
+
+ u32 pseudo_palette[256];
+};
+
+static int __devinit s3d_get_props(struct s3d_info *sp)
+{
+ sp->width = of_getintprop_default(sp->of_node, "width", 0);
+ sp->height = of_getintprop_default(sp->of_node, "height", 0);
+ sp->depth = of_getintprop_default(sp->of_node, "depth", 8);
+
+ if (!sp->width || !sp->height) {
+ printk(KERN_ERR "s3d: Critical properties missing for %s\n",
+ pci_name(sp->pdev));
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int s3d_setcolreg(unsigned regno,
+ unsigned red, unsigned green, unsigned blue,
+ unsigned transp, struct fb_info *info)
+{
+ u32 value;
+
+ if (regno >= 256)
+ return 1;
+
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+
+ value = (blue << 24) | (green << 16) | (red << 8);
+ ((u32 *)info->pseudo_palette)[regno] = value;
+
+ return 0;
+}
+
+static struct fb_ops s3d_ops = {
+ .owner = THIS_MODULE,
+ .fb_setcolreg = s3d_setcolreg,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+static int __devinit s3d_set_fbinfo(struct s3d_info *sp)
+{
+ struct fb_info *info = sp->info;
+ struct fb_var_screeninfo *var = &info->var;
+
+ info->flags = FBINFO_DEFAULT;
+ info->fbops = &s3d_ops;
+ info->screen_base = sp->fb_base;
+ info->screen_size = sp->fb_size;
+
+ info->pseudo_palette = sp->pseudo_palette;
+
+ /* Fill fix common fields */
+ strlcpy(info->fix.id, "s3d", sizeof(info->fix.id));
+ info->fix.smem_start = sp->fb_base_phys;
+ info->fix.smem_len = sp->fb_size;
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ if (sp->depth == 32 || sp->depth == 24)
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ else
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+ var->xres = sp->width;
+ var->yres = sp->height;
+ var->xres_virtual = var->xres;
+ var->yres_virtual = var->yres;
+ var->bits_per_pixel = sp->depth;
+
+ var->red.offset = 8;
+ var->red.length = 8;
+ var->green.offset = 16;
+ var->green.length = 8;
+ var->blue.offset = 24;
+ var->blue.length = 8;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+
+ if (fb_alloc_cmap(&info->cmap, 256, 0)) {
+ printk(KERN_ERR "s3d: Cannot allocate color map.\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int __devinit s3d_pci_register(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct fb_info *info;
+ struct s3d_info *sp;
+ int err;
+
+ err = pci_enable_device(pdev);
+ if (err < 0) {
+ printk(KERN_ERR "s3d: Cannot enable PCI device %s\n",
+ pci_name(pdev));
+ goto err_out;
+ }
+
+ info = framebuffer_alloc(sizeof(struct s3d_info), &pdev->dev);
+ if (!info) {
+ printk(KERN_ERR "s3d: Cannot allocate fb_info\n");
+ err = -ENOMEM;
+ goto err_disable;
+ }
+
+ sp = info->par;
+ sp->info = info;
+ sp->pdev = pdev;
+ sp->of_node = pci_device_to_OF_node(pdev);
+ if (!sp->of_node) {
+ printk(KERN_ERR "s3d: Cannot find OF node of %s\n",
+ pci_name(pdev));
+ err = -ENODEV;
+ goto err_release_fb;
+ }
+
+ sp->fb_base_phys = pci_resource_start (pdev, 1);
+
+ err = pci_request_region(pdev, 1, "s3d framebuffer");
+ if (err < 0) {
+ printk("s3d: Cannot request region 1 for %s\n",
+ pci_name(pdev));
+ goto err_release_fb;
+ }
+
+ err = s3d_get_props(sp);
+ if (err)
+ goto err_release_pci;
+
+ /* XXX 'linebytes' is often wrong, it is equal to the width
+ * XXX with depth of 32 on my XVR-2500 which is clearly not
+ * XXX right. So we don't try to use it.
+ */
+ switch (sp->depth) {
+ case 8:
+ info->fix.line_length = sp->width;
+ break;
+ case 16:
+ info->fix.line_length = sp->width * 2;
+ break;
+ case 24:
+ info->fix.line_length = sp->width * 3;
+ break;
+ case 32:
+ info->fix.line_length = sp->width * 4;
+ break;
+ }
+ sp->fb_size = info->fix.line_length * sp->height;
+
+ sp->fb_base = ioremap(sp->fb_base_phys, sp->fb_size);
+ if (!sp->fb_base)
+ goto err_release_pci;
+
+ err = s3d_set_fbinfo(sp);
+ if (err)
+ goto err_unmap_fb;
+
+ pci_set_drvdata(pdev, info);
+
+ printk("s3d: Found device at %s\n", pci_name(pdev));
+
+ err = register_framebuffer(info);
+ if (err < 0) {
+ printk(KERN_ERR "s3d: Could not register framebuffer %s\n",
+ pci_name(pdev));
+ goto err_unmap_fb;
+ }
+
+ return 0;
+
+err_unmap_fb:
+ iounmap(sp->fb_base);
+
+err_release_pci:
+ pci_release_region(pdev, 1);
+
+err_release_fb:
+ framebuffer_release(info);
+
+err_disable:
+ pci_disable_device(pdev);
+
+err_out:
+ return err;
+}
+
+static void __devexit s3d_pci_unregister(struct pci_dev *pdev)
+{
+ struct fb_info *info = pci_get_drvdata(pdev);
+ struct s3d_info *sp = info->par;
+
+ unregister_framebuffer(info);
+
+ iounmap(sp->fb_base);
+
+ pci_release_region(pdev, 1);
+
+ framebuffer_release(info);
+
+ pci_disable_device(pdev);
+}
+
+static struct pci_device_id s3d_pci_table[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002c), },
+ { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002d), },
+ { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002e), },
+ { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002f), },
+ { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x0030), },
+ { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x0031), },
+ { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x0032), },
+ { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x0033), },
+ { 0, }
+};
+
+static struct pci_driver s3d_driver = {
+ .name = "s3d",
+ .id_table = s3d_pci_table,
+ .probe = s3d_pci_register,
+ .remove = __devexit_p(s3d_pci_unregister),
+};
+
+static int __init s3d_init(void)
+{
+ if (fb_get_options("s3d", NULL))
+ return -ENODEV;
+
+ return pci_register_driver(&s3d_driver);
+}
+
+static void __exit s3d_exit(void)
+{
+ pci_unregister_driver(&s3d_driver);
+}
+
+module_init(s3d_init);
+module_exit(s3d_exit);
+
+MODULE_DESCRIPTION("framebuffer driver for Sun XVR-2500 graphics");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c
new file mode 100644
index 0000000..08880a6
--- /dev/null
+++ b/drivers/video/sunxvr500.c
@@ -0,0 +1,443 @@
+/* sunxvr500.c: Sun 3DLABS XVR-500 Expert3D driver for sparc64 systems
+ *
+ * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
+
+/* XXX This device has a 'dev-comm' property which aparently is
+ * XXX a pointer into the openfirmware's address space which is
+ * XXX a shared area the kernel driver can use to keep OBP
+ * XXX informed about the current resolution setting. The idea
+ * XXX is that the kernel can change resolutions, and as long
+ * XXX as the values in the 'dev-comm' area are accurate then
+ * XXX OBP can still render text properly to the console.
+ * XXX
+ * XXX I'm still working out the layout of this and whether there
+ * XXX are any signatures we need to look for etc.
+ */
+struct e3d_info {
+ struct fb_info *info;
+ struct pci_dev *pdev;
+
+ spinlock_t lock;
+
+ char __iomem *fb_base;
+ unsigned long fb_base_phys;
+
+ unsigned long fb8_buf_diff;
+ unsigned long regs_base_phys;
+
+ void __iomem *ramdac;
+
+ struct device_node *of_node;
+
+ unsigned int width;
+ unsigned int height;
+ unsigned int depth;
+ unsigned int fb_size;
+
+ u32 fb_base_reg;
+ u32 fb8_0_off;
+ u32 fb8_1_off;
+
+ u32 pseudo_palette[256];
+};
+
+static int __devinit e3d_get_props(struct e3d_info *ep)
+{
+ ep->width = of_getintprop_default(ep->of_node, "width", 0);
+ ep->height = of_getintprop_default(ep->of_node, "height", 0);
+ ep->depth = of_getintprop_default(ep->of_node, "depth", 8);
+
+ if (!ep->width || !ep->height) {
+ printk(KERN_ERR "e3d: Critical properties missing for %s\n",
+ pci_name(ep->pdev));
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* My XVR-500 comes up, at 1280x768 and a FB base register value of
+ * 0x04000000, the following video layout register values:
+ *
+ * RAMDAC_VID_WH 0x03ff04ff
+ * RAMDAC_VID_CFG 0x1a0b0088
+ * RAMDAC_VID_32FB_0 0x04000000
+ * RAMDAC_VID_32FB_1 0x04800000
+ * RAMDAC_VID_8FB_0 0x05000000
+ * RAMDAC_VID_8FB_1 0x05200000
+ * RAMDAC_VID_XXXFB 0x05400000
+ * RAMDAC_VID_YYYFB 0x05c00000
+ * RAMDAC_VID_ZZZFB 0x05e00000
+ */
+/* Video layout registers */
+#define RAMDAC_VID_WH 0x00000070UL /* (height-1)<<16 | (width-1) */
+#define RAMDAC_VID_CFG 0x00000074UL /* 0x1a000088|(linesz_log2<<16) */
+#define RAMDAC_VID_32FB_0 0x00000078UL /* PCI base 32bpp FB buffer 0 */
+#define RAMDAC_VID_32FB_1 0x0000007cUL /* PCI base 32bpp FB buffer 1 */
+#define RAMDAC_VID_8FB_0 0x00000080UL /* PCI base 8bpp FB buffer 0 */
+#define RAMDAC_VID_8FB_1 0x00000084UL /* PCI base 8bpp FB buffer 1 */
+#define RAMDAC_VID_XXXFB 0x00000088UL /* PCI base of XXX FB */
+#define RAMDAC_VID_YYYFB 0x0000008cUL /* PCI base of YYY FB */
+#define RAMDAC_VID_ZZZFB 0x00000090UL /* PCI base of ZZZ FB */
+
+/* CLUT registers */
+#define RAMDAC_INDEX 0x000000bcUL
+#define RAMDAC_DATA 0x000000c0UL
+
+static void e3d_clut_write(struct e3d_info *ep, int index, u32 val)
+{
+ void __iomem *ramdac = ep->ramdac;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ep->lock, flags);
+
+ writel(index, ramdac + RAMDAC_INDEX);
+ writel(val, ramdac + RAMDAC_DATA);
+
+ spin_unlock_irqrestore(&ep->lock, flags);
+}
+
+static int e3d_setcolreg(unsigned regno,
+ unsigned red, unsigned green, unsigned blue,
+ unsigned transp, struct fb_info *info)
+{
+ struct e3d_info *ep = info->par;
+ u32 red_8, green_8, blue_8;
+ u32 red_10, green_10, blue_10;
+ u32 value;
+
+ if (regno >= 256)
+ return 1;
+
+ red_8 = red >> 8;
+ green_8 = green >> 8;
+ blue_8 = blue >> 8;
+
+ value = (blue_8 << 24) | (green_8 << 16) | (red_8 << 8);
+ ((u32 *)info->pseudo_palette)[regno] = value;
+
+
+ red_10 = red >> 6;
+ green_10 = green >> 6;
+ blue_10 = blue >> 6;
+
+ value = (blue_10 << 20) | (green_10 << 10) | (red_10 << 0);
+ e3d_clut_write(ep, regno, value);
+
+ return 0;
+}
+
+/* XXX This is a bit of a hack. I can't figure out exactly how the
+ * XXX two 8bpp areas of the framebuffer work. I imagine there is
+ * XXX a WID attribute somewhere else in the framebuffer which tells
+ * XXX the ramdac which of the two 8bpp framebuffer regions to take
+ * XXX the pixel from. So, for now, render into both regions to make
+ * XXX sure the pixel shows up.
+ */
+static void e3d_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+ struct e3d_info *ep = info->par;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ep->lock, flags);
+ cfb_imageblit(info, image);
+ info->screen_base += ep->fb8_buf_diff;
+ cfb_imageblit(info, image);
+ info->screen_base -= ep->fb8_buf_diff;
+ spin_unlock_irqrestore(&ep->lock, flags);
+}
+
+static void e3d_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+{
+ struct e3d_info *ep = info->par;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ep->lock, flags);
+ cfb_fillrect(info, rect);
+ info->screen_base += ep->fb8_buf_diff;
+ cfb_fillrect(info, rect);
+ info->screen_base -= ep->fb8_buf_diff;
+ spin_unlock_irqrestore(&ep->lock, flags);
+}
+
+static void e3d_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+{
+ struct e3d_info *ep = info->par;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ep->lock, flags);
+ cfb_copyarea(info, area);
+ info->screen_base += ep->fb8_buf_diff;
+ cfb_copyarea(info, area);
+ info->screen_base -= ep->fb8_buf_diff;
+ spin_unlock_irqrestore(&ep->lock, flags);
+}
+
+static struct fb_ops e3d_ops = {
+ .owner = THIS_MODULE,
+ .fb_setcolreg = e3d_setcolreg,
+ .fb_fillrect = e3d_fillrect,
+ .fb_copyarea = e3d_copyarea,
+ .fb_imageblit = e3d_imageblit,
+};
+
+static int __devinit e3d_set_fbinfo(struct e3d_info *ep)
+{
+ struct fb_info *info = ep->info;
+ struct fb_var_screeninfo *var = &info->var;
+
+ info->flags = FBINFO_DEFAULT;
+ info->fbops = &e3d_ops;
+ info->screen_base = ep->fb_base;
+ info->screen_size = ep->fb_size;
+
+ info->pseudo_palette = ep->pseudo_palette;
+
+ /* Fill fix common fields */
+ strlcpy(info->fix.id, "e3d", sizeof(info->fix.id));
+ info->fix.smem_start = ep->fb_base_phys;
+ info->fix.smem_len = ep->fb_size;
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ if (ep->depth == 32 || ep->depth == 24)
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ else
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+
+ var->xres = ep->width;
+ var->yres = ep->height;
+ var->xres_virtual = var->xres;
+ var->yres_virtual = var->yres;
+ var->bits_per_pixel = ep->depth;
+
+ var->red.offset = 8;
+ var->red.length = 8;
+ var->green.offset = 16;
+ var->green.length = 8;
+ var->blue.offset = 24;
+ var->blue.length = 8;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+
+ if (fb_alloc_cmap(&info->cmap, 256, 0)) {
+ printk(KERN_ERR "e3d: Cannot allocate color map.\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static int __devinit e3d_pci_register(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct fb_info *info;
+ struct e3d_info *ep;
+ unsigned int line_length;
+ int err;
+
+ err = pci_enable_device(pdev);
+ if (err < 0) {
+ printk(KERN_ERR "e3d: Cannot enable PCI device %s\n",
+ pci_name(pdev));
+ goto err_out;
+ }
+
+ info = framebuffer_alloc(sizeof(struct e3d_info), &pdev->dev);
+ if (!info) {
+ printk(KERN_ERR "e3d: Cannot allocate fb_info\n");
+ err = -ENOMEM;
+ goto err_disable;
+ }
+
+ ep = info->par;
+ ep->info = info;
+ ep->pdev = pdev;
+ spin_lock_init(&ep->lock);
+ ep->of_node = pci_device_to_OF_node(pdev);
+ if (!ep->of_node) {
+ printk(KERN_ERR "e3d: Cannot find OF node of %s\n",
+ pci_name(pdev));
+ err = -ENODEV;
+ goto err_release_fb;
+ }
+
+ /* Read the PCI base register of the frame buffer, which we
+ * need in order to interpret the RAMDAC_VID_*FB* values in
+ * the ramdac correctly.
+ */
+ pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0,
+ &ep->fb_base_reg);
+ ep->fb_base_reg &= PCI_BASE_ADDRESS_MEM_MASK;
+
+ ep->regs_base_phys = pci_resource_start (pdev, 1);
+ err = pci_request_region(pdev, 1, "e3d regs");
+ if (err < 0) {
+ printk("e3d: Cannot request region 1 for %s\n",
+ pci_name(pdev));
+ goto err_release_fb;
+ }
+ ep->ramdac = ioremap(ep->regs_base_phys + 0x8000, 0x1000);
+ if (!ep->ramdac)
+ goto err_release_pci1;
+
+ ep->fb8_0_off = readl(ep->ramdac + RAMDAC_VID_8FB_0);
+ ep->fb8_0_off -= ep->fb_base_reg;
+
+ ep->fb8_1_off = readl(ep->ramdac + RAMDAC_VID_8FB_1);
+ ep->fb8_1_off -= ep->fb_base_reg;
+
+ ep->fb8_buf_diff = ep->fb8_1_off - ep->fb8_0_off;
+
+ ep->fb_base_phys = pci_resource_start (pdev, 0);
+ ep->fb_base_phys += ep->fb8_0_off;
+
+ err = pci_request_region(pdev, 0, "e3d framebuffer");
+ if (err < 0) {
+ printk("e3d: Cannot request region 0 for %s\n",
+ pci_name(pdev));
+ goto err_unmap_ramdac;
+ }
+
+ err = e3d_get_props(ep);
+ if (err)
+ goto err_release_pci0;
+
+ line_length = (readl(ep->ramdac + RAMDAC_VID_CFG) >> 16) & 0xff;
+ line_length = 1 << line_length;
+
+ switch (ep->depth) {
+ case 8:
+ info->fix.line_length = line_length;
+ break;
+ case 16:
+ info->fix.line_length = line_length * 2;
+ break;
+ case 24:
+ info->fix.line_length = line_length * 3;
+ break;
+ case 32:
+ info->fix.line_length = line_length * 4;
+ break;
+ }
+ ep->fb_size = info->fix.line_length * ep->height;
+
+ ep->fb_base = ioremap(ep->fb_base_phys, ep->fb_size);
+ if (!ep->fb_base)
+ goto err_release_pci0;
+
+ err = e3d_set_fbinfo(ep);
+ if (err)
+ goto err_unmap_fb;
+
+ pci_set_drvdata(pdev, info);
+
+ printk("e3d: Found device at %s\n", pci_name(pdev));
+
+ err = register_framebuffer(info);
+ if (err < 0) {
+ printk(KERN_ERR "e3d: Could not register framebuffer %s\n",
+ pci_name(pdev));
+ goto err_unmap_fb;
+ }
+
+ return 0;
+
+err_unmap_fb:
+ iounmap(ep->fb_base);
+
+err_release_pci0:
+ pci_release_region(pdev, 0);
+
+err_unmap_ramdac:
+ iounmap(ep->ramdac);
+
+err_release_pci1:
+ pci_release_region(pdev, 1);
+
+err_release_fb:
+ framebuffer_release(info);
+
+err_disable:
+ pci_disable_device(pdev);
+
+err_out:
+ return err;
+}
+
+static void __devexit e3d_pci_unregister(struct pci_dev *pdev)
+{
+ struct fb_info *info = pci_get_drvdata(pdev);
+ struct e3d_info *ep = info->par;
+
+ unregister_framebuffer(info);
+
+ iounmap(ep->ramdac);
+ iounmap(ep->fb_base);
+
+ pci_release_region(pdev, 0);
+ pci_release_region(pdev, 1);
+
+ framebuffer_release(info);
+
+ pci_disable_device(pdev);
+}
+
+static struct pci_device_id e3d_pci_table[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a0), },
+ { PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x7a2), },
+ { .vendor = PCI_VENDOR_ID_3DLABS,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_VENDOR_ID_3DLABS,
+ .subdevice = 0x0108,
+ },
+ { .vendor = PCI_VENDOR_ID_3DLABS,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_VENDOR_ID_3DLABS,
+ .subdevice = 0x0140,
+ },
+ { .vendor = PCI_VENDOR_ID_3DLABS,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_VENDOR_ID_3DLABS,
+ .subdevice = 0x1024,
+ },
+ { 0, }
+};
+
+static struct pci_driver e3d_driver = {
+ .name = "e3d",
+ .id_table = e3d_pci_table,
+ .probe = e3d_pci_register,
+ .remove = __devexit_p(e3d_pci_unregister),
+};
+
+static int __init e3d_init(void)
+{
+ if (fb_get_options("e3d", NULL))
+ return -ENODEV;
+
+ return pci_register_driver(&e3d_driver);
+}
+
+static void __exit e3d_exit(void)
+{
+ pci_unregister_driver(&e3d_driver);
+}
+
+module_init(e3d_init);
+module_exit(e3d_exit);
+
+MODULE_DESCRIPTION("framebuffer driver for Sun XVR-500 graphics");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/svgalib.c b/drivers/video/svgalib.c
index 68b30d9..079cdc9 100644
--- a/drivers/video/svgalib.c
+++ b/drivers/video/svgalib.c
@@ -194,7 +194,7 @@ void svga_dump_var(struct fb_var_screeninfo *var, int node)
void svga_settile(struct fb_info *info, struct fb_tilemap *map)
{
const u8 *font = map->data;
- u8* fb = (u8 *) info->screen_base;
+ u8 __iomem *fb = (u8 __iomem *)info->screen_base;
int i, c;
if ((map->width != 8) || (map->height != 16) ||
@@ -207,7 +207,8 @@ void svga_settile(struct fb_info *info, struct fb_tilemap *map)
fb += 2;
for (c = 0; c < map->length; c++) {
for (i = 0; i < map->height; i++) {
- fb[i * 4] = font[i];
+ fb_writeb(font[i], fb + i * 4);
+// fb[i * 4] = font[i];
}
fb += 128;
font += map->height;
@@ -221,8 +222,8 @@ void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area)
/* colstride is halved in this function because u16 are used */
int colstride = 1 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
int rowstride = colstride * (info->var.xres_virtual / 8);
- u16 *fb = (u16 *) info->screen_base;
- u16 *src, *dst;
+ u16 __iomem *fb = (u16 __iomem *) info->screen_base;
+ u16 __iomem *src, *dst;
if ((area->sy > area->dy) ||
((area->sy == area->dy) && (area->sx > area->dx))) {
@@ -239,10 +240,11 @@ void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area)
}
for (dy = 0; dy < area->height; dy++) {
- u16* src2 = src;
- u16* dst2 = dst;
+ u16 __iomem *src2 = src;
+ u16 __iomem *dst2 = dst;
for (dx = 0; dx < area->width; dx++) {
- *dst2 = *src2;
+ fb_writew(fb_readw(src2), dst2);
+// *dst2 = *src2;
src2 += colstride;
dst2 += colstride;
}
@@ -258,14 +260,14 @@ void svga_tilefill(struct fb_info *info, struct fb_tilerect *rect)
int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
int rowstride = colstride * (info->var.xres_virtual / 8);
int attr = (0x0F & rect->bg) << 4 | (0x0F & rect->fg);
- u8 *fb = (u8 *) info->screen_base;
+ u8 __iomem *fb = (u8 __iomem *)info->screen_base;
fb += rect->sx * colstride + rect->sy * rowstride;
for (dy = 0; dy < rect->height; dy++) {
- u8* fb2 = fb;
+ u8 __iomem *fb2 = fb;
for (dx = 0; dx < rect->width; dx++) {
- fb2[0] = rect->index;
- fb2[1] = attr;
+ fb_writeb(rect->index, fb2);
+ fb_writeb(attr, fb2 + 1);
fb2 += colstride;
}
fb += rowstride;
@@ -279,15 +281,15 @@ void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit)
int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
int rowstride = colstride * (info->var.xres_virtual / 8);
int attr = (0x0F & blit->bg) << 4 | (0x0F & blit->fg);
- u8* fb = (u8 *) info->screen_base;
+ u8 __iomem *fb = (u8 __iomem *)info->screen_base;
fb += blit->sx * colstride + blit->sy * rowstride;
i=0;
for (dy=0; dy < blit->height; dy ++) {
- u8* fb2 = fb;
+ u8 __iomem *fb2 = fb;
for (dx = 0; dx < blit->width; dx ++) {
- fb2[0] = blit->indices[i];
- fb2[1] = attr;
+ fb_writeb(blit->indices[i], fb2);
+ fb_writeb(attr, fb2 + 1);
fb2 += colstride;
i ++;
if (i == blit->length) return;
@@ -340,6 +342,11 @@ void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
vga_wcrt(NULL, 0x0A, cs); /* set cursor start and enable it */
}
+int svga_get_tilemax(struct fb_info *info)
+{
+ return 256;
+}
+
/* ------------------------------------------------------------------------- */
@@ -621,6 +628,7 @@ EXPORT_SYMBOL(svga_tilecopy);
EXPORT_SYMBOL(svga_tilefill);
EXPORT_SYMBOL(svga_tileblit);
EXPORT_SYMBOL(svga_tilecursor);
+EXPORT_SYMBOL(svga_get_tilemax);
EXPORT_SYMBOL(svga_compute_pll);
EXPORT_SYMBOL(svga_check_timings);
diff --git a/drivers/video/syscopyarea.c b/drivers/video/syscopyarea.c
new file mode 100644
index 0000000..37af10a
--- /dev/null
+++ b/drivers/video/syscopyarea.c
@@ -0,0 +1,378 @@
+/*
+ * Generic Bit Block Transfer for frame buffers located in system RAM with
+ * packed pixels of any depth.
+ *
+ * Based almost entirely from cfbcopyarea.c (which is based almost entirely
+ * on Geert Uytterhoeven's copyarea routine)
+ *
+ * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+#include <linux/slab.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include "fb_draw.h"
+
+ /*
+ * Generic bitwise copy algorithm
+ */
+
+static void
+bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
+ int src_idx, int bits, unsigned n)
+{
+ unsigned long first, last;
+ int const shift = dst_idx-src_idx;
+ int left, right;
+
+ first = FB_SHIFT_HIGH(~0UL, dst_idx);
+ last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
+
+ if (!shift) {
+ /* Same alignment for source and dest */
+ if (dst_idx+n <= bits) {
+ /* Single word */
+ if (last)
+ first &= last;
+ *dst = comp(*src, *dst, first);
+ } else {
+ /* Multiple destination words */
+ /* Leading bits */
+ if (first != ~0UL) {
+ *dst = comp(*src, *dst, first);
+ dst++;
+ src++;
+ n -= bits - dst_idx;
+ }
+
+ /* Main chunk */
+ n /= bits;
+ while (n >= 8) {
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ n -= 8;
+ }
+ while (n--)
+ *dst++ = *src++;
+
+ /* Trailing bits */
+ if (last)
+ *dst = comp(*src, *dst, last);
+ }
+ } else {
+ unsigned long d0, d1;
+ int m;
+
+ /* Different alignment for source and dest */
+ right = shift & (bits - 1);
+ left = -shift & (bits - 1);
+
+ if (dst_idx+n <= bits) {
+ /* Single destination word */
+ if (last)
+ first &= last;
+ if (shift > 0) {
+ /* Single source word */
+ *dst = comp(*src >> right, *dst, first);
+ } else if (src_idx+n <= bits) {
+ /* Single source word */
+ *dst = comp(*src << left, *dst, first);
+ } else {
+ /* 2 source words */
+ d0 = *src++;
+ d1 = *src;
+ *dst = comp(d0 << left | d1 >> right, *dst,
+ first);
+ }
+ } else {
+ /* Multiple destination words */
+ /** We must always remember the last value read,
+ because in case SRC and DST overlap bitwise (e.g.
+ when moving just one pixel in 1bpp), we always
+ collect one full long for DST and that might
+ overlap with the current long from SRC. We store
+ this value in 'd0'. */
+ d0 = *src++;
+ /* Leading bits */
+ if (shift > 0) {
+ /* Single source word */
+ *dst = comp(d0 >> right, *dst, first);
+ dst++;
+ n -= bits - dst_idx;
+ } else {
+ /* 2 source words */
+ d1 = *src++;
+ *dst = comp(d0 << left | *dst >> right, *dst, first);
+ d0 = d1;
+ dst++;
+ n -= bits - dst_idx;
+ }
+
+ /* Main chunk */
+ m = n % bits;
+ n /= bits;
+ while (n >= 4) {
+ d1 = *src++;
+ *dst++ = d0 << left | d1 >> right;
+ d0 = d1;
+ d1 = *src++;
+ *dst++ = d0 << left | d1 >> right;
+ d0 = d1;
+ d1 = *src++;
+ *dst++ = d0 << left | d1 >> right;
+ d0 = d1;
+ d1 = *src++;
+ *dst++ = d0 << left | d1 >> right;
+ d0 = d1;
+ n -= 4;
+ }
+ while (n--) {
+ d1 = *src++;
+ *dst++ = d0 << left | d1 >> right;
+ d0 = d1;
+ }
+
+ /* Trailing bits */
+ if (last) {
+ if (m <= right) {
+ /* Single source word */
+ *dst = comp(d0 << left, *dst, last);
+ } else {
+ /* 2 source words */
+ d1 = *src;
+ *dst = comp(d0 << left | d1 >> right,
+ *dst, last);
+ }
+ }
+ }
+ }
+}
+
+ /*
+ * Generic bitwise copy algorithm, operating backward
+ */
+
+static void
+bitcpy_rev(unsigned long *dst, int dst_idx, const unsigned long *src,
+ int src_idx, int bits, unsigned n)
+{
+ unsigned long first, last;
+ int shift;
+
+ dst += (n-1)/bits;
+ src += (n-1)/bits;
+ if ((n-1) % bits) {
+ dst_idx += (n-1) % bits;
+ dst += dst_idx >> (ffs(bits) - 1);
+ dst_idx &= bits - 1;
+ src_idx += (n-1) % bits;
+ src += src_idx >> (ffs(bits) - 1);
+ src_idx &= bits - 1;
+ }
+
+ shift = dst_idx-src_idx;
+
+ first = FB_SHIFT_LOW(~0UL, bits - 1 - dst_idx);
+ last = ~(FB_SHIFT_LOW(~0UL, bits - 1 - ((dst_idx-n) % bits)));
+
+ if (!shift) {
+ /* Same alignment for source and dest */
+ if ((unsigned long)dst_idx+1 >= n) {
+ /* Single word */
+ if (last)
+ first &= last;
+ *dst = comp(*src, *dst, first);
+ } else {
+ /* Multiple destination words */
+
+ /* Leading bits */
+ if (first != ~0UL) {
+ *dst = comp(*src, *dst, first);
+ dst--;
+ src--;
+ n -= dst_idx+1;
+ }
+
+ /* Main chunk */
+ n /= bits;
+ while (n >= 8) {
+ *dst-- = *src--;
+ *dst-- = *src--;
+ *dst-- = *src--;
+ *dst-- = *src--;
+ *dst-- = *src--;
+ *dst-- = *src--;
+ *dst-- = *src--;
+ *dst-- = *src--;
+ n -= 8;
+ }
+ while (n--)
+ *dst-- = *src--;
+ /* Trailing bits */
+ if (last)
+ *dst = comp(*src, *dst, last);
+ }
+ } else {
+ /* Different alignment for source and dest */
+
+ int const left = -shift & (bits-1);
+ int const right = shift & (bits-1);
+
+ if ((unsigned long)dst_idx+1 >= n) {
+ /* Single destination word */
+ if (last)
+ first &= last;
+ if (shift < 0) {
+ /* Single source word */
+ *dst = comp(*src << left, *dst, first);
+ } else if (1+(unsigned long)src_idx >= n) {
+ /* Single source word */
+ *dst = comp(*src >> right, *dst, first);
+ } else {
+ /* 2 source words */
+ *dst = comp(*src >> right | *(src-1) << left,
+ *dst, first);
+ }
+ } else {
+ /* Multiple destination words */
+ /** We must always remember the last value read,
+ because in case SRC and DST overlap bitwise (e.g.
+ when moving just one pixel in 1bpp), we always
+ collect one full long for DST and that might
+ overlap with the current long from SRC. We store
+ this value in 'd0'. */
+ unsigned long d0, d1;
+ int m;
+
+ d0 = *src--;
+ /* Leading bits */
+ if (shift < 0) {
+ /* Single source word */
+ *dst = comp(d0 << left, *dst, first);
+ } else {
+ /* 2 source words */
+ d1 = *src--;
+ *dst = comp(d0 >> right | d1 << left, *dst,
+ first);
+ d0 = d1;
+ }
+ dst--;
+ n -= dst_idx+1;
+
+ /* Main chunk */
+ m = n % bits;
+ n /= bits;
+ while (n >= 4) {
+ d1 = *src--;
+ *dst-- = d0 >> right | d1 << left;
+ d0 = d1;
+ d1 = *src--;
+ *dst-- = d0 >> right | d1 << left;
+ d0 = d1;
+ d1 = *src--;
+ *dst-- = d0 >> right | d1 << left;
+ d0 = d1;
+ d1 = *src--;
+ *dst-- = d0 >> right | d1 << left;
+ d0 = d1;
+ n -= 4;
+ }
+ while (n--) {
+ d1 = *src--;
+ *dst-- = d0 >> right | d1 << left;
+ d0 = d1;
+ }
+
+ /* Trailing bits */
+ if (last) {
+ if (m <= left) {
+ /* Single source word */
+ *dst = comp(d0 >> right, *dst, last);
+ } else {
+ /* 2 source words */
+ d1 = *src;
+ *dst = comp(d0 >> right | d1 << left,
+ *dst, last);
+ }
+ }
+ }
+ }
+}
+
+void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area)
+{
+ u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
+ u32 height = area->height, width = area->width;
+ unsigned long const bits_per_line = p->fix.line_length*8u;
+ unsigned long *dst = NULL, *src = NULL;
+ int bits = BITS_PER_LONG, bytes = bits >> 3;
+ int dst_idx = 0, src_idx = 0, rev_copy = 0;
+
+ if (p->state != FBINFO_STATE_RUNNING)
+ return;
+
+ /* if the beginning of the target area might overlap with the end of
+ the source area, be have to copy the area reverse. */
+ if ((dy == sy && dx > sx) || (dy > sy)) {
+ dy += height;
+ sy += height;
+ rev_copy = 1;
+ }
+
+ /* split the base of the framebuffer into a long-aligned address and
+ the index of the first bit */
+ dst = src = (unsigned long *)((unsigned long)p->screen_base &
+ ~(bytes-1));
+ dst_idx = src_idx = 8*((unsigned long)p->screen_base & (bytes-1));
+ /* add offset of source and target area */
+ dst_idx += dy*bits_per_line + dx*p->var.bits_per_pixel;
+ src_idx += sy*bits_per_line + sx*p->var.bits_per_pixel;
+
+ if (p->fbops->fb_sync)
+ p->fbops->fb_sync(p);
+
+ if (rev_copy) {
+ while (height--) {
+ dst_idx -= bits_per_line;
+ src_idx -= bits_per_line;
+ dst += dst_idx >> (ffs(bits) - 1);
+ dst_idx &= (bytes - 1);
+ src += src_idx >> (ffs(bits) - 1);
+ src_idx &= (bytes - 1);
+ bitcpy_rev(dst, dst_idx, src, src_idx, bits,
+ width*p->var.bits_per_pixel);
+ }
+ } else {
+ while (height--) {
+ dst += dst_idx >> (ffs(bits) - 1);
+ dst_idx &= (bytes - 1);
+ src += src_idx >> (ffs(bits) - 1);
+ src_idx &= (bytes - 1);
+ bitcpy(dst, dst_idx, src, src_idx, bits,
+ width*p->var.bits_per_pixel);
+ dst_idx += bits_per_line;
+ src_idx += bits_per_line;
+ }
+ }
+}
+
+EXPORT_SYMBOL(sys_copyarea);
+
+MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
+MODULE_DESCRIPTION("Generic copyarea (sys-to-sys)");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/video/sysfillrect.c b/drivers/video/sysfillrect.c
new file mode 100644
index 0000000..a261e9e
--- /dev/null
+++ b/drivers/video/sysfillrect.c
@@ -0,0 +1,334 @@
+/*
+ * Generic fillrect for frame buffers in system RAM with packed pixels of
+ * any depth.
+ *
+ * Based almost entirely from cfbfillrect.c (which is based almost entirely
+ * on Geert Uytterhoeven's fillrect routine)
+ *
+ * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+#include <asm/types.h>
+#include "fb_draw.h"
+
+ /*
+ * Aligned pattern fill using 32/64-bit memory accesses
+ */
+
+static void
+bitfill_aligned(unsigned long *dst, int dst_idx, unsigned long pat,
+ unsigned n, int bits)
+{
+ unsigned long first, last;
+
+ if (!n)
+ return;
+
+ first = FB_SHIFT_HIGH(~0UL, dst_idx);
+ last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
+
+ if (dst_idx+n <= bits) {
+ /* Single word */
+ if (last)
+ first &= last;
+ *dst = comp(pat, *dst, first);
+ } else {
+ /* Multiple destination words */
+
+ /* Leading bits */
+ if (first!= ~0UL) {
+ *dst = comp(pat, *dst, first);
+ dst++;
+ n -= bits - dst_idx;
+ }
+
+ /* Main chunk */
+ n /= bits;
+ while (n >= 8) {
+ *dst++ = pat;
+ *dst++ = pat;
+ *dst++ = pat;
+ *dst++ = pat;
+ *dst++ = pat;
+ *dst++ = pat;
+ *dst++ = pat;
+ *dst++ = pat;
+ n -= 8;
+ }
+ while (n--)
+ *dst++ = pat;
+ /* Trailing bits */
+ if (last)
+ *dst = comp(pat, *dst, last);
+ }
+}
+
+
+ /*
+ * Unaligned generic pattern fill using 32/64-bit memory accesses
+ * The pattern must have been expanded to a full 32/64-bit value
+ * Left/right are the appropriate shifts to convert to the pattern to be
+ * used for the next 32/64-bit word
+ */
+
+static void
+bitfill_unaligned(unsigned long *dst, int dst_idx, unsigned long pat,
+ int left, int right, unsigned n, int bits)
+{
+ unsigned long first, last;
+
+ if (!n)
+ return;
+
+ first = FB_SHIFT_HIGH(~0UL, dst_idx);
+ last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
+
+ if (dst_idx+n <= bits) {
+ /* Single word */
+ if (last)
+ first &= last;
+ *dst = comp(pat, *dst, first);
+ } else {
+ /* Multiple destination words */
+ /* Leading bits */
+ if (first) {
+ *dst = comp(pat, *dst, first);
+ dst++;
+ pat = pat << left | pat >> right;
+ n -= bits - dst_idx;
+ }
+
+ /* Main chunk */
+ n /= bits;
+ while (n >= 4) {
+ *dst++ = pat;
+ pat = pat << left | pat >> right;
+ *dst++ = pat;
+ pat = pat << left | pat >> right;
+ *dst++ = pat;
+ pat = pat << left | pat >> right;
+ *dst++ = pat;
+ pat = pat << left | pat >> right;
+ n -= 4;
+ }
+ while (n--) {
+ *dst++ = pat;
+ pat = pat << left | pat >> right;
+ }
+
+ /* Trailing bits */
+ if (last)
+ *dst = comp(pat, *dst, first);
+ }
+}
+
+ /*
+ * Aligned pattern invert using 32/64-bit memory accesses
+ */
+static void
+bitfill_aligned_rev(unsigned long *dst, int dst_idx, unsigned long pat,
+ unsigned n, int bits)
+{
+ unsigned long val = pat;
+ unsigned long first, last;
+
+ if (!n)
+ return;
+
+ first = FB_SHIFT_HIGH(~0UL, dst_idx);
+ last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
+
+ if (dst_idx+n <= bits) {
+ /* Single word */
+ if (last)
+ first &= last;
+ *dst = comp(*dst ^ val, *dst, first);
+ } else {
+ /* Multiple destination words */
+ /* Leading bits */
+ if (first!=0UL) {
+ *dst = comp(*dst ^ val, *dst, first);
+ dst++;
+ n -= bits - dst_idx;
+ }
+
+ /* Main chunk */
+ n /= bits;
+ while (n >= 8) {
+ *dst++ ^= val;
+ *dst++ ^= val;
+ *dst++ ^= val;
+ *dst++ ^= val;
+ *dst++ ^= val;
+ *dst++ ^= val;
+ *dst++ ^= val;
+ *dst++ ^= val;
+ n -= 8;
+ }
+ while (n--)
+ *dst++ ^= val;
+ /* Trailing bits */
+ if (last)
+ *dst = comp(*dst ^ val, *dst, last);
+ }
+}
+
+
+ /*
+ * Unaligned generic pattern invert using 32/64-bit memory accesses
+ * The pattern must have been expanded to a full 32/64-bit value
+ * Left/right are the appropriate shifts to convert to the pattern to be
+ * used for the next 32/64-bit word
+ */
+
+static void
+bitfill_unaligned_rev(unsigned long *dst, int dst_idx, unsigned long pat,
+ int left, int right, unsigned n, int bits)
+{
+ unsigned long first, last;
+
+ if (!n)
+ return;
+
+ first = FB_SHIFT_HIGH(~0UL, dst_idx);
+ last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
+
+ if (dst_idx+n <= bits) {
+ /* Single word */
+ if (last)
+ first &= last;
+ *dst = comp(*dst ^ pat, *dst, first);
+ } else {
+ /* Multiple destination words */
+
+ /* Leading bits */
+ if (first != 0UL) {
+ *dst = comp(*dst ^ pat, *dst, first);
+ dst++;
+ pat = pat << left | pat >> right;
+ n -= bits - dst_idx;
+ }
+
+ /* Main chunk */
+ n /= bits;
+ while (n >= 4) {
+ *dst++ ^= pat;
+ pat = pat << left | pat >> right;
+ *dst++ ^= pat;
+ pat = pat << left | pat >> right;
+ *dst++ ^= pat;
+ pat = pat << left | pat >> right;
+ *dst++ ^= pat;
+ pat = pat << left | pat >> right;
+ n -= 4;
+ }
+ while (n--) {
+ *dst ^= pat;
+ pat = pat << left | pat >> right;
+ }
+
+ /* Trailing bits */
+ if (last)
+ *dst = comp(*dst ^ pat, *dst, last);
+ }
+}
+
+void sys_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
+{
+ unsigned long pat, fg;
+ unsigned long width = rect->width, height = rect->height;
+ int bits = BITS_PER_LONG, bytes = bits >> 3;
+ u32 bpp = p->var.bits_per_pixel;
+ unsigned long *dst;
+ int dst_idx, left;
+
+ if (p->state != FBINFO_STATE_RUNNING)
+ return;
+
+ if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
+ p->fix.visual == FB_VISUAL_DIRECTCOLOR )
+ fg = ((u32 *) (p->pseudo_palette))[rect->color];
+ else
+ fg = rect->color;
+
+ pat = pixel_to_pat( bpp, fg);
+
+ dst = (unsigned long *)((unsigned long)p->screen_base & ~(bytes-1));
+ dst_idx = ((unsigned long)p->screen_base & (bytes - 1))*8;
+ dst_idx += rect->dy*p->fix.line_length*8+rect->dx*bpp;
+ /* FIXME For now we support 1-32 bpp only */
+ left = bits % bpp;
+ if (p->fbops->fb_sync)
+ p->fbops->fb_sync(p);
+ if (!left) {
+ void (*fill_op32)(unsigned long *dst, int dst_idx,
+ unsigned long pat, unsigned n, int bits) =
+ NULL;
+
+ switch (rect->rop) {
+ case ROP_XOR:
+ fill_op32 = bitfill_aligned_rev;
+ break;
+ case ROP_COPY:
+ fill_op32 = bitfill_aligned;
+ break;
+ default:
+ printk( KERN_ERR "cfb_fillrect(): unknown rop, "
+ "defaulting to ROP_COPY\n");
+ fill_op32 = bitfill_aligned;
+ break;
+ }
+ while (height--) {
+ dst += dst_idx >> (ffs(bits) - 1);
+ dst_idx &= (bits - 1);
+ fill_op32(dst, dst_idx, pat, width*bpp, bits);
+ dst_idx += p->fix.line_length*8;
+ }
+ } else {
+ int right;
+ int r;
+ int rot = (left-dst_idx) % bpp;
+ void (*fill_op)(unsigned long *dst, int dst_idx,
+ unsigned long pat, int left, int right,
+ unsigned n, int bits) = NULL;
+
+ /* rotate pattern to correct start position */
+ pat = pat << rot | pat >> (bpp-rot);
+
+ right = bpp-left;
+ switch (rect->rop) {
+ case ROP_XOR:
+ fill_op = bitfill_unaligned_rev;
+ break;
+ case ROP_COPY:
+ fill_op = bitfill_unaligned;
+ break;
+ default:
+ printk(KERN_ERR "cfb_fillrect(): unknown rop, "
+ "defaulting to ROP_COPY\n");
+ fill_op = bitfill_unaligned;
+ break;
+ }
+ while (height--) {
+ dst += dst_idx >> (ffs(bits) - 1);
+ dst_idx &= (bits - 1);
+ fill_op(dst, dst_idx, pat, left, right,
+ width*bpp, bits);
+ r = (p->fix.line_length*8) % bpp;
+ pat = pat << (bpp-r) | pat >> r;
+ dst_idx += p->fix.line_length*8;
+ }
+ }
+}
+
+EXPORT_SYMBOL(sys_fillrect);
+
+MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
+MODULE_DESCRIPTION("Generic fill rectangle (sys-to-sys)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/sysimgblt.c b/drivers/video/sysimgblt.c
new file mode 100644
index 0000000..bd7e7e9
--- /dev/null
+++ b/drivers/video/sysimgblt.c
@@ -0,0 +1,291 @@
+/*
+ * Generic 1-bit or 8-bit source to 1-32 bit destination expansion
+ * for frame buffer located in system RAM with packed pixels of any depth.
+ *
+ * Based almost entirely on cfbimgblt.c
+ *
+ * Copyright (C) April 2007 Antonino Daplas <adaplas@pol.net>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+#include <asm/types.h>
+
+#define DEBUG
+
+#ifdef DEBUG
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt,__FUNCTION__,## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+static const u32 cfb_tab8[] = {
+#if defined(__BIG_ENDIAN)
+ 0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
+ 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
+ 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
+ 0xffff0000,0xffff00ff,0xffffff00,0xffffffff
+#elif defined(__LITTLE_ENDIAN)
+ 0x00000000,0xff000000,0x00ff0000,0xffff0000,
+ 0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
+ 0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
+ 0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
+#else
+#error FIXME: No endianness??
+#endif
+};
+
+static const u32 cfb_tab16[] = {
+#if defined(__BIG_ENDIAN)
+ 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
+#elif defined(__LITTLE_ENDIAN)
+ 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
+#else
+#error FIXME: No endianness??
+#endif
+};
+
+static const u32 cfb_tab32[] = {
+ 0x00000000, 0xffffffff
+};
+
+static void color_imageblit(const struct fb_image *image, struct fb_info *p,
+ void *dst1, u32 start_index, u32 pitch_index)
+{
+ /* Draw the penguin */
+ u32 *dst, *dst2;
+ u32 color = 0, val, shift;
+ int i, n, bpp = p->var.bits_per_pixel;
+ u32 null_bits = 32 - bpp;
+ u32 *palette = (u32 *) p->pseudo_palette;
+ const u8 *src = image->data;
+
+ dst2 = dst1;
+ for (i = image->height; i--; ) {
+ n = image->width;
+ dst = dst1;
+ shift = 0;
+ val = 0;
+
+ if (start_index) {
+ u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,
+ start_index));
+ val = *dst & start_mask;
+ shift = start_index;
+ }
+ while (n--) {
+ if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
+ p->fix.visual == FB_VISUAL_DIRECTCOLOR )
+ color = palette[*src];
+ else
+ color = *src;
+ color <<= FB_LEFT_POS(bpp);
+ val |= FB_SHIFT_HIGH(color, shift);
+ if (shift >= null_bits) {
+ *dst++ = val;
+
+ val = (shift == null_bits) ? 0 :
+ FB_SHIFT_LOW(color, 32 - shift);
+ }
+ shift += bpp;
+ shift &= (32 - 1);
+ src++;
+ }
+ if (shift) {
+ u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift);
+
+ *dst &= end_mask;
+ *dst |= val;
+ }
+ dst1 += p->fix.line_length;
+ if (pitch_index) {
+ dst2 += p->fix.line_length;
+ dst1 = (u8 *)((long)dst2 & ~(sizeof(u32) - 1));
+
+ start_index += pitch_index;
+ start_index &= 32 - 1;
+ }
+ }
+}
+
+static void slow_imageblit(const struct fb_image *image, struct fb_info *p,
+ void *dst1, u32 fgcolor, u32 bgcolor,
+ u32 start_index, u32 pitch_index)
+{
+ u32 shift, color = 0, bpp = p->var.bits_per_pixel;
+ u32 *dst, *dst2;
+ u32 val, pitch = p->fix.line_length;
+ u32 null_bits = 32 - bpp;
+ u32 spitch = (image->width+7)/8;
+ const u8 *src = image->data, *s;
+ u32 i, j, l;
+
+ dst2 = dst1;
+ fgcolor <<= FB_LEFT_POS(bpp);
+ bgcolor <<= FB_LEFT_POS(bpp);
+
+ for (i = image->height; i--; ) {
+ shift = val = 0;
+ l = 8;
+ j = image->width;
+ dst = dst1;
+ s = src;
+
+ /* write leading bits */
+ if (start_index) {
+ u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,start_index));
+ val = *dst & start_mask;
+ shift = start_index;
+ }
+
+ while (j--) {
+ l--;
+ color = (*s & (1 << l)) ? fgcolor : bgcolor;
+ val |= FB_SHIFT_HIGH(color, shift);
+
+ /* Did the bitshift spill bits to the next long? */
+ if (shift >= null_bits) {
+ *dst++ = val;
+ val = (shift == null_bits) ? 0 :
+ FB_SHIFT_LOW(color,32 - shift);
+ }
+ shift += bpp;
+ shift &= (32 - 1);
+ if (!l) { l = 8; s++; };
+ }
+
+ /* write trailing bits */
+ if (shift) {
+ u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift);
+
+ *dst &= end_mask;
+ *dst |= val;
+ }
+
+ dst1 += pitch;
+ src += spitch;
+ if (pitch_index) {
+ dst2 += pitch;
+ dst1 = (u8 *)((long)dst2 & ~(sizeof(u32) - 1));
+ start_index += pitch_index;
+ start_index &= 32 - 1;
+ }
+
+ }
+}
+
+/*
+ * fast_imageblit - optimized monochrome color expansion
+ *
+ * Only if: bits_per_pixel == 8, 16, or 32
+ * image->width is divisible by pixel/dword (ppw);
+ * fix->line_legth is divisible by 4;
+ * beginning and end of a scanline is dword aligned
+ */
+static void fast_imageblit(const struct fb_image *image, struct fb_info *p,
+ void *dst1, u32 fgcolor, u32 bgcolor)
+{
+ u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
+ u32 ppw = 32/bpp, spitch = (image->width + 7)/8;
+ u32 bit_mask, end_mask, eorx, shift;
+ const char *s = image->data, *src;
+ u32 *dst;
+ const u32 *tab = NULL;
+ int i, j, k;
+
+ switch (bpp) {
+ case 8:
+ tab = cfb_tab8;
+ break;
+ case 16:
+ tab = cfb_tab16;
+ break;
+ case 32:
+ default:
+ tab = cfb_tab32;
+ break;
+ }
+
+ for (i = ppw-1; i--; ) {
+ fgx <<= bpp;
+ bgx <<= bpp;
+ fgx |= fgcolor;
+ bgx |= bgcolor;
+ }
+
+ bit_mask = (1 << ppw) - 1;
+ eorx = fgx ^ bgx;
+ k = image->width/ppw;
+
+ for (i = image->height; i--; ) {
+ dst = dst1;
+ shift = 8;
+ src = s;
+
+ for (j = k; j--; ) {
+ shift -= ppw;
+ end_mask = tab[(*src >> shift) & bit_mask];
+ *dst++ = (end_mask & eorx) ^ bgx;
+ if (!shift) {
+ shift = 8;
+ src++;
+ }
+ }
+ dst1 += p->fix.line_length;
+ s += spitch;
+ }
+}
+
+void sys_imageblit(struct fb_info *p, const struct fb_image *image)
+{
+ u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
+ u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel;
+ u32 width = image->width;
+ u32 dx = image->dx, dy = image->dy;
+ void *dst1;
+
+ if (p->state != FBINFO_STATE_RUNNING)
+ return;
+
+ bitstart = (dy * p->fix.line_length * 8) + (dx * bpp);
+ start_index = bitstart & (32 - 1);
+ pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
+
+ bitstart /= 8;
+ bitstart &= ~(bpl - 1);
+ dst1 = (void __force *)p->screen_base + bitstart;
+
+ if (p->fbops->fb_sync)
+ p->fbops->fb_sync(p);
+
+ if (image->depth == 1) {
+ if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
+ p->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+ fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color];
+ bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color];
+ } else {
+ fgcolor = image->fg_color;
+ bgcolor = image->bg_color;
+ }
+
+ if (32 % bpp == 0 && !start_index && !pitch_index &&
+ ((width & (32/bpp-1)) == 0) &&
+ bpp >= 8 && bpp <= 32)
+ fast_imageblit(image, p, dst1, fgcolor, bgcolor);
+ else
+ slow_imageblit(image, p, dst1, fgcolor, bgcolor,
+ start_index, pitch_index);
+ } else
+ color_imageblit(image, p, dst1, start_index, pitch_index);
+}
+
+EXPORT_SYMBOL(sys_imageblit);
+
+MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
+MODULE_DESCRIPTION("1-bit/8-bit to 1-32 bit color expansion (sys-to-sys)");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 7478d0e..f0fde6e 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -5,27 +5,45 @@
* Copyright (C) 1997 Geert Uytterhoeven
* Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha
* Copyright (C) 2002 Richard Henderson
+ * Copyright (C) 2006 Maciej W. Rozycki
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
+#include <linux/bitrev.h>
#include <linux/delay.h>
-#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/errno.h>
#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
#include <linux/pci.h>
#include <linux/selection.h>
-#include <linux/bitrev.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/tc.h>
+
#include <asm/io.h>
+
#include <video/tgafb.h>
+#ifdef CONFIG_PCI
+#define TGA_BUS_PCI(dev) (dev->bus == &pci_bus_type)
+#else
+#define TGA_BUS_PCI(dev) 0
+#endif
+
+#ifdef CONFIG_TC
+#define TGA_BUS_TC(dev) (dev->bus == &tc_bus_type)
+#else
+#define TGA_BUS_TC(dev) 0
+#endif
+
/*
* Local functions.
*/
@@ -41,14 +59,19 @@ static void tgafb_init_fix(struct fb_info *);
static void tgafb_imageblit(struct fb_info *, const struct fb_image *);
static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *);
static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *);
+static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
-static int __devinit tgafb_pci_register(struct pci_dev *,
- const struct pci_device_id *);
-static void __devexit tgafb_pci_unregister(struct pci_dev *);
+static int __devinit tgafb_register(struct device *dev);
+static void __devexit tgafb_unregister(struct device *dev);
-static const char *mode_option = "640x480@60";
+static const char *mode_option;
+static const char *mode_option_pci = "640x480@60";
+static const char *mode_option_tc = "1280x1024@72";
+static struct pci_driver tgafb_pci_driver;
+static struct tc_driver tgafb_tc_driver;
+
/*
* Frame buffer operations
*/
@@ -59,15 +82,20 @@ static struct fb_ops tgafb_ops = {
.fb_set_par = tgafb_set_par,
.fb_setcolreg = tgafb_setcolreg,
.fb_blank = tgafb_blank,
+ .fb_pan_display = tgafb_pan_display,
.fb_fillrect = tgafb_fillrect,
.fb_copyarea = tgafb_copyarea,
.fb_imageblit = tgafb_imageblit,
};
+#ifdef CONFIG_PCI
/*
* PCI registration operations
*/
+static int __devinit tgafb_pci_register(struct pci_dev *,
+ const struct pci_device_id *);
+static void __devexit tgafb_pci_unregister(struct pci_dev *);
static struct pci_device_id const tgafb_pci_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA) },
@@ -75,13 +103,68 @@ static struct pci_device_id const tgafb_pci_table[] = {
};
MODULE_DEVICE_TABLE(pci, tgafb_pci_table);
-static struct pci_driver tgafb_driver = {
+static struct pci_driver tgafb_pci_driver = {
.name = "tgafb",
.id_table = tgafb_pci_table,
.probe = tgafb_pci_register,
.remove = __devexit_p(tgafb_pci_unregister),
};
+static int __devinit
+tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ return tgafb_register(&pdev->dev);
+}
+
+static void __devexit
+tgafb_pci_unregister(struct pci_dev *pdev)
+{
+ tgafb_unregister(&pdev->dev);
+}
+#endif /* CONFIG_PCI */
+
+#ifdef CONFIG_TC
+/*
+ * TC registration operations
+ */
+static int __devinit tgafb_tc_register(struct device *);
+static int __devexit tgafb_tc_unregister(struct device *);
+
+static struct tc_device_id const tgafb_tc_table[] = {
+ { "DEC ", "PMAGD-AA" },
+ { "DEC ", "PMAGD " },
+ { }
+};
+MODULE_DEVICE_TABLE(tc, tgafb_tc_table);
+
+static struct tc_driver tgafb_tc_driver = {
+ .id_table = tgafb_tc_table,
+ .driver = {
+ .name = "tgafb",
+ .bus = &tc_bus_type,
+ .probe = tgafb_tc_register,
+ .remove = __devexit_p(tgafb_tc_unregister),
+ },
+};
+
+static int __devinit
+tgafb_tc_register(struct device *dev)
+{
+ int status = tgafb_register(dev);
+ if (!status)
+ get_device(dev);
+ return status;
+}
+
+static int __devexit
+tgafb_tc_unregister(struct device *dev)
+{
+ put_device(dev);
+ tgafb_unregister(dev);
+ return 0;
+}
+#endif /* CONFIG_TC */
+
/**
* tgafb_check_var - Optional function. Validates a var passed in.
@@ -132,10 +215,10 @@ static int
tgafb_set_par(struct fb_info *info)
{
static unsigned int const deep_presets[4] = {
- 0x00014000,
- 0x0001440d,
+ 0x00004000,
+ 0x0000440d,
0xffffffff,
- 0x0001441d
+ 0x0000441d
};
static unsigned int const rasterop_presets[4] = {
0x00000003,
@@ -157,6 +240,8 @@ tgafb_set_par(struct fb_info *info)
};
struct tga_par *par = (struct tga_par *) info->par;
+ int tga_bus_pci = TGA_BUS_PCI(par->dev);
+ int tga_bus_tc = TGA_BUS_TC(par->dev);
u32 htimings, vtimings, pll_freq;
u8 tga_type;
int i;
@@ -221,7 +306,7 @@ tgafb_set_par(struct fb_info *info)
TGA_WRITE_REG(par, vtimings, TGA_VERT_REG);
/* Initalise RAMDAC. */
- if (tga_type == TGA_TYPE_8PLANE) {
+ if (tga_type == TGA_TYPE_8PLANE && tga_bus_pci) {
/* Init BT485 RAMDAC registers. */
BT485_WRITE(par, 0xa2 | (par->sync_on_green ? 0x8 : 0x0),
@@ -236,21 +321,7 @@ tgafb_set_par(struct fb_info *info)
BT485_WRITE(par, 0x00, BT485_ADDR_PAL_WRITE);
TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);
-#ifdef CONFIG_HW_CONSOLE
- for (i = 0; i < 16; i++) {
- int j = color_table[i];
-
- TGA_WRITE_REG(par, default_red[j]|(BT485_DATA_PAL<<8),
- TGA_RAMDAC_REG);
- TGA_WRITE_REG(par, default_grn[j]|(BT485_DATA_PAL<<8),
- TGA_RAMDAC_REG);
- TGA_WRITE_REG(par, default_blu[j]|(BT485_DATA_PAL<<8),
- TGA_RAMDAC_REG);
- }
- for (i = 0; i < 240 * 3; i += 4) {
-#else
for (i = 0; i < 256 * 3; i += 4) {
-#endif
TGA_WRITE_REG(par, 0x55 | (BT485_DATA_PAL << 8),
TGA_RAMDAC_REG);
TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8),
@@ -261,6 +332,27 @@ tgafb_set_par(struct fb_info *info)
TGA_RAMDAC_REG);
}
+ } else if (tga_type == TGA_TYPE_8PLANE && tga_bus_tc) {
+
+ /* Init BT459 RAMDAC registers. */
+ BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_0, 0x40);
+ BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_1, 0x00);
+ BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_2,
+ (par->sync_on_green ? 0xc0 : 0x40));
+
+ BT459_WRITE(par, BT459_REG_ACC, BT459_CUR_CMD_REG, 0x00);
+
+ /* Fill the palette. */
+ BT459_LOAD_ADDR(par, 0x0000);
+ TGA_WRITE_REG(par, BT459_PALETTE << 2, TGA_RAMDAC_SETUP_REG);
+
+ for (i = 0; i < 256 * 3; i += 4) {
+ TGA_WRITE_REG(par, 0x55, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
+ }
+
} else { /* 24-plane or 24plusZ */
/* Init BT463 RAMDAC registers. */
@@ -431,6 +523,8 @@ tgafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
unsigned transp, struct fb_info *info)
{
struct tga_par *par = (struct tga_par *) info->par;
+ int tga_bus_pci = TGA_BUS_PCI(par->dev);
+ int tga_bus_tc = TGA_BUS_TC(par->dev);
if (regno > 255)
return 1;
@@ -438,12 +532,18 @@ tgafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
green >>= 8;
blue >>= 8;
- if (par->tga_type == TGA_TYPE_8PLANE) {
+ if (par->tga_type == TGA_TYPE_8PLANE && tga_bus_pci) {
BT485_WRITE(par, regno, BT485_ADDR_PAL_WRITE);
TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);
TGA_WRITE_REG(par, red|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
TGA_WRITE_REG(par, green|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
TGA_WRITE_REG(par, blue|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
+ } else if (par->tga_type == TGA_TYPE_8PLANE && tga_bus_tc) {
+ BT459_LOAD_ADDR(par, regno);
+ TGA_WRITE_REG(par, BT459_PALETTE << 2, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(par, red, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, green, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, blue, TGA_RAMDAC_REG);
} else {
if (regno < 16) {
u32 value = (regno << 16) | (regno << 8) | regno;
@@ -523,16 +623,8 @@ tgafb_blank(int blank, struct fb_info *info)
* Acceleration.
*/
-/**
- * tgafb_imageblit - REQUIRED function. Can use generic routines if
- * non acclerated hardware and packed pixel based.
- * Copies a image from system memory to the screen.
- *
- * @info: frame buffer structure that represents a single frame buffer
- * @image: structure defining the image.
- */
static void
-tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
+tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct tga_par *par = (struct tga_par *) info->par;
u32 fgcolor, bgcolor, dx, dy, width, height, vxres, vyres, pixelmask;
@@ -542,6 +634,17 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
void __iomem *regs_base;
void __iomem *fb_base;
+ is8bpp = info->var.bits_per_pixel == 8;
+
+ /* For copies that aren't pixel expansion, there's little we
+ can do better than the generic code. */
+ /* ??? There is a DMA write mode; I wonder if that could be
+ made to pull the data from the image buffer... */
+ if (image->depth > 1) {
+ cfb_imageblit(info, image);
+ return;
+ }
+
dx = image->dx;
dy = image->dy;
width = image->width;
@@ -559,18 +662,8 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
if (dy + height > vyres)
height = vyres - dy;
- /* For copies that aren't pixel expansion, there's little we
- can do better than the generic code. */
- /* ??? There is a DMA write mode; I wonder if that could be
- made to pull the data from the image buffer... */
- if (image->depth > 1) {
- cfb_imageblit(info, image);
- return;
- }
-
regs_base = par->tga_regs_base;
fb_base = par->tga_fb_base;
- is8bpp = info->var.bits_per_pixel == 8;
/* Expand the color values to fill 32-bits. */
/* ??? Would be nice to notice colour changes elsewhere, so
@@ -748,6 +841,85 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
regs_base + TGA_MODE_REG);
}
+static void
+tgafb_clut_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+ struct tga_par *par = (struct tga_par *) info->par;
+ u32 color, dx, dy, width, height, vxres, vyres;
+ u32 *palette = ((u32 *)info->pseudo_palette);
+ unsigned long pos, line_length, i, j;
+ const unsigned char *data;
+ void *regs_base, *fb_base;
+
+ dx = image->dx;
+ dy = image->dy;
+ width = image->width;
+ height = image->height;
+ vxres = info->var.xres_virtual;
+ vyres = info->var.yres_virtual;
+ line_length = info->fix.line_length;
+
+ /* Crop the image to the screen. */
+ if (dx > vxres || dy > vyres)
+ return;
+ if (dx + width > vxres)
+ width = vxres - dx;
+ if (dy + height > vyres)
+ height = vyres - dy;
+
+ regs_base = par->tga_regs_base;
+ fb_base = par->tga_fb_base;
+
+ pos = dy * line_length + (dx * 4);
+ data = image->data;
+
+ /* Now copy the image, color_expanding via the palette. */
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ color = palette[*data++];
+ __raw_writel(color, fb_base + pos + j*4);
+ }
+ pos += line_length;
+ }
+}
+
+/**
+ * tgafb_imageblit - REQUIRED function. Can use generic routines if
+ * non acclerated hardware and packed pixel based.
+ * Copies a image from system memory to the screen.
+ *
+ * @info: frame buffer structure that represents a single frame buffer
+ * @image: structure defining the image.
+ */
+static void
+tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+ unsigned int is8bpp = info->var.bits_per_pixel == 8;
+
+ /* If a mono image, regardless of FB depth, go do it. */
+ if (image->depth == 1) {
+ tgafb_mono_imageblit(info, image);
+ return;
+ }
+
+ /* For copies that aren't pixel expansion, there's little we
+ can do better than the generic code. */
+ /* ??? There is a DMA write mode; I wonder if that could be
+ made to pull the data from the image buffer... */
+ if (image->depth == info->var.bits_per_pixel) {
+ cfb_imageblit(info, image);
+ return;
+ }
+
+ /* If 24-plane FB and the image is 8-plane with CLUT, we can do it. */
+ if (!is8bpp && image->depth == 8) {
+ tgafb_clut_imageblit(info, image);
+ return;
+ }
+
+ /* Silently return... */
+}
+
/**
* tgafb_fillrect - REQUIRED function. Can use generic routines if
* non acclerated hardware and packed pixel based.
@@ -1309,18 +1481,29 @@ static void
tgafb_init_fix(struct fb_info *info)
{
struct tga_par *par = (struct tga_par *)info->par;
+ int tga_bus_pci = TGA_BUS_PCI(par->dev);
+ int tga_bus_tc = TGA_BUS_TC(par->dev);
u8 tga_type = par->tga_type;
- const char *tga_type_name;
+ const char *tga_type_name = NULL;
switch (tga_type) {
case TGA_TYPE_8PLANE:
- tga_type_name = "Digital ZLXp-E1";
+ if (tga_bus_pci)
+ tga_type_name = "Digital ZLXp-E1";
+ if (tga_bus_tc)
+ tga_type_name = "Digital ZLX-E1";
break;
case TGA_TYPE_24PLANE:
- tga_type_name = "Digital ZLXp-E2";
+ if (tga_bus_pci)
+ tga_type_name = "Digital ZLXp-E2";
+ if (tga_bus_tc)
+ tga_type_name = "Digital ZLX-E2";
break;
case TGA_TYPE_24PLUSZ:
- tga_type_name = "Digital ZLXp-E3";
+ if (tga_bus_pci)
+ tga_type_name = "Digital ZLXp-E3";
+ if (tga_bus_tc)
+ tga_type_name = "Digital ZLX-E3";
break;
default:
tga_type_name = "Unknown";
@@ -1346,11 +1529,37 @@ tgafb_init_fix(struct fb_info *info)
info->fix.ywrapstep = 0;
info->fix.accel = FB_ACCEL_DEC_TGA;
+
+ /*
+ * These are needed by fb_set_logo_truepalette(), so we
+ * set them here for 24-plane cards.
+ */
+ if (tga_type != TGA_TYPE_8PLANE) {
+ info->var.red.length = 8;
+ info->var.green.length = 8;
+ info->var.blue.length = 8;
+ info->var.red.offset = 16;
+ info->var.green.offset = 8;
+ info->var.blue.offset = 0;
+ }
}
-static __devinit int
-tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ /* We just use this to catch switches out of graphics mode. */
+ tgafb_set_par(info); /* A bit of overkill for BASE_ADDR reset. */
+ return 0;
+}
+
+static int __devinit
+tgafb_register(struct device *dev)
{
+ static const struct fb_videomode modedb_tc = {
+ /* 1280x1024 @ 72 Hz, 76.8 kHz hsync */
+ "1280x1024@72", 0, 1280, 1024, 7645, 224, 28, 33, 3, 160, 3,
+ FB_SYNC_ON_GREEN, FB_VMODE_NONINTERLACED
+ };
+
static unsigned int const fb_offset_presets[4] = {
TGA_8PLANE_FB_OFFSET,
TGA_24PLANE_FB_OFFSET,
@@ -1358,40 +1567,51 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
TGA_24PLUSZ_FB_OFFSET
};
+ const struct fb_videomode *modedb_tga = NULL;
+ resource_size_t bar0_start = 0, bar0_len = 0;
+ const char *mode_option_tga = NULL;
+ int tga_bus_pci = TGA_BUS_PCI(dev);
+ int tga_bus_tc = TGA_BUS_TC(dev);
+ unsigned int modedbsize_tga = 0;
void __iomem *mem_base;
- unsigned long bar0_start, bar0_len;
struct fb_info *info;
struct tga_par *par;
u8 tga_type;
- int ret;
+ int ret = 0;
/* Enable device in PCI config. */
- if (pci_enable_device(pdev)) {
+ if (tga_bus_pci && pci_enable_device(to_pci_dev(dev))) {
printk(KERN_ERR "tgafb: Cannot enable PCI device\n");
return -ENODEV;
}
/* Allocate the fb and par structures. */
- info = framebuffer_alloc(sizeof(struct tga_par), &pdev->dev);
+ info = framebuffer_alloc(sizeof(struct tga_par), dev);
if (!info) {
printk(KERN_ERR "tgafb: Cannot allocate memory\n");
return -ENOMEM;
}
par = info->par;
- pci_set_drvdata(pdev, info);
+ dev_set_drvdata(dev, info);
/* Request the mem regions. */
- bar0_start = pci_resource_start(pdev, 0);
- bar0_len = pci_resource_len(pdev, 0);
ret = -ENODEV;
+ if (tga_bus_pci) {
+ bar0_start = pci_resource_start(to_pci_dev(dev), 0);
+ bar0_len = pci_resource_len(to_pci_dev(dev), 0);
+ }
+ if (tga_bus_tc) {
+ bar0_start = to_tc_dev(dev)->resource.start;
+ bar0_len = to_tc_dev(dev)->resource.end - bar0_start + 1;
+ }
if (!request_mem_region (bar0_start, bar0_len, "tgafb")) {
printk(KERN_ERR "tgafb: cannot reserve FB region\n");
goto err0;
}
/* Map the framebuffer. */
- mem_base = ioremap(bar0_start, bar0_len);
+ mem_base = ioremap_nocache(bar0_start, bar0_len);
if (!mem_base) {
printk(KERN_ERR "tgafb: Cannot map MMIO\n");
goto err1;
@@ -1399,12 +1619,16 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Grab info about the card. */
tga_type = (readl(mem_base) >> 12) & 0x0f;
- par->pdev = pdev;
+ par->dev = dev;
par->tga_mem_base = mem_base;
par->tga_fb_base = mem_base + fb_offset_presets[tga_type];
par->tga_regs_base = mem_base + TGA_REGS_OFFSET;
par->tga_type = tga_type;
- pci_read_config_byte(pdev, PCI_REVISION_ID, &par->tga_chip_rev);
+ if (tga_bus_pci)
+ pci_read_config_byte(to_pci_dev(dev), PCI_REVISION_ID,
+ &par->tga_chip_rev);
+ if (tga_bus_tc)
+ par->tga_chip_rev = TGA_READ_REG(par, TGA_START_REG) & 0xff;
/* Setup framebuffer. */
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
@@ -1414,8 +1638,17 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
info->pseudo_palette = (void *)(par + 1);
/* This should give a reasonable default video mode. */
-
- ret = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL,
+ if (tga_bus_pci) {
+ mode_option_tga = mode_option_pci;
+ }
+ if (tga_bus_tc) {
+ mode_option_tga = mode_option_tc;
+ modedb_tga = &modedb_tc;
+ modedbsize_tga = 1;
+ }
+ ret = fb_find_mode(&info->var, info,
+ mode_option ? mode_option : mode_option_tga,
+ modedb_tga, modedbsize_tga, NULL,
tga_type == TGA_TYPE_8PLANE ? 8 : 32);
if (ret == 0 || ret == 4) {
printk(KERN_ERR "tgafb: Could not find valid video mode\n");
@@ -1438,13 +1671,19 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err1;
}
- printk(KERN_INFO "tgafb: DC21030 [TGA] detected, rev=0x%02x\n",
- par->tga_chip_rev);
- printk(KERN_INFO "tgafb: at PCI bus %d, device %d, function %d\n",
- pdev->bus->number, PCI_SLOT(pdev->devfn),
- PCI_FUNC(pdev->devfn));
- printk(KERN_INFO "fb%d: %s frame buffer device at 0x%lx\n",
- info->node, info->fix.id, bar0_start);
+ if (tga_bus_pci) {
+ pr_info("tgafb: DC21030 [TGA] detected, rev=0x%02x\n",
+ par->tga_chip_rev);
+ pr_info("tgafb: at PCI bus %d, device %d, function %d\n",
+ to_pci_dev(dev)->bus->number,
+ PCI_SLOT(to_pci_dev(dev)->devfn),
+ PCI_FUNC(to_pci_dev(dev)->devfn));
+ }
+ if (tga_bus_tc)
+ pr_info("tgafb: SFB+ detected, rev=0x%02x\n",
+ par->tga_chip_rev);
+ pr_info("fb%d: %s frame buffer device at 0x%lx\n",
+ info->node, info->fix.id, (long)bar0_start);
return 0;
@@ -1458,25 +1697,39 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
}
static void __devexit
-tgafb_pci_unregister(struct pci_dev *pdev)
+tgafb_unregister(struct device *dev)
{
- struct fb_info *info = pci_get_drvdata(pdev);
- struct tga_par *par = info->par;
+ resource_size_t bar0_start = 0, bar0_len = 0;
+ int tga_bus_pci = TGA_BUS_PCI(dev);
+ int tga_bus_tc = TGA_BUS_TC(dev);
+ struct fb_info *info = NULL;
+ struct tga_par *par;
+ info = dev_get_drvdata(dev);
if (!info)
return;
+
+ par = info->par;
unregister_framebuffer(info);
fb_dealloc_cmap(&info->cmap);
iounmap(par->tga_mem_base);
- release_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
+ if (tga_bus_pci) {
+ bar0_start = pci_resource_start(to_pci_dev(dev), 0);
+ bar0_len = pci_resource_len(to_pci_dev(dev), 0);
+ }
+ if (tga_bus_tc) {
+ bar0_start = to_tc_dev(dev)->resource.start;
+ bar0_len = to_tc_dev(dev)->resource.end - bar0_start + 1;
+ }
+ release_mem_region(bar0_start, bar0_len);
framebuffer_release(info);
}
static void __devexit
tgafb_exit(void)
{
- pci_unregister_driver(&tgafb_driver);
+ tc_unregister_driver(&tgafb_tc_driver);
+ pci_unregister_driver(&tgafb_pci_driver);
}
#ifndef MODULE
@@ -1505,6 +1758,7 @@ tgafb_setup(char *arg)
static int __devinit
tgafb_init(void)
{
+ int status;
#ifndef MODULE
char *option = NULL;
@@ -1512,7 +1766,10 @@ tgafb_init(void)
return -ENODEV;
tgafb_setup(option);
#endif
- return pci_register_driver(&tgafb_driver);
+ status = pci_register_driver(&tgafb_pci_driver);
+ if (!status)
+ status = tc_register_driver(&tgafb_tc_driver);
+ return status;
}
/*
@@ -1522,5 +1779,5 @@ tgafb_init(void)
module_init(tgafb_init);
module_exit(tgafb_exit);
-MODULE_DESCRIPTION("framebuffer driver for TGA chipset");
+MODULE_DESCRIPTION("Framebuffer driver for TGA/SFB+ chipset");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/vermilion/Makefile b/drivers/video/vermilion/Makefile
new file mode 100644
index 0000000..cc21a65
--- /dev/null
+++ b/drivers/video/vermilion/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_FB_LE80578) += vmlfb.o
+obj-$(CONFIG_FB_CARILLO_RANCH) += crvml.o
+
+vmlfb-objs := vermilion.o
+crvml-objs := cr_pll.o
diff --git a/drivers/video/vermilion/cr_pll.c b/drivers/video/vermilion/cr_pll.c
new file mode 100644
index 0000000..ebc6e6e
--- /dev/null
+++ b/drivers/video/vermilion/cr_pll.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * This file is part of the Carillo Ranch video subsystem driver.
+ * The Carillo Ranch video subsystem driver is free software;
+ * you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Carillo Ranch video subsystem driver is distributed
+ * in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ * Alan Hourihane <alanh-at-tungstengraphics-dot-com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include "vermilion.h"
+
+/* The PLL Clock register sits on Host bridge */
+#define CRVML_DEVICE_MCH 0x5001
+#define CRVML_REG_MCHBAR 0x44
+#define CRVML_REG_MCHEN 0x54
+#define CRVML_MCHEN_BIT (1 << 28)
+#define CRVML_MCHMAP_SIZE 4096
+#define CRVML_REG_CLOCK 0xc3c
+#define CRVML_CLOCK_SHIFT 8
+#define CRVML_CLOCK_MASK 0x00000f00
+
+static struct pci_dev *mch_dev;
+static u32 mch_bar;
+static void __iomem *mch_regs_base;
+static u32 saved_clock;
+
+static const unsigned crvml_clocks[] = {
+ 6750,
+ 13500,
+ 27000,
+ 29700,
+ 37125,
+ 54000,
+ 59400,
+ 74250,
+ 120000
+ /*
+ * There are more clocks, but they are disabled on the CR board.
+ */
+};
+
+static const u32 crvml_clock_bits[] = {
+ 0x0a,
+ 0x09,
+ 0x08,
+ 0x07,
+ 0x06,
+ 0x05,
+ 0x04,
+ 0x03,
+ 0x0b
+};
+
+static const unsigned crvml_num_clocks = ARRAY_SIZE(crvml_clocks);
+
+static int crvml_sys_restore(struct vml_sys *sys)
+{
+ void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK;
+
+ iowrite32(saved_clock, clock_reg);
+ ioread32(clock_reg);
+
+ return 0;
+}
+
+static int crvml_sys_save(struct vml_sys *sys)
+{
+ void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK;
+
+ saved_clock = ioread32(clock_reg);
+
+ return 0;
+}
+
+static int crvml_nearest_index(const struct vml_sys *sys, int clock)
+{
+ int i;
+ int cur_index = 0;
+ int cur_diff;
+ int diff;
+
+ cur_diff = clock - crvml_clocks[0];
+ cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff;
+ for (i = 1; i < crvml_num_clocks; ++i) {
+ diff = clock - crvml_clocks[i];
+ diff = (diff < 0) ? -diff : diff;
+ if (diff < cur_diff) {
+ cur_index = i;
+ cur_diff = diff;
+ }
+ }
+ return cur_index;
+}
+
+static int crvml_nearest_clock(const struct vml_sys *sys, int clock)
+{
+ return crvml_clocks[crvml_nearest_index(sys, clock)];
+}
+
+static int crvml_set_clock(struct vml_sys *sys, int clock)
+{
+ void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK;
+ int index;
+ u32 clock_val;
+
+ index = crvml_nearest_index(sys, clock);
+
+ if (crvml_clocks[index] != clock)
+ return -EINVAL;
+
+ clock_val = ioread32(clock_reg) & ~CRVML_CLOCK_MASK;
+ clock_val = crvml_clock_bits[index] << CRVML_CLOCK_SHIFT;
+ iowrite32(clock_val, clock_reg);
+ ioread32(clock_reg);
+
+ return 0;
+}
+
+static struct vml_sys cr_pll_ops = {
+ .name = "Carillo Ranch",
+ .save = crvml_sys_save,
+ .restore = crvml_sys_restore,
+ .set_clock = crvml_set_clock,
+ .nearest_clock = crvml_nearest_clock,
+};
+
+static int __init cr_pll_init(void)
+{
+ int err;
+ u32 dev_en;
+
+ mch_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
+ CRVML_DEVICE_MCH, NULL);
+ if (!mch_dev) {
+ printk(KERN_ERR
+ "Could not find Carillo Ranch MCH device.\n");
+ return -ENODEV;
+ }
+
+ pci_read_config_dword(mch_dev, CRVML_REG_MCHEN, &dev_en);
+ if (!(dev_en & CRVML_MCHEN_BIT)) {
+ printk(KERN_ERR
+ "Carillo Ranch MCH device was not enabled.\n");
+ pci_dev_put(mch_dev);
+ return -ENODEV;
+ }
+
+ pci_read_config_dword(mch_dev, CRVML_REG_MCHBAR,
+ &mch_bar);
+ mch_regs_base =
+ ioremap_nocache(mch_bar, CRVML_MCHMAP_SIZE);
+ if (!mch_regs_base) {
+ printk(KERN_ERR
+ "Carillo Ranch MCH device was not enabled.\n");
+ pci_dev_put(mch_dev);
+ return -ENODEV;
+ }
+
+ err = vmlfb_register_subsys(&cr_pll_ops);
+ if (err) {
+ printk(KERN_ERR
+ "Carillo Ranch failed to initialize vml_sys.\n");
+ pci_dev_put(mch_dev);
+ return err;
+ }
+
+ return 0;
+}
+
+static void __exit cr_pll_exit(void)
+{
+ vmlfb_unregister_subsys(&cr_pll_ops);
+
+ iounmap(mch_regs_base);
+ pci_dev_put(mch_dev);
+}
+
+module_init(cr_pll_init);
+module_exit(cr_pll_exit);
+
+MODULE_AUTHOR("Tungsten Graphics Inc.");
+MODULE_DESCRIPTION("Carillo Ranch PLL Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
new file mode 100644
index 0000000..de531c9
--- /dev/null
+++ b/drivers/video/vermilion/vermilion.c
@@ -0,0 +1,1195 @@
+/*
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * This file is part of the Vermilion Range fb driver.
+ * The Vermilion Range fb driver is free software;
+ * you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Vermilion Range fb driver is distributed
+ * in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Michel Dänzer <michel-at-tungstengraphics-dot-com>
+ * Alan Hourihane <alanh-at-tungstengraphics-dot-com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <linux/mmzone.h>
+#include <asm/uaccess.h>
+
+/* #define VERMILION_DEBUG */
+
+#include "vermilion.h"
+
+#define MODULE_NAME "vmlfb"
+
+#define VML_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)
+
+static struct mutex vml_mutex;
+static struct list_head global_no_mode;
+static struct list_head global_has_mode;
+static struct fb_ops vmlfb_ops;
+static struct vml_sys *subsys = NULL;
+static char *vml_default_mode = "1024x768@60";
+static struct fb_videomode defaultmode = {
+ NULL, 60, 1024, 768, 12896, 144, 24, 29, 3, 136, 6,
+ 0, FB_VMODE_NONINTERLACED
+};
+
+static u32 vml_mem_requested = (10 * 1024 * 1024);
+static u32 vml_mem_contig = (4 * 1024 * 1024);
+static u32 vml_mem_min = (4 * 1024 * 1024);
+
+static u32 vml_clocks[] = {
+ 6750,
+ 13500,
+ 27000,
+ 29700,
+ 37125,
+ 54000,
+ 59400,
+ 74250,
+ 120000,
+ 148500
+};
+
+static u32 vml_num_clocks = ARRAY_SIZE(vml_clocks);
+
+/*
+ * Allocate a contiguous vram area and make its linear kernel map
+ * uncached.
+ */
+
+static int vmlfb_alloc_vram_area(struct vram_area *va, unsigned max_order,
+ unsigned min_order)
+{
+ gfp_t flags;
+ unsigned long i;
+ pgprot_t wc_pageprot;
+
+ wc_pageprot = PAGE_KERNEL_NOCACHE;
+ max_order++;
+ do {
+ /*
+ * Really try hard to get the needed memory.
+ * We need memory below the first 32MB, so we
+ * add the __GFP_DMA flag that guarantees that we are
+ * below the first 16MB.
+ */
+
+ flags = __GFP_DMA | __GFP_HIGH;
+ va->logical =
+ __get_free_pages(flags, --max_order);
+ } while (va->logical == 0 && max_order > min_order);
+
+ if (!va->logical)
+ return -ENOMEM;
+
+ va->phys = virt_to_phys((void *)va->logical);
+ va->size = PAGE_SIZE << max_order;
+ va->order = max_order;
+
+ /*
+ * It seems like __get_free_pages only ups the usage count
+ * of the first page. This doesn't work with nopage mapping, so
+ * up the usage count once more.
+ */
+
+ memset((void *)va->logical, 0x00, va->size);
+ for (i = va->logical; i < va->logical + va->size; i += PAGE_SIZE) {
+ get_page(virt_to_page(i));
+ }
+
+ /*
+ * Change caching policy of the linear kernel map to avoid
+ * mapping type conflicts with user-space mappings.
+ * The first global_flush_tlb() is really only there to do a global
+ * wbinvd().
+ */
+
+ global_flush_tlb();
+ change_page_attr(virt_to_page(va->logical), va->size >> PAGE_SHIFT,
+ wc_pageprot);
+ global_flush_tlb();
+
+ printk(KERN_DEBUG MODULE_NAME
+ ": Allocated %ld bytes vram area at 0x%08lx\n",
+ va->size, va->phys);
+
+ return 0;
+}
+
+/*
+ * Free a contiguous vram area and reset its linear kernel map
+ * mapping type.
+ */
+
+static void vmlfb_free_vram_area(struct vram_area *va)
+{
+ unsigned long j;
+
+ if (va->logical) {
+
+ /*
+ * Reset the linear kernel map caching policy.
+ */
+
+ change_page_attr(virt_to_page(va->logical),
+ va->size >> PAGE_SHIFT, PAGE_KERNEL);
+ global_flush_tlb();
+
+ /*
+ * Decrease the usage count on the pages we've used
+ * to compensate for upping when allocating.
+ */
+
+ for (j = va->logical; j < va->logical + va->size;
+ j += PAGE_SIZE) {
+ (void)put_page_testzero(virt_to_page(j));
+ }
+
+ printk(KERN_DEBUG MODULE_NAME
+ ": Freeing %ld bytes vram area at 0x%08lx\n",
+ va->size, va->phys);
+ free_pages(va->logical, va->order);
+
+ va->logical = 0;
+ }
+}
+
+/*
+ * Free allocated vram.
+ */
+
+static void vmlfb_free_vram(struct vml_info *vinfo)
+{
+ int i;
+
+ for (i = 0; i < vinfo->num_areas; ++i) {
+ vmlfb_free_vram_area(&vinfo->vram[i]);
+ }
+ vinfo->num_areas = 0;
+}
+
+/*
+ * Allocate vram. Currently we try to allocate contiguous areas from the
+ * __GFP_DMA zone and puzzle them together. A better approach would be to
+ * allocate one contiguous area for scanout and use one-page allocations for
+ * offscreen areas. This requires user-space and GPU virtual mappings.
+ */
+
+static int vmlfb_alloc_vram(struct vml_info *vinfo,
+ size_t requested,
+ size_t min_total, size_t min_contig)
+{
+ int i, j;
+ int order;
+ int contiguous;
+ int err;
+ struct vram_area *va;
+ struct vram_area *va2;
+
+ vinfo->num_areas = 0;
+ for (i = 0; i < VML_VRAM_AREAS; ++i) {
+ va = &vinfo->vram[i];
+ order = 0;
+
+ while (requested > (PAGE_SIZE << order) && order < MAX_ORDER)
+ order++;
+
+ err = vmlfb_alloc_vram_area(va, order, 0);
+
+ if (err)
+ break;
+
+ if (i == 0) {
+ vinfo->vram_start = va->phys;
+ vinfo->vram_logical = (void __iomem *) va->logical;
+ vinfo->vram_contig_size = va->size;
+ vinfo->num_areas = 1;
+ } else {
+ contiguous = 0;
+
+ for (j = 0; j < i; ++j) {
+ va2 = &vinfo->vram[j];
+ if (va->phys + va->size == va2->phys ||
+ va2->phys + va2->size == va->phys) {
+ contiguous = 1;
+ break;
+ }
+ }
+
+ if (contiguous) {
+ vinfo->num_areas++;
+ if (va->phys < vinfo->vram_start) {
+ vinfo->vram_start = va->phys;
+ vinfo->vram_logical =
+ (void __iomem *)va->logical;
+ }
+ vinfo->vram_contig_size += va->size;
+ } else {
+ vmlfb_free_vram_area(va);
+ break;
+ }
+ }
+
+ if (requested < va->size)
+ break;
+ else
+ requested -= va->size;
+ }
+
+ if (vinfo->vram_contig_size > min_total &&
+ vinfo->vram_contig_size > min_contig) {
+
+ printk(KERN_DEBUG MODULE_NAME
+ ": Contiguous vram: %ld bytes at physical 0x%08lx.\n",
+ (unsigned long)vinfo->vram_contig_size,
+ (unsigned long)vinfo->vram_start);
+
+ return 0;
+ }
+
+ printk(KERN_ERR MODULE_NAME
+ ": Could not allocate requested minimal amount of vram.\n");
+
+ vmlfb_free_vram(vinfo);
+
+ return -ENOMEM;
+}
+
+/*
+ * Find the GPU to use with our display controller.
+ */
+
+static int vmlfb_get_gpu(struct vml_par *par)
+{
+ mutex_lock(&vml_mutex);
+
+ par->gpu = pci_get_device(PCI_VENDOR_ID_INTEL, VML_DEVICE_GPU, NULL);
+
+ if (!par->gpu) {
+ mutex_unlock(&vml_mutex);
+ return -ENODEV;
+ }
+
+ mutex_unlock(&vml_mutex);
+
+ if (pci_enable_device(par->gpu) < 0)
+ return -ENODEV;
+
+ return 0;
+}
+
+/*
+ * Find a contiguous vram area that contains a given offset from vram start.
+ */
+static int vmlfb_vram_offset(struct vml_info *vinfo, unsigned long offset)
+{
+ unsigned long aoffset;
+ unsigned i;
+
+ for (i = 0; i < vinfo->num_areas; ++i) {
+ aoffset = offset - (vinfo->vram[i].phys - vinfo->vram_start);
+
+ if (aoffset < vinfo->vram[i].size) {
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+/*
+ * Remap the MMIO register spaces of the VDC and the GPU.
+ */
+
+static int vmlfb_enable_mmio(struct vml_par *par)
+{
+ int err;
+
+ par->vdc_mem_base = pci_resource_start(par->vdc, 0);
+ par->vdc_mem_size = pci_resource_len(par->vdc, 0);
+ if (!request_mem_region(par->vdc_mem_base, par->vdc_mem_size, "vmlfb")) {
+ printk(KERN_ERR MODULE_NAME
+ ": Could not claim display controller MMIO.\n");
+ return -EBUSY;
+ }
+ par->vdc_mem = ioremap_nocache(par->vdc_mem_base, par->vdc_mem_size);
+ if (par->vdc_mem == NULL) {
+ printk(KERN_ERR MODULE_NAME
+ ": Could not map display controller MMIO.\n");
+ err = -ENOMEM;
+ goto out_err_0;
+ }
+
+ par->gpu_mem_base = pci_resource_start(par->gpu, 0);
+ par->gpu_mem_size = pci_resource_len(par->gpu, 0);
+ if (!request_mem_region(par->gpu_mem_base, par->gpu_mem_size, "vmlfb")) {
+ printk(KERN_ERR MODULE_NAME ": Could not claim GPU MMIO.\n");
+ err = -EBUSY;
+ goto out_err_1;
+ }
+ par->gpu_mem = ioremap_nocache(par->gpu_mem_base, par->gpu_mem_size);
+ if (par->gpu_mem == NULL) {
+ printk(KERN_ERR MODULE_NAME ": Could not map GPU MMIO.\n");
+ err = -ENOMEM;
+ goto out_err_2;
+ }
+
+ return 0;
+
+out_err_2:
+ release_mem_region(par->gpu_mem_base, par->gpu_mem_size);
+out_err_1:
+ iounmap(par->vdc_mem);
+out_err_0:
+ release_mem_region(par->vdc_mem_base, par->vdc_mem_size);
+ return err;
+}
+
+/*
+ * Unmap the VDC and GPU register spaces.
+ */
+
+static void vmlfb_disable_mmio(struct vml_par *par)
+{
+ iounmap(par->gpu_mem);
+ release_mem_region(par->gpu_mem_base, par->gpu_mem_size);
+ iounmap(par->vdc_mem);
+ release_mem_region(par->vdc_mem_base, par->vdc_mem_size);
+}
+
+/*
+ * Release and uninit the VDC and GPU.
+ */
+
+static void vmlfb_release_devices(struct vml_par *par)
+{
+ if (atomic_dec_and_test(&par->refcount)) {
+ pci_set_drvdata(par->vdc, NULL);
+ pci_disable_device(par->gpu);
+ pci_disable_device(par->vdc);
+ }
+}
+
+/*
+ * Free up allocated resources for a device.
+ */
+
+static void __devexit vml_pci_remove(struct pci_dev *dev)
+{
+ struct fb_info *info;
+ struct vml_info *vinfo;
+ struct vml_par *par;
+
+ info = pci_get_drvdata(dev);
+ if (info) {
+ vinfo = container_of(info, struct vml_info, info);
+ par = vinfo->par;
+ mutex_lock(&vml_mutex);
+ unregister_framebuffer(info);
+ fb_dealloc_cmap(&info->cmap);
+ vmlfb_free_vram(vinfo);
+ vmlfb_disable_mmio(par);
+ vmlfb_release_devices(par);
+ kfree(vinfo);
+ kfree(par);
+ mutex_unlock(&vml_mutex);
+ }
+}
+
+static void vmlfb_set_pref_pixel_format(struct fb_var_screeninfo *var)
+{
+ switch (var->bits_per_pixel) {
+ case 16:
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ var->green.offset = 5;
+ var->green.length = 5;
+ var->red.offset = 10;
+ var->red.length = 5;
+ var->transp.offset = 15;
+ var->transp.length = 1;
+ break;
+ case 32:
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 0;
+ break;
+ default:
+ break;
+ }
+
+ var->blue.msb_right = var->green.msb_right =
+ var->red.msb_right = var->transp.msb_right = 0;
+}
+
+/*
+ * Device initialization.
+ * We initialize one vml_par struct per device and one vml_info
+ * struct per pipe. Currently we have only one pipe.
+ */
+
+static int __devinit vml_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ struct vml_info *vinfo;
+ struct fb_info *info;
+ struct vml_par *par;
+ int err = 0;
+
+ par = kzalloc(sizeof(*par), GFP_KERNEL);
+ if (par == NULL)
+ return -ENOMEM;
+
+ vinfo = kzalloc(sizeof(*vinfo), GFP_KERNEL);
+ if (vinfo == NULL) {
+ err = -ENOMEM;
+ goto out_err_0;
+ }
+
+ vinfo->par = par;
+ par->vdc = dev;
+ atomic_set(&par->refcount, 1);
+
+ switch (id->device) {
+ case VML_DEVICE_VDC:
+ if ((err = vmlfb_get_gpu(par)))
+ goto out_err_1;
+ pci_set_drvdata(dev, &vinfo->info);
+ break;
+ default:
+ err = -ENODEV;
+ goto out_err_1;
+ break;
+ }
+
+ info = &vinfo->info;
+ info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK;
+
+ err = vmlfb_enable_mmio(par);
+ if (err)
+ goto out_err_2;
+
+ err = vmlfb_alloc_vram(vinfo, vml_mem_requested,
+ vml_mem_contig, vml_mem_min);
+ if (err)
+ goto out_err_3;
+
+ strcpy(info->fix.id, "Vermilion Range");
+ info->fix.mmio_start = 0;
+ info->fix.mmio_len = 0;
+ info->fix.smem_start = vinfo->vram_start;
+ info->fix.smem_len = vinfo->vram_contig_size;
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ info->fix.ypanstep = 1;
+ info->fix.xpanstep = 1;
+ info->fix.ywrapstep = 0;
+ info->fix.accel = FB_ACCEL_NONE;
+ info->screen_base = vinfo->vram_logical;
+ info->pseudo_palette = vinfo->pseudo_palette;
+ info->par = par;
+ info->fbops = &vmlfb_ops;
+ info->device = &dev->dev;
+
+ INIT_LIST_HEAD(&vinfo->head);
+ vinfo->pipe_disabled = 1;
+ vinfo->cur_blank_mode = FB_BLANK_UNBLANK;
+
+ info->var.grayscale = 0;
+ info->var.bits_per_pixel = 16;
+ vmlfb_set_pref_pixel_format(&info->var);
+
+ if (!fb_find_mode
+ (&info->var, info, vml_default_mode, NULL, 0, &defaultmode, 16)) {
+ printk(KERN_ERR MODULE_NAME ": Could not find initial mode\n");
+ }
+
+ if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) {
+ err = -ENOMEM;
+ goto out_err_4;
+ }
+
+ err = register_framebuffer(info);
+ if (err) {
+ printk(KERN_ERR MODULE_NAME ": Register framebuffer error.\n");
+ goto out_err_5;
+ }
+
+ printk("Initialized vmlfb\n");
+
+ return 0;
+
+out_err_5:
+ fb_dealloc_cmap(&info->cmap);
+out_err_4:
+ vmlfb_free_vram(vinfo);
+out_err_3:
+ vmlfb_disable_mmio(par);
+out_err_2:
+ vmlfb_release_devices(par);
+out_err_1:
+ kfree(vinfo);
+out_err_0:
+ kfree(par);
+ return err;
+}
+
+static int vmlfb_open(struct fb_info *info, int user)
+{
+ /*
+ * Save registers here?
+ */
+ return 0;
+}
+
+static int vmlfb_release(struct fb_info *info, int user)
+{
+ /*
+ * Restore registers here.
+ */
+
+ return 0;
+}
+
+static int vml_nearest_clock(int clock)
+{
+
+ int i;
+ int cur_index;
+ int cur_diff;
+ int diff;
+
+ cur_index = 0;
+ cur_diff = clock - vml_clocks[0];
+ cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff;
+ for (i = 1; i < vml_num_clocks; ++i) {
+ diff = clock - vml_clocks[i];
+ diff = (diff < 0) ? -diff : diff;
+ if (diff < cur_diff) {
+ cur_index = i;
+ cur_diff = diff;
+ }
+ }
+ return vml_clocks[cur_index];
+}
+
+static int vmlfb_check_var_locked(struct fb_var_screeninfo *var,
+ struct vml_info *vinfo)
+{
+ u32 pitch;
+ u64 mem;
+ int nearest_clock;
+ int clock;
+ int clock_diff;
+ struct fb_var_screeninfo v;
+
+ v = *var;
+ clock = PICOS2KHZ(var->pixclock);
+
+ if (subsys && subsys->nearest_clock) {
+ nearest_clock = subsys->nearest_clock(subsys, clock);
+ } else {
+ nearest_clock = vml_nearest_clock(clock);
+ }
+
+ /*
+ * Accept a 20% diff.
+ */
+
+ clock_diff = nearest_clock - clock;
+ clock_diff = (clock_diff < 0) ? -clock_diff : clock_diff;
+ if (clock_diff > clock / 5) {
+#if 0
+ printk(KERN_DEBUG MODULE_NAME ": Diff failure. %d %d\n",clock_diff,clock);
+#endif
+ return -EINVAL;
+ }
+
+ v.pixclock = KHZ2PICOS(nearest_clock);
+
+ if (var->xres > VML_MAX_XRES || var->yres > VML_MAX_YRES) {
+ printk(KERN_DEBUG MODULE_NAME ": Resolution failure.\n");
+ return -EINVAL;
+ }
+ if (var->xres_virtual > VML_MAX_XRES_VIRTUAL) {
+ printk(KERN_DEBUG MODULE_NAME
+ ": Virtual resolution failure.\n");
+ return -EINVAL;
+ }
+ switch (v.bits_per_pixel) {
+ case 0 ... 16:
+ v.bits_per_pixel = 16;
+ break;
+ case 17 ... 32:
+ v.bits_per_pixel = 32;
+ break;
+ default:
+ printk(KERN_DEBUG MODULE_NAME ": Invalid bpp: %d.\n",
+ var->bits_per_pixel);
+ return -EINVAL;
+ }
+
+ pitch = __ALIGN_MASK((var->xres * var->bits_per_pixel) >> 3, 0x3F);
+ mem = pitch * var->yres_virtual;
+ if (mem > vinfo->vram_contig_size) {
+ return -ENOMEM;
+ }
+
+ switch (v.bits_per_pixel) {
+ case 16:
+ if (var->blue.offset != 0 ||
+ var->blue.length != 5 ||
+ var->green.offset != 5 ||
+ var->green.length != 5 ||
+ var->red.offset != 10 ||
+ var->red.length != 5 ||
+ var->transp.offset != 15 || var->transp.length != 1) {
+ vmlfb_set_pref_pixel_format(&v);
+ }
+ break;
+ case 32:
+ if (var->blue.offset != 0 ||
+ var->blue.length != 8 ||
+ var->green.offset != 8 ||
+ var->green.length != 8 ||
+ var->red.offset != 16 ||
+ var->red.length != 8 ||
+ (var->transp.length != 0 && var->transp.length != 8) ||
+ (var->transp.length == 8 && var->transp.offset != 24)) {
+ vmlfb_set_pref_pixel_format(&v);
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ *var = v;
+
+ return 0;
+}
+
+static int vmlfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct vml_info *vinfo = container_of(info, struct vml_info, info);
+ int ret;
+
+ mutex_lock(&vml_mutex);
+ ret = vmlfb_check_var_locked(var, vinfo);
+ mutex_unlock(&vml_mutex);
+
+ return ret;
+}
+
+static void vml_wait_vblank(struct vml_info *vinfo)
+{
+ /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */
+ mdelay(20);
+}
+
+static void vmlfb_disable_pipe(struct vml_info *vinfo)
+{
+ struct vml_par *par = vinfo->par;
+
+ /* Disable the MDVO pad */
+ VML_WRITE32(par, VML_RCOMPSTAT, 0);
+ while (!(VML_READ32(par, VML_RCOMPSTAT) & VML_MDVO_VDC_I_RCOMP)) ;
+
+ /* Disable display planes */
+ VML_WRITE32(par, VML_DSPCCNTR,
+ VML_READ32(par, VML_DSPCCNTR) & ~VML_GFX_ENABLE);
+ (void)VML_READ32(par, VML_DSPCCNTR);
+ /* Wait for vblank for the disable to take effect */
+ vml_wait_vblank(vinfo);
+
+ /* Next, disable display pipes */
+ VML_WRITE32(par, VML_PIPEACONF, 0);
+ (void)VML_READ32(par, VML_PIPEACONF);
+
+ vinfo->pipe_disabled = 1;
+}
+
+#ifdef VERMILION_DEBUG
+static void vml_dump_regs(struct vml_info *vinfo)
+{
+ struct vml_par *par = vinfo->par;
+
+ printk(KERN_DEBUG MODULE_NAME ": Modesetting register dump:\n");
+ printk(KERN_DEBUG MODULE_NAME ": \tHTOTAL_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_HTOTAL_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tHBLANK_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_HBLANK_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tHSYNC_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_HSYNC_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tVTOTAL_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_VTOTAL_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tVBLANK_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_VBLANK_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tVSYNC_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_VSYNC_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tDSPCSTRIDE : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_DSPCSTRIDE));
+ printk(KERN_DEBUG MODULE_NAME ": \tDSPCSIZE : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_DSPCSIZE));
+ printk(KERN_DEBUG MODULE_NAME ": \tDSPCPOS : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_DSPCPOS));
+ printk(KERN_DEBUG MODULE_NAME ": \tDSPARB : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_DSPARB));
+ printk(KERN_DEBUG MODULE_NAME ": \tDSPCADDR : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_DSPCADDR));
+ printk(KERN_DEBUG MODULE_NAME ": \tBCLRPAT_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_BCLRPAT_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tCANVSCLR_A : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_CANVSCLR_A));
+ printk(KERN_DEBUG MODULE_NAME ": \tPIPEASRC : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_PIPEASRC));
+ printk(KERN_DEBUG MODULE_NAME ": \tPIPEACONF : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_PIPEACONF));
+ printk(KERN_DEBUG MODULE_NAME ": \tDSPCCNTR : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_DSPCCNTR));
+ printk(KERN_DEBUG MODULE_NAME ": \tRCOMPSTAT : 0x%08x\n",
+ (unsigned)VML_READ32(par, VML_RCOMPSTAT));
+ printk(KERN_DEBUG MODULE_NAME ": End of modesetting register dump.\n");
+}
+#endif
+
+static int vmlfb_set_par_locked(struct vml_info *vinfo)
+{
+ struct vml_par *par = vinfo->par;
+ struct fb_info *info = &vinfo->info;
+ struct fb_var_screeninfo *var = &info->var;
+ u32 htotal, hactive, hblank_start, hblank_end, hsync_start, hsync_end;
+ u32 vtotal, vactive, vblank_start, vblank_end, vsync_start, vsync_end;
+ u32 dspcntr;
+ int clock;
+
+ vinfo->bytes_per_pixel = var->bits_per_pixel >> 3;
+ vinfo->stride =
+ __ALIGN_MASK(var->xres_virtual * vinfo->bytes_per_pixel, 0x3F);
+ info->fix.line_length = vinfo->stride;
+
+ if (!subsys)
+ return 0;
+
+ htotal =
+ var->xres + var->right_margin + var->hsync_len + var->left_margin;
+ hactive = var->xres;
+ hblank_start = var->xres;
+ hblank_end = htotal;
+ hsync_start = hactive + var->right_margin;
+ hsync_end = hsync_start + var->hsync_len;
+
+ vtotal =
+ var->yres + var->lower_margin + var->vsync_len + var->upper_margin;
+ vactive = var->yres;
+ vblank_start = var->yres;
+ vblank_end = vtotal;
+ vsync_start = vactive + var->lower_margin;
+ vsync_end = vsync_start + var->vsync_len;
+
+ dspcntr = VML_GFX_ENABLE | VML_GFX_GAMMABYPASS;
+ clock = PICOS2KHZ(var->pixclock);
+
+ if (subsys->nearest_clock) {
+ clock = subsys->nearest_clock(subsys, clock);
+ } else {
+ clock = vml_nearest_clock(clock);
+ }
+ printk(KERN_DEBUG MODULE_NAME
+ ": Set mode Hfreq : %d kHz, Vfreq : %d Hz.\n", clock / htotal,
+ ((clock / htotal) * 1000) / vtotal);
+
+ switch (var->bits_per_pixel) {
+ case 16:
+ dspcntr |= VML_GFX_ARGB1555;
+ break;
+ case 32:
+ if (var->transp.length == 8)
+ dspcntr |= VML_GFX_ARGB8888 | VML_GFX_ALPHAMULT;
+ else
+ dspcntr |= VML_GFX_RGB0888;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ vmlfb_disable_pipe(vinfo);
+ mb();
+
+ if (subsys->set_clock)
+ subsys->set_clock(subsys, clock);
+ else
+ return -EINVAL;
+
+ VML_WRITE32(par, VML_HTOTAL_A, ((htotal - 1) << 16) | (hactive - 1));
+ VML_WRITE32(par, VML_HBLANK_A,
+ ((hblank_end - 1) << 16) | (hblank_start - 1));
+ VML_WRITE32(par, VML_HSYNC_A,
+ ((hsync_end - 1) << 16) | (hsync_start - 1));
+ VML_WRITE32(par, VML_VTOTAL_A, ((vtotal - 1) << 16) | (vactive - 1));
+ VML_WRITE32(par, VML_VBLANK_A,
+ ((vblank_end - 1) << 16) | (vblank_start - 1));
+ VML_WRITE32(par, VML_VSYNC_A,
+ ((vsync_end - 1) << 16) | (vsync_start - 1));
+ VML_WRITE32(par, VML_DSPCSTRIDE, vinfo->stride);
+ VML_WRITE32(par, VML_DSPCSIZE,
+ ((var->yres - 1) << 16) | (var->xres - 1));
+ VML_WRITE32(par, VML_DSPCPOS, 0x00000000);
+ VML_WRITE32(par, VML_DSPARB, VML_FIFO_DEFAULT);
+ VML_WRITE32(par, VML_BCLRPAT_A, 0x00000000);
+ VML_WRITE32(par, VML_CANVSCLR_A, 0x00000000);
+ VML_WRITE32(par, VML_PIPEASRC,
+ ((var->xres - 1) << 16) | (var->yres - 1));
+
+ wmb();
+ VML_WRITE32(par, VML_PIPEACONF, VML_PIPE_ENABLE);
+ wmb();
+ VML_WRITE32(par, VML_DSPCCNTR, dspcntr);
+ wmb();
+ VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start +
+ var->yoffset * vinfo->stride +
+ var->xoffset * vinfo->bytes_per_pixel);
+
+ VML_WRITE32(par, VML_RCOMPSTAT, VML_MDVO_PAD_ENABLE);
+
+ while (!(VML_READ32(par, VML_RCOMPSTAT) &
+ (VML_MDVO_VDC_I_RCOMP | VML_MDVO_PAD_ENABLE))) ;
+
+ vinfo->pipe_disabled = 0;
+#ifdef VERMILION_DEBUG
+ vml_dump_regs(vinfo);
+#endif
+
+ return 0;
+}
+
+static int vmlfb_set_par(struct fb_info *info)
+{
+ struct vml_info *vinfo = container_of(info, struct vml_info, info);
+ int ret;
+
+ mutex_lock(&vml_mutex);
+ list_del(&vinfo->head);
+ list_add(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode);
+ ret = vmlfb_set_par_locked(vinfo);
+
+ mutex_unlock(&vml_mutex);
+ return ret;
+}
+
+static int vmlfb_blank_locked(struct vml_info *vinfo)
+{
+ struct vml_par *par = vinfo->par;
+ u32 cur = VML_READ32(par, VML_PIPEACONF);
+
+ switch (vinfo->cur_blank_mode) {
+ case FB_BLANK_UNBLANK:
+ if (vinfo->pipe_disabled) {
+ vmlfb_set_par_locked(vinfo);
+ }
+ VML_WRITE32(par, VML_PIPEACONF, cur & ~VML_PIPE_FORCE_BORDER);
+ (void)VML_READ32(par, VML_PIPEACONF);
+ break;
+ case FB_BLANK_NORMAL:
+ if (vinfo->pipe_disabled) {
+ vmlfb_set_par_locked(vinfo);
+ }
+ VML_WRITE32(par, VML_PIPEACONF, cur | VML_PIPE_FORCE_BORDER);
+ (void)VML_READ32(par, VML_PIPEACONF);
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ if (!vinfo->pipe_disabled) {
+ vmlfb_disable_pipe(vinfo);
+ }
+ break;
+ case FB_BLANK_POWERDOWN:
+ if (!vinfo->pipe_disabled) {
+ vmlfb_disable_pipe(vinfo);
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int vmlfb_blank(int blank_mode, struct fb_info *info)
+{
+ struct vml_info *vinfo = container_of(info, struct vml_info, info);
+ int ret;
+
+ mutex_lock(&vml_mutex);
+ vinfo->cur_blank_mode = blank_mode;
+ ret = vmlfb_blank_locked(vinfo);
+ mutex_unlock(&vml_mutex);
+ return ret;
+}
+
+static int vmlfb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct vml_info *vinfo = container_of(info, struct vml_info, info);
+ struct vml_par *par = vinfo->par;
+
+ mutex_lock(&vml_mutex);
+ VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start +
+ var->yoffset * vinfo->stride +
+ var->xoffset * vinfo->bytes_per_pixel);
+ (void)VML_READ32(par, VML_DSPCADDR);
+ mutex_unlock(&vml_mutex);
+
+ return 0;
+}
+
+static int vmlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ u32 v;
+
+ if (regno >= 16)
+ return -EINVAL;
+
+ if (info->var.grayscale) {
+ red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
+ }
+
+ if (info->fix.visual != FB_VISUAL_TRUECOLOR)
+ return -EINVAL;
+
+ red = VML_TOHW(red, info->var.red.length);
+ blue = VML_TOHW(blue, info->var.blue.length);
+ green = VML_TOHW(green, info->var.green.length);
+ transp = VML_TOHW(transp, info->var.transp.length);
+
+ v = (red << info->var.red.offset) |
+ (green << info->var.green.offset) |
+ (blue << info->var.blue.offset) |
+ (transp << info->var.transp.offset);
+
+ switch (info->var.bits_per_pixel) {
+ case 16:
+ ((u32 *) info->pseudo_palette)[regno] = v;
+ break;
+ case 24:
+ case 32:
+ ((u32 *) info->pseudo_palette)[regno] = v;
+ break;
+ }
+ return 0;
+}
+
+static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct vml_info *vinfo = container_of(info, struct vml_info, info);
+ unsigned long size = vma->vm_end - vma->vm_start;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ int ret;
+
+ if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+ return -EINVAL;
+ if (offset + size > vinfo->vram_contig_size)
+ return -EINVAL;
+ ret = vmlfb_vram_offset(vinfo, offset);
+ if (ret)
+ return -EINVAL;
+ offset += vinfo->vram_start;
+ pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
+ pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
+ vma->vm_flags |= VM_RESERVED | VM_IO;
+ if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
+ size, vma->vm_page_prot))
+ return -EAGAIN;
+ return 0;
+}
+
+static int vmlfb_sync(struct fb_info *info)
+{
+ return 0;
+}
+
+static int vmlfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+ return -EINVAL; /* just to force soft_cursor() call */
+}
+
+static struct fb_ops vmlfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_open = vmlfb_open,
+ .fb_release = vmlfb_release,
+ .fb_check_var = vmlfb_check_var,
+ .fb_set_par = vmlfb_set_par,
+ .fb_blank = vmlfb_blank,
+ .fb_pan_display = vmlfb_pan_display,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_cursor = vmlfb_cursor,
+ .fb_sync = vmlfb_sync,
+ .fb_mmap = vmlfb_mmap,
+ .fb_setcolreg = vmlfb_setcolreg
+};
+
+static struct pci_device_id vml_ids[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, VML_DEVICE_VDC)},
+ {0}
+};
+
+static struct pci_driver vmlfb_pci_driver = {
+ .name = "vmlfb",
+ .id_table = vml_ids,
+ .probe = vml_pci_probe,
+ .remove = __devexit_p(vml_pci_remove)
+};
+
+static void __exit vmlfb_cleanup(void)
+{
+ pci_unregister_driver(&vmlfb_pci_driver);
+}
+
+static int __init vmlfb_init(void)
+{
+
+#ifndef MODULE
+ char *option = NULL;
+
+ if (fb_get_options(MODULE_NAME, &option))
+ return -ENODEV;
+#endif
+
+ printk(KERN_DEBUG MODULE_NAME ": initializing\n");
+ mutex_init(&vml_mutex);
+ INIT_LIST_HEAD(&global_no_mode);
+ INIT_LIST_HEAD(&global_has_mode);
+
+ return pci_register_driver(&vmlfb_pci_driver);
+}
+
+int vmlfb_register_subsys(struct vml_sys *sys)
+{
+ struct vml_info *entry;
+ struct list_head *list;
+ u32 save_activate;
+
+ mutex_lock(&vml_mutex);
+ if (subsys != NULL) {
+ subsys->restore(subsys);
+ }
+ subsys = sys;
+ subsys->save(subsys);
+
+ /*
+ * We need to restart list traversal for each item, since we
+ * release the list mutex in the loop.
+ */
+
+ list = global_no_mode.next;
+ while (list != &global_no_mode) {
+ list_del_init(list);
+ entry = list_entry(list, struct vml_info, head);
+
+ /*
+ * First, try the current mode which might not be
+ * completely validated with respect to the pixel clock.
+ */
+
+ if (!vmlfb_check_var_locked(&entry->info.var, entry)) {
+ vmlfb_set_par_locked(entry);
+ list_add_tail(list, &global_has_mode);
+ } else {
+
+ /*
+ * Didn't work. Try to find another mode,
+ * that matches this subsys.
+ */
+
+ mutex_unlock(&vml_mutex);
+ save_activate = entry->info.var.activate;
+ entry->info.var.bits_per_pixel = 16;
+ vmlfb_set_pref_pixel_format(&entry->info.var);
+ if (fb_find_mode(&entry->info.var,
+ &entry->info,
+ vml_default_mode, NULL, 0, NULL, 16)) {
+ entry->info.var.activate |=
+ FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
+ fb_set_var(&entry->info, &entry->info.var);
+ } else {
+ printk(KERN_ERR MODULE_NAME
+ ": Sorry. no mode found for this subsys.\n");
+ }
+ entry->info.var.activate = save_activate;
+ mutex_lock(&vml_mutex);
+ }
+ vmlfb_blank_locked(entry);
+ list = global_no_mode.next;
+ }
+ mutex_unlock(&vml_mutex);
+
+ printk(KERN_DEBUG MODULE_NAME ": Registered %s subsystem.\n",
+ subsys->name ? subsys->name : "unknown");
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(vmlfb_register_subsys);
+
+void vmlfb_unregister_subsys(struct vml_sys *sys)
+{
+ struct vml_info *entry, *next;
+
+ mutex_lock(&vml_mutex);
+ if (subsys != sys) {
+ mutex_unlock(&vml_mutex);
+ return;
+ }
+ subsys->restore(subsys);
+ subsys = NULL;
+ list_for_each_entry_safe(entry, next, &global_has_mode, head) {
+ printk(KERN_DEBUG MODULE_NAME ": subsys disable pipe\n");
+ vmlfb_disable_pipe(entry);
+ list_del(&entry->head);
+ list_add_tail(&entry->head, &global_no_mode);
+ }
+ mutex_unlock(&vml_mutex);
+}
+
+EXPORT_SYMBOL_GPL(vmlfb_unregister_subsys);
+
+module_init(vmlfb_init);
+module_exit(vmlfb_cleanup);
+
+MODULE_AUTHOR("Tungsten Graphics");
+MODULE_DESCRIPTION("Initialization of the Vermilion display devices");
+MODULE_VERSION("1.0.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/vermilion/vermilion.h b/drivers/video/vermilion/vermilion.h
new file mode 100644
index 0000000..1fc6695
--- /dev/null
+++ b/drivers/video/vermilion/vermilion.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) Intel Corp. 2007.
+ * All Rights Reserved.
+ *
+ * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ * develop this driver.
+ *
+ * This file is part of the Vermilion Range fb driver.
+ * The Vermilion Range fb driver is free software;
+ * you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Vermilion Range fb driver is distributed
+ * in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#ifndef _VERMILION_H_
+#define _VERMILION_H_
+
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/pci.h>
+#include <asm/atomic.h>
+#include <linux/mutex.h>
+
+#define VML_DEVICE_GPU 0x5002
+#define VML_DEVICE_VDC 0x5009
+
+#define VML_VRAM_AREAS 3
+#define VML_MAX_XRES 1024
+#define VML_MAX_YRES 768
+#define VML_MAX_XRES_VIRTUAL 1040
+
+/*
+ * Display controller registers:
+ */
+
+/* Display controller 10-bit color representation */
+
+#define VML_R_MASK 0x3FF00000
+#define VML_R_SHIFT 20
+#define VML_G_MASK 0x000FFC00
+#define VML_G_SHIFT 10
+#define VML_B_MASK 0x000003FF
+#define VML_B_SHIFT 0
+
+/* Graphics plane control */
+#define VML_DSPCCNTR 0x00072180
+#define VML_GFX_ENABLE 0x80000000
+#define VML_GFX_GAMMABYPASS 0x40000000
+#define VML_GFX_ARGB1555 0x0C000000
+#define VML_GFX_RGB0888 0x18000000
+#define VML_GFX_ARGB8888 0x1C000000
+#define VML_GFX_ALPHACONST 0x02000000
+#define VML_GFX_ALPHAMULT 0x01000000
+#define VML_GFX_CONST_ALPHA 0x000000FF
+
+/* Graphics plane start address. Pixel aligned. */
+#define VML_DSPCADDR 0x00072184
+
+/* Graphics plane stride register. */
+#define VML_DSPCSTRIDE 0x00072188
+
+/* Graphics plane position register. */
+#define VML_DSPCPOS 0x0007218C
+#define VML_POS_YMASK 0x0FFF0000
+#define VML_POS_YSHIFT 16
+#define VML_POS_XMASK 0x00000FFF
+#define VML_POS_XSHIFT 0
+
+/* Graphics plane height and width */
+#define VML_DSPCSIZE 0x00072190
+#define VML_SIZE_HMASK 0x0FFF0000
+#define VML_SIZE_HSHIFT 16
+#define VML_SISE_WMASK 0x00000FFF
+#define VML_SIZE_WSHIFT 0
+
+/* Graphics plane gamma correction lookup table registers (129 * 32 bits) */
+#define VML_DSPCGAMLUT 0x00072200
+
+/* Pixel video output configuration register */
+#define VML_PVOCONFIG 0x00061140
+#define VML_CONFIG_BASE 0x80000000
+#define VML_CONFIG_PIXEL_SWAP 0x04000000
+#define VML_CONFIG_DE_INV 0x01000000
+#define VML_CONFIG_HREF_INV 0x00400000
+#define VML_CONFIG_VREF_INV 0x00100000
+#define VML_CONFIG_CLK_INV 0x00040000
+#define VML_CONFIG_CLK_DIV2 0x00010000
+#define VML_CONFIG_ESTRB_INV 0x00008000
+
+/* Pipe A Horizontal total register */
+#define VML_HTOTAL_A 0x00060000
+#define VML_HTOTAL_MASK 0x1FFF0000
+#define VML_HTOTAL_SHIFT 16
+#define VML_HTOTAL_VAL 8192
+#define VML_HACTIVE_MASK 0x000007FF
+#define VML_HACTIVE_SHIFT 0
+#define VML_HACTIVE_VAL 4096
+
+/* Pipe A Horizontal Blank register */
+#define VML_HBLANK_A 0x00060004
+#define VML_HBLANK_END_MASK 0x1FFF0000
+#define VML_HBLANK_END_SHIFT 16
+#define VML_HBLANK_END_VAL 8192
+#define VML_HBLANK_START_MASK 0x00001FFF
+#define VML_HBLANK_START_SHIFT 0
+#define VML_HBLANK_START_VAL 8192
+
+/* Pipe A Horizontal Sync register */
+#define VML_HSYNC_A 0x00060008
+#define VML_HSYNC_END_MASK 0x1FFF0000
+#define VML_HSYNC_END_SHIFT 16
+#define VML_HSYNC_END_VAL 8192
+#define VML_HSYNC_START_MASK 0x00001FFF
+#define VML_HSYNC_START_SHIFT 0
+#define VML_HSYNC_START_VAL 8192
+
+/* Pipe A Vertical total register */
+#define VML_VTOTAL_A 0x0006000C
+#define VML_VTOTAL_MASK 0x1FFF0000
+#define VML_VTOTAL_SHIFT 16
+#define VML_VTOTAL_VAL 8192
+#define VML_VACTIVE_MASK 0x000007FF
+#define VML_VACTIVE_SHIFT 0
+#define VML_VACTIVE_VAL 4096
+
+/* Pipe A Vertical Blank register */
+#define VML_VBLANK_A 0x00060010
+#define VML_VBLANK_END_MASK 0x1FFF0000
+#define VML_VBLANK_END_SHIFT 16
+#define VML_VBLANK_END_VAL 8192
+#define VML_VBLANK_START_MASK 0x00001FFF
+#define VML_VBLANK_START_SHIFT 0
+#define VML_VBLANK_START_VAL 8192
+
+/* Pipe A Vertical Sync register */
+#define VML_VSYNC_A 0x00060014
+#define VML_VSYNC_END_MASK 0x1FFF0000
+#define VML_VSYNC_END_SHIFT 16
+#define VML_VSYNC_END_VAL 8192
+#define VML_VSYNC_START_MASK 0x00001FFF
+#define VML_VSYNC_START_SHIFT 0
+#define VML_VSYNC_START_VAL 8192
+
+/* Pipe A Source Image size (minus one - equal to active size)
+ * Programmable while pipe is enabled.
+ */
+#define VML_PIPEASRC 0x0006001C
+#define VML_PIPEASRC_HMASK 0x0FFF0000
+#define VML_PIPEASRC_HSHIFT 16
+#define VML_PIPEASRC_VMASK 0x00000FFF
+#define VML_PIPEASRC_VSHIFT 0
+
+/* Pipe A Border Color Pattern register (10 bit color) */
+#define VML_BCLRPAT_A 0x00060020
+
+/* Pipe A Canvas Color register (10 bit color) */
+#define VML_CANVSCLR_A 0x00060024
+
+/* Pipe A Configuration register */
+#define VML_PIPEACONF 0x00070008
+#define VML_PIPE_BASE 0x00000000
+#define VML_PIPE_ENABLE 0x80000000
+#define VML_PIPE_FORCE_BORDER 0x02000000
+#define VML_PIPE_PLANES_OFF 0x00080000
+#define VML_PIPE_ARGB_OUTPUT_MODE 0x00040000
+
+/* Pipe A FIFO setting */
+#define VML_DSPARB 0x00070030
+#define VML_FIFO_DEFAULT 0x00001D9C
+
+/* MDVO rcomp status & pads control register */
+#define VML_RCOMPSTAT 0x00070048
+#define VML_MDVO_VDC_I_RCOMP 0x80000000
+#define VML_MDVO_POWERSAVE_OFF 0x00000008
+#define VML_MDVO_PAD_ENABLE 0x00000004
+#define VML_MDVO_PULLDOWN_ENABLE 0x00000001
+
+struct vml_par {
+ struct pci_dev *vdc;
+ u64 vdc_mem_base;
+ u64 vdc_mem_size;
+ char __iomem *vdc_mem;
+
+ struct pci_dev *gpu;
+ u64 gpu_mem_base;
+ u64 gpu_mem_size;
+ char __iomem *gpu_mem;
+
+ atomic_t refcount;
+};
+
+struct vram_area {
+ unsigned long logical;
+ unsigned long phys;
+ unsigned long size;
+ unsigned order;
+};
+
+struct vml_info {
+ struct fb_info info;
+ struct vml_par *par;
+ struct list_head head;
+ struct vram_area vram[VML_VRAM_AREAS];
+ u64 vram_start;
+ u64 vram_contig_size;
+ u32 num_areas;
+ void __iomem *vram_logical;
+ u32 pseudo_palette[16];
+ u32 stride;
+ u32 bytes_per_pixel;
+ atomic_t vmas;
+ int cur_blank_mode;
+ int pipe_disabled;
+};
+
+/*
+ * Subsystem
+ */
+
+struct vml_sys {
+ char *name;
+
+ /*
+ * Save / Restore;
+ */
+
+ int (*save) (struct vml_sys * sys);
+ int (*restore) (struct vml_sys * sys);
+
+ /*
+ * PLL programming;
+ */
+
+ int (*set_clock) (struct vml_sys * sys, int clock);
+ int (*nearest_clock) (const struct vml_sys * sys, int clock);
+};
+
+extern int vmlfb_register_subsys(struct vml_sys *sys);
+extern void vmlfb_unregister_subsys(struct vml_sys *sys);
+
+#define VML_READ32(_par, _offset) \
+ (ioread32((_par)->vdc_mem + (_offset)))
+#define VML_WRITE32(_par, _offset, _value) \
+ iowrite32(_value, (_par)->vdc_mem + (_offset))
+
+#endif
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index a9b99b0..64ee78c 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -84,13 +84,15 @@ static int vfb_mmap(struct fb_info *info,
struct vm_area_struct *vma);
static struct fb_ops vfb_ops = {
+ .fb_read = fb_sys_read,
+ .fb_write = fb_sys_write,
.fb_check_var = vfb_check_var,
.fb_set_par = vfb_set_par,
.fb_setcolreg = vfb_setcolreg,
.fb_pan_display = vfb_pan_display,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
+ .fb_fillrect = sys_fillrect,
+ .fb_copyarea = sys_copyarea,
+ .fb_imageblit = sys_imageblit,
.fb_mmap = vfb_mmap,
};
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index ec4c7dc..2a14d28 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -1378,6 +1378,8 @@ static int __init vga16fb_probe(struct platform_device *dev)
info->fbops = &vga16fb_ops;
info->var = vga16fb_defined;
info->fix = vga16fb_fix;
+ /* supports rectangles with widths of multiples of 8 */
+ info->pixmap.blit_x = 1 << 7 | 1 << 15 | 1 << 23 | 1 << 31;
info->flags = FBINFO_FLAG_DEFAULT |
FBINFO_HWACCEL_YPAN;
diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c
index d94efaf..b91c466 100644
--- a/drivers/video/vgastate.c
+++ b/drivers/video/vgastate.c
@@ -50,23 +50,28 @@ static void save_vga_text(struct vgastate *state, void __iomem *fbbase)
struct regstate *saved = (struct regstate *) state->vidstate;
int i;
u8 misc, attr10, gr4, gr5, gr6, seq1, seq2, seq4;
+ unsigned short iobase;
/* if in graphics mode, no need to save */
+ misc = vga_r(state->vgabase, VGA_MIS_R);
+ iobase = (misc & 1) ? 0x3d0 : 0x3b0;
+
+ vga_r(state->vgabase, iobase + 0xa);
+ vga_w(state->vgabase, VGA_ATT_W, 0x00);
attr10 = vga_rattr(state->vgabase, 0x10);
+ vga_r(state->vgabase, iobase + 0xa);
+ vga_w(state->vgabase, VGA_ATT_W, 0x20);
+
if (attr10 & 1)
return;
-
+
/* save regs */
- misc = vga_r(state->vgabase, VGA_MIS_R);
gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ);
gr5 = vga_rgfx(state->vgabase, VGA_GFX_MODE);
gr6 = vga_rgfx(state->vgabase, VGA_GFX_MISC);
seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE);
seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE);
- /* force graphics mode */
- vga_w(state->vgabase, VGA_MIS_W, misc | 1);
-
/* blank screen */
seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);
vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
@@ -115,15 +120,12 @@ static void save_vga_text(struct vgastate *state, void __iomem *fbbase)
}
/* restore regs */
- vga_wattr(state->vgabase, 0x10, attr10);
-
vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, seq2);
vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, seq4);
vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4);
vga_wgfx(state->vgabase, VGA_GFX_MODE, gr5);
vga_wgfx(state->vgabase, VGA_GFX_MISC, gr6);
- vga_w(state->vgabase, VGA_MIS_W, misc);
/* unblank screen */
vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
@@ -137,11 +139,10 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase)
{
struct regstate *saved = (struct regstate *) state->vidstate;
int i;
- u8 misc, gr1, gr3, gr4, gr5, gr6, gr8;
+ u8 gr1, gr3, gr4, gr5, gr6, gr8;
u8 seq1, seq2, seq4;
/* save regs */
- misc = vga_r(state->vgabase, VGA_MIS_R);
gr1 = vga_rgfx(state->vgabase, VGA_GFX_SR_ENABLE);
gr3 = vga_rgfx(state->vgabase, VGA_GFX_DATA_ROTATE);
gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ);
@@ -151,9 +152,6 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase)
seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE);
seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE);
- /* force graphics mode */
- vga_w(state->vgabase, VGA_MIS_W, misc | 1);
-
/* blank screen */
seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);
vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
@@ -213,8 +211,6 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase)
vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3);
/* restore regs */
- vga_w(state->vgabase, VGA_MIS_W, misc);
-
vga_wgfx(state->vgabase, VGA_GFX_SR_ENABLE, gr1);
vga_wgfx(state->vgabase, VGA_GFX_DATA_ROTATE, gr3);
vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4);
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
new file mode 100644
index 0000000..1d29a89
--- /dev/null
+++ b/drivers/video/xilinxfb.c
@@ -0,0 +1,381 @@
+/*
+ * xilinxfb.c
+ *
+ * Xilinx TFT LCD frame buffer driver
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * 2002-2007 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+/*
+ * This driver was based on au1100fb.c by MontaVista rewritten for 2.6
+ * by Embedded Alley Solutions <source@embeddedalley.com>, which in turn
+ * was based on skeletonfb.c, Skeleton for a frame buffer device by
+ * Geert Uytterhoeven.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+#include <syslib/virtex_devices.h>
+
+#define DRIVER_NAME "xilinxfb"
+#define DRIVER_DESCRIPTION "Xilinx TFT LCD frame buffer driver"
+
+/*
+ * Xilinx calls it "PLB TFT LCD Controller" though it can also be used for
+ * the VGA port on the Xilinx ML40x board. This is a hardware display controller
+ * for a 640x480 resolution TFT or VGA screen.
+ *
+ * The interface to the framebuffer is nice and simple. There are two
+ * control registers. The first tells the LCD interface where in memory
+ * the frame buffer is (only the 11 most significant bits are used, so
+ * don't start thinking about scrolling). The second allows the LCD to
+ * be turned on or off as well as rotated 180 degrees.
+ */
+#define NUM_REGS 2
+#define REG_FB_ADDR 0
+#define REG_CTRL 1
+#define REG_CTRL_ENABLE 0x0001
+#define REG_CTRL_ROTATE 0x0002
+
+/*
+ * The hardware only handles a single mode: 640x480 24 bit true
+ * color. Each pixel gets a word (32 bits) of memory. Within each word,
+ * the 8 most significant bits are ignored, the next 8 bits are the red
+ * level, the next 8 bits are the green level and the 8 least
+ * significant bits are the blue level. Each row of the LCD uses 1024
+ * words, but only the first 640 pixels are displayed with the other 384
+ * words being ignored. There are 480 rows.
+ */
+#define BYTES_PER_PIXEL 4
+#define BITS_PER_PIXEL (BYTES_PER_PIXEL * 8)
+#define XRES 640
+#define YRES 480
+#define XRES_VIRTUAL 1024
+#define YRES_VIRTUAL YRES
+#define LINE_LENGTH (XRES_VIRTUAL * BYTES_PER_PIXEL)
+#define FB_SIZE (YRES_VIRTUAL * LINE_LENGTH)
+
+#define RED_SHIFT 16
+#define GREEN_SHIFT 8
+#define BLUE_SHIFT 0
+
+#define PALETTE_ENTRIES_NO 16 /* passed to fb_alloc_cmap() */
+
+/*
+ * Here are the default fb_fix_screeninfo and fb_var_screeninfo structures
+ */
+static struct fb_fix_screeninfo xilinx_fb_fix __initdata = {
+ .id = "Xilinx",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_TRUECOLOR,
+ .smem_len = FB_SIZE,
+ .line_length = LINE_LENGTH,
+ .accel = FB_ACCEL_NONE
+};
+
+static struct fb_var_screeninfo xilinx_fb_var __initdata = {
+ .xres = XRES,
+ .yres = YRES,
+ .xres_virtual = XRES_VIRTUAL,
+ .yres_virtual = YRES_VIRTUAL,
+
+ .bits_per_pixel = BITS_PER_PIXEL,
+
+ .red = { RED_SHIFT, 8, 0 },
+ .green = { GREEN_SHIFT, 8, 0 },
+ .blue = { BLUE_SHIFT, 8, 0 },
+ .transp = { 0, 0, 0 },
+
+ .activate = FB_ACTIVATE_NOW
+};
+
+struct xilinxfb_drvdata {
+
+ struct fb_info info; /* FB driver info record */
+
+ u32 regs_phys; /* phys. address of the control registers */
+ u32 __iomem *regs; /* virt. address of the control registers */
+
+ unsigned char __iomem *fb_virt; /* virt. address of the frame buffer */
+ dma_addr_t fb_phys; /* phys. address of the frame buffer */
+
+ u32 reg_ctrl_default;
+
+ u32 pseudo_palette[PALETTE_ENTRIES_NO];
+ /* Fake palette of 16 colors */
+};
+
+#define to_xilinxfb_drvdata(_info) \
+ container_of(_info, struct xilinxfb_drvdata, info)
+
+/*
+ * The LCD controller has DCR interface to its registers, but all
+ * the boards and configurations the driver has been tested with
+ * use opb2dcr bridge. So the registers are seen as memory mapped.
+ * This macro is to make it simple to add the direct DCR access
+ * when it's needed.
+ */
+#define xilinx_fb_out_be32(driverdata, offset, val) \
+ out_be32(driverdata->regs + offset, val)
+
+static int
+xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+ unsigned transp, struct fb_info *fbi)
+{
+ u32 *palette = fbi->pseudo_palette;
+
+ if (regno >= PALETTE_ENTRIES_NO)
+ return -EINVAL;
+
+ if (fbi->var.grayscale) {
+ /* Convert color to grayscale.
+ * grayscale = 0.30*R + 0.59*G + 0.11*B */
+ red = green = blue =
+ (red * 77 + green * 151 + blue * 28 + 127) >> 8;
+ }
+
+ /* fbi->fix.visual is always FB_VISUAL_TRUECOLOR */
+
+ /* We only handle 8 bits of each color. */
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+ palette[regno] = (red << RED_SHIFT) | (green << GREEN_SHIFT) |
+ (blue << BLUE_SHIFT);
+
+ return 0;
+}
+
+static int
+xilinx_fb_blank(int blank_mode, struct fb_info *fbi)
+{
+ struct xilinxfb_drvdata *drvdata = to_xilinxfb_drvdata(fbi);
+
+ switch (blank_mode) {
+ case FB_BLANK_UNBLANK:
+ /* turn on panel */
+ xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
+ break;
+
+ case FB_BLANK_NORMAL:
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_POWERDOWN:
+ /* turn off panel */
+ xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
+ default:
+ break;
+
+ }
+ return 0; /* success */
+}
+
+static struct fb_ops xilinxfb_ops =
+{
+ .owner = THIS_MODULE,
+ .fb_setcolreg = xilinx_fb_setcolreg,
+ .fb_blank = xilinx_fb_blank,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+/* === The device driver === */
+
+static int
+xilinxfb_drv_probe(struct device *dev)
+{
+ struct platform_device *pdev;
+ struct xilinxfb_platform_data *pdata;
+ struct xilinxfb_drvdata *drvdata;
+ struct resource *regs_res;
+ int retval;
+
+ if (!dev)
+ return -EINVAL;
+
+ pdev = to_platform_device(dev);
+ pdata = pdev->dev.platform_data;
+
+ if (pdata == NULL) {
+ printk(KERN_ERR "Couldn't find platform data.\n");
+ return -EFAULT;
+ }
+
+ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata) {
+ printk(KERN_ERR "Couldn't allocate device private record\n");
+ return -ENOMEM;
+ }
+ dev_set_drvdata(dev, drvdata);
+
+ /* Map the control registers in */
+ regs_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!regs_res || (regs_res->end - regs_res->start + 1 < 8)) {
+ printk(KERN_ERR "Couldn't get registers resource\n");
+ retval = -EFAULT;
+ goto failed1;
+ }
+
+ if (!request_mem_region(regs_res->start, 8, DRIVER_NAME)) {
+ printk(KERN_ERR
+ "Couldn't lock memory region at 0x%08X\n",
+ regs_res->start);
+ retval = -EBUSY;
+ goto failed1;
+ }
+ drvdata->regs = (u32 __iomem*) ioremap(regs_res->start, 8);
+ drvdata->regs_phys = regs_res->start;
+
+ /* Allocate the framebuffer memory */
+ drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(FB_SIZE),
+ &drvdata->fb_phys, GFP_KERNEL);
+ if (!drvdata->fb_virt) {
+ printk(KERN_ERR "Could not allocate frame buffer memory\n");
+ retval = -ENOMEM;
+ goto failed2;
+ }
+
+ /* Clear (turn to black) the framebuffer */
+ memset_io((void *) drvdata->fb_virt, 0, FB_SIZE);
+
+ /* Tell the hardware where the frame buffer is */
+ xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys);
+
+ /* Turn on the display */
+ if (pdata->rotate_screen) {
+ drvdata->reg_ctrl_default = REG_CTRL_ENABLE | REG_CTRL_ROTATE;
+ } else {
+ drvdata->reg_ctrl_default = REG_CTRL_ENABLE;
+ }
+ xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
+
+ /* Fill struct fb_info */
+ drvdata->info.device = dev;
+ drvdata->info.screen_base = drvdata->fb_virt;
+ drvdata->info.fbops = &xilinxfb_ops;
+ drvdata->info.fix = xilinx_fb_fix;
+ drvdata->info.fix.smem_start = drvdata->fb_phys;
+ drvdata->info.pseudo_palette = drvdata->pseudo_palette;
+
+ if (fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0) < 0) {
+ printk(KERN_ERR "Fail to allocate colormap (%d entries)\n",
+ PALETTE_ENTRIES_NO);
+ retval = -EFAULT;
+ goto failed3;
+ }
+
+ drvdata->info.flags = FBINFO_DEFAULT;
+ xilinx_fb_var.height = pdata->screen_height_mm;
+ xilinx_fb_var.width = pdata->screen_width_mm;
+ drvdata->info.var = xilinx_fb_var;
+
+ /* Register new frame buffer */
+ if (register_framebuffer(&drvdata->info) < 0) {
+ printk(KERN_ERR "Could not register frame buffer\n");
+ retval = -EINVAL;
+ goto failed4;
+ }
+
+ return 0; /* success */
+
+failed4:
+ fb_dealloc_cmap(&drvdata->info.cmap);
+
+failed3:
+ dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt,
+ drvdata->fb_phys);
+
+ /* Turn off the display */
+ xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
+ iounmap(drvdata->regs);
+
+failed2:
+ release_mem_region(regs_res->start, 8);
+
+failed1:
+ kfree(drvdata);
+ dev_set_drvdata(dev, NULL);
+
+ return retval;
+}
+
+static int
+xilinxfb_drv_remove(struct device *dev)
+{
+ struct xilinxfb_drvdata *drvdata;
+
+ if (!dev)
+ return -ENODEV;
+
+ drvdata = (struct xilinxfb_drvdata *) dev_get_drvdata(dev);
+
+#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
+ xilinx_fb_blank(VESA_POWERDOWN, &drvdata->info);
+#endif
+
+ unregister_framebuffer(&drvdata->info);
+
+ fb_dealloc_cmap(&drvdata->info.cmap);
+
+ dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt,
+ drvdata->fb_phys);
+
+ /* Turn off the display */
+ xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
+ iounmap(drvdata->regs);
+
+ release_mem_region(drvdata->regs_phys, 8);
+
+ kfree(drvdata);
+ dev_set_drvdata(dev, NULL);
+
+ return 0;
+}
+
+
+static struct device_driver xilinxfb_driver = {
+ .name = DRIVER_NAME,
+ .bus = &platform_bus_type,
+
+ .probe = xilinxfb_drv_probe,
+ .remove = xilinxfb_drv_remove
+};
+
+static int __init
+xilinxfb_init(void)
+{
+ /*
+ * No kernel boot options used,
+ * so we just need to register the driver
+ */
+ return driver_register(&xilinxfb_driver);
+}
+
+static void __exit
+xilinxfb_cleanup(void)
+{
+ driver_unregister(&xilinxfb_driver);
+}
+
+module_init(xilinxfb_init);
+module_exit(xilinxfb_cleanup);
+
+MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
+MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig
index 2fb4255..8f77933 100644
--- a/drivers/w1/masters/Kconfig
+++ b/drivers/w1/masters/Kconfig
@@ -35,5 +35,13 @@ config W1_MASTER_DS2482
This driver can also be built as a module. If so, the module
will be called ds2482.
+config W1_MASTER_DS1WM
+ tristate "Maxim DS1WM 1-wire busmaster"
+ depends on W1 && ARM
+ help
+ Say Y here to enable the DS1WM 1-wire driver, such as that
+ in HP iPAQ devices like h5xxx, h2200, and ASIC3-based like
+ hx4700.
+
endmenu
diff --git a/drivers/w1/masters/Makefile b/drivers/w1/masters/Makefile
index 4cee256..11551b3 100644
--- a/drivers/w1/masters/Makefile
+++ b/drivers/w1/masters/Makefile
@@ -5,4 +5,4 @@
obj-$(CONFIG_W1_MASTER_MATROX) += matrox_w1.o
obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o
obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o
-
+obj-$(CONFIG_W1_MASTER_DS1WM) += ds1wm.o
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
new file mode 100644
index 0000000..763bc73
--- /dev/null
+++ b/drivers/w1/masters/ds1wm.c
@@ -0,0 +1,468 @@
+/*
+ * 1-wire busmaster driver for DS1WM and ASICs with embedded DS1WMs
+ * such as HP iPAQs (including h5xxx, h2200, and devices with ASIC3
+ * like hx4700).
+ *
+ * Copyright (c) 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
+ * Copyright (c) 2004-2007, Matt Reimer <mreimer@vpop.net>
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/ds1wm.h>
+
+#include <asm/io.h>
+
+#include "../w1.h"
+#include "../w1_int.h"
+
+
+#define DS1WM_CMD 0x00 /* R/W 4 bits command */
+#define DS1WM_DATA 0x01 /* R/W 8 bits, transmit/receive buffer */
+#define DS1WM_INT 0x02 /* R/W interrupt status */
+#define DS1WM_INT_EN 0x03 /* R/W interrupt enable */
+#define DS1WM_CLKDIV 0x04 /* R/W 5 bits of divisor and pre-scale */
+
+#define DS1WM_CMD_1W_RESET (1 << 0) /* force reset on 1-wire bus */
+#define DS1WM_CMD_SRA (1 << 1) /* enable Search ROM accelerator mode */
+#define DS1WM_CMD_DQ_OUTPUT (1 << 2) /* write only - forces bus low */
+#define DS1WM_CMD_DQ_INPUT (1 << 3) /* read only - reflects state of bus */
+#define DS1WM_CMD_RST (1 << 5) /* software reset */
+#define DS1WM_CMD_OD (1 << 7) /* overdrive */
+
+#define DS1WM_INT_PD (1 << 0) /* presence detect */
+#define DS1WM_INT_PDR (1 << 1) /* presence detect result */
+#define DS1WM_INT_TBE (1 << 2) /* tx buffer empty */
+#define DS1WM_INT_TSRE (1 << 3) /* tx shift register empty */
+#define DS1WM_INT_RBF (1 << 4) /* rx buffer full */
+#define DS1WM_INT_RSRF (1 << 5) /* rx shift register full */
+
+#define DS1WM_INTEN_EPD (1 << 0) /* enable presence detect int */
+#define DS1WM_INTEN_IAS (1 << 1) /* INTR active state */
+#define DS1WM_INTEN_ETBE (1 << 2) /* enable tx buffer empty int */
+#define DS1WM_INTEN_ETMT (1 << 3) /* enable tx shift register empty int */
+#define DS1WM_INTEN_ERBF (1 << 4) /* enable rx buffer full int */
+#define DS1WM_INTEN_ERSRF (1 << 5) /* enable rx shift register full int */
+#define DS1WM_INTEN_DQO (1 << 6) /* enable direct bus driving ops */
+
+
+#define DS1WM_TIMEOUT (HZ * 5)
+
+static struct {
+ unsigned long freq;
+ unsigned long divisor;
+} freq[] = {
+ { 4000000, 0x8 },
+ { 5000000, 0x2 },
+ { 6000000, 0x5 },
+ { 7000000, 0x3 },
+ { 8000000, 0xc },
+ { 10000000, 0x6 },
+ { 12000000, 0x9 },
+ { 14000000, 0x7 },
+ { 16000000, 0x10 },
+ { 20000000, 0xa },
+ { 24000000, 0xd },
+ { 28000000, 0xb },
+ { 32000000, 0x14 },
+ { 40000000, 0xe },
+ { 48000000, 0x11 },
+ { 56000000, 0xf },
+ { 64000000, 0x18 },
+ { 80000000, 0x12 },
+ { 96000000, 0x15 },
+ { 112000000, 0x13 },
+ { 128000000, 0x1c },
+};
+
+struct ds1wm_data {
+ void *map;
+ int bus_shift; /* # of shifts to calc register offsets */
+ struct platform_device *pdev;
+ struct ds1wm_platform_data *pdata;
+ int irq;
+ int active_high;
+ struct clk *clk;
+ int slave_present;
+ void *reset_complete;
+ void *read_complete;
+ void *write_complete;
+ u8 read_byte; /* last byte received */
+};
+
+static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg,
+ u8 val)
+{
+ __raw_writeb(val, ds1wm_data->map + (reg << ds1wm_data->bus_shift));
+}
+
+static inline u8 ds1wm_read_register(struct ds1wm_data *ds1wm_data, u32 reg)
+{
+ return __raw_readb(ds1wm_data->map + (reg << ds1wm_data->bus_shift));
+}
+
+
+static irqreturn_t ds1wm_isr(int isr, void *data)
+{
+ struct ds1wm_data *ds1wm_data = data;
+ u8 intr = ds1wm_read_register(ds1wm_data, DS1WM_INT);
+
+ ds1wm_data->slave_present = (intr & DS1WM_INT_PDR) ? 0 : 1;
+
+ if ((intr & DS1WM_INT_PD) && ds1wm_data->reset_complete)
+ complete(ds1wm_data->reset_complete);
+
+ if ((intr & DS1WM_INT_TSRE) && ds1wm_data->write_complete)
+ complete(ds1wm_data->write_complete);
+
+ if (intr & DS1WM_INT_RBF) {
+ ds1wm_data->read_byte = ds1wm_read_register(ds1wm_data,
+ DS1WM_DATA);
+ if (ds1wm_data->read_complete)
+ complete(ds1wm_data->read_complete);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int ds1wm_reset(struct ds1wm_data *ds1wm_data)
+{
+ unsigned long timeleft;
+ DECLARE_COMPLETION_ONSTACK(reset_done);
+
+ ds1wm_data->reset_complete = &reset_done;
+
+ ds1wm_write_register(ds1wm_data, DS1WM_INT_EN, DS1WM_INTEN_EPD |
+ (ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0));
+
+ ds1wm_write_register(ds1wm_data, DS1WM_CMD, DS1WM_CMD_1W_RESET);
+
+ timeleft = wait_for_completion_timeout(&reset_done, DS1WM_TIMEOUT);
+ ds1wm_data->reset_complete = NULL;
+ if (!timeleft) {
+ dev_dbg(&ds1wm_data->pdev->dev, "reset failed\n");
+ return 1;
+ }
+
+ /* Wait for the end of the reset. According to the specs, the time
+ * from when the interrupt is asserted to the end of the reset is:
+ * tRSTH - tPDH - tPDL - tPDI
+ * 625 us - 60 us - 240 us - 100 ns = 324.9 us
+ *
+ * We'll wait a bit longer just to be sure.
+ */
+ udelay(500);
+
+ ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
+ DS1WM_INTEN_ERBF | DS1WM_INTEN_ETMT | DS1WM_INTEN_EPD |
+ (ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0));
+
+ if (!ds1wm_data->slave_present) {
+ dev_dbg(&ds1wm_data->pdev->dev, "reset: no devices found\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+static int ds1wm_write(struct ds1wm_data *ds1wm_data, u8 data)
+{
+ DECLARE_COMPLETION_ONSTACK(write_done);
+ ds1wm_data->write_complete = &write_done;
+
+ ds1wm_write_register(ds1wm_data, DS1WM_DATA, data);
+
+ wait_for_completion_timeout(&write_done, DS1WM_TIMEOUT);
+ ds1wm_data->write_complete = NULL;
+
+ return 0;
+}
+
+static int ds1wm_read(struct ds1wm_data *ds1wm_data, unsigned char write_data)
+{
+ DECLARE_COMPLETION_ONSTACK(read_done);
+ ds1wm_data->read_complete = &read_done;
+
+ ds1wm_write(ds1wm_data, write_data);
+ wait_for_completion_timeout(&read_done, DS1WM_TIMEOUT);
+ ds1wm_data->read_complete = NULL;
+
+ return ds1wm_data->read_byte;
+}
+
+static int ds1wm_find_divisor(int gclk)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(freq); i++)
+ if (gclk <= freq[i].freq)
+ return freq[i].divisor;
+
+ return 0;
+}
+
+static void ds1wm_up(struct ds1wm_data *ds1wm_data)
+{
+ int gclk, divisor;
+
+ if (ds1wm_data->pdata->enable)
+ ds1wm_data->pdata->enable(ds1wm_data->pdev);
+
+ gclk = clk_get_rate(ds1wm_data->clk);
+ clk_enable(ds1wm_data->clk);
+ divisor = ds1wm_find_divisor(gclk);
+ if (divisor == 0) {
+ dev_err(&ds1wm_data->pdev->dev,
+ "no suitable divisor for %dHz clock\n", gclk);
+ return;
+ }
+ ds1wm_write_register(ds1wm_data, DS1WM_CLKDIV, divisor);
+
+ /* Let the w1 clock stabilize. */
+ msleep(1);
+
+ ds1wm_reset(ds1wm_data);
+}
+
+static void ds1wm_down(struct ds1wm_data *ds1wm_data)
+{
+ ds1wm_reset(ds1wm_data);
+
+ /* Disable interrupts. */
+ ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
+ ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0);
+
+ if (ds1wm_data->pdata->disable)
+ ds1wm_data->pdata->disable(ds1wm_data->pdev);
+
+ clk_disable(ds1wm_data->clk);
+}
+
+/* --------------------------------------------------------------------- */
+/* w1 methods */
+
+static u8 ds1wm_read_byte(void *data)
+{
+ struct ds1wm_data *ds1wm_data = data;
+
+ return ds1wm_read(ds1wm_data, 0xff);
+}
+
+static void ds1wm_write_byte(void *data, u8 byte)
+{
+ struct ds1wm_data *ds1wm_data = data;
+
+ ds1wm_write(ds1wm_data, byte);
+}
+
+static u8 ds1wm_reset_bus(void *data)
+{
+ struct ds1wm_data *ds1wm_data = data;
+
+ ds1wm_reset(ds1wm_data);
+
+ return 0;
+}
+
+static void ds1wm_search(void *data, u8 search_type,
+ w1_slave_found_callback slave_found)
+{
+ struct ds1wm_data *ds1wm_data = data;
+ int i;
+ unsigned long long rom_id;
+
+ /* XXX We need to iterate for multiple devices per the DS1WM docs.
+ * See http://www.maxim-ic.com/appnotes.cfm/appnote_number/120. */
+ if (ds1wm_reset(ds1wm_data))
+ return;
+
+ ds1wm_write(ds1wm_data, search_type);
+ ds1wm_write_register(ds1wm_data, DS1WM_CMD, DS1WM_CMD_SRA);
+
+ for (rom_id = 0, i = 0; i < 16; i++) {
+
+ unsigned char resp, r, d;
+
+ resp = ds1wm_read(ds1wm_data, 0x00);
+
+ r = ((resp & 0x02) >> 1) |
+ ((resp & 0x08) >> 2) |
+ ((resp & 0x20) >> 3) |
+ ((resp & 0x80) >> 4);
+
+ d = ((resp & 0x01) >> 0) |
+ ((resp & 0x04) >> 1) |
+ ((resp & 0x10) >> 2) |
+ ((resp & 0x40) >> 3);
+
+ rom_id |= (unsigned long long) r << (i * 4);
+
+ }
+ dev_dbg(&ds1wm_data->pdev->dev, "found 0x%08llX", rom_id);
+
+ ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA);
+ ds1wm_reset(ds1wm_data);
+
+ slave_found(ds1wm_data, rom_id);
+}
+
+/* --------------------------------------------------------------------- */
+
+static struct w1_bus_master ds1wm_master = {
+ .read_byte = ds1wm_read_byte,
+ .write_byte = ds1wm_write_byte,
+ .reset_bus = ds1wm_reset_bus,
+ .search = ds1wm_search,
+};
+
+static int ds1wm_probe(struct platform_device *pdev)
+{
+ struct ds1wm_data *ds1wm_data;
+ struct ds1wm_platform_data *plat;
+ struct resource *res;
+ int ret;
+
+ if (!pdev)
+ return -ENODEV;
+
+ ds1wm_data = kzalloc(sizeof (*ds1wm_data), GFP_KERNEL);
+ if (!ds1wm_data)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, ds1wm_data);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ ret = -ENXIO;
+ goto err0;
+ }
+ ds1wm_data->map = ioremap(res->start, res->end - res->start + 1);
+ if (!ds1wm_data->map) {
+ ret = -ENOMEM;
+ goto err0;
+ }
+ plat = pdev->dev.platform_data;
+ ds1wm_data->bus_shift = plat->bus_shift;
+ ds1wm_data->pdev = pdev;
+ ds1wm_data->pdata = plat;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ ret = -ENXIO;
+ goto err1;
+ }
+ ds1wm_data->irq = res->start;
+ ds1wm_data->active_high = (res->flags & IORESOURCE_IRQ_HIGHEDGE) ?
+ 1 : 0;
+
+ set_irq_type(ds1wm_data->irq, ds1wm_data->active_high ?
+ IRQ_TYPE_EDGE_RISING : IRQ_TYPE_EDGE_FALLING);
+
+ ret = request_irq(ds1wm_data->irq, ds1wm_isr, IRQF_DISABLED,
+ "ds1wm", ds1wm_data);
+ if (ret)
+ goto err1;
+
+ ds1wm_data->clk = clk_get(&pdev->dev, "ds1wm");
+ if (!ds1wm_data->clk) {
+ ret = -ENOENT;
+ goto err2;
+ }
+
+ ds1wm_up(ds1wm_data);
+
+ ds1wm_master.data = (void *)ds1wm_data;
+
+ ret = w1_add_master_device(&ds1wm_master);
+ if (ret)
+ goto err3;
+
+ return 0;
+
+err3:
+ ds1wm_down(ds1wm_data);
+ clk_put(ds1wm_data->clk);
+err2:
+ free_irq(ds1wm_data->irq, ds1wm_data);
+err1:
+ iounmap(ds1wm_data->map);
+err0:
+ kfree(ds1wm_data);
+
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static int ds1wm_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
+
+ ds1wm_down(ds1wm_data);
+
+ return 0;
+}
+
+static int ds1wm_resume(struct platform_device *pdev)
+{
+ struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
+
+ ds1wm_up(ds1wm_data);
+
+ return 0;
+}
+#else
+#define ds1wm_suspend NULL
+#define ds1wm_resume NULL
+#endif
+
+static int ds1wm_remove(struct platform_device *pdev)
+{
+ struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
+
+ w1_remove_master_device(&ds1wm_master);
+ ds1wm_down(ds1wm_data);
+ clk_put(ds1wm_data->clk);
+ free_irq(ds1wm_data->irq, ds1wm_data);
+ iounmap(ds1wm_data->map);
+ kfree(ds1wm_data);
+
+ return 0;
+}
+
+static struct platform_driver ds1wm_driver = {
+ .driver = {
+ .name = "ds1wm",
+ },
+ .probe = ds1wm_probe,
+ .remove = ds1wm_remove,
+ .suspend = ds1wm_suspend,
+ .resume = ds1wm_resume
+};
+
+static int __init ds1wm_init(void)
+{
+ printk("DS1WM w1 busmaster driver - (c) 2004 Szabolcs Gyurko\n");
+ return platform_driver_register(&ds1wm_driver);
+}
+
+static void __exit ds1wm_exit(void)
+{
+ platform_driver_unregister(&ds1wm_driver);
+}
+
+module_init(ds1wm_init);
+module_exit(ds1wm_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, "
+ "Matt Reimer <mreimer@vpop.net>");
+MODULE_DESCRIPTION("DS1WM w1 busmaster driver");
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 63c0724..7d6876d 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -459,7 +459,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
(unsigned long long) sl->reg_num.id);
dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__,
- &sl->dev.bus_id[0]);
+ &sl->dev.bus_id[0], sl);
err = device_register(&sl->dev);
if (err < 0) {
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 357a2e0..258defd 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -100,7 +100,8 @@ int w1_add_master_device(struct w1_bus_master *master)
/* validate minimum functionality */
if (!(master->touch_bit && master->reset_bus) &&
- !(master->write_bit && master->read_bit)) {
+ !(master->write_bit && master->read_bit) &&
+ !(master->write_byte && master->read_byte && master->reset_bus)) {
printk(KERN_ERR "w1_add_master_device: invalid function set\n");
return(-EINVAL);
}
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
index bed48fa..3128aa9 100644
--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -29,7 +29,6 @@
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/inet.h>
#include <linux/pagemap.h>
#include <linux/idr.h>
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
index ddffd8a..775e26e 100644
--- a/fs/9p/vfs_dentry.c
+++ b/fs/9p/vfs_dentry.c
@@ -30,7 +30,6 @@
#include <linux/pagemap.h>
#include <linux/stat.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/inet.h>
#include <linux/namei.h>
#include <linux/idr.h>
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index 3129688..1dd86ee 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -29,7 +29,6 @@
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/sched.h>
#include <linux/inet.h>
#include <linux/idr.h>
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index c7b6772..6e7678e 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -30,7 +30,6 @@
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/inet.h>
#include <linux/list.h>
#include <asm/uaccess.h>
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index b01b0a4..7624821 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -30,7 +30,6 @@
#include <linux/pagemap.h>
#include <linux/stat.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/inet.h>
#include <linux/namei.h>
#include <linux/idr.h>
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 0ec42f6..8eb9263 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -31,7 +31,6 @@
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/inet.h>
#include <linux/pagemap.h>
#include <linux/seq_file.h>
diff --git a/fs/Kconfig b/fs/Kconfig
index 8ea7b04..4622dab 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -314,7 +314,7 @@ config REISERFS_CHECK
config REISERFS_PROC_INFO
bool "Stats in /proc/fs/reiserfs"
- depends on REISERFS_FS
+ depends on REISERFS_FS && PROC_FS
help
Create under /proc/fs/reiserfs a hierarchy of files, displaying
various ReiserFS statistics and internal data at the expense of
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index f3d3d81..74c6440 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -26,7 +26,7 @@ config BINFMT_ELF
config BINFMT_ELF_FDPIC
bool "Kernel support for FDPIC ELF binaries"
default y
- depends on FRV
+ depends on (FRV || BLACKFIN)
help
ELF FDPIC binaries are based on ELF, but allow the individual load
segments of a binary to be located in memory independently of each
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index 2e5f2c8..30c2965 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -232,8 +232,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct adfs_inode_info *ei = (struct adfs_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&ei->vfs_inode);
}
diff --git a/fs/affs/super.c b/fs/affs/super.c
index c3986a1..beff7d2 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -87,8 +87,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct affs_inode_info *ei = (struct affs_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
init_MUTEX(&ei->i_link_lock);
init_MUTEX(&ei->i_ext_lock);
inode_init_once(&ei->vfs_inode);
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index dac5b99..0c1e902 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -194,10 +194,7 @@ static struct page *afs_dir_get_page(struct inode *dir, unsigned long index,
page = read_mapping_page(dir->i_mapping, index, &file);
if (!IS_ERR(page)) {
- wait_on_page_locked(page);
kmap(page);
- if (!PageUptodate(page))
- goto fail;
if (!PageChecked(page))
afs_dir_check_page(dir, page);
if (PageError(page))
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index b905ae3..034fcfd 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -68,13 +68,11 @@ int afs_mntpt_check_symlink(struct afs_vnode *vnode, struct key *key)
}
ret = -EIO;
- wait_on_page_locked(page);
- buf = kmap(page);
- if (!PageUptodate(page))
- goto out_free;
if (PageError(page))
goto out_free;
+ buf = kmap(page);
+
/* examine the symlink's contents */
size = vnode->status.size;
_debug("symlink to %*.*s", (int) size, (int) size, buf);
@@ -91,8 +89,8 @@ int afs_mntpt_check_symlink(struct afs_vnode *vnode, struct key *key)
ret = 0;
-out_free:
kunmap(page);
+out_free:
page_cache_release(page);
out:
_leave(" = %d", ret);
@@ -171,8 +169,7 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
}
ret = -EIO;
- wait_on_page_locked(page);
- if (!PageUptodate(page) || PageError(page))
+ if (PageError(page))
goto error;
buf = kmap(page);
diff --git a/fs/afs/super.c b/fs/afs/super.c
index 41173f8..7030d76 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -453,8 +453,7 @@ static void afs_i_init_once(void *_vnode, struct kmem_cache *cachep,
{
struct afs_vnode *vnode = _vnode;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
memset(vnode, 0, sizeof(*vnode));
inode_init_once(&vnode->vfs_inode);
init_waitqueue_head(&vnode->update_waitq);
diff --git a/fs/aio.c b/fs/aio.c
index e4598d6..b97ab80 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -68,10 +68,8 @@ static void aio_queue_work(struct kioctx *);
*/
static int __init aio_setup(void)
{
- kiocb_cachep = kmem_cache_create("kiocb", sizeof(struct kiocb),
- 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
- kioctx_cachep = kmem_cache_create("kioctx", sizeof(struct kioctx),
- 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
+ kiocb_cachep = KMEM_CACHE(kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC);
+ kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC);
aio_wq = create_workqueue("aio");
diff --git a/fs/attr.c b/fs/attr.c
index 97de946..a0a0c7b 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -9,7 +9,6 @@
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/capability.h>
#include <linux/fsnotify.h>
#include <linux/fcntl.h>
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 26063dc..5769a2f 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -18,7 +18,6 @@
#include <linux/pagemap.h>
#include <linux/parser.h>
#include <linux/bitops.h>
-#include <linux/smp_lock.h>
#include <linux/magic.h>
#include "autofs_i.h"
#include <linux/module.h>
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index d0e9b3a..15170f4 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -17,7 +17,6 @@
#include <linux/stat.h>
#include <linux/param.h>
#include <linux/time.h>
-#include <linux/smp_lock.h>
#include "autofs_i.h"
static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *);
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index efeab2f..329ee47 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -12,7 +12,6 @@
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/time.h>
-#include <linux/smp_lock.h>
#include <linux/namei.h>
#include <linux/poll.h>
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index cc6cc8e..fe96108 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -293,8 +293,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct befs_inode_info *bi = (struct befs_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
inode_init_once(&bi->vfs_inode);
}
}
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 93d6219..edc08d8 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -248,8 +248,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct bfs_inode_info *bi = foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&bi->vfs_inode);
}
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 9cc4f0a..fa8ea33 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -31,7 +31,6 @@
#include <linux/init.h>
#include <linux/highuid.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/compiler.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
@@ -39,6 +38,7 @@
#include <linux/syscalls.h>
#include <linux/random.h>
#include <linux/elf.h>
+#include <linux/utsname.h>
#include <asm/uaccess.h>
#include <asm/param.h>
#include <asm/page.h>
@@ -871,6 +871,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
elf_prot, elf_flags);
if (BAD_ADDR(error)) {
send_sig(SIGKILL, current, 0);
+ retval = IS_ERR((void *)error) ?
+ PTR_ERR((void*)error) : -EINVAL;
goto out_free_dentry;
}
@@ -900,6 +902,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
TASK_SIZE - elf_ppnt->p_memsz < k) {
/* set_brk can never work. Avoid overflows. */
send_sig(SIGKILL, current, 0);
+ retval = -EINVAL;
goto out_free_dentry;
}
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index f3ddca4..9d62fba 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -30,7 +30,6 @@
#include <linux/personality.h>
#include <linux/ptrace.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/elf.h>
#include <linux/elf-fdpic.h>
#include <linux/elfcore.h>
diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c
index 1f2d1ad..576dd7d 100644
--- a/fs/binfmt_em86.c
+++ b/fs/binfmt_em86.c
@@ -12,7 +12,6 @@
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/binfmts.h>
#include <linux/elf.h>
#include <linux/init.h>
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index e6f5799..18657f0 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -727,8 +727,8 @@ static const struct super_operations s_ops = {
static int bm_fill_super(struct super_block * sb, void * data, int silent)
{
static struct tree_descr bm_files[] = {
- [1] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
- [2] = {"register", &bm_register_operations, S_IWUSR},
+ [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
+ [3] = {"register", &bm_register_operations, S_IWUSR},
/* last one */ {""}
};
int err = simple_fill_super(sb, 0x42494e4d, bm_files);
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
index 1edbcca..304c885 100644
--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -12,7 +12,6 @@
#include <linux/binfmts.h>
#include <linux/init.h>
#include <linux/file.h>
-#include <linux/smp_lock.h>
#include <linux/err.h>
#include <linux/fs.h>
diff --git a/fs/bio.c b/fs/bio.c
index 693940d..093345f 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1193,8 +1193,7 @@ static void __init biovec_init_slabs(void)
static int __init init_bio(void)
{
- bio_slab = kmem_cache_create("bio", sizeof(struct bio), 0,
- SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
+ bio_slab = KMEM_CACHE(bio, SLAB_HWCACHE_ALIGN|SLAB_PANIC);
biovec_init_slabs();
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 575076c..7428992 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -22,6 +22,7 @@
#include <linux/mount.h>
#include <linux/uio.h>
#include <linux/namei.h>
+#include <linux/log2.h>
#include <asm/uaccess.h>
#include "internal.h"
@@ -55,17 +56,19 @@ static sector_t max_block(struct block_device *bdev)
return retval;
}
-/* Kill _all_ buffers, dirty or not.. */
+/* Kill _all_ buffers and pagecache , dirty or not.. */
static void kill_bdev(struct block_device *bdev)
{
- invalidate_bdev(bdev, 1);
+ if (bdev->bd_inode->i_mapping->nrpages == 0)
+ return;
+ invalidate_bh_lrus();
truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
}
int set_blocksize(struct block_device *bdev, int size)
{
/* Size must be a power of two, and between 512 and PAGE_SIZE */
- if (size > PAGE_SIZE || size < 512 || (size & (size-1)))
+ if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size))
return -EINVAL;
/* Size cannot be smaller than the size supported by the device */
@@ -455,9 +458,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
struct bdev_inode *ei = (struct bdev_inode *) foo;
struct block_device *bdev = &ei->bdev;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
- {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
memset(bdev, 0, sizeof(*bdev));
mutex_init(&bdev->bd_mutex);
sema_init(&bdev->bd_mount_sem, 1);
@@ -1478,7 +1479,7 @@ int __invalidate_device(struct block_device *bdev)
res = invalidate_inodes(sb);
drop_super(sb);
}
- invalidate_bdev(bdev, 0);
+ invalidate_bdev(bdev);
return res;
}
EXPORT_SYMBOL(__invalidate_device);
diff --git a/fs/buffer.c b/fs/buffer.c
index 1d0852f..eb820b8 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -24,7 +24,6 @@
#include <linux/mm.h>
#include <linux/percpu.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/capability.h>
#include <linux/blkdev.h>
#include <linux/file.h>
@@ -44,7 +43,6 @@
#include <linux/bit_spinlock.h>
static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
-static void invalidate_bh_lrus(void);
#define BH_ENTRY(list) list_entry((list), struct buffer_head, b_assoc_buffers)
@@ -333,7 +331,7 @@ out:
we think the disk contains more recent information than the buffercache.
The update == 1 pass marks the buffers we need to update, the update == 2
pass does the actual I/O. */
-void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers)
+void invalidate_bdev(struct block_device *bdev)
{
struct address_space *mapping = bdev->bd_inode->i_mapping;
@@ -341,11 +339,6 @@ void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers)
return;
invalidate_bh_lrus();
- /*
- * FIXME: what about destroy_dirty_buffers?
- * We really want to use invalidate_inode_pages2() for
- * that, but not until that's cleaned up.
- */
invalidate_mapping_pages(mapping, 0, -1);
}
@@ -1408,7 +1401,7 @@ static void invalidate_bh_lru(void *arg)
put_cpu_var(bh_lrus);
}
-static void invalidate_bh_lrus(void)
+void invalidate_bh_lrus(void)
{
on_each_cpu(invalidate_bh_lru, NULL, 1, 1);
}
@@ -1700,17 +1693,8 @@ done:
* clean. Someone wrote them back by hand with
* ll_rw_block/submit_bh. A rare case.
*/
- int uptodate = 1;
- do {
- if (!buffer_uptodate(bh)) {
- uptodate = 0;
- break;
- }
- bh = bh->b_this_page;
- } while (bh != head);
- if (uptodate)
- SetPageUptodate(page);
end_page_writeback(page);
+
/*
* The page and buffer_heads can be released at any time from
* here on.
@@ -1742,6 +1726,7 @@ recover:
} while ((bh = bh->b_this_page) != head);
SetPageError(page);
BUG_ON(PageWriteback(page));
+ mapping_set_error(page->mapping, err);
set_page_writeback(page);
do {
struct buffer_head *next = bh->b_this_page;
@@ -2968,8 +2953,7 @@ EXPORT_SYMBOL(free_buffer_head);
static void
init_buffer_head(void *data, struct kmem_cache *cachep, unsigned long flags)
{
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
struct buffer_head * bh = (struct buffer_head *)data;
memset(bh, 0, sizeof(*bh));
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 5036dae..8568e10 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -701,8 +701,7 @@ cifs_init_once(void *inode, struct kmem_cache * cachep, unsigned long flags)
{
struct cifsInodeInfo *cifsi = inode;
- if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
inode_init_once(&cifsi->vfs_inode);
INIT_LIST_HEAD(&cifsi->lockList);
}
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index b570530..94d5b49 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -27,7 +27,6 @@
#include <linux/fcntl.h>
#include <linux/pagemap.h>
#include <linux/pagevec.h>
-#include <linux/smp_lock.h>
#include <linux/writeback.h>
#include <linux/task_io_accounting_ops.h>
#include <linux/delay.h>
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index b5364f90..c08bda9 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -23,7 +23,6 @@
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/stat.h>
-#include <linux/smp_lock.h>
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsproto.h"
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 614175a..0aaff36 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -62,8 +62,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct coda_inode_info *ei = (struct coda_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&ei->vfs_inode);
}
diff --git a/fs/compat.c b/fs/compat.c
index 72e5e69..9cf75df 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -15,6 +15,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/kernel.h>
#include <linux/linkage.h>
#include <linux/compat.h>
#include <linux/errno.h>
@@ -24,10 +25,8 @@
#include <linux/namei.h>
#include <linux/file.h>
#include <linux/vfs.h>
-#include <linux/ioctl32.h>
#include <linux/ioctl.h>
#include <linux/init.h>
-#include <linux/sockios.h> /* for SIOCDEVPRIVATE */
#include <linux/smb.h>
#include <linux/smb_mount.h>
#include <linux/ncp_mount.h>
@@ -45,13 +44,12 @@
#include <linux/personality.h>
#include <linux/rwsem.h>
#include <linux/tsacct_kern.h>
+#include <linux/security.h>
#include <linux/highmem.h>
#include <linux/poll.h>
#include <linux/mm.h>
#include <linux/eventpoll.h>
-#include <net/sock.h> /* siocdevprivate_ioctl */
-
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/ioctls.h>
@@ -79,30 +77,57 @@ int compat_printk(const char *fmt, ...)
*/
asmlinkage long compat_sys_utime(char __user *filename, struct compat_utimbuf __user *t)
{
- struct timeval tv[2];
+ struct timespec tv[2];
if (t) {
if (get_user(tv[0].tv_sec, &t->actime) ||
get_user(tv[1].tv_sec, &t->modtime))
return -EFAULT;
- tv[0].tv_usec = 0;
- tv[1].tv_usec = 0;
+ tv[0].tv_nsec = 0;
+ tv[1].tv_nsec = 0;
+ }
+ return do_utimes(AT_FDCWD, filename, t ? tv : NULL, 0);
+}
+
+asmlinkage long compat_sys_utimensat(unsigned int dfd, char __user *filename, struct compat_timespec __user *t, int flags)
+{
+ struct timespec tv[2];
+
+ if (t) {
+ if (get_compat_timespec(&tv[0], &t[0]) ||
+ get_compat_timespec(&tv[1], &t[1]))
+ return -EFAULT;
+
+ if ((tv[0].tv_nsec == UTIME_OMIT || tv[0].tv_nsec == UTIME_NOW)
+ && tv[0].tv_sec != 0)
+ return -EINVAL;
+ if ((tv[1].tv_nsec == UTIME_OMIT || tv[1].tv_nsec == UTIME_NOW)
+ && tv[1].tv_sec != 0)
+ return -EINVAL;
+
+ if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT)
+ return 0;
}
- return do_utimes(AT_FDCWD, filename, t ? tv : NULL);
+ return do_utimes(dfd, filename, t ? tv : NULL, flags);
}
asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, struct compat_timeval __user *t)
{
- struct timeval tv[2];
+ struct timespec tv[2];
if (t) {
if (get_user(tv[0].tv_sec, &t[0].tv_sec) ||
- get_user(tv[0].tv_usec, &t[0].tv_usec) ||
+ get_user(tv[0].tv_nsec, &t[0].tv_usec) ||
get_user(tv[1].tv_sec, &t[1].tv_sec) ||
- get_user(tv[1].tv_usec, &t[1].tv_usec))
+ get_user(tv[1].tv_nsec, &t[1].tv_usec))
return -EFAULT;
+ if (tv[0].tv_nsec >= 1000000 || tv[0].tv_nsec < 0 ||
+ tv[1].tv_nsec >= 1000000 || tv[1].tv_nsec < 0)
+ return -EINVAL;
+ tv[0].tv_nsec *= 1000;
+ tv[1].tv_nsec *= 1000;
}
- return do_utimes(dfd, filename, t ? tv : NULL);
+ return do_utimes(dfd, filename, t ? tv : NULL, 0);
}
asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval __user *t)
@@ -312,163 +337,6 @@ out:
return error;
}
-/* ioctl32 stuff, used by sparc64, parisc, s390x, ppc64, x86_64, MIPS */
-
-#define IOCTL_HASHSIZE 256
-static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE];
-
-static inline unsigned long ioctl32_hash(unsigned long cmd)
-{
- return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE;
-}
-
-static void ioctl32_insert_translation(struct ioctl_trans *trans)
-{
- unsigned long hash;
- struct ioctl_trans *t;
-
- hash = ioctl32_hash (trans->cmd);
- if (!ioctl32_hash_table[hash])
- ioctl32_hash_table[hash] = trans;
- else {
- t = ioctl32_hash_table[hash];
- while (t->next)
- t = t->next;
- trans->next = NULL;
- t->next = trans;
- }
-}
-
-static int __init init_sys32_ioctl(void)
-{
- int i;
-
- for (i = 0; i < ioctl_table_size; i++) {
- if (ioctl_start[i].next != 0) {
- printk("ioctl translation %d bad\n",i);
- return -1;
- }
-
- ioctl32_insert_translation(&ioctl_start[i]);
- }
- return 0;
-}
-
-__initcall(init_sys32_ioctl);
-
-static void compat_ioctl_error(struct file *filp, unsigned int fd,
- unsigned int cmd, unsigned long arg)
-{
- char buf[10];
- char *fn = "?";
- char *path;
-
- /* find the name of the device. */
- path = (char *)__get_free_page(GFP_KERNEL);
- if (path) {
- fn = d_path(filp->f_path.dentry, filp->f_path.mnt, path, PAGE_SIZE);
- if (IS_ERR(fn))
- fn = "?";
- }
-
- sprintf(buf,"'%c'", (cmd>>_IOC_TYPESHIFT) & _IOC_TYPEMASK);
- if (!isprint(buf[1]))
- sprintf(buf, "%02x", buf[1]);
- compat_printk("ioctl32(%s:%d): Unknown cmd fd(%d) "
- "cmd(%08x){t:%s;sz:%u} arg(%08x) on %s\n",
- current->comm, current->pid,
- (int)fd, (unsigned int)cmd, buf,
- (cmd >> _IOC_SIZESHIFT) & _IOC_SIZEMASK,
- (unsigned int)arg, fn);
-
- if (path)
- free_page((unsigned long)path);
-}
-
-asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
- unsigned long arg)
-{
- struct file *filp;
- int error = -EBADF;
- struct ioctl_trans *t;
- int fput_needed;
-
- filp = fget_light(fd, &fput_needed);
- if (!filp)
- goto out;
-
- /* RED-PEN how should LSM module know it's handling 32bit? */
- error = security_file_ioctl(filp, cmd, arg);
- if (error)
- goto out_fput;
-
- /*
- * To allow the compat_ioctl handlers to be self contained
- * we need to check the common ioctls here first.
- * Just handle them with the standard handlers below.
- */
- switch (cmd) {
- case FIOCLEX:
- case FIONCLEX:
- case FIONBIO:
- case FIOASYNC:
- case FIOQSIZE:
- break;
-
- case FIBMAP:
- case FIGETBSZ:
- case FIONREAD:
- if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
- break;
- /*FALL THROUGH*/
-
- default:
- if (filp->f_op && filp->f_op->compat_ioctl) {
- error = filp->f_op->compat_ioctl(filp, cmd, arg);
- if (error != -ENOIOCTLCMD)
- goto out_fput;
- }
-
- if (!filp->f_op ||
- (!filp->f_op->ioctl && !filp->f_op->unlocked_ioctl))
- goto do_ioctl;
- break;
- }
-
- for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) {
- if (t->cmd == cmd)
- goto found_handler;
- }
-
- if (S_ISSOCK(filp->f_path.dentry->d_inode->i_mode) &&
- cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
- error = siocdevprivate_ioctl(fd, cmd, arg);
- } else {
- static int count;
-
- if (++count <= 50)
- compat_ioctl_error(filp, fd, cmd, arg);
- error = -EINVAL;
- }
-
- goto out_fput;
-
- found_handler:
- if (t->handler) {
- lock_kernel();
- error = t->handler(fd, cmd, arg, filp);
- unlock_kernel();
- goto out_fput;
- }
-
- do_ioctl:
- error = vfs_ioctl(filp, fd, cmd, arg);
- out_fput:
- fput_light(filp, fput_needed);
- out:
- return error;
-}
-
static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl)
{
if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) ||
@@ -902,8 +770,6 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
}
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
-#define COMPAT_ROUND_UP(x) (((x)+sizeof(compat_long_t)-1) & \
- ~(sizeof(compat_long_t)-1))
struct compat_old_linux_dirent {
compat_ulong_t d_ino;
@@ -991,7 +857,7 @@ static int compat_filldir(void *__buf, const char *name, int namlen,
struct compat_linux_dirent __user * dirent;
struct compat_getdents_callback *buf = __buf;
compat_ulong_t d_ino;
- int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
+ int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 2, sizeof(compat_long_t));
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
@@ -1066,7 +932,6 @@ out:
}
#ifndef __ARCH_OMIT_COMPAT_SYS_GETDENTS64
-#define COMPAT_ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
struct compat_getdents_callback64 {
struct linux_dirent64 __user *current_dir;
@@ -1081,7 +946,7 @@ static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t
struct linux_dirent64 __user *dirent;
struct compat_getdents_callback64 *buf = __buf;
int jj = NAME_OFFSET(dirent);
- int reclen = COMPAT_ROUND_UP64(jj + namlen + 1);
+ int reclen = ALIGN(jj + namlen + 1, sizeof(u64));
u64 off;
buf->error = -EINVAL; /* only used if we fail.. */
@@ -1594,8 +1459,6 @@ out_ret:
#define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t))
-#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
-
/*
* Ooo, nasty. We need here to frob 32-bit unsigned longs to
* 64-bit unsigned longs.
@@ -1604,7 +1467,7 @@ static
int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
unsigned long *fdset)
{
- nr = ROUND_UP(nr, __COMPAT_NFDBITS);
+ nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS);
if (ufdset) {
unsigned long odd;
@@ -1638,7 +1501,7 @@ int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
unsigned long *fdset)
{
unsigned long odd;
- nr = ROUND_UP(nr, __COMPAT_NFDBITS);
+ nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS);
if (!ufdset)
return 0;
@@ -1760,7 +1623,7 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS)
timeout = -1; /* infinite */
else {
- timeout = ROUND_UP(tv.tv_usec, 1000000/HZ);
+ timeout = DIV_ROUND_UP(tv.tv_usec, 1000000/HZ);
timeout += tv.tv_sec * HZ;
}
}
@@ -1828,7 +1691,7 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp,
do {
if (tsp) {
if ((unsigned long)ts.tv_sec < MAX_SELECT_SECONDS) {
- timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ);
+ timeout = DIV_ROUND_UP(ts.tv_nsec, 1000000000/HZ);
timeout += ts.tv_sec * (unsigned long)HZ;
ts.tv_sec = 0;
ts.tv_nsec = 0;
@@ -1924,7 +1787,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
/* We assume that ts.tv_sec is always lower than
the number of seconds that can be expressed in
an s64. Otherwise the compiler bitches at us */
- timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ);
+ timeout = DIV_ROUND_UP(ts.tv_nsec, 1000000000/HZ);
timeout += ts.tv_sec * HZ;
}
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 464c04a..d92bc3e 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -17,7 +17,6 @@
#include <linux/compiler.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/ioctl.h>
#include <linux/if.h>
#include <linux/if_bridge.h>
@@ -58,7 +57,6 @@
#include <linux/serial.h>
#include <linux/if_tun.h>
#include <linux/ctype.h>
-#include <linux/ioctl32.h>
#include <linux/syscalls.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
@@ -66,7 +64,6 @@
#include <linux/atalk.h>
#include <linux/blktrace_api.h>
-#include <net/sock.h> /* siocdevprivate_ioctl */
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci.h>
#include <net/bluetooth/rfcomm.h>
@@ -475,7 +472,7 @@ static int bond_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
};
}
-int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+static int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct ifreq __user *u_ifreq64;
struct ifreq32 __user *u_ifreq32 = compat_ptr(arg);
@@ -687,8 +684,10 @@ static int hdio_getgeo(unsigned int fd, unsigned int cmd, unsigned long arg)
if (!err) {
err = copy_to_user (ugeo, &geo, 4);
err |= __put_user (geo.start, &ugeo->start);
+ if (err)
+ err = -EFAULT;
}
- return err ? -EFAULT : 0;
+ return err;
}
static int hdio_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -2385,6 +2384,16 @@ lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
return sys_ioctl(fd, cmd, (unsigned long)tn);
}
+
+typedef int (*ioctl_trans_handler_t)(unsigned int, unsigned int,
+ unsigned long, struct file *);
+
+struct ioctl_trans {
+ unsigned long cmd;
+ ioctl_trans_handler_t handler;
+ struct ioctl_trans *next;
+};
+
#define HANDLE_IOCTL(cmd,handler) \
{ (cmd), (ioctl_trans_handler_t)(handler) },
@@ -2405,8 +2414,835 @@ lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
Most other reasons are not valid. */
#define IGNORE_IOCTL(cmd) COMPATIBLE_IOCTL(cmd)
-struct ioctl_trans ioctl_start[] = {
-#include <linux/compat_ioctl.h>
+static struct ioctl_trans ioctl_start[] = {
+/* compatible ioctls first */
+COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */
+COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */
+
+/* Big T */
+COMPATIBLE_IOCTL(TCGETA)
+COMPATIBLE_IOCTL(TCSETA)
+COMPATIBLE_IOCTL(TCSETAW)
+COMPATIBLE_IOCTL(TCSETAF)
+COMPATIBLE_IOCTL(TCSBRK)
+ULONG_IOCTL(TCSBRKP)
+COMPATIBLE_IOCTL(TCXONC)
+COMPATIBLE_IOCTL(TCFLSH)
+COMPATIBLE_IOCTL(TCGETS)
+COMPATIBLE_IOCTL(TCSETS)
+COMPATIBLE_IOCTL(TCSETSW)
+COMPATIBLE_IOCTL(TCSETSF)
+COMPATIBLE_IOCTL(TIOCLINUX)
+COMPATIBLE_IOCTL(TIOCSBRK)
+COMPATIBLE_IOCTL(TIOCCBRK)
+ULONG_IOCTL(TIOCMIWAIT)
+COMPATIBLE_IOCTL(TIOCGICOUNT)
+/* Little t */
+COMPATIBLE_IOCTL(TIOCGETD)
+COMPATIBLE_IOCTL(TIOCSETD)
+COMPATIBLE_IOCTL(TIOCEXCL)
+COMPATIBLE_IOCTL(TIOCNXCL)
+COMPATIBLE_IOCTL(TIOCCONS)
+COMPATIBLE_IOCTL(TIOCGSOFTCAR)
+COMPATIBLE_IOCTL(TIOCSSOFTCAR)
+COMPATIBLE_IOCTL(TIOCSWINSZ)
+COMPATIBLE_IOCTL(TIOCGWINSZ)
+COMPATIBLE_IOCTL(TIOCMGET)
+COMPATIBLE_IOCTL(TIOCMBIC)
+COMPATIBLE_IOCTL(TIOCMBIS)
+COMPATIBLE_IOCTL(TIOCMSET)
+COMPATIBLE_IOCTL(TIOCPKT)
+COMPATIBLE_IOCTL(TIOCNOTTY)
+COMPATIBLE_IOCTL(TIOCSTI)
+COMPATIBLE_IOCTL(TIOCOUTQ)
+COMPATIBLE_IOCTL(TIOCSPGRP)
+COMPATIBLE_IOCTL(TIOCGPGRP)
+ULONG_IOCTL(TIOCSCTTY)
+COMPATIBLE_IOCTL(TIOCGPTN)
+COMPATIBLE_IOCTL(TIOCSPTLCK)
+COMPATIBLE_IOCTL(TIOCSERGETLSR)
+/* Little f */
+COMPATIBLE_IOCTL(FIOCLEX)
+COMPATIBLE_IOCTL(FIONCLEX)
+COMPATIBLE_IOCTL(FIOASYNC)
+COMPATIBLE_IOCTL(FIONBIO)
+COMPATIBLE_IOCTL(FIONREAD) /* This is also TIOCINQ */
+/* 0x00 */
+COMPATIBLE_IOCTL(FIBMAP)
+COMPATIBLE_IOCTL(FIGETBSZ)
+/* 0x03 -- HD/IDE ioctl's used by hdparm and friends.
+ * Some need translations, these do not.
+ */
+COMPATIBLE_IOCTL(HDIO_GET_IDENTITY)
+COMPATIBLE_IOCTL(HDIO_DRIVE_TASK)
+COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
+ULONG_IOCTL(HDIO_SET_MULTCOUNT)
+ULONG_IOCTL(HDIO_SET_UNMASKINTR)
+ULONG_IOCTL(HDIO_SET_KEEPSETTINGS)
+ULONG_IOCTL(HDIO_SET_32BIT)
+ULONG_IOCTL(HDIO_SET_NOWERR)
+ULONG_IOCTL(HDIO_SET_DMA)
+ULONG_IOCTL(HDIO_SET_PIO_MODE)
+ULONG_IOCTL(HDIO_SET_NICE)
+ULONG_IOCTL(HDIO_SET_WCACHE)
+ULONG_IOCTL(HDIO_SET_ACOUSTIC)
+ULONG_IOCTL(HDIO_SET_BUSSTATE)
+ULONG_IOCTL(HDIO_SET_ADDRESS)
+COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
+/* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */
+COMPATIBLE_IOCTL(0x330)
+/* 0x02 -- Floppy ioctls */
+COMPATIBLE_IOCTL(FDMSGON)
+COMPATIBLE_IOCTL(FDMSGOFF)
+COMPATIBLE_IOCTL(FDSETEMSGTRESH)
+COMPATIBLE_IOCTL(FDFLUSH)
+COMPATIBLE_IOCTL(FDWERRORCLR)
+COMPATIBLE_IOCTL(FDSETMAXERRS)
+COMPATIBLE_IOCTL(FDGETMAXERRS)
+COMPATIBLE_IOCTL(FDGETDRVTYP)
+COMPATIBLE_IOCTL(FDEJECT)
+COMPATIBLE_IOCTL(FDCLRPRM)
+COMPATIBLE_IOCTL(FDFMTBEG)
+COMPATIBLE_IOCTL(FDFMTEND)
+COMPATIBLE_IOCTL(FDRESET)
+COMPATIBLE_IOCTL(FDTWADDLE)
+COMPATIBLE_IOCTL(FDFMTTRK)
+COMPATIBLE_IOCTL(FDRAWCMD)
+/* 0x12 */
+#ifdef CONFIG_BLOCK
+COMPATIBLE_IOCTL(BLKRASET)
+COMPATIBLE_IOCTL(BLKROSET)
+COMPATIBLE_IOCTL(BLKROGET)
+COMPATIBLE_IOCTL(BLKRRPART)
+COMPATIBLE_IOCTL(BLKFLSBUF)
+COMPATIBLE_IOCTL(BLKSECTSET)
+COMPATIBLE_IOCTL(BLKSSZGET)
+COMPATIBLE_IOCTL(BLKTRACESTART)
+COMPATIBLE_IOCTL(BLKTRACESTOP)
+COMPATIBLE_IOCTL(BLKTRACESETUP)
+COMPATIBLE_IOCTL(BLKTRACETEARDOWN)
+ULONG_IOCTL(BLKRASET)
+ULONG_IOCTL(BLKFRASET)
+#endif
+/* RAID */
+COMPATIBLE_IOCTL(RAID_VERSION)
+COMPATIBLE_IOCTL(GET_ARRAY_INFO)
+COMPATIBLE_IOCTL(GET_DISK_INFO)
+COMPATIBLE_IOCTL(PRINT_RAID_DEBUG)
+COMPATIBLE_IOCTL(RAID_AUTORUN)
+COMPATIBLE_IOCTL(CLEAR_ARRAY)
+COMPATIBLE_IOCTL(ADD_NEW_DISK)
+ULONG_IOCTL(HOT_REMOVE_DISK)
+COMPATIBLE_IOCTL(SET_ARRAY_INFO)
+COMPATIBLE_IOCTL(SET_DISK_INFO)
+COMPATIBLE_IOCTL(WRITE_RAID_INFO)
+COMPATIBLE_IOCTL(UNPROTECT_ARRAY)
+COMPATIBLE_IOCTL(PROTECT_ARRAY)
+ULONG_IOCTL(HOT_ADD_DISK)
+ULONG_IOCTL(SET_DISK_FAULTY)
+COMPATIBLE_IOCTL(RUN_ARRAY)
+COMPATIBLE_IOCTL(STOP_ARRAY)
+COMPATIBLE_IOCTL(STOP_ARRAY_RO)
+COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
+COMPATIBLE_IOCTL(GET_BITMAP_FILE)
+ULONG_IOCTL(SET_BITMAP_FILE)
+/* DM */
+COMPATIBLE_IOCTL(DM_VERSION_32)
+COMPATIBLE_IOCTL(DM_REMOVE_ALL_32)
+COMPATIBLE_IOCTL(DM_LIST_DEVICES_32)
+COMPATIBLE_IOCTL(DM_DEV_CREATE_32)
+COMPATIBLE_IOCTL(DM_DEV_REMOVE_32)
+COMPATIBLE_IOCTL(DM_DEV_RENAME_32)
+COMPATIBLE_IOCTL(DM_DEV_SUSPEND_32)
+COMPATIBLE_IOCTL(DM_DEV_STATUS_32)
+COMPATIBLE_IOCTL(DM_DEV_WAIT_32)
+COMPATIBLE_IOCTL(DM_TABLE_LOAD_32)
+COMPATIBLE_IOCTL(DM_TABLE_CLEAR_32)
+COMPATIBLE_IOCTL(DM_TABLE_DEPS_32)
+COMPATIBLE_IOCTL(DM_TABLE_STATUS_32)
+COMPATIBLE_IOCTL(DM_LIST_VERSIONS_32)
+COMPATIBLE_IOCTL(DM_TARGET_MSG_32)
+COMPATIBLE_IOCTL(DM_DEV_SET_GEOMETRY_32)
+COMPATIBLE_IOCTL(DM_VERSION)
+COMPATIBLE_IOCTL(DM_REMOVE_ALL)
+COMPATIBLE_IOCTL(DM_LIST_DEVICES)
+COMPATIBLE_IOCTL(DM_DEV_CREATE)
+COMPATIBLE_IOCTL(DM_DEV_REMOVE)
+COMPATIBLE_IOCTL(DM_DEV_RENAME)
+COMPATIBLE_IOCTL(DM_DEV_SUSPEND)
+COMPATIBLE_IOCTL(DM_DEV_STATUS)
+COMPATIBLE_IOCTL(DM_DEV_WAIT)
+COMPATIBLE_IOCTL(DM_TABLE_LOAD)
+COMPATIBLE_IOCTL(DM_TABLE_CLEAR)
+COMPATIBLE_IOCTL(DM_TABLE_DEPS)
+COMPATIBLE_IOCTL(DM_TABLE_STATUS)
+COMPATIBLE_IOCTL(DM_LIST_VERSIONS)
+COMPATIBLE_IOCTL(DM_TARGET_MSG)
+COMPATIBLE_IOCTL(DM_DEV_SET_GEOMETRY)
+/* Big K */
+COMPATIBLE_IOCTL(PIO_FONT)
+COMPATIBLE_IOCTL(GIO_FONT)
+ULONG_IOCTL(KDSIGACCEPT)
+COMPATIBLE_IOCTL(KDGETKEYCODE)
+COMPATIBLE_IOCTL(KDSETKEYCODE)
+ULONG_IOCTL(KIOCSOUND)
+ULONG_IOCTL(KDMKTONE)
+COMPATIBLE_IOCTL(KDGKBTYPE)
+ULONG_IOCTL(KDSETMODE)
+COMPATIBLE_IOCTL(KDGETMODE)
+ULONG_IOCTL(KDSKBMODE)
+COMPATIBLE_IOCTL(KDGKBMODE)
+ULONG_IOCTL(KDSKBMETA)
+COMPATIBLE_IOCTL(KDGKBMETA)
+COMPATIBLE_IOCTL(KDGKBENT)
+COMPATIBLE_IOCTL(KDSKBENT)
+COMPATIBLE_IOCTL(KDGKBSENT)
+COMPATIBLE_IOCTL(KDSKBSENT)
+COMPATIBLE_IOCTL(KDGKBDIACR)
+COMPATIBLE_IOCTL(KDSKBDIACR)
+COMPATIBLE_IOCTL(KDKBDREP)
+COMPATIBLE_IOCTL(KDGKBLED)
+ULONG_IOCTL(KDSKBLED)
+COMPATIBLE_IOCTL(KDGETLED)
+ULONG_IOCTL(KDSETLED)
+COMPATIBLE_IOCTL(GIO_SCRNMAP)
+COMPATIBLE_IOCTL(PIO_SCRNMAP)
+COMPATIBLE_IOCTL(GIO_UNISCRNMAP)
+COMPATIBLE_IOCTL(PIO_UNISCRNMAP)
+COMPATIBLE_IOCTL(PIO_FONTRESET)
+COMPATIBLE_IOCTL(PIO_UNIMAPCLR)
+/* Big S */
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN)
+COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK)
+COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK)
+COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY)
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER)
+COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
+COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
+/* Big T */
+COMPATIBLE_IOCTL(TUNSETNOCSUM)
+COMPATIBLE_IOCTL(TUNSETDEBUG)
+COMPATIBLE_IOCTL(TUNSETPERSIST)
+COMPATIBLE_IOCTL(TUNSETOWNER)
+/* Big V */
+COMPATIBLE_IOCTL(VT_SETMODE)
+COMPATIBLE_IOCTL(VT_GETMODE)
+COMPATIBLE_IOCTL(VT_GETSTATE)
+COMPATIBLE_IOCTL(VT_OPENQRY)
+ULONG_IOCTL(VT_ACTIVATE)
+ULONG_IOCTL(VT_WAITACTIVE)
+ULONG_IOCTL(VT_RELDISP)
+ULONG_IOCTL(VT_DISALLOCATE)
+COMPATIBLE_IOCTL(VT_RESIZE)
+COMPATIBLE_IOCTL(VT_RESIZEX)
+COMPATIBLE_IOCTL(VT_LOCKSWITCH)
+COMPATIBLE_IOCTL(VT_UNLOCKSWITCH)
+COMPATIBLE_IOCTL(VT_GETHIFONTMASK)
+/* Little p (/dev/rtc, /dev/envctrl, etc.) */
+COMPATIBLE_IOCTL(RTC_AIE_ON)
+COMPATIBLE_IOCTL(RTC_AIE_OFF)
+COMPATIBLE_IOCTL(RTC_UIE_ON)
+COMPATIBLE_IOCTL(RTC_UIE_OFF)
+COMPATIBLE_IOCTL(RTC_PIE_ON)
+COMPATIBLE_IOCTL(RTC_PIE_OFF)
+COMPATIBLE_IOCTL(RTC_WIE_ON)
+COMPATIBLE_IOCTL(RTC_WIE_OFF)
+COMPATIBLE_IOCTL(RTC_ALM_SET)
+COMPATIBLE_IOCTL(RTC_ALM_READ)
+COMPATIBLE_IOCTL(RTC_RD_TIME)
+COMPATIBLE_IOCTL(RTC_SET_TIME)
+COMPATIBLE_IOCTL(RTC_WKALM_SET)
+COMPATIBLE_IOCTL(RTC_WKALM_RD)
+/*
+ * These two are only for the sbus rtc driver, but
+ * hwclock tries them on every rtc device first when
+ * running on sparc. On other architectures the entries
+ * are useless but harmless.
+ */
+COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
+COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
+/* Little m */
+COMPATIBLE_IOCTL(MTIOCTOP)
+/* Socket level stuff */
+COMPATIBLE_IOCTL(FIOQSIZE)
+COMPATIBLE_IOCTL(FIOSETOWN)
+COMPATIBLE_IOCTL(SIOCSPGRP)
+COMPATIBLE_IOCTL(FIOGETOWN)
+COMPATIBLE_IOCTL(SIOCGPGRP)
+COMPATIBLE_IOCTL(SIOCATMARK)
+COMPATIBLE_IOCTL(SIOCSIFLINK)
+COMPATIBLE_IOCTL(SIOCSIFENCAP)
+COMPATIBLE_IOCTL(SIOCGIFENCAP)
+COMPATIBLE_IOCTL(SIOCSIFNAME)
+COMPATIBLE_IOCTL(SIOCSARP)
+COMPATIBLE_IOCTL(SIOCGARP)
+COMPATIBLE_IOCTL(SIOCDARP)
+COMPATIBLE_IOCTL(SIOCSRARP)
+COMPATIBLE_IOCTL(SIOCGRARP)
+COMPATIBLE_IOCTL(SIOCDRARP)
+COMPATIBLE_IOCTL(SIOCADDDLCI)
+COMPATIBLE_IOCTL(SIOCDELDLCI)
+COMPATIBLE_IOCTL(SIOCGMIIPHY)
+COMPATIBLE_IOCTL(SIOCGMIIREG)
+COMPATIBLE_IOCTL(SIOCSMIIREG)
+COMPATIBLE_IOCTL(SIOCGIFVLAN)
+COMPATIBLE_IOCTL(SIOCSIFVLAN)
+COMPATIBLE_IOCTL(SIOCBRADDBR)
+COMPATIBLE_IOCTL(SIOCBRDELBR)
+/* SG stuff */
+COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
+COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
+COMPATIBLE_IOCTL(SG_EMULATED_HOST)
+ULONG_IOCTL(SG_SET_TRANSFORM)
+COMPATIBLE_IOCTL(SG_GET_TRANSFORM)
+COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE)
+COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE)
+COMPATIBLE_IOCTL(SG_GET_SCSI_ID)
+COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA)
+COMPATIBLE_IOCTL(SG_GET_LOW_DMA)
+COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID)
+COMPATIBLE_IOCTL(SG_GET_PACK_ID)
+COMPATIBLE_IOCTL(SG_GET_NUM_WAITING)
+COMPATIBLE_IOCTL(SG_SET_DEBUG)
+COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE)
+COMPATIBLE_IOCTL(SG_GET_COMMAND_Q)
+COMPATIBLE_IOCTL(SG_SET_COMMAND_Q)
+COMPATIBLE_IOCTL(SG_GET_VERSION_NUM)
+COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN)
+COMPATIBLE_IOCTL(SG_SCSI_RESET)
+COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
+COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN)
+COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN)
+/* PPP stuff */
+COMPATIBLE_IOCTL(PPPIOCGFLAGS)
+COMPATIBLE_IOCTL(PPPIOCSFLAGS)
+COMPATIBLE_IOCTL(PPPIOCGASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCSASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCGUNIT)
+COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCGMRU)
+COMPATIBLE_IOCTL(PPPIOCSMRU)
+COMPATIBLE_IOCTL(PPPIOCSMAXCID)
+COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
+COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
+/* PPPIOCSCOMPRESS is translated */
+COMPATIBLE_IOCTL(PPPIOCGNPMODE)
+COMPATIBLE_IOCTL(PPPIOCSNPMODE)
+COMPATIBLE_IOCTL(PPPIOCGDEBUG)
+COMPATIBLE_IOCTL(PPPIOCSDEBUG)
+/* PPPIOCSPASS is translated */
+/* PPPIOCSACTIVE is translated */
+/* PPPIOCGIDLE is translated */
+COMPATIBLE_IOCTL(PPPIOCNEWUNIT)
+COMPATIBLE_IOCTL(PPPIOCATTACH)
+COMPATIBLE_IOCTL(PPPIOCDETACH)
+COMPATIBLE_IOCTL(PPPIOCSMRRU)
+COMPATIBLE_IOCTL(PPPIOCCONNECT)
+COMPATIBLE_IOCTL(PPPIOCDISCONN)
+COMPATIBLE_IOCTL(PPPIOCATTCHAN)
+COMPATIBLE_IOCTL(PPPIOCGCHAN)
+/* PPPOX */
+COMPATIBLE_IOCTL(PPPOEIOCSFWD)
+COMPATIBLE_IOCTL(PPPOEIOCDFWD)
+/* LP */
+COMPATIBLE_IOCTL(LPGETSTATUS)
+/* ppdev */
+COMPATIBLE_IOCTL(PPSETMODE)
+COMPATIBLE_IOCTL(PPRSTATUS)
+COMPATIBLE_IOCTL(PPRCONTROL)
+COMPATIBLE_IOCTL(PPWCONTROL)
+COMPATIBLE_IOCTL(PPFCONTROL)
+COMPATIBLE_IOCTL(PPRDATA)
+COMPATIBLE_IOCTL(PPWDATA)
+COMPATIBLE_IOCTL(PPCLAIM)
+COMPATIBLE_IOCTL(PPRELEASE)
+COMPATIBLE_IOCTL(PPYIELD)
+COMPATIBLE_IOCTL(PPEXCL)
+COMPATIBLE_IOCTL(PPDATADIR)
+COMPATIBLE_IOCTL(PPNEGOT)
+COMPATIBLE_IOCTL(PPWCTLONIRQ)
+COMPATIBLE_IOCTL(PPCLRIRQ)
+COMPATIBLE_IOCTL(PPSETPHASE)
+COMPATIBLE_IOCTL(PPGETMODES)
+COMPATIBLE_IOCTL(PPGETMODE)
+COMPATIBLE_IOCTL(PPGETPHASE)
+COMPATIBLE_IOCTL(PPGETFLAGS)
+COMPATIBLE_IOCTL(PPSETFLAGS)
+/* CDROM stuff */
+COMPATIBLE_IOCTL(CDROMPAUSE)
+COMPATIBLE_IOCTL(CDROMRESUME)
+COMPATIBLE_IOCTL(CDROMPLAYMSF)
+COMPATIBLE_IOCTL(CDROMPLAYTRKIND)
+COMPATIBLE_IOCTL(CDROMREADTOCHDR)
+COMPATIBLE_IOCTL(CDROMREADTOCENTRY)
+COMPATIBLE_IOCTL(CDROMSTOP)
+COMPATIBLE_IOCTL(CDROMSTART)
+COMPATIBLE_IOCTL(CDROMEJECT)
+COMPATIBLE_IOCTL(CDROMVOLCTRL)
+COMPATIBLE_IOCTL(CDROMSUBCHNL)
+ULONG_IOCTL(CDROMEJECT_SW)
+COMPATIBLE_IOCTL(CDROMMULTISESSION)
+COMPATIBLE_IOCTL(CDROM_GET_MCN)
+COMPATIBLE_IOCTL(CDROMRESET)
+COMPATIBLE_IOCTL(CDROMVOLREAD)
+COMPATIBLE_IOCTL(CDROMSEEK)
+COMPATIBLE_IOCTL(CDROMPLAYBLK)
+COMPATIBLE_IOCTL(CDROMCLOSETRAY)
+ULONG_IOCTL(CDROM_SET_OPTIONS)
+ULONG_IOCTL(CDROM_CLEAR_OPTIONS)
+ULONG_IOCTL(CDROM_SELECT_SPEED)
+ULONG_IOCTL(CDROM_SELECT_DISC)
+ULONG_IOCTL(CDROM_MEDIA_CHANGED)
+ULONG_IOCTL(CDROM_DRIVE_STATUS)
+COMPATIBLE_IOCTL(CDROM_DISC_STATUS)
+COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS)
+ULONG_IOCTL(CDROM_LOCKDOOR)
+ULONG_IOCTL(CDROM_DEBUG)
+COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY)
+/* Ignore cdrom.h about these next 5 ioctls, they absolutely do
+ * not take a struct cdrom_read, instead they take a struct cdrom_msf
+ * which is compatible.
+ */
+COMPATIBLE_IOCTL(CDROMREADMODE2)
+COMPATIBLE_IOCTL(CDROMREADMODE1)
+COMPATIBLE_IOCTL(CDROMREADRAW)
+COMPATIBLE_IOCTL(CDROMREADCOOKED)
+COMPATIBLE_IOCTL(CDROMREADALL)
+/* DVD ioctls */
+COMPATIBLE_IOCTL(DVD_READ_STRUCT)
+COMPATIBLE_IOCTL(DVD_WRITE_STRUCT)
+COMPATIBLE_IOCTL(DVD_AUTH)
+/* pktcdvd */
+COMPATIBLE_IOCTL(PACKET_CTRL_CMD)
+/* Big A */
+/* sparc only */
+/* Big Q for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_INFO)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_CTRLRATE)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETOUTCOUNT)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETINCOUNT)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_PERCMODE)
+COMPATIBLE_IOCTL(SNDCTL_FM_LOAD_INSTR)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_TESTMIDI)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_RESETSAMPLES)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_NRSYNTHS)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_NRMIDIS)
+COMPATIBLE_IOCTL(SNDCTL_MIDI_INFO)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_THRESHOLD)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_MEMAVL)
+COMPATIBLE_IOCTL(SNDCTL_FM_4OP_ENABLE)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_PANIC)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_OUTOFBAND)
+COMPATIBLE_IOCTL(SNDCTL_SEQ_GETTIME)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_ID)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_CONTROL)
+COMPATIBLE_IOCTL(SNDCTL_SYNTH_REMOVESAMPLE)
+/* Big T for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_TMR_TIMEBASE)
+COMPATIBLE_IOCTL(SNDCTL_TMR_START)
+COMPATIBLE_IOCTL(SNDCTL_TMR_STOP)
+COMPATIBLE_IOCTL(SNDCTL_TMR_CONTINUE)
+COMPATIBLE_IOCTL(SNDCTL_TMR_TEMPO)
+COMPATIBLE_IOCTL(SNDCTL_TMR_SOURCE)
+COMPATIBLE_IOCTL(SNDCTL_TMR_METRONOME)
+COMPATIBLE_IOCTL(SNDCTL_TMR_SELECT)
+/* Little m for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_MIDI_PRETIME)
+COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUMODE)
+COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUCMD)
+/* Big P for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_DSP_RESET)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SYNC)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SPEED)
+COMPATIBLE_IOCTL(SNDCTL_DSP_STEREO)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETBLKSIZE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_CHANNELS)
+COMPATIBLE_IOCTL(SOUND_PCM_WRITE_FILTER)
+COMPATIBLE_IOCTL(SNDCTL_DSP_POST)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SUBDIVIDE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETFRAGMENT)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETFMTS)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETFMT)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETOSPACE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETISPACE)
+COMPATIBLE_IOCTL(SNDCTL_DSP_NONBLOCK)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETCAPS)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETTRIGGER)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETTRIGGER)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETIPTR)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETOPTR)
+/* SNDCTL_DSP_MAPINBUF, XXX needs translation */
+/* SNDCTL_DSP_MAPOUTBUF, XXX needs translation */
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETSYNCRO)
+COMPATIBLE_IOCTL(SNDCTL_DSP_SETDUPLEX)
+COMPATIBLE_IOCTL(SNDCTL_DSP_GETODELAY)
+COMPATIBLE_IOCTL(SNDCTL_DSP_PROFILE)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_RATE)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_CHANNELS)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_BITS)
+COMPATIBLE_IOCTL(SOUND_PCM_READ_FILTER)
+/* Big C for sound/OSS */
+COMPATIBLE_IOCTL(SNDCTL_COPR_RESET)
+COMPATIBLE_IOCTL(SNDCTL_COPR_LOAD)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RDATA)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RCODE)
+COMPATIBLE_IOCTL(SNDCTL_COPR_WDATA)
+COMPATIBLE_IOCTL(SNDCTL_COPR_WCODE)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RUN)
+COMPATIBLE_IOCTL(SNDCTL_COPR_HALT)
+COMPATIBLE_IOCTL(SNDCTL_COPR_SENDMSG)
+COMPATIBLE_IOCTL(SNDCTL_COPR_RCVMSG)
+/* Big M for sound/OSS */
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_VOLUME)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_BASS)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_TREBLE)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_SYNTH)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_PCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_SPEAKER)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_MIC)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_CD)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_IMIX)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_ALTPCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECLEV)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_IGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_OGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE1)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE2)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE3)
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL1))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL2))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL3))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEIN))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEOUT))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_VIDEO))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_RADIO))
+COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_MONITOR))
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_MUTE)
+/* SOUND_MIXER_READ_ENHANCE, same value as READ_MUTE */
+/* SOUND_MIXER_READ_LOUD, same value as READ_MUTE */
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECSRC)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_DEVMASK)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECMASK)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_STEREODEVS)
+COMPATIBLE_IOCTL(SOUND_MIXER_READ_CAPS)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_VOLUME)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_BASS)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_TREBLE)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SYNTH)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_PCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SPEAKER)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MIC)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_CD)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IMIX)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_ALTPCM)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECLEV)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_OGAIN)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE1)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE2)
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE3)
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL1))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL2))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL3))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEIN))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEOUT))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_VIDEO))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_RADIO))
+COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_MONITOR))
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MUTE)
+/* SOUND_MIXER_WRITE_ENHANCE, same value as WRITE_MUTE */
+/* SOUND_MIXER_WRITE_LOUD, same value as WRITE_MUTE */
+COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECSRC)
+COMPATIBLE_IOCTL(SOUND_MIXER_INFO)
+COMPATIBLE_IOCTL(SOUND_OLD_MIXER_INFO)
+COMPATIBLE_IOCTL(SOUND_MIXER_ACCESS)
+COMPATIBLE_IOCTL(SOUND_MIXER_AGC)
+COMPATIBLE_IOCTL(SOUND_MIXER_3DSE)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE1)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE2)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE3)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE4)
+COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5)
+COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS)
+COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS)
+COMPATIBLE_IOCTL(OSS_GETVERSION)
+/* AUTOFS */
+ULONG_IOCTL(AUTOFS_IOC_READY)
+ULONG_IOCTL(AUTOFS_IOC_FAIL)
+COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
+COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
+COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
+COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI)
+COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER)
+COMPATIBLE_IOCTL(AUTOFS_IOC_ASKREGHOST)
+COMPATIBLE_IOCTL(AUTOFS_IOC_TOGGLEREGHOST)
+COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT)
+/* Raw devices */
+COMPATIBLE_IOCTL(RAW_SETBIND)
+COMPATIBLE_IOCTL(RAW_GETBIND)
+/* SMB ioctls which do not need any translations */
+COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
+/* Little a */
+COMPATIBLE_IOCTL(ATMSIGD_CTRL)
+COMPATIBLE_IOCTL(ATMARPD_CTRL)
+COMPATIBLE_IOCTL(ATMLEC_CTRL)
+COMPATIBLE_IOCTL(ATMLEC_MCAST)
+COMPATIBLE_IOCTL(ATMLEC_DATA)
+COMPATIBLE_IOCTL(ATM_SETSC)
+COMPATIBLE_IOCTL(SIOCSIFATMTCP)
+COMPATIBLE_IOCTL(SIOCMKCLIP)
+COMPATIBLE_IOCTL(ATMARP_MKIP)
+COMPATIBLE_IOCTL(ATMARP_SETENTRY)
+COMPATIBLE_IOCTL(ATMARP_ENCAP)
+COMPATIBLE_IOCTL(ATMTCP_CREATE)
+COMPATIBLE_IOCTL(ATMTCP_REMOVE)
+COMPATIBLE_IOCTL(ATMMPC_CTRL)
+COMPATIBLE_IOCTL(ATMMPC_DATA)
+/* Watchdog */
+COMPATIBLE_IOCTL(WDIOC_GETSUPPORT)
+COMPATIBLE_IOCTL(WDIOC_GETSTATUS)
+COMPATIBLE_IOCTL(WDIOC_GETBOOTSTATUS)
+COMPATIBLE_IOCTL(WDIOC_GETTEMP)
+COMPATIBLE_IOCTL(WDIOC_SETOPTIONS)
+COMPATIBLE_IOCTL(WDIOC_KEEPALIVE)
+COMPATIBLE_IOCTL(WDIOC_SETTIMEOUT)
+COMPATIBLE_IOCTL(WDIOC_GETTIMEOUT)
+/* Big R */
+COMPATIBLE_IOCTL(RNDGETENTCNT)
+COMPATIBLE_IOCTL(RNDADDTOENTCNT)
+COMPATIBLE_IOCTL(RNDGETPOOL)
+COMPATIBLE_IOCTL(RNDADDENTROPY)
+COMPATIBLE_IOCTL(RNDZAPENTCNT)
+COMPATIBLE_IOCTL(RNDCLEARPOOL)
+/* Bluetooth */
+COMPATIBLE_IOCTL(HCIDEVUP)
+COMPATIBLE_IOCTL(HCIDEVDOWN)
+COMPATIBLE_IOCTL(HCIDEVRESET)
+COMPATIBLE_IOCTL(HCIDEVRESTAT)
+COMPATIBLE_IOCTL(HCIGETDEVLIST)
+COMPATIBLE_IOCTL(HCIGETDEVINFO)
+COMPATIBLE_IOCTL(HCIGETCONNLIST)
+COMPATIBLE_IOCTL(HCIGETCONNINFO)
+COMPATIBLE_IOCTL(HCISETRAW)
+COMPATIBLE_IOCTL(HCISETSCAN)
+COMPATIBLE_IOCTL(HCISETAUTH)
+COMPATIBLE_IOCTL(HCISETENCRYPT)
+COMPATIBLE_IOCTL(HCISETPTYPE)
+COMPATIBLE_IOCTL(HCISETLINKPOL)
+COMPATIBLE_IOCTL(HCISETLINKMODE)
+COMPATIBLE_IOCTL(HCISETACLMTU)
+COMPATIBLE_IOCTL(HCISETSCOMTU)
+COMPATIBLE_IOCTL(HCIINQUIRY)
+COMPATIBLE_IOCTL(HCIUARTSETPROTO)
+COMPATIBLE_IOCTL(HCIUARTGETPROTO)
+COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
+COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
+COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
+COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
+COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
+COMPATIBLE_IOCTL(BNEPCONNADD)
+COMPATIBLE_IOCTL(BNEPCONNDEL)
+COMPATIBLE_IOCTL(BNEPGETCONNLIST)
+COMPATIBLE_IOCTL(BNEPGETCONNINFO)
+COMPATIBLE_IOCTL(CMTPCONNADD)
+COMPATIBLE_IOCTL(CMTPCONNDEL)
+COMPATIBLE_IOCTL(CMTPGETCONNLIST)
+COMPATIBLE_IOCTL(CMTPGETCONNINFO)
+COMPATIBLE_IOCTL(HIDPCONNADD)
+COMPATIBLE_IOCTL(HIDPCONNDEL)
+COMPATIBLE_IOCTL(HIDPGETCONNLIST)
+COMPATIBLE_IOCTL(HIDPGETCONNINFO)
+/* CAPI */
+COMPATIBLE_IOCTL(CAPI_REGISTER)
+COMPATIBLE_IOCTL(CAPI_GET_MANUFACTURER)
+COMPATIBLE_IOCTL(CAPI_GET_VERSION)
+COMPATIBLE_IOCTL(CAPI_GET_SERIAL)
+COMPATIBLE_IOCTL(CAPI_GET_PROFILE)
+COMPATIBLE_IOCTL(CAPI_MANUFACTURER_CMD)
+COMPATIBLE_IOCTL(CAPI_GET_ERRCODE)
+COMPATIBLE_IOCTL(CAPI_INSTALLED)
+COMPATIBLE_IOCTL(CAPI_GET_FLAGS)
+COMPATIBLE_IOCTL(CAPI_SET_FLAGS)
+COMPATIBLE_IOCTL(CAPI_CLR_FLAGS)
+COMPATIBLE_IOCTL(CAPI_NCCI_OPENCOUNT)
+COMPATIBLE_IOCTL(CAPI_NCCI_GETUNIT)
+/* Siemens Gigaset */
+COMPATIBLE_IOCTL(GIGASET_REDIR)
+COMPATIBLE_IOCTL(GIGASET_CONFIG)
+COMPATIBLE_IOCTL(GIGASET_BRKCHARS)
+COMPATIBLE_IOCTL(GIGASET_VERSION)
+/* Misc. */
+COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */
+COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */
+COMPATIBLE_IOCTL(PCIIOC_CONTROLLER)
+COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO)
+COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM)
+COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE)
+/* USB */
+COMPATIBLE_IOCTL(USBDEVFS_RESETEP)
+COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE)
+COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION)
+COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER)
+COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB)
+COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE)
+COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE)
+COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO)
+COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO)
+COMPATIBLE_IOCTL(USBDEVFS_RESET)
+COMPATIBLE_IOCTL(USBDEVFS_SUBMITURB32)
+COMPATIBLE_IOCTL(USBDEVFS_REAPURB32)
+COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32)
+COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT)
+/* MTD */
+COMPATIBLE_IOCTL(MEMGETINFO)
+COMPATIBLE_IOCTL(MEMERASE)
+COMPATIBLE_IOCTL(MEMLOCK)
+COMPATIBLE_IOCTL(MEMUNLOCK)
+COMPATIBLE_IOCTL(MEMGETREGIONCOUNT)
+COMPATIBLE_IOCTL(MEMGETREGIONINFO)
+COMPATIBLE_IOCTL(MEMGETBADBLOCK)
+COMPATIBLE_IOCTL(MEMSETBADBLOCK)
+/* NBD */
+ULONG_IOCTL(NBD_SET_SOCK)
+ULONG_IOCTL(NBD_SET_BLKSIZE)
+ULONG_IOCTL(NBD_SET_SIZE)
+COMPATIBLE_IOCTL(NBD_DO_IT)
+COMPATIBLE_IOCTL(NBD_CLEAR_SOCK)
+COMPATIBLE_IOCTL(NBD_CLEAR_QUE)
+COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
+ULONG_IOCTL(NBD_SET_SIZE_BLOCKS)
+COMPATIBLE_IOCTL(NBD_DISCONNECT)
+/* i2c */
+COMPATIBLE_IOCTL(I2C_SLAVE)
+COMPATIBLE_IOCTL(I2C_SLAVE_FORCE)
+COMPATIBLE_IOCTL(I2C_TENBIT)
+COMPATIBLE_IOCTL(I2C_PEC)
+COMPATIBLE_IOCTL(I2C_RETRIES)
+COMPATIBLE_IOCTL(I2C_TIMEOUT)
+/* wireless */
+COMPATIBLE_IOCTL(SIOCSIWCOMMIT)
+COMPATIBLE_IOCTL(SIOCGIWNAME)
+COMPATIBLE_IOCTL(SIOCSIWNWID)
+COMPATIBLE_IOCTL(SIOCGIWNWID)
+COMPATIBLE_IOCTL(SIOCSIWFREQ)
+COMPATIBLE_IOCTL(SIOCGIWFREQ)
+COMPATIBLE_IOCTL(SIOCSIWMODE)
+COMPATIBLE_IOCTL(SIOCGIWMODE)
+COMPATIBLE_IOCTL(SIOCSIWSENS)
+COMPATIBLE_IOCTL(SIOCGIWSENS)
+COMPATIBLE_IOCTL(SIOCSIWRANGE)
+COMPATIBLE_IOCTL(SIOCSIWPRIV)
+COMPATIBLE_IOCTL(SIOCGIWPRIV)
+COMPATIBLE_IOCTL(SIOCSIWSTATS)
+COMPATIBLE_IOCTL(SIOCGIWSTATS)
+COMPATIBLE_IOCTL(SIOCSIWAP)
+COMPATIBLE_IOCTL(SIOCGIWAP)
+COMPATIBLE_IOCTL(SIOCSIWSCAN)
+COMPATIBLE_IOCTL(SIOCSIWRATE)
+COMPATIBLE_IOCTL(SIOCGIWRATE)
+COMPATIBLE_IOCTL(SIOCSIWRTS)
+COMPATIBLE_IOCTL(SIOCGIWRTS)
+COMPATIBLE_IOCTL(SIOCSIWFRAG)
+COMPATIBLE_IOCTL(SIOCGIWFRAG)
+COMPATIBLE_IOCTL(SIOCSIWTXPOW)
+COMPATIBLE_IOCTL(SIOCGIWTXPOW)
+COMPATIBLE_IOCTL(SIOCSIWRETRY)
+COMPATIBLE_IOCTL(SIOCGIWRETRY)
+COMPATIBLE_IOCTL(SIOCSIWPOWER)
+COMPATIBLE_IOCTL(SIOCGIWPOWER)
+/* hiddev */
+COMPATIBLE_IOCTL(HIDIOCGVERSION)
+COMPATIBLE_IOCTL(HIDIOCAPPLICATION)
+COMPATIBLE_IOCTL(HIDIOCGDEVINFO)
+COMPATIBLE_IOCTL(HIDIOCGSTRING)
+COMPATIBLE_IOCTL(HIDIOCINITREPORT)
+COMPATIBLE_IOCTL(HIDIOCGREPORT)
+COMPATIBLE_IOCTL(HIDIOCSREPORT)
+COMPATIBLE_IOCTL(HIDIOCGREPORTINFO)
+COMPATIBLE_IOCTL(HIDIOCGFIELDINFO)
+COMPATIBLE_IOCTL(HIDIOCGUSAGE)
+COMPATIBLE_IOCTL(HIDIOCSUSAGE)
+COMPATIBLE_IOCTL(HIDIOCGUCODE)
+COMPATIBLE_IOCTL(HIDIOCGFLAG)
+COMPATIBLE_IOCTL(HIDIOCSFLAG)
+COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINDEX)
+COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINFO)
+/* dvb */
+COMPATIBLE_IOCTL(AUDIO_STOP)
+COMPATIBLE_IOCTL(AUDIO_PLAY)
+COMPATIBLE_IOCTL(AUDIO_PAUSE)
+COMPATIBLE_IOCTL(AUDIO_CONTINUE)
+COMPATIBLE_IOCTL(AUDIO_SELECT_SOURCE)
+COMPATIBLE_IOCTL(AUDIO_SET_MUTE)
+COMPATIBLE_IOCTL(AUDIO_SET_AV_SYNC)
+COMPATIBLE_IOCTL(AUDIO_SET_BYPASS_MODE)
+COMPATIBLE_IOCTL(AUDIO_CHANNEL_SELECT)
+COMPATIBLE_IOCTL(AUDIO_GET_STATUS)
+COMPATIBLE_IOCTL(AUDIO_GET_CAPABILITIES)
+COMPATIBLE_IOCTL(AUDIO_CLEAR_BUFFER)
+COMPATIBLE_IOCTL(AUDIO_SET_ID)
+COMPATIBLE_IOCTL(AUDIO_SET_MIXER)
+COMPATIBLE_IOCTL(AUDIO_SET_STREAMTYPE)
+COMPATIBLE_IOCTL(AUDIO_SET_EXT_ID)
+COMPATIBLE_IOCTL(AUDIO_SET_ATTRIBUTES)
+COMPATIBLE_IOCTL(AUDIO_SET_KARAOKE)
+COMPATIBLE_IOCTL(DMX_START)
+COMPATIBLE_IOCTL(DMX_STOP)
+COMPATIBLE_IOCTL(DMX_SET_FILTER)
+COMPATIBLE_IOCTL(DMX_SET_PES_FILTER)
+COMPATIBLE_IOCTL(DMX_SET_BUFFER_SIZE)
+COMPATIBLE_IOCTL(DMX_GET_PES_PIDS)
+COMPATIBLE_IOCTL(DMX_GET_CAPS)
+COMPATIBLE_IOCTL(DMX_SET_SOURCE)
+COMPATIBLE_IOCTL(DMX_GET_STC)
+COMPATIBLE_IOCTL(FE_GET_INFO)
+COMPATIBLE_IOCTL(FE_DISEQC_RESET_OVERLOAD)
+COMPATIBLE_IOCTL(FE_DISEQC_SEND_MASTER_CMD)
+COMPATIBLE_IOCTL(FE_DISEQC_RECV_SLAVE_REPLY)
+COMPATIBLE_IOCTL(FE_DISEQC_SEND_BURST)
+COMPATIBLE_IOCTL(FE_SET_TONE)
+COMPATIBLE_IOCTL(FE_SET_VOLTAGE)
+COMPATIBLE_IOCTL(FE_ENABLE_HIGH_LNB_VOLTAGE)
+COMPATIBLE_IOCTL(FE_READ_STATUS)
+COMPATIBLE_IOCTL(FE_READ_BER)
+COMPATIBLE_IOCTL(FE_READ_SIGNAL_STRENGTH)
+COMPATIBLE_IOCTL(FE_READ_SNR)
+COMPATIBLE_IOCTL(FE_READ_UNCORRECTED_BLOCKS)
+COMPATIBLE_IOCTL(FE_SET_FRONTEND)
+COMPATIBLE_IOCTL(FE_GET_FRONTEND)
+COMPATIBLE_IOCTL(FE_GET_EVENT)
+COMPATIBLE_IOCTL(FE_DISHNETWORK_SEND_LEGACY_CMD)
+COMPATIBLE_IOCTL(VIDEO_STOP)
+COMPATIBLE_IOCTL(VIDEO_PLAY)
+COMPATIBLE_IOCTL(VIDEO_FREEZE)
+COMPATIBLE_IOCTL(VIDEO_CONTINUE)
+COMPATIBLE_IOCTL(VIDEO_SELECT_SOURCE)
+COMPATIBLE_IOCTL(VIDEO_SET_BLANK)
+COMPATIBLE_IOCTL(VIDEO_GET_STATUS)
+COMPATIBLE_IOCTL(VIDEO_SET_DISPLAY_FORMAT)
+COMPATIBLE_IOCTL(VIDEO_FAST_FORWARD)
+COMPATIBLE_IOCTL(VIDEO_SLOWMOTION)
+COMPATIBLE_IOCTL(VIDEO_GET_CAPABILITIES)
+COMPATIBLE_IOCTL(VIDEO_CLEAR_BUFFER)
+COMPATIBLE_IOCTL(VIDEO_SET_ID)
+COMPATIBLE_IOCTL(VIDEO_SET_STREAMTYPE)
+COMPATIBLE_IOCTL(VIDEO_SET_FORMAT)
+COMPATIBLE_IOCTL(VIDEO_SET_SYSTEM)
+COMPATIBLE_IOCTL(VIDEO_SET_HIGHLIGHT)
+COMPATIBLE_IOCTL(VIDEO_SET_SPU)
+COMPATIBLE_IOCTL(VIDEO_GET_NAVI)
+COMPATIBLE_IOCTL(VIDEO_SET_ATTRIBUTES)
+COMPATIBLE_IOCTL(VIDEO_GET_SIZE)
+COMPATIBLE_IOCTL(VIDEO_GET_FRAME_RATE)
+
+/* now things that need handlers */
HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob)
HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob)
#ifdef CONFIG_NET
@@ -2638,4 +3474,156 @@ IGNORE_IOCTL(VFAT_IOCTL_READDIR_BOTH32)
IGNORE_IOCTL(VFAT_IOCTL_READDIR_SHORT32)
};
-int ioctl_table_size = ARRAY_SIZE(ioctl_start);
+#define IOCTL_HASHSIZE 256
+static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE];
+
+static inline unsigned long ioctl32_hash(unsigned long cmd)
+{
+ return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE;
+}
+
+static void compat_ioctl_error(struct file *filp, unsigned int fd,
+ unsigned int cmd, unsigned long arg)
+{
+ char buf[10];
+ char *fn = "?";
+ char *path;
+
+ /* find the name of the device. */
+ path = (char *)__get_free_page(GFP_KERNEL);
+ if (path) {
+ fn = d_path(filp->f_path.dentry, filp->f_path.mnt, path, PAGE_SIZE);
+ if (IS_ERR(fn))
+ fn = "?";
+ }
+
+ sprintf(buf,"'%c'", (cmd>>_IOC_TYPESHIFT) & _IOC_TYPEMASK);
+ if (!isprint(buf[1]))
+ sprintf(buf, "%02x", buf[1]);
+ compat_printk("ioctl32(%s:%d): Unknown cmd fd(%d) "
+ "cmd(%08x){t:%s;sz:%u} arg(%08x) on %s\n",
+ current->comm, current->pid,
+ (int)fd, (unsigned int)cmd, buf,
+ (cmd >> _IOC_SIZESHIFT) & _IOC_SIZEMASK,
+ (unsigned int)arg, fn);
+
+ if (path)
+ free_page((unsigned long)path);
+}
+
+asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
+ unsigned long arg)
+{
+ struct file *filp;
+ int error = -EBADF;
+ struct ioctl_trans *t;
+ int fput_needed;
+
+ filp = fget_light(fd, &fput_needed);
+ if (!filp)
+ goto out;
+
+ /* RED-PEN how should LSM module know it's handling 32bit? */
+ error = security_file_ioctl(filp, cmd, arg);
+ if (error)
+ goto out_fput;
+
+ /*
+ * To allow the compat_ioctl handlers to be self contained
+ * we need to check the common ioctls here first.
+ * Just handle them with the standard handlers below.
+ */
+ switch (cmd) {
+ case FIOCLEX:
+ case FIONCLEX:
+ case FIONBIO:
+ case FIOASYNC:
+ case FIOQSIZE:
+ break;
+
+ case FIBMAP:
+ case FIGETBSZ:
+ case FIONREAD:
+ if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
+ break;
+ /*FALL THROUGH*/
+
+ default:
+ if (filp->f_op && filp->f_op->compat_ioctl) {
+ error = filp->f_op->compat_ioctl(filp, cmd, arg);
+ if (error != -ENOIOCTLCMD)
+ goto out_fput;
+ }
+
+ if (!filp->f_op ||
+ (!filp->f_op->ioctl && !filp->f_op->unlocked_ioctl))
+ goto do_ioctl;
+ break;
+ }
+
+ for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) {
+ if (t->cmd == cmd)
+ goto found_handler;
+ }
+
+ if (S_ISSOCK(filp->f_path.dentry->d_inode->i_mode) &&
+ cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
+ error = siocdevprivate_ioctl(fd, cmd, arg);
+ } else {
+ static int count;
+
+ if (++count <= 50)
+ compat_ioctl_error(filp, fd, cmd, arg);
+ error = -EINVAL;
+ }
+
+ goto out_fput;
+
+ found_handler:
+ if (t->handler) {
+ lock_kernel();
+ error = t->handler(fd, cmd, arg, filp);
+ unlock_kernel();
+ goto out_fput;
+ }
+
+ do_ioctl:
+ error = vfs_ioctl(filp, fd, cmd, arg);
+ out_fput:
+ fput_light(filp, fput_needed);
+ out:
+ return error;
+}
+
+static void ioctl32_insert_translation(struct ioctl_trans *trans)
+{
+ unsigned long hash;
+ struct ioctl_trans *t;
+
+ hash = ioctl32_hash (trans->cmd);
+ if (!ioctl32_hash_table[hash])
+ ioctl32_hash_table[hash] = trans;
+ else {
+ t = ioctl32_hash_table[hash];
+ while (t->next)
+ t = t->next;
+ trans->next = NULL;
+ t->next = trans;
+ }
+}
+
+static int __init init_sys32_ioctl(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ioctl_start); i++) {
+ if (ioctl_start[i].next != 0) {
+ printk("ioctl translation %d bad\n",i);
+ return -1;
+ }
+
+ ioctl32_insert_translation(&ioctl_start[i]);
+ }
+ return 0;
+}
+__initcall(init_sys32_ioctl);
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index facd0c8..3d194a2 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -180,7 +180,8 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
struct page *page = NULL;
if (blocknr + i < devsize) {
- page = read_mapping_page(mapping, blocknr + i, NULL);
+ page = read_mapping_page_async(mapping, blocknr + i,
+ NULL);
/* synchronous error? */
if (IS_ERR(page))
page = NULL;
diff --git a/fs/dcache.c b/fs/dcache.c
index d68631f..0e73aa0 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -21,7 +21,6 @@
#include <linux/fsnotify.h>
#include <linux/slab.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/hash.h>
#include <linux/cache.h>
#include <linux/module.h>
@@ -121,6 +120,28 @@ static void dentry_iput(struct dentry * dentry)
}
}
+/**
+ * d_kill - kill dentry and return parent
+ * @dentry: dentry to kill
+ *
+ * Called with dcache_lock and d_lock, releases both. The dentry must
+ * already be unhashed and removed from the LRU.
+ *
+ * If this is the root of the dentry tree, return NULL.
+ */
+static struct dentry *d_kill(struct dentry *dentry)
+{
+ struct dentry *parent;
+
+ list_del(&dentry->d_u.d_child);
+ dentry_stat.nr_dentry--; /* For d_free, below */
+ /*drops the locks, at that point nobody can reach this dentry */
+ dentry_iput(dentry);
+ parent = dentry->d_parent;
+ d_free(dentry);
+ return dentry == parent ? NULL : parent;
+}
+
/*
* This is dput
*
@@ -189,28 +210,17 @@ repeat:
unhash_it:
__d_drop(dentry);
-
-kill_it: {
- struct dentry *parent;
-
- /* If dentry was on d_lru list
- * delete it from there
- */
- if (!list_empty(&dentry->d_lru)) {
- list_del(&dentry->d_lru);
- dentry_stat.nr_unused--;
- }
- list_del(&dentry->d_u.d_child);
- dentry_stat.nr_dentry--; /* For d_free, below */
- /*drops the locks, at that point nobody can reach this dentry */
- dentry_iput(dentry);
- parent = dentry->d_parent;
- d_free(dentry);
- if (dentry == parent)
- return;
- dentry = parent;
- goto repeat;
+kill_it:
+ /* If dentry was on d_lru list
+ * delete it from there
+ */
+ if (!list_empty(&dentry->d_lru)) {
+ list_del(&dentry->d_lru);
+ dentry_stat.nr_unused--;
}
+ dentry = d_kill(dentry);
+ if (dentry)
+ goto repeat;
}
/**
@@ -371,22 +381,40 @@ restart:
* Throw away a dentry - free the inode, dput the parent. This requires that
* the LRU list has already been removed.
*
+ * If prune_parents is true, try to prune ancestors as well.
+ *
* Called with dcache_lock, drops it and then regains.
* Called with dentry->d_lock held, drops it.
*/
-static void prune_one_dentry(struct dentry * dentry)
+static void prune_one_dentry(struct dentry * dentry, int prune_parents)
{
- struct dentry * parent;
-
__d_drop(dentry);
- list_del(&dentry->d_u.d_child);
- dentry_stat.nr_dentry--; /* For d_free, below */
- dentry_iput(dentry);
- parent = dentry->d_parent;
- d_free(dentry);
- if (parent != dentry)
- dput(parent);
+ dentry = d_kill(dentry);
+ if (!prune_parents) {
+ dput(dentry);
+ spin_lock(&dcache_lock);
+ return;
+ }
+
+ /*
+ * Prune ancestors. Locking is simpler than in dput(),
+ * because dcache_lock needs to be taken anyway.
+ */
spin_lock(&dcache_lock);
+ while (dentry) {
+ if (!atomic_dec_and_lock(&dentry->d_count, &dentry->d_lock))
+ return;
+
+ if (dentry->d_op && dentry->d_op->d_delete)
+ dentry->d_op->d_delete(dentry);
+ if (!list_empty(&dentry->d_lru)) {
+ list_del(&dentry->d_lru);
+ dentry_stat.nr_unused--;
+ }
+ __d_drop(dentry);
+ dentry = d_kill(dentry);
+ spin_lock(&dcache_lock);
+ }
}
/**
@@ -394,6 +422,7 @@ static void prune_one_dentry(struct dentry * dentry)
* @count: number of entries to try and free
* @sb: if given, ignore dentries for other superblocks
* which are being unmounted.
+ * @prune_parents: if true, try to prune ancestors as well in one go
*
* Shrink the dcache. This is done when we need
* more memory, or simply when we need to unmount
@@ -404,7 +433,7 @@ static void prune_one_dentry(struct dentry * dentry)
* all the dentries are in use.
*/
-static void prune_dcache(int count, struct super_block *sb)
+static void prune_dcache(int count, struct super_block *sb, int prune_parents)
{
spin_lock(&dcache_lock);
for (; count ; count--) {
@@ -464,7 +493,7 @@ static void prune_dcache(int count, struct super_block *sb)
* without taking the s_umount lock (I already hold it).
*/
if (sb && dentry->d_sb == sb) {
- prune_one_dentry(dentry);
+ prune_one_dentry(dentry, prune_parents);
continue;
}
/*
@@ -479,7 +508,7 @@ static void prune_dcache(int count, struct super_block *sb)
s_umount = &dentry->d_sb->s_umount;
if (down_read_trylock(s_umount)) {
if (dentry->d_sb->s_root != NULL) {
- prune_one_dentry(dentry);
+ prune_one_dentry(dentry, prune_parents);
up_read(s_umount);
continue;
}
@@ -550,7 +579,7 @@ repeat:
spin_unlock(&dentry->d_lock);
continue;
}
- prune_one_dentry(dentry);
+ prune_one_dentry(dentry, 1);
cond_resched_lock(&dcache_lock);
goto repeat;
}
@@ -829,7 +858,7 @@ void shrink_dcache_parent(struct dentry * parent)
int found;
while ((found = select_parent(parent)) != 0)
- prune_dcache(found, parent->d_sb);
+ prune_dcache(found, parent->d_sb, 1);
}
/*
@@ -849,7 +878,7 @@ static int shrink_dcache_memory(int nr, gfp_t gfp_mask)
if (nr) {
if (!(gfp_mask & __GFP_FS))
return -1;
- prune_dcache(nr, NULL);
+ prune_dcache(nr, NULL, 1);
}
return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure;
}
@@ -1823,6 +1852,16 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
struct vfsmount *rootmnt;
struct dentry *root;
+ /*
+ * We have various synthetic filesystems that never get mounted. On
+ * these filesystems dentries are never used for lookup purposes, and
+ * thus don't need to be hashed. They also don't need a name until a
+ * user wants to identify the object in /proc/pid/fd/. The little hack
+ * below allows us to generate a name for these objects on demand:
+ */
+ if (dentry->d_op && dentry->d_op->d_dname)
+ return dentry->d_op->d_dname(dentry, buf, buflen);
+
read_lock(&current->fs->lock);
rootmnt = mntget(current->fs->rootmnt);
root = dget(current->fs->root);
@@ -1836,6 +1875,27 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
}
/*
+ * Helper function for dentry_operations.d_dname() members
+ */
+char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
+ const char *fmt, ...)
+{
+ va_list args;
+ char temp[64];
+ int sz;
+
+ va_start(args, fmt);
+ sz = vsnprintf(temp, sizeof(temp), fmt, args) + 1;
+ va_end(args);
+
+ if (sz > sizeof(temp) || sz > buflen)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ buffer += buflen - sz;
+ return memcpy(buffer, temp, sz);
+}
+
+/*
* NOTE! The user-level library version returns a
* character pointer. The kernel system call just
* returns the length of the buffer filled (which
@@ -2052,12 +2112,8 @@ static void __init dcache_init(unsigned long mempages)
* but it is probably not worth it because of the cache nature
* of the dcache.
*/
- dentry_cache = kmem_cache_create("dentry_cache",
- sizeof(struct dentry),
- 0,
- (SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|
- SLAB_MEM_SPREAD),
- NULL, NULL);
+ dentry_cache = KMEM_CACHE(dentry,
+ SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD);
set_shrinker(DEFAULT_SEEKS, shrink_dcache_memory);
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 643e57b..06ef9a2 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -19,6 +19,7 @@
#include <linux/tty.h>
#include <linux/devpts_fs.h>
#include <linux/parser.h>
+#include <linux/fsnotify.h>
#define DEVPTS_SUPER_MAGIC 0x1cd1
@@ -178,8 +179,10 @@ int devpts_pty_new(struct tty_struct *tty)
inode->i_private = tty;
dentry = get_node(number);
- if (!IS_ERR(dentry) && !dentry->d_inode)
+ if (!IS_ERR(dentry) && !dentry->d_inode) {
d_instantiate(dentry, inode);
+ fsnotify_create(devpts_root->d_inode, dentry);
+ }
mutex_unlock(&devpts_root->d_inode->i_mutex);
diff --git a/fs/dlm/Kconfig b/fs/dlm/Kconfig
index 6fa7b0d..69a9469 100644
--- a/fs/dlm/Kconfig
+++ b/fs/dlm/Kconfig
@@ -3,36 +3,19 @@ menu "Distributed Lock Manager"
config DLM
tristate "Distributed Lock Manager (DLM)"
- depends on SYSFS && (IPV6 || IPV6=n)
+ depends on IPV6 || IPV6=n
select CONFIGFS_FS
- select IP_SCTP if DLM_SCTP
+ select IP_SCTP
help
- A general purpose distributed lock manager for kernel or userspace
- applications.
-
-choice
- prompt "Select DLM communications protocol"
- depends on DLM
- default DLM_TCP
- help
- The DLM Can use TCP or SCTP for it's network communications.
- SCTP supports multi-homed operations whereas TCP doesn't.
- However, SCTP seems to have stability problems at the moment.
-
-config DLM_TCP
- bool "TCP/IP"
-
-config DLM_SCTP
- bool "SCTP"
-
-endchoice
+ A general purpose distributed lock manager for kernel or userspace
+ applications.
config DLM_DEBUG
bool "DLM debugging"
depends on DLM
help
- Under the debugfs mount point, the name of each lockspace will
- appear as a file in the "dlm" directory. The output is the
- list of resource and locks the local node knows about.
+ Under the debugfs mount point, the name of each lockspace will
+ appear as a file in the "dlm" directory. The output is the
+ list of resource and locks the local node knows about.
endmenu
diff --git a/fs/dlm/Makefile b/fs/dlm/Makefile
index 6538894..604cf7d 100644
--- a/fs/dlm/Makefile
+++ b/fs/dlm/Makefile
@@ -8,14 +8,12 @@ dlm-y := ast.o \
member.o \
memory.o \
midcomms.o \
+ lowcomms.o \
rcom.o \
recover.o \
recoverd.o \
requestqueue.o \
user.o \
- util.o
+ util.o
dlm-$(CONFIG_DLM_DEBUG) += debug_fs.o
-dlm-$(CONFIG_DLM_TCP) += lowcomms-tcp.o
-
-dlm-$(CONFIG_DLM_SCTP) += lowcomms-sctp.o \ No newline at end of file
diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c
index f91d39c..6308122 100644
--- a/fs/dlm/ast.c
+++ b/fs/dlm/ast.c
@@ -14,6 +14,7 @@
#include "dlm_internal.h"
#include "lock.h"
#include "user.h"
+#include "ast.h"
#define WAKE_ASTS 0
diff --git a/fs/dlm/config.c b/fs/dlm/config.c
index 8665c88..822abdc 100644
--- a/fs/dlm/config.c
+++ b/fs/dlm/config.c
@@ -2,7 +2,7 @@
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
-** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -89,6 +89,7 @@ struct cluster {
unsigned int cl_toss_secs;
unsigned int cl_scan_secs;
unsigned int cl_log_debug;
+ unsigned int cl_protocol;
};
enum {
@@ -101,6 +102,7 @@ enum {
CLUSTER_ATTR_TOSS_SECS,
CLUSTER_ATTR_SCAN_SECS,
CLUSTER_ATTR_LOG_DEBUG,
+ CLUSTER_ATTR_PROTOCOL,
};
struct cluster_attribute {
@@ -159,6 +161,7 @@ CLUSTER_ATTR(recover_timer, 1);
CLUSTER_ATTR(toss_secs, 1);
CLUSTER_ATTR(scan_secs, 1);
CLUSTER_ATTR(log_debug, 0);
+CLUSTER_ATTR(protocol, 0);
static struct configfs_attribute *cluster_attrs[] = {
[CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr,
@@ -170,6 +173,7 @@ static struct configfs_attribute *cluster_attrs[] = {
[CLUSTER_ATTR_TOSS_SECS] = &cluster_attr_toss_secs.attr,
[CLUSTER_ATTR_SCAN_SECS] = &cluster_attr_scan_secs.attr,
[CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug.attr,
+ [CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol.attr,
NULL,
};
@@ -904,6 +908,7 @@ int dlm_our_addr(struct sockaddr_storage *addr, int num)
#define DEFAULT_TOSS_SECS 10
#define DEFAULT_SCAN_SECS 5
#define DEFAULT_LOG_DEBUG 0
+#define DEFAULT_PROTOCOL 0
struct dlm_config_info dlm_config = {
.ci_tcp_port = DEFAULT_TCP_PORT,
@@ -914,6 +919,7 @@ struct dlm_config_info dlm_config = {
.ci_recover_timer = DEFAULT_RECOVER_TIMER,
.ci_toss_secs = DEFAULT_TOSS_SECS,
.ci_scan_secs = DEFAULT_SCAN_SECS,
- .ci_log_debug = DEFAULT_LOG_DEBUG
+ .ci_log_debug = DEFAULT_LOG_DEBUG,
+ .ci_protocol = DEFAULT_PROTOCOL
};
diff --git a/fs/dlm/config.h b/fs/dlm/config.h
index 1e97861..967cc3d 100644
--- a/fs/dlm/config.h
+++ b/fs/dlm/config.h
@@ -2,7 +2,7 @@
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
-** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -26,6 +26,7 @@ struct dlm_config_info {
int ci_toss_secs;
int ci_scan_secs;
int ci_log_debug;
+ int ci_protocol;
};
extern struct dlm_config_info dlm_config;
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
index 61d9320..30994d6 100644
--- a/fs/dlm/dlm_internal.h
+++ b/fs/dlm/dlm_internal.h
@@ -2,7 +2,7 @@
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
-** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -210,6 +210,9 @@ struct dlm_args {
#define DLM_IFL_MSTCPY 0x00010000
#define DLM_IFL_RESEND 0x00020000
#define DLM_IFL_DEAD 0x00040000
+#define DLM_IFL_OVERLAP_UNLOCK 0x00080000
+#define DLM_IFL_OVERLAP_CANCEL 0x00100000
+#define DLM_IFL_ENDOFLIFE 0x00200000
#define DLM_IFL_USER 0x00000001
#define DLM_IFL_ORPHAN 0x00000002
@@ -230,8 +233,8 @@ struct dlm_lkb {
int8_t lkb_grmode; /* granted lock mode */
int8_t lkb_bastmode; /* requested mode */
int8_t lkb_highbast; /* highest mode bast sent for */
-
int8_t lkb_wait_type; /* type of reply waiting for */
+ int8_t lkb_wait_count;
int8_t lkb_ast_type; /* type of ast queued for */
struct list_head lkb_idtbl_list; /* lockspace lkbtbl */
@@ -339,6 +342,7 @@ struct dlm_header {
#define DLM_MSG_LOOKUP 11
#define DLM_MSG_REMOVE 12
#define DLM_MSG_LOOKUP_REPLY 13
+#define DLM_MSG_PURGE 14
struct dlm_message {
struct dlm_header m_header;
@@ -440,6 +444,9 @@ struct dlm_ls {
struct mutex ls_waiters_mutex;
struct list_head ls_waiters; /* lkbs needing a reply */
+ struct mutex ls_orphans_mutex;
+ struct list_head ls_orphans;
+
struct list_head ls_nodes; /* current nodes in ls */
struct list_head ls_nodes_gone; /* dead node list, recovery */
int ls_num_nodes; /* number of nodes in ls */
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index e725005..d8d6e72 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -1,7 +1,7 @@
/******************************************************************************
*******************************************************************************
**
-** Copyright (C) 2005 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -85,6 +85,7 @@ static int _request_lock(struct dlm_rsb *r, struct dlm_lkb *lkb);
static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
struct dlm_message *ms);
static int receive_extralen(struct dlm_message *ms);
+static void do_purge(struct dlm_ls *ls, int nodeid, int pid);
/*
* Lock compatibilty matrix - thanks Steve
@@ -223,6 +224,16 @@ static inline int is_demoted(struct dlm_lkb *lkb)
return (lkb->lkb_sbflags & DLM_SBF_DEMOTED);
}
+static inline int is_altmode(struct dlm_lkb *lkb)
+{
+ return (lkb->lkb_sbflags & DLM_SBF_ALTMODE);
+}
+
+static inline int is_granted(struct dlm_lkb *lkb)
+{
+ return (lkb->lkb_status == DLM_LKSTS_GRANTED);
+}
+
static inline int is_remote(struct dlm_rsb *r)
{
DLM_ASSERT(r->res_nodeid >= 0, dlm_print_rsb(r););
@@ -254,6 +265,22 @@ static inline int down_conversion(struct dlm_lkb *lkb)
return (!middle_conversion(lkb) && lkb->lkb_rqmode < lkb->lkb_grmode);
}
+static inline int is_overlap_unlock(struct dlm_lkb *lkb)
+{
+ return lkb->lkb_flags & DLM_IFL_OVERLAP_UNLOCK;
+}
+
+static inline int is_overlap_cancel(struct dlm_lkb *lkb)
+{
+ return lkb->lkb_flags & DLM_IFL_OVERLAP_CANCEL;
+}
+
+static inline int is_overlap(struct dlm_lkb *lkb)
+{
+ return (lkb->lkb_flags & (DLM_IFL_OVERLAP_UNLOCK |
+ DLM_IFL_OVERLAP_CANCEL));
+}
+
static void queue_cast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv)
{
if (is_master_copy(lkb))
@@ -267,6 +294,12 @@ static void queue_cast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rv)
dlm_add_ast(lkb, AST_COMP);
}
+static inline void queue_cast_overlap(struct dlm_rsb *r, struct dlm_lkb *lkb)
+{
+ queue_cast(r, lkb,
+ is_overlap_unlock(lkb) ? -DLM_EUNLOCK : -DLM_ECANCEL);
+}
+
static void queue_bast(struct dlm_rsb *r, struct dlm_lkb *lkb, int rqmode)
{
if (is_master_copy(lkb))
@@ -547,6 +580,7 @@ static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
lkb->lkb_grmode = DLM_LOCK_IV;
kref_init(&lkb->lkb_ref);
INIT_LIST_HEAD(&lkb->lkb_ownqueue);
+ INIT_LIST_HEAD(&lkb->lkb_rsb_lookup);
get_random_bytes(&bucket, sizeof(bucket));
bucket &= (ls->ls_lkbtbl_size - 1);
@@ -556,7 +590,7 @@ static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
/* counter can roll over so we must verify lkid is not in use */
while (lkid == 0) {
- lkid = bucket | (ls->ls_lkbtbl[bucket].counter++ << 16);
+ lkid = (bucket << 16) | ls->ls_lkbtbl[bucket].counter++;
list_for_each_entry(tmp, &ls->ls_lkbtbl[bucket].list,
lkb_idtbl_list) {
@@ -577,8 +611,8 @@ static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
static struct dlm_lkb *__find_lkb(struct dlm_ls *ls, uint32_t lkid)
{
- uint16_t bucket = lkid & 0xFFFF;
struct dlm_lkb *lkb;
+ uint16_t bucket = (lkid >> 16);
list_for_each_entry(lkb, &ls->ls_lkbtbl[bucket].list, lkb_idtbl_list) {
if (lkb->lkb_id == lkid)
@@ -590,7 +624,7 @@ static struct dlm_lkb *__find_lkb(struct dlm_ls *ls, uint32_t lkid)
static int find_lkb(struct dlm_ls *ls, uint32_t lkid, struct dlm_lkb **lkb_ret)
{
struct dlm_lkb *lkb;
- uint16_t bucket = lkid & 0xFFFF;
+ uint16_t bucket = (lkid >> 16);
if (bucket >= ls->ls_lkbtbl_size)
return -EBADSLT;
@@ -620,7 +654,7 @@ static void kill_lkb(struct kref *kref)
static int __put_lkb(struct dlm_ls *ls, struct dlm_lkb *lkb)
{
- uint16_t bucket = lkb->lkb_id & 0xFFFF;
+ uint16_t bucket = (lkb->lkb_id >> 16);
write_lock(&ls->ls_lkbtbl[bucket].lock);
if (kref_put(&lkb->lkb_ref, kill_lkb)) {
@@ -735,23 +769,75 @@ static void move_lkb(struct dlm_rsb *r, struct dlm_lkb *lkb, int sts)
unhold_lkb(lkb);
}
+static int msg_reply_type(int mstype)
+{
+ switch (mstype) {
+ case DLM_MSG_REQUEST:
+ return DLM_MSG_REQUEST_REPLY;
+ case DLM_MSG_CONVERT:
+ return DLM_MSG_CONVERT_REPLY;
+ case DLM_MSG_UNLOCK:
+ return DLM_MSG_UNLOCK_REPLY;
+ case DLM_MSG_CANCEL:
+ return DLM_MSG_CANCEL_REPLY;
+ case DLM_MSG_LOOKUP:
+ return DLM_MSG_LOOKUP_REPLY;
+ }
+ return -1;
+}
+
/* add/remove lkb from global waiters list of lkb's waiting for
a reply from a remote node */
-static void add_to_waiters(struct dlm_lkb *lkb, int mstype)
+static int add_to_waiters(struct dlm_lkb *lkb, int mstype)
{
struct dlm_ls *ls = lkb->lkb_resource->res_ls;
+ int error = 0;
mutex_lock(&ls->ls_waiters_mutex);
- if (lkb->lkb_wait_type) {
- log_print("add_to_waiters error %d", lkb->lkb_wait_type);
+
+ if (is_overlap_unlock(lkb) ||
+ (is_overlap_cancel(lkb) && (mstype == DLM_MSG_CANCEL))) {
+ error = -EINVAL;
+ goto out;
+ }
+
+ if (lkb->lkb_wait_type || is_overlap_cancel(lkb)) {
+ switch (mstype) {
+ case DLM_MSG_UNLOCK:
+ lkb->lkb_flags |= DLM_IFL_OVERLAP_UNLOCK;
+ break;
+ case DLM_MSG_CANCEL:
+ lkb->lkb_flags |= DLM_IFL_OVERLAP_CANCEL;
+ break;
+ default:
+ error = -EBUSY;
+ goto out;
+ }
+ lkb->lkb_wait_count++;
+ hold_lkb(lkb);
+
+ log_debug(ls, "add overlap %x cur %d new %d count %d flags %x",
+ lkb->lkb_id, lkb->lkb_wait_type, mstype,
+ lkb->lkb_wait_count, lkb->lkb_flags);
goto out;
}
+
+ DLM_ASSERT(!lkb->lkb_wait_count,
+ dlm_print_lkb(lkb);
+ printk("wait_count %d\n", lkb->lkb_wait_count););
+
+ lkb->lkb_wait_count++;
lkb->lkb_wait_type = mstype;
- kref_get(&lkb->lkb_ref);
+ hold_lkb(lkb);
list_add(&lkb->lkb_wait_reply, &ls->ls_waiters);
out:
+ if (error)
+ log_error(ls, "add_to_waiters %x error %d flags %x %d %d %s",
+ lkb->lkb_id, error, lkb->lkb_flags, mstype,
+ lkb->lkb_wait_type, lkb->lkb_resource->res_name);
mutex_unlock(&ls->ls_waiters_mutex);
+ return error;
}
/* We clear the RESEND flag because we might be taking an lkb off the waiters
@@ -759,34 +845,85 @@ static void add_to_waiters(struct dlm_lkb *lkb, int mstype)
request reply on the requestqueue) between dlm_recover_waiters_pre() which
set RESEND and dlm_recover_waiters_post() */
-static int _remove_from_waiters(struct dlm_lkb *lkb)
+static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype)
{
- int error = 0;
+ struct dlm_ls *ls = lkb->lkb_resource->res_ls;
+ int overlap_done = 0;
- if (!lkb->lkb_wait_type) {
- log_print("remove_from_waiters error");
- error = -EINVAL;
- goto out;
+ if (is_overlap_unlock(lkb) && (mstype == DLM_MSG_UNLOCK_REPLY)) {
+ lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK;
+ overlap_done = 1;
+ goto out_del;
+ }
+
+ if (is_overlap_cancel(lkb) && (mstype == DLM_MSG_CANCEL_REPLY)) {
+ lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL;
+ overlap_done = 1;
+ goto out_del;
+ }
+
+ /* N.B. type of reply may not always correspond to type of original
+ msg due to lookup->request optimization, verify others? */
+
+ if (lkb->lkb_wait_type) {
+ lkb->lkb_wait_type = 0;
+ goto out_del;
+ }
+
+ log_error(ls, "remove_from_waiters lkid %x flags %x types %d %d",
+ lkb->lkb_id, lkb->lkb_flags, mstype, lkb->lkb_wait_type);
+ return -1;
+
+ out_del:
+ /* the force-unlock/cancel has completed and we haven't recvd a reply
+ to the op that was in progress prior to the unlock/cancel; we
+ give up on any reply to the earlier op. FIXME: not sure when/how
+ this would happen */
+
+ if (overlap_done && lkb->lkb_wait_type) {
+ log_error(ls, "remove_from_waiters %x reply %d give up on %d",
+ lkb->lkb_id, mstype, lkb->lkb_wait_type);
+ lkb->lkb_wait_count--;
+ lkb->lkb_wait_type = 0;
}
- lkb->lkb_wait_type = 0;
+
+ DLM_ASSERT(lkb->lkb_wait_count, dlm_print_lkb(lkb););
+
lkb->lkb_flags &= ~DLM_IFL_RESEND;
- list_del(&lkb->lkb_wait_reply);
+ lkb->lkb_wait_count--;
+ if (!lkb->lkb_wait_count)
+ list_del_init(&lkb->lkb_wait_reply);
unhold_lkb(lkb);
- out:
- return error;
+ return 0;
}
-static int remove_from_waiters(struct dlm_lkb *lkb)
+static int remove_from_waiters(struct dlm_lkb *lkb, int mstype)
{
struct dlm_ls *ls = lkb->lkb_resource->res_ls;
int error;
mutex_lock(&ls->ls_waiters_mutex);
- error = _remove_from_waiters(lkb);
+ error = _remove_from_waiters(lkb, mstype);
mutex_unlock(&ls->ls_waiters_mutex);
return error;
}
+/* Handles situations where we might be processing a "fake" or "stub" reply in
+ which we can't try to take waiters_mutex again. */
+
+static int remove_from_waiters_ms(struct dlm_lkb *lkb, struct dlm_message *ms)
+{
+ struct dlm_ls *ls = lkb->lkb_resource->res_ls;
+ int error;
+
+ if (ms != &ls->ls_stub_ms)
+ mutex_lock(&ls->ls_waiters_mutex);
+ error = _remove_from_waiters(lkb, ms->m_type);
+ if (ms != &ls->ls_stub_ms)
+ mutex_unlock(&ls->ls_waiters_mutex);
+ return error;
+}
+
static void dir_remove(struct dlm_rsb *r)
{
int to_nodeid;
@@ -988,8 +1125,14 @@ static void remove_lock_pc(struct dlm_rsb *r, struct dlm_lkb *lkb)
_remove_lock(r, lkb);
}
-static void revert_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
+/* returns: 0 did nothing
+ 1 moved lock to granted
+ -1 removed lock */
+
+static int revert_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
{
+ int rv = 0;
+
lkb->lkb_rqmode = DLM_LOCK_IV;
switch (lkb->lkb_status) {
@@ -997,6 +1140,7 @@ static void revert_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
break;
case DLM_LKSTS_CONVERT:
move_lkb(r, lkb, DLM_LKSTS_GRANTED);
+ rv = 1;
break;
case DLM_LKSTS_WAITING:
del_lkb(r, lkb);
@@ -1004,15 +1148,17 @@ static void revert_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
/* this unhold undoes the original ref from create_lkb()
so this leads to the lkb being freed */
unhold_lkb(lkb);
+ rv = -1;
break;
default:
log_print("invalid status for revert %d", lkb->lkb_status);
}
+ return rv;
}
-static void revert_lock_pc(struct dlm_rsb *r, struct dlm_lkb *lkb)
+static int revert_lock_pc(struct dlm_rsb *r, struct dlm_lkb *lkb)
{
- revert_lock(r, lkb);
+ return revert_lock(r, lkb);
}
static void _grant_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
@@ -1055,6 +1201,50 @@ static void grant_lock_pending(struct dlm_rsb *r, struct dlm_lkb *lkb)
queue_cast(r, lkb, 0);
}
+/* The special CONVDEADLK, ALTPR and ALTCW flags allow the master to
+ change the granted/requested modes. We're munging things accordingly in
+ the process copy.
+ CONVDEADLK: our grmode may have been forced down to NL to resolve a
+ conversion deadlock
+ ALTPR/ALTCW: our rqmode may have been changed to PR or CW to become
+ compatible with other granted locks */
+
+static void munge_demoted(struct dlm_lkb *lkb, struct dlm_message *ms)
+{
+ if (ms->m_type != DLM_MSG_CONVERT_REPLY) {
+ log_print("munge_demoted %x invalid reply type %d",
+ lkb->lkb_id, ms->m_type);
+ return;
+ }
+
+ if (lkb->lkb_rqmode == DLM_LOCK_IV || lkb->lkb_grmode == DLM_LOCK_IV) {
+ log_print("munge_demoted %x invalid modes gr %d rq %d",
+ lkb->lkb_id, lkb->lkb_grmode, lkb->lkb_rqmode);
+ return;
+ }
+
+ lkb->lkb_grmode = DLM_LOCK_NL;
+}
+
+static void munge_altmode(struct dlm_lkb *lkb, struct dlm_message *ms)
+{
+ if (ms->m_type != DLM_MSG_REQUEST_REPLY &&
+ ms->m_type != DLM_MSG_GRANT) {
+ log_print("munge_altmode %x invalid reply type %d",
+ lkb->lkb_id, ms->m_type);
+ return;
+ }
+
+ if (lkb->lkb_exflags & DLM_LKF_ALTPR)
+ lkb->lkb_rqmode = DLM_LOCK_PR;
+ else if (lkb->lkb_exflags & DLM_LKF_ALTCW)
+ lkb->lkb_rqmode = DLM_LOCK_CW;
+ else {
+ log_print("munge_altmode invalid exflags %x", lkb->lkb_exflags);
+ dlm_print_lkb(lkb);
+ }
+}
+
static inline int first_in_list(struct dlm_lkb *lkb, struct list_head *head)
{
struct dlm_lkb *first = list_entry(head->next, struct dlm_lkb,
@@ -1499,7 +1689,7 @@ static void process_lookup_list(struct dlm_rsb *r)
struct dlm_lkb *lkb, *safe;
list_for_each_entry_safe(lkb, safe, &r->res_lookup, lkb_rsb_lookup) {
- list_del(&lkb->lkb_rsb_lookup);
+ list_del_init(&lkb->lkb_rsb_lookup);
_request_lock(r, lkb);
schedule();
}
@@ -1530,7 +1720,7 @@ static void confirm_master(struct dlm_rsb *r, int error)
if (!list_empty(&r->res_lookup)) {
lkb = list_entry(r->res_lookup.next, struct dlm_lkb,
lkb_rsb_lookup);
- list_del(&lkb->lkb_rsb_lookup);
+ list_del_init(&lkb->lkb_rsb_lookup);
r->res_first_lkid = lkb->lkb_id;
_request_lock(r, lkb);
} else
@@ -1614,6 +1804,9 @@ static int set_unlock_args(uint32_t flags, void *astarg, struct dlm_args *args)
DLM_LKF_FORCEUNLOCK))
return -EINVAL;
+ if (flags & DLM_LKF_CANCEL && flags & DLM_LKF_FORCEUNLOCK)
+ return -EINVAL;
+
args->flags = flags;
args->astparam = (long) astarg;
return 0;
@@ -1638,6 +1831,9 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
if (lkb->lkb_wait_type)
goto out;
+
+ if (is_overlap(lkb))
+ goto out;
}
lkb->lkb_exflags = args->flags;
@@ -1654,35 +1850,126 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
return rv;
}
+/* when dlm_unlock() sees -EBUSY with CANCEL/FORCEUNLOCK it returns 0
+ for success */
+
+/* note: it's valid for lkb_nodeid/res_nodeid to be -1 when we get here
+ because there may be a lookup in progress and it's valid to do
+ cancel/unlockf on it */
+
static int validate_unlock_args(struct dlm_lkb *lkb, struct dlm_args *args)
{
+ struct dlm_ls *ls = lkb->lkb_resource->res_ls;
int rv = -EINVAL;
- if (lkb->lkb_flags & DLM_IFL_MSTCPY)
+ if (lkb->lkb_flags & DLM_IFL_MSTCPY) {
+ log_error(ls, "unlock on MSTCPY %x", lkb->lkb_id);
+ dlm_print_lkb(lkb);
goto out;
+ }
- if (args->flags & DLM_LKF_FORCEUNLOCK)
- goto out_ok;
+ /* an lkb may still exist even though the lock is EOL'ed due to a
+ cancel, unlock or failed noqueue request; an app can't use these
+ locks; return same error as if the lkid had not been found at all */
- if (args->flags & DLM_LKF_CANCEL &&
- lkb->lkb_status == DLM_LKSTS_GRANTED)
+ if (lkb->lkb_flags & DLM_IFL_ENDOFLIFE) {
+ log_debug(ls, "unlock on ENDOFLIFE %x", lkb->lkb_id);
+ rv = -ENOENT;
goto out;
+ }
- if (!(args->flags & DLM_LKF_CANCEL) &&
- lkb->lkb_status != DLM_LKSTS_GRANTED)
- goto out;
+ /* an lkb may be waiting for an rsb lookup to complete where the
+ lookup was initiated by another lock */
+
+ if (args->flags & (DLM_LKF_CANCEL | DLM_LKF_FORCEUNLOCK)) {
+ if (!list_empty(&lkb->lkb_rsb_lookup)) {
+ log_debug(ls, "unlock on rsb_lookup %x", lkb->lkb_id);
+ list_del_init(&lkb->lkb_rsb_lookup);
+ queue_cast(lkb->lkb_resource, lkb,
+ args->flags & DLM_LKF_CANCEL ?
+ -DLM_ECANCEL : -DLM_EUNLOCK);
+ unhold_lkb(lkb); /* undoes create_lkb() */
+ rv = -EBUSY;
+ goto out;
+ }
+ }
+
+ /* cancel not allowed with another cancel/unlock in progress */
+
+ if (args->flags & DLM_LKF_CANCEL) {
+ if (lkb->lkb_exflags & DLM_LKF_CANCEL)
+ goto out;
+
+ if (is_overlap(lkb))
+ goto out;
+
+ if (lkb->lkb_flags & DLM_IFL_RESEND) {
+ lkb->lkb_flags |= DLM_IFL_OVERLAP_CANCEL;
+ rv = -EBUSY;
+ goto out;
+ }
+
+ switch (lkb->lkb_wait_type) {
+ case DLM_MSG_LOOKUP:
+ case DLM_MSG_REQUEST:
+ lkb->lkb_flags |= DLM_IFL_OVERLAP_CANCEL;
+ rv = -EBUSY;
+ goto out;
+ case DLM_MSG_UNLOCK:
+ case DLM_MSG_CANCEL:
+ goto out;
+ }
+ /* add_to_waiters() will set OVERLAP_CANCEL */
+ goto out_ok;
+ }
+
+ /* do we need to allow a force-unlock if there's a normal unlock
+ already in progress? in what conditions could the normal unlock
+ fail such that we'd want to send a force-unlock to be sure? */
+
+ if (args->flags & DLM_LKF_FORCEUNLOCK) {
+ if (lkb->lkb_exflags & DLM_LKF_FORCEUNLOCK)
+ goto out;
+
+ if (is_overlap_unlock(lkb))
+ goto out;
+ if (lkb->lkb_flags & DLM_IFL_RESEND) {
+ lkb->lkb_flags |= DLM_IFL_OVERLAP_UNLOCK;
+ rv = -EBUSY;
+ goto out;
+ }
+
+ switch (lkb->lkb_wait_type) {
+ case DLM_MSG_LOOKUP:
+ case DLM_MSG_REQUEST:
+ lkb->lkb_flags |= DLM_IFL_OVERLAP_UNLOCK;
+ rv = -EBUSY;
+ goto out;
+ case DLM_MSG_UNLOCK:
+ goto out;
+ }
+ /* add_to_waiters() will set OVERLAP_UNLOCK */
+ goto out_ok;
+ }
+
+ /* normal unlock not allowed if there's any op in progress */
rv = -EBUSY;
- if (lkb->lkb_wait_type)
+ if (lkb->lkb_wait_type || lkb->lkb_wait_count)
goto out;
out_ok:
- lkb->lkb_exflags = args->flags;
+ /* an overlapping op shouldn't blow away exflags from other op */
+ lkb->lkb_exflags |= args->flags;
lkb->lkb_sbflags = 0;
lkb->lkb_astparam = args->astparam;
-
rv = 0;
out:
+ if (rv)
+ log_debug(ls, "validate_unlock_args %d %x %x %x %x %d %s", rv,
+ lkb->lkb_id, lkb->lkb_flags, lkb->lkb_exflags,
+ args->flags, lkb->lkb_wait_type,
+ lkb->lkb_resource->res_name);
return rv;
}
@@ -1732,9 +2019,24 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
goto out;
}
- if (can_be_queued(lkb)) {
- if (is_demoted(lkb))
+ /* is_demoted() means the can_be_granted() above set the grmode
+ to NL, and left us on the granted queue. This auto-demotion
+ (due to CONVDEADLK) might mean other locks, and/or this lock, are
+ now grantable. We have to try to grant other converting locks
+ before we try again to grant this one. */
+
+ if (is_demoted(lkb)) {
+ grant_pending_convert(r, DLM_LOCK_IV);
+ if (_can_be_granted(r, lkb, 1)) {
+ grant_lock(r, lkb);
+ queue_cast(r, lkb, 0);
grant_pending_locks(r);
+ goto out;
+ }
+ /* else fall through and move to convert queue */
+ }
+
+ if (can_be_queued(lkb)) {
error = -EINPROGRESS;
del_lkb(r, lkb);
add_lkb(r, lkb, DLM_LKSTS_CONVERT);
@@ -1759,17 +2061,19 @@ static int do_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb)
return -DLM_EUNLOCK;
}
-/* FIXME: if revert_lock() finds that the lkb is granted, we should
- skip the queue_cast(ECANCEL). It indicates that the request/convert
- completed (and queued a normal ast) just before the cancel; we don't
- want to clobber the sb_result for the normal ast with ECANCEL. */
+/* returns: 0 did nothing, -DLM_ECANCEL canceled lock */
static int do_cancel(struct dlm_rsb *r, struct dlm_lkb *lkb)
{
- revert_lock(r, lkb);
- queue_cast(r, lkb, -DLM_ECANCEL);
- grant_pending_locks(r);
- return -DLM_ECANCEL;
+ int error;
+
+ error = revert_lock(r, lkb);
+ if (error) {
+ queue_cast(r, lkb, -DLM_ECANCEL);
+ grant_pending_locks(r);
+ return -DLM_ECANCEL;
+ }
+ return 0;
}
/*
@@ -2035,6 +2339,8 @@ int dlm_unlock(dlm_lockspace_t *lockspace,
if (error == -DLM_EUNLOCK || error == -DLM_ECANCEL)
error = 0;
+ if (error == -EBUSY && (flags & (DLM_LKF_CANCEL | DLM_LKF_FORCEUNLOCK)))
+ error = 0;
out_put:
dlm_put_lkb(lkb);
out:
@@ -2065,31 +2371,14 @@ int dlm_unlock(dlm_lockspace_t *lockspace,
* receive_lookup_reply send_lookup_reply
*/
-static int create_message(struct dlm_rsb *r, struct dlm_lkb *lkb,
- int to_nodeid, int mstype,
- struct dlm_message **ms_ret,
- struct dlm_mhandle **mh_ret)
+static int _create_message(struct dlm_ls *ls, int mb_len,
+ int to_nodeid, int mstype,
+ struct dlm_message **ms_ret,
+ struct dlm_mhandle **mh_ret)
{
struct dlm_message *ms;
struct dlm_mhandle *mh;
char *mb;
- int mb_len = sizeof(struct dlm_message);
-
- switch (mstype) {
- case DLM_MSG_REQUEST:
- case DLM_MSG_LOOKUP:
- case DLM_MSG_REMOVE:
- mb_len += r->res_length;
- break;
- case DLM_MSG_CONVERT:
- case DLM_MSG_UNLOCK:
- case DLM_MSG_REQUEST_REPLY:
- case DLM_MSG_CONVERT_REPLY:
- case DLM_MSG_GRANT:
- if (lkb && lkb->lkb_lvbptr)
- mb_len += r->res_ls->ls_lvblen;
- break;
- }
/* get_buffer gives us a message handle (mh) that we need to
pass into lowcomms_commit and a message buffer (mb) that we
@@ -2104,7 +2393,7 @@ static int create_message(struct dlm_rsb *r, struct dlm_lkb *lkb,
ms = (struct dlm_message *) mb;
ms->m_header.h_version = (DLM_HEADER_MAJOR | DLM_HEADER_MINOR);
- ms->m_header.h_lockspace = r->res_ls->ls_global_id;
+ ms->m_header.h_lockspace = ls->ls_global_id;
ms->m_header.h_nodeid = dlm_our_nodeid();
ms->m_header.h_length = mb_len;
ms->m_header.h_cmd = DLM_MSG;
@@ -2116,6 +2405,33 @@ static int create_message(struct dlm_rsb *r, struct dlm_lkb *lkb,
return 0;
}
+static int create_message(struct dlm_rsb *r, struct dlm_lkb *lkb,
+ int to_nodeid, int mstype,
+ struct dlm_message **ms_ret,
+ struct dlm_mhandle **mh_ret)
+{
+ int mb_len = sizeof(struct dlm_message);
+
+ switch (mstype) {
+ case DLM_MSG_REQUEST:
+ case DLM_MSG_LOOKUP:
+ case DLM_MSG_REMOVE:
+ mb_len += r->res_length;
+ break;
+ case DLM_MSG_CONVERT:
+ case DLM_MSG_UNLOCK:
+ case DLM_MSG_REQUEST_REPLY:
+ case DLM_MSG_CONVERT_REPLY:
+ case DLM_MSG_GRANT:
+ if (lkb && lkb->lkb_lvbptr)
+ mb_len += r->res_ls->ls_lvblen;
+ break;
+ }
+
+ return _create_message(r->res_ls, mb_len, to_nodeid, mstype,
+ ms_ret, mh_ret);
+}
+
/* further lowcomms enhancements or alternate implementations may make
the return value from this function useful at some point */
@@ -2176,7 +2492,9 @@ static int send_common(struct dlm_rsb *r, struct dlm_lkb *lkb, int mstype)
struct dlm_mhandle *mh;
int to_nodeid, error;
- add_to_waiters(lkb, mstype);
+ error = add_to_waiters(lkb, mstype);
+ if (error)
+ return error;
to_nodeid = r->res_nodeid;
@@ -2192,7 +2510,7 @@ static int send_common(struct dlm_rsb *r, struct dlm_lkb *lkb, int mstype)
return 0;
fail:
- remove_from_waiters(lkb);
+ remove_from_waiters(lkb, msg_reply_type(mstype));
return error;
}
@@ -2209,7 +2527,8 @@ static int send_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
/* down conversions go without a reply from the master */
if (!error && down_conversion(lkb)) {
- remove_from_waiters(lkb);
+ remove_from_waiters(lkb, DLM_MSG_CONVERT_REPLY);
+ r->res_ls->ls_stub_ms.m_type = DLM_MSG_CONVERT_REPLY;
r->res_ls->ls_stub_ms.m_result = 0;
r->res_ls->ls_stub_ms.m_flags = lkb->lkb_flags;
__receive_convert_reply(r, lkb, &r->res_ls->ls_stub_ms);
@@ -2280,7 +2599,9 @@ static int send_lookup(struct dlm_rsb *r, struct dlm_lkb *lkb)
struct dlm_mhandle *mh;
int to_nodeid, error;
- add_to_waiters(lkb, DLM_MSG_LOOKUP);
+ error = add_to_waiters(lkb, DLM_MSG_LOOKUP);
+ if (error)
+ return error;
to_nodeid = dlm_dir_nodeid(r);
@@ -2296,7 +2617,7 @@ static int send_lookup(struct dlm_rsb *r, struct dlm_lkb *lkb)
return 0;
fail:
- remove_from_waiters(lkb);
+ remove_from_waiters(lkb, DLM_MSG_LOOKUP_REPLY);
return error;
}
@@ -2656,6 +2977,8 @@ static void receive_grant(struct dlm_ls *ls, struct dlm_message *ms)
lock_rsb(r);
receive_flags_reply(lkb, ms);
+ if (is_altmode(lkb))
+ munge_altmode(lkb, ms);
grant_lock_pc(r, lkb, ms);
queue_cast(r, lkb, 0);
@@ -2736,11 +3059,16 @@ static void receive_remove(struct dlm_ls *ls, struct dlm_message *ms)
dlm_dir_remove_entry(ls, from_nodeid, ms->m_extra, len);
}
+static void receive_purge(struct dlm_ls *ls, struct dlm_message *ms)
+{
+ do_purge(ls, ms->m_nodeid, ms->m_pid);
+}
+
static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
{
struct dlm_lkb *lkb;
struct dlm_rsb *r;
- int error, mstype;
+ int error, mstype, result;
error = find_lkb(ls, ms->m_remid, &lkb);
if (error) {
@@ -2749,20 +3077,15 @@ static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
}
DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
- mstype = lkb->lkb_wait_type;
- error = remove_from_waiters(lkb);
- if (error) {
- log_error(ls, "receive_request_reply not on waiters");
- goto out;
- }
-
- /* this is the value returned from do_request() on the master */
- error = ms->m_result;
-
r = lkb->lkb_resource;
hold_rsb(r);
lock_rsb(r);
+ mstype = lkb->lkb_wait_type;
+ error = remove_from_waiters(lkb, DLM_MSG_REQUEST_REPLY);
+ if (error)
+ goto out;
+
/* Optimization: the dir node was also the master, so it took our
lookup as a request and sent request reply instead of lookup reply */
if (mstype == DLM_MSG_LOOKUP) {
@@ -2770,14 +3093,15 @@ static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
lkb->lkb_nodeid = r->res_nodeid;
}
- switch (error) {
+ /* this is the value returned from do_request() on the master */
+ result = ms->m_result;
+
+ switch (result) {
case -EAGAIN:
- /* request would block (be queued) on remote master;
- the unhold undoes the original ref from create_lkb()
- so it leads to the lkb being freed */
+ /* request would block (be queued) on remote master */
queue_cast(r, lkb, -EAGAIN);
confirm_master(r, -EAGAIN);
- unhold_lkb(lkb);
+ unhold_lkb(lkb); /* undoes create_lkb() */
break;
case -EINPROGRESS:
@@ -2785,41 +3109,64 @@ static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms)
/* request was queued or granted on remote master */
receive_flags_reply(lkb, ms);
lkb->lkb_remid = ms->m_lkid;
- if (error)
+ if (is_altmode(lkb))
+ munge_altmode(lkb, ms);
+ if (result)
add_lkb(r, lkb, DLM_LKSTS_WAITING);
else {
grant_lock_pc(r, lkb, ms);
queue_cast(r, lkb, 0);
}
- confirm_master(r, error);
+ confirm_master(r, result);
break;
case -EBADR:
case -ENOTBLK:
/* find_rsb failed to find rsb or rsb wasn't master */
+ log_debug(ls, "receive_request_reply %x %x master diff %d %d",
+ lkb->lkb_id, lkb->lkb_flags, r->res_nodeid, result);
r->res_nodeid = -1;
lkb->lkb_nodeid = -1;
- _request_lock(r, lkb);
+
+ if (is_overlap(lkb)) {
+ /* we'll ignore error in cancel/unlock reply */
+ queue_cast_overlap(r, lkb);
+ unhold_lkb(lkb); /* undoes create_lkb() */
+ } else
+ _request_lock(r, lkb);
break;
default:
- log_error(ls, "receive_request_reply error %d", error);
+ log_error(ls, "receive_request_reply %x error %d",
+ lkb->lkb_id, result);
}
+ if (is_overlap_unlock(lkb) && (result == 0 || result == -EINPROGRESS)) {
+ log_debug(ls, "receive_request_reply %x result %d unlock",
+ lkb->lkb_id, result);
+ lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK;
+ lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL;
+ send_unlock(r, lkb);
+ } else if (is_overlap_cancel(lkb) && (result == -EINPROGRESS)) {
+ log_debug(ls, "receive_request_reply %x cancel", lkb->lkb_id);
+ lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK;
+ lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL;
+ send_cancel(r, lkb);
+ } else {
+ lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL;
+ lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK;
+ }
+ out:
unlock_rsb(r);
put_rsb(r);
- out:
dlm_put_lkb(lkb);
}
static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
struct dlm_message *ms)
{
- int error = ms->m_result;
-
/* this is the value returned from do_convert() on the master */
-
- switch (error) {
+ switch (ms->m_result) {
case -EAGAIN:
/* convert would block (be queued) on remote master */
queue_cast(r, lkb, -EAGAIN);
@@ -2827,6 +3174,9 @@ static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
case -EINPROGRESS:
/* convert was queued on remote master */
+ receive_flags_reply(lkb, ms);
+ if (is_demoted(lkb))
+ munge_demoted(lkb, ms);
del_lkb(r, lkb);
add_lkb(r, lkb, DLM_LKSTS_CONVERT);
break;
@@ -2834,24 +3184,33 @@ static void __receive_convert_reply(struct dlm_rsb *r, struct dlm_lkb *lkb,
case 0:
/* convert was granted on remote master */
receive_flags_reply(lkb, ms);
+ if (is_demoted(lkb))
+ munge_demoted(lkb, ms);
grant_lock_pc(r, lkb, ms);
queue_cast(r, lkb, 0);
break;
default:
- log_error(r->res_ls, "receive_convert_reply error %d", error);
+ log_error(r->res_ls, "receive_convert_reply %x error %d",
+ lkb->lkb_id, ms->m_result);
}
}
static void _receive_convert_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
{
struct dlm_rsb *r = lkb->lkb_resource;
+ int error;
hold_rsb(r);
lock_rsb(r);
- __receive_convert_reply(r, lkb, ms);
+ /* stub reply can happen with waiters_mutex held */
+ error = remove_from_waiters_ms(lkb, ms);
+ if (error)
+ goto out;
+ __receive_convert_reply(r, lkb, ms);
+ out:
unlock_rsb(r);
put_rsb(r);
}
@@ -2868,37 +3227,38 @@ static void receive_convert_reply(struct dlm_ls *ls, struct dlm_message *ms)
}
DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
- error = remove_from_waiters(lkb);
- if (error) {
- log_error(ls, "receive_convert_reply not on waiters");
- goto out;
- }
-
_receive_convert_reply(lkb, ms);
- out:
dlm_put_lkb(lkb);
}
static void _receive_unlock_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
{
struct dlm_rsb *r = lkb->lkb_resource;
- int error = ms->m_result;
+ int error;
hold_rsb(r);
lock_rsb(r);
+ /* stub reply can happen with waiters_mutex held */
+ error = remove_from_waiters_ms(lkb, ms);
+ if (error)
+ goto out;
+
/* this is the value returned from do_unlock() on the master */
- switch (error) {
+ switch (ms->m_result) {
case -DLM_EUNLOCK:
receive_flags_reply(lkb, ms);
remove_lock_pc(r, lkb);
queue_cast(r, lkb, -DLM_EUNLOCK);
break;
+ case -ENOENT:
+ break;
default:
- log_error(r->res_ls, "receive_unlock_reply error %d", error);
+ log_error(r->res_ls, "receive_unlock_reply %x error %d",
+ lkb->lkb_id, ms->m_result);
}
-
+ out:
unlock_rsb(r);
put_rsb(r);
}
@@ -2915,37 +3275,39 @@ static void receive_unlock_reply(struct dlm_ls *ls, struct dlm_message *ms)
}
DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
- error = remove_from_waiters(lkb);
- if (error) {
- log_error(ls, "receive_unlock_reply not on waiters");
- goto out;
- }
-
_receive_unlock_reply(lkb, ms);
- out:
dlm_put_lkb(lkb);
}
static void _receive_cancel_reply(struct dlm_lkb *lkb, struct dlm_message *ms)
{
struct dlm_rsb *r = lkb->lkb_resource;
- int error = ms->m_result;
+ int error;
hold_rsb(r);
lock_rsb(r);
+ /* stub reply can happen with waiters_mutex held */
+ error = remove_from_waiters_ms(lkb, ms);
+ if (error)
+ goto out;
+
/* this is the value returned from do_cancel() on the master */
- switch (error) {
+ switch (ms->m_result) {
case -DLM_ECANCEL:
receive_flags_reply(lkb, ms);
revert_lock_pc(r, lkb);
- queue_cast(r, lkb, -DLM_ECANCEL);
+ if (ms->m_result)
+ queue_cast(r, lkb, -DLM_ECANCEL);
+ break;
+ case 0:
break;
default:
- log_error(r->res_ls, "receive_cancel_reply error %d", error);
+ log_error(r->res_ls, "receive_cancel_reply %x error %d",
+ lkb->lkb_id, ms->m_result);
}
-
+ out:
unlock_rsb(r);
put_rsb(r);
}
@@ -2962,14 +3324,7 @@ static void receive_cancel_reply(struct dlm_ls *ls, struct dlm_message *ms)
}
DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
- error = remove_from_waiters(lkb);
- if (error) {
- log_error(ls, "receive_cancel_reply not on waiters");
- goto out;
- }
-
_receive_cancel_reply(lkb, ms);
- out:
dlm_put_lkb(lkb);
}
@@ -2985,20 +3340,17 @@ static void receive_lookup_reply(struct dlm_ls *ls, struct dlm_message *ms)
return;
}
- error = remove_from_waiters(lkb);
- if (error) {
- log_error(ls, "receive_lookup_reply not on waiters");
- goto out;
- }
-
- /* this is the value returned by dlm_dir_lookup on dir node
+ /* ms->m_result is the value returned by dlm_dir_lookup on dir node
FIXME: will a non-zero error ever be returned? */
- error = ms->m_result;
r = lkb->lkb_resource;
hold_rsb(r);
lock_rsb(r);
+ error = remove_from_waiters(lkb, DLM_MSG_LOOKUP_REPLY);
+ if (error)
+ goto out;
+
ret_nodeid = ms->m_nodeid;
if (ret_nodeid == dlm_our_nodeid()) {
r->res_nodeid = 0;
@@ -3009,14 +3361,22 @@ static void receive_lookup_reply(struct dlm_ls *ls, struct dlm_message *ms)
r->res_nodeid = ret_nodeid;
}
+ if (is_overlap(lkb)) {
+ log_debug(ls, "receive_lookup_reply %x unlock %x",
+ lkb->lkb_id, lkb->lkb_flags);
+ queue_cast_overlap(r, lkb);
+ unhold_lkb(lkb); /* undoes create_lkb() */
+ goto out_list;
+ }
+
_request_lock(r, lkb);
+ out_list:
if (!ret_nodeid)
process_lookup_list(r);
-
+ out:
unlock_rsb(r);
put_rsb(r);
- out:
dlm_put_lkb(lkb);
}
@@ -3133,6 +3493,12 @@ int dlm_receive_message(struct dlm_header *hd, int nodeid, int recovery)
receive_lookup_reply(ls, ms);
break;
+ /* other messages */
+
+ case DLM_MSG_PURGE:
+ receive_purge(ls, ms);
+ break;
+
default:
log_error(ls, "unknown message type %d", ms->m_type);
}
@@ -3153,9 +3519,9 @@ static void recover_convert_waiter(struct dlm_ls *ls, struct dlm_lkb *lkb)
{
if (middle_conversion(lkb)) {
hold_lkb(lkb);
+ ls->ls_stub_ms.m_type = DLM_MSG_CONVERT_REPLY;
ls->ls_stub_ms.m_result = -EINPROGRESS;
ls->ls_stub_ms.m_flags = lkb->lkb_flags;
- _remove_from_waiters(lkb);
_receive_convert_reply(lkb, &ls->ls_stub_ms);
/* Same special case as in receive_rcom_lock_args() */
@@ -3227,18 +3593,18 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls)
case DLM_MSG_UNLOCK:
hold_lkb(lkb);
+ ls->ls_stub_ms.m_type = DLM_MSG_UNLOCK_REPLY;
ls->ls_stub_ms.m_result = -DLM_EUNLOCK;
ls->ls_stub_ms.m_flags = lkb->lkb_flags;
- _remove_from_waiters(lkb);
_receive_unlock_reply(lkb, &ls->ls_stub_ms);
dlm_put_lkb(lkb);
break;
case DLM_MSG_CANCEL:
hold_lkb(lkb);
+ ls->ls_stub_ms.m_type = DLM_MSG_CANCEL_REPLY;
ls->ls_stub_ms.m_result = -DLM_ECANCEL;
ls->ls_stub_ms.m_flags = lkb->lkb_flags;
- _remove_from_waiters(lkb);
_receive_cancel_reply(lkb, &ls->ls_stub_ms);
dlm_put_lkb(lkb);
break;
@@ -3252,37 +3618,47 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls)
mutex_unlock(&ls->ls_waiters_mutex);
}
-static int remove_resend_waiter(struct dlm_ls *ls, struct dlm_lkb **lkb_ret)
+static struct dlm_lkb *find_resend_waiter(struct dlm_ls *ls)
{
struct dlm_lkb *lkb;
- int rv = 0;
+ int found = 0;
mutex_lock(&ls->ls_waiters_mutex);
list_for_each_entry(lkb, &ls->ls_waiters, lkb_wait_reply) {
if (lkb->lkb_flags & DLM_IFL_RESEND) {
- rv = lkb->lkb_wait_type;
- _remove_from_waiters(lkb);
- lkb->lkb_flags &= ~DLM_IFL_RESEND;
+ hold_lkb(lkb);
+ found = 1;
break;
}
}
mutex_unlock(&ls->ls_waiters_mutex);
- if (!rv)
+ if (!found)
lkb = NULL;
- *lkb_ret = lkb;
- return rv;
+ return lkb;
}
/* Deal with lookups and lkb's marked RESEND from _pre. We may now be the
master or dir-node for r. Processing the lkb may result in it being placed
back on waiters. */
+/* We do this after normal locking has been enabled and any saved messages
+ (in requestqueue) have been processed. We should be confident that at
+ this point we won't get or process a reply to any of these waiting
+ operations. But, new ops may be coming in on the rsbs/locks here from
+ userspace or remotely. */
+
+/* there may have been an overlap unlock/cancel prior to recovery or after
+ recovery. if before, the lkb may still have a pos wait_count; if after, the
+ overlap flag would just have been set and nothing new sent. we can be
+ confident here than any replies to either the initial op or overlap ops
+ prior to recovery have been received. */
+
int dlm_recover_waiters_post(struct dlm_ls *ls)
{
struct dlm_lkb *lkb;
struct dlm_rsb *r;
- int error = 0, mstype;
+ int error = 0, mstype, err, oc, ou;
while (1) {
if (dlm_locking_stopped(ls)) {
@@ -3291,48 +3667,78 @@ int dlm_recover_waiters_post(struct dlm_ls *ls)
break;
}
- mstype = remove_resend_waiter(ls, &lkb);
- if (!mstype)
+ lkb = find_resend_waiter(ls);
+ if (!lkb)
break;
r = lkb->lkb_resource;
+ hold_rsb(r);
+ lock_rsb(r);
+
+ mstype = lkb->lkb_wait_type;
+ oc = is_overlap_cancel(lkb);
+ ou = is_overlap_unlock(lkb);
+ err = 0;
log_debug(ls, "recover_waiters_post %x type %d flags %x %s",
lkb->lkb_id, mstype, lkb->lkb_flags, r->res_name);
- switch (mstype) {
-
- case DLM_MSG_LOOKUP:
- hold_rsb(r);
- lock_rsb(r);
- _request_lock(r, lkb);
- if (is_master(r))
- confirm_master(r, 0);
- unlock_rsb(r);
- put_rsb(r);
- break;
-
- case DLM_MSG_REQUEST:
- hold_rsb(r);
- lock_rsb(r);
- _request_lock(r, lkb);
- if (is_master(r))
- confirm_master(r, 0);
- unlock_rsb(r);
- put_rsb(r);
- break;
-
- case DLM_MSG_CONVERT:
- hold_rsb(r);
- lock_rsb(r);
- _convert_lock(r, lkb);
- unlock_rsb(r);
- put_rsb(r);
- break;
-
- default:
- log_error(ls, "recover_waiters_post type %d", mstype);
+ /* At this point we assume that we won't get a reply to any
+ previous op or overlap op on this lock. First, do a big
+ remove_from_waiters() for all previous ops. */
+
+ lkb->lkb_flags &= ~DLM_IFL_RESEND;
+ lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK;
+ lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL;
+ lkb->lkb_wait_type = 0;
+ lkb->lkb_wait_count = 0;
+ mutex_lock(&ls->ls_waiters_mutex);
+ list_del_init(&lkb->lkb_wait_reply);
+ mutex_unlock(&ls->ls_waiters_mutex);
+ unhold_lkb(lkb); /* for waiters list */
+
+ if (oc || ou) {
+ /* do an unlock or cancel instead of resending */
+ switch (mstype) {
+ case DLM_MSG_LOOKUP:
+ case DLM_MSG_REQUEST:
+ queue_cast(r, lkb, ou ? -DLM_EUNLOCK :
+ -DLM_ECANCEL);
+ unhold_lkb(lkb); /* undoes create_lkb() */
+ break;
+ case DLM_MSG_CONVERT:
+ if (oc) {
+ queue_cast(r, lkb, -DLM_ECANCEL);
+ } else {
+ lkb->lkb_exflags |= DLM_LKF_FORCEUNLOCK;
+ _unlock_lock(r, lkb);
+ }
+ break;
+ default:
+ err = 1;
+ }
+ } else {
+ switch (mstype) {
+ case DLM_MSG_LOOKUP:
+ case DLM_MSG_REQUEST:
+ _request_lock(r, lkb);
+ if (is_master(r))
+ confirm_master(r, 0);
+ break;
+ case DLM_MSG_CONVERT:
+ _convert_lock(r, lkb);
+ break;
+ default:
+ err = 1;
+ }
}
+
+ if (err)
+ log_error(ls, "recover_waiters_post %x %d %x %d %d",
+ lkb->lkb_id, mstype, lkb->lkb_flags, oc, ou);
+ unlock_rsb(r);
+ put_rsb(r);
+ dlm_put_lkb(lkb);
}
return error;
@@ -3684,7 +4090,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
/* add this new lkb to the per-process list of locks */
spin_lock(&ua->proc->locks_spin);
- kref_get(&lkb->lkb_ref);
+ hold_lkb(lkb);
list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks);
spin_unlock(&ua->proc->locks_spin);
out:
@@ -3774,6 +4180,9 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
if (error == -DLM_EUNLOCK)
error = 0;
+ /* from validate_unlock_args() */
+ if (error == -EBUSY && (flags & DLM_LKF_FORCEUNLOCK))
+ error = 0;
if (error)
goto out_put;
@@ -3786,6 +4195,7 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
dlm_put_lkb(lkb);
out:
unlock_recovery(ls);
+ kfree(ua_tmp);
return error;
}
@@ -3815,33 +4225,37 @@ int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
if (error == -DLM_ECANCEL)
error = 0;
- if (error)
- goto out_put;
-
- /* this lkb was removed from the WAITING queue */
- if (lkb->lkb_grmode == DLM_LOCK_IV) {
- spin_lock(&ua->proc->locks_spin);
- list_move(&lkb->lkb_ownqueue, &ua->proc->unlocking);
- spin_unlock(&ua->proc->locks_spin);
- }
+ /* from validate_unlock_args() */
+ if (error == -EBUSY)
+ error = 0;
out_put:
dlm_put_lkb(lkb);
out:
unlock_recovery(ls);
+ kfree(ua_tmp);
return error;
}
+/* lkb's that are removed from the waiters list by revert are just left on the
+ orphans list with the granted orphan locks, to be freed by purge */
+
static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
{
struct dlm_user_args *ua = (struct dlm_user_args *)lkb->lkb_astparam;
+ struct dlm_args args;
+ int error;
- if (ua->lksb.sb_lvbptr)
- kfree(ua->lksb.sb_lvbptr);
- kfree(ua);
- lkb->lkb_astparam = (long)NULL;
+ hold_lkb(lkb);
+ mutex_lock(&ls->ls_orphans_mutex);
+ list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans);
+ mutex_unlock(&ls->ls_orphans_mutex);
- /* TODO: propogate to master if needed */
- return 0;
+ set_unlock_args(0, ua, &args);
+
+ error = cancel_lock(ls, lkb, &args);
+ if (error == -DLM_ECANCEL)
+ error = 0;
+ return error;
}
/* The force flag allows the unlock to go ahead even if the lkb isn't granted.
@@ -3853,10 +4267,6 @@ static int unlock_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
struct dlm_args args;
int error;
- /* FIXME: we need to handle the case where the lkb is in limbo
- while the rsb is being looked up, currently we assert in
- _unlock_lock/is_remote because rsb nodeid is -1. */
-
set_unlock_args(DLM_LKF_FORCEUNLOCK, ua, &args);
error = unlock_lock(ls, lkb, &args);
@@ -3865,6 +4275,31 @@ static int unlock_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
return error;
}
+/* We have to release clear_proc_locks mutex before calling unlock_proc_lock()
+ (which does lock_rsb) due to deadlock with receiving a message that does
+ lock_rsb followed by dlm_user_add_ast() */
+
+static struct dlm_lkb *del_proc_lock(struct dlm_ls *ls,
+ struct dlm_user_proc *proc)
+{
+ struct dlm_lkb *lkb = NULL;
+
+ mutex_lock(&ls->ls_clear_proc_locks);
+ if (list_empty(&proc->locks))
+ goto out;
+
+ lkb = list_entry(proc->locks.next, struct dlm_lkb, lkb_ownqueue);
+ list_del_init(&lkb->lkb_ownqueue);
+
+ if (lkb->lkb_exflags & DLM_LKF_PERSISTENT)
+ lkb->lkb_flags |= DLM_IFL_ORPHAN;
+ else
+ lkb->lkb_flags |= DLM_IFL_DEAD;
+ out:
+ mutex_unlock(&ls->ls_clear_proc_locks);
+ return lkb;
+}
+
/* The ls_clear_proc_locks mutex protects against dlm_user_add_asts() which
1) references lkb->ua which we free here and 2) adds lkbs to proc->asts,
which we clear here. */
@@ -3880,18 +4315,15 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
struct dlm_lkb *lkb, *safe;
lock_recovery(ls);
- mutex_lock(&ls->ls_clear_proc_locks);
- list_for_each_entry_safe(lkb, safe, &proc->locks, lkb_ownqueue) {
- list_del_init(&lkb->lkb_ownqueue);
-
- if (lkb->lkb_exflags & DLM_LKF_PERSISTENT) {
- lkb->lkb_flags |= DLM_IFL_ORPHAN;
+ while (1) {
+ lkb = del_proc_lock(ls, proc);
+ if (!lkb)
+ break;
+ if (lkb->lkb_exflags & DLM_LKF_PERSISTENT)
orphan_proc_lock(ls, lkb);
- } else {
- lkb->lkb_flags |= DLM_IFL_DEAD;
+ else
unlock_proc_lock(ls, lkb);
- }
/* this removes the reference for the proc->locks list
added by dlm_user_request, it may result in the lkb
@@ -3900,6 +4332,8 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
dlm_put_lkb(lkb);
}
+ mutex_lock(&ls->ls_clear_proc_locks);
+
/* in-progress unlocks */
list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
list_del_init(&lkb->lkb_ownqueue);
@@ -3916,3 +4350,92 @@ void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
unlock_recovery(ls);
}
+static void purge_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
+{
+ struct dlm_lkb *lkb, *safe;
+
+ while (1) {
+ lkb = NULL;
+ spin_lock(&proc->locks_spin);
+ if (!list_empty(&proc->locks)) {
+ lkb = list_entry(proc->locks.next, struct dlm_lkb,
+ lkb_ownqueue);
+ list_del_init(&lkb->lkb_ownqueue);
+ }
+ spin_unlock(&proc->locks_spin);
+
+ if (!lkb)
+ break;
+
+ lkb->lkb_flags |= DLM_IFL_DEAD;
+ unlock_proc_lock(ls, lkb);
+ dlm_put_lkb(lkb); /* ref from proc->locks list */
+ }
+
+ spin_lock(&proc->locks_spin);
+ list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
+ list_del_init(&lkb->lkb_ownqueue);
+ lkb->lkb_flags |= DLM_IFL_DEAD;
+ dlm_put_lkb(lkb);
+ }
+ spin_unlock(&proc->locks_spin);
+
+ spin_lock(&proc->asts_spin);
+ list_for_each_entry_safe(lkb, safe, &proc->asts, lkb_astqueue) {
+ list_del(&lkb->lkb_astqueue);
+ dlm_put_lkb(lkb);
+ }
+ spin_unlock(&proc->asts_spin);
+}
+
+/* pid of 0 means purge all orphans */
+
+static void do_purge(struct dlm_ls *ls, int nodeid, int pid)
+{
+ struct dlm_lkb *lkb, *safe;
+
+ mutex_lock(&ls->ls_orphans_mutex);
+ list_for_each_entry_safe(lkb, safe, &ls->ls_orphans, lkb_ownqueue) {
+ if (pid && lkb->lkb_ownpid != pid)
+ continue;
+ unlock_proc_lock(ls, lkb);
+ list_del_init(&lkb->lkb_ownqueue);
+ dlm_put_lkb(lkb);
+ }
+ mutex_unlock(&ls->ls_orphans_mutex);
+}
+
+static int send_purge(struct dlm_ls *ls, int nodeid, int pid)
+{
+ struct dlm_message *ms;
+ struct dlm_mhandle *mh;
+ int error;
+
+ error = _create_message(ls, sizeof(struct dlm_message), nodeid,
+ DLM_MSG_PURGE, &ms, &mh);
+ if (error)
+ return error;
+ ms->m_nodeid = nodeid;
+ ms->m_pid = pid;
+
+ return send_message(mh, ms);
+}
+
+int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc,
+ int nodeid, int pid)
+{
+ int error = 0;
+
+ if (nodeid != dlm_our_nodeid()) {
+ error = send_purge(ls, nodeid, pid);
+ } else {
+ lock_recovery(ls);
+ if (pid == current->pid)
+ purge_proc_locks(ls, proc);
+ else
+ do_purge(ls, nodeid, pid);
+ unlock_recovery(ls);
+ }
+ return error;
+}
+
diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h
index 0843a30..64fc4ec 100644
--- a/fs/dlm/lock.h
+++ b/fs/dlm/lock.h
@@ -41,6 +41,8 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
uint32_t flags, uint32_t lkid, char *lvb_in);
int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
uint32_t flags, uint32_t lkid);
+int dlm_user_purge(struct dlm_ls *ls, struct dlm_user_proc *proc,
+ int nodeid, int pid);
void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc);
static inline int is_master(struct dlm_rsb *r)
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index 8e6ad76..a677b2a 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -2,7 +2,7 @@
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
-** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -459,6 +459,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
INIT_LIST_HEAD(&ls->ls_waiters);
mutex_init(&ls->ls_waiters_mutex);
+ INIT_LIST_HEAD(&ls->ls_orphans);
+ mutex_init(&ls->ls_orphans_mutex);
INIT_LIST_HEAD(&ls->ls_nodes);
INIT_LIST_HEAD(&ls->ls_nodes_gone);
diff --git a/fs/dlm/lowcomms-sctp.c b/fs/dlm/lowcomms-sctp.c
deleted file mode 100644
index dc83a9d..0000000
--- a/fs/dlm/lowcomms-sctp.c
+++ /dev/null
@@ -1,1210 +0,0 @@
-/******************************************************************************
-*******************************************************************************
-**
-** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
-** Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
-**
-** This copyrighted material is made available to anyone wishing to use,
-** modify, copy, or redistribute it subject to the terms and conditions
-** of the GNU General Public License v.2.
-**
-*******************************************************************************
-******************************************************************************/
-
-/*
- * lowcomms.c
- *
- * This is the "low-level" comms layer.
- *
- * It is responsible for sending/receiving messages
- * from other nodes in the cluster.
- *
- * Cluster nodes are referred to by their nodeids. nodeids are
- * simply 32 bit numbers to the locking module - if they need to
- * be expanded for the cluster infrastructure then that is it's
- * responsibility. It is this layer's
- * responsibility to resolve these into IP address or
- * whatever it needs for inter-node communication.
- *
- * The comms level is two kernel threads that deal mainly with
- * the receiving of messages from other nodes and passing them
- * up to the mid-level comms layer (which understands the
- * message format) for execution by the locking core, and
- * a send thread which does all the setting up of connections
- * to remote nodes and the sending of data. Threads are not allowed
- * to send their own data because it may cause them to wait in times
- * of high load. Also, this way, the sending thread can collect together
- * messages bound for one node and send them in one block.
- *
- * I don't see any problem with the recv thread executing the locking
- * code on behalf of remote processes as the locking code is
- * short, efficient and never (well, hardly ever) waits.
- *
- */
-
-#include <asm/ioctls.h>
-#include <net/sock.h>
-#include <net/tcp.h>
-#include <net/sctp/user.h>
-#include <linux/pagemap.h>
-#include <linux/socket.h>
-#include <linux/idr.h>
-
-#include "dlm_internal.h"
-#include "lowcomms.h"
-#include "config.h"
-#include "midcomms.h"
-
-static struct sockaddr_storage *dlm_local_addr[DLM_MAX_ADDR_COUNT];
-static int dlm_local_count;
-static int dlm_local_nodeid;
-
-/* One of these per connected node */
-
-#define NI_INIT_PENDING 1
-#define NI_WRITE_PENDING 2
-
-struct nodeinfo {
- spinlock_t lock;
- sctp_assoc_t assoc_id;
- unsigned long flags;
- struct list_head write_list; /* nodes with pending writes */
- struct list_head writequeue; /* outgoing writequeue_entries */
- spinlock_t writequeue_lock;
- int nodeid;
- struct work_struct swork; /* Send workqueue */
- struct work_struct lwork; /* Locking workqueue */
-};
-
-static DEFINE_IDR(nodeinfo_idr);
-static DECLARE_RWSEM(nodeinfo_lock);
-static int max_nodeid;
-
-struct cbuf {
- unsigned int base;
- unsigned int len;
- unsigned int mask;
-};
-
-/* Just the one of these, now. But this struct keeps
- the connection-specific variables together */
-
-#define CF_READ_PENDING 1
-
-struct connection {
- struct socket *sock;
- unsigned long flags;
- struct page *rx_page;
- atomic_t waiting_requests;
- struct cbuf cb;
- int eagain_flag;
- struct work_struct work; /* Send workqueue */
-};
-
-/* An entry waiting to be sent */
-
-struct writequeue_entry {
- struct list_head list;
- struct page *page;
- int offset;
- int len;
- int end;
- int users;
- struct nodeinfo *ni;
-};
-
-static void cbuf_add(struct cbuf *cb, int n)
-{
- cb->len += n;
-}
-
-static int cbuf_data(struct cbuf *cb)
-{
- return ((cb->base + cb->len) & cb->mask);
-}
-
-static void cbuf_init(struct cbuf *cb, int size)
-{
- cb->base = cb->len = 0;
- cb->mask = size-1;
-}
-
-static void cbuf_eat(struct cbuf *cb, int n)
-{
- cb->len -= n;
- cb->base += n;
- cb->base &= cb->mask;
-}
-
-/* List of nodes which have writes pending */
-static LIST_HEAD(write_nodes);
-static DEFINE_SPINLOCK(write_nodes_lock);
-
-
-/* Maximum number of incoming messages to process before
- * doing a schedule()
- */
-#define MAX_RX_MSG_COUNT 25
-
-/* Work queues */
-static struct workqueue_struct *recv_workqueue;
-static struct workqueue_struct *send_workqueue;
-static struct workqueue_struct *lock_workqueue;
-
-/* The SCTP connection */
-static struct connection sctp_con;
-
-static void process_send_sockets(struct work_struct *work);
-static void process_recv_sockets(struct work_struct *work);
-static void process_lock_request(struct work_struct *work);
-
-static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr)
-{
- struct sockaddr_storage addr;
- int error;
-
- if (!dlm_local_count)
- return -1;
-
- error = dlm_nodeid_to_addr(nodeid, &addr);
- if (error)
- return error;
-
- if (dlm_local_addr[0]->ss_family == AF_INET) {
- struct sockaddr_in *in4 = (struct sockaddr_in *) &addr;
- struct sockaddr_in *ret4 = (struct sockaddr_in *) retaddr;
- ret4->sin_addr.s_addr = in4->sin_addr.s_addr;
- } else {
- struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &addr;
- struct sockaddr_in6 *ret6 = (struct sockaddr_in6 *) retaddr;
- memcpy(&ret6->sin6_addr, &in6->sin6_addr,
- sizeof(in6->sin6_addr));
- }
-
- return 0;
-}
-
-/* If alloc is 0 here we will not attempt to allocate a new
- nodeinfo struct */
-static struct nodeinfo *nodeid2nodeinfo(int nodeid, gfp_t alloc)
-{
- struct nodeinfo *ni;
- int r;
- int n;
-
- down_read(&nodeinfo_lock);
- ni = idr_find(&nodeinfo_idr, nodeid);
- up_read(&nodeinfo_lock);
-
- if (ni || !alloc)
- return ni;
-
- down_write(&nodeinfo_lock);
-
- ni = idr_find(&nodeinfo_idr, nodeid);
- if (ni)
- goto out_up;
-
- r = idr_pre_get(&nodeinfo_idr, alloc);
- if (!r)
- goto out_up;
-
- ni = kmalloc(sizeof(struct nodeinfo), alloc);
- if (!ni)
- goto out_up;
-
- r = idr_get_new_above(&nodeinfo_idr, ni, nodeid, &n);
- if (r) {
- kfree(ni);
- ni = NULL;
- goto out_up;
- }
- if (n != nodeid) {
- idr_remove(&nodeinfo_idr, n);
- kfree(ni);
- ni = NULL;
- goto out_up;
- }
- memset(ni, 0, sizeof(struct nodeinfo));
- spin_lock_init(&ni->lock);
- INIT_LIST_HEAD(&ni->writequeue);
- spin_lock_init(&ni->writequeue_lock);
- INIT_WORK(&ni->lwork, process_lock_request);
- INIT_WORK(&ni->swork, process_send_sockets);
- ni->nodeid = nodeid;
-
- if (nodeid > max_nodeid)
- max_nodeid = nodeid;
-out_up:
- up_write(&nodeinfo_lock);
-
- return ni;
-}
-
-/* Don't call this too often... */
-static struct nodeinfo *assoc2nodeinfo(sctp_assoc_t assoc)
-{
- int i;
- struct nodeinfo *ni;
-
- for (i=1; i<=max_nodeid; i++) {
- ni = nodeid2nodeinfo(i, 0);
- if (ni && ni->assoc_id == assoc)
- return ni;
- }
- return NULL;
-}
-
-/* Data or notification available on socket */
-static void lowcomms_data_ready(struct sock *sk, int count_unused)
-{
- if (test_and_set_bit(CF_READ_PENDING, &sctp_con.flags))
- queue_work(recv_workqueue, &sctp_con.work);
-}
-
-
-/* Add the port number to an IP6 or 4 sockaddr and return the address length.
- Also padd out the struct with zeros to make comparisons meaningful */
-
-static void make_sockaddr(struct sockaddr_storage *saddr, uint16_t port,
- int *addr_len)
-{
- struct sockaddr_in *local4_addr;
- struct sockaddr_in6 *local6_addr;
-
- if (!dlm_local_count)
- return;
-
- if (!port) {
- if (dlm_local_addr[0]->ss_family == AF_INET) {
- local4_addr = (struct sockaddr_in *)dlm_local_addr[0];
- port = be16_to_cpu(local4_addr->sin_port);
- } else {
- local6_addr = (struct sockaddr_in6 *)dlm_local_addr[0];
- port = be16_to_cpu(local6_addr->sin6_port);
- }
- }
-
- saddr->ss_family = dlm_local_addr[0]->ss_family;
- if (dlm_local_addr[0]->ss_family == AF_INET) {
- struct sockaddr_in *in4_addr = (struct sockaddr_in *)saddr;
- in4_addr->sin_port = cpu_to_be16(port);
- memset(&in4_addr->sin_zero, 0, sizeof(in4_addr->sin_zero));
- memset(in4_addr+1, 0, sizeof(struct sockaddr_storage) -
- sizeof(struct sockaddr_in));
- *addr_len = sizeof(struct sockaddr_in);
- } else {
- struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)saddr;
- in6_addr->sin6_port = cpu_to_be16(port);
- memset(in6_addr+1, 0, sizeof(struct sockaddr_storage) -
- sizeof(struct sockaddr_in6));
- *addr_len = sizeof(struct sockaddr_in6);
- }
-}
-
-/* Close the connection and tidy up */
-static void close_connection(void)
-{
- if (sctp_con.sock) {
- sock_release(sctp_con.sock);
- sctp_con.sock = NULL;
- }
-
- if (sctp_con.rx_page) {
- __free_page(sctp_con.rx_page);
- sctp_con.rx_page = NULL;
- }
-}
-
-/* We only send shutdown messages to nodes that are not part of the cluster */
-static void send_shutdown(sctp_assoc_t associd)
-{
- static char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
- struct msghdr outmessage;
- struct cmsghdr *cmsg;
- struct sctp_sndrcvinfo *sinfo;
- int ret;
-
- outmessage.msg_name = NULL;
- outmessage.msg_namelen = 0;
- outmessage.msg_control = outcmsg;
- outmessage.msg_controllen = sizeof(outcmsg);
- outmessage.msg_flags = MSG_EOR;
-
- cmsg = CMSG_FIRSTHDR(&outmessage);
- cmsg->cmsg_level = IPPROTO_SCTP;
- cmsg->cmsg_type = SCTP_SNDRCV;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
- outmessage.msg_controllen = cmsg->cmsg_len;
- sinfo = CMSG_DATA(cmsg);
- memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
-
- sinfo->sinfo_flags |= MSG_EOF;
- sinfo->sinfo_assoc_id = associd;
-
- ret = kernel_sendmsg(sctp_con.sock, &outmessage, NULL, 0, 0);
-
- if (ret != 0)
- log_print("send EOF to node failed: %d", ret);
-}
-
-
-/* INIT failed but we don't know which node...
- restart INIT on all pending nodes */
-static void init_failed(void)
-{
- int i;
- struct nodeinfo *ni;
-
- for (i=1; i<=max_nodeid; i++) {
- ni = nodeid2nodeinfo(i, 0);
- if (!ni)
- continue;
-
- if (test_and_clear_bit(NI_INIT_PENDING, &ni->flags)) {
- ni->assoc_id = 0;
- if (!test_and_set_bit(NI_WRITE_PENDING, &ni->flags)) {
- spin_lock_bh(&write_nodes_lock);
- list_add_tail(&ni->write_list, &write_nodes);
- spin_unlock_bh(&write_nodes_lock);
- queue_work(send_workqueue, &ni->swork);
- }
- }
- }
-}
-
-/* Something happened to an association */
-static void process_sctp_notification(struct msghdr *msg, char *buf)
-{
- union sctp_notification *sn = (union sctp_notification *)buf;
-
- if (sn->sn_header.sn_type == SCTP_ASSOC_CHANGE) {
- switch (sn->sn_assoc_change.sac_state) {
-
- case SCTP_COMM_UP:
- case SCTP_RESTART:
- {
- /* Check that the new node is in the lockspace */
- struct sctp_prim prim;
- mm_segment_t fs;
- int nodeid;
- int prim_len, ret;
- int addr_len;
- struct nodeinfo *ni;
-
- /* This seems to happen when we received a connection
- * too early... or something... anyway, it happens but
- * we always seem to get a real message too, see
- * receive_from_sock */
-
- if ((int)sn->sn_assoc_change.sac_assoc_id <= 0) {
- log_print("COMM_UP for invalid assoc ID %d",
- (int)sn->sn_assoc_change.sac_assoc_id);
- init_failed();
- return;
- }
- memset(&prim, 0, sizeof(struct sctp_prim));
- prim_len = sizeof(struct sctp_prim);
- prim.ssp_assoc_id = sn->sn_assoc_change.sac_assoc_id;
-
- fs = get_fs();
- set_fs(get_ds());
- ret = sctp_con.sock->ops->getsockopt(sctp_con.sock,
- IPPROTO_SCTP,
- SCTP_PRIMARY_ADDR,
- (char*)&prim,
- &prim_len);
- set_fs(fs);
- if (ret < 0) {
- struct nodeinfo *ni;
-
- log_print("getsockopt/sctp_primary_addr on "
- "new assoc %d failed : %d",
- (int)sn->sn_assoc_change.sac_assoc_id,
- ret);
-
- /* Retry INIT later */
- ni = assoc2nodeinfo(sn->sn_assoc_change.sac_assoc_id);
- if (ni)
- clear_bit(NI_INIT_PENDING, &ni->flags);
- return;
- }
- make_sockaddr(&prim.ssp_addr, 0, &addr_len);
- if (dlm_addr_to_nodeid(&prim.ssp_addr, &nodeid)) {
- log_print("reject connect from unknown addr");
- send_shutdown(prim.ssp_assoc_id);
- return;
- }
-
- ni = nodeid2nodeinfo(nodeid, GFP_KERNEL);
- if (!ni)
- return;
-
- /* Save the assoc ID */
- ni->assoc_id = sn->sn_assoc_change.sac_assoc_id;
-
- log_print("got new/restarted association %d nodeid %d",
- (int)sn->sn_assoc_change.sac_assoc_id, nodeid);
-
- /* Send any pending writes */
- clear_bit(NI_INIT_PENDING, &ni->flags);
- if (!test_and_set_bit(NI_WRITE_PENDING, &ni->flags)) {
- spin_lock_bh(&write_nodes_lock);
- list_add_tail(&ni->write_list, &write_nodes);
- spin_unlock_bh(&write_nodes_lock);
- queue_work(send_workqueue, &ni->swork);
- }
- }
- break;
-
- case SCTP_COMM_LOST:
- case SCTP_SHUTDOWN_COMP:
- {
- struct nodeinfo *ni;
-
- ni = assoc2nodeinfo(sn->sn_assoc_change.sac_assoc_id);
- if (ni) {
- spin_lock(&ni->lock);
- ni->assoc_id = 0;
- spin_unlock(&ni->lock);
- }
- }
- break;
-
- /* We don't know which INIT failed, so clear the PENDING flags
- * on them all. if assoc_id is zero then it will then try
- * again */
-
- case SCTP_CANT_STR_ASSOC:
- {
- log_print("Can't start SCTP association - retrying");
- init_failed();
- }
- break;
-
- default:
- log_print("unexpected SCTP assoc change id=%d state=%d",
- (int)sn->sn_assoc_change.sac_assoc_id,
- sn->sn_assoc_change.sac_state);
- }
- }
-}
-
-/* Data received from remote end */
-static int receive_from_sock(void)
-{
- int ret = 0;
- struct msghdr msg;
- struct kvec iov[2];
- unsigned len;
- int r;
- struct sctp_sndrcvinfo *sinfo;
- struct cmsghdr *cmsg;
- struct nodeinfo *ni;
-
- /* These two are marginally too big for stack allocation, but this
- * function is (currently) only called by dlm_recvd so static should be
- * OK.
- */
- static struct sockaddr_storage msgname;
- static char incmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
-
- if (sctp_con.sock == NULL)
- goto out;
-
- if (sctp_con.rx_page == NULL) {
- /*
- * This doesn't need to be atomic, but I think it should
- * improve performance if it is.
- */
- sctp_con.rx_page = alloc_page(GFP_ATOMIC);
- if (sctp_con.rx_page == NULL)
- goto out_resched;
- cbuf_init(&sctp_con.cb, PAGE_CACHE_SIZE);
- }
-
- memset(&incmsg, 0, sizeof(incmsg));
- memset(&msgname, 0, sizeof(msgname));
-
- msg.msg_name = &msgname;
- msg.msg_namelen = sizeof(msgname);
- msg.msg_flags = 0;
- msg.msg_control = incmsg;
- msg.msg_controllen = sizeof(incmsg);
- msg.msg_iovlen = 1;
-
- /* I don't see why this circular buffer stuff is necessary for SCTP
- * which is a packet-based protocol, but the whole thing breaks under
- * load without it! The overhead is minimal (and is in the TCP lowcomms
- * anyway, of course) so I'll leave it in until I can figure out what's
- * really happening.
- */
-
- /*
- * iov[0] is the bit of the circular buffer between the current end
- * point (cb.base + cb.len) and the end of the buffer.
- */
- iov[0].iov_len = sctp_con.cb.base - cbuf_data(&sctp_con.cb);
- iov[0].iov_base = page_address(sctp_con.rx_page) +
- cbuf_data(&sctp_con.cb);
- iov[1].iov_len = 0;
-
- /*
- * iov[1] is the bit of the circular buffer between the start of the
- * buffer and the start of the currently used section (cb.base)
- */
- if (cbuf_data(&sctp_con.cb) >= sctp_con.cb.base) {
- iov[0].iov_len = PAGE_CACHE_SIZE - cbuf_data(&sctp_con.cb);
- iov[1].iov_len = sctp_con.cb.base;
- iov[1].iov_base = page_address(sctp_con.rx_page);
- msg.msg_iovlen = 2;
- }
- len = iov[0].iov_len + iov[1].iov_len;
-
- r = ret = kernel_recvmsg(sctp_con.sock, &msg, iov, msg.msg_iovlen, len,
- MSG_NOSIGNAL | MSG_DONTWAIT);
- if (ret <= 0)
- goto out_close;
-
- msg.msg_control = incmsg;
- msg.msg_controllen = sizeof(incmsg);
- cmsg = CMSG_FIRSTHDR(&msg);
- sinfo = CMSG_DATA(cmsg);
-
- if (msg.msg_flags & MSG_NOTIFICATION) {
- process_sctp_notification(&msg, page_address(sctp_con.rx_page));
- return 0;
- }
-
- /* Is this a new association ? */
- ni = nodeid2nodeinfo(le32_to_cpu(sinfo->sinfo_ppid), GFP_KERNEL);
- if (ni) {
- ni->assoc_id = sinfo->sinfo_assoc_id;
- if (test_and_clear_bit(NI_INIT_PENDING, &ni->flags)) {
-
- if (!test_and_set_bit(NI_WRITE_PENDING, &ni->flags)) {
- spin_lock_bh(&write_nodes_lock);
- list_add_tail(&ni->write_list, &write_nodes);
- spin_unlock_bh(&write_nodes_lock);
- queue_work(send_workqueue, &ni->swork);
- }
- }
- }
-
- /* INIT sends a message with length of 1 - ignore it */
- if (r == 1)
- return 0;
-
- cbuf_add(&sctp_con.cb, ret);
- // PJC: TODO: Add to node's workqueue....can we ??
- ret = dlm_process_incoming_buffer(cpu_to_le32(sinfo->sinfo_ppid),
- page_address(sctp_con.rx_page),
- sctp_con.cb.base, sctp_con.cb.len,
- PAGE_CACHE_SIZE);
- if (ret < 0)
- goto out_close;
- cbuf_eat(&sctp_con.cb, ret);
-
-out:
- ret = 0;
- goto out_ret;
-
-out_resched:
- lowcomms_data_ready(sctp_con.sock->sk, 0);
- ret = 0;
- cond_resched();
- goto out_ret;
-
-out_close:
- if (ret != -EAGAIN)
- log_print("error reading from sctp socket: %d", ret);
-out_ret:
- return ret;
-}
-
-/* Bind to an IP address. SCTP allows multiple address so it can do multi-homing */
-static int add_bind_addr(struct sockaddr_storage *addr, int addr_len, int num)
-{
- mm_segment_t fs;
- int result = 0;
-
- fs = get_fs();
- set_fs(get_ds());
- if (num == 1)
- result = sctp_con.sock->ops->bind(sctp_con.sock,
- (struct sockaddr *) addr,
- addr_len);
- else
- result = sctp_con.sock->ops->setsockopt(sctp_con.sock, SOL_SCTP,
- SCTP_SOCKOPT_BINDX_ADD,
- (char *)addr, addr_len);
- set_fs(fs);
-
- if (result < 0)
- log_print("Can't bind to port %d addr number %d",
- dlm_config.ci_tcp_port, num);
-
- return result;
-}
-
-static void init_local(void)
-{
- struct sockaddr_storage sas, *addr;
- int i;
-
- dlm_local_nodeid = dlm_our_nodeid();
-
- for (i = 0; i < DLM_MAX_ADDR_COUNT - 1; i++) {
- if (dlm_our_addr(&sas, i))
- break;
-
- addr = kmalloc(sizeof(*addr), GFP_KERNEL);
- if (!addr)
- break;
- memcpy(addr, &sas, sizeof(*addr));
- dlm_local_addr[dlm_local_count++] = addr;
- }
-}
-
-/* Initialise SCTP socket and bind to all interfaces */
-static int init_sock(void)
-{
- mm_segment_t fs;
- struct socket *sock = NULL;
- struct sockaddr_storage localaddr;
- struct sctp_event_subscribe subscribe;
- int result = -EINVAL, num = 1, i, addr_len;
-
- if (!dlm_local_count) {
- init_local();
- if (!dlm_local_count) {
- log_print("no local IP address has been set");
- goto out;
- }
- }
-
- result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_SEQPACKET,
- IPPROTO_SCTP, &sock);
- if (result < 0) {
- log_print("Can't create comms socket, check SCTP is loaded");
- goto out;
- }
-
- /* Listen for events */
- memset(&subscribe, 0, sizeof(subscribe));
- subscribe.sctp_data_io_event = 1;
- subscribe.sctp_association_event = 1;
- subscribe.sctp_send_failure_event = 1;
- subscribe.sctp_shutdown_event = 1;
- subscribe.sctp_partial_delivery_event = 1;
-
- fs = get_fs();
- set_fs(get_ds());
- result = sock->ops->setsockopt(sock, SOL_SCTP, SCTP_EVENTS,
- (char *)&subscribe, sizeof(subscribe));
- set_fs(fs);
-
- if (result < 0) {
- log_print("Failed to set SCTP_EVENTS on socket: result=%d",
- result);
- goto create_delsock;
- }
-
- /* Init con struct */
- sock->sk->sk_user_data = &sctp_con;
- sctp_con.sock = sock;
- sctp_con.sock->sk->sk_data_ready = lowcomms_data_ready;
-
- /* Bind to all interfaces. */
- for (i = 0; i < dlm_local_count; i++) {
- memcpy(&localaddr, dlm_local_addr[i], sizeof(localaddr));
- make_sockaddr(&localaddr, dlm_config.ci_tcp_port, &addr_len);
-
- result = add_bind_addr(&localaddr, addr_len, num);
- if (result)
- goto create_delsock;
- ++num;
- }
-
- result = sock->ops->listen(sock, 5);
- if (result < 0) {
- log_print("Can't set socket listening");
- goto create_delsock;
- }
-
- return 0;
-
-create_delsock:
- sock_release(sock);
- sctp_con.sock = NULL;
-out:
- return result;
-}
-
-
-static struct writequeue_entry *new_writequeue_entry(gfp_t allocation)
-{
- struct writequeue_entry *entry;
-
- entry = kmalloc(sizeof(struct writequeue_entry), allocation);
- if (!entry)
- return NULL;
-
- entry->page = alloc_page(allocation);
- if (!entry->page) {
- kfree(entry);
- return NULL;
- }
-
- entry->offset = 0;
- entry->len = 0;
- entry->end = 0;
- entry->users = 0;
-
- return entry;
-}
-
-void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc)
-{
- struct writequeue_entry *e;
- int offset = 0;
- int users = 0;
- struct nodeinfo *ni;
-
- ni = nodeid2nodeinfo(nodeid, allocation);
- if (!ni)
- return NULL;
-
- spin_lock(&ni->writequeue_lock);
- e = list_entry(ni->writequeue.prev, struct writequeue_entry, list);
- if ((&e->list == &ni->writequeue) ||
- (PAGE_CACHE_SIZE - e->end < len)) {
- e = NULL;
- } else {
- offset = e->end;
- e->end += len;
- users = e->users++;
- }
- spin_unlock(&ni->writequeue_lock);
-
- if (e) {
- got_one:
- if (users == 0)
- kmap(e->page);
- *ppc = page_address(e->page) + offset;
- return e;
- }
-
- e = new_writequeue_entry(allocation);
- if (e) {
- spin_lock(&ni->writequeue_lock);
- offset = e->end;
- e->end += len;
- e->ni = ni;
- users = e->users++;
- list_add_tail(&e->list, &ni->writequeue);
- spin_unlock(&ni->writequeue_lock);
- goto got_one;
- }
- return NULL;
-}
-
-void dlm_lowcomms_commit_buffer(void *arg)
-{
- struct writequeue_entry *e = (struct writequeue_entry *) arg;
- int users;
- struct nodeinfo *ni = e->ni;
-
- spin_lock(&ni->writequeue_lock);
- users = --e->users;
- if (users)
- goto out;
- e->len = e->end - e->offset;
- kunmap(e->page);
- spin_unlock(&ni->writequeue_lock);
-
- if (!test_and_set_bit(NI_WRITE_PENDING, &ni->flags)) {
- spin_lock_bh(&write_nodes_lock);
- list_add_tail(&ni->write_list, &write_nodes);
- spin_unlock_bh(&write_nodes_lock);
-
- queue_work(send_workqueue, &ni->swork);
- }
- return;
-
-out:
- spin_unlock(&ni->writequeue_lock);
- return;
-}
-
-static void free_entry(struct writequeue_entry *e)
-{
- __free_page(e->page);
- kfree(e);
-}
-
-/* Initiate an SCTP association. In theory we could just use sendmsg() on
- the first IP address and it should work, but this allows us to set up the
- association before sending any valuable data that we can't afford to lose.
- It also keeps the send path clean as it can now always use the association ID */
-static void initiate_association(int nodeid)
-{
- struct sockaddr_storage rem_addr;
- static char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
- struct msghdr outmessage;
- struct cmsghdr *cmsg;
- struct sctp_sndrcvinfo *sinfo;
- int ret;
- int addrlen;
- char buf[1];
- struct kvec iov[1];
- struct nodeinfo *ni;
-
- log_print("Initiating association with node %d", nodeid);
-
- ni = nodeid2nodeinfo(nodeid, GFP_KERNEL);
- if (!ni)
- return;
-
- if (nodeid_to_addr(nodeid, (struct sockaddr *)&rem_addr)) {
- log_print("no address for nodeid %d", nodeid);
- return;
- }
-
- make_sockaddr(&rem_addr, dlm_config.ci_tcp_port, &addrlen);
-
- outmessage.msg_name = &rem_addr;
- outmessage.msg_namelen = addrlen;
- outmessage.msg_control = outcmsg;
- outmessage.msg_controllen = sizeof(outcmsg);
- outmessage.msg_flags = MSG_EOR;
-
- iov[0].iov_base = buf;
- iov[0].iov_len = 1;
-
- /* Real INIT messages seem to cause trouble. Just send a 1 byte message
- we can afford to lose */
- cmsg = CMSG_FIRSTHDR(&outmessage);
- cmsg->cmsg_level = IPPROTO_SCTP;
- cmsg->cmsg_type = SCTP_SNDRCV;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
- sinfo = CMSG_DATA(cmsg);
- memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
- sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid);
-
- outmessage.msg_controllen = cmsg->cmsg_len;
- ret = kernel_sendmsg(sctp_con.sock, &outmessage, iov, 1, 1);
- if (ret < 0) {
- log_print("send INIT to node failed: %d", ret);
- /* Try again later */
- clear_bit(NI_INIT_PENDING, &ni->flags);
- }
-}
-
-/* Send a message */
-static void send_to_sock(struct nodeinfo *ni)
-{
- int ret = 0;
- struct writequeue_entry *e;
- int len, offset;
- struct msghdr outmsg;
- static char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
- struct cmsghdr *cmsg;
- struct sctp_sndrcvinfo *sinfo;
- struct kvec iov;
-
- /* See if we need to init an association before we start
- sending precious messages */
- spin_lock(&ni->lock);
- if (!ni->assoc_id && !test_and_set_bit(NI_INIT_PENDING, &ni->flags)) {
- spin_unlock(&ni->lock);
- initiate_association(ni->nodeid);
- return;
- }
- spin_unlock(&ni->lock);
-
- outmsg.msg_name = NULL; /* We use assoc_id */
- outmsg.msg_namelen = 0;
- outmsg.msg_control = outcmsg;
- outmsg.msg_controllen = sizeof(outcmsg);
- outmsg.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL | MSG_EOR;
-
- cmsg = CMSG_FIRSTHDR(&outmsg);
- cmsg->cmsg_level = IPPROTO_SCTP;
- cmsg->cmsg_type = SCTP_SNDRCV;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
- sinfo = CMSG_DATA(cmsg);
- memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
- sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid);
- sinfo->sinfo_assoc_id = ni->assoc_id;
- outmsg.msg_controllen = cmsg->cmsg_len;
-
- spin_lock(&ni->writequeue_lock);
- for (;;) {
- if (list_empty(&ni->writequeue))
- break;
- e = list_entry(ni->writequeue.next, struct writequeue_entry,
- list);
- len = e->len;
- offset = e->offset;
- BUG_ON(len == 0 && e->users == 0);
- spin_unlock(&ni->writequeue_lock);
- kmap(e->page);
-
- ret = 0;
- if (len) {
- iov.iov_base = page_address(e->page)+offset;
- iov.iov_len = len;
-
- ret = kernel_sendmsg(sctp_con.sock, &outmsg, &iov, 1,
- len);
- if (ret == -EAGAIN) {
- sctp_con.eagain_flag = 1;
- goto out;
- } else if (ret < 0)
- goto send_error;
- } else {
- /* Don't starve people filling buffers */
- cond_resched();
- }
-
- spin_lock(&ni->writequeue_lock);
- e->offset += ret;
- e->len -= ret;
-
- if (e->len == 0 && e->users == 0) {
- list_del(&e->list);
- kunmap(e->page);
- free_entry(e);
- continue;
- }
- }
- spin_unlock(&ni->writequeue_lock);
-out:
- return;
-
-send_error:
- log_print("Error sending to node %d %d", ni->nodeid, ret);
- spin_lock(&ni->lock);
- if (!test_and_set_bit(NI_INIT_PENDING, &ni->flags)) {
- ni->assoc_id = 0;
- spin_unlock(&ni->lock);
- initiate_association(ni->nodeid);
- } else
- spin_unlock(&ni->lock);
-
- return;
-}
-
-/* Try to send any messages that are pending */
-static void process_output_queue(void)
-{
- struct list_head *list;
- struct list_head *temp;
-
- spin_lock_bh(&write_nodes_lock);
- list_for_each_safe(list, temp, &write_nodes) {
- struct nodeinfo *ni =
- list_entry(list, struct nodeinfo, write_list);
- clear_bit(NI_WRITE_PENDING, &ni->flags);
- list_del(&ni->write_list);
-
- spin_unlock_bh(&write_nodes_lock);
-
- send_to_sock(ni);
- spin_lock_bh(&write_nodes_lock);
- }
- spin_unlock_bh(&write_nodes_lock);
-}
-
-/* Called after we've had -EAGAIN and been woken up */
-static void refill_write_queue(void)
-{
- int i;
-
- for (i=1; i<=max_nodeid; i++) {
- struct nodeinfo *ni = nodeid2nodeinfo(i, 0);
-
- if (ni) {
- if (!test_and_set_bit(NI_WRITE_PENDING, &ni->flags)) {
- spin_lock_bh(&write_nodes_lock);
- list_add_tail(&ni->write_list, &write_nodes);
- spin_unlock_bh(&write_nodes_lock);
- }
- }
- }
-}
-
-static void clean_one_writequeue(struct nodeinfo *ni)
-{
- struct list_head *list;
- struct list_head *temp;
-
- spin_lock(&ni->writequeue_lock);
- list_for_each_safe(list, temp, &ni->writequeue) {
- struct writequeue_entry *e =
- list_entry(list, struct writequeue_entry, list);
- list_del(&e->list);
- free_entry(e);
- }
- spin_unlock(&ni->writequeue_lock);
-}
-
-static void clean_writequeues(void)
-{
- int i;
-
- for (i=1; i<=max_nodeid; i++) {
- struct nodeinfo *ni = nodeid2nodeinfo(i, 0);
- if (ni)
- clean_one_writequeue(ni);
- }
-}
-
-
-static void dealloc_nodeinfo(void)
-{
- int i;
-
- for (i=1; i<=max_nodeid; i++) {
- struct nodeinfo *ni = nodeid2nodeinfo(i, 0);
- if (ni) {
- idr_remove(&nodeinfo_idr, i);
- kfree(ni);
- }
- }
-}
-
-int dlm_lowcomms_close(int nodeid)
-{
- struct nodeinfo *ni;
-
- ni = nodeid2nodeinfo(nodeid, 0);
- if (!ni)
- return -1;
-
- spin_lock(&ni->lock);
- if (ni->assoc_id) {
- ni->assoc_id = 0;
- /* Don't send shutdown here, sctp will just queue it
- till the node comes back up! */
- }
- spin_unlock(&ni->lock);
-
- clean_one_writequeue(ni);
- clear_bit(NI_INIT_PENDING, &ni->flags);
- return 0;
-}
-
-// PJC: The work queue function for receiving.
-static void process_recv_sockets(struct work_struct *work)
-{
- if (test_and_clear_bit(CF_READ_PENDING, &sctp_con.flags)) {
- int ret;
- int count = 0;
-
- do {
- ret = receive_from_sock();
-
- /* Don't starve out everyone else */
- if (++count >= MAX_RX_MSG_COUNT) {
- cond_resched();
- count = 0;
- }
- } while (!kthread_should_stop() && ret >=0);
- }
- cond_resched();
-}
-
-// PJC: the work queue function for sending
-static void process_send_sockets(struct work_struct *work)
-{
- if (sctp_con.eagain_flag) {
- sctp_con.eagain_flag = 0;
- refill_write_queue();
- }
- process_output_queue();
-}
-
-// PJC: Process lock requests from a particular node.
-// TODO: can we optimise this out on UP ??
-static void process_lock_request(struct work_struct *work)
-{
-}
-
-static void daemons_stop(void)
-{
- destroy_workqueue(recv_workqueue);
- destroy_workqueue(send_workqueue);
- destroy_workqueue(lock_workqueue);
-}
-
-static int daemons_start(void)
-{
- int error;
- recv_workqueue = create_workqueue("dlm_recv");
- error = IS_ERR(recv_workqueue);
- if (error) {
- log_print("can't start dlm_recv %d", error);
- return error;
- }
-
- send_workqueue = create_singlethread_workqueue("dlm_send");
- error = IS_ERR(send_workqueue);
- if (error) {
- log_print("can't start dlm_send %d", error);
- destroy_workqueue(recv_workqueue);
- return error;
- }
-
- lock_workqueue = create_workqueue("dlm_rlock");
- error = IS_ERR(lock_workqueue);
- if (error) {
- log_print("can't start dlm_rlock %d", error);
- destroy_workqueue(send_workqueue);
- destroy_workqueue(recv_workqueue);
- return error;
- }
-
- return 0;
-}
-
-/*
- * This is quite likely to sleep...
- */
-int dlm_lowcomms_start(void)
-{
- int error;
-
- INIT_WORK(&sctp_con.work, process_recv_sockets);
-
- error = init_sock();
- if (error)
- goto fail_sock;
- error = daemons_start();
- if (error)
- goto fail_sock;
- return 0;
-
-fail_sock:
- close_connection();
- return error;
-}
-
-void dlm_lowcomms_stop(void)
-{
- int i;
-
- sctp_con.flags = 0x7;
- daemons_stop();
- clean_writequeues();
- close_connection();
- dealloc_nodeinfo();
- max_nodeid = 0;
-
- dlm_local_count = 0;
- dlm_local_nodeid = 0;
-
- for (i = 0; i < dlm_local_count; i++)
- kfree(dlm_local_addr[i]);
-}
diff --git a/fs/dlm/lowcomms-tcp.c b/fs/dlm/lowcomms.c
index 07e0a12..27970a5 100644
--- a/fs/dlm/lowcomms-tcp.c
+++ b/fs/dlm/lowcomms.c
@@ -36,30 +36,36 @@
* of high load. Also, this way, the sending thread can collect together
* messages bound for one node and send them in one block.
*
- * I don't see any problem with the recv thread executing the locking
- * code on behalf of remote processes as the locking code is
- * short, efficient and never waits.
+ * lowcomms will choose to use wither TCP or SCTP as its transport layer
+ * depending on the configuration variable 'protocol'. This should be set
+ * to 0 (default) for TCP or 1 for SCTP. It shouldbe configured using a
+ * cluster-wide mechanism as it must be the same on all nodes of the cluster
+ * for the DLM to function.
*
*/
-
#include <asm/ioctls.h>
#include <net/sock.h>
#include <net/tcp.h>
#include <linux/pagemap.h>
+#include <linux/idr.h>
+#include <linux/file.h>
+#include <linux/sctp.h>
+#include <net/sctp/user.h>
#include "dlm_internal.h"
#include "lowcomms.h"
#include "midcomms.h"
#include "config.h"
+#define NEEDED_RMEM (4*1024*1024)
+
struct cbuf {
unsigned int base;
unsigned int len;
unsigned int mask;
};
-#define NODE_INCREMENT 32
static void cbuf_add(struct cbuf *cb, int n)
{
cb->len += n;
@@ -88,28 +94,25 @@ static bool cbuf_empty(struct cbuf *cb)
return cb->len == 0;
}
-/* Maximum number of incoming messages to process before
- doing a cond_resched()
-*/
-#define MAX_RX_MSG_COUNT 25
-
struct connection {
struct socket *sock; /* NULL if not connected */
uint32_t nodeid; /* So we know who we are in the list */
struct mutex sock_mutex;
- unsigned long flags; /* bit 1,2 = We are on the read/write lists */
+ unsigned long flags;
#define CF_READ_PENDING 1
#define CF_WRITE_PENDING 2
#define CF_CONNECT_PENDING 3
-#define CF_IS_OTHERCON 4
+#define CF_INIT_PENDING 4
+#define CF_IS_OTHERCON 5
struct list_head writequeue; /* List of outgoing writequeue_entries */
- struct list_head listenlist; /* List of allocated listening sockets */
spinlock_t writequeue_lock;
int (*rx_action) (struct connection *); /* What to do when active */
+ void (*connect_action) (struct connection *); /* What to do to connect */
struct page *rx_page;
struct cbuf cb;
int retries;
#define MAX_CONNECT_RETRIES 3
+ int sctp_assoc;
struct connection *othercon;
struct work_struct rwork; /* Receive workqueue */
struct work_struct swork; /* Send workqueue */
@@ -127,68 +130,136 @@ struct writequeue_entry {
struct connection *con;
};
-static struct sockaddr_storage dlm_local_addr;
+static struct sockaddr_storage *dlm_local_addr[DLM_MAX_ADDR_COUNT];
+static int dlm_local_count;
/* Work queues */
static struct workqueue_struct *recv_workqueue;
static struct workqueue_struct *send_workqueue;
-/* An array of pointers to connections, indexed by NODEID */
-static struct connection **connections;
+static DEFINE_IDR(connections_idr);
static DECLARE_MUTEX(connections_lock);
+static int max_nodeid;
static struct kmem_cache *con_cache;
-static int conn_array_size;
static void process_recv_sockets(struct work_struct *work);
static void process_send_sockets(struct work_struct *work);
-static struct connection *nodeid2con(int nodeid, gfp_t allocation)
+/*
+ * If 'allocation' is zero then we don't attempt to create a new
+ * connection structure for this node.
+ */
+static struct connection *__nodeid2con(int nodeid, gfp_t alloc)
{
struct connection *con = NULL;
+ int r;
+ int n;
- down(&connections_lock);
- if (nodeid >= conn_array_size) {
- int new_size = nodeid + NODE_INCREMENT;
- struct connection **new_conns;
+ con = idr_find(&connections_idr, nodeid);
+ if (con || !alloc)
+ return con;
- new_conns = kzalloc(sizeof(struct connection *) *
- new_size, allocation);
- if (!new_conns)
- goto finish;
+ r = idr_pre_get(&connections_idr, alloc);
+ if (!r)
+ return NULL;
+
+ con = kmem_cache_zalloc(con_cache, alloc);
+ if (!con)
+ return NULL;
- memcpy(new_conns, connections, sizeof(struct connection *) * conn_array_size);
- conn_array_size = new_size;
- kfree(connections);
- connections = new_conns;
+ r = idr_get_new_above(&connections_idr, con, nodeid, &n);
+ if (r) {
+ kmem_cache_free(con_cache, con);
+ return NULL;
+ }
+ if (n != nodeid) {
+ idr_remove(&connections_idr, n);
+ kmem_cache_free(con_cache, con);
+ return NULL;
}
- con = connections[nodeid];
- if (con == NULL && allocation) {
- con = kmem_cache_zalloc(con_cache, allocation);
- if (!con)
- goto finish;
+ con->nodeid = nodeid;
+ mutex_init(&con->sock_mutex);
+ INIT_LIST_HEAD(&con->writequeue);
+ spin_lock_init(&con->writequeue_lock);
+ INIT_WORK(&con->swork, process_send_sockets);
+ INIT_WORK(&con->rwork, process_recv_sockets);
- con->nodeid = nodeid;
- mutex_init(&con->sock_mutex);
- INIT_LIST_HEAD(&con->writequeue);
- spin_lock_init(&con->writequeue_lock);
- INIT_WORK(&con->swork, process_send_sockets);
- INIT_WORK(&con->rwork, process_recv_sockets);
+ /* Setup action pointers for child sockets */
+ if (con->nodeid) {
+ struct connection *zerocon = idr_find(&connections_idr, 0);
- connections[nodeid] = con;
+ con->connect_action = zerocon->connect_action;
+ if (!con->rx_action)
+ con->rx_action = zerocon->rx_action;
}
-finish:
+ if (nodeid > max_nodeid)
+ max_nodeid = nodeid;
+
+ return con;
+}
+
+static struct connection *nodeid2con(int nodeid, gfp_t allocation)
+{
+ struct connection *con;
+
+ down(&connections_lock);
+ con = __nodeid2con(nodeid, allocation);
up(&connections_lock);
+
return con;
}
+/* This is a bit drastic, but only called when things go wrong */
+static struct connection *assoc2con(int assoc_id)
+{
+ int i;
+ struct connection *con;
+
+ down(&connections_lock);
+ for (i=0; i<=max_nodeid; i++) {
+ con = __nodeid2con(i, 0);
+ if (con && con->sctp_assoc == assoc_id) {
+ up(&connections_lock);
+ return con;
+ }
+ }
+ up(&connections_lock);
+ return NULL;
+}
+
+static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr)
+{
+ struct sockaddr_storage addr;
+ int error;
+
+ if (!dlm_local_count)
+ return -1;
+
+ error = dlm_nodeid_to_addr(nodeid, &addr);
+ if (error)
+ return error;
+
+ if (dlm_local_addr[0]->ss_family == AF_INET) {
+ struct sockaddr_in *in4 = (struct sockaddr_in *) &addr;
+ struct sockaddr_in *ret4 = (struct sockaddr_in *) retaddr;
+ ret4->sin_addr.s_addr = in4->sin_addr.s_addr;
+ } else {
+ struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &addr;
+ struct sockaddr_in6 *ret6 = (struct sockaddr_in6 *) retaddr;
+ memcpy(&ret6->sin6_addr, &in6->sin6_addr,
+ sizeof(in6->sin6_addr));
+ }
+
+ return 0;
+}
+
/* Data available on socket or listen socket received a connect */
static void lowcomms_data_ready(struct sock *sk, int count_unused)
{
struct connection *con = sock2con(sk);
-
if (!test_and_set_bit(CF_READ_PENDING, &con->flags))
queue_work(recv_workqueue, &con->rwork);
}
@@ -222,20 +293,21 @@ static int add_sock(struct socket *sock, struct connection *con)
con->sock->sk->sk_data_ready = lowcomms_data_ready;
con->sock->sk->sk_write_space = lowcomms_write_space;
con->sock->sk->sk_state_change = lowcomms_state_change;
-
+ con->sock->sk->sk_user_data = con;
return 0;
}
-/* Add the port number to an IP6 or 4 sockaddr and return the address
+/* Add the port number to an IPv6 or 4 sockaddr and return the address
length */
static void make_sockaddr(struct sockaddr_storage *saddr, uint16_t port,
int *addr_len)
{
- saddr->ss_family = dlm_local_addr.ss_family;
+ saddr->ss_family = dlm_local_addr[0]->ss_family;
if (saddr->ss_family == AF_INET) {
struct sockaddr_in *in4_addr = (struct sockaddr_in *)saddr;
in4_addr->sin_port = cpu_to_be16(port);
*addr_len = sizeof(struct sockaddr_in);
+ memset(&in4_addr->sin_zero, 0, sizeof(in4_addr->sin_zero));
} else {
struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)saddr;
in6_addr->sin6_port = cpu_to_be16(port);
@@ -264,6 +336,193 @@ static void close_connection(struct connection *con, bool and_other)
mutex_unlock(&con->sock_mutex);
}
+/* We only send shutdown messages to nodes that are not part of the cluster */
+static void sctp_send_shutdown(sctp_assoc_t associd)
+{
+ static char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct msghdr outmessage;
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+ int ret;
+ struct connection *con;
+
+ con = nodeid2con(0,0);
+ BUG_ON(con == NULL);
+
+ outmessage.msg_name = NULL;
+ outmessage.msg_namelen = 0;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = MSG_EOR;
+
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ outmessage.msg_controllen = cmsg->cmsg_len;
+ sinfo = CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+
+ sinfo->sinfo_flags |= MSG_EOF;
+ sinfo->sinfo_assoc_id = associd;
+
+ ret = kernel_sendmsg(con->sock, &outmessage, NULL, 0, 0);
+
+ if (ret != 0)
+ log_print("send EOF to node failed: %d", ret);
+}
+
+/* INIT failed but we don't know which node...
+ restart INIT on all pending nodes */
+static void sctp_init_failed(void)
+{
+ int i;
+ struct connection *con;
+
+ down(&connections_lock);
+ for (i=1; i<=max_nodeid; i++) {
+ con = __nodeid2con(i, 0);
+ if (!con)
+ continue;
+ con->sctp_assoc = 0;
+ if (test_and_clear_bit(CF_CONNECT_PENDING, &con->flags)) {
+ if (!test_and_set_bit(CF_WRITE_PENDING, &con->flags)) {
+ queue_work(send_workqueue, &con->swork);
+ }
+ }
+ }
+ up(&connections_lock);
+}
+
+/* Something happened to an association */
+static void process_sctp_notification(struct connection *con,
+ struct msghdr *msg, char *buf)
+{
+ union sctp_notification *sn = (union sctp_notification *)buf;
+
+ if (sn->sn_header.sn_type == SCTP_ASSOC_CHANGE) {
+ switch (sn->sn_assoc_change.sac_state) {
+
+ case SCTP_COMM_UP:
+ case SCTP_RESTART:
+ {
+ /* Check that the new node is in the lockspace */
+ struct sctp_prim prim;
+ int nodeid;
+ int prim_len, ret;
+ int addr_len;
+ struct connection *new_con;
+ struct file *file;
+ sctp_peeloff_arg_t parg;
+ int parglen = sizeof(parg);
+
+ /*
+ * We get this before any data for an association.
+ * We verify that the node is in the cluster and
+ * then peel off a socket for it.
+ */
+ if ((int)sn->sn_assoc_change.sac_assoc_id <= 0) {
+ log_print("COMM_UP for invalid assoc ID %d",
+ (int)sn->sn_assoc_change.sac_assoc_id);
+ sctp_init_failed();
+ return;
+ }
+ memset(&prim, 0, sizeof(struct sctp_prim));
+ prim_len = sizeof(struct sctp_prim);
+ prim.ssp_assoc_id = sn->sn_assoc_change.sac_assoc_id;
+
+ ret = kernel_getsockopt(con->sock,
+ IPPROTO_SCTP,
+ SCTP_PRIMARY_ADDR,
+ (char*)&prim,
+ &prim_len);
+ if (ret < 0) {
+ log_print("getsockopt/sctp_primary_addr on "
+ "new assoc %d failed : %d",
+ (int)sn->sn_assoc_change.sac_assoc_id,
+ ret);
+
+ /* Retry INIT later */
+ new_con = assoc2con(sn->sn_assoc_change.sac_assoc_id);
+ if (new_con)
+ clear_bit(CF_CONNECT_PENDING, &con->flags);
+ return;
+ }
+ make_sockaddr(&prim.ssp_addr, 0, &addr_len);
+ if (dlm_addr_to_nodeid(&prim.ssp_addr, &nodeid)) {
+ int i;
+ unsigned char *b=(unsigned char *)&prim.ssp_addr;
+ log_print("reject connect from unknown addr");
+ for (i=0; i<sizeof(struct sockaddr_storage);i++)
+ printk("%02x ", b[i]);
+ printk("\n");
+ sctp_send_shutdown(prim.ssp_assoc_id);
+ return;
+ }
+
+ new_con = nodeid2con(nodeid, GFP_KERNEL);
+ if (!new_con)
+ return;
+
+ /* Peel off a new sock */
+ parg.associd = sn->sn_assoc_change.sac_assoc_id;
+ ret = kernel_getsockopt(con->sock, IPPROTO_SCTP,
+ SCTP_SOCKOPT_PEELOFF,
+ (void *)&parg, &parglen);
+ if (ret) {
+ log_print("Can't peel off a socket for "
+ "connection %d to node %d: err=%d\n",
+ parg.associd, nodeid, ret);
+ }
+ file = fget(parg.sd);
+ new_con->sock = SOCKET_I(file->f_dentry->d_inode);
+ add_sock(new_con->sock, new_con);
+ fput(file);
+ put_unused_fd(parg.sd);
+
+ log_print("got new/restarted association %d nodeid %d",
+ (int)sn->sn_assoc_change.sac_assoc_id, nodeid);
+
+ /* Send any pending writes */
+ clear_bit(CF_CONNECT_PENDING, &new_con->flags);
+ clear_bit(CF_INIT_PENDING, &con->flags);
+ if (!test_and_set_bit(CF_WRITE_PENDING, &new_con->flags)) {
+ queue_work(send_workqueue, &new_con->swork);
+ }
+ if (!test_and_set_bit(CF_READ_PENDING, &new_con->flags))
+ queue_work(recv_workqueue, &new_con->rwork);
+ }
+ break;
+
+ case SCTP_COMM_LOST:
+ case SCTP_SHUTDOWN_COMP:
+ {
+ con = assoc2con(sn->sn_assoc_change.sac_assoc_id);
+ if (con) {
+ con->sctp_assoc = 0;
+ }
+ }
+ break;
+
+ /* We don't know which INIT failed, so clear the PENDING flags
+ * on them all. if assoc_id is zero then it will then try
+ * again */
+
+ case SCTP_CANT_STR_ASSOC:
+ {
+ log_print("Can't start SCTP association - retrying");
+ sctp_init_failed();
+ }
+ break;
+
+ default:
+ log_print("unexpected SCTP assoc change id=%d state=%d",
+ (int)sn->sn_assoc_change.sac_assoc_id,
+ sn->sn_assoc_change.sac_state);
+ }
+ }
+}
+
/* Data received from remote end */
static int receive_from_sock(struct connection *con)
{
@@ -274,6 +533,7 @@ static int receive_from_sock(struct connection *con)
int r;
int call_again_soon = 0;
int nvec;
+ char incmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
mutex_lock(&con->sock_mutex);
@@ -293,12 +553,18 @@ static int receive_from_sock(struct connection *con)
cbuf_init(&con->cb, PAGE_CACHE_SIZE);
}
+ /* Only SCTP needs these really */
+ memset(&incmsg, 0, sizeof(incmsg));
+ msg.msg_control = incmsg;
+ msg.msg_controllen = sizeof(incmsg);
+
/*
* iov[0] is the bit of the circular buffer between the current end
* point (cb.base + cb.len) and the end of the buffer.
*/
iov[0].iov_len = con->cb.base - cbuf_data(&con->cb);
iov[0].iov_base = page_address(con->rx_page) + cbuf_data(&con->cb);
+ iov[1].iov_len = 0;
nvec = 1;
/*
@@ -315,11 +581,20 @@ static int receive_from_sock(struct connection *con)
r = ret = kernel_recvmsg(con->sock, &msg, iov, nvec, len,
MSG_DONTWAIT | MSG_NOSIGNAL);
-
if (ret <= 0)
goto out_close;
- if (ret == -EAGAIN)
- goto out_resched;
+
+ /* Process SCTP notifications */
+ if (msg.msg_flags & MSG_NOTIFICATION) {
+ msg.msg_control = incmsg;
+ msg.msg_controllen = sizeof(incmsg);
+
+ process_sctp_notification(con, &msg,
+ page_address(con->rx_page) + con->cb.base);
+ mutex_unlock(&con->sock_mutex);
+ return 0;
+ }
+ BUG_ON(con->nodeid == 0);
if (ret == len)
call_again_soon = 1;
@@ -329,10 +604,10 @@ static int receive_from_sock(struct connection *con)
con->cb.base, con->cb.len,
PAGE_CACHE_SIZE);
if (ret == -EBADMSG) {
- printk(KERN_INFO "dlm: lowcomms: addr=%p, base=%u, len=%u, "
- "iov_len=%u, iov_base[0]=%p, read=%d\n",
- page_address(con->rx_page), con->cb.base, con->cb.len,
- len, iov[0].iov_base, r);
+ log_print("lowcomms: addr=%p, base=%u, len=%u, "
+ "iov_len=%u, iov_base[0]=%p, read=%d",
+ page_address(con->rx_page), con->cb.base, con->cb.len,
+ len, iov[0].iov_base, r);
}
if (ret < 0)
goto out_close;
@@ -368,7 +643,7 @@ out_close:
}
/* Listening socket is busy, accept a connection */
-static int accept_from_sock(struct connection *con)
+static int tcp_accept_from_sock(struct connection *con)
{
int result;
struct sockaddr_storage peeraddr;
@@ -379,7 +654,7 @@ static int accept_from_sock(struct connection *con)
struct connection *addcon;
memset(&peeraddr, 0, sizeof(peeraddr));
- result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM,
+ result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_STREAM,
IPPROTO_TCP, &newsock);
if (result < 0)
return -ENOMEM;
@@ -408,7 +683,7 @@ static int accept_from_sock(struct connection *con)
/* Get the new node's NODEID */
make_sockaddr(&peeraddr, 0, &len);
if (dlm_addr_to_nodeid(&peeraddr, &nodeid)) {
- printk("dlm: connect from non cluster node\n");
+ log_print("connect from non cluster node");
sock_release(newsock);
mutex_unlock(&con->sock_mutex);
return -1;
@@ -419,7 +694,6 @@ static int accept_from_sock(struct connection *con)
/* Check to see if we already have a connection to this node. This
* could happen if the two nodes initiate a connection at roughly
* the same time and the connections cross on the wire.
- * TEMPORARY FIX:
* In this case we store the incoming one in "othercon"
*/
newcon = nodeid2con(nodeid, GFP_KERNEL);
@@ -434,7 +708,7 @@ static int accept_from_sock(struct connection *con)
if (!othercon) {
othercon = kmem_cache_zalloc(con_cache, GFP_KERNEL);
if (!othercon) {
- printk("dlm: failed to allocate incoming socket\n");
+ log_print("failed to allocate incoming socket");
mutex_unlock(&newcon->sock_mutex);
result = -ENOMEM;
goto accept_err;
@@ -477,12 +751,107 @@ accept_err:
sock_release(newsock);
if (result != -EAGAIN)
- printk("dlm: error accepting connection from node: %d\n", result);
+ log_print("error accepting connection from node: %d", result);
return result;
}
+static void free_entry(struct writequeue_entry *e)
+{
+ __free_page(e->page);
+ kfree(e);
+}
+
+/* Initiate an SCTP association.
+ This is a special case of send_to_sock() in that we don't yet have a
+ peeled-off socket for this association, so we use the listening socket
+ and add the primary IP address of the remote node.
+ */
+static void sctp_init_assoc(struct connection *con)
+{
+ struct sockaddr_storage rem_addr;
+ char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+ struct msghdr outmessage;
+ struct cmsghdr *cmsg;
+ struct sctp_sndrcvinfo *sinfo;
+ struct connection *base_con;
+ struct writequeue_entry *e;
+ int len, offset;
+ int ret;
+ int addrlen;
+ struct kvec iov[1];
+
+ if (test_and_set_bit(CF_INIT_PENDING, &con->flags))
+ return;
+
+ if (con->retries++ > MAX_CONNECT_RETRIES)
+ return;
+
+ log_print("Initiating association with node %d", con->nodeid);
+
+ if (nodeid_to_addr(con->nodeid, (struct sockaddr *)&rem_addr)) {
+ log_print("no address for nodeid %d", con->nodeid);
+ return;
+ }
+ base_con = nodeid2con(0, 0);
+ BUG_ON(base_con == NULL);
+
+ make_sockaddr(&rem_addr, dlm_config.ci_tcp_port, &addrlen);
+
+ outmessage.msg_name = &rem_addr;
+ outmessage.msg_namelen = addrlen;
+ outmessage.msg_control = outcmsg;
+ outmessage.msg_controllen = sizeof(outcmsg);
+ outmessage.msg_flags = MSG_EOR;
+
+ spin_lock(&con->writequeue_lock);
+ e = list_entry(con->writequeue.next, struct writequeue_entry,
+ list);
+
+ BUG_ON((struct list_head *) e == &con->writequeue);
+
+ len = e->len;
+ offset = e->offset;
+ spin_unlock(&con->writequeue_lock);
+ kmap(e->page);
+
+ /* Send the first block off the write queue */
+ iov[0].iov_base = page_address(e->page)+offset;
+ iov[0].iov_len = len;
+
+ cmsg = CMSG_FIRSTHDR(&outmessage);
+ cmsg->cmsg_level = IPPROTO_SCTP;
+ cmsg->cmsg_type = SCTP_SNDRCV;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+ sinfo = CMSG_DATA(cmsg);
+ memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
+ sinfo->sinfo_ppid = cpu_to_le32(dlm_our_nodeid());
+ outmessage.msg_controllen = cmsg->cmsg_len;
+
+ ret = kernel_sendmsg(base_con->sock, &outmessage, iov, 1, len);
+ if (ret < 0) {
+ log_print("Send first packet to node %d failed: %d",
+ con->nodeid, ret);
+
+ /* Try again later */
+ clear_bit(CF_CONNECT_PENDING, &con->flags);
+ clear_bit(CF_INIT_PENDING, &con->flags);
+ }
+ else {
+ spin_lock(&con->writequeue_lock);
+ e->offset += ret;
+ e->len -= ret;
+
+ if (e->len == 0 && e->users == 0) {
+ list_del(&e->list);
+ kunmap(e->page);
+ free_entry(e);
+ }
+ spin_unlock(&con->writequeue_lock);
+ }
+}
+
/* Connect a new socket to its peer */
-static void connect_to_sock(struct connection *con)
+static void tcp_connect_to_sock(struct connection *con)
{
int result = -EHOSTUNREACH;
struct sockaddr_storage saddr;
@@ -505,7 +874,7 @@ static void connect_to_sock(struct connection *con)
}
/* Create a socket to communicate with */
- result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM,
+ result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_STREAM,
IPPROTO_TCP, &sock);
if (result < 0)
goto out_err;
@@ -516,11 +885,11 @@ static void connect_to_sock(struct connection *con)
sock->sk->sk_user_data = con;
con->rx_action = receive_from_sock;
+ con->connect_action = tcp_connect_to_sock;
+ add_sock(sock, con);
make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len);
- add_sock(sock, con);
-
log_print("connecting to %d", con->nodeid);
result =
sock->ops->connect(sock, (struct sockaddr *)&saddr, addr_len,
@@ -550,64 +919,57 @@ out:
return;
}
-static struct socket *create_listen_sock(struct connection *con,
- struct sockaddr_storage *saddr)
+static struct socket *tcp_create_listen_sock(struct connection *con,
+ struct sockaddr_storage *saddr)
{
struct socket *sock = NULL;
- mm_segment_t fs;
int result = 0;
int one = 1;
int addr_len;
- if (dlm_local_addr.ss_family == AF_INET)
+ if (dlm_local_addr[0]->ss_family == AF_INET)
addr_len = sizeof(struct sockaddr_in);
else
addr_len = sizeof(struct sockaddr_in6);
/* Create a socket to communicate with */
- result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM, IPPROTO_TCP, &sock);
+ result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_STREAM,
+ IPPROTO_TCP, &sock);
if (result < 0) {
- printk("dlm: Can't create listening comms socket\n");
+ log_print("Can't create listening comms socket");
goto create_out;
}
- fs = get_fs();
- set_fs(get_ds());
- result = sock_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
- (char *)&one, sizeof(one));
- set_fs(fs);
+ result = kernel_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ (char *)&one, sizeof(one));
+
if (result < 0) {
- printk("dlm: Failed to set SO_REUSEADDR on socket: result=%d\n",
- result);
+ log_print("Failed to set SO_REUSEADDR on socket: %d", result);
}
sock->sk->sk_user_data = con;
- con->rx_action = accept_from_sock;
+ con->rx_action = tcp_accept_from_sock;
+ con->connect_action = tcp_connect_to_sock;
con->sock = sock;
/* Bind to our port */
make_sockaddr(saddr, dlm_config.ci_tcp_port, &addr_len);
result = sock->ops->bind(sock, (struct sockaddr *) saddr, addr_len);
if (result < 0) {
- printk("dlm: Can't bind to port %d\n", dlm_config.ci_tcp_port);
+ log_print("Can't bind to port %d", dlm_config.ci_tcp_port);
sock_release(sock);
sock = NULL;
con->sock = NULL;
goto create_out;
}
-
- fs = get_fs();
- set_fs(get_ds());
-
- result = sock_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
+ result = kernel_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
(char *)&one, sizeof(one));
- set_fs(fs);
if (result < 0) {
- printk("dlm: Set keepalive failed: %d\n", result);
+ log_print("Set keepalive failed: %d", result);
}
result = sock->ops->listen(sock, 5);
if (result < 0) {
- printk("dlm: Can't listen on port %d\n", dlm_config.ci_tcp_port);
+ log_print("Can't listen on port %d", dlm_config.ci_tcp_port);
sock_release(sock);
sock = NULL;
goto create_out;
@@ -617,18 +979,146 @@ create_out:
return sock;
}
+/* Get local addresses */
+static void init_local(void)
+{
+ struct sockaddr_storage sas, *addr;
+ int i;
+
+ dlm_local_count = 0;
+ for (i = 0; i < DLM_MAX_ADDR_COUNT - 1; i++) {
+ if (dlm_our_addr(&sas, i))
+ break;
+
+ addr = kmalloc(sizeof(*addr), GFP_KERNEL);
+ if (!addr)
+ break;
+ memcpy(addr, &sas, sizeof(*addr));
+ dlm_local_addr[dlm_local_count++] = addr;
+ }
+}
+
+/* Bind to an IP address. SCTP allows multiple address so it can do
+ multi-homing */
+static int add_sctp_bind_addr(struct connection *sctp_con,
+ struct sockaddr_storage *addr,
+ int addr_len, int num)
+{
+ int result = 0;
+
+ if (num == 1)
+ result = kernel_bind(sctp_con->sock,
+ (struct sockaddr *) addr,
+ addr_len);
+ else
+ result = kernel_setsockopt(sctp_con->sock, SOL_SCTP,
+ SCTP_SOCKOPT_BINDX_ADD,
+ (char *)addr, addr_len);
+
+ if (result < 0)
+ log_print("Can't bind to port %d addr number %d",
+ dlm_config.ci_tcp_port, num);
+
+ return result;
+}
-/* Listen on all interfaces */
-static int listen_for_all(void)
+/* Initialise SCTP socket and bind to all interfaces */
+static int sctp_listen_for_all(void)
+{
+ struct socket *sock = NULL;
+ struct sockaddr_storage localaddr;
+ struct sctp_event_subscribe subscribe;
+ int result = -EINVAL, num = 1, i, addr_len;
+ struct connection *con = nodeid2con(0, GFP_KERNEL);
+ int bufsize = NEEDED_RMEM;
+
+ if (!con)
+ return -ENOMEM;
+
+ log_print("Using SCTP for communications");
+
+ result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_SEQPACKET,
+ IPPROTO_SCTP, &sock);
+ if (result < 0) {
+ log_print("Can't create comms socket, check SCTP is loaded");
+ goto out;
+ }
+
+ /* Listen for events */
+ memset(&subscribe, 0, sizeof(subscribe));
+ subscribe.sctp_data_io_event = 1;
+ subscribe.sctp_association_event = 1;
+ subscribe.sctp_send_failure_event = 1;
+ subscribe.sctp_shutdown_event = 1;
+ subscribe.sctp_partial_delivery_event = 1;
+
+ result = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
+ (char *)&bufsize, sizeof(bufsize));
+ if (result)
+ log_print("Error increasing buffer space on socket %d", result);
+
+ result = kernel_setsockopt(sock, SOL_SCTP, SCTP_EVENTS,
+ (char *)&subscribe, sizeof(subscribe));
+ if (result < 0) {
+ log_print("Failed to set SCTP_EVENTS on socket: result=%d",
+ result);
+ goto create_delsock;
+ }
+
+ /* Init con struct */
+ sock->sk->sk_user_data = con;
+ con->sock = sock;
+ con->sock->sk->sk_data_ready = lowcomms_data_ready;
+ con->rx_action = receive_from_sock;
+ con->connect_action = sctp_init_assoc;
+
+ /* Bind to all interfaces. */
+ for (i = 0; i < dlm_local_count; i++) {
+ memcpy(&localaddr, dlm_local_addr[i], sizeof(localaddr));
+ make_sockaddr(&localaddr, dlm_config.ci_tcp_port, &addr_len);
+
+ result = add_sctp_bind_addr(con, &localaddr, addr_len, num);
+ if (result)
+ goto create_delsock;
+ ++num;
+ }
+
+ result = sock->ops->listen(sock, 5);
+ if (result < 0) {
+ log_print("Can't set socket listening");
+ goto create_delsock;
+ }
+
+ return 0;
+
+create_delsock:
+ sock_release(sock);
+ con->sock = NULL;
+out:
+ return result;
+}
+
+static int tcp_listen_for_all(void)
{
struct socket *sock = NULL;
struct connection *con = nodeid2con(0, GFP_KERNEL);
int result = -EINVAL;
+ if (!con)
+ return -ENOMEM;
+
/* We don't support multi-homed hosts */
+ if (dlm_local_addr[1] != NULL) {
+ log_print("TCP protocol can't handle multi-homed hosts, "
+ "try SCTP");
+ return -EINVAL;
+ }
+
+ log_print("Using TCP for communications");
+
set_bit(CF_IS_OTHERCON, &con->flags);
- sock = create_listen_sock(con, &dlm_local_addr);
+ sock = tcp_create_listen_sock(con, dlm_local_addr[0]);
if (sock) {
add_sock(sock, con);
result = 0;
@@ -666,8 +1156,7 @@ static struct writequeue_entry *new_writequeue_entry(struct connection *con,
return entry;
}
-void *dlm_lowcomms_get_buffer(int nodeid, int len,
- gfp_t allocation, char **ppc)
+void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc)
{
struct connection *con;
struct writequeue_entry *e;
@@ -735,12 +1224,6 @@ out:
return;
}
-static void free_entry(struct writequeue_entry *e)
-{
- __free_page(e->page);
- kfree(e);
-}
-
/* Send a message */
static void send_to_sock(struct connection *con)
{
@@ -777,8 +1260,7 @@ static void send_to_sock(struct connection *con)
goto out;
if (ret <= 0)
goto send_error;
- }
- else {
+ } else {
/* Don't starve people filling buffers */
cond_resched();
}
@@ -807,7 +1289,8 @@ send_error:
out_connect:
mutex_unlock(&con->sock_mutex);
- connect_to_sock(con);
+ if (!test_bit(CF_INIT_PENDING, &con->flags))
+ lowcomms_connect_sock(con);
return;
}
@@ -832,9 +1315,6 @@ int dlm_lowcomms_close(int nodeid)
{
struct connection *con;
- if (!connections)
- goto out;
-
log_print("closing connection to node %d", nodeid);
con = nodeid2con(nodeid, 0);
if (con) {
@@ -842,12 +1322,9 @@ int dlm_lowcomms_close(int nodeid)
close_connection(con, true);
}
return 0;
-
-out:
- return -1;
}
-/* Look for activity on active sockets */
+/* Receive workqueue function */
static void process_recv_sockets(struct work_struct *work)
{
struct connection *con = container_of(work, struct connection, rwork);
@@ -859,15 +1336,14 @@ static void process_recv_sockets(struct work_struct *work)
} while (!err);
}
-
+/* Send workqueue function */
static void process_send_sockets(struct work_struct *work)
{
struct connection *con = container_of(work, struct connection, swork);
if (test_and_clear_bit(CF_CONNECT_PENDING, &con->flags)) {
- connect_to_sock(con);
+ con->connect_action(con);
}
-
clear_bit(CF_WRITE_PENDING, &con->flags);
send_to_sock(con);
}
@@ -878,8 +1354,8 @@ static void clean_writequeues(void)
{
int nodeid;
- for (nodeid = 1; nodeid < conn_array_size; nodeid++) {
- struct connection *con = nodeid2con(nodeid, 0);
+ for (nodeid = 1; nodeid <= max_nodeid; nodeid++) {
+ struct connection *con = __nodeid2con(nodeid, 0);
if (con)
clean_one_writequeue(con);
@@ -916,64 +1392,67 @@ static int work_start(void)
void dlm_lowcomms_stop(void)
{
int i;
+ struct connection *con;
/* Set all the flags to prevent any
socket activity.
*/
- for (i = 0; i < conn_array_size; i++) {
- if (connections[i])
- connections[i]->flags |= 0xFF;
+ down(&connections_lock);
+ for (i = 0; i <= max_nodeid; i++) {
+ con = __nodeid2con(i, 0);
+ if (con)
+ con->flags |= 0xFF;
}
+ up(&connections_lock);
work_stop();
+
+ down(&connections_lock);
clean_writequeues();
- for (i = 0; i < conn_array_size; i++) {
- if (connections[i]) {
- close_connection(connections[i], true);
- if (connections[i]->othercon)
- kmem_cache_free(con_cache, connections[i]->othercon);
- kmem_cache_free(con_cache, connections[i]);
+ for (i = 0; i <= max_nodeid; i++) {
+ con = __nodeid2con(i, 0);
+ if (con) {
+ close_connection(con, true);
+ if (con->othercon)
+ kmem_cache_free(con_cache, con->othercon);
+ kmem_cache_free(con_cache, con);
}
}
-
- kfree(connections);
- connections = NULL;
-
+ max_nodeid = 0;
+ up(&connections_lock);
kmem_cache_destroy(con_cache);
+ idr_init(&connections_idr);
}
-/* This is quite likely to sleep... */
int dlm_lowcomms_start(void)
{
- int error = 0;
-
- error = -ENOMEM;
- connections = kzalloc(sizeof(struct connection *) *
- NODE_INCREMENT, GFP_KERNEL);
- if (!connections)
- goto out;
-
- conn_array_size = NODE_INCREMENT;
+ int error = -EINVAL;
+ struct connection *con;
- if (dlm_our_addr(&dlm_local_addr, 0)) {
+ init_local();
+ if (!dlm_local_count) {
+ error = -ENOTCONN;
log_print("no local IP address has been set");
- goto fail_free_conn;
- }
- if (!dlm_our_addr(&dlm_local_addr, 1)) {
- log_print("This dlm comms module does not support multi-homed clustering");
- goto fail_free_conn;
+ goto out;
}
+ error = -ENOMEM;
con_cache = kmem_cache_create("dlm_conn", sizeof(struct connection),
__alignof__(struct connection), 0,
NULL, NULL);
if (!con_cache)
- goto fail_free_conn;
+ goto out;
+ /* Set some sysctl minima */
+ if (sysctl_rmem_max < NEEDED_RMEM)
+ sysctl_rmem_max = NEEDED_RMEM;
/* Start listening */
- error = listen_for_all();
+ if (dlm_config.ci_protocol == 0)
+ error = tcp_listen_for_all();
+ else
+ error = sctp_listen_for_all();
if (error)
goto fail_unlisten;
@@ -984,24 +1463,13 @@ int dlm_lowcomms_start(void)
return 0;
fail_unlisten:
- close_connection(connections[0], false);
- kmem_cache_free(con_cache, connections[0]);
+ con = nodeid2con(0,0);
+ if (con) {
+ close_connection(con, false);
+ kmem_cache_free(con_cache, con);
+ }
kmem_cache_destroy(con_cache);
-fail_free_conn:
- kfree(connections);
-
out:
return error;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 3870150..b0201ec 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2006-2007 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
@@ -56,6 +56,7 @@ struct dlm_write_request32 {
union {
struct dlm_lock_params32 lock;
struct dlm_lspace_params lspace;
+ struct dlm_purge_params purge;
} i;
};
@@ -92,6 +93,9 @@ static void compat_input(struct dlm_write_request *kb,
kb->i.lspace.flags = kb32->i.lspace.flags;
kb->i.lspace.minor = kb32->i.lspace.minor;
strcpy(kb->i.lspace.name, kb32->i.lspace.name);
+ } else if (kb->cmd == DLM_USER_PURGE) {
+ kb->i.purge.nodeid = kb32->i.purge.nodeid;
+ kb->i.purge.pid = kb32->i.purge.pid;
} else {
kb->i.lock.mode = kb32->i.lock.mode;
kb->i.lock.namelen = kb32->i.lock.namelen;
@@ -111,8 +115,6 @@ static void compat_input(struct dlm_write_request *kb,
static void compat_output(struct dlm_lock_result *res,
struct dlm_lock_result32 *res32)
{
- res32->length = res->length - (sizeof(struct dlm_lock_result) -
- sizeof(struct dlm_lock_result32));
res32->user_astaddr = (__u32)(long)res->user_astaddr;
res32->user_astparam = (__u32)(long)res->user_astparam;
res32->user_lksb = (__u32)(long)res->user_lksb;
@@ -128,35 +130,30 @@ static void compat_output(struct dlm_lock_result *res,
}
#endif
+/* we could possibly check if the cancel of an orphan has resulted in the lkb
+ being removed and then remove that lkb from the orphans list and free it */
void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
{
struct dlm_ls *ls;
struct dlm_user_args *ua;
struct dlm_user_proc *proc;
- int remove_ownqueue = 0;
+ int eol = 0, ast_type;
- /* dlm_clear_proc_locks() sets ORPHAN/DEAD flag on each
- lkb before dealing with it. We need to check this
- flag before taking ls_clear_proc_locks mutex because if
- it's set, dlm_clear_proc_locks() holds the mutex. */
-
- if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD)) {
- /* log_print("user_add_ast skip1 %x", lkb->lkb_flags); */
+ if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD))
return;
- }
ls = lkb->lkb_resource->res_ls;
mutex_lock(&ls->ls_clear_proc_locks);
/* If ORPHAN/DEAD flag is set, it means the process is dead so an ast
can't be delivered. For ORPHAN's, dlm_clear_proc_locks() freed
- lkb->ua so we can't try to use it. */
+ lkb->ua so we can't try to use it. This second check is necessary
+ for cases where a completion ast is received for an operation that
+ began before clear_proc_locks did its cancel/unlock. */
- if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD)) {
- /* log_print("user_add_ast skip2 %x", lkb->lkb_flags); */
+ if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD))
goto out;
- }
DLM_ASSERT(lkb->lkb_astparam, dlm_print_lkb(lkb););
ua = (struct dlm_user_args *)lkb->lkb_astparam;
@@ -166,28 +163,42 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
goto out;
spin_lock(&proc->asts_spin);
- if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) {
+
+ ast_type = lkb->lkb_ast_type;
+ lkb->lkb_ast_type |= type;
+
+ if (!ast_type) {
kref_get(&lkb->lkb_ref);
list_add_tail(&lkb->lkb_astqueue, &proc->asts);
- lkb->lkb_ast_type |= type;
wake_up_interruptible(&proc->wait);
}
-
- /* noqueue requests that fail may need to be removed from the
- proc's locks list, there should be a better way of detecting
- this situation than checking all these things... */
-
- if (type == AST_COMP && lkb->lkb_grmode == DLM_LOCK_IV &&
- ua->lksb.sb_status == -EAGAIN && !list_empty(&lkb->lkb_ownqueue))
- remove_ownqueue = 1;
-
- /* unlocks or cancels of waiting requests need to be removed from the
- proc's unlocking list, again there must be a better way... */
-
- if (ua->lksb.sb_status == -DLM_EUNLOCK ||
+ if (type == AST_COMP && (ast_type & AST_COMP))
+ log_debug(ls, "ast overlap %x status %x %x",
+ lkb->lkb_id, ua->lksb.sb_status, lkb->lkb_flags);
+
+ /* Figure out if this lock is at the end of its life and no longer
+ available for the application to use. The lkb still exists until
+ the final ast is read. A lock becomes EOL in three situations:
+ 1. a noqueue request fails with EAGAIN
+ 2. an unlock completes with EUNLOCK
+ 3. a cancel of a waiting request completes with ECANCEL
+ An EOL lock needs to be removed from the process's list of locks.
+ And we can't allow any new operation on an EOL lock. This is
+ not related to the lifetime of the lkb struct which is managed
+ entirely by refcount. */
+
+ if (type == AST_COMP &&
+ lkb->lkb_grmode == DLM_LOCK_IV &&
+ ua->lksb.sb_status == -EAGAIN)
+ eol = 1;
+ else if (ua->lksb.sb_status == -DLM_EUNLOCK ||
(ua->lksb.sb_status == -DLM_ECANCEL &&
lkb->lkb_grmode == DLM_LOCK_IV))
- remove_ownqueue = 1;
+ eol = 1;
+ if (eol) {
+ lkb->lkb_ast_type &= ~AST_BAST;
+ lkb->lkb_flags |= DLM_IFL_ENDOFLIFE;
+ }
/* We want to copy the lvb to userspace when the completion
ast is read if the status is 0, the lock has an lvb and
@@ -204,11 +215,13 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
spin_unlock(&proc->asts_spin);
- if (remove_ownqueue) {
+ if (eol) {
spin_lock(&ua->proc->locks_spin);
- list_del_init(&lkb->lkb_ownqueue);
+ if (!list_empty(&lkb->lkb_ownqueue)) {
+ list_del_init(&lkb->lkb_ownqueue);
+ dlm_put_lkb(lkb);
+ }
spin_unlock(&ua->proc->locks_spin);
- dlm_put_lkb(lkb);
}
out:
mutex_unlock(&ls->ls_clear_proc_locks);
@@ -286,47 +299,71 @@ static int device_user_unlock(struct dlm_user_proc *proc,
return error;
}
-static int device_create_lockspace(struct dlm_lspace_params *params)
+static int create_misc_device(struct dlm_ls *ls, char *name)
{
- dlm_lockspace_t *lockspace;
- struct dlm_ls *ls;
int error, len;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- error = dlm_new_lockspace(params->name, strlen(params->name),
- &lockspace, 0, DLM_USER_LVB_LEN);
- if (error)
- return error;
-
- ls = dlm_find_lockspace_local(lockspace);
- if (!ls)
- return -ENOENT;
-
error = -ENOMEM;
- len = strlen(params->name) + strlen(name_prefix) + 2;
+ len = strlen(name) + strlen(name_prefix) + 2;
ls->ls_device.name = kzalloc(len, GFP_KERNEL);
if (!ls->ls_device.name)
goto fail;
+
snprintf((char *)ls->ls_device.name, len, "%s_%s", name_prefix,
- params->name);
+ name);
ls->ls_device.fops = &device_fops;
ls->ls_device.minor = MISC_DYNAMIC_MINOR;
error = misc_register(&ls->ls_device);
if (error) {
kfree(ls->ls_device.name);
- goto fail;
}
+fail:
+ return error;
+}
+
+static int device_user_purge(struct dlm_user_proc *proc,
+ struct dlm_purge_params *params)
+{
+ struct dlm_ls *ls;
+ int error;
+
+ ls = dlm_find_lockspace_local(proc->lockspace);
+ if (!ls)
+ return -ENOENT;
+
+ error = dlm_user_purge(ls, proc, params->nodeid, params->pid);
- error = ls->ls_device.minor;
dlm_put_lockspace(ls);
return error;
+}
+
+static int device_create_lockspace(struct dlm_lspace_params *params)
+{
+ dlm_lockspace_t *lockspace;
+ struct dlm_ls *ls;
+ int error;
- fail:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ error = dlm_new_lockspace(params->name, strlen(params->name),
+ &lockspace, 0, DLM_USER_LVB_LEN);
+ if (error)
+ return error;
+
+ ls = dlm_find_lockspace_local(lockspace);
+ if (!ls)
+ return -ENOENT;
+
+ error = create_misc_device(ls, params->name);
dlm_put_lockspace(ls);
- dlm_release_lockspace(lockspace, 0);
+
+ if (error)
+ dlm_release_lockspace(lockspace, 0);
+ else
+ error = ls->ls_device.minor;
+
return error;
}
@@ -343,6 +380,10 @@ static int device_remove_lockspace(struct dlm_lspace_params *params)
if (!ls)
return -ENOENT;
+ /* Deregister the misc device first, so we don't have
+ * a device that's not attached to a lockspace. If
+ * dlm_release_lockspace fails then we can recreate it
+ */
error = misc_deregister(&ls->ls_device);
if (error) {
dlm_put_lockspace(ls);
@@ -361,6 +402,8 @@ static int device_remove_lockspace(struct dlm_lspace_params *params)
dlm_put_lockspace(ls);
error = dlm_release_lockspace(lockspace, force);
+ if (error)
+ create_misc_device(ls, ls->ls_name);
out:
return error;
}
@@ -497,6 +540,14 @@ static ssize_t device_write(struct file *file, const char __user *buf,
error = device_remove_lockspace(&kbuf->i.lspace);
break;
+ case DLM_USER_PURGE:
+ if (!proc) {
+ log_print("no locking on control device");
+ goto out_sig;
+ }
+ error = device_user_purge(proc, &kbuf->i.purge);
+ break;
+
default:
log_print("Unknown command passed to DLM device : %d\n",
kbuf->cmd);
diff --git a/fs/dquot.c b/fs/dquot.c
index b16f991..3a99584 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -69,7 +69,6 @@
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
@@ -475,7 +474,7 @@ int vfs_quota_sync(struct super_block *sb, int type)
spin_lock(&dq_list_lock);
dirty = &dqopt->info[cnt].dqi_dirty_list;
while (!list_empty(dirty)) {
- dquot = list_entry(dirty->next, struct dquot, dq_dirty);
+ dquot = list_first_entry(dirty, struct dquot, dq_dirty);
/* Dirty and inactive can be only bad dquot... */
if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
clear_dquot_dirty(dquot);
@@ -721,7 +720,8 @@ static inline int dqput_blocks(struct dquot *dquot)
/* Remove references to dquots from inode - add dquot to list for freeing if needed */
/* We can't race with anybody because we hold dqptr_sem for writing... */
-int remove_inode_dquot_ref(struct inode *inode, int type, struct list_head *tofree_head)
+static int remove_inode_dquot_ref(struct inode *inode, int type,
+ struct list_head *tofree_head)
{
struct dquot *dquot = inode->i_dquot[type];
@@ -1432,7 +1432,7 @@ int vfs_quota_off(struct super_block *sb, int type)
mutex_unlock(&dqopt->dqonoff_mutex);
}
if (sb->s_bdev)
- invalidate_bdev(sb->s_bdev, 0);
+ invalidate_bdev(sb->s_bdev);
return 0;
}
@@ -1468,7 +1468,7 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id)
* we see all the changes from userspace... */
write_inode_now(inode, 1);
/* And now flush the block cache so that kernel sees the changes */
- invalidate_bdev(sb->s_bdev, 0);
+ invalidate_bdev(sb->s_bdev);
mutex_lock(&inode->i_mutex);
mutex_lock(&dqopt->dqonoff_mutex);
if (sb_has_quota_enabled(sb, type)) {
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 7a7d25d..9881b5c 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -28,7 +28,6 @@
#include <linux/mount.h>
#include <linux/pagemap.h>
#include <linux/security.h>
-#include <linux/smp_lock.h>
#include <linux/compat.h>
#include <linux/fs_stack.h>
#include "ecryptfs_kernel.h"
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 6acc8f4..8cbf3f6 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -583,8 +583,7 @@ inode_info_init_once(void *vptr, struct kmem_cache *cachep, unsigned long flags)
{
struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr;
- if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&ei->vfs_inode);
}
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index b731b09..0770c4b 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -46,7 +46,6 @@ struct kmem_cache *ecryptfs_lower_page_cache;
*/
static struct page *ecryptfs_get1page(struct file *file, int index)
{
- struct page *page;
struct dentry *dentry;
struct inode *inode;
struct address_space *mapping;
@@ -54,14 +53,7 @@ static struct page *ecryptfs_get1page(struct file *file, int index)
dentry = file->f_path.dentry;
inode = dentry->d_inode;
mapping = inode->i_mapping;
- page = read_cache_page(mapping, index,
- (filler_t *)mapping->a_ops->readpage,
- (void *)file);
- if (IS_ERR(page))
- goto out;
- wait_on_page_locked(page);
-out:
- return page;
+ return read_mapping_page(mapping, index, (void *)file);
}
static
@@ -233,7 +225,6 @@ int ecryptfs_do_readpage(struct file *file, struct page *page,
ecryptfs_printk(KERN_ERR, "Error reading from page cache\n");
goto out;
}
- wait_on_page_locked(lower_page);
page_data = kmap_atomic(page, KM_USER0);
lower_page_data = kmap_atomic(lower_page, KM_USER1);
memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE);
diff --git a/fs/efs/super.c b/fs/efs/super.c
index c2235e4..ba7a8b9 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -72,8 +72,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct efs_inode_info *ei = (struct efs_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&ei->vfs_inode);
}
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 3ae644e..b5c7ca5 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -22,7 +22,6 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/hash.h>
@@ -185,7 +184,7 @@ struct eppoll_entry {
/*
* Each file descriptor added to the eventpoll interface will
- * have an entry of this type linked to the hash.
+ * have an entry of this type linked to the "rbr" RB tree.
*/
struct epitem {
/* RB-Tree node used to link this structure to the eventpoll rb-tree */
@@ -217,15 +216,6 @@ struct epitem {
/* List header used to link this item to the "struct file" items list */
struct list_head fllink;
-
- /* List header used to link the item to the transfer list */
- struct list_head txlink;
-
- /*
- * This is used during the collection/transfer of events to userspace
- * to pin items empty events set.
- */
- unsigned int revents;
};
/* Wrapper struct used by poll queueing */
@@ -258,11 +248,8 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi);
static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *key);
static int ep_eventpoll_close(struct inode *inode, struct file *file);
static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait);
-static int ep_collect_ready_items(struct eventpoll *ep,
- struct list_head *txlist, int maxevents);
static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
- struct epoll_event __user *events);
-static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist);
+ struct epoll_event __user *events, int maxevents);
static int ep_events_transfer(struct eventpoll *ep,
struct epoll_event __user *events,
int maxevents);
@@ -355,17 +342,6 @@ static inline int ep_rb_linked(struct rb_node *n)
return rb_parent(n) != n;
}
-/*
- * Remove the item from the list and perform its initialization.
- * This is useful for us because we can test if the item is linked
- * using "ep_is_linked(p)".
- */
-static inline void ep_list_del(struct list_head *p)
-{
- list_del(p);
- INIT_LIST_HEAD(p);
-}
-
/* Tells us if the item is currently linked */
static inline int ep_is_linked(struct list_head *p)
{
@@ -385,7 +361,7 @@ static inline struct epitem * ep_item_from_epqueue(poll_table *p)
}
/* Tells if the epoll_ctl(2) operation needs an event copy from userspace */
-static inline int ep_op_hash_event(int op)
+static inline int ep_op_has_event(int op)
{
return op != EPOLL_CTL_DEL;
}
@@ -477,10 +453,10 @@ void eventpoll_release_file(struct file *file)
mutex_lock(&epmutex);
while (!list_empty(lsthead)) {
- epi = list_entry(lsthead->next, struct epitem, fllink);
+ epi = list_first_entry(lsthead, struct epitem, fllink);
ep = epi->ep;
- ep_list_del(&epi->fllink);
+ list_del_init(&epi->fllink);
down_write(&ep->sem);
ep_remove(ep, epi);
up_write(&ep->sem);
@@ -557,7 +533,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event)
current, epfd, op, fd, event));
error = -EFAULT;
- if (ep_op_hash_event(op) &&
+ if (ep_op_has_event(op) &&
copy_from_user(&epds, event, sizeof(struct epoll_event)))
goto eexit_1;
@@ -594,7 +570,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event)
down_write(&ep->sem);
- /* Try to lookup the file inside our hash table */
+ /* Try to lookup the file inside our RB tree */
epi = ep_find(ep, tfile, fd);
error = -EINVAL;
@@ -876,7 +852,7 @@ static void ep_free(struct eventpoll *ep)
}
/*
- * Walks through the whole hash by freeing each "struct epitem". At this
+ * Walks through the whole tree by freeing each "struct epitem". At this
* point we are sure no poll callbacks will be lingering around, and also by
* write-holding "sem" we can be sure that no file cleanup code will hit
* us during this operation. So we can avoid the lock on "ep->lock".
@@ -891,7 +867,7 @@ static void ep_free(struct eventpoll *ep)
/*
- * Search the file inside the eventpoll hash. It add usage count to
+ * Search the file inside the eventpoll tree. It add usage count to
* the returned item, so the caller must call ep_release_epitem()
* after finished using the "struct epitem".
*/
@@ -1011,7 +987,6 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
ep_rb_initnode(&epi->rbn);
INIT_LIST_HEAD(&epi->rdllink);
INIT_LIST_HEAD(&epi->fllink);
- INIT_LIST_HEAD(&epi->txlink);
INIT_LIST_HEAD(&epi->pwqlist);
epi->ep = ep;
ep_set_ffd(&epi->ffd, tfile, fd);
@@ -1080,7 +1055,7 @@ eexit_2:
*/
write_lock_irqsave(&ep->lock, flags);
if (ep_is_linked(&epi->rdllink))
- ep_list_del(&epi->rdllink);
+ list_del_init(&epi->rdllink);
write_unlock_irqrestore(&ep->lock, flags);
kmem_cache_free(epi_cache, epi);
@@ -1119,7 +1094,7 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even
epi->event.data = event->data;
/*
- * If the item is not linked to the hash it means that it's on its
+ * If the item is not linked to the RB tree it means that it's on its
* way toward the removal. Do nothing in this case.
*/
if (ep_rb_linked(&epi->rbn)) {
@@ -1168,9 +1143,9 @@ static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi)
if (nwait) {
while (!list_empty(lsthead)) {
- pwq = list_entry(lsthead->next, struct eppoll_entry, llink);
+ pwq = list_first_entry(lsthead, struct eppoll_entry, llink);
- ep_list_del(&pwq->llink);
+ list_del_init(&pwq->llink);
remove_wait_queue(pwq->whead, &pwq->wait);
kmem_cache_free(pwq_cache, pwq);
}
@@ -1213,7 +1188,7 @@ static int ep_unlink(struct eventpoll *ep, struct epitem *epi)
* we want to remove it from this list to avoid stale events.
*/
if (ep_is_linked(&epi->rdllink))
- ep_list_del(&epi->rdllink);
+ list_del_init(&epi->rdllink);
error = 0;
eexit_1:
@@ -1226,7 +1201,7 @@ eexit_1:
/*
- * Removes a "struct epitem" from the eventpoll hash and deallocates
+ * Removes a "struct epitem" from the eventpoll RB tree and deallocates
* all the associated resources.
*/
static int ep_remove(struct eventpoll *ep, struct epitem *epi)
@@ -1248,13 +1223,13 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi)
/* Remove the current item from the list of epoll hooks */
spin_lock(&file->f_ep_lock);
if (ep_is_linked(&epi->fllink))
- ep_list_del(&epi->fllink);
+ list_del_init(&epi->fllink);
spin_unlock(&file->f_ep_lock);
/* We need to acquire the write IRQ lock before calling ep_unlink() */
write_lock_irqsave(&ep->lock, flags);
- /* Really unlink the item from the hash */
+ /* Really unlink the item from the RB tree */
error = ep_unlink(ep, epi);
write_unlock_irqrestore(&ep->lock, flags);
@@ -1362,71 +1337,30 @@ static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait)
/*
- * Since we have to release the lock during the __copy_to_user() operation and
- * during the f_op->poll() call, we try to collect the maximum number of items
- * by reducing the irqlock/irqunlock switching rate.
- */
-static int ep_collect_ready_items(struct eventpoll *ep, struct list_head *txlist, int maxevents)
-{
- int nepi;
- unsigned long flags;
- struct list_head *lsthead = &ep->rdllist, *lnk;
- struct epitem *epi;
-
- write_lock_irqsave(&ep->lock, flags);
-
- for (nepi = 0, lnk = lsthead->next; lnk != lsthead && nepi < maxevents;) {
- epi = list_entry(lnk, struct epitem, rdllink);
-
- lnk = lnk->next;
-
- /* If this file is already in the ready list we exit soon */
- if (!ep_is_linked(&epi->txlink)) {
- /*
- * This is initialized in this way so that the default
- * behaviour of the reinjecting code will be to push back
- * the item inside the ready list.
- */
- epi->revents = epi->event.events;
-
- /* Link the ready item into the transfer list */
- list_add(&epi->txlink, txlist);
- nepi++;
-
- /*
- * Unlink the item from the ready list.
- */
- ep_list_del(&epi->rdllink);
- }
- }
-
- write_unlock_irqrestore(&ep->lock, flags);
-
- return nepi;
-}
-
-
-/*
* This function is called without holding the "ep->lock" since the call to
* __copy_to_user() might sleep, and also f_op->poll() might reenable the IRQ
* because of the way poll() is traditionally implemented in Linux.
*/
static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
- struct epoll_event __user *events)
+ struct epoll_event __user *events, int maxevents)
{
- int eventcnt = 0;
+ int eventcnt, error = -EFAULT, pwake = 0;
unsigned int revents;
- struct list_head *lnk;
+ unsigned long flags;
struct epitem *epi;
+ struct list_head injlist;
+
+ INIT_LIST_HEAD(&injlist);
/*
* We can loop without lock because this is a task private list.
- * The test done during the collection loop will guarantee us that
- * another task will not try to collect this file. Also, items
- * cannot vanish during the loop because we are holding "sem".
+ * We just splice'd out the ep->rdllist in ep_collect_ready_items().
+ * Items cannot vanish during the loop because we are holding "sem" in
+ * read.
*/
- list_for_each(lnk, txlist) {
- epi = list_entry(lnk, struct epitem, txlink);
+ for (eventcnt = 0; !list_empty(txlist) && eventcnt < maxevents;) {
+ epi = list_first_entry(txlist, struct epitem, rdllink);
+ prefetch(epi->rdllink.next);
/*
* Get the ready file event set. We can safely use the file
@@ -1434,64 +1368,65 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
* guarantee that both the file and the item will not vanish.
*/
revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL);
+ revents &= epi->event.events;
/*
- * Set the return event set for the current file descriptor.
- * Note that only the task task was successfully able to link
- * the item to its "txlist" will write this field.
+ * Is the event mask intersect the caller-requested one,
+ * deliver the event to userspace. Again, we are holding
+ * "sem" in read, so no operations coming from userspace
+ * can change the item.
*/
- epi->revents = revents & epi->event.events;
-
- if (epi->revents) {
- if (__put_user(epi->revents,
+ if (revents) {
+ if (__put_user(revents,
&events[eventcnt].events) ||
__put_user(epi->event.data,
&events[eventcnt].data))
- return -EFAULT;
+ goto errxit;
if (epi->event.events & EPOLLONESHOT)
epi->event.events &= EP_PRIVATE_BITS;
eventcnt++;
}
- }
- return eventcnt;
-}
-
-
-/*
- * Walk through the transfer list we collected with ep_collect_ready_items()
- * and, if 1) the item is still "alive" 2) its event set is not empty 3) it's
- * not already linked, links it to the ready list. Same as above, we are holding
- * "sem" so items cannot vanish underneath our nose.
- */
-static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
-{
- int ricnt = 0, pwake = 0;
- unsigned long flags;
- struct epitem *epi;
-
- write_lock_irqsave(&ep->lock, flags);
-
- while (!list_empty(txlist)) {
- epi = list_entry(txlist->next, struct epitem, txlink);
-
- /* Unlink the current item from the transfer list */
- ep_list_del(&epi->txlink);
/*
- * If the item is no more linked to the interest set, we don't
- * have to push it inside the ready list because the following
- * ep_release_epitem() is going to drop it. Also, if the current
- * item is set to have an Edge Triggered behaviour, we don't have
- * to push it back either.
+ * This is tricky. We are holding the "sem" in read, and this
+ * means that the operations that can change the "linked" status
+ * of the epoll item (epi->rbn and epi->rdllink), cannot touch
+ * them. Also, since we are "linked" from a epi->rdllink POV
+ * (the item is linked to our transmission list we just
+ * spliced), the ep_poll_callback() cannot touch us either,
+ * because of the check present in there. Another parallel
+ * epoll_wait() will not get the same result set, since we
+ * spliced the ready list before. Note that list_del() still
+ * shows the item as linked to the test in ep_poll_callback().
*/
- if (ep_rb_linked(&epi->rbn) && !(epi->event.events & EPOLLET) &&
- (epi->revents & epi->event.events) && !ep_is_linked(&epi->rdllink)) {
- list_add_tail(&epi->rdllink, &ep->rdllist);
- ricnt++;
+ list_del(&epi->rdllink);
+ if (!(epi->event.events & EPOLLET) &&
+ (revents & epi->event.events))
+ list_add_tail(&epi->rdllink, &injlist);
+ else {
+ /*
+ * Be sure the item is totally detached before re-init
+ * the list_head. After INIT_LIST_HEAD() is committed,
+ * the ep_poll_callback() can requeue the item again,
+ * but we don't care since we are already past it.
+ */
+ smp_mb();
+ INIT_LIST_HEAD(&epi->rdllink);
}
}
+ error = 0;
- if (ricnt) {
+ errxit:
+
+ /*
+ * If the re-injection list or the txlist are not empty, re-splice
+ * them to the ready list and do proper wakeups.
+ */
+ if (!list_empty(&injlist) || !list_empty(txlist)) {
+ write_lock_irqsave(&ep->lock, flags);
+
+ list_splice(txlist, &ep->rdllist);
+ list_splice(&injlist, &ep->rdllist);
/*
* Wake up ( if active ) both the eventpoll wait list and the ->poll()
* wait list.
@@ -1501,13 +1436,15 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
TASK_INTERRUPTIBLE);
if (waitqueue_active(&ep->poll_wait))
pwake++;
- }
- write_unlock_irqrestore(&ep->lock, flags);
+ write_unlock_irqrestore(&ep->lock, flags);
+ }
/* We have to call this outside the lock */
if (pwake)
ep_poll_safewake(&psw, &ep->poll_wait);
+
+ return eventcnt == 0 ? error: eventcnt;
}
@@ -1517,7 +1454,8 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
static int ep_events_transfer(struct eventpoll *ep,
struct epoll_event __user *events, int maxevents)
{
- int eventcnt = 0;
+ int eventcnt;
+ unsigned long flags;
struct list_head txlist;
INIT_LIST_HEAD(&txlist);
@@ -1528,14 +1466,17 @@ static int ep_events_transfer(struct eventpoll *ep,
*/
down_read(&ep->sem);
- /* Collect/extract ready items */
- if (ep_collect_ready_items(ep, &txlist, maxevents) > 0) {
- /* Build result set in userspace */
- eventcnt = ep_send_events(ep, &txlist, events);
+ /*
+ * Steal the ready list, and re-init the original one to the
+ * empty list.
+ */
+ write_lock_irqsave(&ep->lock, flags);
+ list_splice(&ep->rdllist, &txlist);
+ INIT_LIST_HEAD(&ep->rdllist);
+ write_unlock_irqrestore(&ep->lock, flags);
- /* Reinject ready items into the ready list */
- ep_reinject_items(ep, &txlist);
- }
+ /* Build result set in userspace */
+ eventcnt = ep_send_events(ep, &txlist, events, maxevents);
up_read(&ep->sem);
@@ -1612,14 +1553,12 @@ retry:
return res;
}
-
static int eventpollfs_delete_dentry(struct dentry *dentry)
{
return 1;
}
-
static struct inode *ep_eventpoll_inode(void)
{
int error = -ENOMEM;
@@ -1647,7 +1586,6 @@ eexit_1:
return ERR_PTR(error);
}
-
static int
eventpollfs_get_sb(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data, struct vfsmount *mnt)
diff --git a/fs/exec.c b/fs/exec.c
index 3155e91..1ba85c7 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -100,6 +100,7 @@ int unregister_binfmt(struct linux_binfmt * fmt)
while (*tmp) {
if (fmt == *tmp) {
*tmp = fmt->next;
+ fmt->next = NULL;
write_unlock(&binfmt_lock);
return 0;
}
@@ -982,33 +983,51 @@ void compute_creds(struct linux_binprm *bprm)
task_unlock(current);
security_bprm_post_apply_creds(bprm);
}
-
EXPORT_SYMBOL(compute_creds);
+/*
+ * Arguments are '\0' separated strings found at the location bprm->p
+ * points to; chop off the first by relocating brpm->p to right after
+ * the first '\0' encountered.
+ */
void remove_arg_zero(struct linux_binprm *bprm)
{
if (bprm->argc) {
- unsigned long offset;
- char * kaddr;
- struct page *page;
+ char ch;
- offset = bprm->p % PAGE_SIZE;
- goto inside;
+ do {
+ unsigned long offset;
+ unsigned long index;
+ char *kaddr;
+ struct page *page;
- while (bprm->p++, *(kaddr+offset++)) {
- if (offset != PAGE_SIZE)
- continue;
- offset = 0;
- kunmap_atomic(kaddr, KM_USER0);
-inside:
- page = bprm->page[bprm->p/PAGE_SIZE];
+ offset = bprm->p & ~PAGE_MASK;
+ index = bprm->p >> PAGE_SHIFT;
+
+ page = bprm->page[index];
kaddr = kmap_atomic(page, KM_USER0);
- }
- kunmap_atomic(kaddr, KM_USER0);
+
+ /* run through page until we reach end or find NUL */
+ do {
+ ch = *(kaddr + offset);
+
+ /* discard that character... */
+ bprm->p++;
+ offset++;
+ } while (offset < PAGE_SIZE && ch != '\0');
+
+ kunmap_atomic(kaddr, KM_USER0);
+
+ /* free the old page */
+ if (offset == PAGE_SIZE) {
+ __free_page(page);
+ bprm->page[index] = NULL;
+ }
+ } while (ch != '\0');
+
bprm->argc--;
}
}
-
EXPORT_SYMBOL(remove_arg_zero);
/*
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 93e77c3..e98f6cd 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -2,7 +2,6 @@
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/namei.h>
struct export_operations export_op_default;
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index e89bfc8..2bf49d7 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -23,7 +23,6 @@
#include "ext2.h"
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
typedef struct ext2_dir_entry_2 ext2_dirent;
@@ -161,10 +160,7 @@ static struct page * ext2_get_page(struct inode *dir, unsigned long n)
struct address_space *mapping = dir->i_mapping;
struct page *page = read_mapping_page(mapping, n, NULL);
if (!IS_ERR(page)) {
- wait_on_page_locked(page);
kmap(page);
- if (!PageUptodate(page))
- goto fail;
if (!PageChecked(page))
ext2_check_page(page);
if (PageError(page))
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index e2a0ea5..9fd0ec5 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -133,6 +133,7 @@ extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int);
extern void ext2_truncate (struct inode *);
extern int ext2_setattr (struct dentry *, struct iattr *);
extern void ext2_set_inode_flags(struct inode *inode);
+extern void ext2_get_inode_flags(struct ext2_inode_info *);
/* ioctl.c */
extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
diff --git a/fs/ext2/fsync.c b/fs/ext2/fsync.c
index 7806b9e..fc66c93 100644
--- a/fs/ext2/fsync.c
+++ b/fs/ext2/fsync.c
@@ -23,7 +23,6 @@
*/
#include "ext2.h"
-#include <linux/smp_lock.h>
#include <linux/buffer_head.h> /* for sync_mapping_buffers() */
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index dd4e14c..0079b2c 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -1055,6 +1055,25 @@ void ext2_set_inode_flags(struct inode *inode)
inode->i_flags |= S_DIRSYNC;
}
+/* Propagate flags from i_flags to EXT2_I(inode)->i_flags */
+void ext2_get_inode_flags(struct ext2_inode_info *ei)
+{
+ unsigned int flags = ei->vfs_inode.i_flags;
+
+ ei->i_flags &= ~(EXT2_SYNC_FL|EXT2_APPEND_FL|
+ EXT2_IMMUTABLE_FL|EXT2_NOATIME_FL|EXT2_DIRSYNC_FL);
+ if (flags & S_SYNC)
+ ei->i_flags |= EXT2_SYNC_FL;
+ if (flags & S_APPEND)
+ ei->i_flags |= EXT2_APPEND_FL;
+ if (flags & S_IMMUTABLE)
+ ei->i_flags |= EXT2_IMMUTABLE_FL;
+ if (flags & S_NOATIME)
+ ei->i_flags |= EXT2_NOATIME_FL;
+ if (flags & S_DIRSYNC)
+ ei->i_flags |= EXT2_DIRSYNC_FL;
+}
+
void ext2_read_inode (struct inode * inode)
{
struct ext2_inode_info *ei = EXT2_I(inode);
@@ -1079,9 +1098,9 @@ void ext2_read_inode (struct inode * inode)
}
inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
inode->i_size = le32_to_cpu(raw_inode->i_size);
- inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
- inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime);
- inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime);
+ inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
+ inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime);
+ inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
inode->i_atime.tv_nsec = inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 0;
ei->i_dtime = le32_to_cpu(raw_inode->i_dtime);
/* We now have enough fields to check if the inode was active or not.
@@ -1188,6 +1207,7 @@ static int ext2_update_inode(struct inode * inode, int do_sync)
if (ei->i_state & EXT2_STATE_NEW)
memset(raw_inode, 0, EXT2_SB(sb)->s_inode_size);
+ ext2_get_inode_flags(ei);
raw_inode->i_mode = cpu_to_le16(inode->i_mode);
if (!(test_opt(sb, NO_UID32))) {
raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid));
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c
index 4b099d3..e85c482 100644
--- a/fs/ext2/ioctl.c
+++ b/fs/ext2/ioctl.c
@@ -27,6 +27,7 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
switch (cmd) {
case EXT2_IOC_GETFLAGS:
+ ext2_get_inode_flags(ei);
flags = ei->i_flags & EXT2_FL_USER_VISIBLE;
return put_user(flags, (int __user *) arg);
case EXT2_IOC_SETFLAGS: {
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index a046a41..685a1c2 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -160,8 +160,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct ext2_inode_info *ei = (struct ext2_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
rwlock_init(&ei->i_meta_lock);
#ifdef CONFIG_EXT2_FS_XATTR
init_rwsem(&ei->xattr_sem);
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c
index a266127..eaa23d2 100644
--- a/fs/ext2/xattr_security.c
+++ b/fs/ext2/xattr_security.c
@@ -6,7 +6,6 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext2_fs.h>
#include <linux/security.h>
#include "xattr.h"
diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c
index f28a6a4..83ee149 100644
--- a/fs/ext2/xattr_trusted.c
+++ b/fs/ext2/xattr_trusted.c
@@ -9,7 +9,6 @@
#include <linux/string.h>
#include <linux/capability.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext2_fs.h>
#include "xattr.h"
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index 665adee..8528698 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -25,7 +25,6 @@
#include <linux/jbd.h>
#include <linux/ext3_fs.h>
#include <linux/buffer_head.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/rbtree.h>
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index a5b150f..e1bb031 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -27,7 +27,6 @@
#include <linux/time.h>
#include <linux/ext3_jbd.h>
#include <linux/jbd.h>
-#include <linux/smp_lock.h>
#include <linux/highuid.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
@@ -2581,6 +2580,25 @@ void ext3_set_inode_flags(struct inode *inode)
inode->i_flags |= S_DIRSYNC;
}
+/* Propagate flags from i_flags to EXT3_I(inode)->i_flags */
+void ext3_get_inode_flags(struct ext3_inode_info *ei)
+{
+ unsigned int flags = ei->vfs_inode.i_flags;
+
+ ei->i_flags &= ~(EXT3_SYNC_FL|EXT3_APPEND_FL|
+ EXT3_IMMUTABLE_FL|EXT3_NOATIME_FL|EXT3_DIRSYNC_FL);
+ if (flags & S_SYNC)
+ ei->i_flags |= EXT3_SYNC_FL;
+ if (flags & S_APPEND)
+ ei->i_flags |= EXT3_APPEND_FL;
+ if (flags & S_IMMUTABLE)
+ ei->i_flags |= EXT3_IMMUTABLE_FL;
+ if (flags & S_NOATIME)
+ ei->i_flags |= EXT3_NOATIME_FL;
+ if (flags & S_DIRSYNC)
+ ei->i_flags |= EXT3_DIRSYNC_FL;
+}
+
void ext3_read_inode(struct inode * inode)
{
struct ext3_iloc iloc;
@@ -2608,9 +2626,9 @@ void ext3_read_inode(struct inode * inode)
}
inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
inode->i_size = le32_to_cpu(raw_inode->i_size);
- inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
- inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime);
- inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime);
+ inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
+ inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime);
+ inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0;
ei->i_state = 0;
@@ -2736,6 +2754,7 @@ static int ext3_do_update_inode(handle_t *handle,
if (ei->i_state & EXT3_STATE_NEW)
memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size);
+ ext3_get_inode_flags(ei);
raw_inode->i_mode = cpu_to_le16(inode->i_mode);
if(!(test_opt(inode->i_sb, NO_UID32))) {
raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
index 9b8090d..965006d 100644
--- a/fs/ext3/ioctl.c
+++ b/fs/ext3/ioctl.c
@@ -28,6 +28,7 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
switch (cmd) {
case EXT3_IOC_GETFLAGS:
+ ext3_get_inode_flags(ei);
flags = ei->i_flags & EXT3_FL_USER_VISIBLE;
return put_user(flags, (int __user *) arg);
case EXT3_IOC_SETFLAGS: {
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 49159f1..9bb046d 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -36,7 +36,6 @@
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
#include <linux/bio.h>
-#include <linux/smp_lock.h>
#include "namei.h"
#include "xattr.h"
@@ -969,6 +968,7 @@ static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry,
(block<<EXT3_BLOCK_SIZE_BITS(sb))
+((char *)de - bh->b_data))) {
brelse (bh);
+ *err = ERR_BAD_DX_DIR;
goto errout;
}
*res_dir = de;
@@ -1134,9 +1134,9 @@ static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
char *data1 = (*bh)->b_data, *data2;
unsigned split;
struct ext3_dir_entry_2 *de = NULL, *de2;
- int err;
+ int err = 0;
- bh2 = ext3_append (handle, dir, &newblock, error);
+ bh2 = ext3_append (handle, dir, &newblock, &err);
if (!(bh2)) {
brelse(*bh);
*bh = NULL;
@@ -1145,14 +1145,9 @@ static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
BUFFER_TRACE(*bh, "get_write_access");
err = ext3_journal_get_write_access(handle, *bh);
- if (err) {
- journal_error:
- brelse(*bh);
- brelse(bh2);
- *bh = NULL;
- ext3_std_error(dir->i_sb, err);
- goto errout;
- }
+ if (err)
+ goto journal_error;
+
BUFFER_TRACE(frame->bh, "get_write_access");
err = ext3_journal_get_write_access(handle, frame->bh);
if (err)
@@ -1195,8 +1190,16 @@ static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
goto journal_error;
brelse (bh2);
dxtrace(dx_show_index ("frame", frame->entries));
-errout:
return de;
+
+journal_error:
+ brelse(*bh);
+ brelse(bh2);
+ *bh = NULL;
+ ext3_std_error(dir->i_sb, err);
+errout:
+ *error = err;
+ return NULL;
}
#endif
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index ecf8990..2c97e09 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -11,7 +11,6 @@
#define EXT3FS_DEBUG
-#include <linux/smp_lock.h>
#include <linux/ext3_jbd.h>
#include <linux/errno.h>
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 4a4fcd6..54d3c90 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -420,7 +420,7 @@ static void ext3_put_super (struct super_block * sb)
dump_orphan_list(sb, sbi);
J_ASSERT(list_empty(&sbi->s_orphan));
- invalidate_bdev(sb->s_bdev, 0);
+ invalidate_bdev(sb->s_bdev);
if (sbi->journal_bdev && sbi->journal_bdev != sb->s_bdev) {
/*
* Invalidate the journal device's buffers. We don't want them
@@ -428,7 +428,7 @@ static void ext3_put_super (struct super_block * sb)
* hotswapped, and it breaks the `ro-after' testing code.
*/
sync_blockdev(sbi->journal_bdev);
- invalidate_bdev(sbi->journal_bdev, 0);
+ invalidate_bdev(sbi->journal_bdev);
ext3_blkdev_remove(sbi);
}
sb->s_fs_info = NULL;
@@ -466,8 +466,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct ext3_inode_info *ei = (struct ext3_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
INIT_LIST_HEAD(&ei->i_orphan);
#ifdef CONFIG_EXT3_FS_XATTR
init_rwsem(&ei->xattr_sem);
diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c
index b9c40c1..821efaf 100644
--- a/fs/ext3/xattr_security.c
+++ b/fs/ext3/xattr_security.c
@@ -6,7 +6,6 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext3_jbd.h>
#include <linux/ext3_fs.h>
#include <linux/security.h>
diff --git a/fs/ext3/xattr_trusted.c b/fs/ext3/xattr_trusted.c
index 86d91f1..0327497 100644
--- a/fs/ext3/xattr_trusted.c
+++ b/fs/ext3/xattr_trusted.c
@@ -9,7 +9,6 @@
#include <linux/string.h>
#include <linux/capability.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext3_jbd.h>
#include <linux/ext3_fs.h>
#include "xattr.h"
diff --git a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c
index a85a0a1..1abd8f9 100644
--- a/fs/ext3/xattr_user.c
+++ b/fs/ext3/xattr_user.c
@@ -8,7 +8,6 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext3_jbd.h>
#include <linux/ext3_fs.h>
#include "xattr.h"
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index da80368..e8ad06e 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -25,7 +25,6 @@
#include <linux/jbd2.h>
#include <linux/ext4_fs.h>
#include <linux/buffer_head.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/rbtree.h>
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 7916b50..a0f0c04 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -34,7 +34,6 @@
#include <linux/time.h>
#include <linux/ext4_jbd2.h>
#include <linux/jbd.h>
-#include <linux/smp_lock.h>
#include <linux/highuid.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 810b6d6..b34182b 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -27,7 +27,6 @@
#include <linux/time.h>
#include <linux/ext4_jbd2.h>
#include <linux/jbd2.h>
-#include <linux/smp_lock.h>
#include <linux/highuid.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
@@ -2611,9 +2610,9 @@ void ext4_read_inode(struct inode * inode)
}
inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
inode->i_size = le32_to_cpu(raw_inode->i_size);
- inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
- inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->i_ctime);
- inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->i_mtime);
+ inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
+ inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime);
+ inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0;
ei->i_state = 0;
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index e7e1d79..4ec57be 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -36,7 +36,6 @@
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
#include <linux/bio.h>
-#include <linux/smp_lock.h>
#include "namei.h"
#include "xattr.h"
@@ -967,6 +966,7 @@ static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
(block<<EXT4_BLOCK_SIZE_BITS(sb))
+((char *)de - bh->b_data))) {
brelse (bh);
+ *err = ERR_BAD_DX_DIR;
goto errout;
}
*res_dir = de;
@@ -1132,9 +1132,9 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
char *data1 = (*bh)->b_data, *data2;
unsigned split;
struct ext4_dir_entry_2 *de = NULL, *de2;
- int err;
+ int err = 0;
- bh2 = ext4_append (handle, dir, &newblock, error);
+ bh2 = ext4_append (handle, dir, &newblock, &err);
if (!(bh2)) {
brelse(*bh);
*bh = NULL;
@@ -1143,14 +1143,9 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
BUFFER_TRACE(*bh, "get_write_access");
err = ext4_journal_get_write_access(handle, *bh);
- if (err) {
- journal_error:
- brelse(*bh);
- brelse(bh2);
- *bh = NULL;
- ext4_std_error(dir->i_sb, err);
- goto errout;
- }
+ if (err)
+ goto journal_error;
+
BUFFER_TRACE(frame->bh, "get_write_access");
err = ext4_journal_get_write_access(handle, frame->bh);
if (err)
@@ -1193,8 +1188,16 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
goto journal_error;
brelse (bh2);
dxtrace(dx_show_index ("frame", frame->entries));
-errout:
return de;
+
+journal_error:
+ brelse(*bh);
+ brelse(bh2);
+ *bh = NULL;
+ ext4_std_error(dir->i_sb, err);
+errout:
+ *error = err;
+ return NULL;
}
#endif
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index ea99f6c..aa11d7d 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -11,7 +11,6 @@
#define EXT4FS_DEBUG
-#include <linux/smp_lock.h>
#include <linux/ext4_jbd2.h>
#include <linux/errno.h>
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 61c4718..7191269 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -470,7 +470,7 @@ static void ext4_put_super (struct super_block * sb)
dump_orphan_list(sb, sbi);
J_ASSERT(list_empty(&sbi->s_orphan));
- invalidate_bdev(sb->s_bdev, 0);
+ invalidate_bdev(sb->s_bdev);
if (sbi->journal_bdev && sbi->journal_bdev != sb->s_bdev) {
/*
* Invalidate the journal device's buffers. We don't want them
@@ -478,7 +478,7 @@ static void ext4_put_super (struct super_block * sb)
* hotswapped, and it breaks the `ro-after' testing code.
*/
sync_blockdev(sbi->journal_bdev);
- invalidate_bdev(sbi->journal_bdev, 0);
+ invalidate_bdev(sbi->journal_bdev);
ext4_blkdev_remove(sbi);
}
sb->s_fs_info = NULL;
@@ -517,8 +517,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct ext4_inode_info *ei = (struct ext4_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
INIT_LIST_HEAD(&ei->i_orphan);
#ifdef CONFIG_EXT4DEV_FS_XATTR
init_rwsem(&ei->xattr_sem);
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
index b6a6861..f17eaf2 100644
--- a/fs/ext4/xattr_security.c
+++ b/fs/ext4/xattr_security.c
@@ -6,7 +6,6 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext4_jbd2.h>
#include <linux/ext4_fs.h>
#include <linux/security.h>
diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c
index b76f2db..e0f05ac 100644
--- a/fs/ext4/xattr_trusted.c
+++ b/fs/ext4/xattr_trusted.c
@@ -9,7 +9,6 @@
#include <linux/string.h>
#include <linux/capability.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext4_jbd2.h>
#include <linux/ext4_fs.h>
#include "xattr.h"
diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c
index c53cded..7ed3d8e 100644
--- a/fs/ext4/xattr_user.c
+++ b/fs/ext4/xattr_user.c
@@ -8,7 +8,6 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/ext4_jbd2.h>
#include <linux/ext4_fs.h>
#include "xattr.h"
diff --git a/fs/fat/cache.c b/fs/fat/cache.c
index 05c2941..1959143 100644
--- a/fs/fat/cache.c
+++ b/fs/fat/cache.c
@@ -40,8 +40,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
{
struct fat_cache *cache = (struct fat_cache *)foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
INIT_LIST_HEAD(&cache->cache_list);
}
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index c16af24..ccf161d 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -422,7 +422,7 @@ EODir:
EXPORT_SYMBOL_GPL(fat_search_long);
struct fat_ioctl_filldir_callback {
- struct dirent __user *dirent;
+ void __user *dirent;
int result;
/* for dir ioctl */
const char *longname;
@@ -647,62 +647,85 @@ static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir)
return __fat_readdir(inode, filp, dirent, filldir, 0, 0);
}
-static int fat_ioctl_filldir(void *__buf, const char *name, int name_len,
- loff_t offset, u64 ino, unsigned int d_type)
+#define FAT_IOCTL_FILLDIR_FUNC(func, dirent_type) \
+static int func(void *__buf, const char *name, int name_len, \
+ loff_t offset, u64 ino, unsigned int d_type) \
+{ \
+ struct fat_ioctl_filldir_callback *buf = __buf; \
+ struct dirent_type __user *d1 = buf->dirent; \
+ struct dirent_type __user *d2 = d1 + 1; \
+ \
+ if (buf->result) \
+ return -EINVAL; \
+ buf->result++; \
+ \
+ if (name != NULL) { \
+ /* dirent has only short name */ \
+ if (name_len >= sizeof(d1->d_name)) \
+ name_len = sizeof(d1->d_name) - 1; \
+ \
+ if (put_user(0, d2->d_name) || \
+ put_user(0, &d2->d_reclen) || \
+ copy_to_user(d1->d_name, name, name_len) || \
+ put_user(0, d1->d_name + name_len) || \
+ put_user(name_len, &d1->d_reclen)) \
+ goto efault; \
+ } else { \
+ /* dirent has short and long name */ \
+ const char *longname = buf->longname; \
+ int long_len = buf->long_len; \
+ const char *shortname = buf->shortname; \
+ int short_len = buf->short_len; \
+ \
+ if (long_len >= sizeof(d1->d_name)) \
+ long_len = sizeof(d1->d_name) - 1; \
+ if (short_len >= sizeof(d1->d_name)) \
+ short_len = sizeof(d1->d_name) - 1; \
+ \
+ if (copy_to_user(d2->d_name, longname, long_len) || \
+ put_user(0, d2->d_name + long_len) || \
+ put_user(long_len, &d2->d_reclen) || \
+ put_user(ino, &d2->d_ino) || \
+ put_user(offset, &d2->d_off) || \
+ copy_to_user(d1->d_name, shortname, short_len) || \
+ put_user(0, d1->d_name + short_len) || \
+ put_user(short_len, &d1->d_reclen)) \
+ goto efault; \
+ } \
+ return 0; \
+efault: \
+ buf->result = -EFAULT; \
+ return -EFAULT; \
+}
+
+FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, dirent)
+
+static int fat_ioctl_readdir(struct inode *inode, struct file *filp,
+ void __user *dirent, filldir_t filldir,
+ int short_only, int both)
{
- struct fat_ioctl_filldir_callback *buf = __buf;
- struct dirent __user *d1 = buf->dirent;
- struct dirent __user *d2 = d1 + 1;
-
- if (buf->result)
- return -EINVAL;
- buf->result++;
-
- if (name != NULL) {
- /* dirent has only short name */
- if (name_len >= sizeof(d1->d_name))
- name_len = sizeof(d1->d_name) - 1;
-
- if (put_user(0, d2->d_name) ||
- put_user(0, &d2->d_reclen) ||
- copy_to_user(d1->d_name, name, name_len) ||
- put_user(0, d1->d_name + name_len) ||
- put_user(name_len, &d1->d_reclen))
- goto efault;
- } else {
- /* dirent has short and long name */
- const char *longname = buf->longname;
- int long_len = buf->long_len;
- const char *shortname = buf->shortname;
- int short_len = buf->short_len;
-
- if (long_len >= sizeof(d1->d_name))
- long_len = sizeof(d1->d_name) - 1;
- if (short_len >= sizeof(d1->d_name))
- short_len = sizeof(d1->d_name) - 1;
-
- if (copy_to_user(d2->d_name, longname, long_len) ||
- put_user(0, d2->d_name + long_len) ||
- put_user(long_len, &d2->d_reclen) ||
- put_user(ino, &d2->d_ino) ||
- put_user(offset, &d2->d_off) ||
- copy_to_user(d1->d_name, shortname, short_len) ||
- put_user(0, d1->d_name + short_len) ||
- put_user(short_len, &d1->d_reclen))
- goto efault;
+ struct fat_ioctl_filldir_callback buf;
+ int ret;
+
+ buf.dirent = dirent;
+ buf.result = 0;
+ mutex_lock(&inode->i_mutex);
+ ret = -ENOENT;
+ if (!IS_DEADDIR(inode)) {
+ ret = __fat_readdir(inode, filp, &buf, filldir,
+ short_only, both);
}
- return 0;
-efault:
- buf->result = -EFAULT;
- return -EFAULT;
+ mutex_unlock(&inode->i_mutex);
+ if (ret >= 0)
+ ret = buf.result;
+ return ret;
}
-static int fat_dir_ioctl(struct inode * inode, struct file * filp,
- unsigned int cmd, unsigned long arg)
+static int fat_dir_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
{
- struct fat_ioctl_filldir_callback buf;
- struct dirent __user *d1;
- int ret, short_only, both;
+ struct dirent __user *d1 = (struct dirent __user *)arg;
+ int short_only, both;
switch (cmd) {
case VFAT_IOCTL_READDIR_SHORT:
@@ -717,7 +740,6 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp,
return fat_generic_ioctl(inode, filp, cmd, arg);
}
- d1 = (struct dirent __user *)arg;
if (!access_ok(VERIFY_WRITE, d1, sizeof(struct dirent[2])))
return -EFAULT;
/*
@@ -728,69 +750,48 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp,
if (put_user(0, &d1->d_reclen))
return -EFAULT;
- buf.dirent = d1;
- buf.result = 0;
- mutex_lock(&inode->i_mutex);
- ret = -ENOENT;
- if (!IS_DEADDIR(inode)) {
- ret = __fat_readdir(inode, filp, &buf, fat_ioctl_filldir,
- short_only, both);
- }
- mutex_unlock(&inode->i_mutex);
- if (ret >= 0)
- ret = buf.result;
- return ret;
+ return fat_ioctl_readdir(inode, filp, d1, fat_ioctl_filldir,
+ short_only, both);
}
#ifdef CONFIG_COMPAT
#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2])
#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2])
-static long fat_compat_put_dirent32(struct dirent *d,
- struct compat_dirent __user *d32)
-{
- if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent)))
- return -EFAULT;
-
- __put_user(d->d_ino, &d32->d_ino);
- __put_user(d->d_off, &d32->d_off);
- __put_user(d->d_reclen, &d32->d_reclen);
- if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen))
- return -EFAULT;
+FAT_IOCTL_FILLDIR_FUNC(fat_compat_ioctl_filldir, compat_dirent)
- return 0;
-}
-
-static long fat_compat_dir_ioctl(struct file *file, unsigned cmd,
+static long fat_compat_dir_ioctl(struct file *filp, unsigned cmd,
unsigned long arg)
{
- struct compat_dirent __user *p = compat_ptr(arg);
- int ret;
- mm_segment_t oldfs = get_fs();
- struct dirent d[2];
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ struct compat_dirent __user *d1 = compat_ptr(arg);
+ int short_only, both;
switch (cmd) {
- case VFAT_IOCTL_READDIR_BOTH32:
- cmd = VFAT_IOCTL_READDIR_BOTH;
- break;
case VFAT_IOCTL_READDIR_SHORT32:
- cmd = VFAT_IOCTL_READDIR_SHORT;
+ short_only = 1;
+ both = 0;
+ break;
+ case VFAT_IOCTL_READDIR_BOTH32:
+ short_only = 0;
+ both = 1;
break;
default:
return -ENOIOCTLCMD;
}
- set_fs(KERNEL_DS);
- lock_kernel();
- ret = fat_dir_ioctl(file->f_path.dentry->d_inode, file,
- cmd, (unsigned long) &d);
- unlock_kernel();
- set_fs(oldfs);
- if (ret >= 0) {
- ret |= fat_compat_put_dirent32(&d[0], p);
- ret |= fat_compat_put_dirent32(&d[1], p + 1);
- }
- return ret;
+ if (!access_ok(VERIFY_WRITE, d1, sizeof(struct compat_dirent[2])))
+ return -EFAULT;
+ /*
+ * Yes, we don't need this put_user() absolutely. However old
+ * code didn't return the right value. So, app use this value,
+ * in order to check whether it is EOF.
+ */
+ if (put_user(0, &d1->d_reclen))
+ return -EFAULT;
+
+ return fat_ioctl_readdir(inode, filp, d1, fat_compat_ioctl_filldir,
+ short_only, both);
}
#endif /* CONFIG_COMPAT */
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 9bfe607..2c55e8d 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -25,6 +25,7 @@
#include <linux/parser.h>
#include <linux/uio.h>
#include <linux/writeback.h>
+#include <linux/log2.h>
#include <asm/unaligned.h>
#ifndef CONFIG_FAT_DEFAULT_IOCHARSET
@@ -499,8 +500,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct msdos_inode_info *ei = (struct msdos_inode_info *)foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
spin_lock_init(&ei->cache_lru_lock);
ei->nr_caches = 0;
ei->cache_valid_id = FAT_CACHE_VALID + 1;
@@ -825,6 +825,8 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
}
if (opts->name_check != 'n')
seq_printf(m, ",check=%c", opts->name_check);
+ if (opts->usefree)
+ seq_puts(m, ",usefree");
if (opts->quiet)
seq_puts(m, ",quiet");
if (opts->showexec)
@@ -850,7 +852,7 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
enum {
Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid,
- Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_nocase,
+ Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_usefree, Opt_nocase,
Opt_quiet, Opt_showexec, Opt_debug, Opt_immutable,
Opt_dots, Opt_nodots,
Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
@@ -872,6 +874,7 @@ static match_table_t fat_tokens = {
{Opt_dmask, "dmask=%o"},
{Opt_fmask, "fmask=%o"},
{Opt_codepage, "codepage=%u"},
+ {Opt_usefree, "usefree"},
{Opt_nocase, "nocase"},
{Opt_quiet, "quiet"},
{Opt_showexec, "showexec"},
@@ -951,7 +954,7 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug,
opts->quiet = opts->showexec = opts->sys_immutable = opts->dotsOK = 0;
opts->utf8 = opts->unicode_xlate = 0;
opts->numtail = 1;
- opts->nocase = 0;
+ opts->usefree = opts->nocase = 0;
*debug = 0;
if (!options)
@@ -979,6 +982,9 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug,
case Opt_check_n:
opts->name_check = 'n';
break;
+ case Opt_usefree:
+ opts->usefree = 1;
+ break;
case Opt_nocase:
if (!is_vfat)
opts->nocase = 1;
@@ -1218,8 +1224,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
}
logical_sector_size =
le16_to_cpu(get_unaligned((__le16 *)&b->sector_size));
- if (!logical_sector_size
- || (logical_sector_size & (logical_sector_size - 1))
+ if (!is_power_of_2(logical_sector_size)
|| (logical_sector_size < 512)
|| (PAGE_CACHE_SIZE < logical_sector_size)) {
if (!silent)
@@ -1229,8 +1234,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
goto out_invalid;
}
sbi->sec_per_clus = b->sec_per_clus;
- if (!sbi->sec_per_clus
- || (sbi->sec_per_clus & (sbi->sec_per_clus - 1))) {
+ if (!is_power_of_2(sbi->sec_per_clus)) {
if (!silent)
printk(KERN_ERR "FAT: bogus sectors per cluster %u\n",
sbi->sec_per_clus);
@@ -1306,7 +1310,9 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
le32_to_cpu(fsinfo->signature2),
sbi->fsinfo_sector);
} else {
- sbi->free_clusters = le32_to_cpu(fsinfo->free_clusters);
+ if (sbi->options.usefree)
+ sbi->free_clusters =
+ le32_to_cpu(fsinfo->free_clusters);
sbi->prev_free = le32_to_cpu(fsinfo->next_cluster);
}
diff --git a/fs/fifo.c b/fs/fifo.c
index 49035b1..6e7df72 100644
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -11,7 +11,6 @@
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/pipe_fs_i.h>
diff --git a/fs/file_table.c b/fs/file_table.c
index 4c17a18..d17fd69 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -10,7 +10,6 @@
#include <linux/file.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/security.h>
#include <linux/eventpoll.h>
diff --git a/fs/filesystems.c b/fs/filesystems.c
index 7a4f61a..f37f872 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -41,11 +41,12 @@ void put_filesystem(struct file_system_type *fs)
module_put(fs->owner);
}
-static struct file_system_type **find_filesystem(const char *name)
+static struct file_system_type **find_filesystem(const char *name, unsigned len)
{
struct file_system_type **p;
for (p=&file_systems; *p; p=&(*p)->next)
- if (strcmp((*p)->name,name) == 0)
+ if (strlen((*p)->name) == len &&
+ strncmp((*p)->name, name, len) == 0)
break;
return p;
}
@@ -68,11 +69,12 @@ int register_filesystem(struct file_system_type * fs)
int res = 0;
struct file_system_type ** p;
+ BUG_ON(strchr(fs->name, '.'));
if (fs->next)
return -EBUSY;
INIT_LIST_HEAD(&fs->fs_supers);
write_lock(&file_systems_lock);
- p = find_filesystem(fs->name);
+ p = find_filesystem(fs->name, strlen(fs->name));
if (*p)
res = -EBUSY;
else
@@ -215,19 +217,26 @@ int get_filesystem_list(char * buf)
struct file_system_type *get_fs_type(const char *name)
{
struct file_system_type *fs;
+ const char *dot = strchr(name, '.');
+ unsigned len = dot ? dot - name : strlen(name);
read_lock(&file_systems_lock);
- fs = *(find_filesystem(name));
+ fs = *(find_filesystem(name, len));
if (fs && !try_module_get(fs->owner))
fs = NULL;
read_unlock(&file_systems_lock);
- if (!fs && (request_module("%s", name) == 0)) {
+ if (!fs && (request_module("%.*s", len, name) == 0)) {
read_lock(&file_systems_lock);
- fs = *(find_filesystem(name));
+ fs = *(find_filesystem(name, len));
if (fs && !try_module_get(fs->owner))
fs = NULL;
read_unlock(&file_systems_lock);
}
+
+ if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
+ put_filesystem(fs);
+ fs = NULL;
+ }
return fs;
}
diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c
index 2d71128..f86fd3c 100644
--- a/fs/freevxfs/vxfs_bmap.c
+++ b/fs/freevxfs/vxfs_bmap.c
@@ -137,7 +137,7 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
bp = sb_bread(ip->i_sb,
indir + (i / VXFS_TYPED_PER_BLOCK(ip->i_sb)));
- if (!buffer_mapped(bp))
+ if (!bp || !buffer_mapped(bp))
return 0;
typ = ((struct vxfs_typed *)bp->b_data) +
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 098a915..d1f7c5b 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -99,7 +99,7 @@ vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino)
offset = ((ino % (sbp->s_blocksize / VXFS_ISIZE)) * VXFS_ISIZE);
bp = sb_bread(sbp, block);
- if (buffer_mapped(bp)) {
+ if (bp && buffer_mapped(bp)) {
struct vxfs_inode_info *vip;
struct vxfs_dinode *dip;
diff --git a/fs/freevxfs/vxfs_subr.c b/fs/freevxfs/vxfs_subr.c
index decac62..ed8f0b0 100644
--- a/fs/freevxfs/vxfs_subr.c
+++ b/fs/freevxfs/vxfs_subr.c
@@ -74,10 +74,7 @@ vxfs_get_page(struct address_space *mapping, u_long n)
pp = read_mapping_page(mapping, n, NULL);
if (!IS_ERR(pp)) {
- wait_on_page_locked(pp);
kmap(pp);
- if (!PageUptodate(pp))
- goto fail;
/** if (!PageChecked(pp)) **/
/** vxfs_check_page(pp); **/
if (PageError(pp))
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 2fd0692..acfad65 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -738,8 +738,7 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl)
if (cmd == F_GETLK) {
if (fc->no_lock) {
- if (!posix_test_lock(file, fl, fl))
- fl->fl_type = F_UNLCK;
+ posix_test_lock(file, fl);
err = 0;
} else
err = fuse_getlk(file, fl);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index bdffe0c..1397018 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -636,6 +636,7 @@ static int fuse_get_sb(struct file_system_type *fs_type,
static struct file_system_type fuse_fs_type = {
.owner = THIS_MODULE,
.name = "fuse",
+ .fs_flags = FS_HAS_SUBTYPE,
.get_sb = fuse_get_sb,
.kill_sb = kill_anon_super,
};
@@ -652,6 +653,7 @@ static int fuse_get_sb_blk(struct file_system_type *fs_type,
static struct file_system_type fuseblk_fs_type = {
.owner = THIS_MODULE,
.name = "fuseblk",
+ .fs_flags = FS_HAS_SUBTYPE,
.get_sb = fuse_get_sb_blk,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
@@ -685,8 +687,7 @@ static void fuse_inode_init_once(void *foo, struct kmem_cache *cachep,
{
struct inode * inode = foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(inode);
}
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 82a1ac7..a96fa07 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -1262,9 +1262,10 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
u64 leaf_no)
{
struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
struct buffer_head *bh;
struct gfs2_leaf *lf;
- unsigned entries = 0;
+ unsigned entries = 0, entries2 = 0;
unsigned leaves = 0;
const struct gfs2_dirent **darr, *dent;
struct dirent_gather g;
@@ -1290,7 +1291,13 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
return 0;
error = -ENOMEM;
- larr = vmalloc((leaves + entries) * sizeof(void *));
+ /*
+ * The extra 99 entries are not normally used, but are a buffer
+ * zone in case the number of entries in the leaf is corrupt.
+ * 99 is the maximum number of entries that can fit in a single
+ * leaf block.
+ */
+ larr = vmalloc((leaves + entries + 99) * sizeof(void *));
if (!larr)
goto out;
darr = (const struct gfs2_dirent **)(larr + leaves);
@@ -1305,10 +1312,20 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
lf = (struct gfs2_leaf *)bh->b_data;
lfn = be64_to_cpu(lf->lf_next);
if (lf->lf_entries) {
+ entries2 += be16_to_cpu(lf->lf_entries);
dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size,
gfs2_dirent_gather, NULL, &g);
error = PTR_ERR(dent);
- if (IS_ERR(dent)) {
+ if (IS_ERR(dent))
+ goto out_kfree;
+ if (entries2 != g.offset) {
+ fs_warn(sdp, "Number of entries corrupt in dir "
+ "leaf %llu, entries2 (%u) != "
+ "g.offset (%u)\n",
+ (unsigned long long)bh->b_blocknr,
+ entries2, g.offset);
+
+ error = -EIO;
goto out_kfree;
}
error = 0;
@@ -1318,6 +1335,7 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
}
} while(lfn);
+ BUG_ON(entries2 != entries);
error = do_filldir_main(ip, offset, opaque, filldir, darr,
entries, copied);
out_kfree:
@@ -1401,6 +1419,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
filldir_t filldir)
{
struct gfs2_inode *dip = GFS2_I(inode);
+ struct gfs2_sbd *sdp = GFS2_SB(inode);
struct dirent_gather g;
const struct gfs2_dirent **darr, *dent;
struct buffer_head *dibh;
@@ -1423,8 +1442,8 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
return error;
error = -ENOMEM;
- darr = kmalloc(dip->i_di.di_entries * sizeof(struct gfs2_dirent *),
- GFP_KERNEL);
+ /* 96 is max number of dirents which can be stuffed into an inode */
+ darr = kmalloc(96 * sizeof(struct gfs2_dirent *), GFP_KERNEL);
if (darr) {
g.pdent = darr;
g.offset = 0;
@@ -1434,6 +1453,15 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
error = PTR_ERR(dent);
goto out;
}
+ if (dip->i_di.di_entries != g.offset) {
+ fs_warn(sdp, "Number of entries corrupt in dir %llu, "
+ "ip->i_di.di_entries (%u) != g.offset (%u)\n",
+ (unsigned long long)dip->i_num.no_addr,
+ dip->i_di.di_entries,
+ g.offset);
+ error = -EIO;
+ goto out;
+ }
error = do_filldir_main(dip, offset, opaque, filldir, darr,
dip->i_di.di_entries, &copied);
out:
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 12accb0..1815429 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -23,6 +23,10 @@
#include <linux/module.h>
#include <linux/rwsem.h>
#include <asm/uaccess.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
#include "gfs2.h"
#include "incore.h"
@@ -40,20 +44,30 @@ struct gfs2_gl_hash_bucket {
struct hlist_head hb_list;
};
+struct glock_iter {
+ int hash; /* hash bucket index */
+ struct gfs2_sbd *sdp; /* incore superblock */
+ struct gfs2_glock *gl; /* current glock struct */
+ struct hlist_head *hb_list; /* current hash bucket ptr */
+ struct seq_file *seq; /* sequence file for debugfs */
+ char string[512]; /* scratch space */
+};
+
typedef void (*glock_examiner) (struct gfs2_glock * gl);
static int gfs2_dump_lockstate(struct gfs2_sbd *sdp);
-static int dump_glock(struct gfs2_glock *gl);
-static int dump_inode(struct gfs2_inode *ip);
-static void gfs2_glock_xmote_th(struct gfs2_holder *gh);
+static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl);
+static void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh);
static void gfs2_glock_drop_th(struct gfs2_glock *gl);
static DECLARE_RWSEM(gfs2_umount_flush_sem);
+static struct dentry *gfs2_root;
#define GFS2_GL_HASH_SHIFT 15
#define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT)
#define GFS2_GL_HASH_MASK (GFS2_GL_HASH_SIZE - 1)
static struct gfs2_gl_hash_bucket gl_hash_table[GFS2_GL_HASH_SIZE];
+static struct dentry *gfs2_root;
/*
* Despite what you might think, the numbers below are not arbitrary :-)
@@ -202,7 +216,6 @@ int gfs2_glock_put(struct gfs2_glock *gl)
gfs2_assert(sdp, list_empty(&gl->gl_reclaim));
gfs2_assert(sdp, list_empty(&gl->gl_holders));
gfs2_assert(sdp, list_empty(&gl->gl_waiters1));
- gfs2_assert(sdp, list_empty(&gl->gl_waiters2));
gfs2_assert(sdp, list_empty(&gl->gl_waiters3));
glock_free(gl);
rv = 1;
@@ -303,7 +316,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
atomic_set(&gl->gl_ref, 1);
gl->gl_state = LM_ST_UNLOCKED;
gl->gl_hash = hash;
- gl->gl_owner = NULL;
+ gl->gl_owner_pid = 0;
gl->gl_ip = 0;
gl->gl_ops = glops;
gl->gl_req_gh = NULL;
@@ -367,7 +380,7 @@ void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, unsigned flags,
INIT_LIST_HEAD(&gh->gh_list);
gh->gh_gl = gl;
gh->gh_ip = (unsigned long)__builtin_return_address(0);
- gh->gh_owner = current;
+ gh->gh_owner_pid = current->pid;
gh->gh_state = state;
gh->gh_flags = flags;
gh->gh_error = 0;
@@ -389,7 +402,7 @@ void gfs2_holder_reinit(unsigned int state, unsigned flags, struct gfs2_holder *
{
gh->gh_state = state;
gh->gh_flags = flags;
- gh->gh_iflags &= 1 << HIF_ALLOCED;
+ gh->gh_iflags = 0;
gh->gh_ip = (unsigned long)__builtin_return_address(0);
}
@@ -406,54 +419,8 @@ void gfs2_holder_uninit(struct gfs2_holder *gh)
gh->gh_ip = 0;
}
-/**
- * gfs2_holder_get - get a struct gfs2_holder structure
- * @gl: the glock
- * @state: the state we're requesting
- * @flags: the modifier flags
- * @gfp_flags:
- *
- * Figure out how big an impact this function has. Either:
- * 1) Replace it with a cache of structures hanging off the struct gfs2_sbd
- * 2) Leave it like it is
- *
- * Returns: the holder structure, NULL on ENOMEM
- */
-
-static struct gfs2_holder *gfs2_holder_get(struct gfs2_glock *gl,
- unsigned int state,
- int flags, gfp_t gfp_flags)
-{
- struct gfs2_holder *gh;
-
- gh = kmalloc(sizeof(struct gfs2_holder), gfp_flags);
- if (!gh)
- return NULL;
-
- gfs2_holder_init(gl, state, flags, gh);
- set_bit(HIF_ALLOCED, &gh->gh_iflags);
- gh->gh_ip = (unsigned long)__builtin_return_address(0);
- return gh;
-}
-
-/**
- * gfs2_holder_put - get rid of a struct gfs2_holder structure
- * @gh: the holder structure
- *
- */
-
-static void gfs2_holder_put(struct gfs2_holder *gh)
+static void gfs2_holder_wake(struct gfs2_holder *gh)
{
- gfs2_holder_uninit(gh);
- kfree(gh);
-}
-
-static void gfs2_holder_dispose_or_wake(struct gfs2_holder *gh)
-{
- if (test_bit(HIF_DEALLOC, &gh->gh_iflags)) {
- gfs2_holder_put(gh);
- return;
- }
clear_bit(HIF_WAIT, &gh->gh_iflags);
smp_mb();
wake_up_bit(&gh->gh_iflags, HIF_WAIT);
@@ -519,7 +486,7 @@ static int rq_promote(struct gfs2_holder *gh)
gfs2_reclaim_glock(sdp);
}
- gfs2_glock_xmote_th(gh);
+ gfs2_glock_xmote_th(gh->gh_gl, gh);
spin_lock(&gl->gl_spin);
}
return 1;
@@ -542,7 +509,7 @@ static int rq_promote(struct gfs2_holder *gh)
gh->gh_error = 0;
set_bit(HIF_HOLDER, &gh->gh_iflags);
- gfs2_holder_dispose_or_wake(gh);
+ gfs2_holder_wake(gh);
return 0;
}
@@ -554,32 +521,24 @@ static int rq_promote(struct gfs2_holder *gh)
* Returns: 1 if the queue is blocked
*/
-static int rq_demote(struct gfs2_holder *gh)
+static int rq_demote(struct gfs2_glock *gl)
{
- struct gfs2_glock *gl = gh->gh_gl;
-
if (!list_empty(&gl->gl_holders))
return 1;
- if (gl->gl_state == gh->gh_state || gl->gl_state == LM_ST_UNLOCKED) {
- list_del_init(&gh->gh_list);
- gh->gh_error = 0;
- spin_unlock(&gl->gl_spin);
- gfs2_holder_dispose_or_wake(gh);
- spin_lock(&gl->gl_spin);
- } else {
- gl->gl_req_gh = gh;
- set_bit(GLF_LOCK, &gl->gl_flags);
- spin_unlock(&gl->gl_spin);
-
- if (gh->gh_state == LM_ST_UNLOCKED ||
- gl->gl_state != LM_ST_EXCLUSIVE)
- gfs2_glock_drop_th(gl);
- else
- gfs2_glock_xmote_th(gh);
-
- spin_lock(&gl->gl_spin);
+ if (gl->gl_state == gl->gl_demote_state ||
+ gl->gl_state == LM_ST_UNLOCKED) {
+ clear_bit(GLF_DEMOTE, &gl->gl_flags);
+ return 0;
}
+ set_bit(GLF_LOCK, &gl->gl_flags);
+ spin_unlock(&gl->gl_spin);
+ if (gl->gl_demote_state == LM_ST_UNLOCKED ||
+ gl->gl_state != LM_ST_EXCLUSIVE)
+ gfs2_glock_drop_th(gl);
+ else
+ gfs2_glock_xmote_th(gl, NULL);
+ spin_lock(&gl->gl_spin);
return 0;
}
@@ -607,16 +566,8 @@ static void run_queue(struct gfs2_glock *gl)
else
gfs2_assert_warn(gl->gl_sbd, 0);
- } else if (!list_empty(&gl->gl_waiters2) &&
- !test_bit(GLF_SKIP_WAITERS2, &gl->gl_flags)) {
- gh = list_entry(gl->gl_waiters2.next,
- struct gfs2_holder, gh_list);
-
- if (test_bit(HIF_DEMOTE, &gh->gh_iflags))
- blocked = rq_demote(gh);
- else
- gfs2_assert_warn(gl->gl_sbd, 0);
-
+ } else if (test_bit(GLF_DEMOTE, &gl->gl_flags)) {
+ blocked = rq_demote(gl);
} else if (!list_empty(&gl->gl_waiters3)) {
gh = list_entry(gl->gl_waiters3.next,
struct gfs2_holder, gh_list);
@@ -654,7 +605,7 @@ static void gfs2_glmutex_lock(struct gfs2_glock *gl)
if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) {
list_add_tail(&gh.gh_list, &gl->gl_waiters1);
} else {
- gl->gl_owner = current;
+ gl->gl_owner_pid = current->pid;
gl->gl_ip = (unsigned long)__builtin_return_address(0);
clear_bit(HIF_WAIT, &gh.gh_iflags);
smp_mb();
@@ -681,7 +632,7 @@ static int gfs2_glmutex_trylock(struct gfs2_glock *gl)
if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) {
acquired = 0;
} else {
- gl->gl_owner = current;
+ gl->gl_owner_pid = current->pid;
gl->gl_ip = (unsigned long)__builtin_return_address(0);
}
spin_unlock(&gl->gl_spin);
@@ -699,7 +650,7 @@ static void gfs2_glmutex_unlock(struct gfs2_glock *gl)
{
spin_lock(&gl->gl_spin);
clear_bit(GLF_LOCK, &gl->gl_flags);
- gl->gl_owner = NULL;
+ gl->gl_owner_pid = 0;
gl->gl_ip = 0;
run_queue(gl);
BUG_ON(!spin_is_locked(&gl->gl_spin));
@@ -707,50 +658,24 @@ static void gfs2_glmutex_unlock(struct gfs2_glock *gl)
}
/**
- * handle_callback - add a demote request to a lock's queue
+ * handle_callback - process a demote request
* @gl: the glock
* @state: the state the caller wants us to change to
*
- * Note: This may fail sliently if we are out of memory.
+ * There are only two requests that we are going to see in actual
+ * practise: LM_ST_SHARED and LM_ST_UNLOCKED
*/
static void handle_callback(struct gfs2_glock *gl, unsigned int state)
{
- struct gfs2_holder *gh, *new_gh = NULL;
-
-restart:
spin_lock(&gl->gl_spin);
-
- list_for_each_entry(gh, &gl->gl_waiters2, gh_list) {
- if (test_bit(HIF_DEMOTE, &gh->gh_iflags) &&
- gl->gl_req_gh != gh) {
- if (gh->gh_state != state)
- gh->gh_state = LM_ST_UNLOCKED;
- goto out;
- }
- }
-
- if (new_gh) {
- list_add_tail(&new_gh->gh_list, &gl->gl_waiters2);
- new_gh = NULL;
- } else {
- spin_unlock(&gl->gl_spin);
-
- new_gh = gfs2_holder_get(gl, state, LM_FLAG_TRY, GFP_NOFS);
- if (!new_gh)
- return;
- set_bit(HIF_DEMOTE, &new_gh->gh_iflags);
- set_bit(HIF_DEALLOC, &new_gh->gh_iflags);
- set_bit(HIF_WAIT, &new_gh->gh_iflags);
-
- goto restart;
+ if (test_and_set_bit(GLF_DEMOTE, &gl->gl_flags) == 0) {
+ gl->gl_demote_state = state;
+ gl->gl_demote_time = jiffies;
+ } else if (gl->gl_demote_state != LM_ST_UNLOCKED) {
+ gl->gl_demote_state = state;
}
-
-out:
spin_unlock(&gl->gl_spin);
-
- if (new_gh)
- gfs2_holder_put(new_gh);
}
/**
@@ -810,56 +735,37 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
/* Deal with each possible exit condition */
- if (!gh)
+ if (!gh) {
gl->gl_stamp = jiffies;
- else if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) {
+ if (ret & LM_OUT_CANCELED)
+ op_done = 0;
+ else
+ clear_bit(GLF_DEMOTE, &gl->gl_flags);
+ } else {
spin_lock(&gl->gl_spin);
list_del_init(&gh->gh_list);
gh->gh_error = -EIO;
- spin_unlock(&gl->gl_spin);
- } else if (test_bit(HIF_DEMOTE, &gh->gh_iflags)) {
- spin_lock(&gl->gl_spin);
- list_del_init(&gh->gh_list);
- if (gl->gl_state == gh->gh_state ||
- gl->gl_state == LM_ST_UNLOCKED) {
+ if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
+ goto out;
+ gh->gh_error = GLR_CANCELED;
+ if (ret & LM_OUT_CANCELED)
+ goto out;
+ if (relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) {
+ list_add_tail(&gh->gh_list, &gl->gl_holders);
gh->gh_error = 0;
- } else {
- if (gfs2_assert_warn(sdp, gh->gh_flags &
- (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) == -1)
- fs_warn(sdp, "ret = 0x%.8X\n", ret);
- gh->gh_error = GLR_TRYFAILED;
+ set_bit(HIF_HOLDER, &gh->gh_iflags);
+ set_bit(HIF_FIRST, &gh->gh_iflags);
+ op_done = 0;
+ goto out;
}
- spin_unlock(&gl->gl_spin);
-
- if (ret & LM_OUT_CANCELED)
- handle_callback(gl, LM_ST_UNLOCKED);
-
- } else if (ret & LM_OUT_CANCELED) {
- spin_lock(&gl->gl_spin);
- list_del_init(&gh->gh_list);
- gh->gh_error = GLR_CANCELED;
- spin_unlock(&gl->gl_spin);
-
- } else if (relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) {
- spin_lock(&gl->gl_spin);
- list_move_tail(&gh->gh_list, &gl->gl_holders);
- gh->gh_error = 0;
- set_bit(HIF_HOLDER, &gh->gh_iflags);
- spin_unlock(&gl->gl_spin);
-
- set_bit(HIF_FIRST, &gh->gh_iflags);
-
- op_done = 0;
-
- } else if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) {
- spin_lock(&gl->gl_spin);
- list_del_init(&gh->gh_list);
gh->gh_error = GLR_TRYFAILED;
- spin_unlock(&gl->gl_spin);
-
- } else {
+ if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))
+ goto out;
+ gh->gh_error = -EINVAL;
if (gfs2_assert_withdraw(sdp, 0) == -1)
fs_err(sdp, "ret = 0x%.8X\n", ret);
+out:
+ spin_unlock(&gl->gl_spin);
}
if (glops->go_xmote_bh)
@@ -877,7 +783,7 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
gfs2_glock_put(gl);
if (gh)
- gfs2_holder_dispose_or_wake(gh);
+ gfs2_holder_wake(gh);
}
/**
@@ -888,12 +794,11 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret)
*
*/
-void gfs2_glock_xmote_th(struct gfs2_holder *gh)
+void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh)
{
- struct gfs2_glock *gl = gh->gh_gl;
struct gfs2_sbd *sdp = gl->gl_sbd;
- int flags = gh->gh_flags;
- unsigned state = gh->gh_state;
+ int flags = gh ? gh->gh_flags : 0;
+ unsigned state = gh ? gh->gh_state : gl->gl_demote_state;
const struct gfs2_glock_operations *glops = gl->gl_ops;
int lck_flags = flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB |
LM_FLAG_NOEXP | LM_FLAG_ANY |
@@ -943,6 +848,7 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret)
gfs2_assert_warn(sdp, !ret);
state_change(gl, LM_ST_UNLOCKED);
+ clear_bit(GLF_DEMOTE, &gl->gl_flags);
if (glops->go_inval)
glops->go_inval(gl, DIO_METADATA);
@@ -964,7 +870,7 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret)
gfs2_glock_put(gl);
if (gh)
- gfs2_holder_dispose_or_wake(gh);
+ gfs2_holder_wake(gh);
}
/**
@@ -1097,18 +1003,32 @@ static int glock_wait_internal(struct gfs2_holder *gh)
}
static inline struct gfs2_holder *
-find_holder_by_owner(struct list_head *head, struct task_struct *owner)
+find_holder_by_owner(struct list_head *head, pid_t pid)
{
struct gfs2_holder *gh;
list_for_each_entry(gh, head, gh_list) {
- if (gh->gh_owner == owner)
+ if (gh->gh_owner_pid == pid)
return gh;
}
return NULL;
}
+static void print_dbg(struct glock_iter *gi, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ if (gi) {
+ vsprintf(gi->string, fmt, args);
+ seq_printf(gi->seq, gi->string);
+ }
+ else
+ vprintk(fmt, args);
+ va_end(args);
+}
+
/**
* add_to_queue - Add a holder to the wait queue (but look for recursion)
* @gh: the holder structure to add
@@ -1120,24 +1040,24 @@ static void add_to_queue(struct gfs2_holder *gh)
struct gfs2_glock *gl = gh->gh_gl;
struct gfs2_holder *existing;
- BUG_ON(!gh->gh_owner);
+ BUG_ON(!gh->gh_owner_pid);
if (test_and_set_bit(HIF_WAIT, &gh->gh_iflags))
BUG();
- existing = find_holder_by_owner(&gl->gl_holders, gh->gh_owner);
+ existing = find_holder_by_owner(&gl->gl_holders, gh->gh_owner_pid);
if (existing) {
print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip);
- printk(KERN_INFO "pid : %d\n", existing->gh_owner->pid);
+ printk(KERN_INFO "pid : %d\n", existing->gh_owner_pid);
printk(KERN_INFO "lock type : %d lock state : %d\n",
existing->gh_gl->gl_name.ln_type, existing->gh_gl->gl_state);
print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip);
- printk(KERN_INFO "pid : %d\n", gh->gh_owner->pid);
+ printk(KERN_INFO "pid : %d\n", gh->gh_owner_pid);
printk(KERN_INFO "lock type : %d lock state : %d\n",
gl->gl_name.ln_type, gl->gl_state);
BUG();
}
- existing = find_holder_by_owner(&gl->gl_waiters3, gh->gh_owner);
+ existing = find_holder_by_owner(&gl->gl_waiters3, gh->gh_owner_pid);
if (existing) {
print_symbol(KERN_WARNING "original: %s\n", existing->gh_ip);
print_symbol(KERN_WARNING "new: %s\n", gh->gh_ip);
@@ -1267,9 +1187,8 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
if (glops->go_unlock)
glops->go_unlock(gh);
- gl->gl_stamp = jiffies;
-
spin_lock(&gl->gl_spin);
+ gl->gl_stamp = jiffies;
}
clear_bit(GLF_LOCK, &gl->gl_flags);
@@ -1841,6 +1760,15 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait)
* Diagnostic routines to help debug distributed deadlock
*/
+static void gfs2_print_symbol(struct glock_iter *gi, const char *fmt,
+ unsigned long address)
+{
+ char buffer[KSYM_SYMBOL_LEN];
+
+ sprint_symbol(buffer, address);
+ print_dbg(gi, fmt, buffer);
+}
+
/**
* dump_holder - print information about a glock holder
* @str: a string naming the type of holder
@@ -1849,31 +1777,37 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait)
* Returns: 0 on success, -ENOBUFS when we run out of space
*/
-static int dump_holder(char *str, struct gfs2_holder *gh)
+static int dump_holder(struct glock_iter *gi, char *str,
+ struct gfs2_holder *gh)
{
unsigned int x;
- int error = -ENOBUFS;
-
- printk(KERN_INFO " %s\n", str);
- printk(KERN_INFO " owner = %ld\n",
- (gh->gh_owner) ? (long)gh->gh_owner->pid : -1);
- printk(KERN_INFO " gh_state = %u\n", gh->gh_state);
- printk(KERN_INFO " gh_flags =");
+ struct task_struct *gh_owner;
+
+ print_dbg(gi, " %s\n", str);
+ if (gh->gh_owner_pid) {
+ print_dbg(gi, " owner = %ld ", (long)gh->gh_owner_pid);
+ gh_owner = find_task_by_pid(gh->gh_owner_pid);
+ if (gh_owner)
+ print_dbg(gi, "(%s)\n", gh_owner->comm);
+ else
+ print_dbg(gi, "(ended)\n");
+ } else
+ print_dbg(gi, " owner = -1\n");
+ print_dbg(gi, " gh_state = %u\n", gh->gh_state);
+ print_dbg(gi, " gh_flags =");
for (x = 0; x < 32; x++)
if (gh->gh_flags & (1 << x))
- printk(" %u", x);
- printk(" \n");
- printk(KERN_INFO " error = %d\n", gh->gh_error);
- printk(KERN_INFO " gh_iflags =");
+ print_dbg(gi, " %u", x);
+ print_dbg(gi, " \n");
+ print_dbg(gi, " error = %d\n", gh->gh_error);
+ print_dbg(gi, " gh_iflags =");
for (x = 0; x < 32; x++)
if (test_bit(x, &gh->gh_iflags))
- printk(" %u", x);
- printk(" \n");
- print_symbol(KERN_INFO " initialized at: %s\n", gh->gh_ip);
-
- error = 0;
+ print_dbg(gi, " %u", x);
+ print_dbg(gi, " \n");
+ gfs2_print_symbol(gi, " initialized at: %s\n", gh->gh_ip);
- return error;
+ return 0;
}
/**
@@ -1883,25 +1817,20 @@ static int dump_holder(char *str, struct gfs2_holder *gh)
* Returns: 0 on success, -ENOBUFS when we run out of space
*/
-static int dump_inode(struct gfs2_inode *ip)
+static int dump_inode(struct glock_iter *gi, struct gfs2_inode *ip)
{
unsigned int x;
- int error = -ENOBUFS;
- printk(KERN_INFO " Inode:\n");
- printk(KERN_INFO " num = %llu %llu\n",
- (unsigned long long)ip->i_num.no_formal_ino,
- (unsigned long long)ip->i_num.no_addr);
- printk(KERN_INFO " type = %u\n", IF2DT(ip->i_inode.i_mode));
- printk(KERN_INFO " i_flags =");
+ print_dbg(gi, " Inode:\n");
+ print_dbg(gi, " num = %llu/%llu\n",
+ ip->i_num.no_formal_ino, ip->i_num.no_addr);
+ print_dbg(gi, " type = %u\n", IF2DT(ip->i_inode.i_mode));
+ print_dbg(gi, " i_flags =");
for (x = 0; x < 32; x++)
if (test_bit(x, &ip->i_flags))
- printk(" %u", x);
- printk(" \n");
-
- error = 0;
-
- return error;
+ print_dbg(gi, " %u", x);
+ print_dbg(gi, " \n");
+ return 0;
}
/**
@@ -1912,74 +1841,86 @@ static int dump_inode(struct gfs2_inode *ip)
* Returns: 0 on success, -ENOBUFS when we run out of space
*/
-static int dump_glock(struct gfs2_glock *gl)
+static int dump_glock(struct glock_iter *gi, struct gfs2_glock *gl)
{
struct gfs2_holder *gh;
unsigned int x;
int error = -ENOBUFS;
+ struct task_struct *gl_owner;
spin_lock(&gl->gl_spin);
- printk(KERN_INFO "Glock 0x%p (%u, %llu)\n", gl, gl->gl_name.ln_type,
- (unsigned long long)gl->gl_name.ln_number);
- printk(KERN_INFO " gl_flags =");
+ print_dbg(gi, "Glock 0x%p (%u, %llu)\n", gl, gl->gl_name.ln_type,
+ (unsigned long long)gl->gl_name.ln_number);
+ print_dbg(gi, " gl_flags =");
for (x = 0; x < 32; x++) {
if (test_bit(x, &gl->gl_flags))
- printk(" %u", x);
+ print_dbg(gi, " %u", x);
}
- printk(" \n");
- printk(KERN_INFO " gl_ref = %d\n", atomic_read(&gl->gl_ref));
- printk(KERN_INFO " gl_state = %u\n", gl->gl_state);
- printk(KERN_INFO " gl_owner = %s\n", gl->gl_owner->comm);
- print_symbol(KERN_INFO " gl_ip = %s\n", gl->gl_ip);
- printk(KERN_INFO " req_gh = %s\n", (gl->gl_req_gh) ? "yes" : "no");
- printk(KERN_INFO " req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no");
- printk(KERN_INFO " lvb_count = %d\n", atomic_read(&gl->gl_lvb_count));
- printk(KERN_INFO " object = %s\n", (gl->gl_object) ? "yes" : "no");
- printk(KERN_INFO " le = %s\n",
+ if (!test_bit(GLF_LOCK, &gl->gl_flags))
+ print_dbg(gi, " (unlocked)");
+ print_dbg(gi, " \n");
+ print_dbg(gi, " gl_ref = %d\n", atomic_read(&gl->gl_ref));
+ print_dbg(gi, " gl_state = %u\n", gl->gl_state);
+ if (gl->gl_owner_pid) {
+ gl_owner = find_task_by_pid(gl->gl_owner_pid);
+ if (gl_owner)
+ print_dbg(gi, " gl_owner = pid %d (%s)\n",
+ gl->gl_owner_pid, gl_owner->comm);
+ else
+ print_dbg(gi, " gl_owner = %d (ended)\n",
+ gl->gl_owner_pid);
+ } else
+ print_dbg(gi, " gl_owner = -1\n");
+ print_dbg(gi, " gl_ip = %lu\n", gl->gl_ip);
+ print_dbg(gi, " req_gh = %s\n", (gl->gl_req_gh) ? "yes" : "no");
+ print_dbg(gi, " req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no");
+ print_dbg(gi, " lvb_count = %d\n", atomic_read(&gl->gl_lvb_count));
+ print_dbg(gi, " object = %s\n", (gl->gl_object) ? "yes" : "no");
+ print_dbg(gi, " le = %s\n",
(list_empty(&gl->gl_le.le_list)) ? "no" : "yes");
- printk(KERN_INFO " reclaim = %s\n",
- (list_empty(&gl->gl_reclaim)) ? "no" : "yes");
+ print_dbg(gi, " reclaim = %s\n",
+ (list_empty(&gl->gl_reclaim)) ? "no" : "yes");
if (gl->gl_aspace)
- printk(KERN_INFO " aspace = 0x%p nrpages = %lu\n", gl->gl_aspace,
- gl->gl_aspace->i_mapping->nrpages);
+ print_dbg(gi, " aspace = 0x%p nrpages = %lu\n", gl->gl_aspace,
+ gl->gl_aspace->i_mapping->nrpages);
else
- printk(KERN_INFO " aspace = no\n");
- printk(KERN_INFO " ail = %d\n", atomic_read(&gl->gl_ail_count));
+ print_dbg(gi, " aspace = no\n");
+ print_dbg(gi, " ail = %d\n", atomic_read(&gl->gl_ail_count));
if (gl->gl_req_gh) {
- error = dump_holder("Request", gl->gl_req_gh);
+ error = dump_holder(gi, "Request", gl->gl_req_gh);
if (error)
goto out;
}
list_for_each_entry(gh, &gl->gl_holders, gh_list) {
- error = dump_holder("Holder", gh);
+ error = dump_holder(gi, "Holder", gh);
if (error)
goto out;
}
list_for_each_entry(gh, &gl->gl_waiters1, gh_list) {
- error = dump_holder("Waiter1", gh);
- if (error)
- goto out;
- }
- list_for_each_entry(gh, &gl->gl_waiters2, gh_list) {
- error = dump_holder("Waiter2", gh);
+ error = dump_holder(gi, "Waiter1", gh);
if (error)
goto out;
}
list_for_each_entry(gh, &gl->gl_waiters3, gh_list) {
- error = dump_holder("Waiter3", gh);
+ error = dump_holder(gi, "Waiter3", gh);
if (error)
goto out;
}
+ if (test_bit(GLF_DEMOTE, &gl->gl_flags)) {
+ print_dbg(gi, " Demotion req to state %u (%llu uS ago)\n",
+ gl->gl_demote_state,
+ (u64)(jiffies - gl->gl_demote_time)*(1000000/HZ));
+ }
if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) {
if (!test_bit(GLF_LOCK, &gl->gl_flags) &&
- list_empty(&gl->gl_holders)) {
- error = dump_inode(gl->gl_object);
+ list_empty(&gl->gl_holders)) {
+ error = dump_inode(gi, gl->gl_object);
if (error)
goto out;
} else {
error = -ENOBUFS;
- printk(KERN_INFO " Inode: busy\n");
+ print_dbg(gi, " Inode: busy\n");
}
}
@@ -2014,7 +1955,7 @@ static int gfs2_dump_lockstate(struct gfs2_sbd *sdp)
if (gl->gl_sbd != sdp)
continue;
- error = dump_glock(gl);
+ error = dump_glock(NULL, gl);
if (error)
break;
}
@@ -2043,3 +1984,189 @@ int __init gfs2_glock_init(void)
return 0;
}
+static int gfs2_glock_iter_next(struct glock_iter *gi)
+{
+ read_lock(gl_lock_addr(gi->hash));
+ while (1) {
+ if (!gi->hb_list) { /* If we don't have a hash bucket yet */
+ gi->hb_list = &gl_hash_table[gi->hash].hb_list;
+ if (hlist_empty(gi->hb_list)) {
+ read_unlock(gl_lock_addr(gi->hash));
+ gi->hash++;
+ read_lock(gl_lock_addr(gi->hash));
+ gi->hb_list = NULL;
+ if (gi->hash >= GFS2_GL_HASH_SIZE) {
+ read_unlock(gl_lock_addr(gi->hash));
+ return 1;
+ }
+ else
+ continue;
+ }
+ if (!hlist_empty(gi->hb_list)) {
+ gi->gl = list_entry(gi->hb_list->first,
+ struct gfs2_glock,
+ gl_list);
+ }
+ } else {
+ if (gi->gl->gl_list.next == NULL) {
+ read_unlock(gl_lock_addr(gi->hash));
+ gi->hash++;
+ read_lock(gl_lock_addr(gi->hash));
+ gi->hb_list = NULL;
+ continue;
+ }
+ gi->gl = list_entry(gi->gl->gl_list.next,
+ struct gfs2_glock, gl_list);
+ }
+ if (gi->gl)
+ break;
+ }
+ read_unlock(gl_lock_addr(gi->hash));
+ return 0;
+}
+
+static void gfs2_glock_iter_free(struct glock_iter *gi)
+{
+ kfree(gi);
+}
+
+static struct glock_iter *gfs2_glock_iter_init(struct gfs2_sbd *sdp)
+{
+ struct glock_iter *gi;
+
+ gi = kmalloc(sizeof (*gi), GFP_KERNEL);
+ if (!gi)
+ return NULL;
+
+ gi->sdp = sdp;
+ gi->hash = 0;
+ gi->gl = NULL;
+ gi->hb_list = NULL;
+ gi->seq = NULL;
+ memset(gi->string, 0, sizeof(gi->string));
+
+ if (gfs2_glock_iter_next(gi)) {
+ gfs2_glock_iter_free(gi);
+ return NULL;
+ }
+
+ return gi;
+}
+
+static void *gfs2_glock_seq_start(struct seq_file *file, loff_t *pos)
+{
+ struct glock_iter *gi;
+ loff_t n = *pos;
+
+ gi = gfs2_glock_iter_init(file->private);
+ if (!gi)
+ return NULL;
+
+ while (n--) {
+ if (gfs2_glock_iter_next(gi)) {
+ gfs2_glock_iter_free(gi);
+ return NULL;
+ }
+ }
+
+ return gi;
+}
+
+static void *gfs2_glock_seq_next(struct seq_file *file, void *iter_ptr,
+ loff_t *pos)
+{
+ struct glock_iter *gi = iter_ptr;
+
+ (*pos)++;
+
+ if (gfs2_glock_iter_next(gi)) {
+ gfs2_glock_iter_free(gi);
+ return NULL;
+ }
+
+ return gi;
+}
+
+static void gfs2_glock_seq_stop(struct seq_file *file, void *iter_ptr)
+{
+ /* nothing for now */
+}
+
+static int gfs2_glock_seq_show(struct seq_file *file, void *iter_ptr)
+{
+ struct glock_iter *gi = iter_ptr;
+
+ gi->seq = file;
+ dump_glock(gi, gi->gl);
+
+ return 0;
+}
+
+static struct seq_operations gfs2_glock_seq_ops = {
+ .start = gfs2_glock_seq_start,
+ .next = gfs2_glock_seq_next,
+ .stop = gfs2_glock_seq_stop,
+ .show = gfs2_glock_seq_show,
+};
+
+static int gfs2_debugfs_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ int ret;
+
+ ret = seq_open(file, &gfs2_glock_seq_ops);
+ if (ret)
+ return ret;
+
+ seq = file->private_data;
+ seq->private = inode->i_private;
+
+ return 0;
+}
+
+static const struct file_operations gfs2_debug_fops = {
+ .owner = THIS_MODULE,
+ .open = gfs2_debugfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release
+};
+
+int gfs2_create_debugfs_file(struct gfs2_sbd *sdp)
+{
+ sdp->debugfs_dir = debugfs_create_dir(sdp->sd_table_name, gfs2_root);
+ if (!sdp->debugfs_dir)
+ return -ENOMEM;
+ sdp->debugfs_dentry_glocks = debugfs_create_file("glocks",
+ S_IFREG | S_IRUGO,
+ sdp->debugfs_dir, sdp,
+ &gfs2_debug_fops);
+ if (!sdp->debugfs_dentry_glocks)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp)
+{
+ if (sdp && sdp->debugfs_dir) {
+ if (sdp->debugfs_dentry_glocks) {
+ debugfs_remove(sdp->debugfs_dentry_glocks);
+ sdp->debugfs_dentry_glocks = NULL;
+ }
+ debugfs_remove(sdp->debugfs_dir);
+ sdp->debugfs_dir = NULL;
+ }
+}
+
+int gfs2_register_debugfs(void)
+{
+ gfs2_root = debugfs_create_dir("gfs2", NULL);
+ return gfs2_root ? 0 : -ENOMEM;
+}
+
+void gfs2_unregister_debugfs(void)
+{
+ debugfs_remove(gfs2_root);
+ gfs2_root = NULL;
+}
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index f50e40c..11477ca 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -38,7 +38,7 @@ static inline int gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
/* Look in glock's list of holders for one with current task as owner */
spin_lock(&gl->gl_spin);
list_for_each_entry(gh, &gl->gl_holders, gh_list) {
- if (gh->gh_owner == current) {
+ if (gh->gh_owner_pid == current->pid) {
locked = 1;
break;
}
@@ -67,7 +67,7 @@ static inline int gfs2_glock_is_blocking(struct gfs2_glock *gl)
{
int ret;
spin_lock(&gl->gl_spin);
- ret = !list_empty(&gl->gl_waiters2) || !list_empty(&gl->gl_waiters3);
+ ret = test_bit(GLF_DEMOTE, &gl->gl_flags) || !list_empty(&gl->gl_waiters3);
spin_unlock(&gl->gl_spin);
return ret;
}
@@ -135,5 +135,9 @@ void gfs2_scand_internal(struct gfs2_sbd *sdp);
void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait);
int __init gfs2_glock_init(void);
+int gfs2_create_debugfs_file(struct gfs2_sbd *sdp);
+void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp);
+int gfs2_register_debugfs(void);
+void gfs2_unregister_debugfs(void);
#endif /* __GLOCK_DOT_H__ */
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 39c8ae2..7b82657 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -163,10 +163,7 @@ static void inode_go_sync(struct gfs2_glock *gl)
if (ip) {
struct address_space *mapping = ip->i_inode.i_mapping;
int error = filemap_fdatawait(mapping);
- if (error == -ENOSPC)
- set_bit(AS_ENOSPC, &mapping->flags);
- else if (error)
- set_bit(AS_EIO, &mapping->flags);
+ mapping_set_error(mapping, error);
}
clear_bit(GLF_DIRTY, &gl->gl_flags);
gfs2_ail_empty_gl(gl);
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 49f0dbf..d995441 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -115,11 +115,8 @@ enum {
/* Actions */
HIF_MUTEX = 0,
HIF_PROMOTE = 1,
- HIF_DEMOTE = 2,
/* States */
- HIF_ALLOCED = 4,
- HIF_DEALLOC = 5,
HIF_HOLDER = 6,
HIF_FIRST = 7,
HIF_ABORTED = 9,
@@ -130,7 +127,7 @@ struct gfs2_holder {
struct list_head gh_list;
struct gfs2_glock *gh_gl;
- struct task_struct *gh_owner;
+ pid_t gh_owner_pid;
unsigned int gh_state;
unsigned gh_flags;
@@ -142,8 +139,8 @@ struct gfs2_holder {
enum {
GLF_LOCK = 1,
GLF_STICKY = 2,
+ GLF_DEMOTE = 3,
GLF_DIRTY = 5,
- GLF_SKIP_WAITERS2 = 6,
};
struct gfs2_glock {
@@ -156,11 +153,12 @@ struct gfs2_glock {
unsigned int gl_state;
unsigned int gl_hash;
- struct task_struct *gl_owner;
+ unsigned int gl_demote_state; /* state requested by remote node */
+ unsigned long gl_demote_time; /* time of first demote request */
+ pid_t gl_owner_pid;
unsigned long gl_ip;
struct list_head gl_holders;
struct list_head gl_waiters1; /* HIF_MUTEX */
- struct list_head gl_waiters2; /* HIF_DEMOTE */
struct list_head gl_waiters3; /* HIF_PROMOTE */
const struct gfs2_glock_operations *gl_ops;
@@ -611,6 +609,8 @@ struct gfs2_sbd {
unsigned long sd_last_warning;
struct vfsmount *sd_gfs2mnt;
+ struct dentry *debugfs_dir; /* debugfs directory */
+ struct dentry *debugfs_dentry_glocks; /* for debugfs */
};
#endif /* __INCORE_DOT_H__ */
diff --git a/fs/gfs2/locking/dlm/lock.c b/fs/gfs2/locking/dlm/lock.c
index b167add..c305255 100644
--- a/fs/gfs2/locking/dlm/lock.c
+++ b/fs/gfs2/locking/dlm/lock.c
@@ -151,7 +151,7 @@ static inline unsigned int make_flags(struct gdlm_lock *lp,
/* make_strname - convert GFS lock numbers to a string */
-static inline void make_strname(struct lm_lockname *lockname,
+static inline void make_strname(const struct lm_lockname *lockname,
struct gdlm_strname *str)
{
sprintf(str->name, "%8x%16llx", lockname->ln_type,
@@ -169,6 +169,7 @@ static int gdlm_create_lp(struct gdlm_ls *ls, struct lm_lockname *name,
return -ENOMEM;
lp->lockname = *name;
+ make_strname(name, &lp->strname);
lp->ls = ls;
lp->cur = DLM_LOCK_IV;
lp->lvb = NULL;
@@ -227,7 +228,6 @@ void gdlm_put_lock(void *lock)
unsigned int gdlm_do_lock(struct gdlm_lock *lp)
{
struct gdlm_ls *ls = lp->ls;
- struct gdlm_strname str;
int error, bast = 1;
/*
@@ -249,8 +249,6 @@ unsigned int gdlm_do_lock(struct gdlm_lock *lp)
if (test_bit(LFL_NOBAST, &lp->flags))
bast = 0;
- make_strname(&lp->lockname, &str);
-
set_bit(LFL_ACTIVE, &lp->flags);
log_debug("lk %x,%llx id %x %d,%d %x", lp->lockname.ln_type,
@@ -258,8 +256,8 @@ unsigned int gdlm_do_lock(struct gdlm_lock *lp)
lp->cur, lp->req, lp->lkf);
error = dlm_lock(ls->dlm_lockspace, lp->req, &lp->lksb, lp->lkf,
- str.name, str.namelen, 0, gdlm_ast, lp,
- bast ? gdlm_bast : NULL);
+ lp->strname.name, lp->strname.namelen, 0, gdlm_ast,
+ lp, bast ? gdlm_bast : NULL);
if ((error == -EAGAIN) && (lp->lkf & DLM_LKF_NOQUEUE)) {
lp->lksb.sb_status = -EAGAIN;
@@ -268,7 +266,7 @@ unsigned int gdlm_do_lock(struct gdlm_lock *lp)
}
if (error) {
- log_debug("%s: gdlm_lock %x,%llx err=%d cur=%d req=%d lkf=%x "
+ log_error("%s: gdlm_lock %x,%llx err=%d cur=%d req=%d lkf=%x "
"flags=%lx", ls->fsname, lp->lockname.ln_type,
(unsigned long long)lp->lockname.ln_number, error,
lp->cur, lp->req, lp->lkf, lp->flags);
@@ -296,7 +294,7 @@ static unsigned int gdlm_do_unlock(struct gdlm_lock *lp)
error = dlm_unlock(ls->dlm_lockspace, lp->lksb.sb_lkid, lkf, NULL, lp);
if (error) {
- log_debug("%s: gdlm_unlock %x,%llx err=%d cur=%d req=%d lkf=%x "
+ log_error("%s: gdlm_unlock %x,%llx err=%d cur=%d req=%d lkf=%x "
"flags=%lx", ls->fsname, lp->lockname.ln_type,
(unsigned long long)lp->lockname.ln_number, error,
lp->cur, lp->req, lp->lkf, lp->flags);
diff --git a/fs/gfs2/locking/dlm/lock_dlm.h b/fs/gfs2/locking/dlm/lock_dlm.h
index a87c7bf..d074c6e 100644
--- a/fs/gfs2/locking/dlm/lock_dlm.h
+++ b/fs/gfs2/locking/dlm/lock_dlm.h
@@ -36,7 +36,7 @@
#define GDLM_STRNAME_BYTES 24
#define GDLM_LVB_SIZE 32
-#define GDLM_DROP_COUNT 200000
+#define GDLM_DROP_COUNT 0
#define GDLM_DROP_PERIOD 60
#define GDLM_NAME_LEN 128
@@ -106,6 +106,7 @@ enum {
struct gdlm_lock {
struct gdlm_ls *ls;
struct lm_lockname lockname;
+ struct gdlm_strname strname;
char *lvb;
struct dlm_lksb lksb;
diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/gfs2/locking/dlm/plock.c
index 1dd4215..f82495e 100644
--- a/fs/gfs2/locking/dlm/plock.c
+++ b/fs/gfs2/locking/dlm/plock.c
@@ -25,6 +25,15 @@ struct plock_op {
struct gdlm_plock_info info;
};
+struct plock_xop {
+ struct plock_op xop;
+ void *callback;
+ void *fl;
+ void *file;
+ struct file_lock flc;
+};
+
+
static inline void set_version(struct gdlm_plock_info *info)
{
info->version[0] = GDLM_PLOCK_VERSION_MAJOR;
@@ -64,12 +73,14 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
{
struct gdlm_ls *ls = lockspace;
struct plock_op *op;
+ struct plock_xop *xop;
int rv;
- op = kzalloc(sizeof(*op), GFP_KERNEL);
- if (!op)
+ xop = kzalloc(sizeof(*xop), GFP_KERNEL);
+ if (!xop)
return -ENOMEM;
+ op = &xop->xop;
op->info.optype = GDLM_PLOCK_OP_LOCK;
op->info.pid = fl->fl_pid;
op->info.ex = (fl->fl_type == F_WRLCK);
@@ -79,9 +90,21 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
op->info.start = fl->fl_start;
op->info.end = fl->fl_end;
op->info.owner = (__u64)(long) fl->fl_owner;
+ if (fl->fl_lmops && fl->fl_lmops->fl_grant) {
+ xop->callback = fl->fl_lmops->fl_grant;
+ locks_init_lock(&xop->flc);
+ locks_copy_lock(&xop->flc, fl);
+ xop->fl = fl;
+ xop->file = file;
+ } else
+ xop->callback = NULL;
send_op(op);
- wait_event(recv_wq, (op->done != 0));
+
+ if (xop->callback == NULL)
+ wait_event(recv_wq, (op->done != 0));
+ else
+ return -EINPROGRESS;
spin_lock(&ops_lock);
if (!list_empty(&op->list)) {
@@ -99,7 +122,63 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
(unsigned long long)name->ln_number);
}
- kfree(op);
+ kfree(xop);
+ return rv;
+}
+
+/* Returns failure iff a succesful lock operation should be canceled */
+static int gdlm_plock_callback(struct plock_op *op)
+{
+ struct file *file;
+ struct file_lock *fl;
+ struct file_lock *flc;
+ int (*notify)(void *, void *, int) = NULL;
+ struct plock_xop *xop = (struct plock_xop *)op;
+ int rv = 0;
+
+ spin_lock(&ops_lock);
+ if (!list_empty(&op->list)) {
+ printk(KERN_INFO "plock op on list\n");
+ list_del(&op->list);
+ }
+ spin_unlock(&ops_lock);
+
+ /* check if the following 2 are still valid or make a copy */
+ file = xop->file;
+ flc = &xop->flc;
+ fl = xop->fl;
+ notify = xop->callback;
+
+ if (op->info.rv) {
+ notify(flc, NULL, op->info.rv);
+ goto out;
+ }
+
+ /* got fs lock; bookkeep locally as well: */
+ flc->fl_flags &= ~FL_SLEEP;
+ if (posix_lock_file(file, flc, NULL)) {
+ /*
+ * This can only happen in the case of kmalloc() failure.
+ * The filesystem's own lock is the authoritative lock,
+ * so a failure to get the lock locally is not a disaster.
+ * As long as GFS cannot reliably cancel locks (especially
+ * in a low-memory situation), we're better off ignoring
+ * this failure than trying to recover.
+ */
+ log_error("gdlm_plock: vfs lock error file %p fl %p",
+ file, fl);
+ }
+
+ rv = notify(flc, NULL, 0);
+ if (rv) {
+ /* XXX: We need to cancel the fs lock here: */
+ printk("gfs2 lock granted after lock request failed;"
+ " dangling lock!\n");
+ goto out;
+ }
+
+out:
+ kfree(xop);
return rv;
}
@@ -138,6 +217,9 @@ int gdlm_punlock(void *lockspace, struct lm_lockname *name,
rv = op->info.rv;
+ if (rv == -ENOENT)
+ rv = 0;
+
kfree(op);
return rv;
}
@@ -161,6 +243,7 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
op->info.start = fl->fl_start;
op->info.end = fl->fl_end;
+
send_op(op);
wait_event(recv_wq, (op->done != 0));
@@ -173,9 +256,10 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
rv = op->info.rv;
- if (rv == 0)
- fl->fl_type = F_UNLCK;
- else if (rv > 0) {
+ fl->fl_type = F_UNLCK;
+ if (rv == -ENOENT)
+ rv = 0;
+ else if (rv == 0 && op->info.pid != fl->fl_pid) {
fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK;
fl->fl_pid = op->info.pid;
fl->fl_start = op->info.start;
@@ -243,9 +327,14 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
}
spin_unlock(&ops_lock);
- if (found)
- wake_up(&recv_wq);
- else
+ if (found) {
+ struct plock_xop *xop;
+ xop = (struct plock_xop *)op;
+ if (xop->callback)
+ count = gdlm_plock_callback(op);
+ else
+ wake_up(&recv_wq);
+ } else
printk(KERN_INFO "gdlm dev_write no op %x %llx\n", info.fsid,
(unsigned long long)info.number);
return count;
diff --git a/fs/gfs2/locking/nolock/main.c b/fs/gfs2/locking/nolock/main.c
index acfbc94..0d149c8c 100644
--- a/fs/gfs2/locking/nolock/main.c
+++ b/fs/gfs2/locking/nolock/main.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/fs.h>
-#include <linux/smp_lock.h>
#include <linux/lm_interface.h>
struct nolock_lockspace {
@@ -164,13 +163,7 @@ static void nolock_unhold_lvb(void *lock, char *lvb)
static int nolock_plock_get(void *lockspace, struct lm_lockname *name,
struct file *file, struct file_lock *fl)
{
- struct file_lock tmp;
- int ret;
-
- ret = posix_test_lock(file, fl, &tmp);
- fl->fl_type = F_UNLCK;
- if (ret)
- memcpy(fl, &tmp, sizeof(struct file_lock));
+ posix_test_lock(file, fl);
return 0;
}
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 16bb4b4..f82d84d 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -33,16 +33,17 @@ static void glock_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
tr->tr_touched = 1;
- if (!list_empty(&le->le_list))
- return;
-
gl = container_of(le, struct gfs2_glock, gl_le);
if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(gl)))
return;
- gfs2_glock_hold(gl);
- set_bit(GLF_DIRTY, &gl->gl_flags);
gfs2_log_lock(sdp);
+ if (!list_empty(&le->le_list)){
+ gfs2_log_unlock(sdp);
+ return;
+ }
+ gfs2_glock_hold(gl);
+ set_bit(GLF_DIRTY, &gl->gl_flags);
sdp->sd_log_num_gl++;
list_add(&le->le_list, &sdp->sd_log_le_gl);
gfs2_log_unlock(sdp);
@@ -415,13 +416,14 @@ static void rg_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
tr->tr_touched = 1;
- if (!list_empty(&le->le_list))
- return;
-
rgd = container_of(le, struct gfs2_rgrpd, rd_le);
- gfs2_rgrp_bh_hold(rgd);
gfs2_log_lock(sdp);
+ if (!list_empty(&le->le_list)){
+ gfs2_log_unlock(sdp);
+ return;
+ }
+ gfs2_rgrp_bh_hold(rgd);
sdp->sd_log_num_rg++;
list_add(&le->le_list, &sdp->sd_log_le_rg);
gfs2_log_unlock(sdp);
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index 6e8a598..e460487 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -27,8 +27,7 @@
static void gfs2_init_inode_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
{
struct gfs2_inode *ip = foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
inode_init_once(&ip->i_inode);
spin_lock_init(&ip->i_spin);
init_rwsem(&ip->i_rw_mutex);
@@ -39,13 +38,11 @@ static void gfs2_init_inode_once(void *foo, struct kmem_cache *cachep, unsigned
static void gfs2_init_glock_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
{
struct gfs2_glock *gl = foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
INIT_HLIST_NODE(&gl->gl_list);
spin_lock_init(&gl->gl_spin);
INIT_LIST_HEAD(&gl->gl_holders);
INIT_LIST_HEAD(&gl->gl_waiters1);
- INIT_LIST_HEAD(&gl->gl_waiters2);
INIT_LIST_HEAD(&gl->gl_waiters3);
gl->gl_lvb = NULL;
atomic_set(&gl->gl_lvb_count, 0);
@@ -103,6 +100,8 @@ static int __init init_gfs2_fs(void)
if (error)
goto fail_unregister;
+ gfs2_register_debugfs();
+
printk("GFS2 (built %s %s) installed\n", __DATE__, __TIME__);
return 0;
@@ -130,6 +129,7 @@ fail:
static void __exit exit_gfs2_fs(void)
{
+ gfs2_unregister_debugfs();
unregister_filesystem(&gfs2_fs_type);
unregister_filesystem(&gfs2meta_fs_type);
diff --git a/fs/gfs2/mount.c b/fs/gfs2/mount.c
index 32caecd..4864659 100644
--- a/fs/gfs2/mount.c
+++ b/fs/gfs2/mount.c
@@ -13,6 +13,7 @@
#include <linux/buffer_head.h>
#include <linux/gfs2_ondisk.h>
#include <linux/lm_interface.h>
+#include <linux/parser.h>
#include "gfs2.h"
#include "incore.h"
@@ -20,6 +21,52 @@
#include "sys.h"
#include "util.h"
+enum {
+ Opt_lockproto,
+ Opt_locktable,
+ Opt_hostdata,
+ Opt_spectator,
+ Opt_ignore_local_fs,
+ Opt_localflocks,
+ Opt_localcaching,
+ Opt_debug,
+ Opt_nodebug,
+ Opt_upgrade,
+ Opt_num_glockd,
+ Opt_acl,
+ Opt_noacl,
+ Opt_quota_off,
+ Opt_quota_account,
+ Opt_quota_on,
+ Opt_suiddir,
+ Opt_nosuiddir,
+ Opt_data_writeback,
+ Opt_data_ordered,
+};
+
+static match_table_t tokens = {
+ {Opt_lockproto, "lockproto=%s"},
+ {Opt_locktable, "locktable=%s"},
+ {Opt_hostdata, "hostdata=%s"},
+ {Opt_spectator, "spectator"},
+ {Opt_ignore_local_fs, "ignore_local_fs"},
+ {Opt_localflocks, "localflocks"},
+ {Opt_localcaching, "localcaching"},
+ {Opt_debug, "debug"},
+ {Opt_nodebug, "nodebug"},
+ {Opt_upgrade, "upgrade"},
+ {Opt_num_glockd, "num_glockd=%d"},
+ {Opt_acl, "acl"},
+ {Opt_noacl, "noacl"},
+ {Opt_quota_off, "quota=off"},
+ {Opt_quota_account, "quota=account"},
+ {Opt_quota_on, "quota=on"},
+ {Opt_suiddir, "suiddir"},
+ {Opt_nosuiddir, "nosuiddir"},
+ {Opt_data_writeback, "data=writeback"},
+ {Opt_data_ordered, "data=ordered"}
+};
+
/**
* gfs2_mount_args - Parse mount options
* @sdp:
@@ -54,146 +101,150 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount)
process them */
for (options = data; (o = strsep(&options, ",")); ) {
+ int token, option;
+ substring_t tmp[MAX_OPT_ARGS];
+
if (!*o)
continue;
- v = strchr(o, '=');
- if (v)
- *v++ = 0;
+ token = match_token(o, tokens, tmp);
+ switch (token) {
+ case Opt_lockproto:
+ v = match_strdup(&tmp[0]);
+ if (!v) {
+ fs_info(sdp, "no memory for lockproto\n");
+ error = -ENOMEM;
+ goto out_error;
+ }
- if (!strcmp(o, "lockproto")) {
- if (!v)
- goto need_value;
- if (remount && strcmp(v, args->ar_lockproto))
+ if (remount && strcmp(v, args->ar_lockproto)) {
+ kfree(v);
goto cant_remount;
+ }
+
strncpy(args->ar_lockproto, v, GFS2_LOCKNAME_LEN);
args->ar_lockproto[GFS2_LOCKNAME_LEN - 1] = 0;
- }
+ kfree(v);
+ break;
+ case Opt_locktable:
+ v = match_strdup(&tmp[0]);
+ if (!v) {
+ fs_info(sdp, "no memory for locktable\n");
+ error = -ENOMEM;
+ goto out_error;
+ }
- else if (!strcmp(o, "locktable")) {
- if (!v)
- goto need_value;
- if (remount && strcmp(v, args->ar_locktable))
+ if (remount && strcmp(v, args->ar_locktable)) {
+ kfree(v);
goto cant_remount;
+ }
+
strncpy(args->ar_locktable, v, GFS2_LOCKNAME_LEN);
- args->ar_locktable[GFS2_LOCKNAME_LEN - 1] = 0;
- }
+ args->ar_locktable[GFS2_LOCKNAME_LEN - 1] = 0;
+ kfree(v);
+ break;
+ case Opt_hostdata:
+ v = match_strdup(&tmp[0]);
+ if (!v) {
+ fs_info(sdp, "no memory for hostdata\n");
+ error = -ENOMEM;
+ goto out_error;
+ }
- else if (!strcmp(o, "hostdata")) {
- if (!v)
- goto need_value;
- if (remount && strcmp(v, args->ar_hostdata))
+ if (remount && strcmp(v, args->ar_hostdata)) {
+ kfree(v);
goto cant_remount;
+ }
+
strncpy(args->ar_hostdata, v, GFS2_LOCKNAME_LEN);
args->ar_hostdata[GFS2_LOCKNAME_LEN - 1] = 0;
- }
-
- else if (!strcmp(o, "spectator")) {
+ kfree(v);
+ break;
+ case Opt_spectator:
if (remount && !args->ar_spectator)
goto cant_remount;
args->ar_spectator = 1;
sdp->sd_vfs->s_flags |= MS_RDONLY;
- }
-
- else if (!strcmp(o, "ignore_local_fs")) {
+ break;
+ case Opt_ignore_local_fs:
if (remount && !args->ar_ignore_local_fs)
goto cant_remount;
args->ar_ignore_local_fs = 1;
- }
-
- else if (!strcmp(o, "localflocks")) {
+ break;
+ case Opt_localflocks:
if (remount && !args->ar_localflocks)
goto cant_remount;
args->ar_localflocks = 1;
- }
-
- else if (!strcmp(o, "localcaching")) {
+ break;
+ case Opt_localcaching:
if (remount && !args->ar_localcaching)
goto cant_remount;
args->ar_localcaching = 1;
- }
-
- else if (!strcmp(o, "debug"))
+ break;
+ case Opt_debug:
args->ar_debug = 1;
-
- else if (!strcmp(o, "nodebug"))
+ break;
+ case Opt_nodebug:
args->ar_debug = 0;
-
- else if (!strcmp(o, "upgrade")) {
+ break;
+ case Opt_upgrade:
if (remount && !args->ar_upgrade)
goto cant_remount;
args->ar_upgrade = 1;
- }
+ break;
+ case Opt_num_glockd:
+ if ((error = match_int(&tmp[0], &option))) {
+ fs_info(sdp, "problem getting num_glockd\n");
+ goto out_error;
+ }
- else if (!strcmp(o, "num_glockd")) {
- unsigned int x;
- if (!v)
- goto need_value;
- sscanf(v, "%u", &x);
- if (remount && x != args->ar_num_glockd)
+ if (remount && option != args->ar_num_glockd)
goto cant_remount;
- if (!x || x > GFS2_GLOCKD_MAX) {
+ if (!option || option > GFS2_GLOCKD_MAX) {
fs_info(sdp, "0 < num_glockd <= %u (not %u)\n",
- GFS2_GLOCKD_MAX, x);
+ GFS2_GLOCKD_MAX, option);
error = -EINVAL;
- break;
+ goto out_error;
}
- args->ar_num_glockd = x;
- }
-
- else if (!strcmp(o, "acl")) {
+ args->ar_num_glockd = option;
+ break;
+ case Opt_acl:
args->ar_posix_acl = 1;
sdp->sd_vfs->s_flags |= MS_POSIXACL;
- }
-
- else if (!strcmp(o, "noacl")) {
+ break;
+ case Opt_noacl:
args->ar_posix_acl = 0;
sdp->sd_vfs->s_flags &= ~MS_POSIXACL;
- }
-
- else if (!strcmp(o, "quota")) {
- if (!v)
- goto need_value;
- if (!strcmp(v, "off"))
- args->ar_quota = GFS2_QUOTA_OFF;
- else if (!strcmp(v, "account"))
- args->ar_quota = GFS2_QUOTA_ACCOUNT;
- else if (!strcmp(v, "on"))
- args->ar_quota = GFS2_QUOTA_ON;
- else {
- fs_info(sdp, "invalid value for quota\n");
- error = -EINVAL;
- break;
- }
- }
-
- else if (!strcmp(o, "suiddir"))
+ break;
+ case Opt_quota_off:
+ args->ar_quota = GFS2_QUOTA_OFF;
+ break;
+ case Opt_quota_account:
+ args->ar_quota = GFS2_QUOTA_ACCOUNT;
+ break;
+ case Opt_quota_on:
+ args->ar_quota = GFS2_QUOTA_ON;
+ break;
+ case Opt_suiddir:
args->ar_suiddir = 1;
-
- else if (!strcmp(o, "nosuiddir"))
+ break;
+ case Opt_nosuiddir:
args->ar_suiddir = 0;
-
- else if (!strcmp(o, "data")) {
- if (!v)
- goto need_value;
- if (!strcmp(v, "writeback"))
- args->ar_data = GFS2_DATA_WRITEBACK;
- else if (!strcmp(v, "ordered"))
- args->ar_data = GFS2_DATA_ORDERED;
- else {
- fs_info(sdp, "invalid value for data\n");
- error = -EINVAL;
- break;
- }
- }
-
- else {
+ break;
+ case Opt_data_writeback:
+ args->ar_data = GFS2_DATA_WRITEBACK;
+ break;
+ case Opt_data_ordered:
+ args->ar_data = GFS2_DATA_ORDERED;
+ break;
+ default:
fs_info(sdp, "unknown option: %s\n", o);
error = -EINVAL;
- break;
+ goto out_error;
}
}
+out_error:
if (error)
fs_info(sdp, "invalid mount option(s)\n");
@@ -202,10 +253,6 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount)
return error;
-need_value:
- fs_info(sdp, "need value for option %s\n", o);
- return -EINVAL;
-
cant_remount:
fs_info(sdp, "can't remount with option %s\n", o);
return -EINVAL;
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index b3b7e84..30c1562 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -197,7 +197,19 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
void *kaddr;
int error;
- BUG_ON(page->index);
+ /*
+ * Due to the order of unstuffing files and ->nopage(), we can be
+ * asked for a zero page in the case of a stuffed file being extended,
+ * so we need to supply one here. It doesn't happen often.
+ */
+ if (unlikely(page->index)) {
+ kaddr = kmap_atomic(page, KM_USER0);
+ memset(kaddr, 0, PAGE_CACHE_SIZE);
+ kunmap_atomic(kaddr, KM_USER0);
+ flush_dcache_page(page);
+ SetPageUptodate(page);
+ return 0;
+ }
error = gfs2_meta_inode_buffer(ip, &dibh);
if (error)
@@ -208,9 +220,8 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
ip->i_di.di_size);
memset(kaddr + ip->i_di.di_size, 0, PAGE_CACHE_SIZE - ip->i_di.di_size);
kunmap_atomic(kaddr, KM_USER0);
-
+ flush_dcache_page(page);
brelse(dibh);
-
SetPageUptodate(page);
return 0;
@@ -507,7 +518,9 @@ static int gfs2_commit_write(struct file *file, struct page *page,
gfs2_quota_unlock(ip);
gfs2_alloc_put(ip);
}
+ unlock_page(page);
gfs2_glock_dq_m(1, &ip->i_gh);
+ lock_page(page);
gfs2_holder_uninit(&ip->i_gh);
return 0;
@@ -520,7 +533,9 @@ fail_endtrans:
gfs2_quota_unlock(ip);
gfs2_alloc_put(ip);
}
+ unlock_page(page);
gfs2_glock_dq_m(1, &ip->i_gh);
+ lock_page(page);
gfs2_holder_uninit(&ip->i_gh);
fail_nounlock:
ClearPageUptodate(page);
diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c
index c6bac6b..a6fdc52 100644
--- a/fs/gfs2/ops_dentry.c
+++ b/fs/gfs2/ops_dentry.c
@@ -11,7 +11,6 @@
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
-#include <linux/smp_lock.h>
#include <linux/gfs2_ondisk.h>
#include <linux/crc32.h>
#include <linux/lm_interface.h>
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index b50180e..064df88 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -15,7 +15,6 @@
#include <linux/uio.h>
#include <linux/blkdev.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/gfs2_ondisk.h>
#include <linux/ext2_fs.h>
@@ -513,18 +512,18 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
if (sdp->sd_args.ar_localflocks) {
if (IS_GETLK(cmd)) {
- struct file_lock tmp;
- int ret;
- ret = posix_test_lock(file, fl, &tmp);
- fl->fl_type = F_UNLCK;
- if (ret)
- memcpy(fl, &tmp, sizeof(struct file_lock));
+ posix_test_lock(file, fl);
return 0;
} else {
return posix_lock_file_wait(file, fl);
}
}
+ if (cmd == F_CANCELLK) {
+ /* Hack: */
+ cmd = F_SETLK;
+ fl->fl_type = F_UNLCK;
+ }
if (IS_GETLK(cmd))
return gfs2_lm_plock_get(sdp, &name, file, fl);
else if (fl->fl_type == F_UNLCK)
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index ee54cb6..2c5f8e7 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -690,6 +690,8 @@ static int fill_super(struct super_block *sb, void *data, int silent)
if (error)
goto fail;
+ gfs2_create_debugfs_file(sdp);
+
error = gfs2_sys_fs_add(sdp);
if (error)
goto fail;
@@ -754,6 +756,7 @@ fail_lm:
fail_sys:
gfs2_sys_fs_del(sdp);
fail:
+ gfs2_delete_debugfs_file(sdp);
kfree(sdp);
sb->s_fs_info = NULL;
return error;
@@ -896,6 +899,7 @@ error:
static void gfs2_kill_sb(struct super_block *sb)
{
+ gfs2_delete_debugfs_file(sb->s_fs_info);
kill_block_super(sb);
}
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c
index b89999d3..485ce3d 100644
--- a/fs/gfs2/ops_super.c
+++ b/fs/gfs2/ops_super.c
@@ -284,6 +284,31 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
}
/**
+ * gfs2_drop_inode - Drop an inode (test for remote unlink)
+ * @inode: The inode to drop
+ *
+ * If we've received a callback on an iopen lock then its because a
+ * remote node tried to deallocate the inode but failed due to this node
+ * still having the inode open. Here we mark the link count zero
+ * since we know that it must have reached zero if the GLF_DEMOTE flag
+ * is set on the iopen glock. If we didn't do a disk read since the
+ * remote node removed the final link then we might otherwise miss
+ * this event. This check ensures that this node will deallocate the
+ * inode's blocks, or alternatively pass the baton on to another
+ * node for later deallocation.
+ */
+static void gfs2_drop_inode(struct inode *inode)
+{
+ if (inode->i_private && inode->i_nlink) {
+ struct gfs2_inode *ip = GFS2_I(inode);
+ struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
+ if (gl && test_bit(GLF_DEMOTE, &gl->gl_flags))
+ clear_nlink(inode);
+ }
+ generic_drop_inode(inode);
+}
+
+/**
* gfs2_clear_inode - Deallocate an inode when VFS is done with it
* @inode: The VFS inode
*
@@ -441,7 +466,7 @@ out_unlock:
out_uninit:
gfs2_holder_uninit(&ip->i_iopen_gh);
gfs2_glock_dq_uninit(&gh);
- if (error)
+ if (error && error != GLR_TRYFAILED)
fs_warn(sdp, "gfs2_delete_inode: %d\n", error);
out:
truncate_inode_pages(&inode->i_data, 0);
@@ -481,6 +506,7 @@ const struct super_operations gfs2_super_ops = {
.statfs = gfs2_statfs,
.remount_fs = gfs2_remount_fs,
.clear_inode = gfs2_clear_inode,
+ .drop_inode = gfs2_drop_inode,
.show_options = gfs2_show_options,
};
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 8d9c08b..1727f50 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -27,6 +27,7 @@
#include "trans.h"
#include "ops_file.h"
#include "util.h"
+#include "log.h"
#define BFITNOENT ((u32)~0)
@@ -697,8 +698,6 @@ struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip)
* @al: the struct gfs2_alloc structure describing the reservation
*
* If there's room for the requested blocks to be allocated from the RG:
- * Sets the $al_reserved_data field in @al.
- * Sets the $al_reserved_meta field in @al.
* Sets the $al_rgd field in @al.
*
* Returns: 1 on success (it fits), 0 on failure (it doesn't fit)
@@ -709,6 +708,9 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al)
struct gfs2_sbd *sdp = rgd->rd_sbd;
int ret = 0;
+ if (rgd->rd_rg.rg_flags & GFS2_RGF_NOALLOC)
+ return 0;
+
spin_lock(&sdp->sd_rindex_spin);
if (rgd->rd_free_clone >= al->al_requested) {
al->al_rgd = rgd;
@@ -941,9 +943,13 @@ static int get_local_rgrp(struct gfs2_inode *ip)
rgd = gfs2_rgrpd_get_first(sdp);
if (rgd == begin) {
- if (++loops >= 2 || !skipped)
+ if (++loops >= 3)
return -ENOSPC;
+ if (!skipped)
+ loops++;
flags = 0;
+ if (loops == 2)
+ gfs2_log_flush(sdp, NULL);
}
}
diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c
index 5fd0ed7..8a3a650 100644
--- a/fs/hfs/btree.c
+++ b/fs/hfs/btree.c
@@ -9,6 +9,7 @@
*/
#include <linux/pagemap.h>
+#include <linux/log2.h>
#include "btree.h"
@@ -76,7 +77,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke
tree->depth = be16_to_cpu(head->depth);
size = tree->node_size;
- if (!size || size & (size - 1))
+ if (!is_power_of_2(size))
goto fail_page;
if (!tree->node_count)
goto fail_page;
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 623f509..4f1888f 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -434,7 +434,7 @@ static void hfs_init_once(void *p, struct kmem_cache *cachep, unsigned long flag
{
struct hfs_inode_info *i = p;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&i->vfs_inode);
}
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c
index a9b9e87..90ebab7 100644
--- a/fs/hfsplus/btree.c
+++ b/fs/hfsplus/btree.c
@@ -10,6 +10,7 @@
#include <linux/slab.h>
#include <linux/pagemap.h>
+#include <linux/log2.h>
#include "hfsplus_fs.h"
#include "hfsplus_raw.h"
@@ -69,7 +70,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id)
}
size = tree->node_size;
- if (!size || size & (size - 1))
+ if (!is_power_of_2(size))
goto fail_page;
if (!tree->node_count)
goto fail_page;
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 1a97f92..37afbec 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -470,7 +470,7 @@ static void hfsplus_init_once(void *p, struct kmem_cache *cachep, unsigned long
{
struct hfsplus_inode_info *i = p;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&i->vfs_inode);
}
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
index 70543b1..06e5930 100644
--- a/fs/hostfs/hostfs.h
+++ b/fs/hostfs/hostfs.h
@@ -55,7 +55,7 @@ extern int stat_file(const char *path, unsigned long long *inode_out,
int *mode_out, int *nlink_out, int *uid_out, int *gid_out,
unsigned long long *size_out, struct timespec *atime_out,
struct timespec *mtime_out, struct timespec *ctime_out,
- int *blksize_out, unsigned long long *blocks_out);
+ int *blksize_out, unsigned long long *blocks_out, int fd);
extern int access_file(char *path, int r, int w, int x);
extern int open_file(char *path, int r, int w, int append);
extern int file_type(const char *path, int *maj, int *min);
@@ -71,7 +71,7 @@ extern int lseek_file(int fd, long long offset, int whence);
extern int fsync_file(int fd, int datasync);
extern int file_create(char *name, int ur, int uw, int ux, int gr,
int gw, int gx, int or, int ow, int ox);
-extern int set_attr(const char *file, struct hostfs_iattr *attrs);
+extern int set_attr(const char *file, struct hostfs_iattr *attrs, int fd);
extern int make_symlink(const char *from, const char *to);
extern int unlink_file(const char *file);
extern int do_mkdir(const char *file, int mode);
@@ -87,14 +87,3 @@ extern int do_statfs(char *root, long *bsize_out, long long *blocks_out,
long *spare_out);
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index fd301a9..8286491 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*
* Ported the filesystem routines to 2.5.
@@ -31,14 +31,14 @@ struct hostfs_inode_info {
static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
{
- return(list_entry(inode, struct hostfs_inode_info, vfs_inode));
+ return list_entry(inode, struct hostfs_inode_info, vfs_inode);
}
#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_path.dentry->d_inode)
int hostfs_d_delete(struct dentry *dentry)
{
- return(1);
+ return 1;
}
struct dentry_operations hostfs_dentry_ops = {
@@ -79,7 +79,7 @@ static int __init hostfs_args(char *options, int *add)
}
options = ptr;
}
- return(0);
+ return 0;
}
__uml_setup("hostfs=", hostfs_args,
@@ -110,7 +110,8 @@ static char *dentry_name(struct dentry *dentry, int extra)
root = HOSTFS_I(parent->d_inode)->host_filename;
len += strlen(root);
name = kmalloc(len + extra + 1, GFP_KERNEL);
- if(name == NULL) return(NULL);
+ if(name == NULL)
+ return NULL;
name[len] = '\0';
parent = dentry;
@@ -122,7 +123,7 @@ static char *dentry_name(struct dentry *dentry, int extra)
parent = parent->d_parent;
}
strncpy(name, root, strlen(root));
- return(name);
+ return name;
}
static char *inode_name(struct inode *ino, int extra)
@@ -130,7 +131,7 @@ static char *inode_name(struct inode *ino, int extra)
struct dentry *dentry;
dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
- return(dentry_name(dentry, extra));
+ return dentry_name(dentry, extra);
}
static int read_name(struct inode *ino, char *name)
@@ -147,16 +148,16 @@ static int read_name(struct inode *ino, char *name)
err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid,
&ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime,
- &ino->i_ctime, &i_blksize, &i_blocks);
+ &ino->i_ctime, &i_blksize, &i_blocks, -1);
if(err)
- return(err);
+ return err;
ino->i_ino = i_ino;
ino->i_mode = i_mode;
ino->i_nlink = i_nlink;
ino->i_size = i_size;
ino->i_blocks = i_blocks;
- return(0);
+ return 0;
}
static char *follow_link(char *link)
@@ -181,11 +182,11 @@ static char *follow_link(char *link)
goto out_free;
if(*name == '/')
- return(name);
+ return name;
end = strrchr(link, '/');
if(end == NULL)
- return(name);
+ return name;
*(end + 1) = '\0';
len = strlen(link) + strlen(name) + 1;
@@ -199,12 +200,12 @@ static char *follow_link(char *link)
sprintf(resolved, "%s%s", link, name);
kfree(name);
kfree(link);
- return(resolved);
+ return resolved;
out_free:
kfree(name);
out:
- return(ERR_PTR(n));
+ return ERR_PTR(n);
}
static int read_inode(struct inode *ino)
@@ -234,7 +235,7 @@ static int read_inode(struct inode *ino)
err = read_name(ino, name);
kfree(name);
out:
- return(err);
+ return err;
}
int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
@@ -254,14 +255,15 @@ int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
&sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
&f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
&sf->f_namelen, sf->f_spare);
- if(err) return(err);
+ if(err)
+ return err;
sf->f_blocks = f_blocks;
sf->f_bfree = f_bfree;
sf->f_bavail = f_bavail;
sf->f_files = f_files;
sf->f_ffree = f_ffree;
sf->f_type = HOSTFS_SUPER_MAGIC;
- return(0);
+ return 0;
}
static struct inode *hostfs_alloc_inode(struct super_block *sb)
@@ -270,13 +272,13 @@ static struct inode *hostfs_alloc_inode(struct super_block *sb)
hi = kmalloc(sizeof(*hi), GFP_KERNEL);
if(hi == NULL)
- return(NULL);
+ return NULL;
*hi = ((struct hostfs_inode_info) { .host_filename = NULL,
.fd = -1,
.mode = 0 });
inode_init_once(&hi->vfs_inode);
- return(&hi->vfs_inode);
+ return &hi->vfs_inode;
}
static void hostfs_delete_inode(struct inode *inode)
@@ -325,10 +327,12 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
int error, len;
name = dentry_name(file->f_path.dentry, 0);
- if(name == NULL) return(-ENOMEM);
+ if(name == NULL)
+ return -ENOMEM;
dir = open_dir(name, &error);
kfree(name);
- if(dir == NULL) return(-error);
+ if(dir == NULL)
+ return -error;
next = file->f_pos;
while((name = read_dir(dir, &next, &ino, &len)) != NULL){
error = (*filldir)(ent, name, len, file->f_pos,
@@ -337,7 +341,7 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
file->f_pos = next;
}
close_dir(dir);
- return(0);
+ return 0;
}
int hostfs_file_open(struct inode *ino, struct file *file)
@@ -347,7 +351,7 @@ int hostfs_file_open(struct inode *ino, struct file *file)
mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
if((mode & HOSTFS_I(ino)->mode) == mode)
- return(0);
+ return 0;
/* The file may already have been opened, but with the wrong access,
* so this resets things and reopens the file with the new access.
@@ -367,14 +371,15 @@ int hostfs_file_open(struct inode *ino, struct file *file)
name = dentry_name(file->f_path.dentry, 0);
if(name == NULL)
- return(-ENOMEM);
+ return -ENOMEM;
fd = open_file(name, r, w, append);
kfree(name);
- if(fd < 0) return(fd);
+ if(fd < 0)
+ return fd;
FILE_HOSTFS_I(file)->fd = fd;
- return(0);
+ return 0;
}
int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
@@ -458,7 +463,7 @@ int hostfs_readpage(struct file *file, struct page *page)
out:
kunmap(page);
unlock_page(page);
- return(err);
+ return err;
}
int hostfs_prepare_write(struct file *file, struct page *page,
@@ -485,7 +490,7 @@ int hostfs_prepare_write(struct file *file, struct page *page,
err = 0;
out:
kunmap(page);
- return(err);
+ return err;
}
int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
@@ -511,7 +516,7 @@ int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
inode->i_size = start;
kunmap(page);
- return(err);
+ return err;
}
static const struct address_space_operations hostfs_aops = {
@@ -569,7 +574,7 @@ static int init_inode(struct inode *inode, struct dentry *dentry)
break;
}
out:
- return(err);
+ return err;
}
int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
@@ -607,16 +612,16 @@ int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
HOSTFS_I(inode)->fd = fd;
HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
d_instantiate(dentry, inode);
- return(0);
+ return 0;
out_put:
iput(inode);
out:
- return(error);
+ return error;
}
struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
- struct nameidata *nd)
+ struct nameidata *nd)
{
struct inode *inode;
char *name;
@@ -647,44 +652,45 @@ struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
d_add(dentry, inode);
dentry->d_op = &hostfs_dentry_ops;
- return(NULL);
+ return NULL;
out_put:
iput(inode);
out:
- return(ERR_PTR(err));
+ return ERR_PTR(err);
}
static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
{
- char *file;
+ char *file;
int len;
file = inode_name(ino, dentry->d_name.len + 1);
- if(file == NULL) return(NULL);
- strcat(file, "/");
+ if(file == NULL)
+ return NULL;
+ strcat(file, "/");
len = strlen(file);
- strncat(file, dentry->d_name.name, dentry->d_name.len);
+ strncat(file, dentry->d_name.name, dentry->d_name.len);
file[len + dentry->d_name.len] = '\0';
- return(file);
+ return file;
}
int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
{
- char *from_name, *to_name;
- int err;
+ char *from_name, *to_name;
+ int err;
- if((from_name = inode_dentry_name(ino, from)) == NULL)
- return(-ENOMEM);
- to_name = dentry_name(to, 0);
+ if((from_name = inode_dentry_name(ino, from)) == NULL)
+ return -ENOMEM;
+ to_name = dentry_name(to, 0);
if(to_name == NULL){
kfree(from_name);
- return(-ENOMEM);
+ return -ENOMEM;
}
- err = link_file(to_name, from_name);
- kfree(from_name);
- kfree(to_name);
- return(err);
+ err = link_file(to_name, from_name);
+ kfree(from_name);
+ kfree(to_name);
+ return err;
}
int hostfs_unlink(struct inode *ino, struct dentry *dentry)
@@ -692,13 +698,14 @@ int hostfs_unlink(struct inode *ino, struct dentry *dentry)
char *file;
int err;
- if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
+ if((file = inode_dentry_name(ino, dentry)) == NULL)
+ return -ENOMEM;
if(append)
- return(-EPERM);
+ return -EPERM;
err = unlink_file(file);
kfree(file);
- return(err);
+ return err;
}
int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
@@ -706,10 +713,11 @@ int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
char *file;
int err;
- if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
+ if((file = inode_dentry_name(ino, dentry)) == NULL)
+ return -ENOMEM;
err = make_symlink(file, to);
kfree(file);
- return(err);
+ return err;
}
int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
@@ -717,10 +725,11 @@ int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
char *file;
int err;
- if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
+ if((file = inode_dentry_name(ino, dentry)) == NULL)
+ return -ENOMEM;
err = do_mkdir(file, mode);
kfree(file);
- return(err);
+ return err;
}
int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
@@ -728,10 +737,11 @@ int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
char *file;
int err;
- if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
+ if((file = inode_dentry_name(ino, dentry)) == NULL)
+ return -ENOMEM;
err = do_rmdir(file);
kfree(file);
- return(err);
+ return err;
}
int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
@@ -764,14 +774,14 @@ int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
goto out_put;
d_instantiate(dentry, inode);
- return(0);
+ return 0;
out_free:
kfree(name);
out_put:
iput(inode);
out:
- return(err);
+ return err;
}
int hostfs_rename(struct inode *from_ino, struct dentry *from,
@@ -781,15 +791,15 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from,
int err;
if((from_name = inode_dentry_name(from_ino, from)) == NULL)
- return(-ENOMEM);
+ return -ENOMEM;
if((to_name = inode_dentry_name(to_ino, to)) == NULL){
kfree(from_name);
- return(-ENOMEM);
+ return -ENOMEM;
}
err = rename_file(from_name, to_name);
kfree(from_name);
kfree(to_name);
- return(err);
+ return err;
}
int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
@@ -801,7 +811,8 @@ int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
if (desired & MAY_WRITE) w = 1;
if (desired & MAY_EXEC) x = 1;
name = inode_name(ino, 0);
- if (name == NULL) return(-ENOMEM);
+ if (name == NULL)
+ return -ENOMEM;
if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
@@ -820,6 +831,8 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
char *name;
int err;
+ int fd = HOSTFS_I(dentry->d_inode)->fd;
+
err = inode_change_ok(dentry->d_inode, attr);
if (err)
return err;
@@ -863,20 +876,21 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
}
name = dentry_name(dentry, 0);
- if(name == NULL) return(-ENOMEM);
- err = set_attr(name, &attrs);
+ if(name == NULL)
+ return -ENOMEM;
+ err = set_attr(name, &attrs, fd);
kfree(name);
if(err)
- return(err);
+ return err;
- return(inode_setattr(dentry->d_inode, attr));
+ return inode_setattr(dentry->d_inode, attr);
}
int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
{
generic_fillattr(dentry->d_inode, stat);
- return(0);
+ return 0;
}
static const struct inode_operations hostfs_iops = {
@@ -915,7 +929,8 @@ int hostfs_link_readpage(struct file *file, struct page *page)
buffer = kmap(page);
name = inode_name(page->mapping->host, 0);
- if(name == NULL) return(-ENOMEM);
+ if(name == NULL)
+ return -ENOMEM;
err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
kfree(name);
if(err == PAGE_CACHE_SIZE)
@@ -928,7 +943,7 @@ int hostfs_link_readpage(struct file *file, struct page *page)
}
kunmap(page);
unlock_page(page);
- return(err);
+ return err;
}
static const struct address_space_operations hostfs_link_aops = {
@@ -978,20 +993,20 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
err = read_inode(root_inode);
if(err){
- /* No iput in this case because the dput does that for us */
- dput(sb->s_root);
- sb->s_root = NULL;
+ /* No iput in this case because the dput does that for us */
+ dput(sb->s_root);
+ sb->s_root = NULL;
goto out;
- }
+ }
- return(0);
+ return 0;
- out_put:
- iput(root_inode);
- out_free:
+out_put:
+ iput(root_inode);
+out_free:
kfree(host_root_path);
- out:
- return(err);
+out:
+ return err;
}
static int hostfs_read_sb(struct file_system_type *type,
@@ -1011,7 +1026,7 @@ static struct file_system_type hostfs_type = {
static int __init init_hostfs(void)
{
- return(register_filesystem(&hostfs_type));
+ return register_filesystem(&hostfs_type);
}
static void __exit exit_hostfs(void)
@@ -1022,14 +1037,3 @@ static void __exit exit_hostfs(void)
module_init(init_hostfs)
module_exit(exit_hostfs)
MODULE_LICENSE("GPL");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
index 1ed5ea3..5625e24 100644
--- a/fs/hostfs/hostfs_user.c
+++ b/fs/hostfs/hostfs_user.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -21,12 +21,16 @@ int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
int *nlink_out, int *uid_out, int *gid_out,
unsigned long long *size_out, struct timespec *atime_out,
struct timespec *mtime_out, struct timespec *ctime_out,
- int *blksize_out, unsigned long long *blocks_out)
+ int *blksize_out, unsigned long long *blocks_out, int fd)
{
struct stat64 buf;
- if(lstat64(path, &buf) < 0)
- return(-errno);
+ if(fd >= 0) {
+ if (fstat64(fd, &buf) < 0)
+ return -errno;
+ } else if(lstat64(path, &buf) < 0) {
+ return -errno;
+ }
if(inode_out != NULL) *inode_out = buf.st_ino;
if(mode_out != NULL) *mode_out = buf.st_mode;
@@ -48,7 +52,7 @@ int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
}
if(blksize_out != NULL) *blksize_out = buf.st_blksize;
if(blocks_out != NULL) *blocks_out = buf.st_blocks;
- return(0);
+ return 0;
}
int file_type(const char *path, int *maj, int *min)
@@ -56,7 +60,7 @@ int file_type(const char *path, int *maj, int *min)
struct stat64 buf;
if(lstat64(path, &buf) < 0)
- return(-errno);
+ return -errno;
/*We cannot pass rdev as is because glibc and the kernel disagree
*about its definition.*/
if(maj != NULL)
@@ -64,13 +68,13 @@ int file_type(const char *path, int *maj, int *min)
if(min != NULL)
*min = minor(buf.st_rdev);
- if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
- else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
- else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
- else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
- else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
- else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
- else return(OS_TYPE_FILE);
+ if(S_ISDIR(buf.st_mode)) return OS_TYPE_DIR;
+ else if(S_ISLNK(buf.st_mode)) return OS_TYPE_SYMLINK;
+ else if(S_ISCHR(buf.st_mode)) return OS_TYPE_CHARDEV;
+ else if(S_ISBLK(buf.st_mode)) return OS_TYPE_BLOCKDEV;
+ else if(S_ISFIFO(buf.st_mode))return OS_TYPE_FIFO;
+ else if(S_ISSOCK(buf.st_mode))return OS_TYPE_SOCK;
+ else return OS_TYPE_FILE;
}
int access_file(char *path, int r, int w, int x)
@@ -80,8 +84,9 @@ int access_file(char *path, int r, int w, int x)
if(r) mode = R_OK;
if(w) mode |= W_OK;
if(x) mode |= X_OK;
- if(access(path, mode) != 0) return(-errno);
- else return(0);
+ if(access(path, mode) != 0)
+ return -errno;
+ else return 0;
}
int open_file(char *path, int r, int w, int append)
@@ -99,8 +104,9 @@ int open_file(char *path, int r, int w, int append)
if(append)
mode |= O_APPEND;
fd = open64(path, mode);
- if(fd < 0) return(-errno);
- else return(fd);
+ if(fd < 0)
+ return -errno;
+ else return fd;
}
void *open_dir(char *path, int *err_out)
@@ -109,8 +115,9 @@ void *open_dir(char *path, int *err_out)
dir = opendir(path);
*err_out = errno;
- if(dir == NULL) return(NULL);
- return(dir);
+ if(dir == NULL)
+ return NULL;
+ return dir;
}
char *read_dir(void *stream, unsigned long long *pos,
@@ -121,11 +128,12 @@ char *read_dir(void *stream, unsigned long long *pos,
seekdir(dir, *pos);
ent = readdir(dir);
- if(ent == NULL) return(NULL);
+ if(ent == NULL)
+ return NULL;
*len_out = strlen(ent->d_name);
*ino_out = ent->d_ino;
*pos = telldir(dir);
- return(ent->d_name);
+ return ent->d_name;
}
int read_file(int fd, unsigned long long *offset, char *buf, int len)
@@ -133,9 +141,10 @@ int read_file(int fd, unsigned long long *offset, char *buf, int len)
int n;
n = pread64(fd, buf, len, *offset);
- if(n < 0) return(-errno);
+ if(n < 0)
+ return -errno;
*offset += n;
- return(n);
+ return n;
}
int write_file(int fd, unsigned long long *offset, const char *buf, int len)
@@ -143,9 +152,10 @@ int write_file(int fd, unsigned long long *offset, const char *buf, int len)
int n;
n = pwrite64(fd, buf, len, *offset);
- if(n < 0) return(-errno);
+ if(n < 0)
+ return -errno;
*offset += n;
- return(n);
+ return n;
}
int lseek_file(int fd, long long offset, int whence)
@@ -154,8 +164,8 @@ int lseek_file(int fd, long long offset, int whence)
ret = lseek64(fd, offset, whence);
if(ret < 0)
- return(-errno);
- return(0);
+ return -errno;
+ return 0;
}
int fsync_file(int fd, int datasync)
@@ -198,65 +208,90 @@ int file_create(char *name, int ur, int uw, int ux, int gr,
mode |= ox ? S_IXOTH : 0;
fd = open64(name, O_CREAT | O_RDWR, mode);
if(fd < 0)
- return(-errno);
- return(fd);
+ return -errno;
+ return fd;
}
-int set_attr(const char *file, struct hostfs_iattr *attrs)
+int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
{
- struct utimbuf buf;
+ struct timeval times[2];
+ struct timespec atime_ts, mtime_ts;
int err, ma;
- if(attrs->ia_valid & HOSTFS_ATTR_MODE){
- if(chmod(file, attrs->ia_mode) != 0) return(-errno);
- }
- if(attrs->ia_valid & HOSTFS_ATTR_UID){
- if(chown(file, attrs->ia_uid, -1)) return(-errno);
+ if (attrs->ia_valid & HOSTFS_ATTR_MODE) {
+ if (fd >= 0) {
+ if (fchmod(fd, attrs->ia_mode) != 0)
+ return (-errno);
+ } else if (chmod(file, attrs->ia_mode) != 0) {
+ return -errno;
+ }
}
- if(attrs->ia_valid & HOSTFS_ATTR_GID){
- if(chown(file, -1, attrs->ia_gid)) return(-errno);
+ if (attrs->ia_valid & HOSTFS_ATTR_UID) {
+ if (fd >= 0) {
+ if (fchown(fd, attrs->ia_uid, -1))
+ return -errno;
+ } else if(chown(file, attrs->ia_uid, -1)) {
+ return -errno;
+ }
}
- if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
- if(truncate(file, attrs->ia_size)) return(-errno);
+ if (attrs->ia_valid & HOSTFS_ATTR_GID) {
+ if (fd >= 0) {
+ if (fchown(fd, -1, attrs->ia_gid))
+ return -errno;
+ } else if (chown(file, -1, attrs->ia_gid)) {
+ return -errno;
+ }
}
- ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
- if((attrs->ia_valid & ma) == ma){
- buf.actime = attrs->ia_atime.tv_sec;
- buf.modtime = attrs->ia_mtime.tv_sec;
- if(utime(file, &buf) != 0) return(-errno);
+ if (attrs->ia_valid & HOSTFS_ATTR_SIZE) {
+ if (fd >= 0) {
+ if (ftruncate(fd, attrs->ia_size))
+ return -errno;
+ } else if (truncate(file, attrs->ia_size)) {
+ return -errno;
+ }
}
- else {
- struct timespec ts;
-
- if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
- err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, &ts, NULL, NULL, NULL);
- if(err != 0)
- return(err);
- buf.actime = attrs->ia_atime.tv_sec;
- buf.modtime = ts.tv_sec;
- if(utime(file, &buf) != 0)
- return(-errno);
+
+ /* Update accessed and/or modified time, in two parts: first set
+ * times according to the changes to perform, and then call futimes()
+ * or utimes() to apply them. */
+ ma = (HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET);
+ if (attrs->ia_valid & ma) {
+ err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
+ &atime_ts, &mtime_ts, NULL, NULL, NULL, fd);
+ if (err != 0)
+ return err;
+
+ times[0].tv_sec = atime_ts.tv_sec;
+ times[0].tv_usec = atime_ts.tv_nsec * 1000;
+ times[1].tv_sec = mtime_ts.tv_sec;
+ times[1].tv_usec = mtime_ts.tv_nsec * 1000;
+
+ if (attrs->ia_valid & HOSTFS_ATTR_ATIME_SET) {
+ times[0].tv_sec = attrs->ia_atime.tv_sec;
+ times[0].tv_usec = attrs->ia_atime.tv_nsec * 1000;
+ }
+ if (attrs->ia_valid & HOSTFS_ATTR_MTIME_SET) {
+ times[1].tv_sec = attrs->ia_mtime.tv_sec;
+ times[1].tv_usec = attrs->ia_mtime.tv_nsec * 1000;
}
- if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
- err = stat_file(file, NULL, NULL, NULL, NULL, NULL,
- NULL, &ts, NULL, NULL, NULL, NULL);
- if(err != 0)
- return(err);
- buf.actime = ts.tv_sec;
- buf.modtime = attrs->ia_mtime.tv_sec;
- if(utime(file, &buf) != 0)
- return(-errno);
+
+ if (fd >= 0) {
+ if (futimes(fd, times) != 0)
+ return -errno;
+ } else if (utimes(file, times) != 0) {
+ return -errno;
}
}
+
if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
&attrs->ia_atime, &attrs->ia_mtime, NULL,
- NULL, NULL);
- if(err != 0) return(err);
+ NULL, NULL, fd);
+ if(err != 0)
+ return err;
}
- return(0);
+ return 0;
}
int make_symlink(const char *from, const char *to)
@@ -264,8 +299,9 @@ int make_symlink(const char *from, const char *to)
int err;
err = symlink(to, from);
- if(err) return(-errno);
- return(0);
+ if(err)
+ return -errno;
+ return 0;
}
int unlink_file(const char *file)
@@ -273,8 +309,9 @@ int unlink_file(const char *file)
int err;
err = unlink(file);
- if(err) return(-errno);
- return(0);
+ if(err)
+ return -errno;
+ return 0;
}
int do_mkdir(const char *file, int mode)
@@ -282,8 +319,9 @@ int do_mkdir(const char *file, int mode)
int err;
err = mkdir(file, mode);
- if(err) return(-errno);
- return(0);
+ if(err)
+ return -errno;
+ return 0;
}
int do_rmdir(const char *file)
@@ -291,8 +329,9 @@ int do_rmdir(const char *file)
int err;
err = rmdir(file);
- if(err) return(-errno);
- return(0);
+ if(err)
+ return -errno;
+ return 0;
}
int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor)
@@ -300,8 +339,9 @@ int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor)
int err;
err = mknod(file, mode, makedev(major, minor));
- if(err) return(-errno);
- return(0);
+ if(err)
+ return -errno;
+ return 0;
}
int link_file(const char *to, const char *from)
@@ -309,8 +349,9 @@ int link_file(const char *to, const char *from)
int err;
err = link(to, from);
- if(err) return(-errno);
- return(0);
+ if(err)
+ return -errno;
+ return 0;
}
int do_readlink(char *file, char *buf, int size)
@@ -319,10 +360,10 @@ int do_readlink(char *file, char *buf, int size)
n = readlink(file, buf, size);
if(n < 0)
- return(-errno);
+ return -errno;
if(n < size)
buf[n] = '\0';
- return(n);
+ return n;
}
int rename_file(char *from, char *to)
@@ -330,8 +371,9 @@ int rename_file(char *from, char *to)
int err;
err = rename(from, to);
- if(err < 0) return(-errno);
- return(0);
+ if(err < 0)
+ return -errno;
+ return 0;
}
int do_statfs(char *root, long *bsize_out, long long *blocks_out,
@@ -344,7 +386,9 @@ int do_statfs(char *root, long *bsize_out, long long *blocks_out,
int err;
err = statfs64(root, &buf);
- if(err < 0) return(-errno);
+ if(err < 0)
+ return -errno;
+
*bsize_out = buf.f_bsize;
*blocks_out = buf.f_blocks;
*bfree_out = buf.f_bfree;
@@ -360,16 +404,5 @@ int do_statfs(char *root, long *bsize_out, long long *blocks_out,
spare_out[2] = buf.f_spare[2];
spare_out[3] = buf.f_spare[3];
spare_out[4] = buf.f_spare[4];
- return(0);
+ return 0;
}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index e0174e3..1b95f39f 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -176,8 +176,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
mutex_init(&ei->i_mutex);
mutex_init(&ei->i_parent_mutex);
inode_init_once(&ei->vfs_inode);
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 8c718a3..98959b8 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -22,6 +22,7 @@
#include <linux/backing-dev.h>
#include <linux/hugetlb.h>
#include <linux/pagevec.h>
+#include <linux/mman.h>
#include <linux/quotaops.h>
#include <linux/slab.h>
#include <linux/dnotify.h>
@@ -98,10 +99,7 @@ out:
* Called under down_write(mmap_sem).
*/
-#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
-unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
- unsigned long len, unsigned long pgoff, unsigned long flags);
-#else
+#ifndef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
static unsigned long
hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
unsigned long len, unsigned long pgoff, unsigned long flags)
@@ -115,6 +113,12 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
if (len > TASK_SIZE)
return -ENOMEM;
+ if (flags & MAP_FIXED) {
+ if (prepare_hugepage_range(addr, len, pgoff))
+ return -EINVAL;
+ return addr;
+ }
+
if (addr) {
addr = ALIGN(addr, HPAGE_SIZE);
vma = find_vma(mm, addr);
@@ -453,7 +457,7 @@ static int hugetlbfs_symlink(struct inode *dir,
*/
static int hugetlbfs_set_page_dirty(struct page *page)
{
- struct page *head = (struct page *)page_private(page);
+ struct page *head = compound_head(page);
SetPageDirty(head);
return 0;
@@ -552,8 +556,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
{
struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&ei->vfs_inode);
}
@@ -744,6 +747,9 @@ struct file *hugetlb_zero_setup(size_t size)
char buf[16];
static atomic_t counter;
+ if (!hugetlbfs_vfsmount)
+ return ERR_PTR(-ENOENT);
+
if (!can_do_hugetlb_shm())
return ERR_PTR(-EPERM);
diff --git a/fs/inode.c b/fs/inode.c
index 5abb097..df2ef15 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -213,8 +213,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct inode * inode = (struct inode *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(inode);
}
@@ -251,7 +250,7 @@ void clear_inode(struct inode *inode)
BUG_ON(inode->i_state & I_CLEAR);
wait_on_inode(inode);
DQUOT_DROP(inode);
- if (inode->i_sb && inode->i_sb->s_op->clear_inode)
+ if (inode->i_sb->s_op->clear_inode)
inode->i_sb->s_op->clear_inode(inode);
if (S_ISBLK(inode->i_mode) && inode->i_bdev)
bd_forget(inode);
@@ -276,7 +275,7 @@ static void dispose_list(struct list_head *head)
while (!list_empty(head)) {
struct inode *inode;
- inode = list_entry(head->next, struct inode, i_list);
+ inode = list_first_entry(head, struct inode, i_list);
list_del(&inode->i_list);
if (inode->i_data.nrpages)
@@ -525,7 +524,12 @@ repeat:
*/
struct inode *new_inode(struct super_block *sb)
{
- static unsigned long last_ino;
+ /*
+ * On a 32bit, non LFS stat() call, glibc will generate an EOVERFLOW
+ * error if st_ino won't fit in target struct field. Use 32bit counter
+ * here to attempt to avoid that.
+ */
+ static unsigned int last_ino;
struct inode * inode;
spin_lock_prefetch(&inode_lock);
@@ -684,27 +688,28 @@ static unsigned long hash(struct super_block *sb, unsigned long hashval)
*/
ino_t iunique(struct super_block *sb, ino_t max_reserved)
{
- static ino_t counter;
+ /*
+ * On a 32bit, non LFS stat() call, glibc will generate an EOVERFLOW
+ * error if st_ino won't fit in target struct field. Use 32bit counter
+ * here to attempt to avoid that.
+ */
+ static unsigned int counter;
struct inode *inode;
- struct hlist_head * head;
+ struct hlist_head *head;
ino_t res;
+
spin_lock(&inode_lock);
-retry:
- if (counter > max_reserved) {
- head = inode_hashtable + hash(sb,counter);
+ do {
+ if (counter <= max_reserved)
+ counter = max_reserved + 1;
res = counter++;
+ head = inode_hashtable + hash(sb, res);
inode = find_inode_fast(sb, head, res);
- if (!inode) {
- spin_unlock(&inode_lock);
- return res;
- }
- } else {
- counter = max_reserved + 1;
- }
- goto retry;
-
-}
+ } while (inode != NULL);
+ spin_unlock(&inode_lock);
+ return res;
+}
EXPORT_SYMBOL(iunique);
struct inode *igrab(struct inode *inode)
@@ -1041,7 +1046,7 @@ static void generic_forget_inode(struct inode *inode)
if (!(inode->i_state & (I_DIRTY|I_LOCK)))
list_move(&inode->i_list, &inode_unused);
inodes_stat.nr_unused++;
- if (!sb || (sb->s_flags & MS_ACTIVE)) {
+ if (sb->s_flags & MS_ACTIVE) {
spin_unlock(&inode_lock);
return;
}
diff --git a/fs/inotify.c b/fs/inotify.c
index f5099d8..7457501 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -509,7 +509,7 @@ void inotify_destroy(struct inotify_handle *ih)
mutex_unlock(&ih->mutex);
break;
}
- watch = list_entry(watches->next, struct inotify_watch, h_list);
+ watch = list_first_entry(watches, struct inotify_watch, h_list);
get_inotify_watch(watch);
mutex_unlock(&ih->mutex);
diff --git a/fs/internal.h b/fs/internal.h
index ea00126..392e8cc 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -9,8 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/ioctl32.h>
-
struct super_block;
/*
@@ -42,14 +40,6 @@ static inline int sb_is_blkdev_sb(struct super_block *sb)
extern void __init chrdev_init(void);
/*
- * compat_ioctl.c
- */
-#ifdef CONFIG_COMPAT
-extern struct ioctl_trans ioctl_start[];
-extern int ioctl_table_size;
-#endif
-
-/*
* namespace.c
*/
extern int copy_mount_options(const void __user *, unsigned long *);
diff --git a/fs/ioctl.c b/fs/ioctl.c
index ff61772..479c103 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -67,8 +67,6 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
return put_user(res, p);
}
case FIGETBSZ:
- if (inode->i_sb == NULL)
- return -EBADF;
return put_user(inode->i_sb->s_blocksize, p);
case FIONREAD:
return put_user(i_size_read(inode) - filp->f_pos, p);
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 64a96cd..e99f7ff 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -77,8 +77,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags
{
struct iso_inode_info *ei = foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&ei->vfs_inode);
}
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index be4648b..1facfaf 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -20,7 +20,6 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
/*
* Default IO end handler for temporary BJ_IO buffer_heads.
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 10fff94..46fe743 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -28,7 +28,6 @@
#include <linux/jbd.h>
#include <linux/errno.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/freezer.h>
@@ -211,10 +210,16 @@ end_loop:
return 0;
}
-static void journal_start_thread(journal_t *journal)
+static int journal_start_thread(journal_t *journal)
{
- kthread_run(kjournald, journal, "kjournald");
+ struct task_struct *t;
+
+ t = kthread_run(kjournald, journal, "kjournald");
+ if (IS_ERR(t))
+ return PTR_ERR(t);
+
wait_event(journal->j_wait_done_commit, journal->j_task != 0);
+ return 0;
}
static void journal_kill_thread(journal_t *journal)
@@ -840,8 +845,7 @@ static int journal_reset(journal_t *journal)
/* Add the dynamic fields and write it to disk. */
journal_update_superblock(journal, 1);
- journal_start_thread(journal);
- return 0;
+ return journal_start_thread(journal);
}
/**
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c
index d204ab3..a68cbb6 100644
--- a/fs/jbd/revoke.c
+++ b/fs/jbd/revoke.c
@@ -66,7 +66,6 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/list.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#endif
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index cceaf57..f9822fc 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -23,7 +23,6 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/timer.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/highmem.h>
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 6bd8005..2856e11 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -20,7 +20,6 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
/*
* Default IO end handler for temporary BJ_IO buffer_heads.
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 44fc32b..78d63b8 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -28,7 +28,6 @@
#include <linux/jbd2.h>
#include <linux/errno.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/freezer.h>
@@ -211,10 +210,16 @@ end_loop:
return 0;
}
-static void jbd2_journal_start_thread(journal_t *journal)
+static int jbd2_journal_start_thread(journal_t *journal)
{
- kthread_run(kjournald2, journal, "kjournald2");
+ struct task_struct *t;
+
+ t = kthread_run(kjournald2, journal, "kjournald2");
+ if (IS_ERR(t))
+ return PTR_ERR(t);
+
wait_event(journal->j_wait_done_commit, journal->j_task != 0);
+ return 0;
}
static void journal_kill_thread(journal_t *journal)
@@ -840,8 +845,7 @@ static int journal_reset(journal_t *journal)
/* Add the dynamic fields and write it to disk. */
jbd2_journal_update_superblock(journal, 1);
- jbd2_journal_start_thread(journal);
- return 0;
+ return jbd2_journal_start_thread(journal);
}
/**
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c
index f506646..1e864dc 100644
--- a/fs/jbd2/revoke.c
+++ b/fs/jbd2/revoke.c
@@ -66,7 +66,6 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/list.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#endif
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 3a87001..e347d8c0 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -23,7 +23,6 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/timer.h>
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/highmem.h>
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index e51164a..45368f8 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -47,8 +47,7 @@ static void jffs2_i_init_once(void * foo, struct kmem_cache * cachep, unsigned l
{
struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
init_MUTEX(&ei->sem);
inode_init_once(&ei->vfs_inode);
}
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index e285022..3467dde 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -55,7 +55,6 @@ void jfs_read_inode(struct inode *inode)
inode->i_op = &jfs_file_inode_operations;
init_special_inode(inode, inode->i_mode, inode->i_rdev);
}
- jfs_set_inode_flags(inode);
}
/*
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c
index ed814b1..fe063af 100644
--- a/fs/jfs/ioctl.c
+++ b/fs/jfs/ioctl.c
@@ -59,6 +59,7 @@ int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd,
switch (cmd) {
case JFS_IOC_GETFLAGS:
+ jfs_get_inode_flags(jfs_inode);
flags = jfs_inode->mode2 & JFS_FL_USER_VISIBLE;
flags = jfs_map_ext2(flags, 0);
return put_user(flags, (int __user *) arg);
@@ -78,6 +79,7 @@ int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd,
if (!S_ISDIR(inode->i_mode))
flags &= ~JFS_DIRSYNC_FL;
+ jfs_get_inode_flags(jfs_inode);
oldflags = jfs_inode->mode2;
/*
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index aa5124b..c465607 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -3078,6 +3078,7 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip)
jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
+ jfs_set_inode_flags(ip);
ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff;
if (sbi->umask != -1) {
@@ -3174,6 +3175,7 @@ static void copy_to_dinode(struct dinode * dip, struct inode *ip)
dip->di_gid = cpu_to_le32(ip->i_gid);
else
dip->di_gid = cpu_to_le32(jfs_ip->saved_gid);
+ jfs_get_inode_flags(jfs_ip);
/*
* mode2 is only needed for storing the higher order bits.
* Trust i_mode for the lower order ones
diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c
index 4c67ed9..ed6574b 100644
--- a/fs/jfs/jfs_inode.c
+++ b/fs/jfs/jfs_inode.c
@@ -45,6 +45,24 @@ void jfs_set_inode_flags(struct inode *inode)
inode->i_flags |= S_SYNC;
}
+void jfs_get_inode_flags(struct jfs_inode_info *jfs_ip)
+{
+ unsigned int flags = jfs_ip->vfs_inode.i_flags;
+
+ jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_APPEND_FL | JFS_NOATIME_FL |
+ JFS_DIRSYNC_FL | JFS_SYNC_FL);
+ if (flags & S_IMMUTABLE)
+ jfs_ip->mode2 |= JFS_IMMUTABLE_FL;
+ if (flags & S_APPEND)
+ jfs_ip->mode2 |= JFS_APPEND_FL;
+ if (flags & S_NOATIME)
+ jfs_ip->mode2 |= JFS_NOATIME_FL;
+ if (flags & S_DIRSYNC)
+ jfs_ip->mode2 |= JFS_DIRSYNC_FL;
+ if (flags & S_SYNC)
+ jfs_ip->mode2 |= JFS_SYNC_FL;
+}
+
/*
* NAME: ialloc()
*
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index 6802837..2374b59 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -31,6 +31,7 @@ extern void jfs_truncate(struct inode *);
extern void jfs_truncate_nolock(struct inode *, loff_t);
extern void jfs_free_zero_link(struct inode *);
extern struct dentry *jfs_get_parent(struct dentry *dentry);
+extern void jfs_get_inode_flags(struct jfs_inode_info *);
extern void jfs_set_inode_flags(struct inode *);
extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
diff --git a/fs/jfs/jfs_lock.h b/fs/jfs/jfs_lock.h
index df48ece..ecf0488 100644
--- a/fs/jfs/jfs_lock.h
+++ b/fs/jfs/jfs_lock.h
@@ -45,7 +45,7 @@ do { \
io_schedule(); \
lock_cmd; \
} \
- current->state = TASK_RUNNING; \
+ __set_current_state(TASK_RUNNING); \
remove_wait_queue(&wq, &__wait); \
} while (0)
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index 5065baa..6a3f00d 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -62,7 +62,6 @@
#include <linux/fs.h>
#include <linux/blkdev.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/kthread.h>
#include <linux/buffer_head.h> /* for sync_blockdev() */
@@ -1590,7 +1589,7 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
set_current_state(TASK_UNINTERRUPTIBLE);
LOGGC_UNLOCK(log);
schedule();
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
LOGGC_LOCK(log);
remove_wait_queue(&target->gcwait, &__wait);
}
@@ -2354,14 +2353,15 @@ int jfsIOWait(void *arg)
lbmStartIO(bp);
spin_lock_irq(&log_redrive_lock);
}
- spin_unlock_irq(&log_redrive_lock);
if (freezing(current)) {
+ spin_unlock_irq(&log_redrive_lock);
refrigerator();
} else {
set_current_state(TASK_INTERRUPTIBLE);
+ spin_unlock_irq(&log_redrive_lock);
schedule();
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
}
} while (!kthread_should_stop());
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 58deae0..6b3acb0 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -184,8 +184,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
{
struct metapage *mp = (struct metapage *)foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
mp->lid = 0;
mp->lsn = 0;
mp->flag = 0;
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index 03893ac..25430d0 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -44,7 +44,6 @@
#include <linux/fs.h>
#include <linux/vmalloc.h>
-#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/freezer.h>
#include <linux/module.h>
@@ -136,7 +135,7 @@ static inline void TXN_SLEEP_DROP_LOCK(wait_queue_head_t * event)
set_current_state(TASK_UNINTERRUPTIBLE);
TXN_UNLOCK();
io_schedule();
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(event, &wait);
}
@@ -2798,7 +2797,7 @@ int jfs_lazycommit(void *arg)
set_current_state(TASK_INTERRUPTIBLE);
LAZY_UNLOCK(flags);
schedule();
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&jfs_commit_thread_wait, &wq);
}
} while (!kthread_should_stop());
@@ -2990,7 +2989,7 @@ int jfs_sync(void *arg)
set_current_state(TASK_INTERRUPTIBLE);
TXN_UNLOCK();
schedule();
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
}
} while (!kthread_should_stop());
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 52d73d5..ea9dc3e 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -752,8 +752,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags
{
struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
memset(jfs_ip, 0, sizeof(struct jfs_inode_info));
INIT_LIST_HEAD(&jfs_ip->anon_inode_list);
init_rwsem(&jfs_ip->rdwrlock);
diff --git a/fs/libfs.c b/fs/libfs.c
index d93842d..1247ee9 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -220,6 +220,12 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name,
root = new_inode(s);
if (!root)
goto Enomem;
+ /*
+ * since this is the first inode, make it number 1. New inodes created
+ * after this must take care not to collide with it (by passing
+ * max_reserved of 1 to iunique).
+ */
+ root->i_ino = 1;
root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
root->i_uid = root->i_gid = 0;
root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
@@ -360,6 +366,11 @@ int simple_commit_write(struct file *file, struct page *page,
return 0;
}
+/*
+ * the inodes created here are not hashed. If you use iunique to generate
+ * unique inode values later for this filesystem, then you must take care
+ * to pass it an appropriate max_reserved value to avoid collisions.
+ */
int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files)
{
struct inode *inode;
@@ -376,6 +387,11 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files
inode = new_inode(s);
if (!inode)
return -ENOMEM;
+ /*
+ * because the root inode is 1, the files array must not contain an
+ * entry at index 1
+ */
+ inode->i_ino = 1;
inode->i_mode = S_IFDIR | 0755;
inode->i_uid = inode->i_gid = 0;
inode->i_blocks = 0;
@@ -391,6 +407,13 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files
for (i = 0; !files->name || files->name[0]; i++, files++) {
if (!files->name)
continue;
+
+ /* warn if it tries to conflict with the root inode */
+ if (unlikely(i == 1))
+ printk(KERN_WARNING "%s: %s passed in a files array"
+ "with an index of 1!\n", __func__,
+ s->s_type->name);
+
dentry = d_alloc_name(root, files->name);
if (!dentry)
goto out;
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index a5c019e..a10343b 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -12,7 +12,6 @@
#include <linux/fs.h>
#include <linux/nfs_fs.h>
#include <linux/utsname.h>
-#include <linux/smp_lock.h>
#include <linux/freezer.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/svc.h>
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index 47a66aa..bf27b6c 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -99,7 +99,9 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
/* Now check for conflicting locks */
- resp->status = nlmsvc_testlock(file, &argp->lock, &resp->lock);
+ resp->status = nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie);
+ if (resp->status == nlm_drop_reply)
+ return rpc_drop_reply;
dprintk("lockd: TEST4 status %d\n", ntohl(resp->status));
nlm_release_host(host);
@@ -143,6 +145,8 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Now try to lock the file */
resp->status = nlmsvc_lock(rqstp, file, &argp->lock,
argp->block, &argp->cookie);
+ if (resp->status == nlm_drop_reply)
+ return rpc_drop_reply;
dprintk("lockd: LOCK status %d\n", ntohl(resp->status));
nlm_release_host(host);
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index cf51f84..b3efa45 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -173,7 +173,7 @@ found:
*/
static inline struct nlm_block *
nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
- struct nlm_lock *lock, struct nlm_cookie *cookie)
+ struct nlm_lock *lock, struct nlm_cookie *cookie)
{
struct nlm_block *block;
struct nlm_host *host;
@@ -210,6 +210,7 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
block->b_daemon = rqstp->rq_server;
block->b_host = host;
block->b_file = file;
+ block->b_fl = NULL;
file->f_count++;
/* Add to file's list of blocks */
@@ -261,6 +262,7 @@ static void nlmsvc_free_block(struct kref *kref)
nlmsvc_freegrantargs(block->b_call);
nlm_release_call(block->b_call);
nlm_release_file(block->b_file);
+ kfree(block->b_fl);
kfree(block);
}
@@ -331,6 +333,31 @@ static void nlmsvc_freegrantargs(struct nlm_rqst *call)
}
/*
+ * Deferred lock request handling for non-blocking lock
+ */
+static u32
+nlmsvc_defer_lock_rqst(struct svc_rqst *rqstp, struct nlm_block *block)
+{
+ u32 status = nlm_lck_denied_nolocks;
+
+ block->b_flags |= B_QUEUED;
+
+ nlmsvc_insert_block(block, NLM_TIMEOUT);
+
+ block->b_cache_req = &rqstp->rq_chandle;
+ if (rqstp->rq_chandle.defer) {
+ block->b_deferred_req =
+ rqstp->rq_chandle.defer(block->b_cache_req);
+ if (block->b_deferred_req != NULL)
+ status = nlm_drop_reply;
+ }
+ dprintk("lockd: nlmsvc_defer_lock_rqst block %p flags %d status %d\n",
+ block, block->b_flags, status);
+
+ return status;
+}
+
+/*
* Attempt to establish a lock, and if it can't be granted, block it
* if required.
*/
@@ -338,7 +365,7 @@ __be32
nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
struct nlm_lock *lock, int wait, struct nlm_cookie *cookie)
{
- struct nlm_block *block, *newblock = NULL;
+ struct nlm_block *block = NULL;
int error;
__be32 ret;
@@ -351,29 +378,58 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
wait);
- lock->fl.fl_flags &= ~FL_SLEEP;
-again:
/* Lock file against concurrent access */
mutex_lock(&file->f_mutex);
- /* Get existing block (in case client is busy-waiting) */
+ /* Get existing block (in case client is busy-waiting)
+ * or create new block
+ */
block = nlmsvc_lookup_block(file, lock);
if (block == NULL) {
- if (newblock != NULL)
- lock = &newblock->b_call->a_args.lock;
- } else
+ block = nlmsvc_create_block(rqstp, file, lock, cookie);
+ ret = nlm_lck_denied_nolocks;
+ if (block == NULL)
+ goto out;
lock = &block->b_call->a_args.lock;
+ } else
+ lock->fl.fl_flags &= ~FL_SLEEP;
- error = posix_lock_file(file->f_file, &lock->fl);
- lock->fl.fl_flags &= ~FL_SLEEP;
+ if (block->b_flags & B_QUEUED) {
+ dprintk("lockd: nlmsvc_lock deferred block %p flags %d\n",
+ block, block->b_flags);
+ if (block->b_granted) {
+ nlmsvc_unlink_block(block);
+ ret = nlm_granted;
+ goto out;
+ }
+ if (block->b_flags & B_TIMED_OUT) {
+ nlmsvc_unlink_block(block);
+ ret = nlm_lck_denied;
+ goto out;
+ }
+ ret = nlm_drop_reply;
+ goto out;
+ }
- dprintk("lockd: posix_lock_file returned %d\n", error);
+ if (!wait)
+ lock->fl.fl_flags &= ~FL_SLEEP;
+ error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
+ lock->fl.fl_flags &= ~FL_SLEEP;
+ dprintk("lockd: vfs_lock_file returned %d\n", error);
switch(error) {
case 0:
ret = nlm_granted;
goto out;
case -EAGAIN:
+ ret = nlm_lck_denied;
break;
+ case -EINPROGRESS:
+ if (wait)
+ break;
+ /* Filesystem lock operation is in progress
+ Add it to the queue waiting for callback */
+ ret = nlmsvc_defer_lock_rqst(rqstp, block);
+ goto out;
case -EDEADLK:
ret = nlm_deadlock;
goto out;
@@ -387,26 +443,11 @@ again:
goto out;
ret = nlm_lck_blocked;
- if (block != NULL)
- goto out;
-
- /* If we don't have a block, create and initialize it. Then
- * retry because we may have slept in kmalloc. */
- /* We have to release f_mutex as nlmsvc_create_block may try to
- * to claim it while doing host garbage collection */
- if (newblock == NULL) {
- mutex_unlock(&file->f_mutex);
- dprintk("lockd: blocking on this lock (allocating).\n");
- if (!(newblock = nlmsvc_create_block(rqstp, file, lock, cookie)))
- return nlm_lck_denied_nolocks;
- goto again;
- }
/* Append to list of blocked */
- nlmsvc_insert_block(newblock, NLM_NEVER);
+ nlmsvc_insert_block(block, NLM_NEVER);
out:
mutex_unlock(&file->f_mutex);
- nlmsvc_release_block(newblock);
nlmsvc_release_block(block);
dprintk("lockd: nlmsvc_lock returned %u\n", ret);
return ret;
@@ -416,9 +457,14 @@ out:
* Test for presence of a conflicting lock.
*/
__be32
-nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock,
- struct nlm_lock *conflock)
+nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
+ struct nlm_lock *lock, struct nlm_lock *conflock,
+ struct nlm_cookie *cookie)
{
+ struct nlm_block *block = NULL;
+ int error;
+ __be32 ret;
+
dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
file->f_file->f_path.dentry->d_inode->i_sb->s_id,
file->f_file->f_path.dentry->d_inode->i_ino,
@@ -426,19 +472,70 @@ nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock,
(long long)lock->fl.fl_start,
(long long)lock->fl.fl_end);
- if (posix_test_lock(file->f_file, &lock->fl, &conflock->fl)) {
- dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n",
- conflock->fl.fl_type,
- (long long)conflock->fl.fl_start,
- (long long)conflock->fl.fl_end);
- conflock->caller = "somehost"; /* FIXME */
- conflock->len = strlen(conflock->caller);
- conflock->oh.len = 0; /* don't return OH info */
- conflock->svid = conflock->fl.fl_pid;
- return nlm_lck_denied;
+ /* Get existing block (in case client is busy-waiting) */
+ block = nlmsvc_lookup_block(file, lock);
+
+ if (block == NULL) {
+ struct file_lock *conf = kzalloc(sizeof(*conf), GFP_KERNEL);
+
+ if (conf == NULL)
+ return nlm_granted;
+ block = nlmsvc_create_block(rqstp, file, lock, cookie);
+ if (block == NULL) {
+ kfree(conf);
+ return nlm_granted;
+ }
+ block->b_fl = conf;
+ }
+ if (block->b_flags & B_QUEUED) {
+ dprintk("lockd: nlmsvc_testlock deferred block %p flags %d fl %p\n",
+ block, block->b_flags, block->b_fl);
+ if (block->b_flags & B_TIMED_OUT) {
+ nlmsvc_unlink_block(block);
+ return nlm_lck_denied;
+ }
+ if (block->b_flags & B_GOT_CALLBACK) {
+ if (block->b_fl != NULL
+ && block->b_fl->fl_type != F_UNLCK) {
+ lock->fl = *block->b_fl;
+ goto conf_lock;
+ }
+ else {
+ nlmsvc_unlink_block(block);
+ return nlm_granted;
+ }
+ }
+ return nlm_drop_reply;
}
- return nlm_granted;
+ error = vfs_test_lock(file->f_file, &lock->fl);
+ if (error == -EINPROGRESS)
+ return nlmsvc_defer_lock_rqst(rqstp, block);
+ if (error) {
+ ret = nlm_lck_denied_nolocks;
+ goto out;
+ }
+ if (lock->fl.fl_type == F_UNLCK) {
+ ret = nlm_granted;
+ goto out;
+ }
+
+conf_lock:
+ dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n",
+ lock->fl.fl_type, (long long)lock->fl.fl_start,
+ (long long)lock->fl.fl_end);
+ conflock->caller = "somehost"; /* FIXME */
+ conflock->len = strlen(conflock->caller);
+ conflock->oh.len = 0; /* don't return OH info */
+ conflock->svid = lock->fl.fl_pid;
+ conflock->fl.fl_type = lock->fl.fl_type;
+ conflock->fl.fl_start = lock->fl.fl_start;
+ conflock->fl.fl_end = lock->fl.fl_end;
+ ret = nlm_lck_denied;
+out:
+ if (block)
+ nlmsvc_release_block(block);
+ return ret;
}
/*
@@ -464,7 +561,7 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock)
nlmsvc_cancel_blocked(file, lock);
lock->fl.fl_type = F_UNLCK;
- error = posix_lock_file(file->f_file, &lock->fl);
+ error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
return (error < 0)? nlm_lck_denied_nolocks : nlm_granted;
}
@@ -493,6 +590,8 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
block = nlmsvc_lookup_block(file, lock);
mutex_unlock(&file->f_mutex);
if (block != NULL) {
+ vfs_cancel_lock(block->b_file->f_file,
+ &block->b_call->a_args.lock.fl);
status = nlmsvc_unlink_block(block);
nlmsvc_release_block(block);
}
@@ -500,6 +599,63 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
}
/*
+ * This is a callback from the filesystem for VFS file lock requests.
+ * It will be used if fl_grant is defined and the filesystem can not
+ * respond to the request immediately.
+ * For GETLK request it will copy the reply to the nlm_block.
+ * For SETLK or SETLKW request it will get the local posix lock.
+ * In all cases it will move the block to the head of nlm_blocked q where
+ * nlmsvc_retry_blocked() can send back a reply for SETLKW or revisit the
+ * deferred rpc for GETLK and SETLK.
+ */
+static void
+nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf,
+ int result)
+{
+ block->b_flags |= B_GOT_CALLBACK;
+ if (result == 0)
+ block->b_granted = 1;
+ else
+ block->b_flags |= B_TIMED_OUT;
+ if (conf) {
+ if (block->b_fl)
+ locks_copy_lock(block->b_fl, conf);
+ }
+}
+
+static int nlmsvc_grant_deferred(struct file_lock *fl, struct file_lock *conf,
+ int result)
+{
+ struct nlm_block *block;
+ int rc = -ENOENT;
+
+ lock_kernel();
+ list_for_each_entry(block, &nlm_blocked, b_list) {
+ if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
+ dprintk("lockd: nlmsvc_notify_blocked block %p flags %d\n",
+ block, block->b_flags);
+ if (block->b_flags & B_QUEUED) {
+ if (block->b_flags & B_TIMED_OUT) {
+ rc = -ENOLCK;
+ break;
+ }
+ nlmsvc_update_deferred_block(block, conf, result);
+ } else if (result == 0)
+ block->b_granted = 1;
+
+ nlmsvc_insert_block(block, 0);
+ svc_wake_up(block->b_daemon);
+ rc = 0;
+ break;
+ }
+ }
+ unlock_kernel();
+ if (rc == -ENOENT)
+ printk(KERN_WARNING "lockd: grant for unknown block\n");
+ return rc;
+}
+
+/*
* Unblock a blocked lock request. This is a callback invoked from the
* VFS layer when a lock on which we blocked is removed.
*
@@ -531,6 +687,7 @@ static int nlmsvc_same_owner(struct file_lock *fl1, struct file_lock *fl2)
struct lock_manager_operations nlmsvc_lock_operations = {
.fl_compare_owner = nlmsvc_same_owner,
.fl_notify = nlmsvc_notify_blocked,
+ .fl_grant = nlmsvc_grant_deferred,
};
/*
@@ -553,6 +710,8 @@ nlmsvc_grant_blocked(struct nlm_block *block)
dprintk("lockd: grant blocked lock %p\n", block);
+ kref_get(&block->b_count);
+
/* Unlink block request from list */
nlmsvc_unlink_block(block);
@@ -566,20 +725,23 @@ nlmsvc_grant_blocked(struct nlm_block *block)
/* Try the lock operation again */
lock->fl.fl_flags |= FL_SLEEP;
- error = posix_lock_file(file->f_file, &lock->fl);
+ error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
lock->fl.fl_flags &= ~FL_SLEEP;
switch (error) {
case 0:
break;
case -EAGAIN:
- dprintk("lockd: lock still blocked\n");
+ case -EINPROGRESS:
+ dprintk("lockd: lock still blocked error %d\n", error);
nlmsvc_insert_block(block, NLM_NEVER);
+ nlmsvc_release_block(block);
return;
default:
printk(KERN_WARNING "lockd: unexpected error %d in %s!\n",
-error, __FUNCTION__);
nlmsvc_insert_block(block, 10 * HZ);
+ nlmsvc_release_block(block);
return;
}
@@ -592,7 +754,6 @@ callback:
nlmsvc_insert_block(block, 30 * HZ);
/* Call the client */
- kref_get(&block->b_count);
nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG, &nlmsvc_grant_ops);
}
@@ -665,6 +826,23 @@ nlmsvc_grant_reply(struct nlm_cookie *cookie, __be32 status)
nlmsvc_release_block(block);
}
+/* Helper function to handle retry of a deferred block.
+ * If it is a blocking lock, call grant_blocked.
+ * For a non-blocking lock or test lock, revisit the request.
+ */
+static void
+retry_deferred_block(struct nlm_block *block)
+{
+ if (!(block->b_flags & B_GOT_CALLBACK))
+ block->b_flags |= B_TIMED_OUT;
+ nlmsvc_insert_block(block, NLM_TIMEOUT);
+ dprintk("revisit block %p flags %d\n", block, block->b_flags);
+ if (block->b_deferred_req) {
+ block->b_deferred_req->revisit(block->b_deferred_req, 0);
+ block->b_deferred_req = NULL;
+ }
+}
+
/*
* Retry all blocked locks that have been notified. This is where lockd
* picks up locks that can be granted, or grant notifications that must
@@ -688,9 +866,12 @@ nlmsvc_retry_blocked(void)
dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
block, block->b_when);
- kref_get(&block->b_count);
- nlmsvc_grant_blocked(block);
- nlmsvc_release_block(block);
+ if (block->b_flags & B_QUEUED) {
+ dprintk("nlmsvc_retry_blocked delete block (%p, granted=%d, flags=%d)\n",
+ block, block->b_granted, block->b_flags);
+ retry_deferred_block(block);
+ } else
+ nlmsvc_grant_blocked(block);
}
return timeout;
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 31cb484..9cd5c8b 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -33,6 +33,7 @@ cast_to_nlm(__be32 status, u32 vers)
case nlm_lck_denied_nolocks:
case nlm_lck_blocked:
case nlm_lck_denied_grace_period:
+ case nlm_drop_reply:
break;
case nlm4_deadlock:
status = nlm_lck_denied;
@@ -127,7 +128,9 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
/* Now check for conflicting locks */
- resp->status = cast_status(nlmsvc_testlock(file, &argp->lock, &resp->lock));
+ resp->status = cast_status(nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie));
+ if (resp->status == nlm_drop_reply)
+ return rpc_drop_reply;
dprintk("lockd: TEST status %d vers %d\n",
ntohl(resp->status), rqstp->rq_vers);
@@ -172,6 +175,8 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Now try to lock the file */
resp->status = cast_status(nlmsvc_lock(rqstp, file, &argp->lock,
argp->block, &argp->cookie));
+ if (resp->status == nlm_drop_reply)
+ return rpc_drop_reply;
dprintk("lockd: LOCK status %d\n", ntohl(resp->status));
nlm_release_host(host);
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index c0df00c..84ebba3 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -182,7 +182,7 @@ again:
lock.fl_type = F_UNLCK;
lock.fl_start = 0;
lock.fl_end = OFFSET_MAX;
- if (posix_lock_file(file->f_file, &lock) < 0) {
+ if (vfs_lock_file(file->f_file, F_SETLK, &lock, NULL) < 0) {
printk("lockd: unlock failure in %s:%d\n",
__FILE__, __LINE__);
return 1;
diff --git a/fs/locks.c b/fs/locks.c
index 52a8100..671a034 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -203,8 +203,7 @@ static void init_once(void *foo, struct kmem_cache *cache, unsigned long flags)
{
struct file_lock *lock = (struct file_lock *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) !=
- SLAB_CTOR_CONSTRUCTOR)
+ if (!(flags & SLAB_CTOR_CONSTRUCTOR))
return;
locks_init_lock(lock);
@@ -666,11 +665,11 @@ static int locks_block_on_timeout(struct file_lock *blocker, struct file_lock *w
}
int
-posix_test_lock(struct file *filp, struct file_lock *fl,
- struct file_lock *conflock)
+posix_test_lock(struct file *filp, struct file_lock *fl)
{
struct file_lock *cfl;
+ fl->fl_type = F_UNLCK;
lock_kernel();
for (cfl = filp->f_path.dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) {
if (!IS_POSIX(cfl))
@@ -679,7 +678,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl,
break;
}
if (cfl) {
- __locks_copy_lock(conflock, cfl);
+ __locks_copy_lock(fl, cfl);
unlock_kernel();
return 1;
}
@@ -801,7 +800,7 @@ out:
return error;
}
-static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request, struct file_lock *conflock)
+static int __posix_lock_file(struct inode *inode, struct file_lock *request, struct file_lock *conflock)
{
struct file_lock *fl;
struct file_lock *new_fl = NULL;
@@ -1007,6 +1006,7 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
* posix_lock_file - Apply a POSIX-style lock to a file
* @filp: The file to apply the lock to
* @fl: The lock to be applied
+ * @conflock: Place to return a copy of the conflicting lock, if found.
*
* Add a POSIX style lock to a file.
* We merge adjacent & overlapping locks whenever possible.
@@ -1016,26 +1016,12 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
* whether or not a lock was successfully freed by testing the return
* value for -ENOENT.
*/
-int posix_lock_file(struct file *filp, struct file_lock *fl)
-{
- return __posix_lock_file_conf(filp->f_path.dentry->d_inode, fl, NULL);
-}
-EXPORT_SYMBOL(posix_lock_file);
-
-/**
- * posix_lock_file_conf - Apply a POSIX-style lock to a file
- * @filp: The file to apply the lock to
- * @fl: The lock to be applied
- * @conflock: Place to return a copy of the conflicting lock, if found.
- *
- * Except for the conflock parameter, acts just like posix_lock_file.
- */
-int posix_lock_file_conf(struct file *filp, struct file_lock *fl,
+int posix_lock_file(struct file *filp, struct file_lock *fl,
struct file_lock *conflock)
{
- return __posix_lock_file_conf(filp->f_path.dentry->d_inode, fl, conflock);
+ return __posix_lock_file(filp->f_path.dentry->d_inode, fl, conflock);
}
-EXPORT_SYMBOL(posix_lock_file_conf);
+EXPORT_SYMBOL(posix_lock_file);
/**
* posix_lock_file_wait - Apply a POSIX-style lock to a file
@@ -1051,7 +1037,7 @@ int posix_lock_file_wait(struct file *filp, struct file_lock *fl)
int error;
might_sleep ();
for (;;) {
- error = posix_lock_file(filp, fl);
+ error = posix_lock_file(filp, fl, NULL);
if ((error != -EAGAIN) || !(fl->fl_flags & FL_SLEEP))
break;
error = wait_event_interruptible(fl->fl_wait, !fl->fl_next);
@@ -1123,7 +1109,7 @@ int locks_mandatory_area(int read_write, struct inode *inode,
fl.fl_end = offset + count - 1;
for (;;) {
- error = __posix_lock_file_conf(inode, &fl, NULL);
+ error = __posix_lock_file(inode, &fl, NULL);
if (error != -EAGAIN)
break;
if (!(fl.fl_flags & FL_SLEEP))
@@ -1611,12 +1597,62 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
return error;
}
+/**
+ * vfs_test_lock - test file byte range lock
+ * @filp: The file to test lock for
+ * @fl: The lock to test
+ * @conf: Place to return a copy of the conflicting lock, if found
+ *
+ * Returns -ERRNO on failure. Indicates presence of conflicting lock by
+ * setting conf->fl_type to something other than F_UNLCK.
+ */
+int vfs_test_lock(struct file *filp, struct file_lock *fl)
+{
+ if (filp->f_op && filp->f_op->lock)
+ return filp->f_op->lock(filp, F_GETLK, fl);
+ posix_test_lock(filp, fl);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(vfs_test_lock);
+
+static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
+{
+ flock->l_pid = fl->fl_pid;
+#if BITS_PER_LONG == 32
+ /*
+ * Make sure we can represent the posix lock via
+ * legacy 32bit flock.
+ */
+ if (fl->fl_start > OFFT_OFFSET_MAX)
+ return -EOVERFLOW;
+ if (fl->fl_end != OFFSET_MAX && fl->fl_end > OFFT_OFFSET_MAX)
+ return -EOVERFLOW;
+#endif
+ flock->l_start = fl->fl_start;
+ flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
+ fl->fl_end - fl->fl_start + 1;
+ flock->l_whence = 0;
+ return 0;
+}
+
+#if BITS_PER_LONG == 32
+static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
+{
+ flock->l_pid = fl->fl_pid;
+ flock->l_start = fl->fl_start;
+ flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
+ fl->fl_end - fl->fl_start + 1;
+ flock->l_whence = 0;
+ flock->l_type = fl->fl_type;
+}
+#endif
+
/* Report the first existing lock that would conflict with l.
* This implements the F_GETLK command of fcntl().
*/
int fcntl_getlk(struct file *filp, struct flock __user *l)
{
- struct file_lock *fl, cfl, file_lock;
+ struct file_lock file_lock;
struct flock flock;
int error;
@@ -1631,38 +1667,15 @@ int fcntl_getlk(struct file *filp, struct flock __user *l)
if (error)
goto out;
- if (filp->f_op && filp->f_op->lock) {
- error = filp->f_op->lock(filp, F_GETLK, &file_lock);
- if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
- file_lock.fl_ops->fl_release_private(&file_lock);
- if (error < 0)
- goto out;
- else
- fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
- } else {
- fl = (posix_test_lock(filp, &file_lock, &cfl) ? &cfl : NULL);
- }
+ error = vfs_test_lock(filp, &file_lock);
+ if (error)
+ goto out;
- flock.l_type = F_UNLCK;
- if (fl != NULL) {
- flock.l_pid = fl->fl_pid;
-#if BITS_PER_LONG == 32
- /*
- * Make sure we can represent the posix lock via
- * legacy 32bit flock.
- */
- error = -EOVERFLOW;
- if (fl->fl_start > OFFT_OFFSET_MAX)
- goto out;
- if ((fl->fl_end != OFFSET_MAX)
- && (fl->fl_end > OFFT_OFFSET_MAX))
+ flock.l_type = file_lock.fl_type;
+ if (file_lock.fl_type != F_UNLCK) {
+ error = posix_lock_to_flock(&flock, &file_lock);
+ if (error)
goto out;
-#endif
- flock.l_start = fl->fl_start;
- flock.l_len = fl->fl_end == OFFSET_MAX ? 0 :
- fl->fl_end - fl->fl_start + 1;
- flock.l_whence = 0;
- flock.l_type = fl->fl_type;
}
error = -EFAULT;
if (!copy_to_user(l, &flock, sizeof(flock)))
@@ -1671,6 +1684,48 @@ out:
return error;
}
+/**
+ * vfs_lock_file - file byte range lock
+ * @filp: The file to apply the lock to
+ * @cmd: type of locking operation (F_SETLK, F_GETLK, etc.)
+ * @fl: The lock to be applied
+ * @conf: Place to return a copy of the conflicting lock, if found.
+ *
+ * A caller that doesn't care about the conflicting lock may pass NULL
+ * as the final argument.
+ *
+ * If the filesystem defines a private ->lock() method, then @conf will
+ * be left unchanged; so a caller that cares should initialize it to
+ * some acceptable default.
+ *
+ * To avoid blocking kernel daemons, such as lockd, that need to acquire POSIX
+ * locks, the ->lock() interface may return asynchronously, before the lock has
+ * been granted or denied by the underlying filesystem, if (and only if)
+ * fl_grant is set. Callers expecting ->lock() to return asynchronously
+ * will only use F_SETLK, not F_SETLKW; they will set FL_SLEEP if (and only if)
+ * the request is for a blocking lock. When ->lock() does return asynchronously,
+ * it must return -EINPROGRESS, and call ->fl_grant() when the lock
+ * request completes.
+ * If the request is for non-blocking lock the file system should return
+ * -EINPROGRESS then try to get the lock and call the callback routine with
+ * the result. If the request timed out the callback routine will return a
+ * nonzero return code and the file system should release the lock. The file
+ * system is also responsible to keep a corresponding posix lock when it
+ * grants a lock so the VFS can find out which locks are locally held and do
+ * the correct lock cleanup when required.
+ * The underlying filesystem must not drop the kernel lock or call
+ * ->fl_grant() before returning to the caller with a -EINPROGRESS
+ * return code.
+ */
+int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf)
+{
+ if (filp->f_op && filp->f_op->lock)
+ return filp->f_op->lock(filp, cmd, fl);
+ else
+ return posix_lock_file(filp, fl, conf);
+}
+EXPORT_SYMBOL_GPL(vfs_lock_file);
+
/* Apply the lock described by l to an open file descriptor.
* This implements both the F_SETLK and F_SETLKW commands of fcntl().
*/
@@ -1733,21 +1788,17 @@ again:
if (error)
goto out;
- if (filp->f_op && filp->f_op->lock != NULL)
- error = filp->f_op->lock(filp, cmd, file_lock);
- else {
- for (;;) {
- error = posix_lock_file(filp, file_lock);
- if ((error != -EAGAIN) || (cmd == F_SETLK))
- break;
- error = wait_event_interruptible(file_lock->fl_wait,
- !file_lock->fl_next);
- if (!error)
- continue;
-
- locks_delete_block(file_lock);
+ for (;;) {
+ error = vfs_lock_file(filp, cmd, file_lock, NULL);
+ if (error != -EAGAIN || cmd == F_SETLK)
break;
- }
+ error = wait_event_interruptible(file_lock->fl_wait,
+ !file_lock->fl_next);
+ if (!error)
+ continue;
+
+ locks_delete_block(file_lock);
+ break;
}
/*
@@ -1770,7 +1821,7 @@ out:
*/
int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
{
- struct file_lock *fl, cfl, file_lock;
+ struct file_lock file_lock;
struct flock64 flock;
int error;
@@ -1785,27 +1836,14 @@ int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
if (error)
goto out;
- if (filp->f_op && filp->f_op->lock) {
- error = filp->f_op->lock(filp, F_GETLK, &file_lock);
- if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
- file_lock.fl_ops->fl_release_private(&file_lock);
- if (error < 0)
- goto out;
- else
- fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
- } else {
- fl = (posix_test_lock(filp, &file_lock, &cfl) ? &cfl : NULL);
- }
-
- flock.l_type = F_UNLCK;
- if (fl != NULL) {
- flock.l_pid = fl->fl_pid;
- flock.l_start = fl->fl_start;
- flock.l_len = fl->fl_end == OFFSET_MAX ? 0 :
- fl->fl_end - fl->fl_start + 1;
- flock.l_whence = 0;
- flock.l_type = fl->fl_type;
- }
+ error = vfs_test_lock(filp, &file_lock);
+ if (error)
+ goto out;
+
+ flock.l_type = file_lock.fl_type;
+ if (file_lock.fl_type != F_UNLCK)
+ posix_lock_to_flock64(&flock, &file_lock);
+
error = -EFAULT;
if (!copy_to_user(l, &flock, sizeof(flock)))
error = 0;
@@ -1876,21 +1914,17 @@ again:
if (error)
goto out;
- if (filp->f_op && filp->f_op->lock != NULL)
- error = filp->f_op->lock(filp, cmd, file_lock);
- else {
- for (;;) {
- error = posix_lock_file(filp, file_lock);
- if ((error != -EAGAIN) || (cmd == F_SETLK64))
- break;
- error = wait_event_interruptible(file_lock->fl_wait,
- !file_lock->fl_next);
- if (!error)
- continue;
-
- locks_delete_block(file_lock);
+ for (;;) {
+ error = vfs_lock_file(filp, cmd, file_lock, NULL);
+ if (error != -EAGAIN || cmd == F_SETLK64)
break;
- }
+ error = wait_event_interruptible(file_lock->fl_wait,
+ !file_lock->fl_next);
+ if (!error)
+ continue;
+
+ locks_delete_block(file_lock);
+ break;
}
/*
@@ -1935,10 +1969,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
lock.fl_ops = NULL;
lock.fl_lmops = NULL;
- if (filp->f_op && filp->f_op->lock != NULL)
- filp->f_op->lock(filp, F_SETLK, &lock);
- else
- posix_lock_file(filp, &lock);
+ vfs_lock_file(filp, F_SETLK, &lock, NULL);
if (lock.fl_ops && lock.fl_ops->fl_release_private)
lock.fl_ops->fl_release_private(&lock);
@@ -2015,6 +2046,22 @@ posix_unblock_lock(struct file *filp, struct file_lock *waiter)
EXPORT_SYMBOL(posix_unblock_lock);
+/**
+ * vfs_cancel_lock - file byte range unblock lock
+ * @filp: The file to apply the unblock to
+ * @fl: The lock to be unblocked
+ *
+ * Used by lock managers to cancel blocked requests
+ */
+int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
+{
+ if (filp->f_op && filp->f_op->lock)
+ return filp->f_op->lock(filp, F_CANCELLK, fl);
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(vfs_cancel_lock);
+
static void lock_get_status(char* out, struct file_lock *fl, int id, char *pfx)
{
struct inode *inode = NULL;
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index cb4cb57..e207cbe 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -65,7 +65,6 @@ static struct page * dir_get_page(struct inode *dir, unsigned long n)
struct address_space *mapping = dir->i_mapping;
struct page *page = read_mapping_page(mapping, n, NULL);
if (!IS_ERR(page)) {
- wait_on_page_locked(page);
kmap(page);
if (!PageUptodate(page))
goto fail;
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 92e383a..2f4d43a 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -73,8 +73,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct minix_inode_info *ei = (struct minix_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&ei->vfs_inode);
}
diff --git a/fs/mpage.c b/fs/mpage.c
index 692a3e5..fa2441f 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -663,12 +663,7 @@ confused:
/*
* The caller has a ref on the inode, so *mapping is stable
*/
- if (*ret) {
- if (*ret == -ENOSPC)
- set_bit(AS_ENOSPC, &mapping->flags);
- else
- set_bit(AS_EIO, &mapping->flags);
- }
+ mapping_set_error(mapping, *ret);
out:
return bio;
}
@@ -776,14 +771,7 @@ retry:
if (writepage) {
ret = (*writepage)(page, wbc);
- if (ret) {
- if (ret == -ENOSPC)
- set_bit(AS_ENOSPC,
- &mapping->flags);
- else
- set_bit(AS_EIO,
- &mapping->flags);
- }
+ mapping_set_error(mapping, ret);
} else {
bio = __mpage_writepage(bio, page, get_block,
&last_block_in_bio, &ret, wbc,
diff --git a/fs/namei.c b/fs/namei.c
index 880052c..856b2f5 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -22,7 +22,6 @@
#include <linux/quotaops.h>
#include <linux/pagemap.h>
#include <linux/fsnotify.h>
-#include <linux/smp_lock.h>
#include <linux/personality.h>
#include <linux/security.h>
#include <linux/syscalls.h>
@@ -1350,17 +1349,6 @@ struct dentry *lookup_one_len_kern(const char *name, struct dentry *base, int le
return __lookup_hash_kern(&this, base, NULL);
}
-/*
- * namei()
- *
- * is used by most simple commands to get the inode of a specified name.
- * Open, link etc use their own routines, but this is enough for things
- * like 'chmod' etc.
- *
- * namei exists in two versions: namei/lnamei. The only difference is
- * that namei follows links, while lnamei does not.
- * SMP-safe
- */
int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags,
struct nameidata *nd)
{
@@ -2671,19 +2659,9 @@ static char *page_getlink(struct dentry * dentry, struct page **ppage)
struct address_space *mapping = dentry->d_inode->i_mapping;
page = read_mapping_page(mapping, 0, NULL);
if (IS_ERR(page))
- goto sync_fail;
- wait_on_page_locked(page);
- if (!PageUptodate(page))
- goto async_fail;
+ return (char*)page;
*ppage = page;
return kmap(page);
-
-async_fail:
- page_cache_release(page);
- return ERR_PTR(-EIO);
-
-sync_fail:
- return (char*)page;
}
int page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
diff --git a/fs/namespace.c b/fs/namespace.c
index fd999ca..b696e3a 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -377,6 +377,10 @@ static int show_vfsmnt(struct seq_file *m, void *v)
seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
seq_putc(m, ' ');
mangle(m, mnt->mnt_sb->s_type->name);
+ if (mnt->mnt_sb->s_subtype && mnt->mnt_sb->s_subtype[0]) {
+ seq_putc(m, '.');
+ mangle(m, mnt->mnt_sb->s_subtype);
+ }
seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
if (mnt->mnt_sb->s_flags & fs_infop->flag)
@@ -495,7 +499,7 @@ void release_mounts(struct list_head *head)
{
struct vfsmount *mnt;
while (!list_empty(head)) {
- mnt = list_entry(head->next, struct vfsmount, mnt_hash);
+ mnt = list_first_entry(head, struct vfsmount, mnt_hash);
list_del_init(&mnt->mnt_hash);
if (mnt->mnt_parent != mnt) {
struct dentry *dentry;
@@ -882,6 +886,9 @@ static int do_change_type(struct nameidata *nd, int flag)
int recurse = flag & MS_REC;
int type = flag & ~MS_REC;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
if (nd->dentry != nd->mnt->mnt_root)
return -EINVAL;
@@ -1173,7 +1180,7 @@ static void expire_mount_list(struct list_head *graveyard, struct list_head *mou
while (!list_empty(graveyard)) {
LIST_HEAD(umounts);
- mnt = list_entry(graveyard->next, struct vfsmount, mnt_expire);
+ mnt = list_first_entry(graveyard, struct vfsmount, mnt_expire);
list_del_init(&mnt->mnt_expire);
/* don't do anything if the namespace is dead - all the
@@ -1441,10 +1448,9 @@ dput_out:
* Allocate a new namespace structure and populate it with contents
* copied from the namespace of the passed in task structure.
*/
-struct mnt_namespace *dup_mnt_ns(struct task_struct *tsk,
+static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
struct fs_struct *fs)
{
- struct mnt_namespace *mnt_ns = tsk->nsproxy->mnt_ns;
struct mnt_namespace *new_ns;
struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
struct vfsmount *p, *q;
@@ -1509,36 +1515,21 @@ struct mnt_namespace *dup_mnt_ns(struct task_struct *tsk,
return new_ns;
}
-int copy_mnt_ns(int flags, struct task_struct *tsk)
+struct mnt_namespace *copy_mnt_ns(int flags, struct mnt_namespace *ns,
+ struct fs_struct *new_fs)
{
- struct mnt_namespace *ns = tsk->nsproxy->mnt_ns;
struct mnt_namespace *new_ns;
- int err = 0;
-
- if (!ns)
- return 0;
+ BUG_ON(!ns);
get_mnt_ns(ns);
if (!(flags & CLONE_NEWNS))
- return 0;
+ return ns;
- if (!capable(CAP_SYS_ADMIN)) {
- err = -EPERM;
- goto out;
- }
-
- new_ns = dup_mnt_ns(tsk, tsk->fs);
- if (!new_ns) {
- err = -ENOMEM;
- goto out;
- }
+ new_ns = dup_mnt_ns(ns, new_fs);
- tsk->nsproxy->mnt_ns = new_ns;
-
-out:
put_mnt_ns(ns);
- return err;
+ return new_ns;
}
asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index 6b1f6d2..addfd31 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -17,7 +17,6 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
-#include <linux/smp_lock.h>
#include <linux/ncp_fs.h>
#include "ncplib_kernel.h"
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 7285c94..c29f00a 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -60,8 +60,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
mutex_init(&ei->open_mutex);
inode_init_once(&ei->vfs_inode);
}
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 5bd03b9..50c6821 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -27,7 +27,6 @@
#include <linux/nfs_mount.h>
#include <linux/nfs4_mount.h>
#include <linux/lockd/bind.h>
-#include <linux/smp_lock.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include <linux/nfs_idmap.h>
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index e59fd31..625d8e5 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -334,8 +334,6 @@ int find_dirent_page(nfs_readdir_descriptor_t *desc)
status = PTR_ERR(page);
goto out;
}
- if (!PageUptodate(page))
- goto read_error;
/* NOTE: Someone else may have changed the READDIRPLUS flag */
desc->page = page;
@@ -349,9 +347,6 @@ int find_dirent_page(nfs_readdir_descriptor_t *desc)
out:
dfprintk(DIRCACHE, "NFS: %s: returns %d\n", __FUNCTION__, status);
return status;
- read_error:
- page_cache_release(page);
- return -EIO;
}
/*
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 889de60..345aa5c 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -41,7 +41,6 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/file.h>
#include <linux/pagemap.h>
#include <linux/kref.h>
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 8e66b5a..5eaee6d 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -391,17 +391,12 @@ out_swapfile:
static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
{
- struct file_lock cfl;
struct inode *inode = filp->f_mapping->host;
int status = 0;
lock_kernel();
/* Try local locking first */
- if (posix_test_lock(filp, fl, &cfl)) {
- fl->fl_start = cfl.fl_start;
- fl->fl_end = cfl.fl_end;
- fl->fl_type = cfl.fl_type;
- fl->fl_pid = cfl.fl_pid;
+ if (posix_test_lock(filp, fl)) {
goto out;
}
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index 6ef268f..2347785 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -25,7 +25,6 @@
#include <linux/nfs_mount.h>
#include <linux/nfs4_mount.h>
#include <linux/lockd/bind.h>
-#include <linux/smp_lock.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include <linux/nfs_idmap.h>
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 44aa9b7..1e9a915 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1167,8 +1167,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct nfs_inode *nfsi = (struct nfs_inode *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
inode_init_once(&nfsi->vfs_inode);
spin_lock_init(&nfsi->req_lock);
INIT_LIST_HEAD(&nfsi->dirty);
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 7d0371e..45268d6 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -16,7 +16,6 @@
#include <linux/nfs_fs.h>
#include <linux/nfs_page.h>
#include <linux/lockd/bind.h>
-#include <linux/smp_lock.h>
#include <linux/nfs_mount.h>
#include "iostat.h"
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 3b5ca1b..d6a30e9 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3017,6 +3017,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
case -NFS4ERR_DENIED:
status = 0;
}
+ request->fl_ops->fl_release_private(request);
out:
up_read(&clp->cl_sem);
return status;
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index f5f4430..0505ca1 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -43,7 +43,6 @@
* child task framework of the RPC layer?
*/
-#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/sunrpc/sched.h>
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 1dcf56d..7be0ee2 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -43,7 +43,6 @@
#include <linux/nfs_fs.h>
#include <linux/nfs_page.h>
#include <linux/lockd/bind.h>
-#include <linux/smp_lock.h>
#include "internal.h"
#define NFSDBG_FACILITY NFSDBG_PROC
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
index f4a0548..83e865a 100644
--- a/fs/nfs/symlink.c
+++ b/fs/nfs/symlink.c
@@ -22,7 +22,6 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/namei.h>
/* Symlink caching in the page cache is even more simplistic
@@ -61,15 +60,9 @@ static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
err = page;
goto read_failed;
}
- if (!PageUptodate(page)) {
- err = ERR_PTR(-EIO);
- goto getlink_read_error;
- }
nd_set_link(nd, kmap(page));
return page;
-getlink_read_error:
- page_cache_release(page);
read_failed:
nd_set_link(nd, err);
return NULL;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 5d44b8b..de92b95 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -21,7 +21,6 @@
#include <linux/backing-dev.h>
#include <asm/uaccess.h>
-#include <linux/smp_lock.h>
#include "delegation.h"
#include "internal.h"
@@ -225,7 +224,7 @@ static int nfs_set_page_writeback(struct page *page)
struct inode *inode = page->mapping->host;
struct nfs_server *nfss = NFS_SERVER(inode);
- if (atomic_inc_return(&nfss->writeback) >
+ if (atomic_long_inc_return(&nfss->writeback) >
NFS_CONGESTION_ON_THRESH)
set_bdi_congested(&nfss->backing_dev_info, WRITE);
}
@@ -238,7 +237,7 @@ static void nfs_end_page_writeback(struct page *page)
struct nfs_server *nfss = NFS_SERVER(inode);
end_page_writeback(page);
- if (atomic_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) {
+ if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) {
clear_bdi_congested(&nfss->backing_dev_info, WRITE);
congestion_end(WRITE);
}
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index e4a83d7..45aa21c 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -46,7 +46,6 @@
#include <linux/nfs4.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_page.h>
-#include <linux/smp_lock.h>
#include <linux/sunrpc/cache.h>
#include <linux/nfsd_idmap.h>
#include <linux/list.h>
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index af36070..678f3be 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -50,6 +50,7 @@
#include <linux/nfsd/xdr4.h>
#include <linux/namei.h>
#include <linux/mutex.h>
+#include <linux/lockd/bind.h>
#define NFSDDBG_FACILITY NFSDDBG_PROC
@@ -2657,6 +2658,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct file_lock conflock;
__be32 status = 0;
unsigned int strhashval;
+ unsigned int cmd;
int err;
dprintk("NFSD: nfsd4_lock: start=%Ld length=%Ld\n",
@@ -2739,10 +2741,12 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
case NFS4_READ_LT:
case NFS4_READW_LT:
file_lock.fl_type = F_RDLCK;
+ cmd = F_SETLK;
break;
case NFS4_WRITE_LT:
case NFS4_WRITEW_LT:
file_lock.fl_type = F_WRLCK;
+ cmd = F_SETLK;
break;
default:
status = nfserr_inval;
@@ -2769,9 +2773,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
/* XXX?: Just to divert the locks_release_private at the start of
* locks_copy_lock: */
- conflock.fl_ops = NULL;
- conflock.fl_lmops = NULL;
- err = posix_lock_file_conf(filp, &file_lock, &conflock);
+ locks_init_lock(&conflock);
+ err = vfs_lock_file(filp, cmd, &file_lock, &conflock);
switch (-err) {
case 0: /* success! */
update_stateid(&lock_stp->st_stateid);
@@ -2788,7 +2791,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
status = nfserr_deadlock;
break;
default:
- dprintk("NFSD: nfsd4_lock: posix_lock_file_conf() failed! status %d\n",err);
+ dprintk("NFSD: nfsd4_lock: vfs_lock_file() failed! status %d\n",err);
status = nfserr_resource;
break;
}
@@ -2813,7 +2816,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct inode *inode;
struct file file;
struct file_lock file_lock;
- struct file_lock conflock;
+ int error;
__be32 status;
if (nfs4_in_grace())
@@ -2869,18 +2872,23 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
nfs4_transform_lock_offset(&file_lock);
- /* posix_test_lock uses the struct file _only_ to resolve the inode.
+ /* vfs_test_lock uses the struct file _only_ to resolve the inode.
* since LOCKT doesn't require an OPEN, and therefore a struct
- * file may not exist, pass posix_test_lock a struct file with
+ * file may not exist, pass vfs_test_lock a struct file with
* only the dentry:inode set.
*/
memset(&file, 0, sizeof (struct file));
file.f_path.dentry = cstate->current_fh.fh_dentry;
status = nfs_ok;
- if (posix_test_lock(&file, &file_lock, &conflock)) {
+ error = vfs_test_lock(&file, &file_lock);
+ if (error) {
+ status = nfserrno(error);
+ goto out;
+ }
+ if (file_lock.fl_type != F_UNLCK) {
status = nfserr_denied;
- nfs4_set_lock_denied(&conflock, &lockt->lt_denied);
+ nfs4_set_lock_denied(&file_lock, &lockt->lt_denied);
}
out:
nfs4_unlock_state();
@@ -2933,9 +2941,9 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
/*
* Try to unlock the file in the VFS.
*/
- err = posix_lock_file(filp, &file_lock);
+ err = vfs_lock_file(filp, F_SETLK, &file_lock, NULL);
if (err) {
- dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n");
+ dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n");
goto out_nfserr;
}
/*
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 5d090f1..15809df 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -44,7 +44,6 @@
#include <linux/param.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/vfs.h>
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 8d995bc..739dd3c 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -10,7 +10,6 @@
*/
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/unistd.h>
#include <linux/string.h>
diff --git a/fs/ntfs/aops.h b/fs/ntfs/aops.h
index 9393f4b..caecc58 100644
--- a/fs/ntfs/aops.h
+++ b/fs/ntfs/aops.h
@@ -89,9 +89,8 @@ static inline struct page *ntfs_map_page(struct address_space *mapping,
struct page *page = read_mapping_page(mapping, index, NULL);
if (!IS_ERR(page)) {
- wait_on_page_locked(page);
kmap(page);
- if (PageUptodate(page) && !PageError(page))
+ if (!PageError(page))
return page;
ntfs_unmap_page(page);
return ERR_PTR(-EIO);
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 7659cc1..1c08fef 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -2532,14 +2532,7 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
page = read_mapping_page(mapping, idx, NULL);
if (IS_ERR(page)) {
ntfs_error(vol->sb, "Failed to read first partial "
- "page (sync error, index 0x%lx).", idx);
- return PTR_ERR(page);
- }
- wait_on_page_locked(page);
- if (unlikely(!PageUptodate(page))) {
- ntfs_error(vol->sb, "Failed to read first partial page "
- "(async error, index 0x%lx).", idx);
- page_cache_release(page);
+ "page (error, index 0x%lx).", idx);
return PTR_ERR(page);
}
/*
@@ -2602,14 +2595,7 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
page = read_mapping_page(mapping, idx, NULL);
if (IS_ERR(page)) {
ntfs_error(vol->sb, "Failed to read last partial page "
- "(sync error, index 0x%lx).", idx);
- return PTR_ERR(page);
- }
- wait_on_page_locked(page);
- if (unlikely(!PageUptodate(page))) {
- ntfs_error(vol->sb, "Failed to read last partial page "
- "(async error, index 0x%lx).", idx);
- page_cache_release(page);
+ "(error, index 0x%lx).", idx);
return PTR_ERR(page);
}
kaddr = kmap_atomic(page, KM_USER0);
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
index 74f99a6..34314b3 100644
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -20,7 +20,6 @@
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include "dir.h"
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index d69c459..621de36 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -236,8 +236,7 @@ do_non_resident_extend:
err = PTR_ERR(page);
goto init_err_out;
}
- wait_on_page_locked(page);
- if (unlikely(!PageUptodate(page) || PageError(page))) {
+ if (unlikely(PageError(page))) {
page_cache_release(page);
err = -EIO;
goto init_err_out;
@@ -2130,28 +2129,13 @@ static ssize_t ntfs_file_aio_write_nolock(struct kiocb *iocb,
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
loff_t pos;
- unsigned long seg;
size_t count; /* after file limit checks */
ssize_t written, err;
count = 0;
- for (seg = 0; seg < nr_segs; seg++) {
- const struct iovec *iv = &iov[seg];
- /*
- * If any segment has a negative length, or the cumulative
- * length ever wraps negative then return -EINVAL.
- */
- count += iv->iov_len;
- if (unlikely((ssize_t)(count|iv->iov_len) < 0))
- return -EINVAL;
- if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len))
- continue;
- if (!seg)
- return -EFAULT;
- nr_segs = seg;
- count -= iv->iov_len; /* This segment is no good */
- break;
- }
+ err = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ);
+ if (err)
+ return err;
pos = *ppos;
vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
/* We can write back this queue in page reclaim. */
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index f8bf8da..074791c 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -27,7 +27,6 @@
#include <linux/pagemap.h>
#include <linux/quotaops.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include "aops.h"
#include "attrib.h"
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 1594c90..21d834e 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -2471,7 +2471,6 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
s64 nr_free = vol->nr_clusters;
u32 *kaddr;
struct address_space *mapping = vol->lcnbmp_ino->i_mapping;
- filler_t *readpage = (filler_t*)mapping->a_ops->readpage;
struct page *page;
pgoff_t index, max_index;
@@ -2494,24 +2493,14 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
* Read the page from page cache, getting it from backing store
* if necessary, and increment the use count.
*/
- page = read_cache_page(mapping, index, (filler_t*)readpage,
- NULL);
+ page = read_mapping_page(mapping, index, NULL);
/* Ignore pages which errored synchronously. */
if (IS_ERR(page)) {
- ntfs_debug("Sync read_cache_page() error. Skipping "
+ ntfs_debug("read_mapping_page() error. Skipping "
"page (index 0x%lx).", index);
nr_free -= PAGE_CACHE_SIZE * 8;
continue;
}
- wait_on_page_locked(page);
- /* Ignore pages which errored asynchronously. */
- if (!PageUptodate(page)) {
- ntfs_debug("Async read_cache_page() error. Skipping "
- "page (index 0x%lx).", index);
- page_cache_release(page);
- nr_free -= PAGE_CACHE_SIZE * 8;
- continue;
- }
kaddr = (u32*)kmap_atomic(page, KM_USER0);
/*
* For each 4 bytes, subtract the number of set bits. If this
@@ -2562,7 +2551,6 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
{
u32 *kaddr;
struct address_space *mapping = vol->mftbmp_ino->i_mapping;
- filler_t *readpage = (filler_t*)mapping->a_ops->readpage;
struct page *page;
pgoff_t index;
@@ -2576,21 +2564,11 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
* Read the page from page cache, getting it from backing store
* if necessary, and increment the use count.
*/
- page = read_cache_page(mapping, index, (filler_t*)readpage,
- NULL);
+ page = read_mapping_page(mapping, index, NULL);
/* Ignore pages which errored synchronously. */
if (IS_ERR(page)) {
- ntfs_debug("Sync read_cache_page() error. Skipping "
- "page (index 0x%lx).", index);
- nr_free -= PAGE_CACHE_SIZE * 8;
- continue;
- }
- wait_on_page_locked(page);
- /* Ignore pages which errored asynchronously. */
- if (!PageUptodate(page)) {
- ntfs_debug("Async read_cache_page() error. Skipping "
+ ntfs_debug("read_mapping_page() error. Skipping "
"page (index 0x%lx).", index);
- page_cache_release(page);
nr_free -= PAGE_CACHE_SIZE * 8;
continue;
}
@@ -3107,8 +3085,7 @@ static void ntfs_big_inode_init_once(void *foo, struct kmem_cache *cachep,
{
ntfs_inode *ni = (ntfs_inode *)foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(VFS_I(ni));
}
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c
index de952eb..5671cf9 100644
--- a/fs/ocfs2/dlm/dlmfs.c
+++ b/fs/ocfs2/dlm/dlmfs.c
@@ -42,7 +42,6 @@
#include <linux/highmem.h>
#include <linux/init.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/backing-dev.h>
#include <asm/uaccess.h>
@@ -263,8 +262,7 @@ static void dlmfs_init_once(void *foo,
struct dlmfs_inode_private *ip =
(struct dlmfs_inode_private *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
ip->ip_dlm = NULL;
ip->ip_parent = NULL;
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 024777a..d1bd305 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -27,7 +27,6 @@
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/crc32.h>
#include <linux/kthread.h>
#include <linux/pagemap.h>
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index bc844bf..c53a676 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -28,7 +28,6 @@
#include <linux/slab.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <asm/byteorder.h>
diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c
index d921a28..d8b7906 100644
--- a/fs/ocfs2/slot_map.c
+++ b/fs/ocfs2/slot_map.c
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/highmem.h>
-#include <linux/smp_lock.h>
#define MLOG_MASK_PREFIX ML_SUPER
#include <cluster/masklog.h>
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index f549354..7c5e3f5 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -937,8 +937,7 @@ static void ocfs2_inode_init_once(void *data,
{
struct ocfs2_inode_info *oi = data;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
oi->ip_flags = 0;
oi->ip_open_count = 0;
spin_lock_init(&oi->ip_lock);
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
index 40dc1a5..7134007 100644
--- a/fs/ocfs2/symlink.c
+++ b/fs/ocfs2/symlink.c
@@ -67,16 +67,9 @@ static char *ocfs2_page_getlink(struct dentry * dentry,
page = read_mapping_page(mapping, 0, NULL);
if (IS_ERR(page))
goto sync_fail;
- wait_on_page_locked(page);
- if (!PageUptodate(page))
- goto async_fail;
*ppage = page;
return kmap(page);
-async_fail:
- page_cache_release(page);
- return ERR_PTR(-EIO);
-
sync_fail:
return (char*)page;
}
diff --git a/fs/ocfs2/vote.c b/fs/ocfs2/vote.c
index 4f82a2f..66a13ee 100644
--- a/fs/ocfs2/vote.c
+++ b/fs/ocfs2/vote.c
@@ -26,7 +26,6 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/highmem.h>
-#include <linux/smp_lock.h>
#include <linux/kthread.h>
#include <cluster/heartbeat.h>
diff --git a/fs/open.c b/fs/open.c
index c989fb4..0d515d1 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -7,7 +7,6 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/file.h>
-#include <linux/smp_lock.h>
#include <linux/quotaops.h>
#include <linux/fsnotify.h>
#include <linux/module.h>
@@ -211,6 +210,9 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
newattrs.ia_valid |= ATTR_FILE;
}
+ /* Remove suid/sgid on truncate too */
+ newattrs.ia_valid |= should_remove_suid(dentry);
+
mutex_lock(&dentry->d_inode->i_mutex);
err = notify_change(dentry, &newattrs);
mutex_unlock(&dentry->d_inode->i_mutex);
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index bde1c16..731a90e 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -419,8 +419,7 @@ static void op_inode_init_once(void *data, struct kmem_cache * cachep, unsigned
{
struct op_inode_info *oi = (struct op_inode_info *) data;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&oi->vfs_inode);
}
diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig
index 6e8bb66..0120704 100644
--- a/fs/partitions/Kconfig
+++ b/fs/partitions/Kconfig
@@ -236,3 +236,12 @@ config EFI_PARTITION
help
Say Y here if you would like to use hard disks under Linux which
were partitioned using EFI GPT.
+
+config SYSV68_PARTITION
+ bool "SYSV68 partition table support" if PARTITION_ADVANCED
+ default y if M68K
+ help
+ Say Y here if you would like to be able to read the hard disk
+ partition table format used by Motorola Delta machines (using
+ sysv68).
+ Otherwise, say N.
diff --git a/fs/partitions/Makefile b/fs/partitions/Makefile
index 67e665f..03af8ea 100644
--- a/fs/partitions/Makefile
+++ b/fs/partitions/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o
obj-$(CONFIG_IBM_PARTITION) += ibm.o
obj-$(CONFIG_EFI_PARTITION) += efi.o
obj-$(CONFIG_KARMA_PARTITION) += karma.o
+obj-$(CONFIG_SYSV68_PARTITION) += sysv68.o
diff --git a/fs/partitions/acorn.c b/fs/partitions/acorn.c
index 1bc9f37..e349132 100644
--- a/fs/partitions/acorn.c
+++ b/fs/partitions/acorn.c
@@ -271,7 +271,7 @@ adfspart_check_ADFS(struct parsed_partitions *state, struct block_device *bdev)
extern void xd_set_geometry(struct block_device *,
unsigned char, unsigned char, unsigned int);
xd_set_geometry(bdev, dr->secspertrack, heads, 1);
- invalidate_bdev(bdev, 1);
+ invalidate_bh_lrus();
truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
}
#endif
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index f01572f..9a3a058 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -34,6 +34,7 @@
#include "ultrix.h"
#include "efi.h"
#include "karma.h"
+#include "sysv68.h"
#ifdef CONFIG_BLK_DEV_MD
extern void md_autodetect_dev(dev_t dev);
@@ -105,6 +106,9 @@ static int (*check_part[])(struct parsed_partitions *, struct block_device *) =
#ifdef CONFIG_KARMA_PARTITION
karma_partition,
#endif
+#ifdef CONFIG_SYSV68_PARTITION
+ sysv68_partition,
+#endif
NULL
};
@@ -569,9 +573,6 @@ unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p)
page = read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)),
NULL);
if (!IS_ERR(page)) {
- wait_on_page_locked(page);
- if (!PageUptodate(page))
- goto fail;
if (PageError(page))
goto fail;
p->v = page;
diff --git a/fs/partitions/sysv68.c b/fs/partitions/sysv68.c
new file mode 100644
index 0000000..4eba27b
--- /dev/null
+++ b/fs/partitions/sysv68.c
@@ -0,0 +1,92 @@
+/*
+ * fs/partitions/sysv68.c
+ *
+ * Copyright (C) 2007 Philippe De Muyter <phdm@macqel.be>
+ */
+
+#include "check.h"
+#include "sysv68.h"
+
+/*
+ * Volume ID structure: on first 256-bytes sector of disk
+ */
+
+struct volumeid {
+ u8 vid_unused[248];
+ u8 vid_mac[8]; /* ASCII string "MOTOROLA" */
+};
+
+/*
+ * config block: second 256-bytes sector on disk
+ */
+
+struct dkconfig {
+ u8 ios_unused0[128];
+ __be32 ios_slcblk; /* Slice table block number */
+ __be16 ios_slccnt; /* Number of entries in slice table */
+ u8 ios_unused1[122];
+};
+
+/*
+ * combined volumeid and dkconfig block
+ */
+
+struct dkblk0 {
+ struct volumeid dk_vid;
+ struct dkconfig dk_ios;
+};
+
+/*
+ * Slice Table Structure
+ */
+
+struct slice {
+ __be32 nblocks; /* slice size (in blocks) */
+ __be32 blkoff; /* block offset of slice */
+};
+
+
+int sysv68_partition(struct parsed_partitions *state, struct block_device *bdev)
+{
+ int i, slices;
+ int slot = 1;
+ Sector sect;
+ unsigned char *data;
+ struct dkblk0 *b;
+ struct slice *slice;
+
+ data = read_dev_sector(bdev, 0, &sect);
+ if (!data)
+ return -1;
+
+ b = (struct dkblk0 *)data;
+ if (memcmp(b->dk_vid.vid_mac, "MOTOROLA", sizeof(b->dk_vid.vid_mac))) {
+ put_dev_sector(sect);
+ return 0;
+ }
+ slices = be16_to_cpu(b->dk_ios.ios_slccnt);
+ i = be32_to_cpu(b->dk_ios.ios_slcblk);
+ put_dev_sector(sect);
+
+ data = read_dev_sector(bdev, i, &sect);
+ if (!data)
+ return -1;
+
+ slices -= 1; /* last slice is the whole disk */
+ printk("sysV68: %s(s%u)", state->name, slices);
+ slice = (struct slice *)data;
+ for (i = 0; i < slices; i++, slice++) {
+ if (slot == state->limit)
+ break;
+ if (be32_to_cpu(slice->nblocks)) {
+ put_partition(state, slot,
+ be32_to_cpu(slice->blkoff),
+ be32_to_cpu(slice->nblocks));
+ printk("(s%u)", i);
+ }
+ slot++;
+ }
+ printk("\n");
+ put_dev_sector(sect);
+ return 1;
+}
diff --git a/fs/partitions/sysv68.h b/fs/partitions/sysv68.h
new file mode 100644
index 0000000..fa733f6
--- /dev/null
+++ b/fs/partitions/sysv68.h
@@ -0,0 +1 @@
+extern int sysv68_partition(struct parsed_partitions *state, struct block_device *bdev);
diff --git a/fs/pipe.c b/fs/pipe.c
index ebafde7..3a89592 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -841,8 +841,18 @@ static int pipefs_delete_dentry(struct dentry *dentry)
return 0;
}
+/*
+ * pipefs_dname() is called from d_path().
+ */
+static char *pipefs_dname(struct dentry *dentry, char *buffer, int buflen)
+{
+ return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]",
+ dentry->d_inode->i_ino);
+}
+
static struct dentry_operations pipefs_dentry_operations = {
.d_delete = pipefs_delete_dentry,
+ .d_dname = pipefs_dname,
};
static struct inode * get_pipe_inode(void)
@@ -888,8 +898,7 @@ struct file *create_write_pipe(void)
struct inode *inode;
struct file *f;
struct dentry *dentry;
- char name[32];
- struct qstr this;
+ struct qstr name = { .name = "" };
f = get_empty_filp();
if (!f)
@@ -899,11 +908,8 @@ struct file *create_write_pipe(void)
if (!inode)
goto err_file;
- this.len = sprintf(name, "[%lu]", inode->i_ino);
- this.name = name;
- this.hash = 0;
err = -ENOMEM;
- dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this);
+ dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name);
if (!dentry)
goto err_inode;
diff --git a/fs/pnode.c b/fs/pnode.c
index 56aacea..89940f2 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -59,7 +59,7 @@ static int do_make_slave(struct vfsmount *mnt)
} else {
struct list_head *p = &mnt->mnt_slave_list;
while (!list_empty(p)) {
- slave_mnt = list_entry(p->next,
+ slave_mnt = list_first_entry(p,
struct vfsmount, mnt_slave);
list_del_init(&slave_mnt->mnt_slave);
slave_mnt->mnt_master = NULL;
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 07c9cdb..74f30e0 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -410,9 +410,9 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
/* convert nsec -> ticks */
start_time = nsec_to_clock_t(start_time);
- res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
+ res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %u %lu \
%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
-%lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu %llu\n",
+%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu\n",
task->pid,
tcomm,
state,
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 989af5e..3c41149 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -61,9 +61,9 @@
#include <linux/namei.h>
#include <linux/mnt_namespace.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/rcupdate.h>
#include <linux/kallsyms.h>
+#include <linux/module.h>
#include <linux/mount.h>
#include <linux/security.h>
#include <linux/ptrace.h>
@@ -90,8 +90,8 @@
#define PROC_NUMBUF 13
struct pid_entry {
- int len;
char *name;
+ int len;
mode_t mode;
const struct inode_operations *iop;
const struct file_operations *fop;
@@ -99,8 +99,8 @@ struct pid_entry {
};
#define NOD(NAME, MODE, IOP, FOP, OP) { \
- .len = sizeof(NAME) - 1, \
.name = (NAME), \
+ .len = sizeof(NAME) - 1, \
.mode = MODE, \
.iop = IOP, \
.fop = FOP, \
@@ -123,6 +123,9 @@ struct pid_entry {
NULL, &proc_info_file_operations, \
{ .proc_read = &proc_##OTYPE } )
+int maps_protect;
+EXPORT_SYMBOL(maps_protect);
+
static struct fs_struct *get_fs_struct(struct task_struct *task)
{
struct fs_struct *fs;
@@ -275,17 +278,15 @@ static int proc_pid_auxv(struct task_struct *task, char *buffer)
*/
static int proc_pid_wchan(struct task_struct *task, char *buffer)
{
- char *modname;
- const char *sym_name;
- unsigned long wchan, size, offset;
- char namebuf[KSYM_NAME_LEN+1];
+ unsigned long wchan;
+ char symname[KSYM_NAME_LEN+1];
wchan = get_wchan(task);
- sym_name = kallsyms_lookup(wchan, &size, &offset, &modname, namebuf);
- if (sym_name)
- return sprintf(buffer, "%s", sym_name);
- return sprintf(buffer, "%lu", wchan);
+ if (lookup_symbol_name(wchan, symname) < 0)
+ return sprintf(buffer, "%lu", wchan);
+ else
+ return sprintf(buffer, "%s", symname);
}
#endif /* CONFIG_KALLSYMS */
@@ -310,7 +311,9 @@ static int proc_oom_score(struct task_struct *task, char *buffer)
struct timespec uptime;
do_posix_clock_monotonic_gettime(&uptime);
+ read_lock(&tasklist_lock);
points = badness(task, uptime.tv_sec);
+ read_unlock(&tasklist_lock);
return sprintf(buffer, "%lu\n", points);
}
@@ -344,11 +347,8 @@ static int proc_setattr(struct dentry *dentry, struct iattr *attr)
return -EPERM;
error = inode_change_ok(inode, attr);
- if (!error) {
- error = security_inode_setattr(dentry, attr);
- if (!error)
- error = inode_setattr(inode, attr);
- }
+ if (!error)
+ error = inode_setattr(inode, attr);
return error;
}
@@ -660,7 +660,6 @@ static ssize_t oom_adjust_read(struct file *file, char __user *buf,
char buffer[PROC_NUMBUF];
size_t len;
int oom_adjust;
- loff_t __ppos = *ppos;
if (!task)
return -ESRCH;
@@ -668,14 +667,8 @@ static ssize_t oom_adjust_read(struct file *file, char __user *buf,
put_task_struct(task);
len = snprintf(buffer, sizeof(buffer), "%i\n", oom_adjust);
- if (__ppos >= len)
- return 0;
- if (count > len-__ppos)
- count = len-__ppos;
- if (copy_to_user(buf, buffer + __ppos, count))
- return -EFAULT;
- *ppos = __ppos + count;
- return count;
+
+ return simple_read_from_buffer(buf, count, ppos, buffer, len);
}
static ssize_t oom_adjust_write(struct file *file, const char __user *buf,
@@ -715,6 +708,40 @@ static const struct file_operations proc_oom_adjust_operations = {
.write = oom_adjust_write,
};
+static ssize_t clear_refs_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct task_struct *task;
+ char buffer[PROC_NUMBUF], *end;
+ struct mm_struct *mm;
+
+ memset(buffer, 0, sizeof(buffer));
+ if (count > sizeof(buffer) - 1)
+ count = sizeof(buffer) - 1;
+ if (copy_from_user(buffer, buf, count))
+ return -EFAULT;
+ if (!simple_strtol(buffer, &end, 0))
+ return -EINVAL;
+ if (*end == '\n')
+ end++;
+ task = get_proc_task(file->f_path.dentry->d_inode);
+ if (!task)
+ return -ESRCH;
+ mm = get_task_mm(task);
+ if (mm) {
+ clear_refs_smap(mm);
+ mmput(mm);
+ }
+ put_task_struct(task);
+ if (end - buffer == 0)
+ return -EIO;
+ return end - buffer;
+}
+
+static struct file_operations proc_clear_refs_operations = {
+ .write = clear_refs_write,
+};
+
#ifdef CONFIG_AUDITSYSCALL
#define TMPBUFLEN 21
static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
@@ -789,7 +816,6 @@ static ssize_t seccomp_read(struct file *file, char __user *buf,
{
struct task_struct *tsk = get_proc_task(file->f_dentry->d_inode);
char __buf[20];
- loff_t __ppos = *ppos;
size_t len;
if (!tsk)
@@ -797,14 +823,8 @@ static ssize_t seccomp_read(struct file *file, char __user *buf,
/* no need to print the trailing zero, so use only len */
len = sprintf(__buf, "%u\n", tsk->seccomp.mode);
put_task_struct(tsk);
- if (__ppos >= len)
- return 0;
- if (count > len - __ppos)
- count = len - __ppos;
- if (copy_to_user(buf, __buf + __ppos, count))
- return -EFAULT;
- *ppos = __ppos + count;
- return count;
+
+ return simple_read_from_buffer(buf, count, ppos, __buf, len);
}
static ssize_t seccomp_write(struct file *file, const char __user *buf,
@@ -863,7 +883,6 @@ static ssize_t proc_fault_inject_read(struct file * file, char __user * buf,
char buffer[PROC_NUMBUF];
size_t len;
int make_it_fail;
- loff_t __ppos = *ppos;
if (!task)
return -ESRCH;
@@ -871,14 +890,8 @@ static ssize_t proc_fault_inject_read(struct file * file, char __user * buf,
put_task_struct(task);
len = snprintf(buffer, sizeof(buffer), "%i\n", make_it_fail);
- if (__ppos >= len)
- return 0;
- if (count > len-__ppos)
- count = len-__ppos;
- if (copy_to_user(buf, buffer + __ppos, count))
- return -EFAULT;
- *ppos = __ppos + count;
- return count;
+
+ return simple_read_from_buffer(buf, count, ppos, buffer, len);
}
static ssize_t proc_fault_inject_write(struct file * file,
@@ -941,7 +954,7 @@ static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt,
if (!tmp)
return -ENOMEM;
-
+
inode = dentry->d_inode;
path = d_path(dentry, mnt, tmp, PAGE_SIZE);
len = PTR_ERR(path);
@@ -1121,7 +1134,8 @@ static struct dentry_operations pid_dentry_operations =
/* Lookups */
-typedef struct dentry *instantiate_t(struct inode *, struct dentry *, struct task_struct *, void *);
+typedef struct dentry *instantiate_t(struct inode *, struct dentry *,
+ struct task_struct *, const void *);
/*
* Fill a directory entry.
@@ -1137,7 +1151,7 @@ typedef struct dentry *instantiate_t(struct inode *, struct dentry *, struct tas
*/
static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
char *name, int len,
- instantiate_t instantiate, struct task_struct *task, void *ptr)
+ instantiate_t instantiate, struct task_struct *task, const void *ptr)
{
struct dentry *child, *dir = filp->f_path.dentry;
struct inode *inode;
@@ -1199,7 +1213,10 @@ out:
return ~0U;
}
-static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
+#define PROC_FDINFO_MAX 64
+
+static int proc_fd_info(struct inode *inode, struct dentry **dentry,
+ struct vfsmount **mnt, char *info)
{
struct task_struct *task = get_proc_task(inode);
struct files_struct *files = NULL;
@@ -1218,8 +1235,16 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
spin_lock(&files->file_lock);
file = fcheck_files(files, fd);
if (file) {
- *mnt = mntget(file->f_path.mnt);
- *dentry = dget(file->f_path.dentry);
+ if (mnt)
+ *mnt = mntget(file->f_path.mnt);
+ if (dentry)
+ *dentry = dget(file->f_path.dentry);
+ if (info)
+ snprintf(info, PROC_FDINFO_MAX,
+ "pos:\t%lli\n"
+ "flags:\t0%o\n",
+ (long long) file->f_pos,
+ file->f_flags);
spin_unlock(&files->file_lock);
put_files_struct(files);
return 0;
@@ -1230,6 +1255,12 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
return -ENOENT;
}
+static int proc_fd_link(struct inode *inode, struct dentry **dentry,
+ struct vfsmount **mnt)
+{
+ return proc_fd_info(inode, dentry, mnt, NULL);
+}
+
static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd)
{
struct inode *inode = dentry->d_inode;
@@ -1272,9 +1303,9 @@ static struct dentry_operations tid_fd_dentry_operations =
};
static struct dentry *proc_fd_instantiate(struct inode *dir,
- struct dentry *dentry, struct task_struct *task, void *ptr)
+ struct dentry *dentry, struct task_struct *task, const void *ptr)
{
- unsigned fd = *(unsigned *)ptr;
+ unsigned fd = *(const unsigned *)ptr;
struct file *file;
struct files_struct *files;
struct inode *inode;
@@ -1325,7 +1356,9 @@ out_iput:
goto out;
}
-static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
+static struct dentry *proc_lookupfd_common(struct inode *dir,
+ struct dentry *dentry,
+ instantiate_t instantiate)
{
struct task_struct *task = get_proc_task(dir);
unsigned fd = name_to_int(dentry);
@@ -1336,23 +1369,15 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
if (fd == ~0U)
goto out;
- result = proc_fd_instantiate(dir, dentry, task, &fd);
+ result = instantiate(dir, dentry, task, &fd);
out:
put_task_struct(task);
out_no_task:
return result;
}
-static int proc_fd_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
- struct task_struct *task, int fd)
-{
- char name[PROC_NUMBUF];
- int len = snprintf(name, sizeof(name), "%d", fd);
- return proc_fill_cache(filp, dirent, filldir, name, len,
- proc_fd_instantiate, task, &fd);
-}
-
-static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
+static int proc_readfd_common(struct file * filp, void * dirent,
+ filldir_t filldir, instantiate_t instantiate)
{
struct dentry *dentry = filp->f_path.dentry;
struct inode *inode = dentry->d_inode;
@@ -1388,12 +1413,17 @@ static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
for (fd = filp->f_pos-2;
fd < fdt->max_fds;
fd++, filp->f_pos++) {
+ char name[PROC_NUMBUF];
+ int len;
if (!fcheck_files(files, fd))
continue;
rcu_read_unlock();
- if (proc_fd_fill_cache(filp, dirent, filldir, p, fd) < 0) {
+ len = snprintf(name, sizeof(name), "%d", fd);
+ if (proc_fill_cache(filp, dirent, filldir,
+ name, len, instantiate,
+ p, &fd) < 0) {
rcu_read_lock();
break;
}
@@ -1408,23 +1438,119 @@ out_no_task:
return retval;
}
+static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
+ struct nameidata *nd)
+{
+ return proc_lookupfd_common(dir, dentry, proc_fd_instantiate);
+}
+
+static int proc_readfd(struct file *filp, void *dirent, filldir_t filldir)
+{
+ return proc_readfd_common(filp, dirent, filldir, proc_fd_instantiate);
+}
+
+static ssize_t proc_fdinfo_read(struct file *file, char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ char tmp[PROC_FDINFO_MAX];
+ int err = proc_fd_info(file->f_path.dentry->d_inode, NULL, NULL, tmp);
+ if (!err)
+ err = simple_read_from_buffer(buf, len, ppos, tmp, strlen(tmp));
+ return err;
+}
+
+static const struct file_operations proc_fdinfo_file_operations = {
+ .open = nonseekable_open,
+ .read = proc_fdinfo_read,
+};
+
static const struct file_operations proc_fd_operations = {
.read = generic_read_dir,
.readdir = proc_readfd,
};
/*
+ * /proc/pid/fd needs a special permission handler so that a process can still
+ * access /proc/self/fd after it has executed a setuid().
+ */
+static int proc_fd_permission(struct inode *inode, int mask,
+ struct nameidata *nd)
+{
+ int rv;
+
+ rv = generic_permission(inode, mask, NULL);
+ if (rv == 0)
+ return 0;
+ if (task_pid(current) == proc_pid(inode))
+ rv = 0;
+ return rv;
+}
+
+/*
* proc directories can do almost nothing..
*/
static const struct inode_operations proc_fd_inode_operations = {
.lookup = proc_lookupfd,
+ .permission = proc_fd_permission,
.setattr = proc_setattr,
};
+static struct dentry *proc_fdinfo_instantiate(struct inode *dir,
+ struct dentry *dentry, struct task_struct *task, const void *ptr)
+{
+ unsigned fd = *(unsigned *)ptr;
+ struct inode *inode;
+ struct proc_inode *ei;
+ struct dentry *error = ERR_PTR(-ENOENT);
+
+ inode = proc_pid_make_inode(dir->i_sb, task);
+ if (!inode)
+ goto out;
+ ei = PROC_I(inode);
+ ei->fd = fd;
+ inode->i_mode = S_IFREG | S_IRUSR;
+ inode->i_fop = &proc_fdinfo_file_operations;
+ dentry->d_op = &tid_fd_dentry_operations;
+ d_add(dentry, inode);
+ /* Close the race of the process dying before we return the dentry */
+ if (tid_fd_revalidate(dentry, NULL))
+ error = NULL;
+
+ out:
+ return error;
+}
+
+static struct dentry *proc_lookupfdinfo(struct inode *dir,
+ struct dentry *dentry,
+ struct nameidata *nd)
+{
+ return proc_lookupfd_common(dir, dentry, proc_fdinfo_instantiate);
+}
+
+static int proc_readfdinfo(struct file *filp, void *dirent, filldir_t filldir)
+{
+ return proc_readfd_common(filp, dirent, filldir,
+ proc_fdinfo_instantiate);
+}
+
+static const struct file_operations proc_fdinfo_operations = {
+ .read = generic_read_dir,
+ .readdir = proc_readfdinfo,
+};
+
+/*
+ * proc directories can do almost nothing..
+ */
+static const struct inode_operations proc_fdinfo_inode_operations = {
+ .lookup = proc_lookupfdinfo,
+ .setattr = proc_setattr,
+};
+
+
static struct dentry *proc_pident_instantiate(struct inode *dir,
- struct dentry *dentry, struct task_struct *task, void *ptr)
+ struct dentry *dentry, struct task_struct *task, const void *ptr)
{
- struct pid_entry *p = ptr;
+ const struct pid_entry *p = ptr;
struct inode *inode;
struct proc_inode *ei;
struct dentry *error = ERR_PTR(-EINVAL);
@@ -1453,13 +1579,13 @@ out:
static struct dentry *proc_pident_lookup(struct inode *dir,
struct dentry *dentry,
- struct pid_entry *ents,
+ const struct pid_entry *ents,
unsigned int nents)
{
struct inode *inode;
struct dentry *error;
struct task_struct *task = get_proc_task(dir);
- struct pid_entry *p, *last;
+ const struct pid_entry *p, *last;
error = ERR_PTR(-ENOENT);
inode = NULL;
@@ -1488,8 +1614,8 @@ out_no_task:
return error;
}
-static int proc_pident_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
- struct task_struct *task, struct pid_entry *p)
+static int proc_pident_fill_cache(struct file *filp, void *dirent,
+ filldir_t filldir, struct task_struct *task, const struct pid_entry *p)
{
return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
proc_pident_instantiate, task, p);
@@ -1497,14 +1623,14 @@ static int proc_pident_fill_cache(struct file *filp, void *dirent, filldir_t fil
static int proc_pident_readdir(struct file *filp,
void *dirent, filldir_t filldir,
- struct pid_entry *ents, unsigned int nents)
+ const struct pid_entry *ents, unsigned int nents)
{
int i;
int pid;
struct dentry *dentry = filp->f_path.dentry;
struct inode *inode = dentry->d_inode;
struct task_struct *task = get_proc_task(inode);
- struct pid_entry *p, *last;
+ const struct pid_entry *p, *last;
ino_t ino;
int ret;
@@ -1619,7 +1745,7 @@ static const struct file_operations proc_pid_attr_operations = {
.write = proc_pid_attr_write,
};
-static struct pid_entry attr_dir_stuff[] = {
+static const struct pid_entry attr_dir_stuff[] = {
REG("current", S_IRUGO|S_IWUGO, pid_attr),
REG("prev", S_IRUGO, pid_attr),
REG("exec", S_IRUGO|S_IWUGO, pid_attr),
@@ -1685,7 +1811,7 @@ static const struct inode_operations proc_self_inode_operations = {
* that properly belong to the /proc filesystem, as they describe
* describe something that is process related.
*/
-static struct pid_entry proc_base_stuff[] = {
+static const struct pid_entry proc_base_stuff[] = {
NOD("self", S_IFLNK|S_IRWXUGO,
&proc_self_inode_operations, NULL, {}),
};
@@ -1714,9 +1840,9 @@ static struct dentry_operations proc_base_dentry_operations =
};
static struct dentry *proc_base_instantiate(struct inode *dir,
- struct dentry *dentry, struct task_struct *task, void *ptr)
+ struct dentry *dentry, struct task_struct *task, const void *ptr)
{
- struct pid_entry *p = ptr;
+ const struct pid_entry *p = ptr;
struct inode *inode;
struct proc_inode *ei;
struct dentry *error = ERR_PTR(-EINVAL);
@@ -1764,7 +1890,7 @@ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
{
struct dentry *error;
struct task_struct *task = get_proc_task(dir);
- struct pid_entry *p, *last;
+ const struct pid_entry *p, *last;
error = ERR_PTR(-ENOENT);
@@ -1790,8 +1916,8 @@ out_no_task:
return error;
}
-static int proc_base_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
- struct task_struct *task, struct pid_entry *p)
+static int proc_base_fill_cache(struct file *filp, void *dirent,
+ filldir_t filldir, struct task_struct *task, const struct pid_entry *p)
{
return proc_fill_cache(filp, dirent, filldir, p->name, p->len,
proc_base_instantiate, task, p);
@@ -1828,9 +1954,10 @@ static int proc_pid_io_accounting(struct task_struct *task, char *buffer)
static const struct file_operations proc_task_operations;
static const struct inode_operations proc_task_inode_operations;
-static struct pid_entry tgid_base_stuff[] = {
+static const struct pid_entry tgid_base_stuff[] = {
DIR("task", S_IRUGO|S_IXUGO, task),
DIR("fd", S_IRUSR|S_IXUSR, fd),
+ DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo),
INF("environ", S_IRUSR, pid_environ),
INF("auxv", S_IRUSR, pid_auxv),
INF("status", S_IRUGO, pid_status),
@@ -1851,6 +1978,7 @@ static struct pid_entry tgid_base_stuff[] = {
REG("mounts", S_IRUGO, mounts),
REG("mountstats", S_IRUSR, mountstats),
#ifdef CONFIG_MMU
+ REG("clear_refs", S_IWUSR, clear_refs),
REG("smaps", S_IRUGO, smaps),
#endif
#ifdef CONFIG_SECURITY
@@ -1970,7 +2098,7 @@ out:
static struct dentry *proc_pid_instantiate(struct inode *dir,
struct dentry * dentry,
- struct task_struct *task, void *ptr)
+ struct task_struct *task, const void *ptr)
{
struct dentry *error = ERR_PTR(-ENOENT);
struct inode *inode;
@@ -1983,7 +2111,7 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
inode->i_op = &proc_tgid_base_inode_operations;
inode->i_fop = &proc_tgid_base_operations;
inode->i_flags|=S_IMMUTABLE;
- inode->i_nlink = 4;
+ inode->i_nlink = 5;
#ifdef CONFIG_SECURITY
inode->i_nlink += 1;
#endif
@@ -2085,7 +2213,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
goto out_no_task;
for (; nr < ARRAY_SIZE(proc_base_stuff); filp->f_pos++, nr++) {
- struct pid_entry *p = &proc_base_stuff[nr];
+ const struct pid_entry *p = &proc_base_stuff[nr];
if (proc_base_fill_cache(filp, dirent, filldir, reaper, p) < 0)
goto out;
}
@@ -2111,8 +2239,9 @@ out_no_task:
/*
* Tasks
*/
-static struct pid_entry tid_base_stuff[] = {
+static const struct pid_entry tid_base_stuff[] = {
DIR("fd", S_IRUSR|S_IXUSR, fd),
+ DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo),
INF("environ", S_IRUSR, pid_environ),
INF("auxv", S_IRUSR, pid_auxv),
INF("status", S_IRUGO, pid_status),
@@ -2132,6 +2261,7 @@ static struct pid_entry tid_base_stuff[] = {
LNK("exe", exe),
REG("mounts", S_IRUGO, mounts),
#ifdef CONFIG_MMU
+ REG("clear_refs", S_IWUSR, clear_refs),
REG("smaps", S_IRUGO, smaps),
#endif
#ifdef CONFIG_SECURITY
@@ -2180,7 +2310,7 @@ static const struct inode_operations proc_tid_base_inode_operations = {
};
static struct dentry *proc_task_instantiate(struct inode *dir,
- struct dentry *dentry, struct task_struct *task, void *ptr)
+ struct dentry *dentry, struct task_struct *task, const void *ptr)
{
struct dentry *error = ERR_PTR(-ENOENT);
struct inode *inode;
@@ -2192,7 +2322,7 @@ static struct dentry *proc_task_instantiate(struct inode *dir,
inode->i_op = &proc_tid_base_inode_operations;
inode->i_fop = &proc_tid_base_operations;
inode->i_flags|=S_IMMUTABLE;
- inode->i_nlink = 3;
+ inode->i_nlink = 4;
#ifdef CONFIG_SECURITY
inode->i_nlink += 1;
#endif
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 775fb21..8a40e15 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -398,6 +398,7 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nam
if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
unsigned int ino = de->low_ino;
+ de_get(de);
spin_unlock(&proc_subdir_lock);
error = -EINVAL;
inode = proc_get_inode(dir->i_sb, ino, de);
@@ -414,6 +415,7 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nam
d_add(dentry, inode);
return NULL;
}
+ de_put(de);
return ERR_PTR(error);
}
@@ -476,14 +478,21 @@ int proc_readdir(struct file * filp,
}
do {
+ struct proc_dir_entry *next;
+
/* filldir passes info to user space */
+ de_get(de);
spin_unlock(&proc_subdir_lock);
if (filldir(dirent, de->name, de->namelen, filp->f_pos,
- de->low_ino, de->mode >> 12) < 0)
+ de->low_ino, de->mode >> 12) < 0) {
+ de_put(de);
goto out;
+ }
spin_lock(&proc_subdir_lock);
filp->f_pos++;
- de = de->next;
+ next = de->next;
+ de_put(de);
+ de = next;
} while (de);
spin_unlock(&proc_subdir_lock);
}
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index c372eb15..b817190 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -21,7 +21,7 @@
#include "internal.h"
-static inline struct proc_dir_entry * de_get(struct proc_dir_entry *de)
+struct proc_dir_entry *de_get(struct proc_dir_entry *de)
{
if (de)
atomic_inc(&de->count);
@@ -31,7 +31,7 @@ static inline struct proc_dir_entry * de_get(struct proc_dir_entry *de)
/*
* Decrements the use count and checks for deferred deletion.
*/
-static void de_put(struct proc_dir_entry *de)
+void de_put(struct proc_dir_entry *de)
{
if (de) {
lock_kernel();
@@ -109,8 +109,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct proc_inode *ei = (struct proc_inode *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&ei->vfs_inode);
}
@@ -147,13 +146,6 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino,
{
struct inode * inode;
- /*
- * Increment the use count so the dir entry can't disappear.
- */
- de_get(de);
-
- WARN_ON(de && de->deleted);
-
if (de != NULL && !try_module_get(de->owner))
goto out_mod;
@@ -185,7 +177,6 @@ out_ino:
if (de != NULL)
module_put(de->owner);
out_mod:
- de_put(de);
return NULL;
}
@@ -200,6 +191,7 @@ int proc_fill_super(struct super_block *s, void *data, int silent)
s->s_op = &proc_sops;
s->s_time_gran = 1;
+ de_get(&proc_root);
root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root);
if (!root_inode)
goto out_no_root;
@@ -213,6 +205,7 @@ int proc_fill_super(struct super_block *s, void *data, int silent)
out_no_root:
printk("proc_read_super: get root inode failed\n");
iput(root_inode);
+ de_put(&proc_root);
return -ENOMEM;
}
MODULE_LICENSE("GPL");
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index f771889..b215c35 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -37,6 +37,8 @@ do { \
extern int nommu_vma_show(struct seq_file *, struct vm_area_struct *);
#endif
+extern int maps_protect;
+
extern void create_seq_entry(char *name, mode_t mode, const struct file_operations *f);
extern int proc_exe_link(struct inode *, struct dentry **, struct vfsmount **);
extern int proc_tid_stat(struct task_struct *, char *);
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index e2c4c0a5..5fd49e4 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -35,7 +35,6 @@
#include <linux/signal.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/seq_file.h>
#include <linux/times.h>
#include <linux/profile.h>
@@ -398,8 +397,6 @@ static const struct file_operations proc_modules_operations = {
#endif
#ifdef CONFIG_SLAB
-extern struct seq_operations slabinfo_op;
-extern ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *);
static int slabinfo_open(struct inode *inode, struct file *file)
{
return seq_open(file, &slabinfo_op);
@@ -431,18 +428,11 @@ static int slabstats_open(struct inode *inode, struct file *file)
return ret;
}
-static int slabstats_release(struct inode *inode, struct file *file)
-{
- struct seq_file *m = file->private_data;
- kfree(m->private);
- return seq_release(inode, file);
-}
-
static const struct file_operations proc_slabstats_operations = {
.open = slabstats_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = slabstats_release,
+ .release = seq_release_private,
};
#endif
#endif
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 20e8cbb..680c429 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -429,11 +429,8 @@ static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
return -EPERM;
error = inode_change_ok(inode, attr);
- if (!error) {
- error = security_inode_setattr(dentry, attr);
- if (!error)
- error = inode_setattr(inode, attr);
- }
+ if (!error)
+ error = inode_setattr(inode, attr);
return error;
}
diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c
index c1bbfbe..b3a473b 100644
--- a/fs/proc/proc_tty.c
+++ b/fs/proc/proc_tty.c
@@ -108,6 +108,8 @@ static void *t_start(struct seq_file *m, loff_t *pos)
{
struct list_head *p;
loff_t l = *pos;
+
+ mutex_lock(&tty_mutex);
list_for_each(p, &tty_drivers)
if (!l--)
return list_entry(p, struct tty_driver, tty_drivers);
@@ -124,6 +126,7 @@ static void *t_next(struct seq_file *m, void *v, loff_t *pos)
static void t_stop(struct seq_file *m, void *v)
{
+ mutex_unlock(&tty_mutex);
}
static struct seq_operations tty_drivers_op = {
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 7445980..c24d81a 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -3,6 +3,7 @@
#include <linux/mount.h>
#include <linux/seq_file.h>
#include <linux/highmem.h>
+#include <linux/ptrace.h>
#include <linux/pagemap.h>
#include <linux/mempolicy.h>
@@ -120,6 +121,14 @@ struct mem_size_stats
unsigned long shared_dirty;
unsigned long private_clean;
unsigned long private_dirty;
+ unsigned long referenced;
+};
+
+struct pmd_walker {
+ struct vm_area_struct *vma;
+ void *private;
+ void (*action)(struct vm_area_struct *, pmd_t *, unsigned long,
+ unsigned long, void *);
};
static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
@@ -134,6 +143,9 @@ static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats
dev_t dev = 0;
int len;
+ if (maps_protect && !ptrace_may_attach(task))
+ return -EACCES;
+
if (file) {
struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
dev = inode->i_sb->s_dev;
@@ -181,18 +193,20 @@ static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats
if (mss)
seq_printf(m,
- "Size: %8lu kB\n"
- "Rss: %8lu kB\n"
- "Shared_Clean: %8lu kB\n"
- "Shared_Dirty: %8lu kB\n"
- "Private_Clean: %8lu kB\n"
- "Private_Dirty: %8lu kB\n",
+ "Size: %8lu kB\n"
+ "Rss: %8lu kB\n"
+ "Shared_Clean: %8lu kB\n"
+ "Shared_Dirty: %8lu kB\n"
+ "Private_Clean: %8lu kB\n"
+ "Private_Dirty: %8lu kB\n"
+ "Referenced: %8lu kB\n",
(vma->vm_end - vma->vm_start) >> 10,
mss->resident >> 10,
mss->shared_clean >> 10,
mss->shared_dirty >> 10,
mss->private_clean >> 10,
- mss->private_dirty >> 10);
+ mss->private_dirty >> 10,
+ mss->referenced >> 10);
if (m->count < m->size) /* vma is copied successfully */
m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
@@ -205,15 +219,16 @@ static int show_map(struct seq_file *m, void *v)
}
static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
- unsigned long addr, unsigned long end,
- struct mem_size_stats *mss)
+ unsigned long addr, unsigned long end,
+ void *private)
{
+ struct mem_size_stats *mss = private;
pte_t *pte, ptent;
spinlock_t *ptl;
struct page *page;
pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
- do {
+ for (; addr != end; pte++, addr += PAGE_SIZE) {
ptent = *pte;
if (!pte_present(ptent))
continue;
@@ -224,6 +239,9 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
if (!page)
continue;
+ /* Accumulate the size in pages that have been accessed. */
+ if (pte_young(ptent) || PageReferenced(page))
+ mss->referenced += PAGE_SIZE;
if (page_mapcount(page) >= 2) {
if (pte_dirty(ptent))
mss->shared_dirty += PAGE_SIZE;
@@ -235,57 +253,99 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
else
mss->private_clean += PAGE_SIZE;
}
- } while (pte++, addr += PAGE_SIZE, addr != end);
+ }
pte_unmap_unlock(pte - 1, ptl);
cond_resched();
}
-static inline void smaps_pmd_range(struct vm_area_struct *vma, pud_t *pud,
- unsigned long addr, unsigned long end,
- struct mem_size_stats *mss)
+static void clear_refs_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
+ unsigned long addr, unsigned long end,
+ void *private)
+{
+ pte_t *pte, ptent;
+ spinlock_t *ptl;
+ struct page *page;
+
+ pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
+ for (; addr != end; pte++, addr += PAGE_SIZE) {
+ ptent = *pte;
+ if (!pte_present(ptent))
+ continue;
+
+ page = vm_normal_page(vma, addr, ptent);
+ if (!page)
+ continue;
+
+ /* Clear accessed and referenced bits. */
+ ptep_test_and_clear_young(vma, addr, pte);
+ ClearPageReferenced(page);
+ }
+ pte_unmap_unlock(pte - 1, ptl);
+ cond_resched();
+}
+
+static inline void walk_pmd_range(struct pmd_walker *walker, pud_t *pud,
+ unsigned long addr, unsigned long end)
{
pmd_t *pmd;
unsigned long next;
- pmd = pmd_offset(pud, addr);
- do {
+ for (pmd = pmd_offset(pud, addr); addr != end;
+ pmd++, addr = next) {
next = pmd_addr_end(addr, end);
if (pmd_none_or_clear_bad(pmd))
continue;
- smaps_pte_range(vma, pmd, addr, next, mss);
- } while (pmd++, addr = next, addr != end);
+ walker->action(walker->vma, pmd, addr, next, walker->private);
+ }
}
-static inline void smaps_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
- unsigned long addr, unsigned long end,
- struct mem_size_stats *mss)
+static inline void walk_pud_range(struct pmd_walker *walker, pgd_t *pgd,
+ unsigned long addr, unsigned long end)
{
pud_t *pud;
unsigned long next;
- pud = pud_offset(pgd, addr);
- do {
+ for (pud = pud_offset(pgd, addr); addr != end;
+ pud++, addr = next) {
next = pud_addr_end(addr, end);
if (pud_none_or_clear_bad(pud))
continue;
- smaps_pmd_range(vma, pud, addr, next, mss);
- } while (pud++, addr = next, addr != end);
+ walk_pmd_range(walker, pud, addr, next);
+ }
}
-static inline void smaps_pgd_range(struct vm_area_struct *vma,
- unsigned long addr, unsigned long end,
- struct mem_size_stats *mss)
+/*
+ * walk_page_range - walk the page tables of a VMA with a callback
+ * @vma - VMA to walk
+ * @action - callback invoked for every bottom-level (PTE) page table
+ * @private - private data passed to the callback function
+ *
+ * Recursively walk the page table for the memory area in a VMA, calling
+ * a callback for every bottom-level (PTE) page table.
+ */
+static inline void walk_page_range(struct vm_area_struct *vma,
+ void (*action)(struct vm_area_struct *,
+ pmd_t *, unsigned long,
+ unsigned long, void *),
+ void *private)
{
+ unsigned long addr = vma->vm_start;
+ unsigned long end = vma->vm_end;
+ struct pmd_walker walker = {
+ .vma = vma,
+ .private = private,
+ .action = action,
+ };
pgd_t *pgd;
unsigned long next;
- pgd = pgd_offset(vma->vm_mm, addr);
- do {
+ for (pgd = pgd_offset(vma->vm_mm, addr); addr != end;
+ pgd++, addr = next) {
next = pgd_addr_end(addr, end);
if (pgd_none_or_clear_bad(pgd))
continue;
- smaps_pud_range(vma, pgd, addr, next, mss);
- } while (pgd++, addr = next, addr != end);
+ walk_pud_range(&walker, pgd, addr, next);
+ }
}
static int show_smap(struct seq_file *m, void *v)
@@ -295,10 +355,22 @@ static int show_smap(struct seq_file *m, void *v)
memset(&mss, 0, sizeof mss);
if (vma->vm_mm && !is_vm_hugetlb_page(vma))
- smaps_pgd_range(vma, vma->vm_start, vma->vm_end, &mss);
+ walk_page_range(vma, smaps_pte_range, &mss);
return show_map_internal(m, v, &mss);
}
+void clear_refs_smap(struct mm_struct *mm)
+{
+ struct vm_area_struct *vma;
+
+ down_read(&mm->mmap_sem);
+ for (vma = mm->mmap; vma; vma = vma->vm_next)
+ if (vma->vm_mm && !is_vm_hugetlb_page(vma))
+ walk_page_range(vma, clear_refs_pte_range, NULL);
+ flush_tlb_mm(mm);
+ up_read(&mm->mmap_sem);
+}
+
static void *m_start(struct seq_file *m, loff_t *pos)
{
struct proc_maps_private *priv = m->private;
@@ -444,11 +516,22 @@ const struct file_operations proc_maps_operations = {
#ifdef CONFIG_NUMA
extern int show_numa_map(struct seq_file *m, void *v);
+static int show_numa_map_checked(struct seq_file *m, void *v)
+{
+ struct proc_maps_private *priv = m->private;
+ struct task_struct *task = priv->task;
+
+ if (maps_protect && !ptrace_may_attach(task))
+ return -EACCES;
+
+ return show_numa_map(m, v);
+}
+
static struct seq_operations proc_pid_numa_maps_op = {
.start = m_start,
.next = m_next,
.stop = m_stop,
- .show = show_numa_map
+ .show = show_numa_map_checked
};
static int numa_maps_open(struct inode *inode, struct file *file)
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
index 7cddf6b..d8b8c71 100644
--- a/fs/proc/task_nommu.c
+++ b/fs/proc/task_nommu.c
@@ -2,6 +2,7 @@
#include <linux/mm.h>
#include <linux/file.h>
#include <linux/mount.h>
+#include <linux/ptrace.h>
#include <linux/seq_file.h>
#include "internal.h"
@@ -143,6 +144,12 @@ out:
static int show_map(struct seq_file *m, void *_vml)
{
struct vm_list_struct *vml = _vml;
+ struct proc_maps_private *priv = m->private;
+ struct task_struct *task = priv->task;
+
+ if (maps_protect && !ptrace_may_attach(task))
+ return -EACCES;
+
return nommu_vma_show(m, vml->vma);
}
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 83bc8e7..75fc849 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -536,8 +536,7 @@ static void init_once(void *foo, struct kmem_cache * cachep,
{
struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&ei->vfs_inode);
}
diff --git a/fs/quota.c b/fs/quota.c
index b9dae76..e9d88fd 100644
--- a/fs/quota.c
+++ b/fs/quota.c
@@ -11,7 +11,6 @@
#include <asm/current.h>
#include <asm/uaccess.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/buffer_head.h>
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index d3fd7c6..3b481d5 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -16,7 +16,6 @@
#include <linux/highmem.h>
#include <linux/init.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/backing-dev.h>
#include <linux/ramfs.h>
#include <linux/quotaops.h>
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index ff1f763..4ace5d7 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -30,7 +30,6 @@
#include <linux/time.h>
#include <linux/init.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/backing-dev.h>
#include <linux/ramfs.h>
diff --git a/fs/read_write.c b/fs/read_write.c
index 1f8dc37..4d03008 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -37,10 +37,10 @@ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
mutex_lock(&inode->i_mutex);
switch (origin) {
- case 2:
+ case SEEK_END:
offset += inode->i_size;
break;
- case 1:
+ case SEEK_CUR:
offset += file->f_pos;
}
retval = -EINVAL;
@@ -63,10 +63,10 @@ loff_t remote_llseek(struct file *file, loff_t offset, int origin)
lock_kernel();
switch (origin) {
- case 2:
+ case SEEK_END:
offset += i_size_read(file->f_path.dentry->d_inode);
break;
- case 1:
+ case SEEK_CUR:
offset += file->f_pos;
}
retval = -EINVAL;
@@ -94,10 +94,10 @@ loff_t default_llseek(struct file *file, loff_t offset, int origin)
lock_kernel();
switch (origin) {
- case 2:
+ case SEEK_END:
offset += i_size_read(file->f_path.dentry->d_inode);
break;
- case 1:
+ case SEEK_CUR:
offset += file->f_pos;
}
retval = -EINVAL;
@@ -139,7 +139,7 @@ asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
goto bad;
retval = -EINVAL;
- if (origin <= 2) {
+ if (origin <= SEEK_MAX) {
loff_t res = vfs_llseek(file, offset, origin);
retval = res;
if (res != (loff_t)retval)
@@ -166,7 +166,7 @@ asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high,
goto bad;
retval = -EINVAL;
- if (origin > 2)
+ if (origin > SEEK_MAX)
goto out_putf;
offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low,
diff --git a/fs/readdir.c b/fs/readdir.c
index f39f5b3..efe52e6 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -4,13 +4,13 @@
* Copyright (C) 1995 Linus Torvalds
*/
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/file.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/dirent.h>
#include <linux/security.h>
@@ -52,7 +52,6 @@ EXPORT_SYMBOL(vfs_readdir);
* case (the low-level handlers don't need to care about this).
*/
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
-#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
#ifdef __ARCH_WANT_OLD_READDIR
@@ -147,7 +146,7 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
struct linux_dirent __user * dirent;
struct getdents_callback * buf = (struct getdents_callback *) __buf;
unsigned long d_ino;
- int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
+ int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 2, sizeof(long));
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
@@ -220,8 +219,6 @@ out:
return error;
}
-#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
-
struct getdents_callback64 {
struct linux_dirent64 __user * current_dir;
struct linux_dirent64 __user * previous;
@@ -234,7 +231,7 @@ static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
{
struct linux_dirent64 __user *dirent;
struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf;
- int reclen = ROUND_UP64(NAME_OFFSET(dirent) + namlen + 1);
+ int reclen = ALIGN(NAME_OFFSET(dirent) + namlen + 1, sizeof(u64));
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 96a2f88..9c23fee 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -7,7 +7,6 @@
#include <linux/fs.h>
#include <linux/reiserfs_fs.h>
#include <linux/stat.h>
-#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <asm/uaccess.h>
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index abfada2..ab45db5 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -6,7 +6,6 @@
#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_acl.h>
#include <linux/reiserfs_xattr.h>
-#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 7280a23..e073fd8 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -2918,7 +2918,7 @@ static void queue_log_writer(struct super_block *s)
set_current_state(TASK_UNINTERRUPTIBLE);
if (test_bit(J_WRITERS_QUEUED, &journal->j_state))
schedule();
- current->state = TASK_RUNNING;
+ __set_current_state(TASK_RUNNING);
remove_wait_queue(&journal->j_join_wait, &wait);
}
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index a216184..b378eea 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -16,7 +16,6 @@
#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_acl.h>
#include <linux/reiserfs_xattr.h>
-#include <linux/smp_lock.h>
#include <linux/quotaops.h>
#define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { inc_nlink(i); if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; }
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
index ecc9943..9aa7a06 100644
--- a/fs/reiserfs/procfs.c
+++ b/fs/reiserfs/procfs.c
@@ -16,11 +16,10 @@
#include <asm/uaccess.h>
#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_fs_sb.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
-#if defined( REISERFS_PROC_INFO )
+#ifdef CONFIG_REISERFS_PROC_INFO
/*
* LOCKING:
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c
index 3156847..976cc78 100644
--- a/fs/reiserfs/resize.c
+++ b/fs/reiserfs/resize.c
@@ -131,6 +131,10 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
/* don't use read_bitmap_block since it will cache
* the uninitialized bitmap */
bh = sb_bread(s, i * s->s_blocksize * 8);
+ if (!bh) {
+ vfree(bitmap);
+ return -EIO;
+ }
memset(bh->b_data, 0, sb_blocksize(sb));
reiserfs_test_and_set_le_bit(0, bh->b_data);
reiserfs_cache_bitmap_metadata(s, bh, bitmap + i);
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index afb21ea..b6f1259 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -53,7 +53,6 @@
#include <linux/string.h>
#include <linux/pagemap.h>
#include <linux/reiserfs_fs.h>
-#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/quotaops.h>
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index f13a7f1..c776214 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -18,7 +18,6 @@
#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_acl.h>
#include <linux/reiserfs_xattr.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/buffer_head.h>
@@ -433,12 +432,13 @@ int remove_save_link(struct inode *inode, int truncate)
static void reiserfs_kill_sb(struct super_block *s)
{
if (REISERFS_SB(s)) {
+#ifdef CONFIG_REISERFS_FS_XATTR
if (REISERFS_SB(s)->xattr_root) {
d_invalidate(REISERFS_SB(s)->xattr_root);
dput(REISERFS_SB(s)->xattr_root);
REISERFS_SB(s)->xattr_root = NULL;
}
-
+#endif
if (REISERFS_SB(s)->priv_root) {
d_invalidate(REISERFS_SB(s)->priv_root);
dput(REISERFS_SB(s)->priv_root);
@@ -511,8 +511,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags
{
struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo;
- if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
INIT_LIST_HEAD(&ei->i_prealloc_list);
inode_init_once(&ei->vfs_inode);
#ifdef CONFIG_REISERFS_FS_POSIX_ACL
@@ -1563,9 +1562,10 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
REISERFS_SB(s)->s_alloc_options.preallocmin = 0;
/* Preallocate by 16 blocks (17-1) at once */
REISERFS_SB(s)->s_alloc_options.preallocsize = 17;
+#ifdef CONFIG_REISERFS_FS_XATTR
/* Initialize the rwsem for xattr dir */
init_rwsem(&REISERFS_SB(s)->xattr_dir_sem);
-
+#endif
/* setup default block allocator options */
reiserfs_init_alloc_options(s);
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 2cac562..bf6e582 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -410,11 +410,7 @@ static struct page *reiserfs_get_page(struct inode *dir, unsigned long n)
mapping_set_gfp_mask(mapping, GFP_NOFS);
page = read_mapping_page(mapping, n, NULL);
if (!IS_ERR(page)) {
- wait_on_page_locked(page);
kmap(page);
- if (!PageUptodate(page))
- goto fail;
-
if (PageError(page))
goto fail;
}
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index fd60101..8042851 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -570,8 +570,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct romfs_inode_info *ei = (struct romfs_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&ei->vfs_inode);
}
diff --git a/fs/select.c b/fs/select.c
index fe0893a..d862241 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -14,10 +14,10 @@
* of fds to overcome nfds < 16390 descriptors limit (Tigran Aivazian).
*/
+#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/poll.h>
#include <linux/personality.h> /* for STICKY_TIMEOUTS */
#include <linux/file.h>
@@ -26,7 +26,6 @@
#include <asm/uaccess.h>
-#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
#define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)
struct poll_table_page {
@@ -399,7 +398,7 @@ asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp,
if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS)
timeout = -1; /* infinite */
else {
- timeout = ROUND_UP(tv.tv_usec, USEC_PER_SEC/HZ);
+ timeout = DIV_ROUND_UP(tv.tv_usec, USEC_PER_SEC/HZ);
timeout += tv.tv_sec * HZ;
}
}
@@ -454,7 +453,7 @@ asmlinkage long sys_pselect7(int n, fd_set __user *inp, fd_set __user *outp,
if ((u64)ts.tv_sec >= (u64)MAX_INT64_SECONDS)
timeout = -1; /* infinite */
else {
- timeout = ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ);
+ timeout = DIV_ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ);
timeout += ts.tv_sec * HZ;
}
}
@@ -776,7 +775,7 @@ asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds,
if ((u64)ts.tv_sec >= (u64)MAX_INT64_SECONDS)
timeout = -1; /* infinite */
else {
- timeout = ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ);
+ timeout = DIV_ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ);
timeout += ts.tv_sec * HZ;
}
}
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 5faba4f..424a3dd 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -69,9 +69,8 @@ static void smb_destroy_inode(struct inode *inode)
static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
{
struct smb_inode_info *ei = (struct smb_inode_info *) foo;
- unsigned long flagmask = SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR;
- if ((flags & flagmask) == SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&ei->vfs_inode);
}
diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c
index 723f7c6..c288fbe 100644
--- a/fs/smbfs/request.c
+++ b/fs/smbfs/request.c
@@ -6,6 +6,7 @@
* Please add a note about your changes to smbfs in the ChangeLog file.
*/
+#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/slab.h>
@@ -22,8 +23,6 @@
/* #define SMB_SLAB_DEBUG (SLAB_RED_ZONE | SLAB_POISON) */
#define SMB_SLAB_DEBUG 0
-#define ROUND_UP(x) (((x)+3) & ~3)
-
/* cache for request structures */
static struct kmem_cache *req_cachep;
@@ -200,8 +199,8 @@ static int smb_setup_trans2request(struct smb_request *req)
const int smb_parameters = 15;
const int header = SMB_HEADER_LEN + 2 * smb_parameters + 2;
- const int oparam = ROUND_UP(header + 3);
- const int odata = ROUND_UP(oparam + req->rq_lparm);
+ const int oparam = ALIGN(header + 3, sizeof(u32));
+ const int odata = ALIGN(oparam + req->rq_lparm, sizeof(u32));
const int bcc = (req->rq_data ? odata + req->rq_ldata :
oparam + req->rq_lparm) - header;
diff --git a/fs/smbfs/smbiod.c b/fs/smbfs/smbiod.c
index 89eaf31..67176af 100644
--- a/fs/smbfs/smbiod.c
+++ b/fs/smbfs/smbiod.c
@@ -16,7 +16,6 @@
#include <linux/init.h>
#include <linux/file.h>
#include <linux/dcache.h>
-#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/net.h>
#include <linux/kthread.h>
@@ -299,8 +298,6 @@ out:
*/
static int smbiod(void *unused)
{
- allow_signal(SIGKILL);
-
VERBOSE("SMB Kernel thread starting (%d) ...\n", current->pid);
for (;;) {
diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c
index 92ea6b2..e48bd82 100644
--- a/fs/smbfs/sock.c
+++ b/fs/smbfs/sock.c
@@ -17,7 +17,6 @@
#include <linux/net.h>
#include <linux/mm.h>
#include <linux/netdevice.h>
-#include <linux/smp_lock.h>
#include <linux/workqueue.h>
#include <net/scm.h>
#include <net/tcp_states.h>
diff --git a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c
index fea20ce..00b2909 100644
--- a/fs/smbfs/symlink.c
+++ b/fs/smbfs/symlink.c
@@ -13,7 +13,6 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include <linux/net.h>
#include <linux/namei.h>
diff --git a/fs/splice.c b/fs/splice.c
index 5428b0f..12f2828 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -289,12 +289,10 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
nr_pages = PIPE_BUFFERS;
/*
- * Initiate read-ahead on this page range. however, don't call into
- * read-ahead if this is a non-zero offset (we are likely doing small
- * chunk splice and the page is already there) for a single page.
+ * Don't try to 2nd guess the read-ahead logic, call into
+ * page_cache_readahead() like the page cache reads would do.
*/
- if (!loff || nr_pages > 1)
- page_cache_readahead(mapping, &in->f_ra, in, index, nr_pages);
+ page_cache_readahead(mapping, &in->f_ra, in, index, nr_pages);
/*
* Now fill in the holes:
@@ -378,10 +376,11 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
* If in nonblock mode then dont block on waiting
* for an in-flight io page
*/
- if (flags & SPLICE_F_NONBLOCK)
- break;
-
- lock_page(page);
+ if (flags & SPLICE_F_NONBLOCK) {
+ if (TestSetPageLocked(page))
+ break;
+ } else
+ lock_page(page);
/*
* page was truncated, stop here. if this isn't the
diff --git a/fs/stat.c b/fs/stat.c
index 38a8cb2..6851006 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -8,7 +8,6 @@
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/file.h>
-#include <linux/smp_lock.h>
#include <linux/highuid.h>
#include <linux/fs.h>
#include <linux/namei.h>
diff --git a/fs/super.c b/fs/super.c
index 8341e4e..5260d62 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -107,6 +107,7 @@ out:
static inline void destroy_super(struct super_block *s)
{
security_sb_free(s);
+ kfree(s->s_subtype);
kfree(s);
}
@@ -907,6 +908,29 @@ out:
EXPORT_SYMBOL_GPL(vfs_kern_mount);
+static struct vfsmount *fs_set_subtype(struct vfsmount *mnt, const char *fstype)
+{
+ int err;
+ const char *subtype = strchr(fstype, '.');
+ if (subtype) {
+ subtype++;
+ err = -EINVAL;
+ if (!subtype[0])
+ goto err;
+ } else
+ subtype = "";
+
+ mnt->mnt_sb->s_subtype = kstrdup(subtype, GFP_KERNEL);
+ err = -ENOMEM;
+ if (!mnt->mnt_sb->s_subtype)
+ goto err;
+ return mnt;
+
+ err:
+ mntput(mnt);
+ return ERR_PTR(err);
+}
+
struct vfsmount *
do_kern_mount(const char *fstype, int flags, const char *name, void *data)
{
@@ -915,6 +939,9 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data)
if (!type)
return ERR_PTR(-ENODEV);
mnt = vfs_kern_mount(type, flags, name, data);
+ if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
+ !mnt->mnt_sb->s_subtype)
+ mnt = fs_set_subtype(mnt, fstype);
put_filesystem(type);
return mnt;
}
diff --git a/fs/sync.c b/fs/sync.c
index 5cb9e7e..2f97576 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -229,7 +229,7 @@ asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
!S_ISLNK(i_mode))
goto out_put;
- ret = do_sync_file_range(file, offset, endbyte, flags);
+ ret = do_sync_mapping_range(file->f_mapping, offset, endbyte, flags);
out_put:
fput_light(file, fput_needed);
out:
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index ebf7007..e566b38 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -54,17 +54,9 @@ static struct page * dir_get_page(struct inode *dir, unsigned long n)
{
struct address_space *mapping = dir->i_mapping;
struct page *page = read_mapping_page(mapping, n, NULL);
- if (!IS_ERR(page)) {
- wait_on_page_locked(page);
+ if (!IS_ERR(page))
kmap(page);
- if (!PageUptodate(page))
- goto fail;
- }
return page;
-
-fail:
- dir_put_page(page);
- return ERR_PTR(-EIO);
}
static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir)
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 9311cac..3152d74 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -322,8 +322,7 @@ static void init_once(void *p, struct kmem_cache *cachep, unsigned long flags)
{
struct sysv_inode_info *si = (struct sysv_inode_info *)p;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&si->vfs_inode);
}
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index 4e48abb..6bd850b 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -13,7 +13,6 @@
*/
#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
#include "sysv.h"
static int add_nondir(struct dentry *dentry, struct inode *inode)
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index ea521f8..4cec910 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -427,9 +427,9 @@ static void udf_table_free_blocks(struct super_block * sb,
{
struct udf_sb_info *sbi = UDF_SB(sb);
uint32_t start, end;
- uint32_t nextoffset, oextoffset, elen;
- kernel_lb_addr nbloc, obloc, eloc;
- struct buffer_head *obh, *nbh;
+ uint32_t elen;
+ kernel_lb_addr eloc;
+ struct extent_position oepos, epos;
int8_t etype;
int i;
@@ -457,14 +457,13 @@ static void udf_table_free_blocks(struct super_block * sb,
start = bloc.logicalBlockNum + offset;
end = bloc.logicalBlockNum + offset + count - 1;
- oextoffset = nextoffset = sizeof(struct unallocSpaceEntry);
+ epos.offset = oepos.offset = sizeof(struct unallocSpaceEntry);
elen = 0;
- obloc = nbloc = UDF_I_LOCATION(table);
-
- obh = nbh = NULL;
+ epos.block = oepos.block = UDF_I_LOCATION(table);
+ epos.bh = oepos.bh = NULL;
while (count && (etype =
- udf_next_aext(table, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
+ udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
{
if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) ==
start))
@@ -482,7 +481,7 @@ static void udf_table_free_blocks(struct super_block * sb,
start += count;
count = 0;
}
- udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1);
+ udf_write_aext(table, &oepos, eloc, elen, 1);
}
else if (eloc.logicalBlockNum == (end + 1))
{
@@ -502,20 +501,20 @@ static void udf_table_free_blocks(struct super_block * sb,
end -= count;
count = 0;
}
- udf_write_aext(table, obloc, &oextoffset, eloc, elen, obh, 1);
+ udf_write_aext(table, &oepos, eloc, elen, 1);
}
- if (nbh != obh)
+ if (epos.bh != oepos.bh)
{
i = -1;
- obloc = nbloc;
- udf_release_data(obh);
- atomic_inc(&nbh->b_count);
- obh = nbh;
- oextoffset = 0;
+ oepos.block = epos.block;
+ brelse(oepos.bh);
+ get_bh(epos.bh);
+ oepos.bh = epos.bh;
+ oepos.offset = 0;
}
else
- oextoffset = nextoffset;
+ oepos.offset = epos.offset;
}
if (count)
@@ -547,55 +546,53 @@ static void udf_table_free_blocks(struct super_block * sb,
adsize = sizeof(long_ad);
else
{
- udf_release_data(obh);
- udf_release_data(nbh);
+ brelse(oepos.bh);
+ brelse(epos.bh);
goto error_return;
}
- if (nextoffset + (2 * adsize) > sb->s_blocksize)
+ if (epos.offset + (2 * adsize) > sb->s_blocksize)
{
char *sptr, *dptr;
int loffset;
- udf_release_data(obh);
- obh = nbh;
- obloc = nbloc;
- oextoffset = nextoffset;
+ brelse(oepos.bh);
+ oepos = epos;
/* Steal a block from the extent being free'd */
- nbloc.logicalBlockNum = eloc.logicalBlockNum;
+ epos.block.logicalBlockNum = eloc.logicalBlockNum;
eloc.logicalBlockNum ++;
elen -= sb->s_blocksize;
- if (!(nbh = udf_tread(sb,
- udf_get_lb_pblock(sb, nbloc, 0))))
+ if (!(epos.bh = udf_tread(sb,
+ udf_get_lb_pblock(sb, epos.block, 0))))
{
- udf_release_data(obh);
+ brelse(oepos.bh);
goto error_return;
}
- aed = (struct allocExtDesc *)(nbh->b_data);
- aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
- if (nextoffset + adsize > sb->s_blocksize)
+ aed = (struct allocExtDesc *)(epos.bh->b_data);
+ aed->previousAllocExtLocation = cpu_to_le32(oepos.block.logicalBlockNum);
+ if (epos.offset + adsize > sb->s_blocksize)
{
- loffset = nextoffset;
+ loffset = epos.offset;
aed->lengthAllocDescs = cpu_to_le32(adsize);
- sptr = UDF_I_DATA(inode) + nextoffset -
+ sptr = UDF_I_DATA(inode) + epos.offset -
udf_file_entry_alloc_offset(inode) +
UDF_I_LENEATTR(inode) - adsize;
- dptr = nbh->b_data + sizeof(struct allocExtDesc);
+ dptr = epos.bh->b_data + sizeof(struct allocExtDesc);
memcpy(dptr, sptr, adsize);
- nextoffset = sizeof(struct allocExtDesc) + adsize;
+ epos.offset = sizeof(struct allocExtDesc) + adsize;
}
else
{
- loffset = nextoffset + adsize;
+ loffset = epos.offset + adsize;
aed->lengthAllocDescs = cpu_to_le32(0);
- sptr = (obh)->b_data + nextoffset;
- nextoffset = sizeof(struct allocExtDesc);
+ sptr = oepos.bh->b_data + epos.offset;
+ epos.offset = sizeof(struct allocExtDesc);
- if (obh)
+ if (oepos.bh)
{
- aed = (struct allocExtDesc *)(obh)->b_data;
+ aed = (struct allocExtDesc *)oepos.bh->b_data;
aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
}
@@ -606,11 +603,11 @@ static void udf_table_free_blocks(struct super_block * sb,
}
}
if (UDF_SB_UDFREV(sb) >= 0x0200)
- udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
- nbloc.logicalBlockNum, sizeof(tag));
+ udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 3, 1,
+ epos.block.logicalBlockNum, sizeof(tag));
else
- udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
- nbloc.logicalBlockNum, sizeof(tag));
+ udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 2, 1,
+ epos.block.logicalBlockNum, sizeof(tag));
switch (UDF_I_ALLOCTYPE(table))
{
case ICBTAG_FLAG_AD_SHORT:
@@ -619,7 +616,7 @@ static void udf_table_free_blocks(struct super_block * sb,
sad->extLength = cpu_to_le32(
EXT_NEXT_EXTENT_ALLOCDECS |
sb->s_blocksize);
- sad->extPosition = cpu_to_le32(nbloc.logicalBlockNum);
+ sad->extPosition = cpu_to_le32(epos.block.logicalBlockNum);
break;
}
case ICBTAG_FLAG_AD_LONG:
@@ -628,14 +625,14 @@ static void udf_table_free_blocks(struct super_block * sb,
lad->extLength = cpu_to_le32(
EXT_NEXT_EXTENT_ALLOCDECS |
sb->s_blocksize);
- lad->extLocation = cpu_to_lelb(nbloc);
+ lad->extLocation = cpu_to_lelb(epos.block);
break;
}
}
- if (obh)
+ if (oepos.bh)
{
- udf_update_tag(obh->b_data, loffset);
- mark_buffer_dirty(obh);
+ udf_update_tag(oepos.bh->b_data, loffset);
+ mark_buffer_dirty(oepos.bh);
}
else
mark_inode_dirty(table);
@@ -643,26 +640,26 @@ static void udf_table_free_blocks(struct super_block * sb,
if (elen) /* It's possible that stealing the block emptied the extent */
{
- udf_write_aext(table, nbloc, &nextoffset, eloc, elen, nbh, 1);
+ udf_write_aext(table, &epos, eloc, elen, 1);
- if (!nbh)
+ if (!epos.bh)
{
UDF_I_LENALLOC(table) += adsize;
mark_inode_dirty(table);
}
else
{
- aed = (struct allocExtDesc *)nbh->b_data;
+ aed = (struct allocExtDesc *)epos.bh->b_data;
aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
- udf_update_tag(nbh->b_data, nextoffset);
- mark_buffer_dirty(nbh);
+ udf_update_tag(epos.bh->b_data, epos.offset);
+ mark_buffer_dirty(epos.bh);
}
}
}
- udf_release_data(nbh);
- udf_release_data(obh);
+ brelse(epos.bh);
+ brelse(oepos.bh);
error_return:
sb->s_dirt = 1;
@@ -677,9 +674,9 @@ static int udf_table_prealloc_blocks(struct super_block * sb,
{
struct udf_sb_info *sbi = UDF_SB(sb);
int alloc_count = 0;
- uint32_t extoffset, elen, adsize;
- kernel_lb_addr bloc, eloc;
- struct buffer_head *bh;
+ uint32_t elen, adsize;
+ kernel_lb_addr eloc;
+ struct extent_position epos;
int8_t etype = -1;
if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
@@ -693,14 +690,13 @@ static int udf_table_prealloc_blocks(struct super_block * sb,
return 0;
mutex_lock(&sbi->s_alloc_mutex);
- extoffset = sizeof(struct unallocSpaceEntry);
- bloc = UDF_I_LOCATION(table);
-
- bh = NULL;
+ epos.offset = sizeof(struct unallocSpaceEntry);
+ epos.block = UDF_I_LOCATION(table);
+ epos.bh = NULL;
eloc.logicalBlockNum = 0xFFFFFFFF;
while (first_block != eloc.logicalBlockNum && (etype =
- udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
+ udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
{
udf_debug("eloc=%d, elen=%d, first_block=%d\n",
eloc.logicalBlockNum, elen, first_block);
@@ -709,7 +705,7 @@ static int udf_table_prealloc_blocks(struct super_block * sb,
if (first_block == eloc.logicalBlockNum)
{
- extoffset -= adsize;
+ epos.offset -= adsize;
alloc_count = (elen >> sb->s_blocksize_bits);
if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count))
@@ -719,15 +715,15 @@ static int udf_table_prealloc_blocks(struct super_block * sb,
alloc_count = block_count;
eloc.logicalBlockNum += alloc_count;
elen -= (alloc_count << sb->s_blocksize_bits);
- udf_write_aext(table, bloc, &extoffset, eloc, (etype << 30) | elen, bh, 1);
+ udf_write_aext(table, &epos, eloc, (etype << 30) | elen, 1);
}
else
- udf_delete_aext(table, bloc, extoffset, eloc, (etype << 30) | elen, bh);
+ udf_delete_aext(table, epos, eloc, (etype << 30) | elen);
}
else
alloc_count = 0;
- udf_release_data(bh);
+ brelse(epos.bh);
if (alloc_count && UDF_SB_LVIDBH(sb))
{
@@ -747,9 +743,9 @@ static int udf_table_new_block(struct super_block * sb,
struct udf_sb_info *sbi = UDF_SB(sb);
uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF;
uint32_t newblock = 0, adsize;
- uint32_t extoffset, goal_extoffset, elen, goal_elen = 0;
- kernel_lb_addr bloc, goal_bloc, eloc, goal_eloc;
- struct buffer_head *bh, *goal_bh;
+ uint32_t elen, goal_elen = 0;
+ kernel_lb_addr eloc, goal_eloc;
+ struct extent_position epos, goal_epos;
int8_t etype;
*err = -ENOSPC;
@@ -770,14 +766,12 @@ static int udf_table_new_block(struct super_block * sb,
We store the buffer_head, bloc, and extoffset of the current closest
match and use that when we are done.
*/
-
- extoffset = sizeof(struct unallocSpaceEntry);
- bloc = UDF_I_LOCATION(table);
-
- goal_bh = bh = NULL;
+ epos.offset = sizeof(struct unallocSpaceEntry);
+ epos.block = UDF_I_LOCATION(table);
+ epos.bh = goal_epos.bh = NULL;
while (spread && (etype =
- udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
+ udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
{
if (goal >= eloc.logicalBlockNum)
{
@@ -793,24 +787,24 @@ static int udf_table_new_block(struct super_block * sb,
if (nspread < spread)
{
spread = nspread;
- if (goal_bh != bh)
+ if (goal_epos.bh != epos.bh)
{
- udf_release_data(goal_bh);
- goal_bh = bh;
- atomic_inc(&goal_bh->b_count);
+ brelse(goal_epos.bh);
+ goal_epos.bh = epos.bh;
+ get_bh(goal_epos.bh);
}
- goal_bloc = bloc;
- goal_extoffset = extoffset - adsize;
+ goal_epos.block = epos.block;
+ goal_epos.offset = epos.offset - adsize;
goal_eloc = eloc;
goal_elen = (etype << 30) | elen;
}
}
- udf_release_data(bh);
+ brelse(epos.bh);
if (spread == 0xFFFFFFFF)
{
- udf_release_data(goal_bh);
+ brelse(goal_epos.bh);
mutex_unlock(&sbi->s_alloc_mutex);
return 0;
}
@@ -826,17 +820,17 @@ static int udf_table_new_block(struct super_block * sb,
if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
{
- udf_release_data(goal_bh);
+ brelse(goal_epos.bh);
mutex_unlock(&sbi->s_alloc_mutex);
*err = -EDQUOT;
return 0;
}
if (goal_elen)
- udf_write_aext(table, goal_bloc, &goal_extoffset, goal_eloc, goal_elen, goal_bh, 1);
+ udf_write_aext(table, &goal_epos, goal_eloc, goal_elen, 1);
else
- udf_delete_aext(table, goal_bloc, goal_extoffset, goal_eloc, goal_elen, goal_bh);
- udf_release_data(goal_bh);
+ udf_delete_aext(table, goal_epos, goal_eloc, goal_elen);
+ brelse(goal_epos.bh);
if (UDF_SB_LVIDBH(sb))
{
@@ -921,11 +915,14 @@ inline int udf_new_block(struct super_block * sb,
struct inode * inode,
uint16_t partition, uint32_t goal, int *err)
{
+ int ret;
+
if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP)
{
- return udf_bitmap_new_block(sb, inode,
+ ret = udf_bitmap_new_block(sb, inode,
UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
partition, goal, err);
+ return ret;
}
else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE)
{
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
index 2391c91..e45f86b 100644
--- a/fs/udf/dir.c
+++ b/fs/udf/dir.c
@@ -111,11 +111,13 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
uint16_t liu;
uint8_t lfi;
loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
- struct buffer_head * bh = NULL, * tmp, * bha[16];
- kernel_lb_addr bloc, eloc;
- uint32_t extoffset, elen, offset;
+ struct buffer_head *tmp, *bha[16];
+ kernel_lb_addr eloc;
+ uint32_t elen;
+ sector_t offset;
int i, num;
unsigned int dt_type;
+ struct extent_position epos = { NULL, 0, {0, 0}};
if (nf_pos >= size)
return 0;
@@ -127,23 +129,22 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh.sbh = fibh.ebh = NULL;
else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
- &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
+ &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
{
- offset >>= dir->i_sb->s_blocksize_bits;
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
{
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
- extoffset -= sizeof(short_ad);
+ epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
- extoffset -= sizeof(long_ad);
+ epos.offset -= sizeof(long_ad);
}
else
offset = 0;
if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block)))
{
- udf_release_data(bh);
+ brelse(epos.bh);
return -EIO;
}
@@ -171,7 +172,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
}
else
{
- udf_release_data(bh);
+ brelse(epos.bh);
return -ENOENT;
}
@@ -179,14 +180,14 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
{
filp->f_pos = nf_pos + 1;
- fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
+ fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset);
if (!fi)
{
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
- udf_release_data(bh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
+ brelse(epos.bh);
return 0;
}
@@ -244,9 +245,9 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0)
{
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
- udf_release_data(bh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
+ brelse(epos.bh);
return 0;
}
}
@@ -255,9 +256,9 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
filp->f_pos = nf_pos + 1;
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
- udf_release_data(bh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
+ brelse(epos.bh);
return 0;
}
diff --git a/fs/udf/directory.c b/fs/udf/directory.c
index fe751a2..198caa3 100644
--- a/fs/udf/directory.c
+++ b/fs/udf/directory.c
@@ -36,14 +36,14 @@ udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size,
if (!ad)
{
- udf_release_data(*bh);
+ brelse(*bh);
*error = 1;
return NULL;
}
if (*offset == dir->i_sb->s_blocksize)
{
- udf_release_data(*bh);
+ brelse(*bh);
block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
if (!block)
return NULL;
@@ -57,7 +57,7 @@ udf_filead_read(struct inode *dir, uint8_t *tmpad, uint8_t ad_size,
remainder = dir->i_sb->s_blocksize - loffset;
memcpy((uint8_t *)ad, (*bh)->b_data + loffset, remainder);
- udf_release_data(*bh);
+ brelse(*bh);
block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
if (!block)
return NULL;
@@ -75,9 +75,9 @@ struct fileIdentDesc *
udf_fileident_read(struct inode *dir, loff_t *nf_pos,
struct udf_fileident_bh *fibh,
struct fileIdentDesc *cfi,
- kernel_lb_addr *bloc, uint32_t *extoffset,
+ struct extent_position *epos,
kernel_lb_addr *eloc, uint32_t *elen,
- uint32_t *offset, struct buffer_head **bh)
+ sector_t *offset)
{
struct fileIdentDesc *fi;
int i, num, block;
@@ -105,13 +105,11 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos,
if (fibh->eoffset == dir->i_sb->s_blocksize)
{
- int lextoffset = *extoffset;
+ int lextoffset = epos->offset;
- if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) !=
+ if (udf_next_aext(dir, epos, eloc, elen, 1) !=
(EXT_RECORDED_ALLOCATED >> 30))
- {
return NULL;
- }
block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
@@ -120,9 +118,9 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos,
if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
*offset = 0;
else
- *extoffset = lextoffset;
+ epos->offset = lextoffset;
- udf_release_data(fibh->sbh);
+ brelse(fibh->sbh);
if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block)))
return NULL;
fibh->soffset = fibh->eoffset = 0;
@@ -151,7 +149,7 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos,
}
else if (fibh->sbh != fibh->ebh)
{
- udf_release_data(fibh->sbh);
+ brelse(fibh->sbh);
fibh->sbh = fibh->ebh;
}
@@ -169,13 +167,11 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos,
}
else if (fibh->eoffset > dir->i_sb->s_blocksize)
{
- int lextoffset = *extoffset;
+ int lextoffset = epos->offset;
- if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) !=
+ if (udf_next_aext(dir, epos, eloc, elen, 1) !=
(EXT_RECORDED_ALLOCATED >> 30))
- {
return NULL;
- }
block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
@@ -184,7 +180,7 @@ udf_fileident_read(struct inode *dir, loff_t *nf_pos,
if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
*offset = 0;
else
- *extoffset = lextoffset;
+ epos->offset = lextoffset;
fibh->soffset -= dir->i_sb->s_blocksize;
fibh->eoffset -= dir->i_sb->s_blocksize;
diff --git a/fs/udf/fsync.c b/fs/udf/fsync.c
index 5887d78..6ded93e 100644
--- a/fs/udf/fsync.c
+++ b/fs/udf/fsync.c
@@ -21,7 +21,6 @@
#include "udfdecl.h"
#include <linux/fs.h>
-#include <linux/smp_lock.h>
static int udf_fsync_inode(struct inode *, int);
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index ae21a0e..c846155 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -49,10 +49,10 @@ MODULE_LICENSE("GPL");
static mode_t udf_convert_permissions(struct fileEntry *);
static int udf_update_inode(struct inode *, int);
static void udf_fill_inode(struct inode *, struct buffer_head *);
-static struct buffer_head *inode_getblk(struct inode *, long, int *,
+static struct buffer_head *inode_getblk(struct inode *, sector_t, int *,
long *, int *);
-static int8_t udf_insert_aext(struct inode *, kernel_lb_addr, int,
- kernel_lb_addr, uint32_t, struct buffer_head *);
+static int8_t udf_insert_aext(struct inode *, struct extent_position,
+ kernel_lb_addr, uint32_t);
static void udf_split_extents(struct inode *, int *, int, int,
kernel_long_ad [EXTENT_MERGE_SIZE], int *);
static void udf_prealloc_extents(struct inode *, int, int,
@@ -61,7 +61,7 @@ static void udf_merge_extents(struct inode *,
kernel_long_ad [EXTENT_MERGE_SIZE], int *);
static void udf_update_extents(struct inode *,
kernel_long_ad [EXTENT_MERGE_SIZE], int, int,
- kernel_lb_addr, uint32_t, struct buffer_head **);
+ struct extent_position *);
static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
/*
@@ -194,10 +194,11 @@ void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err)
{
int newblock;
- struct buffer_head *sbh = NULL, *dbh = NULL;
- kernel_lb_addr bloc, eloc;
- uint32_t elen, extoffset;
+ struct buffer_head *dbh = NULL;
+ kernel_lb_addr eloc;
+ uint32_t elen;
uint8_t alloctype;
+ struct extent_position epos;
struct udf_fileident_bh sfibh, dfibh;
loff_t f_pos = udf_ext0_offset(inode) >> 2;
@@ -237,16 +238,16 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int
mark_buffer_dirty_inode(dbh, inode);
sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
- sbh = sfibh.sbh = sfibh.ebh = NULL;
+ sfibh.sbh = sfibh.ebh = NULL;
dfibh.soffset = dfibh.eoffset = 0;
dfibh.sbh = dfibh.ebh = dbh;
while ( (f_pos < size) )
{
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
- sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL, NULL, NULL);
+ sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL);
if (!sfi)
{
- udf_release_data(dbh);
+ brelse(dbh);
return NULL;
}
UDF_I_ALLOCTYPE(inode) = alloctype;
@@ -258,7 +259,7 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int
sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse)))
{
UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
- udf_release_data(dbh);
+ brelse(dbh);
return NULL;
}
}
@@ -266,16 +267,17 @@ struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int
memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode));
UDF_I_LENALLOC(inode) = 0;
- bloc = UDF_I_LOCATION(inode);
eloc.logicalBlockNum = *block;
eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
elen = inode->i_size;
UDF_I_LENEXTENTS(inode) = elen;
- extoffset = udf_file_entry_alloc_offset(inode);
- udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &sbh, 0);
+ epos.bh = NULL;
+ epos.block = UDF_I_LOCATION(inode);
+ epos.offset = udf_file_entry_alloc_offset(inode);
+ udf_add_aext(inode, &epos, eloc, elen, 0);
/* UniqueID stuff */
- udf_release_data(sbh);
+ brelse(epos.bh);
mark_inode_dirty(inode);
return dbh;
}
@@ -354,53 +356,153 @@ udf_getblk(struct inode *inode, long block, int create, int *err)
return NULL;
}
-static struct buffer_head * inode_getblk(struct inode * inode, long block,
+/* Extend the file by 'blocks' blocks, return the number of extents added */
+int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
+ kernel_long_ad *last_ext, sector_t blocks)
+{
+ sector_t add;
+ int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
+ struct super_block *sb = inode->i_sb;
+ kernel_lb_addr prealloc_loc = {0, 0};
+ int prealloc_len = 0;
+
+ /* The previous extent is fake and we should not extend by anything
+ * - there's nothing to do... */
+ if (!blocks && fake)
+ return 0;
+ /* Round the last extent up to a multiple of block size */
+ if (last_ext->extLength & (sb->s_blocksize - 1)) {
+ last_ext->extLength =
+ (last_ext->extLength & UDF_EXTENT_FLAG_MASK) |
+ (((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) +
+ sb->s_blocksize - 1) & ~(sb->s_blocksize - 1));
+ UDF_I_LENEXTENTS(inode) =
+ (UDF_I_LENEXTENTS(inode) + sb->s_blocksize - 1) &
+ ~(sb->s_blocksize - 1);
+ }
+ /* Last extent are just preallocated blocks? */
+ if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_ALLOCATED) {
+ /* Save the extent so that we can reattach it to the end */
+ prealloc_loc = last_ext->extLocation;
+ prealloc_len = last_ext->extLength;
+ /* Mark the extent as a hole */
+ last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
+ (last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
+ last_ext->extLocation.logicalBlockNum = 0;
+ last_ext->extLocation.partitionReferenceNum = 0;
+ }
+ /* Can we merge with the previous extent? */
+ if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_NOT_ALLOCATED) {
+ add = ((1<<30) - sb->s_blocksize - (last_ext->extLength &
+ UDF_EXTENT_LENGTH_MASK)) >> sb->s_blocksize_bits;
+ if (add > blocks)
+ add = blocks;
+ blocks -= add;
+ last_ext->extLength += add << sb->s_blocksize_bits;
+ }
+
+ if (fake) {
+ udf_add_aext(inode, last_pos, last_ext->extLocation,
+ last_ext->extLength, 1);
+ count++;
+ }
+ else
+ udf_write_aext(inode, last_pos, last_ext->extLocation, last_ext->extLength, 1);
+ /* Managed to do everything necessary? */
+ if (!blocks)
+ goto out;
+
+ /* All further extents will be NOT_RECORDED_NOT_ALLOCATED */
+ last_ext->extLocation.logicalBlockNum = 0;
+ last_ext->extLocation.partitionReferenceNum = 0;
+ add = (1 << (30-sb->s_blocksize_bits)) - 1;
+ last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | (add << sb->s_blocksize_bits);
+ /* Create enough extents to cover the whole hole */
+ while (blocks > add) {
+ blocks -= add;
+ if (udf_add_aext(inode, last_pos, last_ext->extLocation,
+ last_ext->extLength, 1) == -1)
+ return -1;
+ count++;
+ }
+ if (blocks) {
+ last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
+ (blocks << sb->s_blocksize_bits);
+ if (udf_add_aext(inode, last_pos, last_ext->extLocation,
+ last_ext->extLength, 1) == -1)
+ return -1;
+ count++;
+ }
+out:
+ /* Do we have some preallocated blocks saved? */
+ if (prealloc_len) {
+ if (udf_add_aext(inode, last_pos, prealloc_loc, prealloc_len, 1) == -1)
+ return -1;
+ last_ext->extLocation = prealloc_loc;
+ last_ext->extLength = prealloc_len;
+ count++;
+ }
+ /* last_pos should point to the last written extent... */
+ if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
+ last_pos->offset -= sizeof(short_ad);
+ else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
+ last_pos->offset -= sizeof(long_ad);
+ else
+ return -1;
+ return count;
+}
+
+static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
int *err, long *phys, int *new)
{
- struct buffer_head *pbh = NULL, *cbh = NULL, *nbh = NULL, *result = NULL;
+ static sector_t last_block;
+ struct buffer_head *result = NULL;
kernel_long_ad laarr[EXTENT_MERGE_SIZE];
- uint32_t pextoffset = 0, cextoffset = 0, nextoffset = 0;
+ struct extent_position prev_epos, cur_epos, next_epos;
int count = 0, startnum = 0, endnum = 0;
uint32_t elen = 0;
- kernel_lb_addr eloc, pbloc, cbloc, nbloc;
+ kernel_lb_addr eloc;
int c = 1;
- uint64_t lbcount = 0, b_off = 0;
- uint32_t newblocknum, newblock, offset = 0;
+ loff_t lbcount = 0, b_off = 0;
+ uint32_t newblocknum, newblock;
+ sector_t offset = 0;
int8_t etype;
int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
- char lastblock = 0;
+ int lastblock = 0;
- pextoffset = cextoffset = nextoffset = udf_file_entry_alloc_offset(inode);
- b_off = (uint64_t)block << inode->i_sb->s_blocksize_bits;
- pbloc = cbloc = nbloc = UDF_I_LOCATION(inode);
+ prev_epos.offset = udf_file_entry_alloc_offset(inode);
+ prev_epos.block = UDF_I_LOCATION(inode);
+ prev_epos.bh = NULL;
+ cur_epos = next_epos = prev_epos;
+ b_off = (loff_t)block << inode->i_sb->s_blocksize_bits;
/* find the extent which contains the block we are looking for.
alternate between laarr[0] and laarr[1] for locations of the
current extent, and the previous extent */
do
{
- if (pbh != cbh)
+ if (prev_epos.bh != cur_epos.bh)
{
- udf_release_data(pbh);
- atomic_inc(&cbh->b_count);
- pbh = cbh;
+ brelse(prev_epos.bh);
+ get_bh(cur_epos.bh);
+ prev_epos.bh = cur_epos.bh;
}
- if (cbh != nbh)
+ if (cur_epos.bh != next_epos.bh)
{
- udf_release_data(cbh);
- atomic_inc(&nbh->b_count);
- cbh = nbh;
+ brelse(cur_epos.bh);
+ get_bh(next_epos.bh);
+ cur_epos.bh = next_epos.bh;
}
lbcount += elen;
- pbloc = cbloc;
- cbloc = nbloc;
+ prev_epos.block = cur_epos.block;
+ cur_epos.block = next_epos.block;
- pextoffset = cextoffset;
- cextoffset = nextoffset;
+ prev_epos.offset = cur_epos.offset;
+ cur_epos.offset = next_epos.offset;
- if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) == -1)
+ if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1)) == -1)
break;
c = !c;
@@ -418,6 +520,8 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
b_off -= lbcount;
offset = b_off >> inode->i_sb->s_blocksize_bits;
+ /* Move into indirect extent if we are at a pointer to it */
+ udf_next_aext(inode, &prev_epos, &eloc, &elen, 0);
/* if the extent is allocated and recorded, return the block
if the extent is not a multiple of the blocksize, round up */
@@ -429,54 +533,77 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
elen = EXT_RECORDED_ALLOCATED |
((elen + inode->i_sb->s_blocksize - 1) &
~(inode->i_sb->s_blocksize - 1));
- etype = udf_write_aext(inode, nbloc, &cextoffset, eloc, elen, nbh, 1);
+ etype = udf_write_aext(inode, &cur_epos, eloc, elen, 1);
}
- udf_release_data(pbh);
- udf_release_data(cbh);
- udf_release_data(nbh);
+ brelse(prev_epos.bh);
+ brelse(cur_epos.bh);
+ brelse(next_epos.bh);
newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset);
*phys = newblock;
return NULL;
}
+ last_block = block;
+ /* Are we beyond EOF? */
if (etype == -1)
{
- endnum = startnum = ((count > 1) ? 1 : count);
- if (laarr[c].extLength & (inode->i_sb->s_blocksize - 1))
- {
- laarr[c].extLength =
- (laarr[c].extLength & UDF_EXTENT_FLAG_MASK) |
- (((laarr[c].extLength & UDF_EXTENT_LENGTH_MASK) +
- inode->i_sb->s_blocksize - 1) &
- ~(inode->i_sb->s_blocksize - 1));
- UDF_I_LENEXTENTS(inode) =
- (UDF_I_LENEXTENTS(inode) + inode->i_sb->s_blocksize - 1) &
- ~(inode->i_sb->s_blocksize - 1);
+ int ret;
+
+ if (count) {
+ if (c)
+ laarr[0] = laarr[1];
+ startnum = 1;
+ }
+ else {
+ /* Create a fake extent when there's not one */
+ memset(&laarr[0].extLocation, 0x00, sizeof(kernel_lb_addr));
+ laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
+ /* Will udf_extend_file() create real extent from a fake one? */
+ startnum = (offset > 0);
+ }
+ /* Create extents for the hole between EOF and offset */
+ ret = udf_extend_file(inode, &prev_epos, laarr, offset);
+ if (ret == -1) {
+ brelse(prev_epos.bh);
+ brelse(cur_epos.bh);
+ brelse(next_epos.bh);
+ /* We don't really know the error here so we just make
+ * something up */
+ *err = -ENOSPC;
+ return NULL;
}
- c = !c;
- laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
- ((offset + 1) << inode->i_sb->s_blocksize_bits);
- memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr));
- count ++;
- endnum ++;
+ c = 0;
+ offset = 0;
+ count += ret;
+ /* We are not covered by a preallocated extent? */
+ if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) != EXT_NOT_RECORDED_ALLOCATED) {
+ /* Is there any real extent? - otherwise we overwrite
+ * the fake one... */
+ if (count)
+ c = !c;
+ laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
+ inode->i_sb->s_blocksize;
+ memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr));
+ count ++;
+ endnum ++;
+ }
+ endnum = c+1;
lastblock = 1;
}
- else
+ else {
endnum = startnum = ((count > 2) ? 2 : count);
- /* if the current extent is in position 0, swap it with the previous */
- if (!c && count != 1)
- {
- laarr[2] = laarr[0];
- laarr[0] = laarr[1];
- laarr[1] = laarr[2];
- c = 1;
- }
+ /* if the current extent is in position 0, swap it with the previous */
+ if (!c && count != 1)
+ {
+ laarr[2] = laarr[0];
+ laarr[0] = laarr[1];
+ laarr[1] = laarr[2];
+ c = 1;
+ }
- /* if the current block is located in a extent, read the next extent */
- if (etype != -1)
- {
- if ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 0)) != -1)
+ /* if the current block is located in an extent, read the next extent */
+ if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0)) != -1)
{
laarr[c+1].extLength = (etype << 30) | elen;
laarr[c+1].extLocation = eloc;
@@ -484,11 +611,10 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
startnum ++;
endnum ++;
}
- else
+ else {
lastblock = 1;
+ }
}
- udf_release_data(cbh);
- udf_release_data(nbh);
/* if the current extent is not recorded but allocated, get the
block in the extent corresponding to the requested block */
@@ -508,7 +634,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
if (!(newblocknum = udf_new_block(inode->i_sb, inode,
UDF_I_LOCATION(inode).partitionReferenceNum, goal, err)))
{
- udf_release_data(pbh);
+ brelse(prev_epos.bh);
*err = -ENOSPC;
return NULL;
}
@@ -529,11 +655,11 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
udf_merge_extents(inode, laarr, &endnum);
/* write back the new extents, inserting new extents if the new number
- of extents is greater than the old number, and deleting extents if
- the new number of extents is less than the old number */
- udf_update_extents(inode, laarr, startnum, endnum, pbloc, pextoffset, &pbh);
+ of extents is greater than the old number, and deleting extents if
+ the new number of extents is less than the old number */
+ udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
- udf_release_data(pbh);
+ brelse(prev_epos.bh);
if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum,
UDF_I_LOCATION(inode).partitionReferenceNum, 0)))
@@ -795,7 +921,7 @@ static void udf_merge_extents(struct inode *inode,
static void udf_update_extents(struct inode *inode,
kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum,
- kernel_lb_addr pbloc, uint32_t pextoffset, struct buffer_head **pbh)
+ struct extent_position *epos)
{
int start = 0, i;
kernel_lb_addr tmploc;
@@ -804,28 +930,26 @@ static void udf_update_extents(struct inode *inode,
if (startnum > endnum)
{
for (i=0; i<(startnum-endnum); i++)
- {
- udf_delete_aext(inode, pbloc, pextoffset, laarr[i].extLocation,
- laarr[i].extLength, *pbh);
- }
+ udf_delete_aext(inode, *epos, laarr[i].extLocation,
+ laarr[i].extLength);
}
else if (startnum < endnum)
{
for (i=0; i<(endnum-startnum); i++)
{
- udf_insert_aext(inode, pbloc, pextoffset, laarr[i].extLocation,
- laarr[i].extLength, *pbh);
- udf_next_aext(inode, &pbloc, &pextoffset, &laarr[i].extLocation,
- &laarr[i].extLength, pbh, 1);
+ udf_insert_aext(inode, *epos, laarr[i].extLocation,
+ laarr[i].extLength);
+ udf_next_aext(inode, epos, &laarr[i].extLocation,
+ &laarr[i].extLength, 1);
start ++;
}
}
for (i=start; i<endnum; i++)
{
- udf_next_aext(inode, &pbloc, &pextoffset, &tmploc, &tmplen, pbh, 0);
- udf_write_aext(inode, pbloc, &pextoffset, laarr[i].extLocation,
- laarr[i].extLength, *pbh, 1);
+ udf_next_aext(inode, epos, &tmploc, &tmplen, 0);
+ udf_write_aext(inode, epos, laarr[i].extLocation,
+ laarr[i].extLength, 1);
}
}
@@ -931,7 +1055,7 @@ __udf_read_inode(struct inode *inode)
{
printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n",
inode->i_ino, ident);
- udf_release_data(bh);
+ brelse(bh);
make_bad_inode(inode);
return;
}
@@ -960,35 +1084,36 @@ __udf_read_inode(struct inode *inode)
ident == TAG_IDENT_EFE)
{
memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr));
- udf_release_data(bh);
- udf_release_data(ibh);
- udf_release_data(nbh);
+ brelse(bh);
+ brelse(ibh);
+ brelse(nbh);
__udf_read_inode(inode);
return;
}
else
{
- udf_release_data(nbh);
- udf_release_data(ibh);
+ brelse(nbh);
+ brelse(ibh);
}
}
else
- udf_release_data(ibh);
+ brelse(ibh);
}
}
else
- udf_release_data(ibh);
+ brelse(ibh);
}
else if (le16_to_cpu(fe->icbTag.strategyType) != 4)
{
printk(KERN_ERR "udf: unsupported strategy type: %d\n",
le16_to_cpu(fe->icbTag.strategyType));
- udf_release_data(bh);
+ brelse(bh);
make_bad_inode(inode);
return;
}
udf_fill_inode(inode, bh);
- udf_release_data(bh);
+
+ brelse(bh);
}
static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
@@ -1331,7 +1456,7 @@ udf_update_inode(struct inode *inode, int do_sync)
use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i];
mark_buffer_dirty(bh);
- udf_release_data(bh);
+ brelse(bh);
return err;
}
@@ -1520,7 +1645,7 @@ udf_update_inode(struct inode *inode, int do_sync)
err = -EIO;
}
}
- udf_release_data(bh);
+ brelse(bh);
return err;
}
@@ -1556,8 +1681,8 @@ udf_iget(struct super_block *sb, kernel_lb_addr ino)
return NULL;
}
-int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
- kernel_lb_addr eloc, uint32_t elen, struct buffer_head **bh, int inc)
+int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
+ kernel_lb_addr eloc, uint32_t elen, int inc)
{
int adsize;
short_ad *sad = NULL;
@@ -1566,10 +1691,10 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
int8_t etype;
uint8_t *ptr;
- if (!*bh)
- ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
+ if (!epos->bh)
+ ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
else
- ptr = (*bh)->b_data + *extoffset;
+ ptr = epos->bh->b_data + epos->offset;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
adsize = sizeof(short_ad);
@@ -1578,20 +1703,20 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
else
return -1;
- if (*extoffset + (2 * adsize) > inode->i_sb->s_blocksize)
+ if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize)
{
char *sptr, *dptr;
struct buffer_head *nbh;
int err, loffset;
- kernel_lb_addr obloc = *bloc;
+ kernel_lb_addr obloc = epos->block;
- if (!(bloc->logicalBlockNum = udf_new_block(inode->i_sb, NULL,
+ if (!(epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL,
obloc.partitionReferenceNum, obloc.logicalBlockNum, &err)))
{
return -1;
}
if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
- *bloc, 0))))
+ epos->block, 0))))
{
return -1;
}
@@ -1604,25 +1729,25 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
aed = (struct allocExtDesc *)(nbh->b_data);
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
- if (*extoffset + adsize > inode->i_sb->s_blocksize)
+ if (epos->offset + adsize > inode->i_sb->s_blocksize)
{
- loffset = *extoffset;
+ loffset = epos->offset;
aed->lengthAllocDescs = cpu_to_le32(adsize);
sptr = ptr - adsize;
dptr = nbh->b_data + sizeof(struct allocExtDesc);
memcpy(dptr, sptr, adsize);
- *extoffset = sizeof(struct allocExtDesc) + adsize;
+ epos->offset = sizeof(struct allocExtDesc) + adsize;
}
else
{
- loffset = *extoffset + adsize;
+ loffset = epos->offset + adsize;
aed->lengthAllocDescs = cpu_to_le32(0);
sptr = ptr;
- *extoffset = sizeof(struct allocExtDesc);
+ epos->offset = sizeof(struct allocExtDesc);
- if (*bh)
+ if (epos->bh)
{
- aed = (struct allocExtDesc *)(*bh)->b_data;
+ aed = (struct allocExtDesc *)epos->bh->b_data;
aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
}
@@ -1634,10 +1759,10 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
}
if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
- bloc->logicalBlockNum, sizeof(tag));
+ epos->block.logicalBlockNum, sizeof(tag));
else
udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
- bloc->logicalBlockNum, sizeof(tag));
+ epos->block.logicalBlockNum, sizeof(tag));
switch (UDF_I_ALLOCTYPE(inode))
{
case ICBTAG_FLAG_AD_SHORT:
@@ -1646,7 +1771,7 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
sad->extLength = cpu_to_le32(
EXT_NEXT_EXTENT_ALLOCDECS |
inode->i_sb->s_blocksize);
- sad->extPosition = cpu_to_le32(bloc->logicalBlockNum);
+ sad->extPosition = cpu_to_le32(epos->block.logicalBlockNum);
break;
}
case ICBTAG_FLAG_AD_LONG:
@@ -1655,60 +1780,57 @@ int8_t udf_add_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
lad->extLength = cpu_to_le32(
EXT_NEXT_EXTENT_ALLOCDECS |
inode->i_sb->s_blocksize);
- lad->extLocation = cpu_to_lelb(*bloc);
+ lad->extLocation = cpu_to_lelb(epos->block);
memset(lad->impUse, 0x00, sizeof(lad->impUse));
break;
}
}
- if (*bh)
+ if (epos->bh)
{
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
- udf_update_tag((*bh)->b_data, loffset);
+ udf_update_tag(epos->bh->b_data, loffset);
else
- udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc));
- mark_buffer_dirty_inode(*bh, inode);
- udf_release_data(*bh);
+ udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc));
+ mark_buffer_dirty_inode(epos->bh, inode);
+ brelse(epos->bh);
}
else
mark_inode_dirty(inode);
- *bh = nbh;
+ epos->bh = nbh;
}
- etype = udf_write_aext(inode, *bloc, extoffset, eloc, elen, *bh, inc);
+ etype = udf_write_aext(inode, epos, eloc, elen, inc);
- if (!*bh)
+ if (!epos->bh)
{
UDF_I_LENALLOC(inode) += adsize;
mark_inode_dirty(inode);
}
else
{
- aed = (struct allocExtDesc *)(*bh)->b_data;
+ aed = (struct allocExtDesc *)epos->bh->b_data;
aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
- udf_update_tag((*bh)->b_data, *extoffset + (inc ? 0 : adsize));
+ udf_update_tag(epos->bh->b_data, epos->offset + (inc ? 0 : adsize));
else
- udf_update_tag((*bh)->b_data, sizeof(struct allocExtDesc));
- mark_buffer_dirty_inode(*bh, inode);
+ udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc));
+ mark_buffer_dirty_inode(epos->bh, inode);
}
return etype;
}
-int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset,
- kernel_lb_addr eloc, uint32_t elen, struct buffer_head *bh, int inc)
+int8_t udf_write_aext(struct inode *inode, struct extent_position *epos,
+ kernel_lb_addr eloc, uint32_t elen, int inc)
{
int adsize;
uint8_t *ptr;
- if (!bh)
- ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
+ if (!epos->bh)
+ ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
else
- {
- ptr = bh->b_data + *extoffset;
- atomic_inc(&bh->b_count);
- }
+ ptr = epos->bh->b_data + epos->offset;
switch (UDF_I_ALLOCTYPE(inode))
{
@@ -1733,40 +1855,39 @@ int8_t udf_write_aext(struct inode *inode, kernel_lb_addr bloc, int *extoffset,
return -1;
}
- if (bh)
+ if (epos->bh)
{
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
{
- struct allocExtDesc *aed = (struct allocExtDesc *)(bh)->b_data;
- udf_update_tag((bh)->b_data,
+ struct allocExtDesc *aed = (struct allocExtDesc *)epos->bh->b_data;
+ udf_update_tag(epos->bh->b_data,
le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc));
}
- mark_buffer_dirty_inode(bh, inode);
- udf_release_data(bh);
+ mark_buffer_dirty_inode(epos->bh, inode);
}
else
mark_inode_dirty(inode);
if (inc)
- *extoffset += adsize;
+ epos->offset += adsize;
return (elen >> 30);
}
-int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
- kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc)
+int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
+ kernel_lb_addr *eloc, uint32_t *elen, int inc)
{
int8_t etype;
- while ((etype = udf_current_aext(inode, bloc, extoffset, eloc, elen, bh, inc)) ==
+ while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) ==
(EXT_NEXT_EXTENT_ALLOCDECS >> 30))
{
- *bloc = *eloc;
- *extoffset = sizeof(struct allocExtDesc);
- udf_release_data(*bh);
- if (!(*bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, *bloc, 0))))
+ epos->block = *eloc;
+ epos->offset = sizeof(struct allocExtDesc);
+ brelse(epos->bh);
+ if (!(epos->bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, epos->block, 0))))
{
udf_debug("reading block %d failed!\n",
- udf_get_lb_pblock(inode->i_sb, *bloc, 0));
+ udf_get_lb_pblock(inode->i_sb, epos->block, 0));
return -1;
}
}
@@ -1774,26 +1895,26 @@ int8_t udf_next_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
return etype;
}
-int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffset,
- kernel_lb_addr *eloc, uint32_t *elen, struct buffer_head **bh, int inc)
+int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
+ kernel_lb_addr *eloc, uint32_t *elen, int inc)
{
int alen;
int8_t etype;
uint8_t *ptr;
- if (!*bh)
+ if (!epos->bh)
{
- if (!(*extoffset))
- *extoffset = udf_file_entry_alloc_offset(inode);
- ptr = UDF_I_DATA(inode) + *extoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
+ if (!epos->offset)
+ epos->offset = udf_file_entry_alloc_offset(inode);
+ ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode);
}
else
{
- if (!(*extoffset))
- *extoffset = sizeof(struct allocExtDesc);
- ptr = (*bh)->b_data + *extoffset;
- alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)(*bh)->b_data)->lengthAllocDescs);
+ if (!epos->offset)
+ epos->offset = sizeof(struct allocExtDesc);
+ ptr = epos->bh->b_data + epos->offset;
+ alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->lengthAllocDescs);
}
switch (UDF_I_ALLOCTYPE(inode))
@@ -1802,7 +1923,7 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse
{
short_ad *sad;
- if (!(sad = udf_get_fileshortad(ptr, alen, extoffset, inc)))
+ if (!(sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc)))
return -1;
etype = le32_to_cpu(sad->extLength) >> 30;
@@ -1815,7 +1936,7 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse
{
long_ad *lad;
- if (!(lad = udf_get_filelongad(ptr, alen, extoffset, inc)))
+ if (!(lad = udf_get_filelongad(ptr, alen, &epos->offset, inc)))
return -1;
etype = le32_to_cpu(lad->extLength) >> 30;
@@ -1834,41 +1955,40 @@ int8_t udf_current_aext(struct inode *inode, kernel_lb_addr *bloc, int *extoffse
}
static int8_t
-udf_insert_aext(struct inode *inode, kernel_lb_addr bloc, int extoffset,
- kernel_lb_addr neloc, uint32_t nelen, struct buffer_head *bh)
+udf_insert_aext(struct inode *inode, struct extent_position epos,
+ kernel_lb_addr neloc, uint32_t nelen)
{
kernel_lb_addr oeloc;
uint32_t oelen;
int8_t etype;
- if (bh)
- atomic_inc(&bh->b_count);
+ if (epos.bh)
+ get_bh(epos.bh);
- while ((etype = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
+ while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1)
{
- udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
+ udf_write_aext(inode, &epos, neloc, nelen, 1);
neloc = oeloc;
nelen = (etype << 30) | oelen;
}
- udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1);
- udf_release_data(bh);
+ udf_add_aext(inode, &epos, neloc, nelen, 1);
+ brelse(epos.bh);
return (nelen >> 30);
}
-int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset,
- kernel_lb_addr eloc, uint32_t elen, struct buffer_head *nbh)
+int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
+ kernel_lb_addr eloc, uint32_t elen)
{
- struct buffer_head *obh;
- kernel_lb_addr obloc;
- int oextoffset, adsize;
+ struct extent_position oepos;
+ int adsize;
int8_t etype;
struct allocExtDesc *aed;
- if (nbh)
+ if (epos.bh)
{
- atomic_inc(&nbh->b_count);
- atomic_inc(&nbh->b_count);
+ get_bh(epos.bh);
+ get_bh(epos.bh);
}
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
@@ -1878,80 +1998,77 @@ int8_t udf_delete_aext(struct inode *inode, kernel_lb_addr nbloc, int nextoffset
else
adsize = 0;
- obh = nbh;
- obloc = nbloc;
- oextoffset = nextoffset;
-
- if (udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1) == -1)
+ oepos = epos;
+ if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1)
return -1;
- while ((etype = udf_next_aext(inode, &nbloc, &nextoffset, &eloc, &elen, &nbh, 1)) != -1)
+ while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1)
{
- udf_write_aext(inode, obloc, &oextoffset, eloc, (etype << 30) | elen, obh, 1);
- if (obh != nbh)
+ udf_write_aext(inode, &oepos, eloc, (etype << 30) | elen, 1);
+ if (oepos.bh != epos.bh)
{
- obloc = nbloc;
- udf_release_data(obh);
- atomic_inc(&nbh->b_count);
- obh = nbh;
- oextoffset = nextoffset - adsize;
+ oepos.block = epos.block;
+ brelse(oepos.bh);
+ get_bh(epos.bh);
+ oepos.bh = epos.bh;
+ oepos.offset = epos.offset - adsize;
}
}
memset(&eloc, 0x00, sizeof(kernel_lb_addr));
elen = 0;
- if (nbh != obh)
+ if (epos.bh != oepos.bh)
{
- udf_free_blocks(inode->i_sb, inode, nbloc, 0, 1);
- udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
- udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
- if (!obh)
+ udf_free_blocks(inode->i_sb, inode, epos.block, 0, 1);
+ udf_write_aext(inode, &oepos, eloc, elen, 1);
+ udf_write_aext(inode, &oepos, eloc, elen, 1);
+ if (!oepos.bh)
{
UDF_I_LENALLOC(inode) -= (adsize * 2);
mark_inode_dirty(inode);
}
else
{
- aed = (struct allocExtDesc *)(obh)->b_data;
+ aed = (struct allocExtDesc *)oepos.bh->b_data;
aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize));
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
- udf_update_tag((obh)->b_data, oextoffset - (2*adsize));
+ udf_update_tag(oepos.bh->b_data, oepos.offset - (2*adsize));
else
- udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc));
- mark_buffer_dirty_inode(obh, inode);
+ udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc));
+ mark_buffer_dirty_inode(oepos.bh, inode);
}
}
else
{
- udf_write_aext(inode, obloc, &oextoffset, eloc, elen, obh, 1);
- if (!obh)
+ udf_write_aext(inode, &oepos, eloc, elen, 1);
+ if (!oepos.bh)
{
UDF_I_LENALLOC(inode) -= adsize;
mark_inode_dirty(inode);
}
else
{
- aed = (struct allocExtDesc *)(obh)->b_data;
+ aed = (struct allocExtDesc *)oepos.bh->b_data;
aed->lengthAllocDescs =
cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize);
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
- udf_update_tag((obh)->b_data, oextoffset - adsize);
+ udf_update_tag(oepos.bh->b_data, epos.offset - adsize);
else
- udf_update_tag((obh)->b_data, sizeof(struct allocExtDesc));
- mark_buffer_dirty_inode(obh, inode);
+ udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc));
+ mark_buffer_dirty_inode(oepos.bh, inode);
}
}
- udf_release_data(nbh);
- udf_release_data(obh);
+ brelse(epos.bh);
+ brelse(oepos.bh);
return (elen >> 30);
}
-int8_t inode_bmap(struct inode *inode, int block, kernel_lb_addr *bloc, uint32_t *extoffset,
- kernel_lb_addr *eloc, uint32_t *elen, uint32_t *offset, struct buffer_head **bh)
+int8_t inode_bmap(struct inode *inode, sector_t block, struct extent_position *pos,
+ kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset)
{
- uint64_t lbcount = 0, bcount = (uint64_t)block << inode->i_sb->s_blocksize_bits;
+ loff_t lbcount = 0, bcount = (loff_t)block << inode->i_sb->s_blocksize_bits;
int8_t etype;
if (block < 0)
@@ -1960,42 +2077,44 @@ int8_t inode_bmap(struct inode *inode, int block, kernel_lb_addr *bloc, uint32_t
return -1;
}
- *extoffset = 0;
+ pos->offset = 0;
+ pos->block = UDF_I_LOCATION(inode);
+ pos->bh = NULL;
*elen = 0;
- *bloc = UDF_I_LOCATION(inode);
do
{
- if ((etype = udf_next_aext(inode, bloc, extoffset, eloc, elen, bh, 1)) == -1)
+ if ((etype = udf_next_aext(inode, pos, eloc, elen, 1)) == -1)
{
- *offset = bcount - lbcount;
+ *offset = (bcount - lbcount) >> inode->i_sb->s_blocksize_bits;
UDF_I_LENEXTENTS(inode) = lbcount;
return -1;
}
lbcount += *elen;
} while (lbcount <= bcount);
- *offset = bcount + *elen - lbcount;
+ *offset = (bcount + *elen - lbcount) >> inode->i_sb->s_blocksize_bits;
return etype;
}
-long udf_block_map(struct inode *inode, long block)
+long udf_block_map(struct inode *inode, sector_t block)
{
- kernel_lb_addr eloc, bloc;
- uint32_t offset, extoffset, elen;
- struct buffer_head *bh = NULL;
+ kernel_lb_addr eloc;
+ uint32_t elen;
+ sector_t offset;
+ struct extent_position epos = { NULL, 0, { 0, 0}};
int ret;
lock_kernel();
- if (inode_bmap(inode, block, &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
- ret = udf_get_lb_pblock(inode->i_sb, eloc, offset >> inode->i_sb->s_blocksize_bits);
+ if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
+ ret = udf_get_lb_pblock(inode->i_sb, eloc, offset);
else
ret = 0;
unlock_kernel();
- udf_release_data(bh);
+ brelse(epos.bh);
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
return udf_fixed_to_variable(ret);
diff --git a/fs/udf/misc.c b/fs/udf/misc.c
index cc8ca32..a2b2a98 100644
--- a/fs/udf/misc.c
+++ b/fs/udf/misc.c
@@ -274,12 +274,6 @@ udf_read_ptagged(struct super_block *sb, kernel_lb_addr loc, uint32_t offset, ui
loc.logicalBlockNum + offset, ident);
}
-void udf_release_data(struct buffer_head *bh)
-{
- if (bh)
- brelse(bh);
-}
-
void udf_update_tag(char *data, int length)
{
tag *tptr = (tag *)data;
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index fe361cd..91df492 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -155,9 +155,10 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
uint8_t lfi;
uint16_t liu;
loff_t size;
- kernel_lb_addr bloc, eloc;
- uint32_t extoffset, elen, offset;
- struct buffer_head *bh = NULL;
+ kernel_lb_addr eloc;
+ uint32_t elen;
+ sector_t offset;
+ struct extent_position epos = { NULL, 0, { 0, 0}};
size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
f_pos = (udf_ext0_offset(dir) >> 2);
@@ -166,42 +167,41 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh->sbh = fibh->ebh = NULL;
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
- &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
+ &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
{
- offset >>= dir->i_sb->s_blocksize_bits;
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
{
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
- extoffset -= sizeof(short_ad);
+ epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
- extoffset -= sizeof(long_ad);
+ epos.offset -= sizeof(long_ad);
}
else
offset = 0;
if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block)))
{
- udf_release_data(bh);
+ brelse(epos.bh);
return NULL;
}
}
else
{
- udf_release_data(bh);
+ brelse(epos.bh);
return NULL;
}
while ( (f_pos < size) )
{
- fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
+ fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, &elen, &offset);
if (!fi)
{
if (fibh->sbh != fibh->ebh)
- udf_release_data(fibh->ebh);
- udf_release_data(fibh->sbh);
- udf_release_data(bh);
+ brelse(fibh->ebh);
+ brelse(fibh->sbh);
+ brelse(epos.bh);
return NULL;
}
@@ -247,15 +247,15 @@ udf_find_entry(struct inode *dir, struct dentry *dentry,
{
if (udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name))
{
- udf_release_data(bh);
+ brelse(epos.bh);
return fi;
}
}
}
if (fibh->sbh != fibh->ebh)
- udf_release_data(fibh->ebh);
- udf_release_data(fibh->sbh);
- udf_release_data(bh);
+ brelse(fibh->ebh);
+ brelse(fibh->sbh);
+ brelse(epos.bh);
return NULL;
}
@@ -321,8 +321,8 @@ udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
if (udf_find_entry(dir, dentry, &fibh, &cfi))
{
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation));
if ( !inode )
@@ -353,9 +353,10 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
uint8_t lfi;
uint16_t liu;
int block;
- kernel_lb_addr bloc, eloc;
- uint32_t extoffset, elen, offset;
- struct buffer_head *bh = NULL;
+ kernel_lb_addr eloc;
+ uint32_t elen;
+ sector_t offset;
+ struct extent_position epos = { NULL, 0, { 0, 0 }};
sb = dir->i_sb;
@@ -384,23 +385,22 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh->sbh = fibh->ebh = NULL;
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
- &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
+ &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
{
- offset >>= dir->i_sb->s_blocksize_bits;
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
{
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
- extoffset -= sizeof(short_ad);
+ epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
- extoffset -= sizeof(long_ad);
+ epos.offset -= sizeof(long_ad);
}
else
offset = 0;
if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block)))
{
- udf_release_data(bh);
+ brelse(epos.bh);
*err = -EIO;
return NULL;
}
@@ -418,14 +418,14 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
while ( (f_pos < size) )
{
- fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
+ fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc, &elen, &offset);
if (!fi)
{
if (fibh->sbh != fibh->ebh)
- udf_release_data(fibh->ebh);
- udf_release_data(fibh->sbh);
- udf_release_data(bh);
+ brelse(fibh->ebh);
+ brelse(fibh->sbh);
+ brelse(epos.bh);
*err = -EIO;
return NULL;
}
@@ -455,7 +455,7 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
{
if (((sizeof(struct fileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen)
{
- udf_release_data(bh);
+ brelse(epos.bh);
cfi->descTag.tagSerialNum = cpu_to_le16(1);
cfi->fileVersionNum = cpu_to_le16(1);
cfi->fileCharacteristics = 0;
@@ -478,9 +478,9 @@ udf_add_entry(struct inode *dir, struct dentry *dentry,
udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name))
{
if (fibh->sbh != fibh->ebh)
- udf_release_data(fibh->ebh);
- udf_release_data(fibh->sbh);
- udf_release_data(bh);
+ brelse(fibh->ebh);
+ brelse(fibh->sbh);
+ brelse(epos.bh);
*err = -EEXIST;
return NULL;
}
@@ -492,25 +492,25 @@ add:
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB &&
sb->s_blocksize - fibh->eoffset < nfidlen)
{
- udf_release_data(bh);
- bh = NULL;
+ brelse(epos.bh);
+ epos.bh = NULL;
fibh->soffset -= udf_ext0_offset(dir);
fibh->eoffset -= udf_ext0_offset(dir);
f_pos -= (udf_ext0_offset(dir) >> 2);
if (fibh->sbh != fibh->ebh)
- udf_release_data(fibh->ebh);
- udf_release_data(fibh->sbh);
+ brelse(fibh->ebh);
+ brelse(fibh->sbh);
if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err)))
return NULL;
- bloc = UDF_I_LOCATION(dir);
+ epos.block = UDF_I_LOCATION(dir);
eloc.logicalBlockNum = block;
eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum;
elen = dir->i_sb->s_blocksize;
- extoffset = udf_file_entry_alloc_offset(dir);
+ epos.offset = udf_file_entry_alloc_offset(dir);
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
- extoffset += sizeof(short_ad);
+ epos.offset += sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
- extoffset += sizeof(long_ad);
+ epos.offset += sizeof(long_ad);
}
if (sb->s_blocksize - fibh->eoffset >= nfidlen)
@@ -519,7 +519,7 @@ add:
fibh->eoffset += nfidlen;
if (fibh->sbh != fibh->ebh)
{
- udf_release_data(fibh->sbh);
+ brelse(fibh->sbh);
fibh->sbh = fibh->ebh;
}
@@ -541,7 +541,7 @@ add:
fibh->eoffset += nfidlen - sb->s_blocksize;
if (fibh->sbh != fibh->ebh)
{
- udf_release_data(fibh->sbh);
+ brelse(fibh->sbh);
fibh->sbh = fibh->ebh;
}
@@ -550,14 +550,14 @@ add:
if (!(fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err)))
{
- udf_release_data(bh);
- udf_release_data(fibh->sbh);
+ brelse(epos.bh);
+ brelse(fibh->sbh);
return NULL;
}
if (!(fibh->soffset))
{
- if (udf_next_aext(dir, &bloc, &extoffset, &eloc, &elen, &bh, 1) ==
+ if (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
(EXT_RECORDED_ALLOCATED >> 30))
{
block = eloc.logicalBlockNum + ((elen - 1) >>
@@ -566,7 +566,7 @@ add:
else
block ++;
- udf_release_data(fibh->sbh);
+ brelse(fibh->sbh);
fibh->sbh = fibh->ebh;
fi = (struct fileIdentDesc *)(fibh->sbh->b_data);
}
@@ -587,7 +587,7 @@ add:
cfi->lengthOfImpUse = cpu_to_le16(0);
if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name))
{
- udf_release_data(bh);
+ brelse(epos.bh);
dir->i_size += nfidlen;
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
UDF_I_LENALLOC(dir) += nfidlen;
@@ -596,10 +596,10 @@ add:
}
else
{
- udf_release_data(bh);
+ brelse(epos.bh);
if (fibh->sbh != fibh->ebh)
- udf_release_data(fibh->ebh);
- udf_release_data(fibh->sbh);
+ brelse(fibh->ebh);
+ brelse(fibh->sbh);
*err = -EIO;
return NULL;
}
@@ -656,8 +656,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, struct
mark_inode_dirty(dir);
}
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
unlock_kernel();
d_instantiate(dentry, inode);
return 0;
@@ -701,8 +701,8 @@ static int udf_mknod(struct inode * dir, struct dentry * dentry, int mode, dev_t
mark_inode_dirty(inode);
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
d_instantiate(dentry, inode);
err = 0;
out:
@@ -743,7 +743,7 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL);
cfi.fileCharacteristics = FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT;
udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL);
- udf_release_data(fibh.sbh);
+ brelse(fibh.sbh);
inode->i_mode = S_IFDIR | mode;
if (dir->i_mode & S_ISGID)
inode->i_mode |= S_ISGID;
@@ -766,8 +766,8 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode)
mark_inode_dirty(dir);
d_instantiate(dentry, inode);
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
err = 0;
out:
unlock_kernel();
@@ -781,9 +781,10 @@ static int empty_dir(struct inode *dir)
loff_t f_pos;
loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
int block;
- kernel_lb_addr bloc, eloc;
- uint32_t extoffset, elen, offset;
- struct buffer_head *bh = NULL;
+ kernel_lb_addr eloc;
+ uint32_t elen;
+ sector_t offset;
+ struct extent_position epos = { NULL, 0, { 0, 0}};
f_pos = (udf_ext0_offset(dir) >> 2);
@@ -792,59 +793,58 @@ static int empty_dir(struct inode *dir)
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
fibh.sbh = fibh.ebh = NULL;
else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
- &bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
+ &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
{
- offset >>= dir->i_sb->s_blocksize_bits;
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
{
if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
- extoffset -= sizeof(short_ad);
+ epos.offset -= sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
- extoffset -= sizeof(long_ad);
+ epos.offset -= sizeof(long_ad);
}
else
offset = 0;
if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block)))
{
- udf_release_data(bh);
+ brelse(epos.bh);
return 0;
}
}
else
{
- udf_release_data(bh);
+ brelse(epos.bh);
return 0;
}
while ( (f_pos < size) )
{
- fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
+ fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset);
if (!fi)
{
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
- udf_release_data(bh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
+ brelse(epos.bh);
return 0;
}
if (cfi.lengthFileIdent && (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0)
{
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
- udf_release_data(bh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
+ brelse(epos.bh);
return 0;
}
}
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
- udf_release_data(bh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
+ brelse(epos.bh);
return 1;
}
@@ -878,14 +878,14 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry)
inode->i_nlink);
clear_nlink(inode);
inode->i_size = 0;
- inode_dec_link_count(inode);
+ inode_dec_link_count(dir);
inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
mark_inode_dirty(dir);
end_rmdir:
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
out:
unlock_kernel();
return retval;
@@ -928,8 +928,8 @@ static int udf_unlink(struct inode * dir, struct dentry * dentry)
end_unlink:
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
out:
unlock_kernel();
return retval;
@@ -941,7 +941,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
struct pathComponent *pc;
char *compstart;
struct udf_fileident_bh fibh;
- struct buffer_head *bh = NULL;
+ struct extent_position epos = { NULL, 0, {0, 0}};
int eoffset, elen = 0;
struct fileIdentDesc *fi;
struct fileIdentDesc cfi;
@@ -961,33 +961,33 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
if (UDF_I_ALLOCTYPE(inode) != ICBTAG_FLAG_AD_IN_ICB)
{
- struct buffer_head *bh = NULL;
- kernel_lb_addr bloc, eloc;
- uint32_t elen, extoffset;
+ kernel_lb_addr eloc;
+ uint32_t elen;
block = udf_new_block(inode->i_sb, inode,
UDF_I_LOCATION(inode).partitionReferenceNum,
UDF_I_LOCATION(inode).logicalBlockNum, &err);
if (!block)
goto out_no_entry;
- bloc = UDF_I_LOCATION(inode);
+ epos.block = UDF_I_LOCATION(inode);
+ epos.offset = udf_file_entry_alloc_offset(inode);
+ epos.bh = NULL;
eloc.logicalBlockNum = block;
eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
elen = inode->i_sb->s_blocksize;
UDF_I_LENEXTENTS(inode) = elen;
- extoffset = udf_file_entry_alloc_offset(inode);
- udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 0);
- udf_release_data(bh);
+ udf_add_aext(inode, &epos, eloc, elen, 0);
+ brelse(epos.bh);
block = udf_get_pblock(inode->i_sb, block,
UDF_I_LOCATION(inode).partitionReferenceNum, 0);
- bh = udf_tread(inode->i_sb, block);
- lock_buffer(bh);
- memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
- set_buffer_uptodate(bh);
- unlock_buffer(bh);
- mark_buffer_dirty_inode(bh, inode);
- ea = bh->b_data + udf_ext0_offset(inode);
+ epos.bh = udf_tread(inode->i_sb, block);
+ lock_buffer(epos.bh);
+ memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize);
+ set_buffer_uptodate(epos.bh);
+ unlock_buffer(epos.bh);
+ mark_buffer_dirty_inode(epos.bh, inode);
+ ea = epos.bh->b_data + udf_ext0_offset(inode);
}
else
ea = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
@@ -1060,7 +1060,7 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
}
}
- udf_release_data(bh);
+ brelse(epos.bh);
inode->i_size = elen;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
UDF_I_LENALLOC(inode) = inode->i_size;
@@ -1089,8 +1089,8 @@ static int udf_symlink(struct inode * dir, struct dentry * dentry, const char *
mark_inode_dirty(dir);
}
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
d_instantiate(dentry, inode);
err = 0;
@@ -1145,8 +1145,8 @@ static int udf_link(struct dentry * old_dentry, struct inode * dir,
mark_inode_dirty(dir);
}
if (fibh.sbh != fibh.ebh)
- udf_release_data(fibh.ebh);
- udf_release_data(fibh.sbh);
+ brelse(fibh.ebh);
+ brelse(fibh.sbh);
inc_nlink(inode);
inode->i_ctime = current_fs_time(inode->i_sb);
mark_inode_dirty(inode);
@@ -1174,8 +1174,8 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
if ((ofi = udf_find_entry(old_dir, old_dentry, &ofibh, &ocfi)))
{
if (ofibh.sbh != ofibh.ebh)
- udf_release_data(ofibh.ebh);
- udf_release_data(ofibh.sbh);
+ brelse(ofibh.ebh);
+ brelse(ofibh.sbh);
}
tloc = lelb_to_cpu(ocfi.icb.extLocation);
if (!ofi || udf_get_lb_pblock(old_dir->i_sb, tloc, 0)
@@ -1188,8 +1188,8 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
if (!new_inode)
{
if (nfibh.sbh != nfibh.ebh)
- udf_release_data(nfibh.ebh);
- udf_release_data(nfibh.sbh);
+ brelse(nfibh.ebh);
+ brelse(nfibh.sbh);
nfi = NULL;
}
}
@@ -1290,19 +1290,19 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
if (ofi)
{
if (ofibh.sbh != ofibh.ebh)
- udf_release_data(ofibh.ebh);
- udf_release_data(ofibh.sbh);
+ brelse(ofibh.ebh);
+ brelse(ofibh.sbh);
}
retval = 0;
end_rename:
- udf_release_data(dir_bh);
+ brelse(dir_bh);
if (nfi)
{
if (nfibh.sbh != nfibh.ebh)
- udf_release_data(nfibh.ebh);
- udf_release_data(nfibh.sbh);
+ brelse(nfibh.ebh);
+ brelse(nfibh.sbh);
}
unlock_kernel();
return retval;
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
index dabf2b8..467a261 100644
--- a/fs/udf/partition.c
+++ b/fs/udf/partition.c
@@ -81,7 +81,7 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, uint16_t
loc = le32_to_cpu(((__le32 *)bh->b_data)[index]);
- udf_release_data(bh);
+ brelse(bh);
if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition)
{
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 8672b88..9b8644a 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -134,9 +134,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct udf_inode_info *ei = (struct udf_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
- {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
ei->i_ext.i_data = NULL;
inode_init_once(&ei->vfs_inode);
}
@@ -565,7 +563,7 @@ udf_vrs(struct super_block *sb, int silent)
if (vsd->stdIdent[0] == 0)
{
- udf_release_data(bh);
+ brelse(bh);
break;
}
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN))
@@ -598,7 +596,7 @@ udf_vrs(struct super_block *sb, int silent)
}
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN))
{
- udf_release_data(bh);
+ brelse(bh);
break;
}
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN))
@@ -609,7 +607,7 @@ udf_vrs(struct super_block *sb, int silent)
{
nsr03 = sector;
}
- udf_release_data(bh);
+ brelse(bh);
}
if (nsr03)
@@ -675,7 +673,7 @@ udf_find_anchor(struct super_block *sb)
{
ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
- udf_release_data(bh);
+ brelse(bh);
}
if (ident == TAG_IDENT_AVDP)
@@ -710,7 +708,7 @@ udf_find_anchor(struct super_block *sb)
{
ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
- udf_release_data(bh);
+ brelse(bh);
}
if (ident == TAG_IDENT_AVDP &&
@@ -729,7 +727,7 @@ udf_find_anchor(struct super_block *sb)
{
ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
- udf_release_data(bh);
+ brelse(bh);
}
if (ident == TAG_IDENT_AVDP &&
@@ -751,7 +749,7 @@ udf_find_anchor(struct super_block *sb)
{
ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
- udf_release_data(bh);
+ brelse(bh);
if (ident == TAG_IDENT_AVDP && location == 256)
UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
@@ -768,7 +766,7 @@ udf_find_anchor(struct super_block *sb)
}
else
{
- udf_release_data(bh);
+ brelse(bh);
if ((ident != TAG_IDENT_AVDP) && (i ||
(ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE)))
{
@@ -797,7 +795,7 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr
return 1;
else if (ident != TAG_IDENT_FSD)
{
- udf_release_data(bh);
+ brelse(bh);
return 1;
}
@@ -836,7 +834,7 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr
newfileset.logicalBlockNum += 1 +
((le32_to_cpu(sp->numOfBytes) + sizeof(struct spaceBitmapDesc) - 1)
>> sb->s_blocksize_bits);
- udf_release_data(bh);
+ brelse(bh);
break;
}
case TAG_IDENT_FSD:
@@ -847,7 +845,7 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr
default:
{
newfileset.logicalBlockNum ++;
- udf_release_data(bh);
+ brelse(bh);
bh = NULL;
break;
}
@@ -867,7 +865,7 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr
UDF_SB_PARTITION(sb) = fileset->partitionReferenceNum;
udf_load_fileset(sb, bh, root);
- udf_release_data(bh);
+ brelse(bh);
return 0;
}
return 1;
@@ -1085,7 +1083,7 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head * bh, kernel_lb_a
if (ident != 0 ||
strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)))
{
- udf_release_data(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]);
+ brelse(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]);
UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = NULL;
}
}
@@ -1139,12 +1137,12 @@ udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc)
udf_load_logicalvolint(sb, leea_to_cpu(UDF_SB_LVID(sb)->nextIntegrityExt));
if (UDF_SB_LVIDBH(sb) != bh)
- udf_release_data(bh);
+ brelse(bh);
loc.extLength -= sb->s_blocksize;
loc.extLocation ++;
}
if (UDF_SB_LVIDBH(sb) != bh)
- udf_release_data(bh);
+ brelse(bh);
}
/*
@@ -1247,7 +1245,7 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_
done = 1;
break;
}
- udf_release_data(bh);
+ brelse(bh);
}
for (i=0; i<VDS_POS_LENGTH; i++)
{
@@ -1269,10 +1267,10 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock, kernel_
gd = (struct generic_desc *)bh2->b_data;
if (ident == TAG_IDENT_PD)
udf_load_partdesc(sb, bh2);
- udf_release_data(bh2);
+ brelse(bh2);
}
}
- udf_release_data(bh);
+ brelse(bh);
}
}
@@ -1335,7 +1333,7 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
reserve_e = reserve_e >> sb->s_blocksize_bits;
reserve_e += reserve_s;
- udf_release_data(bh);
+ brelse(bh);
/* Process the main & reserve sequences */
/* responsible for finding the PartitionDesc(s) */
@@ -1405,12 +1403,14 @@ udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
pos = udf_block_map(UDF_SB_VAT(sb), 0);
bh = sb_bread(sb, pos);
+ if (!bh)
+ return 1;
UDF_SB_TYPEVIRT(sb,i).s_start_offset =
le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) +
udf_ext0_offset(UDF_SB_VAT(sb));
UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size -
UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2;
- udf_release_data(bh);
+ brelse(bh);
}
UDF_SB_PARTROOT(sb,i) = udf_get_pblock(sb, 0, i, 0);
UDF_SB_PARTLEN(sb,i) = UDF_SB_PARTLEN(sb,ino.partitionReferenceNum);
@@ -1663,7 +1663,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
iput(inode);
goto error_out;
}
- sb->s_maxbytes = 1<<30;
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
return 0;
error_out:
@@ -1682,7 +1682,7 @@ error_out:
if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
{
for (i=0; i<4; i++)
- udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
+ brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
}
}
#ifdef CONFIG_UDF_NLS
@@ -1691,7 +1691,7 @@ error_out:
#endif
if (!(sb->s_flags & MS_RDONLY))
udf_close_lvid(sb);
- udf_release_data(UDF_SB_LVIDBH(sb));
+ brelse(UDF_SB_LVIDBH(sb));
UDF_SB_FREE(sb);
kfree(sbi);
sb->s_fs_info = NULL;
@@ -1760,7 +1760,7 @@ udf_put_super(struct super_block *sb)
if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
{
for (i=0; i<4; i++)
- udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
+ brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
}
}
#ifdef CONFIG_UDF_NLS
@@ -1769,7 +1769,7 @@ udf_put_super(struct super_block *sb)
#endif
if (!(sb->s_flags & MS_RDONLY))
udf_close_lvid(sb);
- udf_release_data(UDF_SB_LVIDBH(sb));
+ brelse(UDF_SB_LVIDBH(sb));
UDF_SB_FREE(sb);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
@@ -1839,7 +1839,7 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
}
else if (ident != TAG_IDENT_SBD)
{
- udf_release_data(bh);
+ brelse(bh);
printk(KERN_ERR "udf: udf_count_free failed\n");
goto out;
}
@@ -1861,7 +1861,7 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
}
if ( bytes )
{
- udf_release_data(bh);
+ brelse(bh);
newblock = udf_get_lb_pblock(sb, loc, ++block);
bh = udf_tread(sb, newblock);
if (!bh)
@@ -1873,7 +1873,7 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
ptr = (uint8_t *)bh->b_data;
}
}
- udf_release_data(bh);
+ brelse(bh);
out:
unlock_kernel();
@@ -1885,21 +1885,20 @@ static unsigned int
udf_count_free_table(struct super_block *sb, struct inode * table)
{
unsigned int accum = 0;
- uint32_t extoffset, elen;
- kernel_lb_addr bloc, eloc;
+ uint32_t elen;
+ kernel_lb_addr eloc;
int8_t etype;
- struct buffer_head *bh = NULL;
+ struct extent_position epos;
lock_kernel();
- bloc = UDF_I_LOCATION(table);
- extoffset = sizeof(struct unallocSpaceEntry);
+ epos.block = UDF_I_LOCATION(table);
+ epos.offset = sizeof(struct unallocSpaceEntry);
+ epos.bh = NULL;
- while ((etype = udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
- {
+ while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
accum += (elen >> table->i_sb->s_blocksize_bits);
- }
- udf_release_data(bh);
+ brelse(epos.bh);
unlock_kernel();
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
index ba068a7..12613b6 100644
--- a/fs/udf/symlink.c
+++ b/fs/udf/symlink.c
@@ -95,7 +95,7 @@ static int udf_symlink_filler(struct file *file, struct page *page)
}
udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p);
- udf_release_data(bh);
+ brelse(bh);
unlock_kernel();
SetPageUptodate(page);
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
index 0abd66c..77975ae 100644
--- a/fs/udf/truncate.c
+++ b/fs/udf/truncate.c
@@ -28,8 +28,8 @@
#include "udf_i.h"
#include "udf_sb.h"
-static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffset,
- kernel_lb_addr eloc, int8_t etype, uint32_t elen, struct buffer_head *bh, uint32_t nelen)
+static void extent_trunc(struct inode * inode, struct extent_position *epos,
+ kernel_lb_addr eloc, int8_t etype, uint32_t elen, uint32_t nelen)
{
kernel_lb_addr neloc = { 0, 0 };
int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
@@ -49,7 +49,7 @@ static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffse
if (elen != nelen)
{
- udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0);
+ udf_write_aext(inode, epos, neloc, nelen, 0);
if (last_block - first_block > 0)
{
if (etype == (EXT_RECORDED_ALLOCATED >> 30))
@@ -63,18 +63,16 @@ static void extent_trunc(struct inode * inode, kernel_lb_addr bloc, int extoffse
void udf_discard_prealloc(struct inode * inode)
{
- kernel_lb_addr bloc, eloc;
- uint32_t extoffset = 0, elen, nelen;
+ struct extent_position epos = { NULL, 0, {0, 0}};
+ kernel_lb_addr eloc;
+ uint32_t elen, nelen;
uint64_t lbcount = 0;
int8_t etype = -1, netype;
- struct buffer_head *bh = NULL;
int adsize;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB ||
inode->i_size == UDF_I_LENEXTENTS(inode))
- {
return;
- }
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
adsize = sizeof(short_ad);
@@ -83,52 +81,58 @@ void udf_discard_prealloc(struct inode * inode)
else
adsize = 0;
- bloc = UDF_I_LOCATION(inode);
+ epos.block = UDF_I_LOCATION(inode);
- while ((netype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
+ /* Find the last extent in the file */
+ while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1)
{
etype = netype;
lbcount += elen;
- if (lbcount > inode->i_size && lbcount - inode->i_size < inode->i_sb->s_blocksize)
+ if (lbcount > inode->i_size && lbcount - elen < inode->i_size)
{
+ WARN_ON(lbcount - inode->i_size >= inode->i_sb->s_blocksize);
nelen = elen - (lbcount - inode->i_size);
- extent_trunc(inode, bloc, extoffset-adsize, eloc, etype, elen, bh, nelen);
+ epos.offset -= adsize;
+ extent_trunc(inode, &epos, eloc, etype, elen, nelen);
+ epos.offset += adsize;
lbcount = inode->i_size;
}
}
- if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
- {
- extoffset -= adsize;
+ if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
+ epos.offset -= adsize;
lbcount -= elen;
- extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0);
- if (!bh)
+ extent_trunc(inode, &epos, eloc, etype, elen, 0);
+ if (!epos.bh)
{
- UDF_I_LENALLOC(inode) = extoffset - udf_file_entry_alloc_offset(inode);
+ UDF_I_LENALLOC(inode) = epos.offset - udf_file_entry_alloc_offset(inode);
mark_inode_dirty(inode);
}
else
{
- struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data);
- aed->lengthAllocDescs = cpu_to_le32(extoffset - sizeof(struct allocExtDesc));
+ struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data);
+ aed->lengthAllocDescs = cpu_to_le32(epos.offset - sizeof(struct allocExtDesc));
if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
- udf_update_tag(bh->b_data, extoffset);
+ udf_update_tag(epos.bh->b_data, epos.offset);
else
- udf_update_tag(bh->b_data, sizeof(struct allocExtDesc));
- mark_buffer_dirty_inode(bh, inode);
+ udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc));
+ mark_buffer_dirty_inode(epos.bh, inode);
}
}
UDF_I_LENEXTENTS(inode) = lbcount;
- udf_release_data(bh);
+ WARN_ON(lbcount != inode->i_size);
+ brelse(epos.bh);
}
void udf_truncate_extents(struct inode * inode)
{
- kernel_lb_addr bloc, eloc, neloc = { 0, 0 };
- uint32_t extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc;
+ struct extent_position epos;
+ kernel_lb_addr eloc, neloc = { 0, 0 };
+ uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc;
int8_t etype;
- int first_block = inode->i_size >> inode->i_sb->s_blocksize_bits;
- struct buffer_head *bh = NULL;
+ struct super_block *sb = inode->i_sb;
+ sector_t first_block = inode->i_size >> sb->s_blocksize_bits, offset;
+ loff_t byte_offset;
int adsize;
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
@@ -136,158 +140,130 @@ void udf_truncate_extents(struct inode * inode)
else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
adsize = sizeof(long_ad);
else
- adsize = 0;
+ BUG();
- etype = inode_bmap(inode, first_block, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
- offset += (inode->i_size & (inode->i_sb->s_blocksize - 1));
+ etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset);
+ byte_offset = (offset << sb->s_blocksize_bits) + (inode->i_size & (sb->s_blocksize-1));
if (etype != -1)
{
- extoffset -= adsize;
- extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, offset);
- extoffset += adsize;
-
- if (offset)
- lenalloc = extoffset;
+ epos.offset -= adsize;
+ extent_trunc(inode, &epos, eloc, etype, elen, byte_offset);
+ epos.offset += adsize;
+ if (byte_offset)
+ lenalloc = epos.offset;
else
- lenalloc = extoffset - adsize;
+ lenalloc = epos.offset - adsize;
- if (!bh)
+ if (!epos.bh)
lenalloc -= udf_file_entry_alloc_offset(inode);
else
lenalloc -= sizeof(struct allocExtDesc);
- while ((etype = udf_current_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 0)) != -1)
+ while ((etype = udf_current_aext(inode, &epos, &eloc, &elen, 0)) != -1)
{
if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30))
{
- udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0);
- extoffset = 0;
- if (lelen)
+ udf_write_aext(inode, &epos, neloc, nelen, 0);
+ if (indirect_ext_len)
{
- if (!bh)
+ /* We managed to free all extents in the
+ * indirect extent - free it too */
+ if (!epos.bh)
BUG();
- else
- memset(bh->b_data, 0x00, sizeof(struct allocExtDesc));
- udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
+ udf_free_blocks(sb, inode, epos.block, 0, indirect_ext_len);
}
else
{
- if (!bh)
+ if (!epos.bh)
{
UDF_I_LENALLOC(inode) = lenalloc;
mark_inode_dirty(inode);
}
else
{
- struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data);
+ struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data);
aed->lengthAllocDescs = cpu_to_le32(lenalloc);
- if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
- udf_update_tag(bh->b_data, lenalloc +
+ if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(sb) >= 0x0201)
+ udf_update_tag(epos.bh->b_data, lenalloc +
sizeof(struct allocExtDesc));
else
- udf_update_tag(bh->b_data, sizeof(struct allocExtDesc));
- mark_buffer_dirty_inode(bh, inode);
+ udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc));
+ mark_buffer_dirty_inode(epos.bh, inode);
}
}
-
- udf_release_data(bh);
- extoffset = sizeof(struct allocExtDesc);
- bloc = eloc;
- bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, bloc, 0));
+ brelse(epos.bh);
+ epos.offset = sizeof(struct allocExtDesc);
+ epos.block = eloc;
+ epos.bh = udf_tread(sb, udf_get_lb_pblock(sb, eloc, 0));
if (elen)
- lelen = (elen + inode->i_sb->s_blocksize - 1) >>
- inode->i_sb->s_blocksize_bits;
+ indirect_ext_len = (elen +
+ sb->s_blocksize - 1) >>
+ sb->s_blocksize_bits;
else
- lelen = 1;
+ indirect_ext_len = 1;
}
else
{
- extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0);
- extoffset += adsize;
+ extent_trunc(inode, &epos, eloc, etype, elen, 0);
+ epos.offset += adsize;
}
}
- if (lelen)
+ if (indirect_ext_len)
{
- if (!bh)
+ if (!epos.bh)
BUG();
- else
- memset(bh->b_data, 0x00, sizeof(struct allocExtDesc));
- udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
+ udf_free_blocks(sb, inode, epos.block, 0, indirect_ext_len);
}
else
{
- if (!bh)
+ if (!epos.bh)
{
UDF_I_LENALLOC(inode) = lenalloc;
mark_inode_dirty(inode);
}
else
{
- struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data);
+ struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data);
aed->lengthAllocDescs = cpu_to_le32(lenalloc);
- if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
- udf_update_tag(bh->b_data, lenalloc +
+ if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(sb) >= 0x0201)
+ udf_update_tag(epos.bh->b_data, lenalloc +
sizeof(struct allocExtDesc));
else
- udf_update_tag(bh->b_data, sizeof(struct allocExtDesc));
- mark_buffer_dirty_inode(bh, inode);
+ udf_update_tag(epos.bh->b_data, sizeof(struct allocExtDesc));
+ mark_buffer_dirty_inode(epos.bh, inode);
}
}
}
else if (inode->i_size)
{
- if (offset)
+ if (byte_offset)
{
+ kernel_long_ad extent;
+
/*
* OK, there is not extent covering inode->i_size and
* no extent above inode->i_size => truncate is
- * extending the file by 'offset'.
+ * extending the file by 'offset' blocks.
*/
- if ((!bh && extoffset == udf_file_entry_alloc_offset(inode)) ||
- (bh && extoffset == sizeof(struct allocExtDesc))) {
- /* File has no extents at all! */
- memset(&eloc, 0x00, sizeof(kernel_lb_addr));
- elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
- udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
+ if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) ||
+ (epos.bh && epos.offset == sizeof(struct allocExtDesc))) {
+ /* File has no extents at all or has empty last
+ * indirect extent! Create a fake extent... */
+ extent.extLocation.logicalBlockNum = 0;
+ extent.extLocation.partitionReferenceNum = 0;
+ extent.extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
}
else {
- extoffset -= adsize;
- etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1);
- if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
- {
- extoffset -= adsize;
- elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset);
- udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
- }
- else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
- {
- kernel_lb_addr neloc = { 0, 0 };
- extoffset -= adsize;
- nelen = EXT_NOT_RECORDED_NOT_ALLOCATED |
- ((elen + offset + inode->i_sb->s_blocksize - 1) &
- ~(inode->i_sb->s_blocksize - 1));
- udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
- udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1);
- }
- else
- {
- if (elen & (inode->i_sb->s_blocksize - 1))
- {
- extoffset -= adsize;
- elen = EXT_RECORDED_ALLOCATED |
- ((elen + inode->i_sb->s_blocksize - 1) &
- ~(inode->i_sb->s_blocksize - 1));
- udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
- }
- memset(&eloc, 0x00, sizeof(kernel_lb_addr));
- elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
- udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
- }
+ epos.offset -= adsize;
+ etype = udf_next_aext(inode, &epos,
+ &extent.extLocation, &extent.extLength, 0);
+ extent.extLength |= etype << 30;
}
+ udf_extend_file(inode, &epos, &extent, offset+((inode->i_size & (sb->s_blocksize-1)) != 0));
}
}
UDF_I_LENEXTENTS(inode) = inode->i_size;
- udf_release_data(bh);
+ brelse(epos.bh);
}
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 110f8d6..3b2e6c8 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -93,7 +93,7 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
for (i=0; i<nr_groups; i++)\
{\
if (UDF_SB_BITMAP(X,Y,Z,i))\
- udf_release_data(UDF_SB_BITMAP(X,Y,Z,i));\
+ brelse(UDF_SB_BITMAP(X,Y,Z,i));\
}\
if (size <= PAGE_SIZE)\
kfree(UDF_SB_PARTMAPS(X)[Y].Z.s_bitmap);\
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index ee1dece..67ded28 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -77,6 +77,13 @@ struct ustr
uint8_t u_len;
};
+struct extent_position {
+ struct buffer_head *bh;
+ uint32_t offset;
+ kernel_lb_addr block;
+};
+
+
/* super.c */
extern void udf_error(struct super_block *, const char *, const char *, ...);
extern void udf_warning(struct super_block *, const char *, const char *, ...);
@@ -98,13 +105,14 @@ extern void udf_read_inode(struct inode *);
extern void udf_delete_inode(struct inode *);
extern void udf_clear_inode(struct inode *);
extern int udf_write_inode(struct inode *, int);
-extern long udf_block_map(struct inode *, long);
-extern int8_t inode_bmap(struct inode *, int, kernel_lb_addr *, uint32_t *, kernel_lb_addr *, uint32_t *, uint32_t *, struct buffer_head **);
-extern int8_t udf_add_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr, uint32_t, struct buffer_head **, int);
-extern int8_t udf_write_aext(struct inode *, kernel_lb_addr, int *, kernel_lb_addr, uint32_t, struct buffer_head *, int);
-extern int8_t udf_delete_aext(struct inode *, kernel_lb_addr, int, kernel_lb_addr, uint32_t, struct buffer_head *);
-extern int8_t udf_next_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr *, uint32_t *, struct buffer_head **, int);
-extern int8_t udf_current_aext(struct inode *, kernel_lb_addr *, int *, kernel_lb_addr *, uint32_t *, struct buffer_head **, int);
+extern long udf_block_map(struct inode *, sector_t);
+extern int udf_extend_file(struct inode *, struct extent_position *, kernel_long_ad *, sector_t);
+extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, kernel_lb_addr *, uint32_t *, sector_t *);
+extern int8_t udf_add_aext(struct inode *, struct extent_position *, kernel_lb_addr, uint32_t, int);
+extern int8_t udf_write_aext(struct inode *, struct extent_position *, kernel_lb_addr, uint32_t, int);
+extern int8_t udf_delete_aext(struct inode *, struct extent_position, kernel_lb_addr, uint32_t);
+extern int8_t udf_next_aext(struct inode *, struct extent_position *, kernel_lb_addr *, uint32_t *, int);
+extern int8_t udf_current_aext(struct inode *, struct extent_position *, kernel_lb_addr *, uint32_t *, int);
/* misc.c */
extern struct buffer_head *udf_tgetblk(struct super_block *, int);
@@ -113,7 +121,6 @@ extern struct genericFormat *udf_add_extendedattr(struct inode *, uint32_t, uint
extern struct genericFormat *udf_get_extendedattr(struct inode *, uint32_t, uint8_t);
extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t, uint32_t, uint16_t *);
extern struct buffer_head *udf_read_ptagged(struct super_block *, kernel_lb_addr, uint32_t, uint16_t *);
-extern void udf_release_data(struct buffer_head *);
extern void udf_update_tag(char *, int);
extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int);
@@ -151,7 +158,7 @@ extern int udf_new_block(struct super_block *, struct inode *, uint16_t, uint32_
extern int udf_fsync_file(struct file *, struct dentry *, int);
/* directory.c */
-extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, kernel_lb_addr *, uint32_t *, kernel_lb_addr *, uint32_t *, uint32_t *, struct buffer_head **);
+extern struct fileIdentDesc * udf_fileident_read(struct inode *, loff_t *, struct udf_fileident_bh *, struct fileIdentDesc *, struct extent_position *, kernel_lb_addr *, uint32_t *, sector_t *);
extern struct fileIdentDesc * udf_get_fileident(void * buffer, int bufsize, int * offset);
extern long_ad * udf_get_filelongad(uint8_t *, int, int *, int);
extern short_ad * udf_get_fileshortad(uint8_t *, int, int *, int);
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 4890ddf..1544521 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -19,7 +19,6 @@
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/ufs_fs.h>
-#include <linux/smp_lock.h>
#include "swab.h"
#include "util.h"
@@ -180,13 +179,9 @@ fail:
static struct page *ufs_get_page(struct inode *dir, unsigned long n)
{
struct address_space *mapping = dir->i_mapping;
- struct page *page = read_cache_page(mapping, n,
- (filler_t*)mapping->a_ops->readpage, NULL);
+ struct page *page = read_mapping_page(mapping, n, NULL);
if (!IS_ERR(page)) {
- wait_on_page_locked(page);
kmap(page);
- if (!PageUptodate(page))
- goto fail;
if (!PageChecked(page))
ufs_check_page(page);
if (PageError(page))
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index b5a6461..be7c48c 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -1237,8 +1237,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag
{
struct ufs_inode_info *ei = (struct ufs_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&ei->vfs_inode);
}
diff --git a/fs/ufs/util.c b/fs/ufs/util.c
index 1743757..84357f1 100644
--- a/fs/ufs/util.c
+++ b/fs/ufs/util.c
@@ -251,13 +251,11 @@ struct page *ufs_get_locked_page(struct address_space *mapping,
page = find_lock_page(mapping, index);
if (!page) {
- page = read_cache_page(mapping, index,
- (filler_t*)mapping->a_ops->readpage,
- NULL);
+ page = read_mapping_page(mapping, index, NULL);
if (IS_ERR(page)) {
printk(KERN_ERR "ufs_change_blocknr: "
- "read_cache_page error: ino %lu, index: %lu\n",
+ "read_mapping_page error: ino %lu, index: %lu\n",
mapping->host->i_ino, index);
goto out;
}
diff --git a/fs/utimes.c b/fs/utimes.c
index 99cf2cb..480f7c8 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -1,8 +1,10 @@
#include <linux/compiler.h>
+#include <linux/file.h>
#include <linux/fs.h>
#include <linux/linkage.h>
#include <linux/namei.h>
#include <linux/sched.h>
+#include <linux/stat.h>
#include <linux/utime.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -20,54 +22,18 @@
* must be owner or have write permission.
* Else, update from *times, must be owner or super user.
*/
-asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times)
+asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times)
{
- int error;
- struct nameidata nd;
- struct inode * inode;
- struct iattr newattrs;
+ struct timespec tv[2];
- error = user_path_walk(filename, &nd);
- if (error)
- goto out;
- inode = nd.dentry->d_inode;
-
- error = -EROFS;
- if (IS_RDONLY(inode))
- goto dput_and_out;
-
- /* Don't worry, the checks are done in inode_change_ok() */
- newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
if (times) {
- error = -EPERM;
- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
- goto dput_and_out;
-
- error = get_user(newattrs.ia_atime.tv_sec, &times->actime);
- newattrs.ia_atime.tv_nsec = 0;
- if (!error)
- error = get_user(newattrs.ia_mtime.tv_sec, &times->modtime);
- newattrs.ia_mtime.tv_nsec = 0;
- if (error)
- goto dput_and_out;
-
- newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
- } else {
- error = -EACCES;
- if (IS_IMMUTABLE(inode))
- goto dput_and_out;
-
- if (current->fsuid != inode->i_uid &&
- (error = vfs_permission(&nd, MAY_WRITE)) != 0)
- goto dput_and_out;
+ if (get_user(tv[0].tv_sec, &times->actime) ||
+ get_user(tv[1].tv_sec, &times->modtime))
+ return -EFAULT;
+ tv[0].tv_nsec = 0;
+ tv[1].tv_nsec = 0;
}
- mutex_lock(&inode->i_mutex);
- error = notify_change(nd.dentry, &newattrs);
- mutex_unlock(&inode->i_mutex);
-dput_and_out:
- path_release(&nd);
-out:
- return error;
+ return do_utimes(AT_FDCWD, filename, times ? tv : NULL, 0);
}
#endif
@@ -76,18 +42,38 @@ out:
* must be owner or have write permission.
* Else, update from *times, must be owner or super user.
*/
-long do_utimes(int dfd, char __user *filename, struct timeval *times)
+long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags)
{
int error;
struct nameidata nd;
- struct inode * inode;
+ struct dentry *dentry;
+ struct inode *inode;
struct iattr newattrs;
+ struct file *f = NULL;
- error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
-
- if (error)
+ error = -EINVAL;
+ if (flags & ~AT_SYMLINK_NOFOLLOW)
goto out;
- inode = nd.dentry->d_inode;
+
+ if (filename == NULL && dfd != AT_FDCWD) {
+ error = -EINVAL;
+ if (flags & AT_SYMLINK_NOFOLLOW)
+ goto out;
+
+ error = -EBADF;
+ f = fget(dfd);
+ if (!f)
+ goto out;
+ dentry = f->f_path.dentry;
+ } else {
+ error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd);
+ if (error)
+ goto out;
+
+ dentry = nd.dentry;
+ }
+
+ inode = dentry->d_inode;
error = -EROFS;
if (IS_RDONLY(inode))
@@ -100,11 +86,21 @@ long do_utimes(int dfd, char __user *filename, struct timeval *times)
if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
goto dput_and_out;
- newattrs.ia_atime.tv_sec = times[0].tv_sec;
- newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000;
- newattrs.ia_mtime.tv_sec = times[1].tv_sec;
- newattrs.ia_mtime.tv_nsec = times[1].tv_usec * 1000;
- newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+ if (times[0].tv_nsec == UTIME_OMIT)
+ newattrs.ia_valid &= ~ATTR_ATIME;
+ else if (times[0].tv_nsec != UTIME_NOW) {
+ newattrs.ia_atime.tv_sec = times[0].tv_sec;
+ newattrs.ia_atime.tv_nsec = times[0].tv_nsec;
+ newattrs.ia_valid |= ATTR_ATIME_SET;
+ }
+
+ if (times[1].tv_nsec == UTIME_OMIT)
+ newattrs.ia_valid &= ~ATTR_MTIME;
+ else if (times[1].tv_nsec != UTIME_NOW) {
+ newattrs.ia_mtime.tv_sec = times[1].tv_sec;
+ newattrs.ia_mtime.tv_nsec = times[1].tv_nsec;
+ newattrs.ia_valid |= ATTR_MTIME_SET;
+ }
} else {
error = -EACCES;
if (IS_IMMUTABLE(inode))
@@ -115,21 +111,67 @@ long do_utimes(int dfd, char __user *filename, struct timeval *times)
goto dput_and_out;
}
mutex_lock(&inode->i_mutex);
- error = notify_change(nd.dentry, &newattrs);
+ error = notify_change(dentry, &newattrs);
mutex_unlock(&inode->i_mutex);
dput_and_out:
- path_release(&nd);
+ if (f)
+ fput(f);
+ else
+ path_release(&nd);
out:
return error;
}
+asmlinkage long sys_utimensat(int dfd, char __user *filename, struct timespec __user *utimes, int flags)
+{
+ struct timespec tstimes[2];
+
+ if (utimes) {
+ if (copy_from_user(&tstimes, utimes, sizeof(tstimes)))
+ return -EFAULT;
+ if ((tstimes[0].tv_nsec == UTIME_OMIT ||
+ tstimes[0].tv_nsec == UTIME_NOW) &&
+ tstimes[0].tv_sec != 0)
+ return -EINVAL;
+ if ((tstimes[1].tv_nsec == UTIME_OMIT ||
+ tstimes[1].tv_nsec == UTIME_NOW) &&
+ tstimes[1].tv_sec != 0)
+ return -EINVAL;
+
+ /* Nothing to do, we must not even check the path. */
+ if (tstimes[0].tv_nsec == UTIME_OMIT &&
+ tstimes[1].tv_nsec == UTIME_OMIT)
+ return 0;
+ }
+
+ return do_utimes(dfd, filename, utimes ? tstimes : NULL, flags);
+}
+
asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __user *utimes)
{
struct timeval times[2];
+ struct timespec tstimes[2];
+
+ if (utimes) {
+ if (copy_from_user(&times, utimes, sizeof(times)))
+ return -EFAULT;
+
+ /* This test is needed to catch all invalid values. If we
+ would test only in do_utimes we would miss those invalid
+ values truncated by the multiplication with 1000. Note
+ that we also catch UTIME_{NOW,OMIT} here which are only
+ valid for utimensat. */
+ if (times[0].tv_usec >= 1000000 || times[0].tv_usec < 0 ||
+ times[1].tv_usec >= 1000000 || times[1].tv_usec < 0)
+ return -EINVAL;
+
+ tstimes[0].tv_sec = times[0].tv_sec;
+ tstimes[0].tv_nsec = 1000 * times[0].tv_usec;
+ tstimes[1].tv_sec = times[1].tv_sec;
+ tstimes[1].tv_nsec = 1000 * times[1].tv_usec;
+ }
- if (utimes && copy_from_user(&times, utimes, sizeof(times)))
- return -EFAULT;
- return do_utimes(dfd, filename, utimes ? times : NULL);
+ return do_utimes(dfd, filename, utimes ? tstimes : NULL, 0);
}
asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes)
diff --git a/fs/xattr.c b/fs/xattr.c
index 3864613..9f4568b 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -9,7 +9,6 @@
*/
#include <linux/fs.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/file.h>
#include <linux/xattr.h>
#include <linux/namei.h>
diff --git a/fs/xfs/linux-2.6/mrlock.h b/fs/xfs/linux-2.6/mrlock.h
index af168a1..c110bb0 100644
--- a/fs/xfs/linux-2.6/mrlock.h
+++ b/fs/xfs/linux-2.6/mrlock.h
@@ -43,6 +43,18 @@ static inline void mrupdate(mrlock_t *mrp)
mrp->mr_writer = 1;
}
+static inline void mraccess_nested(mrlock_t *mrp, int subclass)
+{
+ down_read_nested(&mrp->mr_lock, subclass);
+}
+
+static inline void mrupdate_nested(mrlock_t *mrp, int subclass)
+{
+ down_write_nested(&mrp->mr_lock, subclass);
+ mrp->mr_writer = 1;
+}
+
+
static inline int mrtryaccess(mrlock_t *mrp)
{
return down_read_trylock(&mrp->mr_lock);
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 143ffc8..4475588 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -141,9 +141,46 @@ xfs_destroy_ioend(
}
/*
+ * Update on-disk file size now that data has been written to disk.
+ * The current in-memory file size is i_size. If a write is beyond
+ * eof io_new_size will be the intended file size until i_size is
+ * updated. If this write does not extend all the way to the valid
+ * file size then restrict this update to the end of the write.
+ */
+STATIC void
+xfs_setfilesize(
+ xfs_ioend_t *ioend)
+{
+ xfs_inode_t *ip;
+ xfs_fsize_t isize;
+ xfs_fsize_t bsize;
+
+ ip = xfs_vtoi(ioend->io_vnode);
+
+ ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
+ ASSERT(ioend->io_type != IOMAP_READ);
+
+ if (unlikely(ioend->io_error))
+ return;
+
+ bsize = ioend->io_offset + ioend->io_size;
+
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+
+ isize = MAX(ip->i_size, ip->i_iocore.io_new_size);
+ isize = MIN(isize, bsize);
+
+ if (ip->i_d.di_size < isize) {
+ ip->i_d.di_size = isize;
+ ip->i_update_core = 1;
+ ip->i_update_size = 1;
+ }
+
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+}
+
+/*
* Buffered IO write completion for delayed allocate extents.
- * TODO: Update ondisk isize now that we know the file data
- * has been flushed (i.e. the notorious "NULL file" problem).
*/
STATIC void
xfs_end_bio_delalloc(
@@ -152,6 +189,7 @@ xfs_end_bio_delalloc(
xfs_ioend_t *ioend =
container_of(work, xfs_ioend_t, io_work);
+ xfs_setfilesize(ioend);
xfs_destroy_ioend(ioend);
}
@@ -165,6 +203,7 @@ xfs_end_bio_written(
xfs_ioend_t *ioend =
container_of(work, xfs_ioend_t, io_work);
+ xfs_setfilesize(ioend);
xfs_destroy_ioend(ioend);
}
@@ -184,8 +223,23 @@ xfs_end_bio_unwritten(
xfs_off_t offset = ioend->io_offset;
size_t size = ioend->io_size;
- if (likely(!ioend->io_error))
+ if (likely(!ioend->io_error)) {
bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL);
+ xfs_setfilesize(ioend);
+ }
+ xfs_destroy_ioend(ioend);
+}
+
+/*
+ * IO read completion for regular, written extents.
+ */
+STATIC void
+xfs_end_bio_read(
+ struct work_struct *work)
+{
+ xfs_ioend_t *ioend =
+ container_of(work, xfs_ioend_t, io_work);
+
xfs_destroy_ioend(ioend);
}
@@ -224,6 +278,8 @@ xfs_alloc_ioend(
INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten);
else if (type == IOMAP_DELAY)
INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc);
+ else if (type == IOMAP_READ)
+ INIT_WORK(&ioend->io_work, xfs_end_bio_read);
else
INIT_WORK(&ioend->io_work, xfs_end_bio_written);
@@ -913,7 +969,7 @@ xfs_page_state_convert(
bh = head = page_buffers(page);
offset = page_offset(page);
flags = -1;
- type = 0;
+ type = IOMAP_READ;
/* TODO: cleanup count and page_dirty */
@@ -999,7 +1055,7 @@ xfs_page_state_convert(
* That means it must already have extents allocated
* underneath it. Map the extent by reading it.
*/
- if (!iomap_valid || type != 0) {
+ if (!iomap_valid || type != IOMAP_READ) {
flags = BMAPI_READ;
size = xfs_probe_cluster(inode, page, bh,
head, 1);
@@ -1010,7 +1066,7 @@ xfs_page_state_convert(
iomap_valid = xfs_iomap_valid(&iomap, offset);
}
- type = 0;
+ type = IOMAP_READ;
if (!test_and_set_bit(BH_Lock, &bh->b_state)) {
ASSERT(buffer_mapped(bh));
if (iomap_valid)
@@ -1356,12 +1412,21 @@ xfs_end_io_direct(
* completion handler in the future, in which case all this can
* go away.
*/
- if (private && size > 0) {
- ioend->io_offset = offset;
- ioend->io_size = size;
+ ioend->io_offset = offset;
+ ioend->io_size = size;
+ if (ioend->io_type == IOMAP_READ) {
+ xfs_finish_ioend(ioend);
+ } else if (private && size > 0) {
xfs_finish_ioend(ioend);
} else {
- xfs_destroy_ioend(ioend);
+ /*
+ * A direct I/O write ioend starts it's life in unwritten
+ * state in case they map an unwritten extent. This write
+ * didn't map an unwritten extent so switch it's completion
+ * handler.
+ */
+ INIT_WORK(&ioend->io_work, xfs_end_bio_written);
+ xfs_finish_ioend(ioend);
}
/*
@@ -1392,15 +1457,15 @@ xfs_vm_direct_IO(
if (error)
return -error;
- iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN);
-
if (rw == WRITE) {
+ iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN);
ret = blockdev_direct_IO_own_locking(rw, iocb, inode,
iomap.iomap_target->bt_bdev,
iov, offset, nr_segs,
xfs_get_blocks_direct,
xfs_end_io_direct);
} else {
+ iocb->private = xfs_alloc_ioend(inode, IOMAP_READ);
ret = blockdev_direct_IO_no_locking(rw, iocb, inode,
iomap.iomap_target->bt_bdev,
iov, offset, nr_segs,
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 69e9e80..fe4f66a 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -1426,7 +1426,7 @@ xfs_free_bufhash(
/*
* buftarg list for delwrite queue processing
*/
-LIST_HEAD(xfs_buftarg_list);
+static LIST_HEAD(xfs_buftarg_list);
static DEFINE_SPINLOCK(xfs_buftarg_lock);
STATIC void
@@ -1867,3 +1867,11 @@ xfs_buf_terminate(void)
ktrace_free(xfs_buf_trace_buf);
#endif
}
+
+#ifdef CONFIG_KDB_MODULES
+struct list_head *
+xfs_get_buftarg_list(void)
+{
+ return &xfs_buftarg_list;
+}
+#endif
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index 9e8ef8f..b6241f6 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -411,6 +411,9 @@ extern void xfs_free_buftarg(xfs_buftarg_t *, int);
extern void xfs_wait_buftarg(xfs_buftarg_t *);
extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
+#ifdef CONFIG_KDB_MODULES
+extern struct list_head *xfs_get_buftarg_list(void);
+#endif
#define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev)
#define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev)
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c
index dc05628..2eb87cd 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.c
@@ -35,7 +35,7 @@ fs_tosspages(
truncate_inode_pages(ip->i_mapping, first);
}
-void
+int
fs_flushinval_pages(
bhv_desc_t *bdp,
xfs_off_t first,
@@ -44,13 +44,16 @@ fs_flushinval_pages(
{
bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
struct inode *ip = vn_to_inode(vp);
+ int ret = 0;
if (VN_CACHED(vp)) {
if (VN_TRUNC(vp))
VUNTRUNCATE(vp);
- filemap_write_and_wait(ip->i_mapping);
- truncate_inode_pages(ip->i_mapping, first);
+ ret = filemap_write_and_wait(ip->i_mapping);
+ if (!ret)
+ truncate_inode_pages(ip->i_mapping, first);
}
+ return ret;
}
int
@@ -63,14 +66,18 @@ fs_flush_pages(
{
bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
struct inode *ip = vn_to_inode(vp);
+ int ret = 0;
+ int ret2;
if (VN_DIRTY(vp)) {
if (VN_TRUNC(vp))
VUNTRUNCATE(vp);
- filemap_fdatawrite(ip->i_mapping);
+ ret = filemap_fdatawrite(ip->i_mapping);
if (flags & XFS_B_ASYNC)
- return 0;
- filemap_fdatawait(ip->i_mapping);
+ return ret;
+ ret2 = filemap_fdatawait(ip->i_mapping);
+ if (!ret)
+ ret = ret2;
}
- return 0;
+ return ret;
}
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.h b/fs/xfs/linux-2.6/xfs_fs_subr.h
index aee9ccd..c1b5311 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.h
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.h
@@ -23,7 +23,7 @@ extern int fs_noerr(void);
extern int fs_nosys(void);
extern void fs_noval(void);
extern void fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
-extern void fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
+extern int fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
extern int fs_flush_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, uint64_t, int);
#endif /* __XFS_FS_SUBR_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index ff8d64e..86fb671 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -191,7 +191,7 @@ xfs_read(
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
size_t size = 0;
- ssize_t ret;
+ ssize_t ret = 0;
xfs_fsize_t n;
xfs_inode_t *ip;
xfs_mount_t *mp;
@@ -224,7 +224,7 @@ xfs_read(
mp->m_rtdev_targp : mp->m_ddev_targp;
if ((*offset & target->bt_smask) ||
(size & target->bt_smask)) {
- if (*offset == ip->i_d.di_size) {
+ if (*offset == ip->i_size) {
return (0);
}
return -XFS_ERROR(EINVAL);
@@ -263,9 +263,13 @@ xfs_read(
if (unlikely(ioflags & IO_ISDIRECT)) {
if (VN_CACHED(vp))
- bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
+ ret = bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
-1, FI_REMAPF_LOCKED);
mutex_unlock(&inode->i_mutex);
+ if (ret) {
+ xfs_iunlock(ip, XFS_IOLOCK_SHARED);
+ return ret;
+ }
}
xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
@@ -383,9 +387,10 @@ xfs_splice_write(
{
xfs_inode_t *ip = XFS_BHVTOI(bdp);
xfs_mount_t *mp = ip->i_mount;
+ xfs_iocore_t *io = &ip->i_iocore;
ssize_t ret;
struct inode *inode = outfilp->f_mapping->host;
- xfs_fsize_t isize;
+ xfs_fsize_t isize, new_size;
XFS_STATS_INC(xs_write_calls);
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
@@ -406,6 +411,14 @@ xfs_splice_write(
return -error;
}
}
+
+ new_size = *ppos + count;
+
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ if (new_size > ip->i_size)
+ io->io_new_size = new_size;
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+
xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore,
pipe, count, *ppos, ioflags);
ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags);
@@ -416,14 +429,18 @@ xfs_splice_write(
if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize))
*ppos = isize;
- if (*ppos > ip->i_d.di_size) {
+ if (*ppos > ip->i_size) {
xfs_ilock(ip, XFS_ILOCK_EXCL);
- if (*ppos > ip->i_d.di_size) {
- ip->i_d.di_size = *ppos;
- i_size_write(inode, *ppos);
- ip->i_update_core = 1;
- ip->i_update_size = 1;
- }
+ if (*ppos > ip->i_size)
+ ip->i_size = *ppos;
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ }
+
+ if (io->io_new_size) {
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ io->io_new_size = 0;
+ if (ip->i_d.di_size > ip->i_size)
+ ip->i_d.di_size = ip->i_size;
xfs_iunlock(ip, XFS_ILOCK_EXCL);
}
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
@@ -639,37 +656,21 @@ xfs_write(
xfs_fsize_t isize, new_size;
xfs_iocore_t *io;
bhv_vnode_t *vp;
- unsigned long seg;
int iolock;
int eventsent = 0;
bhv_vrwlock_t locktype;
size_t ocount = 0, count;
loff_t pos;
- int need_i_mutex = 1, need_flush = 0;
+ int need_i_mutex;
XFS_STATS_INC(xs_write_calls);
vp = BHV_TO_VNODE(bdp);
xip = XFS_BHVTOI(bdp);
- for (seg = 0; seg < segs; seg++) {
- const struct iovec *iv = &iovp[seg];
-
- /*
- * If any segment has a negative length, or the cumulative
- * length ever wraps negative then return -EINVAL.
- */
- ocount += iv->iov_len;
- if (unlikely((ssize_t)(ocount|iv->iov_len) < 0))
- return -EINVAL;
- if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len))
- continue;
- if (seg == 0)
- return -EFAULT;
- segs = seg;
- ocount -= iv->iov_len; /* This segment is no good */
- break;
- }
+ error = generic_segment_checks(iovp, &segs, &ocount, VERIFY_READ);
+ if (error)
+ return error;
count = ocount;
pos = *offset;
@@ -685,39 +686,20 @@ xfs_write(
if (XFS_FORCED_SHUTDOWN(mp))
return -EIO;
- if (ioflags & IO_ISDIRECT) {
- xfs_buftarg_t *target =
- (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
- mp->m_rtdev_targp : mp->m_ddev_targp;
-
- if ((pos & target->bt_smask) || (count & target->bt_smask))
- return XFS_ERROR(-EINVAL);
-
- if (!VN_CACHED(vp) && pos < i_size_read(inode))
- need_i_mutex = 0;
-
- if (VN_CACHED(vp))
- need_flush = 1;
- }
-
relock:
- if (need_i_mutex) {
+ if (ioflags & IO_ISDIRECT) {
+ iolock = XFS_IOLOCK_SHARED;
+ locktype = VRWLOCK_WRITE_DIRECT;
+ need_i_mutex = 0;
+ } else {
iolock = XFS_IOLOCK_EXCL;
locktype = VRWLOCK_WRITE;
-
+ need_i_mutex = 1;
mutex_lock(&inode->i_mutex);
- } else {
- iolock = XFS_IOLOCK_SHARED;
- locktype = VRWLOCK_WRITE_DIRECT;
}
xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
- isize = i_size_read(inode);
-
- if (file->f_flags & O_APPEND)
- *offset = isize;
-
start:
error = -generic_write_checks(file, &pos, &count,
S_ISBLK(inode->i_mode));
@@ -726,13 +708,8 @@ start:
goto out_unlock_mutex;
}
- new_size = pos + count;
- if (new_size > isize)
- io->io_new_size = new_size;
-
if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) &&
!(ioflags & IO_INVIS) && !eventsent)) {
- loff_t savedsize = pos;
int dmflags = FILP_DELAY_FLAG(file);
if (need_i_mutex)
@@ -743,8 +720,7 @@ start:
pos, count,
dmflags, &locktype);
if (error) {
- xfs_iunlock(xip, iolock);
- goto out_unlock_mutex;
+ goto out_unlock_internal;
}
xfs_ilock(xip, XFS_ILOCK_EXCL);
eventsent = 1;
@@ -756,12 +732,35 @@ start:
* event prevents another call to XFS_SEND_DATA, which is
* what allows the size to change in the first place.
*/
- if ((file->f_flags & O_APPEND) && savedsize != isize) {
- pos = isize = xip->i_d.di_size;
+ if ((file->f_flags & O_APPEND) && pos != xip->i_size)
+ goto start;
+ }
+
+ if (ioflags & IO_ISDIRECT) {
+ xfs_buftarg_t *target =
+ (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
+ mp->m_rtdev_targp : mp->m_ddev_targp;
+
+ if ((pos & target->bt_smask) || (count & target->bt_smask)) {
+ xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
+ return XFS_ERROR(-EINVAL);
+ }
+
+ if (!need_i_mutex && (VN_CACHED(vp) || pos > xip->i_size)) {
+ xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
+ iolock = XFS_IOLOCK_EXCL;
+ locktype = VRWLOCK_WRITE;
+ need_i_mutex = 1;
+ mutex_lock(&inode->i_mutex);
+ xfs_ilock(xip, XFS_ILOCK_EXCL|iolock);
goto start;
}
}
+ new_size = pos + count;
+ if (new_size > xip->i_size)
+ io->io_new_size = new_size;
+
if (likely(!(ioflags & IO_INVIS))) {
file_update_time(file);
xfs_ichgtime_fast(xip, inode,
@@ -777,11 +776,11 @@ start:
* to zero it out up to the new size.
*/
- if (pos > isize) {
- error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, isize);
+ if (pos > xip->i_size) {
+ error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, xip->i_size);
if (error) {
- xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
- goto out_unlock_mutex;
+ xfs_iunlock(xip, XFS_ILOCK_EXCL);
+ goto out_unlock_internal;
}
}
xfs_iunlock(xip, XFS_ILOCK_EXCL);
@@ -801,8 +800,7 @@ start:
if (likely(!error))
error = -remove_suid(file->f_path.dentry);
if (unlikely(error)) {
- xfs_iunlock(xip, iolock);
- goto out_unlock_mutex;
+ goto out_unlock_internal;
}
}
@@ -811,11 +809,14 @@ retry:
current->backing_dev_info = mapping->backing_dev_info;
if ((ioflags & IO_ISDIRECT)) {
- if (need_flush) {
+ if (VN_CACHED(vp)) {
+ WARN_ON(need_i_mutex == 0);
xfs_inval_cached_trace(io, pos, -1,
ctooff(offtoct(pos)), -1);
- bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)),
+ error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)),
-1, FI_REMAPF_LOCKED);
+ if (error)
+ goto out_unlock_internal;
}
if (need_i_mutex) {
@@ -843,7 +844,6 @@ retry:
pos += ret;
count -= ret;
- need_i_mutex = 1;
ioflags &= ~IO_ISDIRECT;
xfs_iunlock(xip, iolock);
goto relock;
@@ -870,12 +870,12 @@ retry:
error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
0, 0, 0); /* Delay flag intentionally unused */
- if (error)
- goto out_nounlocks;
if (need_i_mutex)
mutex_lock(&inode->i_mutex);
xfs_rwlock(bdp, locktype);
- pos = xip->i_d.di_size;
+ if (error)
+ goto out_unlock_internal;
+ pos = xip->i_size;
ret = 0;
goto retry;
}
@@ -884,14 +884,10 @@ retry:
if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize))
*offset = isize;
- if (*offset > xip->i_d.di_size) {
+ if (*offset > xip->i_size) {
xfs_ilock(xip, XFS_ILOCK_EXCL);
- if (*offset > xip->i_d.di_size) {
- xip->i_d.di_size = *offset;
- i_size_write(inode, *offset);
- xip->i_update_core = 1;
- xip->i_update_size = 1;
- }
+ if (*offset > xip->i_size)
+ xip->i_size = *offset;
xfs_iunlock(xip, XFS_ILOCK_EXCL);
}
@@ -913,16 +909,31 @@ retry:
error = sync_page_range(inode, mapping, pos, ret);
if (!error)
- error = ret;
- return error;
+ error = -ret;
+ if (need_i_mutex)
+ mutex_lock(&inode->i_mutex);
+ xfs_rwlock(bdp, locktype);
}
out_unlock_internal:
+ if (io->io_new_size) {
+ xfs_ilock(xip, XFS_ILOCK_EXCL);
+ io->io_new_size = 0;
+ /*
+ * If this was a direct or synchronous I/O that failed (such
+ * as ENOSPC) then part of the I/O may have been written to
+ * disk before the error occured. In this case the on-disk
+ * file size may have been adjusted beyond the in-memory file
+ * size and now needs to be truncated back.
+ */
+ if (xip->i_d.di_size > xip->i_size)
+ xip->i_d.di_size = xip->i_size;
+ xfs_iunlock(xip, XFS_ILOCK_EXCL);
+ }
xfs_rwunlock(bdp, locktype);
out_unlock_mutex:
if (need_i_mutex)
mutex_unlock(&inode->i_mutex);
- out_nounlocks:
return -error;
}
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 2f2c40d..14e2cbe 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -360,8 +360,7 @@ xfs_fs_inode_init_once(
kmem_zone_t *zonep,
unsigned long flags)
{
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(vn_to_inode((bhv_vnode_t *)vnode));
}
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index b76118c..d1b2d01 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -194,7 +194,7 @@ typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int,
typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int);
typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t);
typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
-typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
+typedef int (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
uint64_t, int);
typedef int (*vop_iflush_t)(bhv_desc_t *, int);
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 4adaf13..cfdd35e 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -753,8 +753,7 @@ xfs_qm_idtodq(
goto error0;
}
if (tp) {
- if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES,
- NULL)))
+ if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES)))
goto error1;
}
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 1de2acd..3e4a8ad 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -388,6 +388,17 @@ xfs_qm_mount_quotas(
return XFS_ERROR(error);
}
}
+ /*
+ * If one type of quotas is off, then it will lose its
+ * quotachecked status, since we won't be doing accounting for
+ * that type anymore.
+ */
+ if (!XFS_IS_UQUOTA_ON(mp)) {
+ mp->m_qflags &= ~XFS_UQUOTA_CHKD;
+ }
+ if (!(XFS_IS_GQUOTA_ON(mp) || XFS_IS_PQUOTA_ON(mp))) {
+ mp->m_qflags &= ~XFS_OQUOTA_CHKD;
+ }
write_changes:
/*
@@ -1453,8 +1464,7 @@ xfs_qm_qino_alloc(
XFS_SB_UNLOCK(mp, s);
xfs_mod_sb(tp, sbfields);
- if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES,
- NULL))) {
+ if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) {
xfs_fs_cmn_err(CE_ALERT, mp, "XFS qino_alloc failed!");
return error;
}
@@ -2405,7 +2415,7 @@ xfs_qm_write_sb_changes(
}
xfs_mod_sb(tp, flags);
- (void) xfs_trans_commit(tp, 0, NULL);
+ (void) xfs_trans_commit(tp, 0);
return 0;
}
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 716f562..2df67fd 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -456,9 +456,7 @@ xfs_qm_scall_quotaon(
||
((flags & XFS_PQUOTA_ACCT) == 0 &&
(mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
- (flags & XFS_OQUOTA_ENFD))
- ||
- ((flags & XFS_GQUOTA_ACCT) == 0 &&
+ (flags & XFS_GQUOTA_ACCT) == 0 &&
(mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
(flags & XFS_OQUOTA_ENFD))) {
qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n",
@@ -735,7 +733,7 @@ xfs_qm_scall_setqlim(
xfs_trans_log_dquot(tp, dqp);
xfs_dqtrace_entry(dqp, "Q_SETQLIM: COMMIT");
- xfs_trans_commit(tp, 0, NULL);
+ xfs_trans_commit(tp, 0);
xfs_qm_dqprint(dqp);
xfs_qm_dqrele(dqp);
mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));
@@ -809,7 +807,7 @@ xfs_qm_log_quotaoff_end(
* We don't care about quotoff's performance.
*/
xfs_trans_set_sync(tp);
- error = xfs_trans_commit(tp, 0, NULL);
+ error = xfs_trans_commit(tp, 0);
return (error);
}
@@ -852,7 +850,7 @@ xfs_qm_log_quotaoff(
* We don't care about quotoff's performance.
*/
xfs_trans_set_sync(tp);
- error = xfs_trans_commit(tp, 0, NULL);
+ error = xfs_trans_commit(tp, 0);
error0:
if (error) {
@@ -911,14 +909,19 @@ xfs_qm_export_dquot(
* gets turned off. No need to confuse the user level code,
* so return zeroes in that case.
*/
- if (! XFS_IS_QUOTA_ENFORCED(mp)) {
+ if ((!XFS_IS_UQUOTA_ENFORCED(mp) && src->d_flags == XFS_DQ_USER) ||
+ (!XFS_IS_OQUOTA_ENFORCED(mp) &&
+ (src->d_flags & (XFS_DQ_PROJ | XFS_DQ_GROUP)))) {
dst->d_btimer = 0;
dst->d_itimer = 0;
dst->d_rtbtimer = 0;
}
#ifdef DEBUG
- if (XFS_IS_QUOTA_ENFORCED(mp) && dst->d_id != 0) {
+ if (((XFS_IS_UQUOTA_ENFORCED(mp) && dst->d_flags == XFS_USER_QUOTA) ||
+ (XFS_IS_OQUOTA_ENFORCED(mp) &&
+ (dst->d_flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)))) &&
+ dst->d_id != 0) {
if (((int) dst->d_bcount >= (int) dst->d_blk_softlimit) &&
(dst->d_blk_softlimit > 0)) {
ASSERT(dst->d_btimer != 0);
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index d7491e7..7de6874 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -656,7 +656,9 @@ xfs_trans_dqresv(
if ((flags & XFS_QMOPT_FORCE_RES) == 0 &&
dqp->q_core.d_id &&
- XFS_IS_QUOTA_ENFORCED(dqp->q_mount)) {
+ ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
+ (XFS_IS_OQUOTA_ENFORCED(dqp->q_mount) &&
+ (XFS_QM_ISPDQ(dqp) || XFS_QM_ISGDQ(dqp))))) {
#ifdef QUOTADEBUG
cmn_err(CE_DEBUG, "BLK Res: nblks=%ld + resbcount=%Ld"
" > hardlimit=%Ld?", nblks, *resbcountp, hardlimit);
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index 08bbd3c..f45a49f 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -81,20 +81,3 @@ assfail(char *expr, char *file, int line)
printk("Assertion failed: %s, file: %s, line: %d\n", expr, file, line);
BUG();
}
-
-#if ((defined(DEBUG) || defined(INDUCE_IO_ERRROR)) && !defined(NO_WANT_RANDOM))
-unsigned long random(void)
-{
- static unsigned long RandomValue = 1;
- /* cycles pseudo-randomly through all values between 1 and 2^31 - 2 */
- register long rv = RandomValue;
- register long lo;
- register long hi;
-
- hi = rv / 127773;
- lo = rv % 127773;
- rv = 16807 * lo - 2836 * hi;
- if (rv <= 0) rv += 2147483647;
- return RandomValue = rv;
-}
-#endif /* DEBUG || INDUCE_IO_ERRROR || !NO_WANT_RANDOM */
diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h
index 2a70cc6..a27a7c8 100644
--- a/fs/xfs/support/debug.h
+++ b/fs/xfs/support/debug.h
@@ -50,7 +50,7 @@ extern void assfail(char *expr, char *f, int l);
#else /* DEBUG */
# define ASSERT(expr) ASSERT_ALWAYS(expr)
-extern unsigned long random(void);
+# include <linux/random.h>
#ifndef STATIC
# define STATIC noinline
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index e80dda3..8e9a40a 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -764,7 +764,7 @@ xfs_alloc_ag_vextent_near(
*/
int dofirst; /* set to do first algorithm */
- dofirst = random() & 1;
+ dofirst = random32() & 1;
#endif
/*
* Get a cursor for the by-size btree.
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index 9d358ff..7ce44a7 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -328,8 +328,7 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
xfs_trans_set_sync(args.trans);
}
err2 = xfs_trans_commit(args.trans,
- XFS_TRANS_RELEASE_LOG_RES,
- NULL);
+ XFS_TRANS_RELEASE_LOG_RES);
xfs_iunlock(dp, XFS_ILOCK_EXCL);
/*
@@ -397,8 +396,7 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
* Commit the last in the sequence of transactions.
*/
xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
- error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES,
- NULL);
+ error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES);
xfs_iunlock(dp, XFS_ILOCK_EXCL);
/*
@@ -544,8 +542,7 @@ xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags)
* Commit the last in the sequence of transactions.
*/
xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
- error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES,
- NULL);
+ error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES);
xfs_iunlock(dp, XFS_ILOCK_EXCL);
/*
@@ -859,8 +856,7 @@ xfs_attr_inactive(xfs_inode_t *dp)
* Commit the last in the sequence of transactions.
*/
xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE);
- error = xfs_trans_commit(trans, XFS_TRANS_RELEASE_LOG_RES,
- NULL);
+ error = xfs_trans_commit(trans, XFS_TRANS_RELEASE_LOG_RES);
xfs_iunlock(dp, XFS_ILOCK_EXCL);
return(error);
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 8eab73e..81f45da 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -3053,7 +3053,7 @@ xfs_attr_rolltrans(xfs_trans_t **transp, xfs_inode_t *dp)
* is in progress. The caller takes the responsibility to cancel
* the duplicate transaction that gets returned.
*/
- if ((error = xfs_trans_commit(trans, 0, NULL)))
+ if ((error = xfs_trans_commit(trans, 0)))
return (error);
trans = *transp;
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 8779518..b1ea26e 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -130,7 +130,6 @@ STATIC int /* error */
xfs_bmap_add_extent_hole_delay(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t idx, /* extent number to update/insert */
- xfs_btree_cur_t *cur, /* if null, not a btree */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp,/* inode logging flags */
xfs_extdelta_t *delta, /* Change made to incore extents */
@@ -399,7 +398,6 @@ xfs_bmap_count_leaves(
STATIC int
xfs_bmap_disk_count_leaves(
- xfs_ifork_t *ifp,
xfs_extnum_t idx,
xfs_bmbt_block_t *block,
int numrecs,
@@ -580,7 +578,7 @@ xfs_bmap_add_extent(
if (cur)
ASSERT((cur->bc_private.b.flags &
XFS_BTCUR_BPRV_WASDEL) == 0);
- if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new,
+ if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, new,
&logflags, delta, rsvd)))
goto done;
}
@@ -1841,7 +1839,6 @@ STATIC int /* error */
xfs_bmap_add_extent_hole_delay(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t idx, /* extent number to update/insert */
- xfs_btree_cur_t *cur, /* if null, not a btree */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp, /* inode logging flags */
xfs_extdelta_t *delta, /* Change made to incore extents */
@@ -4071,7 +4068,7 @@ xfs_bmap_add_attrfork(
}
if ((error = xfs_bmap_finish(&tp, &flist, &committed)))
goto error2;
- error = xfs_trans_commit(tp, XFS_TRANS_PERM_LOG_RES, NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_PERM_LOG_RES);
ASSERT(ip->i_df.if_ext_max ==
XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
return error;
@@ -4227,7 +4224,7 @@ xfs_bmap_finish(
logres = ntp->t_log_res;
logcount = ntp->t_log_count;
ntp = xfs_trans_dup(*tp);
- error = xfs_trans_commit(*tp, 0, NULL);
+ error = xfs_trans_commit(*tp, 0);
*tp = ntp;
*committed = 1;
/*
@@ -4447,8 +4444,11 @@ xfs_bmap_one_block(
xfs_bmbt_irec_t s; /* internal version of extent */
#ifndef DEBUG
- if (whichfork == XFS_DATA_FORK)
- return ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize;
+ if (whichfork == XFS_DATA_FORK) {
+ return ((ip->i_d.di_mode & S_IFMT) == S_IFREG) ?
+ (ip->i_size == ip->i_mount->m_sb.sb_blocksize) :
+ (ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize);
+ }
#endif /* !DEBUG */
if (XFS_IFORK_NEXTENTS(ip, whichfork) != 1)
return 0;
@@ -4460,7 +4460,7 @@ xfs_bmap_one_block(
xfs_bmbt_get_all(ep, &s);
rval = s.br_startoff == 0 && s.br_blockcount == 1;
if (rval && whichfork == XFS_DATA_FORK)
- ASSERT(ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize);
+ ASSERT(ip->i_size == ip->i_mount->m_sb.sb_blocksize);
return rval;
}
@@ -5820,7 +5820,7 @@ xfs_getbmap(
fixlen = XFS_MAXIOFFSET(mp);
} else {
prealloced = 0;
- fixlen = ip->i_d.di_size;
+ fixlen = ip->i_size;
}
} else {
prealloced = 0;
@@ -5844,7 +5844,8 @@ xfs_getbmap(
xfs_ilock(ip, XFS_IOLOCK_SHARED);
- if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) {
+ if (whichfork == XFS_DATA_FORK &&
+ (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
/* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
}
@@ -6425,8 +6426,8 @@ xfs_bmap_count_tree(
for (;;) {
nextbno = be64_to_cpu(block->bb_rightsib);
numrecs = be16_to_cpu(block->bb_numrecs);
- if (unlikely(xfs_bmap_disk_count_leaves(ifp,
- 0, block, numrecs, count) < 0)) {
+ if (unlikely(xfs_bmap_disk_count_leaves(0,
+ block, numrecs, count) < 0)) {
xfs_trans_brelse(tp, bp);
XFS_ERROR_REPORT("xfs_bmap_count_tree(2)",
XFS_ERRLEVEL_LOW, mp);
@@ -6472,7 +6473,6 @@ xfs_bmap_count_leaves(
*/
int
xfs_bmap_disk_count_leaves(
- xfs_ifork_t *ifp,
xfs_extnum_t idx,
xfs_bmbt_block_t *block,
int numrecs,
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index b847e6a..de35d18 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -199,7 +199,9 @@ xfs_swap_extents(
if (VN_CACHED(tvp) != 0) {
xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
- bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED);
+ error = bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED);
+ if (error)
+ goto error0;
}
/* Verify O_DIRECT for ftmp */
@@ -382,7 +384,7 @@ xfs_swap_extents(
xfs_trans_set_sync(tp);
}
- error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT, NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT);
locked = 0;
error0:
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 9d7438b..3accc1d 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -282,8 +282,7 @@ xfs_dir2_block_addname(
* This needs to happen before the next call to use_free.
*/
if (needscan) {
- xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block,
- &needlog, NULL);
+ xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
needscan = 0;
}
}
@@ -333,7 +332,7 @@ xfs_dir2_block_addname(
*/
if (needscan) {
xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block,
- &needlog, NULL);
+ &needlog);
needscan = 0;
}
/*
@@ -418,8 +417,7 @@ xfs_dir2_block_addname(
* Clean up the bestfree array and log the header, tail, and entry.
*/
if (needscan)
- xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
- NULL);
+ xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
if (needlog)
xfs_dir2_data_log_header(tp, bp);
xfs_dir2_block_log_tail(tp, bp);
@@ -798,8 +796,7 @@ xfs_dir2_block_removename(
* Fix up bestfree, log the header if necessary.
*/
if (needscan)
- xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
- NULL);
+ xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
if (needlog)
xfs_dir2_data_log_header(tp, bp);
xfs_dir2_data_check(dp, bp);
@@ -996,8 +993,7 @@ xfs_dir2_leaf_to_block(
* Scan the bestfree if we need it and log the data block header.
*/
if (needscan)
- xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
- NULL);
+ xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
if (needlog)
xfs_dir2_data_log_header(tp, dbp);
/*
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index f7c7992..c211c37 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -324,8 +324,7 @@ void
xfs_dir2_data_freescan(
xfs_mount_t *mp, /* filesystem mount point */
xfs_dir2_data_t *d, /* data block pointer */
- int *loghead, /* out: log data header */
- char *aendp) /* in: caller's endp */
+ int *loghead) /* out: log data header */
{
xfs_dir2_block_tail_t *btp; /* block tail */
xfs_dir2_data_entry_t *dep; /* active data entry */
@@ -346,9 +345,7 @@ xfs_dir2_data_freescan(
* Set up pointers.
*/
p = (char *)d->u;
- if (aendp)
- endp = aendp;
- else if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
+ if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
endp = (char *)XFS_DIR2_BLOCK_LEAF_P(btp);
} else
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h
index a6ae2d2..c94c909 100644
--- a/fs/xfs/xfs_dir2_data.h
+++ b/fs/xfs/xfs_dir2_data.h
@@ -166,7 +166,7 @@ extern xfs_dir2_data_free_t *xfs_dir2_data_freefind(xfs_dir2_data_t *d,
extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_t *d,
xfs_dir2_data_unused_t *dup, int *loghead);
extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d,
- int *loghead, char *aendp);
+ int *loghead);
extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
struct xfs_dabuf **bpp);
extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp,
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index b1cf1fb..db14ea7 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -133,8 +133,7 @@ xfs_dir2_block_to_leaf(
*/
block->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
if (needscan)
- xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
- NULL);
+ xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog);
/*
* Set up leaf tail and bests table.
*/
@@ -414,7 +413,7 @@ xfs_dir2_leaf_addname(
* Need to scan fix up the bestfree table.
*/
if (needscan)
- xfs_dir2_data_freescan(mp, data, &needlog, NULL);
+ xfs_dir2_data_freescan(mp, data, &needlog);
/*
* Need to log the data block's header.
*/
@@ -1496,7 +1495,7 @@ xfs_dir2_leaf_removename(
* log the data block header if necessary.
*/
if (needscan)
- xfs_dir2_data_freescan(mp, data, &needlog, NULL);
+ xfs_dir2_data_freescan(mp, data, &needlog);
if (needlog)
xfs_dir2_data_log_header(tp, dbp);
/*
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index 9ca7171..d083c38 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -904,7 +904,7 @@ xfs_dir2_leafn_remove(
* Log the data block header if needed.
*/
if (needscan)
- xfs_dir2_data_freescan(mp, data, &needlog, NULL);
+ xfs_dir2_data_freescan(mp, data, &needlog);
if (needlog)
xfs_dir2_data_log_header(tp, dbp);
xfs_dir2_data_check(dp, dbp);
@@ -1705,7 +1705,7 @@ xfs_dir2_node_addname_int(
* Rescan the block for bestfree if needed.
*/
if (needscan)
- xfs_dir2_data_freescan(mp, data, &needlog, NULL);
+ xfs_dir2_data_freescan(mp, data, &needlog);
/*
* Log the data block header if needed.
*/
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
index b1af544..8c43316 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -80,7 +80,7 @@ xfs_error_test(int error_tag, int *fsidp, char *expression,
int i;
int64_t fsid;
- if (random() % randfactor)
+ if (random32() % randfactor)
return 0;
memcpy(&fsid, fsidp, sizeof(xfs_fsid_t));
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 32c37c1..b599e6b 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -346,7 +346,7 @@ xfs_growfs_data_private(
xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, nfree);
if (dpct)
xfs_trans_mod_sb(tp, XFS_TRANS_SB_IMAXPCT, dpct);
- error = xfs_trans_commit(tp, 0, NULL);
+ error = xfs_trans_commit(tp, 0);
if (error) {
return error;
}
@@ -605,7 +605,7 @@ xfs_fs_log_dummy(
xfs_trans_ihold(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
xfs_trans_set_sync(tp);
- xfs_trans_commit(tp, 0, NULL);
+ xfs_trans_commit(tp, 0);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
}
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index c1c89da..114433a 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -879,17 +879,17 @@ xfs_ilock(xfs_inode_t *ip,
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
- ASSERT((lock_flags & ~XFS_LOCK_MASK) == 0);
+ ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
if (lock_flags & XFS_IOLOCK_EXCL) {
- mrupdate(&ip->i_iolock);
+ mrupdate_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
} else if (lock_flags & XFS_IOLOCK_SHARED) {
- mraccess(&ip->i_iolock);
+ mraccess_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
}
if (lock_flags & XFS_ILOCK_EXCL) {
- mrupdate(&ip->i_lock);
+ mrupdate_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
} else if (lock_flags & XFS_ILOCK_SHARED) {
- mraccess(&ip->i_lock);
+ mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
}
xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address);
}
@@ -923,7 +923,7 @@ xfs_ilock_nowait(xfs_inode_t *ip,
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
- ASSERT((lock_flags & ~XFS_LOCK_MASK) == 0);
+ ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
iolocked = 0;
if (lock_flags & XFS_IOLOCK_EXCL) {
@@ -983,7 +983,8 @@ xfs_iunlock(xfs_inode_t *ip,
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
- ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_IUNLOCK_NONOTIFY)) == 0);
+ ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_IUNLOCK_NONOTIFY |
+ XFS_LOCK_DEP_MASK)) == 0);
ASSERT(lock_flags != 0);
if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) {
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 3da9829..3ca5d43 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -442,6 +442,7 @@ xfs_iformat(
return XFS_ERROR(EFSCORRUPTED);
}
ip->i_d.di_size = 0;
+ ip->i_size = 0;
ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT);
break;
@@ -980,6 +981,7 @@ xfs_iread(
}
ip->i_delayed_blks = 0;
+ ip->i_size = ip->i_d.di_size;
/*
* Mark the buffer containing the inode as something to keep
@@ -1170,6 +1172,7 @@ xfs_ialloc(
}
ip->i_d.di_size = 0;
+ ip->i_size = 0;
ip->i_d.di_nextents = 0;
ASSERT(ip->i_d.di_nblocks == 0);
xfs_ichgtime(ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD);
@@ -1340,7 +1343,7 @@ xfs_file_last_byte(
} else {
last_block = 0;
}
- size_last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)ip->i_d.di_size);
+ size_last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)ip->i_size);
last_block = XFS_FILEOFF_MAX(last_block, size_last_block);
last_byte = XFS_FSB_TO_B(mp, last_block);
@@ -1421,7 +1424,7 @@ xfs_itrunc_trace(
* must be called again with all the same restrictions as the initial
* call.
*/
-void
+int
xfs_itruncate_start(
xfs_inode_t *ip,
uint flags,
@@ -1431,9 +1434,10 @@ xfs_itruncate_start(
xfs_off_t toss_start;
xfs_mount_t *mp;
bhv_vnode_t *vp;
+ int error = 0;
ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
- ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size));
+ ASSERT((new_size == 0) || (new_size <= ip->i_size));
ASSERT((flags == XFS_ITRUNC_DEFINITE) ||
(flags == XFS_ITRUNC_MAYBE));
@@ -1468,7 +1472,7 @@ xfs_itruncate_start(
* file size, so there is no way that the data extended
* out there.
*/
- return;
+ return 0;
}
last_byte = xfs_file_last_byte(ip);
xfs_itrunc_trace(XFS_ITRUNC_START, ip, flags, new_size, toss_start,
@@ -1477,7 +1481,7 @@ xfs_itruncate_start(
if (flags & XFS_ITRUNC_DEFINITE) {
bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
} else {
- bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
+ error = bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
}
}
@@ -1486,6 +1490,7 @@ xfs_itruncate_start(
ASSERT(VN_CACHED(vp) == 0);
}
#endif
+ return error;
}
/*
@@ -1556,7 +1561,7 @@ xfs_itruncate_finish(
ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0);
- ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size));
+ ASSERT((new_size == 0) || (new_size <= ip->i_size));
ASSERT(*tp != NULL);
ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
ASSERT(ip->i_transp == *tp);
@@ -1630,8 +1635,20 @@ xfs_itruncate_finish(
*/
if (fork == XFS_DATA_FORK) {
if (ip->i_d.di_nextents > 0) {
- ip->i_d.di_size = new_size;
- xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
+ /*
+ * If we are not changing the file size then do
+ * not update the on-disk file size - we may be
+ * called from xfs_inactive_free_eofblocks(). If we
+ * update the on-disk file size and then the system
+ * crashes before the contents of the file are
+ * flushed to disk then the files may be full of
+ * holes (ie NULL files bug).
+ */
+ if (ip->i_size != new_size) {
+ ip->i_d.di_size = new_size;
+ ip->i_size = new_size;
+ xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
+ }
}
} else if (sync) {
ASSERT(!(mp->m_flags & XFS_MOUNT_WSYNC));
@@ -1746,7 +1763,7 @@ xfs_itruncate_finish(
xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
}
ntp = xfs_trans_dup(ntp);
- (void) xfs_trans_commit(*tp, 0, NULL);
+ (void) xfs_trans_commit(*tp, 0);
*tp = ntp;
error = xfs_trans_reserve(ntp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
XFS_TRANS_PERM_LOG_RES,
@@ -1767,7 +1784,19 @@ xfs_itruncate_finish(
*/
if (fork == XFS_DATA_FORK) {
xfs_isize_check(mp, ip, new_size);
- ip->i_d.di_size = new_size;
+ /*
+ * If we are not changing the file size then do
+ * not update the on-disk file size - we may be
+ * called from xfs_inactive_free_eofblocks(). If we
+ * update the on-disk file size and then the system
+ * crashes before the contents of the file are
+ * flushed to disk then the files may be full of
+ * holes (ie NULL files bug).
+ */
+ if (ip->i_size != new_size) {
+ ip->i_d.di_size = new_size;
+ ip->i_size = new_size;
+ }
}
xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
ASSERT((new_size != 0) ||
@@ -1800,7 +1829,7 @@ xfs_igrow_start(
ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0);
ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0);
- ASSERT(new_size > ip->i_d.di_size);
+ ASSERT(new_size > ip->i_size);
/*
* Zero any pages that may have been created by
@@ -1808,7 +1837,7 @@ xfs_igrow_start(
* and any blocks between the old and new file sizes.
*/
error = xfs_zero_eof(XFS_ITOV(ip), &ip->i_iocore, new_size,
- ip->i_d.di_size);
+ ip->i_size);
return error;
}
@@ -1832,13 +1861,14 @@ xfs_igrow_finish(
ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0);
ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0);
ASSERT(ip->i_transp == tp);
- ASSERT(new_size > ip->i_d.di_size);
+ ASSERT(new_size > ip->i_size);
/*
* Update the file size. Update the inode change timestamp
* if change_flag set.
*/
ip->i_d.di_size = new_size;
+ ip->i_size = new_size;
if (change_flag)
xfs_ichgtime(ip, XFS_ICHGTIME_CHG);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
@@ -2321,7 +2351,7 @@ xfs_ifree(
ASSERT(ip->i_d.di_nlink == 0);
ASSERT(ip->i_d.di_nextents == 0);
ASSERT(ip->i_d.di_anextents == 0);
- ASSERT((ip->i_d.di_size == 0) ||
+ ASSERT((ip->i_d.di_size == 0 && ip->i_size == 0) ||
((ip->i_d.di_mode & S_IFMT) != S_IFREG));
ASSERT(ip->i_d.di_nblocks == 0);
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index bc82372..f75afec 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -287,6 +287,7 @@ typedef struct xfs_inode {
struct xfs_inode *i_cnext; /* cluster hash link forward */
struct xfs_inode *i_cprev; /* cluster hash link backward */
+ xfs_fsize_t i_size; /* in-memory size */
/* Trace buffers per inode. */
#ifdef XFS_BMAP_TRACE
struct ktrace *i_xtrace; /* inode extent list trace */
@@ -305,6 +306,8 @@ typedef struct xfs_inode {
#endif
} xfs_inode_t;
+#define XFS_ISIZE(ip) (((ip)->i_d.di_mode & S_IFMT) == S_IFREG) ? \
+ (ip)->i_size : (ip)->i_d.di_size;
/*
* i_flags helper functions
@@ -379,26 +382,58 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
/*
* Flags for inode locking.
+ * Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield)
+ * 1<<16 - 1<<32-1 -- lockdep annotation (integers)
*/
-#define XFS_IOLOCK_EXCL 0x001
-#define XFS_IOLOCK_SHARED 0x002
-#define XFS_ILOCK_EXCL 0x004
-#define XFS_ILOCK_SHARED 0x008
-#define XFS_IUNLOCK_NONOTIFY 0x010
-/* XFS_IOLOCK_NESTED 0x020 */
-#define XFS_EXTENT_TOKEN_RD 0x040
-#define XFS_SIZE_TOKEN_RD 0x080
+#define XFS_IOLOCK_EXCL (1<<0)
+#define XFS_IOLOCK_SHARED (1<<1)
+#define XFS_ILOCK_EXCL (1<<2)
+#define XFS_ILOCK_SHARED (1<<3)
+#define XFS_IUNLOCK_NONOTIFY (1<<4)
+/* #define XFS_IOLOCK_NESTED (1<<5) */
+#define XFS_EXTENT_TOKEN_RD (1<<6)
+#define XFS_SIZE_TOKEN_RD (1<<7)
#define XFS_EXTSIZE_RD (XFS_EXTENT_TOKEN_RD|XFS_SIZE_TOKEN_RD)
-#define XFS_WILLLEND 0x100 /* Always acquire tokens for lending */
+#define XFS_WILLLEND (1<<8) /* Always acquire tokens for lending */
#define XFS_EXTENT_TOKEN_WR (XFS_EXTENT_TOKEN_RD | XFS_WILLLEND)
#define XFS_SIZE_TOKEN_WR (XFS_SIZE_TOKEN_RD | XFS_WILLLEND)
#define XFS_EXTSIZE_WR (XFS_EXTSIZE_RD | XFS_WILLLEND)
-/* XFS_SIZE_TOKEN_WANT 0x200 */
+/* TODO:XFS_SIZE_TOKEN_WANT (1<<9) */
-#define XFS_LOCK_MASK \
- (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL | \
- XFS_ILOCK_SHARED | XFS_EXTENT_TOKEN_RD | XFS_SIZE_TOKEN_RD | \
- XFS_WILLLEND)
+#define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \
+ | XFS_ILOCK_EXCL | XFS_ILOCK_SHARED \
+ | XFS_EXTENT_TOKEN_RD | XFS_SIZE_TOKEN_RD \
+ | XFS_WILLLEND)
+
+/*
+ * Flags for lockdep annotations.
+ *
+ * XFS_I[O]LOCK_PARENT - for operations that require locking two inodes
+ * (ie directory operations that require locking a directory inode and
+ * an entry inode). The first inode gets locked with this flag so it
+ * gets a lockdep subclass of 1 and the second lock will have a lockdep
+ * subclass of 0.
+ *
+ * XFS_I[O]LOCK_INUMORDER - for locking several inodes at the some time
+ * with xfs_lock_inodes(). This flag is used as the starting subclass
+ * and each subsequent lock acquired will increment the subclass by one.
+ * So the first lock acquired will have a lockdep subclass of 2, the
+ * second lock will have a lockdep subclass of 3, and so on.
+ */
+#define XFS_IOLOCK_SHIFT 16
+#define XFS_IOLOCK_PARENT (1 << XFS_IOLOCK_SHIFT)
+#define XFS_IOLOCK_INUMORDER (2 << XFS_IOLOCK_SHIFT)
+
+#define XFS_ILOCK_SHIFT 24
+#define XFS_ILOCK_PARENT (1 << XFS_ILOCK_SHIFT)
+#define XFS_ILOCK_INUMORDER (2 << XFS_ILOCK_SHIFT)
+
+#define XFS_IOLOCK_DEP_MASK 0x00ff0000
+#define XFS_ILOCK_DEP_MASK 0xff000000
+#define XFS_LOCK_DEP_MASK (XFS_IOLOCK_DEP_MASK | XFS_ILOCK_DEP_MASK)
+
+#define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT)
+#define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT)
/*
* Flags for xfs_iflush()
@@ -481,7 +516,7 @@ uint xfs_ip2xflags(struct xfs_inode *);
uint xfs_dic2xflags(struct xfs_dinode_core *);
int xfs_ifree(struct xfs_trans *, xfs_inode_t *,
struct xfs_bmap_free *);
-void xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t);
+int xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t);
int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *,
xfs_fsize_t, int, int);
int xfs_iunlink(struct xfs_trans *, xfs_inode_t *);
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c
index 06d710c..81548ec 100644
--- a/fs/xfs/xfs_iocore.c
+++ b/fs/xfs/xfs_iocore.c
@@ -52,7 +52,7 @@ STATIC xfs_fsize_t
xfs_size_fn(
xfs_inode_t *ip)
{
- return (ip->i_d.di_size);
+ return XFS_ISIZE(ip);
}
STATIC int
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index cc6a7b5..3f2b9f2 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -458,7 +458,7 @@ xfs_iomap_write_direct(
extsz = ip->i_d.di_extsize;
}
- isize = ip->i_d.di_size;
+ isize = ip->i_size;
if (io->io_new_size > isize)
isize = io->io_new_size;
@@ -524,7 +524,7 @@ xfs_iomap_write_direct(
xfs_trans_ihold(tp, ip);
bmapi_flag = XFS_BMAPI_WRITE;
- if ((flags & BMAPI_DIRECT) && (offset < ip->i_d.di_size || extsz))
+ if ((flags & BMAPI_DIRECT) && (offset < ip->i_size || extsz))
bmapi_flag |= XFS_BMAPI_PREALLOC;
/*
@@ -543,7 +543,7 @@ xfs_iomap_write_direct(
error = xfs_bmap_finish(&tp, &free_list, &committed);
if (error)
goto error0;
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
if (error)
goto error_out;
@@ -676,7 +676,7 @@ xfs_iomap_write_delay(
offset_fsb = XFS_B_TO_FSBT(mp, offset);
retry:
- isize = ip->i_d.di_size;
+ isize = ip->i_size;
if (io->io_new_size > isize)
isize = io->io_new_size;
@@ -817,7 +817,7 @@ xfs_iomap_write_allocate(
* we dropped the ilock in the interim.
*/
- end_fsb = XFS_B_TO_FSB(mp, ip->i_d.di_size);
+ end_fsb = XFS_B_TO_FSB(mp, ip->i_size);
xfs_bmap_last_offset(NULL, ip, &last_block,
XFS_DATA_FORK);
last_block = XFS_FILEOFF_MAX(last_block, end_fsb);
@@ -840,8 +840,7 @@ xfs_iomap_write_allocate(
if (error)
goto trans_cancel;
- error = xfs_trans_commit(tp,
- XFS_TRANS_RELEASE_LOG_RES, NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
if (error)
goto error0;
@@ -948,7 +947,7 @@ xfs_iomap_write_unwritten(
if (error)
goto error_on_bmapi_transaction;
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
if (error)
return XFS_ERROR(error);
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index 3ce204a..df441ee 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -22,6 +22,7 @@
typedef enum { /* iomap_flags values */
+ IOMAP_READ = 0, /* mapping for a read */
IOMAP_EOF = 0x01, /* mapping contains EOF */
IOMAP_HOLE = 0x02, /* mapping covers a hole */
IOMAP_DELAY = 0x04, /* mapping covers delalloc region */
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index ca74d3f..080fabf 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -1509,7 +1509,6 @@ xlog_recover_insert_item_frontq(
STATIC int
xlog_recover_reorder_trans(
- xlog_t *log,
xlog_recover_t *trans)
{
xlog_recover_item_t *first_item, *itemq, *itemq_next;
@@ -1867,7 +1866,6 @@ xlog_recover_do_inode_buffer(
/*ARGSUSED*/
STATIC void
xlog_recover_do_reg_buffer(
- xfs_mount_t *mp,
xlog_recover_item_t *item,
xfs_buf_t *bp,
xfs_buf_log_format_t *buf_f)
@@ -2083,7 +2081,7 @@ xlog_recover_do_dquot_buffer(
if (log->l_quotaoffs_flag & type)
return;
- xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
+ xlog_recover_do_reg_buffer(item, bp, buf_f);
}
/*
@@ -2184,7 +2182,7 @@ xlog_recover_do_buffer_trans(
(XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
} else {
- xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
+ xlog_recover_do_reg_buffer(item, bp, buf_f);
}
if (error)
return XFS_ERROR(error);
@@ -2765,7 +2763,7 @@ xlog_recover_do_trans(
int error = 0;
xlog_recover_item_t *item, *first_item;
- if ((error = xlog_recover_reorder_trans(log, trans)))
+ if ((error = xlog_recover_reorder_trans(trans)))
return error;
first_item = item = trans->r_itemq;
do {
@@ -3016,7 +3014,7 @@ xlog_recover_process_efi(
}
efip->efi_flags |= XFS_EFI_RECOVERED;
- xfs_trans_commit(tp, 0, NULL);
+ xfs_trans_commit(tp, 0);
}
/*
@@ -3143,7 +3141,7 @@ xlog_recover_clear_agi_bucket(
xfs_trans_log_buf(tp, agibp, offset,
(offset + sizeof(xfs_agino_t) - 1));
- (void) xfs_trans_commit(tp, 0, NULL);
+ (void) xfs_trans_commit(tp, 0);
}
/*
@@ -3886,8 +3884,7 @@ xlog_recover(
* under the vfs layer, so we can get away with it unless
* the device itself is read-only, in which case we fail.
*/
- if ((error = xfs_dev_is_read_only(log->l_mp,
- "recovery required"))) {
+ if ((error = xfs_dev_is_read_only(log->l_mp, "recovery"))) {
return error;
}
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 3bed0cf..f5aa3ef 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1653,7 +1653,7 @@ xfs_mount_log_sbunit(
return;
}
xfs_mod_sb(tp, fields);
- xfs_trans_commit(tp, 0, NULL);
+ xfs_trans_commit(tp, 0);
}
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
index 320d63f..0d594ed 100644
--- a/fs/xfs/xfs_qmops.c
+++ b/fs/xfs/xfs_qmops.c
@@ -78,7 +78,7 @@ xfs_mount_reset_sbqflags(xfs_mount_t *mp)
return error;
}
xfs_mod_sb(tp, XFS_SB_QFLAGS);
- error = xfs_trans_commit(tp, 0, NULL);
+ error = xfs_trans_commit(tp, 0);
return error;
}
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 9dcb32a..6f14df9 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -154,10 +154,11 @@ typedef struct xfs_qoff_logformat {
#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
-#define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD)
#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT)
#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
+#define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD)
+#define XFS_IS_OQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_OQUOTA_ENFD)
/*
* Incore only flags for quotaoff - these bits get cleared when quota(s)
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 4c6573d..7679d7a 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -584,7 +584,7 @@ xfs_rename(
* trans_commit will unlock src_ip, target_ip & decrement
* the vnode references.
*/
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
if (target_ip != NULL) {
xfs_refcache_purge_ip(target_ip);
IRELE(target_ip);
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 6fff19d..b3a5f07 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -150,7 +150,7 @@ xfs_growfs_rt_alloc(
error = xfs_bmap_finish(&tp, &flist, &committed);
if (error)
goto error_exit;
- xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
+ xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
/*
* Now we need to clear the allocated blocks.
* Do this one block per transaction, to keep it simple.
@@ -187,7 +187,7 @@ xfs_growfs_rt_alloc(
/*
* Commit the transaction.
*/
- xfs_trans_commit(tp, 0, NULL);
+ xfs_trans_commit(tp, 0);
}
/*
* Go on to the next extent, if any.
@@ -2042,7 +2042,7 @@ xfs_growfs_rt(
/*
* Commit the transaction.
*/
- xfs_trans_commit(tp, 0, NULL);
+ xfs_trans_commit(tp, 0);
}
if (error)
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
index 1ea7c0c..905d1c0 100644
--- a/fs/xfs/xfs_rw.c
+++ b/fs/xfs/xfs_rw.c
@@ -83,7 +83,7 @@ xfs_write_clear_setuid(
}
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
xfs_trans_set_sync(tp);
- error = xfs_trans_commit(tp, 0, NULL);
+ error = xfs_trans_commit(tp, 0);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
return 0;
}
@@ -164,7 +164,7 @@ xfs_write_sync_logforce(
xfs_trans_ihold(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
xfs_trans_set_sync(tp);
- error = xfs_trans_commit(tp, 0, NULL);
+ error = xfs_trans_commit(tp, 0);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
}
}
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 301ff94..cc2d609 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -753,7 +753,6 @@ int
_xfs_trans_commit(
xfs_trans_t *tp,
uint flags,
- xfs_lsn_t *commit_lsn_p,
int *log_flushed)
{
xfs_log_iovec_t *log_vector;
@@ -812,8 +811,6 @@ shut_us_down:
xfs_trans_free_busy(tp);
xfs_trans_free(tp);
XFS_STATS_INC(xs_trans_empty);
- if (commit_lsn_p)
- *commit_lsn_p = commit_lsn;
return (shutdown);
}
ASSERT(tp->t_ticket != NULL);
@@ -864,9 +861,6 @@ shut_us_down:
kmem_free(log_vector, nvec * sizeof(xfs_log_iovec_t));
}
- if (commit_lsn_p)
- *commit_lsn_p = commit_lsn;
-
/*
* If we got a log write error. Unpin the logitems that we
* had pinned, clean up, free trans structure, and return error.
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index f1d7ab2..7dfcc45 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -988,10 +988,8 @@ void xfs_trans_log_efd_extent(xfs_trans_t *,
xfs_extlen_t);
int _xfs_trans_commit(xfs_trans_t *,
uint flags,
- xfs_lsn_t *,
int *);
-#define xfs_trans_commit(tp, flags, lsn) \
- _xfs_trans_commit(tp, flags, lsn, NULL)
+#define xfs_trans_commit(tp, flags) _xfs_trans_commit(tp, flags, NULL)
void xfs_trans_cancel(xfs_trans_t *, int);
void xfs_trans_ail_init(struct xfs_mount *);
xfs_lsn_t xfs_trans_push_ail(struct xfs_mount *, xfs_lsn_t);
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 9014d7e..20ffec3 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -222,7 +222,7 @@ xfs_dir_ialloc(
}
ntp = xfs_trans_dup(tp);
- code = xfs_trans_commit(tp, 0, NULL);
+ code = xfs_trans_commit(tp, 0);
tp = ntp;
if (committed != NULL) {
*committed = 1;
@@ -420,7 +420,11 @@ xfs_truncate_file(
* in a transaction.
*/
xfs_ilock(ip, XFS_IOLOCK_EXCL);
- xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, (xfs_fsize_t)0);
+ error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, (xfs_fsize_t)0);
+ if (error) {
+ xfs_iunlock(ip, XFS_IOLOCK_EXCL);
+ return error;
+ }
tp = xfs_trans_alloc(mp, XFS_TRANS_TRUNCATE_FILE);
if ((error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
@@ -460,8 +464,7 @@ xfs_truncate_file(
XFS_TRANS_ABORT);
} else {
xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES,
- NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
}
xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 29f72f6..65c5612 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -696,7 +696,7 @@ xfs_unmount_flush(
bhv_vnode_t *rvp = XFS_ITOV(rip);
int error;
- xfs_ilock(rip, XFS_ILOCK_EXCL);
+ xfs_ilock(rip, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
xfs_iflock(rip);
/*
@@ -1147,7 +1147,7 @@ xfs_sync_inodes(
if (XFS_FORCED_SHUTDOWN(mp)) {
bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
} else {
- bhv_vop_flushinval_pages(vp, 0, -1, FI_REMAPF);
+ error = bhv_vop_flushinval_pages(vp, 0, -1, FI_REMAPF);
}
xfs_ilock(ip, XFS_ILOCK_SHARED);
@@ -1539,7 +1539,7 @@ xfs_syncsub(
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
xfs_trans_ihold(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- error = xfs_trans_commit(tp, 0, NULL);
+ error = xfs_trans_commit(tp, 0);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
xfs_log_force(mp, (xfs_lsn_t)0, log_flags);
}
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 52c4171..de17aed 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -133,7 +133,7 @@ xfs_getattr(
if (!(flags & ATTR_LAZY))
xfs_ilock(ip, XFS_ILOCK_SHARED);
- vap->va_size = ip->i_d.di_size;
+ vap->va_size = XFS_ISIZE(ip);
if (vap->va_mask == XFS_AT_SIZE)
goto all_done;
@@ -496,7 +496,7 @@ xfs_setattr(
if (mask & XFS_AT_SIZE) {
/* Short circuit the truncate case for zero length files */
if ((vap->va_size == 0) &&
- (ip->i_d.di_size == 0) && (ip->i_d.di_nextents == 0)) {
+ (ip->i_size == 0) && (ip->i_d.di_nextents == 0)) {
xfs_iunlock(ip, XFS_ILOCK_EXCL);
lock_flags &= ~XFS_ILOCK_EXCL;
if (mask & XFS_AT_CTIME)
@@ -614,7 +614,7 @@ xfs_setattr(
*/
if (mask & XFS_AT_SIZE) {
code = 0;
- if ((vap->va_size > ip->i_d.di_size) &&
+ if ((vap->va_size > ip->i_size) &&
(flags & ATTR_NOSIZETOK) == 0) {
code = xfs_igrow_start(ip, vap->va_size, credp);
}
@@ -654,10 +654,10 @@ xfs_setattr(
* Truncate file. Must have write permission and not be a directory.
*/
if (mask & XFS_AT_SIZE) {
- if (vap->va_size > ip->i_d.di_size) {
+ if (vap->va_size > ip->i_size) {
xfs_igrow_finish(tp, ip, vap->va_size,
!(flags & ATTR_DMI));
- } else if ((vap->va_size <= ip->i_d.di_size) ||
+ } else if ((vap->va_size <= ip->i_size) ||
((vap->va_size == 0) && ip->i_d.di_nextents)) {
/*
* signal a sync transaction unless
@@ -873,7 +873,7 @@ xfs_setattr(
if (mp->m_flags & XFS_MOUNT_WSYNC)
xfs_trans_set_sync(tp);
- code = xfs_trans_commit(tp, commit_flags, NULL);
+ code = xfs_trans_commit(tp, commit_flags);
}
/*
@@ -1176,7 +1176,7 @@ xfs_fsync(
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
if (flag & FSYNC_WAIT)
xfs_trans_set_sync(tp);
- error = _xfs_trans_commit(tp, 0, NULL, &log_flushed);
+ error = _xfs_trans_commit(tp, 0, &log_flushed);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
}
@@ -1221,7 +1221,7 @@ xfs_inactive_free_eofblocks(
* Figure out if there are any blocks beyond the end
* of the file. If not, then there is nothing to do.
*/
- end_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)ip->i_d.di_size));
+ end_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)ip->i_size));
last_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
map_len = last_fsb - end_fsb;
if (map_len <= 0)
@@ -1257,8 +1257,12 @@ xfs_inactive_free_eofblocks(
* do that within a transaction.
*/
xfs_ilock(ip, XFS_IOLOCK_EXCL);
- xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
- ip->i_d.di_size);
+ error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
+ ip->i_size);
+ if (error) {
+ xfs_iunlock(ip, XFS_IOLOCK_EXCL);
+ return error;
+ }
error = xfs_trans_reserve(tp, 0,
XFS_ITRUNCATE_LOG_RES(mp),
@@ -1278,7 +1282,7 @@ xfs_inactive_free_eofblocks(
xfs_trans_ihold(tp, ip);
error = xfs_itruncate_finish(&tp, ip,
- ip->i_d.di_size,
+ ip->i_size,
XFS_DATA_FORK,
0);
/*
@@ -1291,8 +1295,7 @@ xfs_inactive_free_eofblocks(
XFS_TRANS_ABORT));
} else {
error = xfs_trans_commit(tp,
- XFS_TRANS_RELEASE_LOG_RES,
- NULL);
+ XFS_TRANS_RELEASE_LOG_RES);
}
xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
}
@@ -1406,7 +1409,7 @@ xfs_inactive_symlink_rmt(
* we need to unlock the inode since the new transaction doesn't
* have the inode attached.
*/
- error = xfs_trans_commit(tp, 0, NULL);
+ error = xfs_trans_commit(tp, 0);
tp = ntp;
if (error) {
ASSERT(XFS_FORCED_SHUTDOWN(mp));
@@ -1503,7 +1506,7 @@ xfs_inactive_attrs(
tp = *tpp;
mp = ip->i_mount;
ASSERT(ip->i_d.di_forkoff != 0);
- xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
+ xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
error = xfs_attr_inactive(ip);
@@ -1565,7 +1568,7 @@ xfs_release(
if (ip->i_d.di_nlink != 0) {
if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
- ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 ||
+ ((ip->i_size > 0) || (VN_CACHED(vp) > 0 ||
ip->i_delayed_blks > 0)) &&
(ip->i_df.if_flags & XFS_IFEXTENTS)) &&
(!(ip->i_d.di_flags &
@@ -1626,8 +1629,8 @@ xfs_inactive(
* only one with a reference to the inode.
*/
truncate = ((ip->i_d.di_nlink == 0) &&
- ((ip->i_d.di_size != 0) || (ip->i_d.di_nextents > 0) ||
- (ip->i_delayed_blks > 0)) &&
+ ((ip->i_d.di_size != 0) || (ip->i_size != 0) ||
+ (ip->i_d.di_nextents > 0) || (ip->i_delayed_blks > 0)) &&
((ip->i_d.di_mode & S_IFMT) == S_IFREG));
mp = ip->i_mount;
@@ -1645,7 +1648,7 @@ xfs_inactive(
if (ip->i_d.di_nlink != 0) {
if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
- ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 ||
+ ((ip->i_size > 0) || (VN_CACHED(vp) > 0 ||
ip->i_delayed_blks > 0)) &&
(ip->i_df.if_flags & XFS_IFEXTENTS) &&
(!(ip->i_d.di_flags &
@@ -1675,7 +1678,11 @@ xfs_inactive(
*/
xfs_ilock(ip, XFS_IOLOCK_EXCL);
- xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 0);
+ error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 0);
+ if (error) {
+ xfs_iunlock(ip, XFS_IOLOCK_EXCL);
+ return VN_INACTIVE_CACHE;
+ }
error = xfs_trans_reserve(tp, 0,
XFS_ITRUNCATE_LOG_RES(mp),
@@ -1790,7 +1797,7 @@ xfs_inactive(
* nothing we can do except to try to keep going.
*/
(void) xfs_bmap_finish(&tp, &free_list, &committed);
- (void) xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
+ (void) xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
}
/*
* Release the dquots held by inode, if any.
@@ -1940,7 +1947,7 @@ xfs_create(
goto error_return;
}
- xfs_ilock(dp, XFS_ILOCK_EXCL);
+ xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
XFS_BMAP_INIT(&free_list, &first_block);
@@ -2026,7 +2033,7 @@ xfs_create(
goto abort_rele;
}
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
if (error) {
IRELE(ip);
tp = NULL;
@@ -2121,7 +2128,6 @@ int xfs_rm_attempts;
STATIC int
xfs_lock_dir_and_entry(
xfs_inode_t *dp,
- bhv_vname_t *dentry,
xfs_inode_t *ip) /* inode of entry 'name' */
{
int attempts;
@@ -2135,7 +2141,7 @@ xfs_lock_dir_and_entry(
attempts = 0;
again:
- xfs_ilock(dp, XFS_ILOCK_EXCL);
+ xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
e_inum = ip->i_ino;
@@ -2204,6 +2210,21 @@ int xfs_lock_delays;
#endif
/*
+ * Bump the subclass so xfs_lock_inodes() acquires each lock with
+ * a different value
+ */
+static inline int
+xfs_lock_inumorder(int lock_mode, int subclass)
+{
+ if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL))
+ lock_mode |= (subclass + XFS_IOLOCK_INUMORDER) << XFS_IOLOCK_SHIFT;
+ if (lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL))
+ lock_mode |= (subclass + XFS_ILOCK_INUMORDER) << XFS_ILOCK_SHIFT;
+
+ return lock_mode;
+}
+
+/*
* The following routine will lock n inodes in exclusive mode.
* We assume the caller calls us with the inodes in i_ino order.
*
@@ -2270,7 +2291,7 @@ again:
* that is in the AIL.
*/
ASSERT(i != 0);
- if (!xfs_ilock_nowait(ips[i], lock_mode)) {
+ if (!xfs_ilock_nowait(ips[i], xfs_lock_inumorder(lock_mode, i))) {
attempts++;
/*
@@ -2305,7 +2326,7 @@ again:
goto again;
}
} else {
- xfs_ilock(ips[i], lock_mode);
+ xfs_ilock(ips[i], xfs_lock_inumorder(lock_mode, i));
}
}
@@ -2440,7 +2461,7 @@ xfs_remove(
return error;
}
- error = xfs_lock_dir_and_entry(dp, dentry, ip);
+ error = xfs_lock_dir_and_entry(dp, ip);
if (error) {
REMOVE_DEBUG_TRACE(__LINE__);
xfs_trans_cancel(tp, cancel_flags);
@@ -2511,7 +2532,7 @@ xfs_remove(
goto error_rele;
}
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
if (error) {
IRELE(ip);
goto std_return;
@@ -2719,7 +2740,7 @@ xfs_link(
goto abort_return;
}
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
if (error)
goto std_return;
@@ -2839,7 +2860,7 @@ xfs_mkdir(
goto error_return;
}
- xfs_ilock(dp, XFS_ILOCK_EXCL);
+ xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
/*
* Check for directory link count overflow.
@@ -2936,7 +2957,7 @@ xfs_mkdir(
goto error2;
}
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
XFS_QM_DQRELE(mp, udqp);
XFS_QM_DQRELE(mp, gdqp);
if (error) {
@@ -3096,7 +3117,7 @@ xfs_rmdir(
* that the directory entry for the child directory inode has
* not changed while we were obtaining a log reservation.
*/
- error = xfs_lock_dir_and_entry(dp, dentry, cdp);
+ error = xfs_lock_dir_and_entry(dp, cdp);
if (error) {
xfs_trans_cancel(tp, cancel_flags);
IRELE(cdp);
@@ -3190,7 +3211,7 @@ xfs_rmdir(
goto std_return;
}
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
if (error) {
IRELE(cdp);
goto std_return;
@@ -3393,7 +3414,7 @@ xfs_symlink(
goto error_return;
}
- xfs_ilock(dp, XFS_ILOCK_EXCL);
+ xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
/*
* Check whether the directory allows new symlinks or not.
@@ -3535,7 +3556,7 @@ xfs_symlink(
if (error) {
goto error2;
}
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
XFS_QM_DQRELE(mp, udqp);
XFS_QM_DQRELE(mp, gdqp);
@@ -3790,7 +3811,7 @@ xfs_set_dmattrs (
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
IHOLD(ip);
- error = xfs_trans_commit(tp, 0, NULL);
+ error = xfs_trans_commit(tp, 0);
return error;
}
@@ -4049,14 +4070,14 @@ xfs_alloc_file_space(
allocatesize_fsb = XFS_B_TO_FSB(mp, count);
/* Generate a DMAPI event if needed. */
- if (alloc_type != 0 && offset < ip->i_d.di_size &&
+ if (alloc_type != 0 && offset < ip->i_size &&
(attr_flags&ATTR_DMI) == 0 &&
DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
xfs_off_t end_dmi_offset;
end_dmi_offset = offset+len;
- if (end_dmi_offset > ip->i_d.di_size)
- end_dmi_offset = ip->i_d.di_size;
+ if (end_dmi_offset > ip->i_size)
+ end_dmi_offset = ip->i_size;
error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip),
offset, end_dmi_offset - offset,
0, NULL);
@@ -4148,7 +4169,7 @@ retry:
goto error0;
}
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
if (error) {
break;
@@ -4283,7 +4304,6 @@ xfs_free_file_space(
int error;
xfs_fsblock_t firstfsb;
xfs_bmap_free_t free_list;
- xfs_off_t ilen;
xfs_bmbt_irec_t imap;
xfs_off_t ioffset;
xfs_extlen_t mod=0;
@@ -4312,11 +4332,11 @@ xfs_free_file_space(
end_dmi_offset = offset + len;
endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset);
- if (offset < ip->i_d.di_size &&
+ if (offset < ip->i_size &&
(attr_flags & ATTR_DMI) == 0 &&
DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
- if (end_dmi_offset > ip->i_d.di_size)
- end_dmi_offset = ip->i_d.di_size;
+ if (end_dmi_offset > ip->i_size)
+ end_dmi_offset = ip->i_size;
error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp,
offset, end_dmi_offset - offset,
AT_DELAY_FLAG(attr_flags), NULL);
@@ -4332,16 +4352,15 @@ xfs_free_file_space(
}
rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP);
- ilen = len + (offset & (rounding - 1));
ioffset = offset & ~(rounding - 1);
- if (ilen & (rounding - 1))
- ilen = (ilen + rounding) & ~(rounding - 1);
if (VN_CACHED(vp) != 0) {
xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
ctooff(offtoct(ioffset)), -1);
- bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)),
+ error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)),
-1, FI_REMAPF_LOCKED);
+ if (error)
+ goto out_unlock_iolock;
}
/*
@@ -4455,7 +4474,7 @@ xfs_free_file_space(
goto error0;
}
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
+ error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
}
@@ -4533,7 +4552,7 @@ xfs_change_file_space(
bf->l_start += offset;
break;
case 2: /*SEEK_END*/
- bf->l_start += ip->i_d.di_size;
+ bf->l_start += ip->i_size;
break;
default:
return XFS_ERROR(EINVAL);
@@ -4550,7 +4569,7 @@ xfs_change_file_space(
bf->l_whence = 0;
startoffset = bf->l_start;
- fsize = ip->i_d.di_size;
+ fsize = ip->i_size;
/*
* XFS_IOC_RESVSP and XFS_IOC_UNRESVSP will reserve or unreserve
@@ -4649,7 +4668,7 @@ xfs_change_file_space(
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
xfs_trans_set_sync(tp);
- error = xfs_trans_commit(tp, 0, NULL);
+ error = xfs_trans_commit(tp, 0);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 16c3c44..9cfd5b1 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -303,6 +303,9 @@ struct acpi_device {
#define to_acpi_device(d) container_of(d, struct acpi_device, dev)
#define to_acpi_driver(d) container_of(d, struct acpi_driver, drv)
+/* acpi_device.dev.bus == &acpi_bus_type */
+extern struct bus_type acpi_bus_type;
+
/*
* Events
* ------
diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h
index fc77f74..f5cb7b8 100644
--- a/include/asm-alpha/atomic.h
+++ b/include/asm-alpha/atomic.h
@@ -2,6 +2,7 @@
#define _ALPHA_ATOMIC_H
#include <asm/barrier.h>
+#include <asm/system.h>
/*
* Atomic operations that C can't guarantee us. Useful for
@@ -175,19 +176,64 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
return result;
}
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
- c = old; \
- c != (u); \
-})
+/**
+ * atomic_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+ long c, old;
+ c = atomic64_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic64_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
diff --git a/include/asm-alpha/kdebug.h b/include/asm-alpha/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-alpha/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-alpha/local.h b/include/asm-alpha/local.h
index 90a510f..6ad3ea6 100644
--- a/include/asm-alpha/local.h
+++ b/include/asm-alpha/local.h
@@ -4,37 +4,115 @@
#include <linux/percpu.h>
#include <asm/atomic.h>
-typedef atomic64_t local_t;
+typedef struct
+{
+ atomic_long_t a;
+} local_t;
-#define LOCAL_INIT(i) ATOMIC64_INIT(i)
-#define local_read(v) atomic64_read(v)
-#define local_set(v,i) atomic64_set(v,i)
+#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
+#define local_read(l) atomic_long_read(&(l)->a)
+#define local_set(l,i) atomic_long_set(&(l)->a, (i))
+#define local_inc(l) atomic_long_inc(&(l)->a)
+#define local_dec(l) atomic_long_dec(&(l)->a)
+#define local_add(i,l) atomic_long_add((i),(&(l)->a))
+#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
-#define local_inc(v) atomic64_inc(v)
-#define local_dec(v) atomic64_dec(v)
-#define local_add(i, v) atomic64_add(i, v)
-#define local_sub(i, v) atomic64_sub(i, v)
+static __inline__ long local_add_return(long i, local_t * l)
+{
+ long temp, result;
+ __asm__ __volatile__(
+ "1: ldq_l %0,%1\n"
+ " addq %0,%3,%2\n"
+ " addq %0,%3,%0\n"
+ " stq_c %0,%1\n"
+ " beq %0,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (l->a.counter), "=&r" (result)
+ :"Ir" (i), "m" (l->a.counter) : "memory");
+ return result;
+}
-#define __local_inc(v) ((v)->counter++)
-#define __local_dec(v) ((v)->counter++)
-#define __local_add(i,v) ((v)->counter+=(i))
-#define __local_sub(i,v) ((v)->counter-=(i))
+static __inline__ long local_sub_return(long i, local_t * l)
+{
+ long temp, result;
+ __asm__ __volatile__(
+ "1: ldq_l %0,%1\n"
+ " subq %0,%3,%2\n"
+ " subq %0,%3,%0\n"
+ " stq_c %0,%1\n"
+ " beq %0,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (l->a.counter), "=&r" (result)
+ :"Ir" (i), "m" (l->a.counter) : "memory");
+ return result;
+}
+
+#define local_cmpxchg(l, o, n) \
+ (cmpxchg_local(&((l)->a.counter), (o), (n)))
+#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
+
+/**
+ * local_add_unless - add unless the number is a given value
+ * @l: pointer of type local_t
+ * @a: the amount to add to l...
+ * @u: ...unless l is equal to u.
+ *
+ * Atomically adds @a to @l, so long as it was not @u.
+ * Returns non-zero if @l was not @u, and zero otherwise.
+ */
+#define local_add_unless(l, a, u) \
+({ \
+ long c, old; \
+ c = local_read(l); \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = local_cmpxchg((l), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
+ c = old; \
+ } \
+ c != (u); \
+})
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_add_negative(a, l) (local_add_return((a), (l)) < 0)
+
+#define local_dec_return(l) local_sub_return(1,(l))
+
+#define local_inc_return(l) local_add_return(1,(l))
+
+#define local_sub_and_test(i,l) (local_sub_return((i), (l)) == 0)
+
+#define local_inc_and_test(l) (local_add_return(1, (l)) == 0)
+
+#define local_dec_and_test(l) (local_sub_return(1, (l)) == 0)
+
+/* Verify if faster than atomic ops */
+#define __local_inc(l) ((l)->a.counter++)
+#define __local_dec(l) ((l)->a.counter++)
+#define __local_add(i,l) ((l)->a.counter+=(i))
+#define __local_sub(i,l) ((l)->a.counter-=(i))
/* Use these for per-cpu local_t variables: on some archs they are
* much more efficient than these naive implementations. Note they take
* a variable, not an address.
*/
-#define cpu_local_read(v) local_read(&__get_cpu_var(v))
-#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i))
-
-#define cpu_local_inc(v) local_inc(&__get_cpu_var(v))
-#define cpu_local_dec(v) local_dec(&__get_cpu_var(v))
-#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v))
-#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v))
-
-#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v))
-#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v))
-#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v))
-#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v))
+#define cpu_local_read(l) local_read(&__get_cpu_var(l))
+#define cpu_local_set(l, i) local_set(&__get_cpu_var(l), (i))
+
+#define cpu_local_inc(l) local_inc(&__get_cpu_var(l))
+#define cpu_local_dec(l) local_dec(&__get_cpu_var(l))
+#define cpu_local_add(i, l) local_add((i), &__get_cpu_var(l))
+#define cpu_local_sub(i, l) local_sub((i), &__get_cpu_var(l))
+
+#define __cpu_local_inc(l) __local_inc(&__get_cpu_var(l))
+#define __cpu_local_dec(l) __local_dec(&__get_cpu_var(l))
+#define __cpu_local_add(i, l) __local_add((i), &__get_cpu_var(l))
+#define __cpu_local_sub(i, l) __local_sub((i), &__get_cpu_var(l))
#endif /* _ALPHA_LOCAL_H */
diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
index 49ac9be..616d206 100644
--- a/include/asm-alpha/pgtable.h
+++ b/include/asm-alpha/pgtable.h
@@ -345,10 +345,6 @@ extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
#define io_remap_pfn_range(vma, start, pfn, size, prot) \
remap_pfn_range(vma, start, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#define pte_ERROR(e) \
printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
#define pmd_ERROR(e) \
diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h
index 03e9c0e..cf1021a 100644
--- a/include/asm-alpha/system.h
+++ b/include/asm-alpha/system.h
@@ -443,8 +443,110 @@ extern void __xchg_called_with_bad_pointer(void);
(__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
})
-#define tas(ptr) (xchg((ptr),1))
+static inline unsigned long
+__xchg_u8_local(volatile char *m, unsigned long val)
+{
+ unsigned long ret, tmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %4,7,%3\n"
+ " insbl %1,%4,%1\n"
+ "1: ldq_l %2,0(%3)\n"
+ " extbl %2,%4,%0\n"
+ " mskbl %2,%4,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%3)\n"
+ " beq %2,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
+ : "r" ((long)m), "1" (val) : "memory");
+ return ret;
+}
+
+static inline unsigned long
+__xchg_u16_local(volatile short *m, unsigned long val)
+{
+ unsigned long ret, tmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %4,7,%3\n"
+ " inswl %1,%4,%1\n"
+ "1: ldq_l %2,0(%3)\n"
+ " extwl %2,%4,%0\n"
+ " mskwl %2,%4,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%3)\n"
+ " beq %2,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
+ : "r" ((long)m), "1" (val) : "memory");
+
+ return ret;
+}
+
+static inline unsigned long
+__xchg_u32_local(volatile int *m, unsigned long val)
+{
+ unsigned long dummy;
+
+ __asm__ __volatile__(
+ "1: ldl_l %0,%4\n"
+ " bis $31,%3,%1\n"
+ " stl_c %1,%2\n"
+ " beq %1,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ : "=&r" (val), "=&r" (dummy), "=m" (*m)
+ : "rI" (val), "m" (*m) : "memory");
+
+ return val;
+}
+
+static inline unsigned long
+__xchg_u64_local(volatile long *m, unsigned long val)
+{
+ unsigned long dummy;
+
+ __asm__ __volatile__(
+ "1: ldq_l %0,%4\n"
+ " bis $31,%3,%1\n"
+ " stq_c %1,%2\n"
+ " beq %1,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ : "=&r" (val), "=&r" (dummy), "=m" (*m)
+ : "rI" (val), "m" (*m) : "memory");
+
+ return val;
+}
+
+#define __xchg_local(ptr, x, size) \
+({ \
+ unsigned long __xchg__res; \
+ volatile void *__xchg__ptr = (ptr); \
+ switch (size) { \
+ case 1: __xchg__res = __xchg_u8_local(__xchg__ptr, x); break; \
+ case 2: __xchg__res = __xchg_u16_local(__xchg__ptr, x); break; \
+ case 4: __xchg__res = __xchg_u32_local(__xchg__ptr, x); break; \
+ case 8: __xchg__res = __xchg_u64_local(__xchg__ptr, x); break; \
+ default: __xchg_called_with_bad_pointer(); __xchg__res = x; \
+ } \
+ __xchg__res; \
+})
+
+#define xchg_local(ptr,x) \
+ ({ \
+ __typeof__(*(ptr)) _x_ = (x); \
+ (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \
+ sizeof(*(ptr))); \
+ })
/*
* Atomic compare and exchange. Compare OLD with MEM, if identical,
@@ -596,6 +698,128 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
(unsigned long)_n_, sizeof(*(ptr))); \
})
+static inline unsigned long
+__cmpxchg_u8_local(volatile char *m, long old, long new)
+{
+ unsigned long prev, tmp, cmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %5,7,%4\n"
+ " insbl %1,%5,%1\n"
+ "1: ldq_l %2,0(%4)\n"
+ " extbl %2,%5,%0\n"
+ " cmpeq %0,%6,%3\n"
+ " beq %3,2f\n"
+ " mskbl %2,%5,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%4)\n"
+ " beq %2,3f\n"
+ "2:\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
+ : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
+
+ return prev;
+}
+
+static inline unsigned long
+__cmpxchg_u16_local(volatile short *m, long old, long new)
+{
+ unsigned long prev, tmp, cmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %5,7,%4\n"
+ " inswl %1,%5,%1\n"
+ "1: ldq_l %2,0(%4)\n"
+ " extwl %2,%5,%0\n"
+ " cmpeq %0,%6,%3\n"
+ " beq %3,2f\n"
+ " mskwl %2,%5,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%4)\n"
+ " beq %2,3f\n"
+ "2:\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
+ : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
+
+ return prev;
+}
+
+static inline unsigned long
+__cmpxchg_u32_local(volatile int *m, int old, int new)
+{
+ unsigned long prev, cmp;
+
+ __asm__ __volatile__(
+ "1: ldl_l %0,%5\n"
+ " cmpeq %0,%3,%1\n"
+ " beq %1,2f\n"
+ " mov %4,%1\n"
+ " stl_c %1,%2\n"
+ " beq %1,3f\n"
+ "2:\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r"(prev), "=&r"(cmp), "=m"(*m)
+ : "r"((long) old), "r"(new), "m"(*m) : "memory");
+
+ return prev;
+}
+
+static inline unsigned long
+__cmpxchg_u64_local(volatile long *m, unsigned long old, unsigned long new)
+{
+ unsigned long prev, cmp;
+
+ __asm__ __volatile__(
+ "1: ldq_l %0,%5\n"
+ " cmpeq %0,%3,%1\n"
+ " beq %1,2f\n"
+ " mov %4,%1\n"
+ " stq_c %1,%2\n"
+ " beq %1,3f\n"
+ "2:\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r"(prev), "=&r"(cmp), "=m"(*m)
+ : "r"((long) old), "r"(new), "m"(*m) : "memory");
+
+ return prev;
+}
+
+static __always_inline unsigned long
+__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
+ int size)
+{
+ switch (size) {
+ case 1:
+ return __cmpxchg_u8_local(ptr, old, new);
+ case 2:
+ return __cmpxchg_u16_local(ptr, old, new);
+ case 4:
+ return __cmpxchg_u32_local(ptr, old, new);
+ case 8:
+ return __cmpxchg_u64_local(ptr, old, new);
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
+
+#define cmpxchg_local(ptr,o,n) \
+ ({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \
+ (unsigned long)_n_, sizeof(*(ptr))); \
+ })
+
#endif /* __ASSEMBLY__ */
#define arch_align_stack(x) (x)
diff --git a/include/asm-alpha/thread_info.h b/include/asm-alpha/thread_info.h
index 69ffd93..eeb3bef 100644
--- a/include/asm-alpha/thread_info.h
+++ b/include/asm-alpha/thread_info.h
@@ -92,5 +92,27 @@ register struct thread_info *__current_thread_info __asm__("$8");
#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \
| _TIF_SYSCALL_TRACE)
+#define ALPHA_UAC_SHIFT 6
+#define ALPHA_UAC_MASK (1 << TIF_UAC_NOPRINT | 1 << TIF_UAC_NOFIX | \
+ 1 << TIF_UAC_SIGBUS)
+
+#define SET_UNALIGN_CTL(task,value) ({ \
+ (task)->thread_info->flags = (((task)->thread_info->flags & \
+ ~ALPHA_UAC_MASK) \
+ | (((value) << ALPHA_UAC_SHIFT) & (1<<TIF_UAC_NOPRINT))\
+ | (((value) << (ALPHA_UAC_SHIFT + 1)) & (1<<TIF_UAC_SIGBUS)) \
+ | (((value) << (ALPHA_UAC_SHIFT - 1)) & (1<<TIF_UAC_NOFIX)));\
+ 0; })
+
+#define GET_UNALIGN_CTL(task,value) ({ \
+ put_user(((task)->thread_info->flags & (1 << TIF_UAC_NOPRINT)) \
+ >> ALPHA_UAC_SHIFT \
+ | ((task)->thread_info->flags & (1 << TIF_UAC_SIGBUS)) \
+ >> (ALPHA_UAC_SHIFT + 1) \
+ | ((task)->thread_info->flags & (1 << TIF_UAC_NOFIX)) \
+ >> (ALPHA_UAC_SHIFT - 1), \
+ (int __user *)(value)); \
+ })
+
#endif /* __KERNEL__ */
#endif /* _ALPHA_THREAD_INFO_H */
diff --git a/include/asm-arm/arch-at91/at91_adc.h b/include/asm-arm/arch-at91/at91_adc.h
new file mode 100644
index 0000000..1ed66ea
--- /dev/null
+++ b/include/asm-arm/arch-at91/at91_adc.h
@@ -0,0 +1,61 @@
+/*
+ * include/asm-arm/arch-at91/at91_adc.h
+ *
+ * Copyright (C) SAN People
+ *
+ * Analog-to-Digital Converter (ADC) registers.
+ * Based on AT91SAM9260 datasheet revision D.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef AT91_ADC_H
+#define AT91_ADC_H
+
+#define AT91_ADC_CR 0x00 /* Control Register */
+#define AT91_ADC_SWRST (1 << 0) /* Software Reset */
+#define AT91_ADC_START (1 << 1) /* Start Conversion */
+
+#define AT91_ADC_MR 0x04 /* Mode Register */
+#define AT91_ADC_TRGEN (1 << 0) /* Trigger Enable */
+#define AT91_ADC_TRGSEL (7 << 1) /* Trigger Selection */
+#define AT91_ADC_TRGSEL_TC0 (0 << 1)
+#define AT91_ADC_TRGSEL_TC1 (1 << 1)
+#define AT91_ADC_TRGSEL_TC2 (2 << 1)
+#define AT91_ADC_TRGSEL_EXTERNAL (6 << 1)
+#define AT91_ADC_LOWRES (1 << 4) /* Low Resolution */
+#define AT91_ADC_SLEEP (1 << 5) /* Sleep Mode */
+#define AT91_ADC_PRESCAL (0x3f << 8) /* Prescalar Rate Selection */
+#define AT91_ADC_PRESCAL_(x) ((x) << 8)
+#define AT91_ADC_STARTUP (0x1f << 16) /* Startup Up Time */
+#define AT91_ADC_STARTUP_(x) ((x) << 16)
+#define AT91_ADC_SHTIM (0xf << 24) /* Sample & Hold Time */
+#define AT91_ADC_SHTIM_(x) ((x) << 24)
+
+#define AT91_ADC_CHER 0x10 /* Channel Enable Register */
+#define AT91_ADC_CHDR 0x14 /* Channel Disable Register */
+#define AT91_ADC_CHSR 0x18 /* Channel Status Register */
+#define AT91_ADC_CH(n) (1 << (n)) /* Channel Number */
+
+#define AT91_ADC_SR 0x1C /* Status Register */
+#define AT91_ADC_EOC(n) (1 << (n)) /* End of Conversion on Channel N */
+#define AT91_ADC_OVRE(n) (1 << ((n) + 8))/* Overrun Error on Channel N */
+#define AT91_ADC_DRDY (1 << 16) /* Data Ready */
+#define AT91_ADC_GOVRE (1 << 17) /* General Overrun Error */
+#define AT91_ADC_ENDRX (1 << 18) /* End of RX Buffer */
+#define AT91_ADC_RXFUFF (1 << 19) /* RX Buffer Full */
+
+#define AT91_ADC_LCDR 0x20 /* Last Converted Data Register */
+#define AT91_ADC_LDATA (0x3ff)
+
+#define AT91_ADC_IER 0x24 /* Interrupt Enable Register */
+#define AT91_ADC_IDR 0x28 /* Interrupt Disable Register */
+#define AT91_ADC_IMR 0x2C /* Interrupt Mask Register */
+
+#define AT91_ADC_CHR(n) (0x30 + ((n) * 4) /* Channel Data Register N */
+#define AT91_ADC_DATA (0x3ff)
+
+#endif
diff --git a/include/asm-arm/arch-at91/board.h b/include/asm-arm/arch-at91/board.h
index 7b9903c..7a34a5b 100644
--- a/include/asm-arm/arch-at91/board.h
+++ b/include/asm-arm/arch-at91/board.h
@@ -62,7 +62,7 @@ struct at91_mmc_data {
};
extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data);
- /* Ethernet */
+ /* Ethernet (EMAC & MACB) */
struct at91_eth_data {
u8 phy_irq_pin; /* PHY IRQ */
u8 is_rmii; /* using RMII interface? */
@@ -114,6 +114,16 @@ struct atmel_uart_data {
};
extern void __init at91_add_device_serial(void);
+ /* LCD Controller */
+struct atmel_lcdfb_info;
+extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data);
+
+ /* AC97 */
+struct atmel_ac97_data {
+ u8 reset_pin; /* reset */
+}
+extern void __init at91_add_device_ac97(struct atmel_ac97_data *data);
+
/* LEDs */
extern u8 at91_leds_cpu;
extern u8 at91_leds_timer;
diff --git a/include/asm-arm/arch-ebsa110/io.h b/include/asm-arm/arch-ebsa110/io.h
index 722c5e0..44a4001 100644
--- a/include/asm-arm/arch-ebsa110/io.h
+++ b/include/asm-arm/arch-ebsa110/io.h
@@ -81,4 +81,12 @@ extern void outsb(unsigned int port, const void *buf, int sz);
extern void outsw(unsigned int port, const void *buf, int sz);
extern void outsl(unsigned int port, const void *buf, int sz);
+/* can't support writesb atm */
+extern void writesw(void __iomem *addr, const void *data, int wordlen);
+extern void writesl(void __iomem *addr, const void *data, int longlen);
+
+/* can't support readsb atm */
+extern void readsw(const void __iomem *addr, void *data, int wordlen);
+extern void readsl(const void __iomem *addr, void *data, int longlen);
+
#endif
diff --git a/include/asm-arm/arch-imx/imx-regs.h b/include/asm-arm/arch-imx/imx-regs.h
index e56a4e2..de6494a 100644
--- a/include/asm-arm/arch-imx/imx-regs.h
+++ b/include/asm-arm/arch-imx/imx-regs.h
@@ -477,122 +477,4 @@
#define LCDISR_EOF (1<<1)
#define LCDISR_BOF (1<<0)
-/*
- * UART Module. Takes the UART base address as argument
- */
-#define URXD0(x) __REG( 0x0 + (x)) /* Receiver Register */
-#define URTX0(x) __REG( 0x40 + (x)) /* Transmitter Register */
-#define UCR1(x) __REG( 0x80 + (x)) /* Control Register 1 */
-#define UCR2(x) __REG( 0x84 + (x)) /* Control Register 2 */
-#define UCR3(x) __REG( 0x88 + (x)) /* Control Register 3 */
-#define UCR4(x) __REG( 0x8c + (x)) /* Control Register 4 */
-#define UFCR(x) __REG( 0x90 + (x)) /* FIFO Control Register */
-#define USR1(x) __REG( 0x94 + (x)) /* Status Register 1 */
-#define USR2(x) __REG( 0x98 + (x)) /* Status Register 2 */
-#define UESC(x) __REG( 0x9c + (x)) /* Escape Character Register */
-#define UTIM(x) __REG( 0xa0 + (x)) /* Escape Timer Register */
-#define UBIR(x) __REG( 0xa4 + (x)) /* BRM Incremental Register */
-#define UBMR(x) __REG( 0xa8 + (x)) /* BRM Modulator Register */
-#define UBRC(x) __REG( 0xac + (x)) /* Baud Rate Count Register */
-#define BIPR1(x) __REG( 0xb0 + (x)) /* Incremental Preset Register 1 */
-#define BIPR2(x) __REG( 0xb4 + (x)) /* Incremental Preset Register 2 */
-#define BIPR3(x) __REG( 0xb8 + (x)) /* Incremental Preset Register 3 */
-#define BIPR4(x) __REG( 0xbc + (x)) /* Incremental Preset Register 4 */
-#define BMPR1(x) __REG( 0xc0 + (x)) /* BRM Modulator Register 1 */
-#define BMPR2(x) __REG( 0xc4 + (x)) /* BRM Modulator Register 2 */
-#define BMPR3(x) __REG( 0xc8 + (x)) /* BRM Modulator Register 3 */
-#define BMPR4(x) __REG( 0xcc + (x)) /* BRM Modulator Register 4 */
-#define UTS(x) __REG( 0xd0 + (x)) /* UART Test Register */
-
-/* UART Control Register Bit Fields.*/
-#define URXD_CHARRDY (1<<15)
-#define URXD_ERR (1<<14)
-#define URXD_OVRRUN (1<<13)
-#define URXD_FRMERR (1<<12)
-#define URXD_BRK (1<<11)
-#define URXD_PRERR (1<<10)
-#define UCR1_ADEN (1<<15) /* Auto dectect interrupt */
-#define UCR1_ADBR (1<<14) /* Auto detect baud rate */
-#define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */
-#define UCR1_IDEN (1<<12) /* Idle condition interrupt */
-#define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */
-#define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */
-#define UCR1_IREN (1<<7) /* Infrared interface enable */
-#define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */
-#define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */
-#define UCR1_SNDBRK (1<<4) /* Send break */
-#define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */
-#define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */
-#define UCR1_DOZE (1<<1) /* Doze */
-#define UCR1_UARTEN (1<<0) /* UART enabled */
-#define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */
-#define UCR2_IRTS (1<<14) /* Ignore RTS pin */
-#define UCR2_CTSC (1<<13) /* CTS pin control */
-#define UCR2_CTS (1<<12) /* Clear to send */
-#define UCR2_ESCEN (1<<11) /* Escape enable */
-#define UCR2_PREN (1<<8) /* Parity enable */
-#define UCR2_PROE (1<<7) /* Parity odd/even */
-#define UCR2_STPB (1<<6) /* Stop */
-#define UCR2_WS (1<<5) /* Word size */
-#define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */
-#define UCR2_TXEN (1<<2) /* Transmitter enabled */
-#define UCR2_RXEN (1<<1) /* Receiver enabled */
-#define UCR2_SRST (1<<0) /* SW reset */
-#define UCR3_DTREN (1<<13) /* DTR interrupt enable */
-#define UCR3_PARERREN (1<<12) /* Parity enable */
-#define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */
-#define UCR3_DSR (1<<10) /* Data set ready */
-#define UCR3_DCD (1<<9) /* Data carrier detect */
-#define UCR3_RI (1<<8) /* Ring indicator */
-#define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */
-#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */
-#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */
-#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
-#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */
-#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */
-#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */
-#define UCR3_BPEN (1<<0) /* Preset registers enable */
-#define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */
-#define UCR4_INVR (1<<9) /* Inverted infrared reception */
-#define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */
-#define UCR4_WKEN (1<<7) /* Wake interrupt enable */
-#define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */
-#define UCR4_IRSC (1<<5) /* IR special case */
-#define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */
-#define UCR4_BKEN (1<<2) /* Break condition interrupt enable */
-#define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */
-#define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */
-#define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */
-#define UFCR_RFDIV (7<<7) /* Reference freq divider mask */
-#define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */
-#define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */
-#define USR1_RTSS (1<<14) /* RTS pin status */
-#define USR1_TRDY (1<<13) /* Transmitter ready interrupt/dma flag */
-#define USR1_RTSD (1<<12) /* RTS delta */
-#define USR1_ESCF (1<<11) /* Escape seq interrupt flag */
-#define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */
-#define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */
-#define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */
-#define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */
-#define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */
-#define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */
-#define USR2_ADET (1<<15) /* Auto baud rate detect complete */
-#define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */
-#define USR2_DTRF (1<<13) /* DTR edge interrupt flag */
-#define USR2_IDLE (1<<12) /* Idle condition */
-#define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */
-#define USR2_WAKE (1<<7) /* Wake */
-#define USR2_RTSF (1<<4) /* RTS edge interrupt flag */
-#define USR2_TXDC (1<<3) /* Transmitter complete */
-#define USR2_BRCD (1<<2) /* Break condition */
-#define USR2_ORE (1<<1) /* Overrun error */
-#define USR2_RDR (1<<0) /* Recv data ready */
-#define UTS_FRCPERR (1<<13) /* Force parity error */
-#define UTS_LOOP (1<<12) /* Loop tx and rx */
-#define UTS_TXEMPTY (1<<6) /* TxFIFO empty */
-#define UTS_RXEMPTY (1<<5) /* RxFIFO empty */
-#define UTS_TXFULL (1<<4) /* TxFIFO full */
-#define UTS_RXFULL (1<<3) /* RxFIFO full */
-#define UTS_SOFTRST (1<<0) /* Software reset */
-
#endif // _IMX_REGS_H
diff --git a/include/asm-arm/arch-iop13xx/io.h b/include/asm-arm/arch-iop13xx/io.h
index 5a7bdb5..7dfff4a 100644
--- a/include/asm-arm/arch-iop13xx/io.h
+++ b/include/asm-arm/arch-iop13xx/io.h
@@ -26,7 +26,6 @@
#define __mem_isa(a) (a)
extern void __iomem * __iop13xx_io(unsigned long io_addr);
-extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
extern void __iomem *__iop13xx_ioremap(unsigned long cookie, size_t size,
unsigned long flags);
extern void __iop13xx_iounmap(void __iomem *addr);
diff --git a/include/asm-arm/arch-iop13xx/iop13xx.h b/include/asm-arm/arch-iop13xx/iop13xx.h
index d26b755..85707e9 100644
--- a/include/asm-arm/arch-iop13xx/iop13xx.h
+++ b/include/asm-arm/arch-iop13xx/iop13xx.h
@@ -8,6 +8,7 @@ extern u32 iop13xx_atue_pmmr_offset;
void iop13xx_init_irq(void);
void iop13xx_map_io(void);
void iop13xx_platform_init(void);
+void iop13xx_add_tpmi_devices(void);
void iop13xx_init_irq(void);
/* CPUID CP6 R0 Page 0 */
@@ -27,19 +28,24 @@ static inline int iop13xx_cpu_id(void)
#define IOP13XX_PCI_OFFSET IOP13XX_MAX_RAM_SIZE
/* PCI MAP
- * 0x0000.0000 - 0x8000.0000 1:1 mapping with Physical RAM
- * 0x8000.0000 - 0x8800.0000 PCIX/PCIE memory window (128MB)
-*/
+ * bus range cpu phys cpu virt note
+ * 0x0000.0000 + 2GB (n/a) (n/a) inbound, 1:1 mapping with Physical RAM
+ * 0x8000.0000 + 928M 0x1.8000.0000 (ioremap) PCIX outbound memory window
+ * 0x8000.0000 + 928M 0x2.8000.0000 (ioremap) PCIE outbound memory window
+ *
+ * IO MAP
+ * 0x1000 + 64K 0x0.fffb.1000 0xfec6.1000 PCIX outbound i/o window
+ * 0x1000 + 64K 0x0.fffd.1000 0xfed7.1000 PCIE outbound i/o window
+ */
#define IOP13XX_PCIX_IO_WINDOW_SIZE 0x10000UL
#define IOP13XX_PCIX_LOWER_IO_PA 0xfffb0000UL
#define IOP13XX_PCIX_LOWER_IO_VA 0xfec60000UL
-#define IOP13XX_PCIX_LOWER_IO_BA 0x0fff0000UL
+#define IOP13XX_PCIX_LOWER_IO_BA 0x0UL /* OIOTVR */
+#define IOP13XX_PCIX_IO_BUS_OFFSET 0x1000UL
#define IOP13XX_PCIX_UPPER_IO_PA (IOP13XX_PCIX_LOWER_IO_PA +\
IOP13XX_PCIX_IO_WINDOW_SIZE - 1)
#define IOP13XX_PCIX_UPPER_IO_VA (IOP13XX_PCIX_LOWER_IO_VA +\
IOP13XX_PCIX_IO_WINDOW_SIZE - 1)
-#define IOP13XX_PCIX_IO_OFFSET (IOP13XX_PCIX_LOWER_IO_VA -\
- IOP13XX_PCIX_LOWER_IO_BA)
#define IOP13XX_PCIX_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
(IOP13XX_PCIX_LOWER_IO_PA\
- IOP13XX_PCIX_LOWER_IO_VA))
@@ -65,15 +71,14 @@ static inline int iop13xx_cpu_id(void)
#define IOP13XX_PCIE_IO_WINDOW_SIZE 0x10000UL
#define IOP13XX_PCIE_LOWER_IO_PA 0xfffd0000UL
#define IOP13XX_PCIE_LOWER_IO_VA 0xfed70000UL
-#define IOP13XX_PCIE_LOWER_IO_BA 0x0fff0000UL
+#define IOP13XX_PCIE_LOWER_IO_BA 0x0UL /* OIOTVR */
+#define IOP13XX_PCIE_IO_BUS_OFFSET 0x1000UL
#define IOP13XX_PCIE_UPPER_IO_PA (IOP13XX_PCIE_LOWER_IO_PA +\
IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
#define IOP13XX_PCIE_UPPER_IO_VA (IOP13XX_PCIE_LOWER_IO_VA +\
IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
#define IOP13XX_PCIE_UPPER_IO_BA (IOP13XX_PCIE_LOWER_IO_BA +\
IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
-#define IOP13XX_PCIE_IO_OFFSET (IOP13XX_PCIE_LOWER_IO_VA -\
- IOP13XX_PCIE_LOWER_IO_BA)
#define IOP13XX_PCIE_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
(IOP13XX_PCIE_LOWER_IO_PA\
- IOP13XX_PCIE_LOWER_IO_VA))
@@ -451,4 +456,5 @@ static inline int iop13xx_cpu_id(void)
#define IOP13XX_PBI_BAR1 IOP13XX_PBI_OFFSET(0x10)
#define IOP13XX_PBI_LR1 IOP13XX_PBI_OFFSET(0x14)
+#define IOP13XX_PROCESSOR_FREQ IOP13XX_REG_ADDR32(0x2180)
#endif /* _IOP13XX_HW_H_ */
diff --git a/include/asm-arm/arch-iop13xx/time.h b/include/asm-arm/arch-iop13xx/time.h
index 77a837a..49213d9 100644
--- a/include/asm-arm/arch-iop13xx/time.h
+++ b/include/asm-arm/arch-iop13xx/time.h
@@ -7,9 +7,65 @@
#define IOP_TMR_PRIVILEGED 0x08
#define IOP_TMR_RATIO_1_1 0x00
+#define IOP13XX_XSI_FREQ_RATIO_MASK (3 << 19)
+#define IOP13XX_XSI_FREQ_RATIO_2 (0 << 19)
+#define IOP13XX_XSI_FREQ_RATIO_3 (1 << 19)
+#define IOP13XX_XSI_FREQ_RATIO_4 (2 << 19)
+#define IOP13XX_CORE_FREQ_MASK (7 << 16)
+#define IOP13XX_CORE_FREQ_600 (0 << 16)
+#define IOP13XX_CORE_FREQ_667 (1 << 16)
+#define IOP13XX_CORE_FREQ_800 (2 << 16)
+#define IOP13XX_CORE_FREQ_933 (3 << 16)
+#define IOP13XX_CORE_FREQ_1000 (4 << 16)
+#define IOP13XX_CORE_FREQ_1200 (5 << 16)
+
void iop_init_time(unsigned long tickrate);
unsigned long iop_gettimeoffset(void);
+static inline unsigned long iop13xx_core_freq(void)
+{
+ unsigned long freq = __raw_readl(IOP13XX_PROCESSOR_FREQ);
+ freq &= IOP13XX_CORE_FREQ_MASK;
+ switch (freq) {
+ case IOP13XX_CORE_FREQ_600:
+ return 600000000;
+ case IOP13XX_CORE_FREQ_667:
+ return 667000000;
+ case IOP13XX_CORE_FREQ_800:
+ return 800000000;
+ case IOP13XX_CORE_FREQ_933:
+ return 933000000;
+ case IOP13XX_CORE_FREQ_1000:
+ return 1000000000;
+ case IOP13XX_CORE_FREQ_1200:
+ return 1200000000;
+ default:
+ printk("%s: warning unknown frequency, defaulting to 800Mhz\n",
+ __FUNCTION__);
+ }
+
+ return 800000000;
+}
+
+static inline unsigned long iop13xx_xsi_bus_ratio(void)
+{
+ unsigned long ratio = __raw_readl(IOP13XX_PROCESSOR_FREQ);
+ ratio &= IOP13XX_XSI_FREQ_RATIO_MASK;
+ switch (ratio) {
+ case IOP13XX_XSI_FREQ_RATIO_2:
+ return 2;
+ case IOP13XX_XSI_FREQ_RATIO_3:
+ return 3;
+ case IOP13XX_XSI_FREQ_RATIO_4:
+ return 4;
+ default:
+ printk("%s: warning unknown ratio, defaulting to 2\n",
+ __FUNCTION__);
+ }
+
+ return 2;
+}
+
static inline void write_tmr0(u32 val)
{
asm volatile("mcr p6, 0, %0, c0, c9, 0" : : "r" (val));
diff --git a/include/asm-arm/arch-iop32x/io.h b/include/asm-arm/arch-iop32x/io.h
index 5f570a5..994f16a 100644
--- a/include/asm-arm/arch-iop32x/io.h
+++ b/include/asm-arm/arch-iop32x/io.h
@@ -13,7 +13,6 @@
#include <asm/hardware.h>
-extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
extern void __iomem *__iop3xx_ioremap(unsigned long cookie, size_t size,
unsigned long flags);
extern void __iop3xx_iounmap(void __iomem *addr);
diff --git a/include/asm-arm/arch-iop32x/iop32x.h b/include/asm-arm/arch-iop32x/iop32x.h
index 2e94690..0d8af57 100644
--- a/include/asm-arm/arch-iop32x/iop32x.h
+++ b/include/asm-arm/arch-iop32x/iop32x.h
@@ -24,5 +24,14 @@
#include <asm/hardware/iop3xx.h>
+/* ATU Parameters
+ * set up a 1:1 bus to physical ram relationship
+ * w/ physical ram on top of pci in the memory map
+ */
+#define IOP32X_MAX_RAM_SIZE 0x40000000UL
+#define IOP3XX_MAX_RAM_SIZE IOP32X_MAX_RAM_SIZE
+#define IOP3XX_PCI_LOWER_MEM_BA 0x80000000
+#define IOP32X_PCI_MEM_WINDOW_SIZE 0x04000000
+#define IOP3XX_PCI_MEM_WINDOW_SIZE IOP32X_PCI_MEM_WINDOW_SIZE
#endif
diff --git a/include/asm-arm/arch-iop32x/memory.h b/include/asm-arm/arch-iop32x/memory.h
index 764cd3f..c51072a 100644
--- a/include/asm-arm/arch-iop32x/memory.h
+++ b/include/asm-arm/arch-iop32x/memory.h
@@ -19,8 +19,8 @@
* bus_to_virt: Used to convert an address for DMA operations
* to an address that the kernel can use.
*/
-#define __virt_to_bus(x) (((__virt_to_phys(x)) & ~(*IOP3XX_IATVR2)) | ((*IOP3XX_IABAR2) & 0xfffffff0))
-#define __bus_to_virt(x) (__phys_to_virt(((x) & ~(*IOP3XX_IALR2)) | ( *IOP3XX_IATVR2)))
+#define __virt_to_bus(x) (__virt_to_phys(x))
+#define __bus_to_virt(x) (__phys_to_virt(x))
#endif
diff --git a/include/asm-arm/arch-iop33x/io.h b/include/asm-arm/arch-iop33x/io.h
index 1bb5071..993f758 100644
--- a/include/asm-arm/arch-iop33x/io.h
+++ b/include/asm-arm/arch-iop33x/io.h
@@ -13,7 +13,6 @@
#include <asm/hardware.h>
-extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
extern void __iomem *__iop3xx_ioremap(unsigned long cookie, size_t size,
unsigned long flags);
extern void __iop3xx_iounmap(void __iomem *addr);
diff --git a/include/asm-arm/arch-iop33x/iop33x.h b/include/asm-arm/arch-iop33x/iop33x.h
index 7ac6e93..766985b 100644
--- a/include/asm-arm/arch-iop33x/iop33x.h
+++ b/include/asm-arm/arch-iop33x/iop33x.h
@@ -29,5 +29,15 @@
#define IOP33X_UART1_PHYS (IOP3XX_PERIPHERAL_PHYS_BASE + 0x1740)
#define IOP33X_UART1_VIRT (IOP3XX_PERIPHERAL_VIRT_BASE + 0x1740)
+/* ATU Parameters
+ * set up a 1:1 bus to physical ram relationship
+ * w/ pci on top of physical ram in memory map
+ */
+#define IOP33X_MAX_RAM_SIZE 0x80000000UL
+#define IOP3XX_MAX_RAM_SIZE IOP33X_MAX_RAM_SIZE
+#define IOP3XX_PCI_LOWER_MEM_BA (PHYS_OFFSET + IOP33X_MAX_RAM_SIZE)
+#define IOP33X_PCI_MEM_WINDOW_SIZE 0x08000000
+#define IOP3XX_PCI_MEM_WINDOW_SIZE IOP33X_PCI_MEM_WINDOW_SIZE
+
#endif
diff --git a/include/asm-arm/arch-iop33x/memory.h b/include/asm-arm/arch-iop33x/memory.h
index 0d39139..c874912 100644
--- a/include/asm-arm/arch-iop33x/memory.h
+++ b/include/asm-arm/arch-iop33x/memory.h
@@ -19,8 +19,8 @@
* bus_to_virt: Used to convert an address for DMA operations
* to an address that the kernel can use.
*/
-#define __virt_to_bus(x) (((__virt_to_phys(x)) & ~(*IOP3XX_IATVR2)) | ((*IOP3XX_IABAR2) & 0xfffffff0))
-#define __bus_to_virt(x) (__phys_to_virt(((x) & ~(*IOP3XX_IALR2)) | ( *IOP3XX_IATVR2)))
+#define __virt_to_bus(x) (__virt_to_phys(x))
+#define __bus_to_virt(x) (__phys_to_virt(x))
#endif
diff --git a/include/asm-arm/arch-ixp23xx/io.h b/include/asm-arm/arch-ixp23xx/io.h
index 18415a8..66f5baf 100644
--- a/include/asm-arm/arch-ixp23xx/io.h
+++ b/include/asm-arm/arch-ixp23xx/io.h
@@ -23,7 +23,7 @@
#include <linux/kernel.h> /* For BUG */
static inline void __iomem *
-ixp23xx_ioremap(unsigned long addr, unsigned long size, unsigned long flags)
+ixp23xx_ioremap(unsigned long addr, unsigned long size, unsigned int mtype)
{
if (addr >= IXP23XX_PCI_MEM_START &&
addr <= IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE) {
@@ -34,7 +34,7 @@ ixp23xx_ioremap(unsigned long addr, unsigned long size, unsigned long flags)
((addr - IXP23XX_PCI_MEM_START) + IXP23XX_PCI_MEM_VIRT);
}
- return __ioremap(addr, size, flags);
+ return __arm_ioremap(addr, size, mtype);
}
static inline void
diff --git a/include/asm-arm/arch-ixp4xx/cpu.h b/include/asm-arm/arch-ixp4xx/cpu.h
new file mode 100644
index 0000000..d2523b3
--- /dev/null
+++ b/include/asm-arm/arch-ixp4xx/cpu.h
@@ -0,0 +1,31 @@
+/*
+ * include/asm-arm/arch-ixp4xx/cpu.h
+ *
+ * IXP4XX cpu type detection
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ASM_ARCH_CPU_H__
+#define __ASM_ARCH_CPU_H__
+
+extern unsigned int processor_id;
+/* Processor id value in CP15 Register 0 */
+#define IXP425_PROCESSOR_ID_VALUE 0x690541c0
+#define IXP435_PROCESSOR_ID_VALUE 0x69054040
+#define IXP465_PROCESSOR_ID_VALUE 0x69054200
+#define IXP4XX_PROCESSOR_ID_MASK 0xfffffff0
+
+#define cpu_is_ixp42x() ((processor_id & IXP4XX_PROCESSOR_ID_MASK) == \
+ IXP425_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp43x() ((processor_id & IXP4XX_PROCESSOR_ID_MASK) == \
+ IXP435_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp46x() ((processor_id & IXP4XX_PROCESSOR_ID_MASK) == \
+ IXP465_PROCESSOR_ID_VALUE)
+
+#endif /* _ASM_ARCH_CPU_H */
diff --git a/include/asm-arm/arch-ixp4xx/dsmg600.h b/include/asm-arm/arch-ixp4xx/dsmg600.h
new file mode 100644
index 0000000..a19605a
--- /dev/null
+++ b/include/asm-arm/arch-ixp4xx/dsmg600.h
@@ -0,0 +1,57 @@
+/*
+ * DSM-G600 platform specific definitions
+ *
+ * Copyright (C) 2006 Tower Technologies
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ *
+ * based on ixdp425.h:
+ * Copyright 2004 (C) MontaVista, Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H__
+#error "Do not include this directly, instead #include <asm/hardware.h>"
+#endif
+
+#define DSMG600_SDA_PIN 5
+#define DSMG600_SCL_PIN 4
+
+/*
+ * DSMG600 PCI IRQs
+ */
+#define DSMG600_PCI_MAX_DEV 4
+#define DSMG600_PCI_IRQ_LINES 3
+
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define DSMG600_PCI_INTA_PIN 11
+#define DSMG600_PCI_INTB_PIN 10
+#define DSMG600_PCI_INTC_PIN 9
+#define DSMG600_PCI_INTD_PIN 8
+#define DSMG600_PCI_INTE_PIN 7
+#define DSMG600_PCI_INTF_PIN 6
+
+/* DSM-G600 Timer Setting */
+#define DSMG600_FREQ 66000000
+
+/* Buttons */
+
+#define DSMG600_PB_GPIO 15 /* power button */
+#define DSMG600_PB_BM (1L << DSMG600_PB_GPIO)
+
+#define DSMG600_RB_GPIO 3 /* reset button */
+
+#define DSMG600_RB_IRQ IRQ_IXP4XX_GPIO3
+
+#define DSMG600_PO_GPIO 2 /* power off */
+
+/* LEDs */
+
+#define DSMG600_LED_PWR_GPIO 0
+#define DSMG600_LED_PWR_BM (1L << DSMG600_LED_PWR_GPIO)
+
+#define DSMG600_LED_WLAN_GPIO 14
+#define DSMG600_LED_WLAN_BM (1L << DSMG600_LED_WLAN_GPIO)
diff --git a/include/asm-arm/arch-ixp4xx/entry-macro.S b/include/asm-arm/arch-ixp4xx/entry-macro.S
index dadb568..f144a00 100644
--- a/include/asm-arm/arch-ixp4xx/entry-macro.S
+++ b/include/asm-arm/arch-ixp4xx/entry-macro.S
@@ -31,9 +31,9 @@
1001:
/*
- * IXP465 has an upper IRQ status register
+ * IXP465/IXP435 has an upper IRQ status register
*/
-#if defined(CONFIG_CPU_IXP46X)
+#if defined(CONFIG_CPU_IXP46X) || defined(CONFIG_CPU_IXP43X)
ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP2_OFFSET)
ldr \irqstat, [\irqstat] @ get upper interrupts
mov \irqnr, #63
diff --git a/include/asm-arm/arch-ixp4xx/gpio.h b/include/asm-arm/arch-ixp4xx/gpio.h
new file mode 100644
index 0000000..3a4c5b8
--- /dev/null
+++ b/include/asm-arm/arch-ixp4xx/gpio.h
@@ -0,0 +1,73 @@
+/*
+ * linux/include/asm-arm/arch-ixp4xx/gpio.h
+ *
+ * IXP4XX GPIO wrappers for arch-neutral GPIO calls
+ *
+ * Written by Milan Svoboda <msvoboda@ra.rockwell.com>
+ * Based on PXA implementation by Philipp Zabel <philipp.zabel@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_IXP4XX_GPIO_H
+#define __ASM_ARCH_IXP4XX_GPIO_H
+
+#include <asm/hardware.h>
+
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+ return 0;
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+ return;
+}
+
+static inline int gpio_direction_input(unsigned gpio)
+{
+ gpio_line_config(gpio, IXP4XX_GPIO_IN);
+ return 0;
+}
+
+static inline int gpio_direction_output(unsigned gpio, int level)
+{
+ gpio_line_set(gpio, level);
+ gpio_line_config(gpio, IXP4XX_GPIO_OUT);
+ return 0;
+}
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ int value;
+
+ gpio_line_get(gpio, &value);
+
+ return value;
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ gpio_line_set(gpio, value);
+}
+
+#include <asm-generic/gpio.h> /* cansleep wrappers */
+
+extern int gpio_to_irq(int gpio);
+extern int irq_to_gpio(int gpio);
+
+#endif
+
diff --git a/include/asm-arm/arch-ixp4xx/hardware.h b/include/asm-arm/arch-ixp4xx/hardware.h
index 88fd087..297ceda 100644
--- a/include/asm-arm/arch-ixp4xx/hardware.h
+++ b/include/asm-arm/arch-ixp4xx/hardware.h
@@ -17,8 +17,8 @@
#ifndef __ASM_ARCH_HARDWARE_H__
#define __ASM_ARCH_HARDWARE_H__
-#define PCIBIOS_MIN_IO 0x00001000
-#define PCIBIOS_MIN_MEM 0x48000000
+#define PCIBIOS_MIN_IO 0x00001000
+#define PCIBIOS_MIN_MEM (cpu_is_ixp43x() ? 0x40000000 : 0x48000000)
/*
* We override the standard dma-mask routines for bouncing.
@@ -27,11 +27,8 @@
#define pcibios_assign_all_busses() 1
-#if defined(CONFIG_CPU_IXP46X) && !defined(__ASSEMBLY__)
-extern unsigned int processor_id;
-#define cpu_is_ixp465() ((processor_id & 0xffffffc0) == 0x69054200)
-#else
-#define cpu_is_ixp465() (0)
+#ifndef __ASSEMBLER__
+#include <asm/arch/cpu.h>
#endif
/* Register locations and bits */
@@ -47,5 +44,6 @@ extern unsigned int processor_id;
#include "prpmc1100.h"
#include "nslu2.h"
#include "nas100d.h"
+#include "dsmg600.h"
#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h
index a41ba22..c72f9d7 100644
--- a/include/asm-arm/arch-ixp4xx/io.h
+++ b/include/asm-arm/arch-ixp4xx/io.h
@@ -59,10 +59,10 @@ extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
* fallback to the default.
*/
static inline void __iomem *
-__ixp4xx_ioremap(unsigned long addr, size_t size, unsigned long flags)
+__ixp4xx_ioremap(unsigned long addr, size_t size, unsigned int mtype)
{
- if((addr < 0x48000000) || (addr > 0x4fffffff))
- return __ioremap(addr, size, flags);
+ if((addr < PCIBIOS_MIN_MEM) || (addr > 0x4fffffff))
+ return __arm_ioremap(addr, size, mtype);
return (void *)addr;
}
diff --git a/include/asm-arm/arch-ixp4xx/irqs.h b/include/asm-arm/arch-ixp4xx/irqs.h
index e44a563..1180160 100644
--- a/include/asm-arm/arch-ixp4xx/irqs.h
+++ b/include/asm-arm/arch-ixp4xx/irqs.h
@@ -62,10 +62,10 @@
/*
* Only first 32 sources are valid if running on IXP42x systems
*/
-#ifndef CONFIG_CPU_IXP46X
-#define NR_IRQS 32
-#else
+#if defined(CONFIG_CPU_IXP46X) || defined(CONFIG_CPU_IXP43X)
#define NR_IRQS 64
+#else
+#define NR_IRQS 32
#endif
#define XSCALE_PMU_IRQ (IRQ_IXP4XX_XSCALE_PMU)
@@ -118,4 +118,14 @@
#define IRQ_NAS100D_PCI_INTD IRQ_IXP4XX_GPIO8
#define IRQ_NAS100D_PCI_INTE IRQ_IXP4XX_GPIO7
+/*
+ * D-Link DSM-G600 RevA board IRQs
+ */
+#define IRQ_DSMG600_PCI_INTA IRQ_IXP4XX_GPIO11
+#define IRQ_DSMG600_PCI_INTB IRQ_IXP4XX_GPIO10
+#define IRQ_DSMG600_PCI_INTC IRQ_IXP4XX_GPIO9
+#define IRQ_DSMG600_PCI_INTD IRQ_IXP4XX_GPIO8
+#define IRQ_DSMG600_PCI_INTE IRQ_IXP4XX_GPIO7
+#define IRQ_DSMG600_PCI_INTF IRQ_IXP4XX_GPIO6
+
#endif
diff --git a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
index ed35e5c..5d949d7 100644
--- a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
+++ b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
@@ -607,19 +607,4 @@
#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
-#ifndef __ASSEMBLY__
-static inline int cpu_is_ixp46x(void)
-{
-#ifdef CONFIG_CPU_IXP46X
- unsigned int processor_id;
-
- asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :);
-
- if ((processor_id & 0xffffff00) == 0x69054200)
- return 1;
-#endif
- return 0;
-}
-#endif
-
#endif
diff --git a/include/asm-arm/arch-netx/netx-regs.h b/include/asm-arm/arch-netx/netx-regs.h
index 8ab45be..fc9aa21 100644
--- a/include/asm-arm/arch-netx/netx-regs.h
+++ b/include/asm-arm/arch-netx/netx-regs.h
@@ -121,8 +121,8 @@
#define NETX_SYSTEM_IOC_MR NETX_SYSTEM_REG(0x08)
/* FIXME: Docs are not consistent */
-#define NETX_SYSTEM_RES_CR NETX_SYSTEM_REG(0x08)
-/* #define NETX_SYSTEM_RES_CR NETX_SYSTEM_REG(0x0c) */
+/* #define NETX_SYSTEM_RES_CR NETX_SYSTEM_REG(0x08) */
+#define NETX_SYSTEM_RES_CR NETX_SYSTEM_REG(0x0c)
#define NETX_SYSTEM_PHY_CONTROL NETX_SYSTEM_REG(0x10)
#define NETX_SYSTEM_REV NETX_SYSTEM_REG(0x34)
diff --git a/include/asm-arm/arch-ns9xxx/board.h b/include/asm-arm/arch-ns9xxx/board.h
index 91dc8fb..716f34f 100644
--- a/include/asm-arm/arch-ns9xxx/board.h
+++ b/include/asm-arm/arch-ns9xxx/board.h
@@ -15,4 +15,6 @@
#define board_is_a9m9750dev() (machine_is_cc9p9360dev())
+#define board_is_jscc9p9360() (machine_is_cc9p9360js())
+
#endif /* ifndef __ASM_ARCH_BOARD_H */
diff --git a/include/asm-arm/arch-ns9xxx/clock.h b/include/asm-arm/arch-ns9xxx/clock.h
index a7c5ab3..bf30cbd 100644
--- a/include/asm-arm/arch-ns9xxx/clock.h
+++ b/include/asm-arm/arch-ns9xxx/clock.h
@@ -11,13 +11,43 @@
#ifndef __ASM_ARCH_CLOCK_H
#define __ASM_ARCH_CLOCK_H
+#include <asm/arch-ns9xxx/regs-sys.h>
+
+#define CRYSTAL 29491200 /* Hz */
+
+/* The HRM calls this value f_vco */
static inline u32 ns9xxx_systemclock(void) __attribute__((const));
static inline u32 ns9xxx_systemclock(void)
{
+ u32 pll = SYS_PLL;
+
/*
- * This should be a multiple of HZ * TIMERCLOCKSELECT (in time.c)
+ * The system clock should be a multiple of HZ * TIMERCLOCKSELECT (in
+ * time.c).
+ *
+ * The following values are given:
+ * - TIMERCLOCKSELECT == 2^i for an i in {0 .. 6}
+ * - CRYSTAL == 29491200 == 2^17 * 3^2 * 5^2
+ * - ND in {0 .. 31}
+ * - FS in {0 .. 3}
+ *
+ * Assuming the worst, we consider:
+ * - TIMERCLOCKSELECT == 64
+ * - ND == 0
+ * - FS == 3
+ *
+ * So HZ should be a divisor of:
+ * (CRYSTAL * (ND + 1) >> FS) / TIMERCLOCKSELECT
+ * == (2^17 * 3^2 * 5^2 * 1 >> 3) / 64
+ * == 2^8 * 3^2 * 5^2
+ * == 57600
+ *
+ * Currently HZ is defined to be 100 for this platform.
+ *
+ * Fine.
*/
- return 353894400;
+ return CRYSTAL * (REGGET(pll, SYS_PLL, ND) + 1)
+ >> REGGET(pll, SYS_PLL, FS);
}
static inline u32 ns9xxx_cpuclock(void) __attribute__((const));
diff --git a/include/asm-arm/arch-ns9xxx/hardware.h b/include/asm-arm/arch-ns9xxx/hardware.h
index 6819da7..2560055 100644
--- a/include/asm-arm/arch-ns9xxx/hardware.h
+++ b/include/asm-arm/arch-ns9xxx/hardware.h
@@ -51,8 +51,9 @@
~(__REGVAL(reg ## _ ## field, value)))) \
| (__REGVAL(reg ## _ ## field, value))))
-# define REGGET(reg, field) \
- ((reg & (reg ## _ ## field)) / (field & (-field)))
+# define REGGET(var, reg, field) \
+ ((var & (reg ## _ ## field)) / \
+ ((reg ## _ ## field) & (-(reg ## _ ## field))))
#else
diff --git a/include/asm-arm/arch-ns9xxx/processor.h b/include/asm-arm/arch-ns9xxx/processor.h
index 716c106..223e51b 100644
--- a/include/asm-arm/arch-ns9xxx/processor.h
+++ b/include/asm-arm/arch-ns9xxx/processor.h
@@ -13,6 +13,7 @@
#include <asm/mach-types.h>
-#define processor_is_ns9360() (machine_is_cc9p9360dev())
+#define processor_is_ns9360() (machine_is_cc9p9360dev() \
+ || machine_is_cc9p9360js())
#endif /* ifndef __ASM_ARCH_PROCESSOR_H */
diff --git a/include/asm-arm/arch-ns9xxx/regs-sys.h b/include/asm-arm/arch-ns9xxx/regs-sys.h
index 8162a50..a42546a 100644
--- a/include/asm-arm/arch-ns9xxx/regs-sys.h
+++ b/include/asm-arm/arch-ns9xxx/regs-sys.h
@@ -48,6 +48,12 @@
/* PLL Configuration register */
#define SYS_PLL __REG(0xa0900188)
+/* PLL FS status */
+#define SYS_PLL_FS __REGBITS(24, 23)
+
+/* PLL ND status */
+#define SYS_PLL_ND __REGBITS(20, 16)
+
/* PLL Configuration register: PLL SW change */
#define SYS_PLL_SWC __REGBIT(15)
#define SYS_PLL_SWC_NO __REGVAL(SYS_PLL_SWC, 0)
diff --git a/include/asm-arm/arch-pxa/i2c.h b/include/asm-arm/arch-pxa/i2c.h
index 46ec224..e404b23 100644
--- a/include/asm-arm/arch-pxa/i2c.h
+++ b/include/asm-arm/arch-pxa/i2c.h
@@ -64,6 +64,7 @@ struct i2c_slave_client;
struct i2c_pxa_platform_data {
unsigned int slave_addr;
struct i2c_slave_client *slave;
+ unsigned int class;
};
extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info);
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index 139c9d9..dbcc929 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -1801,35 +1801,35 @@
#define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */
#define CCCR_L_MASK 0x001f /* Crystal Frequency to Memory Frequency Multiplier */
-#define CKEN24_CAMERA (1 << 24) /* Camera Interface Clock Enable */
-#define CKEN23_SSP1 (1 << 23) /* SSP1 Unit Clock Enable */
-#define CKEN22_MEMC (1 << 22) /* Memory Controller Clock Enable */
-#define CKEN21_MEMSTK (1 << 21) /* Memory Stick Host Controller */
-#define CKEN20_IM (1 << 20) /* Internal Memory Clock Enable */
-#define CKEN19_KEYPAD (1 << 19) /* Keypad Interface Clock Enable */
-#define CKEN18_USIM (1 << 18) /* USIM Unit Clock Enable */
-#define CKEN17_MSL (1 << 17) /* MSL Unit Clock Enable */
-#define CKEN16_LCD (1 << 16) /* LCD Unit Clock Enable */
-#define CKEN15_PWRI2C (1 << 15) /* PWR I2C Unit Clock Enable */
-#define CKEN14_I2C (1 << 14) /* I2C Unit Clock Enable */
-#define CKEN13_FICP (1 << 13) /* FICP Unit Clock Enable */
-#define CKEN12_MMC (1 << 12) /* MMC Unit Clock Enable */
-#define CKEN11_USB (1 << 11) /* USB Unit Clock Enable */
-#define CKEN10_ASSP (1 << 10) /* ASSP (SSP3) Clock Enable */
-#define CKEN10_USBHOST (1 << 10) /* USB Host Unit Clock Enable */
-#define CKEN9_OSTIMER (1 << 9) /* OS Timer Unit Clock Enable */
-#define CKEN9_NSSP (1 << 9) /* NSSP (SSP2) Clock Enable */
-#define CKEN8_I2S (1 << 8) /* I2S Unit Clock Enable */
-#define CKEN7_BTUART (1 << 7) /* BTUART Unit Clock Enable */
-#define CKEN6_FFUART (1 << 6) /* FFUART Unit Clock Enable */
-#define CKEN5_STUART (1 << 5) /* STUART Unit Clock Enable */
-#define CKEN4_HWUART (1 << 4) /* HWUART Unit Clock Enable */
-#define CKEN4_SSP3 (1 << 4) /* SSP3 Unit Clock Enable */
-#define CKEN3_SSP (1 << 3) /* SSP Unit Clock Enable */
-#define CKEN3_SSP2 (1 << 3) /* SSP2 Unit Clock Enable */
-#define CKEN2_AC97 (1 << 2) /* AC97 Unit Clock Enable */
-#define CKEN1_PWM1 (1 << 1) /* PWM1 Clock Enable */
-#define CKEN0_PWM0 (1 << 0) /* PWM0 Clock Enable */
+#define CKEN_CAMERA (24) /* Camera Interface Clock Enable */
+#define CKEN_SSP1 (23) /* SSP1 Unit Clock Enable */
+#define CKEN_MEMC (22) /* Memory Controller Clock Enable */
+#define CKEN_MEMSTK (21) /* Memory Stick Host Controller */
+#define CKEN_IM (20) /* Internal Memory Clock Enable */
+#define CKEN_KEYPAD (19) /* Keypad Interface Clock Enable */
+#define CKEN_USIM (18) /* USIM Unit Clock Enable */
+#define CKEN_MSL (17) /* MSL Unit Clock Enable */
+#define CKEN_LCD (16) /* LCD Unit Clock Enable */
+#define CKEN_PWRI2C (15) /* PWR I2C Unit Clock Enable */
+#define CKEN_I2C (14) /* I2C Unit Clock Enable */
+#define CKEN_FICP (13) /* FICP Unit Clock Enable */
+#define CKEN_MMC (12) /* MMC Unit Clock Enable */
+#define CKEN_USB (11) /* USB Unit Clock Enable */
+#define CKEN_ASSP (10) /* ASSP (SSP3) Clock Enable */
+#define CKEN_USBHOST (10) /* USB Host Unit Clock Enable */
+#define CKEN_OSTIMER (9) /* OS Timer Unit Clock Enable */
+#define CKEN_NSSP (9) /* NSSP (SSP2) Clock Enable */
+#define CKEN_I2S (8) /* I2S Unit Clock Enable */
+#define CKEN_BTUART (7) /* BTUART Unit Clock Enable */
+#define CKEN_FFUART (6) /* FFUART Unit Clock Enable */
+#define CKEN_STUART (5) /* STUART Unit Clock Enable */
+#define CKEN_HWUART (4) /* HWUART Unit Clock Enable */
+#define CKEN_SSP3 (4) /* SSP3 Unit Clock Enable */
+#define CKEN_SSP (3) /* SSP Unit Clock Enable */
+#define CKEN_SSP2 (3) /* SSP2 Unit Clock Enable */
+#define CKEN_AC97 (2) /* AC97 Unit Clock Enable */
+#define CKEN_PWM1 (1) /* PWM1 Clock Enable */
+#define CKEN_PWM0 (0) /* PWM0 Clock Enable */
#define OSCC_OON (1 << 1) /* 32.768kHz OON (write-once only bit) */
#define OSCC_OOK (1 << 0) /* 32.768kHz OOK (read-only bit) */
diff --git a/include/asm-arm/arch-s3c2410/regs-ac97.h b/include/asm-arm/arch-s3c2410/regs-ac97.h
index bdd6a4f..b004dee 100644
--- a/include/asm-arm/arch-s3c2410/regs-ac97.h
+++ b/include/asm-arm/arch-s3c2410/regs-ac97.h
@@ -13,11 +13,55 @@
#ifndef __ASM_ARCH_REGS_AC97_H
#define __ASM_ARCH_REGS_AC97_H __FILE__
-#define S3C_AC97_GLBCTRL (0x00)
-#define S3C_AC97_GLBSTAT (0x04)
-#define S3C_AC97_CODEC_CMD (0x08)
-#define S3C_AC97_PCM_ADDR (0x10)
-#define S3C_AC97_PCM_DATA (0x18)
-#define S3C_AC97_MIC_DATA (0x1C)
+#define S3C_AC97_GLBCTRL (0x00)
+
+#define S3C_AC97_GLBCTRL_CODECREADYIE (1<<22)
+#define S3C_AC97_GLBCTRL_PCMOUTURIE (1<<21)
+#define S3C_AC97_GLBCTRL_PCMINORIE (1<<20)
+#define S3C_AC97_GLBCTRL_MICINORIE (1<<19)
+#define S3C_AC97_GLBCTRL_PCMOUTTIE (1<<18)
+#define S3C_AC97_GLBCTRL_PCMINTIE (1<<17)
+#define S3C_AC97_GLBCTRL_MICINTIE (1<<16)
+#define S3C_AC97_GLBCTRL_PCMOUTTM_OFF (0<<12)
+#define S3C_AC97_GLBCTRL_PCMOUTTM_PIO (1<<12)
+#define S3C_AC97_GLBCTRL_PCMOUTTM_DMA (2<<12)
+#define S3C_AC97_GLBCTRL_PCMOUTTM_MASK (3<<12)
+#define S3C_AC97_GLBCTRL_PCMINTM_OFF (0<<10)
+#define S3C_AC97_GLBCTRL_PCMINTM_PIO (1<<10)
+#define S3C_AC97_GLBCTRL_PCMINTM_DMA (2<<10)
+#define S3C_AC97_GLBCTRL_PCMINTM_MASK (3<<10)
+#define S3C_AC97_GLBCTRL_MICINTM_OFF (0<<8)
+#define S3C_AC97_GLBCTRL_MICINTM_PIO (1<<8)
+#define S3C_AC97_GLBCTRL_MICINTM_DMA (2<<8)
+#define S3C_AC97_GLBCTRL_MICINTM_MASK (3<<8)
+#define S3C_AC97_GLBCTRL_TRANSFERDATAENABLE (1<<3)
+#define S3C_AC97_GLBCTRL_ACLINKON (1<<2)
+#define S3C_AC97_GLBCTRL_WARMRESET (1<<1)
+#define S3C_AC97_GLBCTRL_COLDRESET (1<<0)
+
+#define S3C_AC97_GLBSTAT (0x04)
+
+#define S3C_AC97_GLBSTAT_CODECREADY (1<<22)
+#define S3C_AC97_GLBSTAT_PCMOUTUR (1<<21)
+#define S3C_AC97_GLBSTAT_PCMINORI (1<<20)
+#define S3C_AC97_GLBSTAT_MICINORI (1<<19)
+#define S3C_AC97_GLBSTAT_PCMOUTTI (1<<18)
+#define S3C_AC97_GLBSTAT_PCMINTI (1<<17)
+#define S3C_AC97_GLBSTAT_MICINTI (1<<16)
+#define S3C_AC97_GLBSTAT_MAINSTATE_IDLE (0<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_INIT (1<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_READY (2<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE (3<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_LP (4<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_WARM (5<<0)
+
+#define S3C_AC97_CODEC_CMD (0x08)
+
+#define S3C_AC97_CODEC_CMD_READ (1<<23)
+
+#define S3C_AC97_STAT (0x0c)
+#define S3C_AC97_PCM_ADDR (0x10)
+#define S3C_AC97_PCM_DATA (0x18)
+#define S3C_AC97_MIC_DATA (0x1C)
#endif /* __ASM_ARCH_REGS_AC97_H */
diff --git a/include/asm-arm/arch-s3c2410/regs-udc.h b/include/asm-arm/arch-s3c2410/regs-udc.h
index 3c83546..e1e9805 100644
--- a/include/asm-arm/arch-s3c2410/regs-udc.h
+++ b/include/asm-arm/arch-s3c2410/regs-udc.h
@@ -75,7 +75,7 @@
#define S3C2410_UDC_OUT_FIFO_CNT1_REG S3C2410_USBDREG(0x0198)
#define S3C2410_UDC_OUT_FIFO_CNT2_REG S3C2410_USBDREG(0x019c)
-
+#define S3C2410_UDC_FUNCADDR_UPDATE (1<<7)
#define S3C2410_UDC_PWR_ISOUP (1<<7) // R/W
#define S3C2410_UDC_PWR_RESET (1<<3) // R
@@ -135,10 +135,6 @@
#define S3C2410_UDC_OCSR2_ISO (1<<6) // R/W
#define S3C2410_UDC_OCSR2_DMAIEN (1<<5) // R/W
-#define S3C2410_UDC_SETIX(base,x) \
- writel(S3C2410_UDC_INDEX_ ## x, base+S3C2410_UDC_INDEX_REG);
-
-
#define S3C2410_UDC_EP0_CSR_OPKRDY (1<<0)
#define S3C2410_UDC_EP0_CSR_IPKRDY (1<<1)
#define S3C2410_UDC_EP0_CSR_SENTSTL (1<<2)
diff --git a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h
index f266c27..3b59f94 100644
--- a/include/asm-arm/atomic.h
+++ b/include/asm-arm/atomic.h
@@ -12,6 +12,7 @@
#define __ASM_ARM_ATOMIC_H
#include <linux/compiler.h>
+#include <asm/system.h>
typedef struct { volatile int counter; } atomic_t;
diff --git a/include/asm-arm/ecard.h b/include/asm-arm/ecard.h
index a0ae2b9..3a6d3eb 100644
--- a/include/asm-arm/ecard.h
+++ b/include/asm-arm/ecard.h
@@ -160,6 +160,7 @@ struct expansion_card {
unsigned char irqmask; /* IRQ mask */
unsigned char fiqmask; /* FIQ mask */
unsigned char claimed; /* Card claimed? */
+ unsigned char easi; /* EASI card */
void *irq_data; /* Data for use for IRQ by card */
void *fiq_data; /* Data for use for FIQ by card */
@@ -169,7 +170,6 @@ struct expansion_card {
CONST unsigned int dma; /* DMA number (for request_dma) */
CONST unsigned int irq; /* IRQ number (for request_irq) */
CONST unsigned int fiq; /* FIQ number (for request_irq) */
- CONST card_type_t type; /* Type of card */
CONST struct in_ecid cid; /* Card Identification */
/* Private internal data */
@@ -224,56 +224,6 @@ ecard_address(struct expansion_card *ec, card_type_t type, card_speed_t speed)
extern int ecard_request_resources(struct expansion_card *ec);
extern void ecard_release_resources(struct expansion_card *ec);
-#ifdef ECARD_C
-/* Definitions internal to ecard.c - for it's use only!!
- *
- * External expansion card header as read from the card
- */
-struct ex_ecid {
- unsigned char r_irq:1;
- unsigned char r_zero:1;
- unsigned char r_fiq:1;
- unsigned char r_id:4;
- unsigned char r_a:1;
-
- unsigned char r_cd:1;
- unsigned char r_is:1;
- unsigned char r_w:2;
- unsigned char r_r1:4;
-
- unsigned char r_r2:8;
-
- unsigned char r_prod[2];
-
- unsigned char r_manu[2];
-
- unsigned char r_country;
-
- unsigned char r_fiqmask;
- unsigned char r_fiqoff[3];
-
- unsigned char r_irqmask;
- unsigned char r_irqoff[3];
-};
-
-/*
- * Chunk directory entry as read from the card
- */
-struct ex_chunk_dir {
- unsigned char r_id;
- unsigned char r_len[3];
- unsigned long r_start;
- union {
- char string[256];
- char data[1];
- } d;
-#define c_id(x) ((x)->r_id)
-#define c_len(x) ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16))
-#define c_start(x) ((x)->r_start)
-};
-
-#endif
-
extern struct bus_type ecard_bus_type;
#define ECARD_DEV(_d) container_of((_d), struct expansion_card, dev)
diff --git a/include/asm-arm/hardware/iop3xx.h b/include/asm-arm/hardware/iop3xx.h
index 15141a9..63feceb 100644
--- a/include/asm-arm/hardware/iop3xx.h
+++ b/include/asm-arm/hardware/iop3xx.h
@@ -28,6 +28,7 @@
extern void gpio_line_config(int line, int direction);
extern int gpio_line_get(int line);
extern void gpio_line_set(int line, int value);
+extern int init_atu;
#endif
@@ -41,7 +42,7 @@ extern void gpio_line_set(int line, int value);
IOP3XX_PERIPHERAL_SIZE - 1)
#define IOP3XX_PERIPHERAL_UPPER_VA (IOP3XX_PERIPHERAL_VIRT_BASE +\
IOP3XX_PERIPHERAL_SIZE - 1)
-#define IOP3XX_PMMR_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
+#define IOP3XX_PMMR_PHYS_TO_VIRT(addr) (u32) ((u32) (addr) -\
(IOP3XX_PERIPHERAL_PHYS_BASE\
- IOP3XX_PERIPHERAL_VIRT_BASE))
#define IOP3XX_REG_ADDR(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + (reg))
@@ -103,6 +104,21 @@ extern void gpio_line_set(int line, int value);
#define IOP3XX_PCIXCMD (volatile u16 *)IOP3XX_REG_ADDR(0x01e2)
#define IOP3XX_PCIXSR (volatile u32 *)IOP3XX_REG_ADDR(0x01e4)
#define IOP3XX_PCIIRSR (volatile u32 *)IOP3XX_REG_ADDR(0x01ec)
+#define IOP3XX_PCSR_OUT_Q_BUSY (1 << 15)
+#define IOP3XX_PCSR_IN_Q_BUSY (1 << 14)
+#define IOP3XX_ATUCR_OUT_EN (1 << 1)
+
+#define IOP3XX_INIT_ATU_DEFAULT 0
+#define IOP3XX_INIT_ATU_DISABLE -1
+#define IOP3XX_INIT_ATU_ENABLE 1
+
+#ifdef CONFIG_IOP3XX_ATU
+#define iop3xx_get_init_atu(x) (init_atu == IOP3XX_INIT_ATU_DEFAULT ?\
+ IOP3XX_INIT_ATU_ENABLE : init_atu)
+#else
+#define iop3xx_get_init_atu(x) (init_atu == IOP3XX_INIT_ATU_DEFAULT ?\
+ IOP3XX_INIT_ATU_DISABLE : init_atu)
+#endif
/* Messaging Unit */
#define IOP3XX_IMR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0310)
@@ -253,14 +269,12 @@ extern void gpio_line_set(int line, int value);
/*
* IOP3XX I/O and Mem space regions for PCI autoconfiguration
*/
-#define IOP3XX_PCI_MEM_WINDOW_SIZE 0x04000000
-#define IOP3XX_PCI_LOWER_MEM_PA 0x80000000
-#define IOP3XX_PCI_LOWER_MEM_BA (*IOP3XX_OMWTVR0)
+#define IOP3XX_PCI_LOWER_MEM_PA 0x80000000
#define IOP3XX_PCI_IO_WINDOW_SIZE 0x00010000
#define IOP3XX_PCI_LOWER_IO_PA 0x90000000
#define IOP3XX_PCI_LOWER_IO_VA 0xfe000000
-#define IOP3XX_PCI_LOWER_IO_BA (*IOP3XX_OIOWTVR)
+#define IOP3XX_PCI_LOWER_IO_BA 0x90000000
#define IOP3XX_PCI_UPPER_IO_PA (IOP3XX_PCI_LOWER_IO_PA +\
IOP3XX_PCI_IO_WINDOW_SIZE - 1)
#define IOP3XX_PCI_UPPER_IO_VA (IOP3XX_PCI_LOWER_IO_VA +\
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index 5f60b42..8261ff9 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -56,13 +56,22 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
/*
* Architecture ioremap implementation.
- *
- * __ioremap takes CPU physical address.
- *
- * __ioremap_pfn takes a Page Frame Number and an offset into that page
*/
-extern void __iomem * __ioremap_pfn(unsigned long, unsigned long, size_t, unsigned long);
-extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
+#define MT_DEVICE 0
+#define MT_DEVICE_NONSHARED 1
+#define MT_DEVICE_CACHED 2
+#define MT_DEVICE_IXP2000 3
+/*
+ * types 4 onwards can be found in asm/mach/map.h and are undefined
+ * for ioremap
+ */
+
+/*
+ * __arm_ioremap takes CPU physical address.
+ * __arm_ioremap_pfn takes a Page Frame Number and an offset into that page
+ */
+extern void __iomem * __arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int);
+extern void __iomem * __arm_ioremap(unsigned long, size_t, unsigned int);
extern void __iounmap(volatile void __iomem *addr);
/*
@@ -203,14 +212,14 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
*
*/
#ifndef __arch_ioremap
-#define ioremap(cookie,size) __ioremap(cookie,size,0)
-#define ioremap_nocache(cookie,size) __ioremap(cookie,size,0)
-#define ioremap_cached(cookie,size) __ioremap(cookie,size,L_PTE_CACHEABLE)
+#define ioremap(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE)
+#define ioremap_nocache(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE)
+#define ioremap_cached(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE_CACHED)
#define iounmap(cookie) __iounmap(cookie)
#else
-#define ioremap(cookie,size) __arch_ioremap((cookie),(size),0)
-#define ioremap_nocache(cookie,size) __arch_ioremap((cookie),(size),0)
-#define ioremap_cached(cookie,size) __arch_ioremap((cookie),(size),L_PTE_CACHEABLE)
+#define ioremap(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE)
+#define ioremap_nocache(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE)
+#define ioremap_cached(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_CACHED)
#define iounmap(cookie) __arch_iounmap(cookie)
#endif
diff --git a/include/asm-arm/kdebug.h b/include/asm-arm/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-arm/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h
index 8c1c616..b5b030e 100644
--- a/include/asm-arm/kexec.h
+++ b/include/asm-arm/kexec.h
@@ -16,8 +16,6 @@
#ifndef __ASSEMBLY__
-#define MAX_NOTE_BYTES 1024
-
struct kimage;
/* Provide a dummy definition to avoid build failures. */
static inline void crash_setup_regs(struct pt_regs *newregs,
diff --git a/include/asm-arm/mach/map.h b/include/asm-arm/mach/map.h
index cef5364..7ef3c83 100644
--- a/include/asm-arm/mach/map.h
+++ b/include/asm-arm/mach/map.h
@@ -9,6 +9,8 @@
*
* Page table mapping constructs and function prototypes
*/
+#include <asm/io.h>
+
struct map_desc {
unsigned long virtual;
unsigned long pfn;
@@ -16,15 +18,16 @@ struct map_desc {
unsigned int type;
};
-#define MT_DEVICE 0
-#define MT_CACHECLEAN 1
-#define MT_MINICLEAN 2
-#define MT_LOW_VECTORS 3
-#define MT_HIGH_VECTORS 4
-#define MT_MEMORY 5
-#define MT_ROM 6
-#define MT_IXP2000_DEVICE 7
-#define MT_NONSHARED_DEVICE 8
+/* types 0-3 are defined in asm/io.h */
+#define MT_CACHECLEAN 4
+#define MT_MINICLEAN 5
+#define MT_LOW_VECTORS 6
+#define MT_HIGH_VECTORS 7
+#define MT_MEMORY 8
+#define MT_ROM 9
+
+#define MT_NONSHARED_DEVICE MT_DEVICE_NONSHARED
+#define MT_IXP2000_DEVICE MT_DEVICE_IXP2000
#ifdef CONFIG_MMU
extern void iotable_init(struct map_desc *, int);
diff --git a/include/asm-arm/pgtable-nommu.h b/include/asm-arm/pgtable-nommu.h
index 7b1c9ac..0c8be19 100644
--- a/include/asm-arm/pgtable-nommu.h
+++ b/include/asm-arm/pgtable-nommu.h
@@ -83,10 +83,6 @@ extern int is_in_rom(unsigned long);
#define io_remap_page_range remap_page_range
#define io_remap_pfn_range remap_pfn_range
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/*
* All 32bit addresses are effectively valid for vmalloc...
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index 7b2bafc..21dec9f 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -395,10 +395,6 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
#define io_remap_pfn_range(vma,from,pfn,size,prot) \
remap_pfn_range(vma, from, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#define pgtable_cache_init() do { } while (0)
#endif /* !__ASSEMBLY__ */
diff --git a/include/asm-arm/plat-s3c24xx/clock.h b/include/asm-arm/plat-s3c24xx/clock.h
index f6135db..235b753 100644
--- a/include/asm-arm/plat-s3c24xx/clock.h
+++ b/include/asm-arm/plat-s3c24xx/clock.h
@@ -56,6 +56,7 @@ extern struct mutex clocks_mutex;
extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
extern int s3c24xx_register_clock(struct clk *clk);
+extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
extern int s3c24xx_setup_clocks(unsigned long xtal,
unsigned long fclk,
diff --git a/include/asm-arm/plat-s3c24xx/cpu.h b/include/asm-arm/plat-s3c24xx/cpu.h
index 15dd188..23e420e 100644
--- a/include/asm-arm/plat-s3c24xx/cpu.h
+++ b/include/asm-arm/plat-s3c24xx/cpu.h
@@ -40,22 +40,6 @@ extern void s3c24xx_init_uartdevs(char *name,
struct s3c24xx_uart_resources *res,
struct s3c2410_uartcfg *cfg, int no);
-/* the board structure is used at first initialsation time
- * to get info such as the devices to register for this
- * board. This is done because platfrom_add_devices() cannot
- * be called from the map_io entry.
-*/
-
-struct s3c24xx_board {
- struct platform_device **devices;
- unsigned int devices_count;
-
- struct clk **clocks;
- unsigned int clocks_count;
-};
-
-extern void s3c24xx_set_board(struct s3c24xx_board *board);
-
/* timer for 2410/2440 */
struct sys_timer;
diff --git a/include/asm-arm/ptrace.h b/include/asm-arm/ptrace.h
index 5a8ef78..2d0dad8 100644
--- a/include/asm-arm/ptrace.h
+++ b/include/asm-arm/ptrace.h
@@ -10,23 +10,19 @@
#ifndef __ASM_ARM_PTRACE_H
#define __ASM_ARM_PTRACE_H
-
#define PTRACE_GETREGS 12
#define PTRACE_SETREGS 13
#define PTRACE_GETFPREGS 14
#define PTRACE_SETFPREGS 15
-
+/* PTRACE_ATTACH is 16 */
+/* PTRACE_DETACH is 17 */
#define PTRACE_GETWMMXREGS 18
#define PTRACE_SETWMMXREGS 19
-
+/* 20 is unused */
#define PTRACE_OLDSETOPTIONS 21
-
#define PTRACE_GET_THREAD_AREA 22
-
#define PTRACE_SET_SYSCALL 23
-
/* PTRACE_SYSCALL is 24 */
-
#define PTRACE_GETCRUNCHREGS 25
#define PTRACE_SETCRUNCHREGS 26
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index 69134c7..f2da3b6 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -76,6 +76,8 @@
#include <linux/linkage.h>
#include <linux/irqflags.h>
+#define __exception __attribute__((section(".exception.text")))
+
struct thread_info;
struct task_struct;
@@ -91,7 +93,7 @@ void die(const char *msg, struct pt_regs *regs, int err)
__attribute__((noreturn));
struct siginfo;
-void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
+void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
unsigned long err, unsigned long trap);
void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
@@ -101,8 +103,6 @@ void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
#define xchg(ptr,x) \
((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
-
extern asmlinkage void __backtrace(void);
extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h
index 5014794..eae85b0 100644
--- a/include/asm-arm/thread_info.h
+++ b/include/asm-arm/thread_info.h
@@ -57,6 +57,7 @@ struct thread_info {
__u32 cpu; /* cpu */
__u32 cpu_domain; /* cpu domain */
struct cpu_context_save cpu_context; /* cpu context */
+ __u32 syscall; /* syscall number */
__u8 used_cp[16]; /* thread used copro */
unsigned long tp_value;
struct crunch_state crunchstate;
diff --git a/include/asm-arm26/atomic.h b/include/asm-arm26/atomic.h
index 97e944f..d6dd423 100644
--- a/include/asm-arm26/atomic.h
+++ b/include/asm-arm26/atomic.h
@@ -20,7 +20,6 @@
#ifndef __ASM_ARM_ATOMIC_H
#define __ASM_ARM_ATOMIC_H
-
#ifdef CONFIG_SMP
#error SMP is NOT supported
#endif
diff --git a/include/asm-arm26/kdebug.h b/include/asm-arm26/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-arm26/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-arm26/pgtable.h b/include/asm-arm26/pgtable.h
index 63a8881..2b20e9f 100644
--- a/include/asm-arm26/pgtable.h
+++ b/include/asm-arm26/pgtable.h
@@ -297,10 +297,6 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
#define io_remap_pfn_range(vma,from,pfn,size,prot) \
remap_pfn_range(vma, from, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#endif /* !__ASSEMBLY__ */
#endif /* _ASMARM_PGTABLE_H */
diff --git a/include/asm-arm26/system.h b/include/asm-arm26/system.h
index 00ae32a..4703593 100644
--- a/include/asm-arm26/system.h
+++ b/include/asm-arm26/system.h
@@ -52,8 +52,6 @@ void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
#define xchg(ptr,x) \
((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
-
extern asmlinkage void __backtrace(void);
#define set_cr(x) \
diff --git a/include/asm-avr32/kdebug.h b/include/asm-avr32/kdebug.h
index f583b64..de41927 100644
--- a/include/asm-avr32/kdebug.h
+++ b/include/asm-avr32/kdebug.h
@@ -3,19 +3,6 @@
#include <linux/notifier.h>
-struct pt_regs;
-
-struct die_args {
- struct pt_regs *regs;
- int trapnr;
-};
-
-int register_die_notifier(struct notifier_block *nb);
-int unregister_die_notifier(struct notifier_block *nb);
-int register_page_fault_notifier(struct notifier_block *nb);
-int unregister_page_fault_notifier(struct notifier_block *nb);
-extern struct atomic_notifier_head avr32_die_chain;
-
/* Grossly misnamed. */
enum die_val {
DIE_FAULT,
@@ -24,15 +11,7 @@ enum die_val {
DIE_PAGE_FAULT,
};
-static inline int notify_die(enum die_val val, struct pt_regs *regs,
- int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .trapnr = trap,
- };
-
- return atomic_notifier_call_chain(&avr32_die_chain, val, &args);
-}
+int register_page_fault_notifier(struct notifier_block *nb);
+int unregister_page_fault_notifier(struct notifier_block *nb);
#endif /* __ASM_AVR32_KDEBUG_H */
diff --git a/include/asm-avr32/pgtable.h b/include/asm-avr32/pgtable.h
index 6b8ca9d..f6cc2b0 100644
--- a/include/asm-avr32/pgtable.h
+++ b/include/asm-avr32/pgtable.h
@@ -394,10 +394,6 @@ typedef pte_t *pte_addr_t;
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/* No page table caches to initialize (?) */
#define pgtable_cache_init() do { } while(0)
diff --git a/include/asm-blackfin/Kbuild b/include/asm-blackfin/Kbuild
new file mode 100644
index 0000000..c68e168
--- /dev/null
+++ b/include/asm-blackfin/Kbuild
@@ -0,0 +1 @@
+include include/asm-generic/Kbuild.asm
diff --git a/include/asm-blackfin/a.out.h b/include/asm-blackfin/a.out.h
new file mode 100644
index 0000000..d37a684
--- /dev/null
+++ b/include/asm-blackfin/a.out.h
@@ -0,0 +1,25 @@
+#ifndef __BFIN_A_OUT_H__
+#define __BFIN_A_OUT_H__
+
+struct exec {
+ unsigned long a_info; /* Use macros N_MAGIC, etc for access */
+ unsigned a_text; /* length of text, in bytes */
+ unsigned a_data; /* length of data, in bytes */
+ unsigned a_bss; /* length of uninitialized data area for file, in bytes */
+ unsigned a_syms; /* length of symbol table data in file, in bytes */
+ unsigned a_entry; /* start address */
+ unsigned a_trsize; /* length of relocation info for text, in bytes */
+ unsigned a_drsize; /* length of relocation info for data, in bytes */
+};
+
+#define N_TRSIZE(a) ((a).a_trsize)
+#define N_DRSIZE(a) ((a).a_drsize)
+#define N_SYMSIZE(a) ((a).a_syms)
+
+#ifdef __KERNEL__
+
+#define STACK_TOP TASK_SIZE
+
+#endif
+
+#endif /* __BFIN_A_OUT_H__ */
diff --git a/include/asm-blackfin/atomic.h b/include/asm-blackfin/atomic.h
new file mode 100644
index 0000000..7cf5087
--- /dev/null
+++ b/include/asm-blackfin/atomic.h
@@ -0,0 +1,144 @@
+#ifndef __ARCH_BLACKFIN_ATOMIC__
+#define __ARCH_BLACKFIN_ATOMIC__
+
+#include <asm/system.h> /* local_irq_XXX() */
+
+/*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc..
+ *
+ * Generally we do not concern about SMP BFIN systems, so we don't have
+ * to deal with that.
+ *
+ * Tony Kou (tonyko@lineo.ca) Lineo Inc. 2001
+ */
+
+typedef struct {
+ int counter;
+} atomic_t;
+#define ATOMIC_INIT(i) { (i) }
+
+#define atomic_read(v) ((v)->counter)
+#define atomic_set(v, i) (((v)->counter) = i)
+
+static __inline__ void atomic_add(int i, atomic_t * v)
+{
+ long flags;
+
+ local_irq_save(flags);
+ v->counter += i;
+ local_irq_restore(flags);
+}
+
+static __inline__ void atomic_sub(int i, atomic_t * v)
+{
+ long flags;
+
+ local_irq_save(flags);
+ v->counter -= i;
+ local_irq_restore(flags);
+
+}
+
+static inline int atomic_add_return(int i, atomic_t * v)
+{
+ int __temp = 0;
+ long flags;
+
+ local_irq_save(flags);
+ v->counter += i;
+ __temp = v->counter;
+ local_irq_restore(flags);
+
+
+ return __temp;
+}
+
+#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
+static inline int atomic_sub_return(int i, atomic_t * v)
+{
+ int __temp = 0;
+ long flags;
+
+ local_irq_save(flags);
+ v->counter -= i;
+ __temp = v->counter;
+ local_irq_restore(flags);
+
+ return __temp;
+}
+
+static __inline__ void atomic_inc(volatile atomic_t * v)
+{
+ long flags;
+
+ local_irq_save(flags);
+ v->counter++;
+ local_irq_restore(flags);
+}
+
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+#define atomic_add_unless(v, a, u) \
+({ \
+ int c, old; \
+ c = atomic_read(v); \
+ while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+ c = old; \
+ c != (u); \
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+static __inline__ void atomic_dec(volatile atomic_t * v)
+{
+ long flags;
+
+ local_irq_save(flags);
+ v->counter--;
+ local_irq_restore(flags);
+}
+
+static __inline__ void atomic_clear_mask(unsigned int mask, atomic_t * v)
+{
+ long flags;
+
+ local_irq_save(flags);
+ v->counter &= ~mask;
+ local_irq_restore(flags);
+}
+
+static __inline__ void atomic_set_mask(unsigned int mask, atomic_t * v)
+{
+ long flags;
+
+ local_irq_save(flags);
+ v->counter |= mask;
+ local_irq_restore(flags);
+}
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec() barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc() barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+#define atomic_dec_return(v) atomic_sub_return(1,(v))
+#define atomic_inc_return(v) atomic_add_return(1,(v))
+
+/*
+ * atomic_inc_and_test - increment and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
+
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+#include <asm-generic/atomic.h>
+
+#endif /* __ARCH_BLACKFIN_ATOMIC __ */
diff --git a/include/asm-blackfin/auxvec.h b/include/asm-blackfin/auxvec.h
new file mode 100644
index 0000000..215506c
--- /dev/null
+++ b/include/asm-blackfin/auxvec.h
@@ -0,0 +1,4 @@
+#ifndef __ASMBFIN_AUXVEC_H
+#define __ASMBFIN_AUXVEC_H
+
+#endif
diff --git a/include/asm-blackfin/bf5xx_timers.h b/include/asm-blackfin/bf5xx_timers.h
new file mode 100644
index 0000000..86c7703
--- /dev/null
+++ b/include/asm-blackfin/bf5xx_timers.h
@@ -0,0 +1,209 @@
+/*
+ * include/asm/bf5xx_timers.h
+ *
+ * This file contains the major Data structures and constants
+ * used for General Purpose Timer Implementation in BF5xx
+ *
+ * Copyright (C) 2005 John DeHority
+ * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
+ *
+ */
+
+#ifndef _BLACKFIN_TIMERS_H_
+#define _BLACKFIN_TIMERS_H_
+
+#undef MAX_BLACKFIN_GPTIMERS
+/*
+ * BF537: 8 timers:
+ */
+#if defined(CONFIG_BF537)
+# define MAX_BLACKFIN_GPTIMERS 8
+# define TIMER0_GROUP_REG TIMER_ENABLE
+#endif
+/*
+ * BF561: 12 timers:
+ */
+#if defined(CONFIG_BF561)
+# define MAX_BLACKFIN_GPTIMERS 12
+# define TIMER0_GROUP_REG TMRS8_ENABLE
+# define TIMER8_GROUP_REG TMRS4_ENABLE
+#endif
+/*
+ * All others: 3 timers:
+ */
+#if !defined(MAX_BLACKFIN_GPTIMERS)
+# define MAX_BLACKFIN_GPTIMERS 3
+# define TIMER0_GROUP_REG TIMER_ENABLE
+#endif
+
+#define BLACKFIN_GPTIMER_IDMASK ((1UL << MAX_BLACKFIN_GPTIMERS) - 1)
+#define BFIN_TIMER_OCTET(x) ((x) >> 3)
+
+/* used in masks for timer_enable() and timer_disable() */
+#define TIMER0bit 0x0001 /* 0001b */
+#define TIMER1bit 0x0002 /* 0010b */
+#define TIMER2bit 0x0004 /* 0100b */
+
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER3bit 0x0008
+# define TIMER4bit 0x0010
+# define TIMER5bit 0x0020
+# define TIMER6bit 0x0040
+# define TIMER7bit 0x0080
+#endif
+
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+# define TIMER8bit 0x0100
+# define TIMER9bit 0x0200
+# define TIMER10bit 0x0400
+# define TIMER11bit 0x0800
+#endif
+
+#define TIMER0_id 0
+#define TIMER1_id 1
+#define TIMER2_id 2
+
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER3_id 3
+# define TIMER4_id 4
+# define TIMER5_id 5
+# define TIMER6_id 6
+# define TIMER7_id 7
+#endif
+
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+# define TIMER8_id 8
+# define TIMER9_id 9
+# define TIMER10_id 10
+# define TIMER11_id 11
+#endif
+
+/* associated timers for ppi framesync: */
+
+#if defined(CONFIG_BF561)
+# define FS0_1_TIMER_ID TIMER8_id
+# define FS0_2_TIMER_ID TIMER9_id
+# define FS1_1_TIMER_ID TIMER10_id
+# define FS1_2_TIMER_ID TIMER11_id
+# define FS0_1_TIMER_BIT TIMER8bit
+# define FS0_2_TIMER_BIT TIMER9bit
+# define FS1_1_TIMER_BIT TIMER10bit
+# define FS1_2_TIMER_BIT TIMER11bit
+# undef FS1_TIMER_ID
+# undef FS2_TIMER_ID
+# undef FS1_TIMER_BIT
+# undef FS2_TIMER_BIT
+#else
+# define FS1_TIMER_ID TIMER0_id
+# define FS2_TIMER_ID TIMER1_id
+# define FS1_TIMER_BIT TIMER0bit
+# define FS2_TIMER_BIT TIMER1bit
+#endif
+
+/*
+** Timer Configuration Register Bits
+*/
+#define TIMER_ERR 0xC000
+#define TIMER_ERR_OVFL 0x4000
+#define TIMER_ERR_PROG_PER 0x8000
+#define TIMER_ERR_PROG_PW 0xC000
+#define TIMER_EMU_RUN 0x0200
+#define TIMER_TOGGLE_HI 0x0100
+#define TIMER_CLK_SEL 0x0080
+#define TIMER_OUT_DIS 0x0040
+#define TIMER_TIN_SEL 0x0020
+#define TIMER_IRQ_ENA 0x0010
+#define TIMER_PERIOD_CNT 0x0008
+#define TIMER_PULSE_HI 0x0004
+#define TIMER_MODE 0x0003
+#define TIMER_MODE_PWM 0x0001
+#define TIMER_MODE_WDTH 0x0002
+#define TIMER_MODE_EXT_CLK 0x0003
+
+/*
+** Timer Status Register Bits
+*/
+#define TIMER_STATUS_TIMIL0 0x0001
+#define TIMER_STATUS_TIMIL1 0x0002
+#define TIMER_STATUS_TIMIL2 0x0004
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER_STATUS_TIMIL3 0x00000008
+# define TIMER_STATUS_TIMIL4 0x00010000
+# define TIMER_STATUS_TIMIL5 0x00020000
+# define TIMER_STATUS_TIMIL6 0x00040000
+# define TIMER_STATUS_TIMIL7 0x00080000
+# if (MAX_BLACKFIN_GPTIMERS > 8)
+# define TIMER_STATUS_TIMIL8 0x0001
+# define TIMER_STATUS_TIMIL9 0x0002
+# define TIMER_STATUS_TIMIL10 0x0004
+# define TIMER_STATUS_TIMIL11 0x0008
+# endif
+# define TIMER_STATUS_INTR 0x000F000F
+#else
+# define TIMER_STATUS_INTR 0x0007 /* any timer interrupt */
+#endif
+
+#define TIMER_STATUS_TOVF0 0x0010 /* timer 0 overflow error */
+#define TIMER_STATUS_TOVF1 0x0020
+#define TIMER_STATUS_TOVF2 0x0040
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER_STATUS_TOVF3 0x00000080
+# define TIMER_STATUS_TOVF4 0x00100000
+# define TIMER_STATUS_TOVF5 0x00200000
+# define TIMER_STATUS_TOVF6 0x00400000
+# define TIMER_STATUS_TOVF7 0x00800000
+# if (MAX_BLACKFIN_GPTIMERS > 8)
+# define TIMER_STATUS_TOVF8 0x0010
+# define TIMER_STATUS_TOVF9 0x0020
+# define TIMER_STATUS_TOVF10 0x0040
+# define TIMER_STATUS_TOVF11 0x0080
+# endif
+# define TIMER_STATUS_OFLOW 0x00F000F0
+#else
+# define TIMER_STATUS_OFLOW 0x0070 /* any timer overflow */
+#endif
+
+/*
+** Timer Slave Enable Status : write 1 to clear
+*/
+#define TIMER_STATUS_TRUN0 0x1000
+#define TIMER_STATUS_TRUN1 0x2000
+#define TIMER_STATUS_TRUN2 0x4000
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER_STATUS_TRUN3 0x00008000
+# define TIMER_STATUS_TRUN4 0x10000000
+# define TIMER_STATUS_TRUN5 0x20000000
+# define TIMER_STATUS_TRUN6 0x40000000
+# define TIMER_STATUS_TRUN7 0x80000000
+# define TIMER_STATUS_TRUN 0xF000F000
+# if (MAX_BLACKFIN_GPTIMERS > 8)
+# define TIMER_STATUS_TRUN8 0x1000
+# define TIMER_STATUS_TRUN9 0x2000
+# define TIMER_STATUS_TRUN10 0x4000
+# define TIMER_STATUS_TRUN11 0x8000
+# endif
+#else
+# define TIMER_STATUS_TRUN 0x7000
+#endif
+
+/*******************************************************************************
+* GP_TIMER API's
+*******************************************************************************/
+
+void set_gptimer_pwidth (int timer_id, int width);
+int get_gptimer_pwidth (int timer_id);
+void set_gptimer_period (int timer_id, int period);
+int get_gptimer_period (int timer_id);
+int get_gptimer_count (int timer_id);
+short get_gptimer_intr (int timer_id);
+void set_gptimer_config (int timer_id, short config);
+short get_gptimer_config (int timer_id);
+void set_gptimer_pulse_hi (int timer_id);
+void clear_gptimer_pulse_hi(int timer_id);
+void enable_gptimers (short mask);
+void disable_gptimers (short mask);
+short get_enabled_timers (void);
+int get_gptimer_status (int octet);
+void set_gptimer_status (int octet, int value);
+
+#endif
diff --git a/include/asm-blackfin/bfin-global.h b/include/asm-blackfin/bfin-global.h
new file mode 100644
index 0000000..e37f816
--- /dev/null
+++ b/include/asm-blackfin/bfin-global.h
@@ -0,0 +1,120 @@
+/*
+ * File: include/asm-blackfin/bfin-global.h
+ * Based on:
+ * Author: *
+ * Created:
+ * Description: Global extern defines for blackfin
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _BFIN_GLOBAL_H_
+#define _BFIN_GLOBAL_H_
+
+#ifndef __ASSEMBLY__
+
+#include <asm-generic/sections.h>
+#include <asm/ptrace.h>
+#include <asm/user.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+
+#if defined(CONFIG_DMA_UNCACHED_2M)
+# define DMA_UNCACHED_REGION (2 * 1024 * 1024)
+#elif defined(CONFIG_DMA_UNCACHED_1M)
+# define DMA_UNCACHED_REGION (1024 * 1024)
+#else
+# define DMA_UNCACHED_REGION (0)
+#endif
+
+extern unsigned long get_cclk(void);
+extern unsigned long get_sclk(void);
+
+extern void dump_thread(struct pt_regs *regs, struct user *dump);
+extern void dump_bfin_regs(struct pt_regs *fp, void *retaddr);
+extern void dump_bfin_trace_buffer(void);
+
+extern int init_arch_irq(void);
+extern void bfin_reset(void);
+extern void _cplb_hdr(void);
+/* Blackfin cache functions */
+extern void bfin_icache_init(void);
+extern void bfin_dcache_init(void);
+extern int read_iloc(void);
+extern int bfin_console_init(void);
+extern asmlinkage void lower_to_irq14(void);
+extern void init_dma(void);
+extern void program_IAR(void);
+extern void evt14_softirq(void);
+extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs);
+extern void bfin_gpio_interrupt_setup(int irq, int irq_pfx, int type);
+
+extern void *l1_data_A_sram_alloc(size_t);
+extern void *l1_data_B_sram_alloc(size_t);
+extern void *l1_inst_sram_alloc(size_t);
+extern void *l1_data_sram_alloc(size_t);
+extern void *l1_data_sram_zalloc(size_t);
+extern int l1_data_A_sram_free(const void*);
+extern int l1_data_B_sram_free(const void*);
+extern int l1_inst_sram_free(const void*);
+extern int l1_data_sram_free(const void*);
+extern int sram_free(const void*);
+
+#define L1_INST_SRAM 0x00000001
+#define L1_DATA_A_SRAM 0x00000002
+#define L1_DATA_B_SRAM 0x00000004
+#define L1_DATA_SRAM 0x00000006
+extern void *sram_alloc_with_lsl(size_t, unsigned long);
+extern int sram_free_with_lsl(const void*);
+
+extern void led_on(int);
+extern void led_off(int);
+extern void led_toggle(int);
+extern void led_disp_num(int);
+extern void led_toggle_num(int);
+extern void init_leds(void);
+
+extern char *bfin_board_name __attribute__ ((weak));
+extern unsigned long wall_jiffies;
+extern unsigned long ipdt_table[];
+extern unsigned long dpdt_table[];
+extern unsigned long icplb_table[];
+extern unsigned long dcplb_table[];
+
+extern unsigned long ipdt_swapcount_table[];
+extern unsigned long dpdt_swapcount_table[];
+
+extern unsigned long table_start, table_end;
+
+extern struct file_operations dpmc_fops;
+extern char _start;
+extern unsigned long _ramstart, _ramend, _rambase;
+extern unsigned long memory_start, memory_end, physical_mem_end;
+extern char _stext_l1[], _etext_l1[], _sdata_l1[], _edata_l1[], _sbss_l1[],
+ _ebss_l1[], _l1_lma_start[], _sdata_b_l1[], _ebss_b_l1[];
+
+#ifdef CONFIG_MTD_UCLINUX
+extern unsigned long memory_mtd_start, memory_mtd_end, mtd_size;
+#endif
+
+#endif
+
+#endif /* _BLACKFIN_H_ */
diff --git a/include/asm-blackfin/bfin5xx_spi.h b/include/asm-blackfin/bfin5xx_spi.h
new file mode 100644
index 0000000..95c1c95
--- /dev/null
+++ b/include/asm-blackfin/bfin5xx_spi.h
@@ -0,0 +1,170 @@
+/************************************************************
+*
+* Copyright (C) 2004, Analog Devices. All Rights Reserved
+*
+* FILE bfin5xx_spi.h
+* PROGRAMMER(S): Luke Yang (Analog Devices Inc.)
+*
+*
+* DATE OF CREATION: March. 10th 2006
+*
+* SYNOPSIS:
+*
+* DESCRIPTION: header file for SPI controller driver for Blackfin5xx.
+**************************************************************
+
+* MODIFICATION HISTORY:
+* March 10, 2006 bfin5xx_spi.h Created. (Luke Yang)
+
+************************************************************/
+
+#ifndef _SPI_CHANNEL_H_
+#define _SPI_CHANNEL_H_
+
+#define SPI0_REGBASE 0xffc00500
+
+#define SPI_READ 0
+#define SPI_WRITE 1
+
+#define SPI_CTRL_OFF 0x0
+#define SPI_FLAG_OFF 0x4
+#define SPI_STAT_OFF 0x8
+#define SPI_TXBUFF_OFF 0xc
+#define SPI_RXBUFF_OFF 0x10
+#define SPI_BAUD_OFF 0x14
+#define SPI_SHAW_OFF 0x18
+
+#define CMD_SPI_OUT_ENABLE 1
+#define CMD_SPI_SET_BAUDRATE 2
+#define CMD_SPI_SET_POLAR 3
+#define CMD_SPI_SET_PHASE 4
+#define CMD_SPI_SET_MASTER 5
+#define CMD_SPI_SET_SENDOPT 6
+#define CMD_SPI_SET_RECVOPT 7
+#define CMD_SPI_SET_ORDER 8
+#define CMD_SPI_SET_LENGTH16 9
+#define CMD_SPI_GET_STAT 11
+#define CMD_SPI_GET_CFG 12
+#define CMD_SPI_SET_CSAVAIL 13
+#define CMD_SPI_SET_CSHIGH 14 /* CS unavail */
+#define CMD_SPI_SET_CSLOW 15 /* CS avail */
+#define CMD_SPI_MISO_ENABLE 16
+#define CMD_SPI_SET_CSENABLE 17
+#define CMD_SPI_SET_CSDISABLE 18
+
+#define CMD_SPI_SET_TRIGGER_MODE 19
+#define CMD_SPI_SET_TRIGGER_SENSE 20
+#define CMD_SPI_SET_TRIGGER_EDGE 21
+#define CMD_SPI_SET_TRIGGER_LEVEL 22
+
+#define CMD_SPI_SET_TIME_SPS 23
+#define CMD_SPI_SET_TIME_SAMPLES 24
+#define CMD_SPI_GET_SYSTEMCLOCK 25
+
+#define CMD_SPI_SET_WRITECONTINUOUS 26
+#define CMD_SPI_SET_SKFS 27
+
+#define CMD_SPI_GET_ALLCONFIG 32 /* For debug */
+
+#define SPI_DEFAULT_BARD 0x0100
+
+#define SPI0_IRQ_NUM IRQ_SPI
+#define SPI_ERR_TRIG -1
+
+#define BIT_CTL_ENABLE 0x4000
+#define BIT_CTL_OPENDRAIN 0x2000
+#define BIT_CTL_MASTER 0x1000
+#define BIT_CTL_POLAR 0x0800
+#define BIT_CTL_PHASE 0x0400
+#define BIT_CTL_BITORDER 0x0200
+#define BIT_CTL_WORDSIZE 0x0100
+#define BIT_CTL_MISOENABLE 0x0020
+#define BIT_CTL_RXMOD 0x0000
+#define BIT_CTL_TXMOD 0x0001
+#define BIT_CTL_TIMOD_DMA_TX 0x0003
+#define BIT_CTL_TIMOD_DMA_RX 0x0002
+#define BIT_CTL_SENDOPT 0x0004
+#define BIT_CTL_TIMOD 0x0003
+
+#define BIT_STAT_SPIF 0x0001
+#define BIT_STAT_MODF 0x0002
+#define BIT_STAT_TXE 0x0004
+#define BIT_STAT_TXS 0x0008
+#define BIT_STAT_RBSY 0x0010
+#define BIT_STAT_RXS 0x0020
+#define BIT_STAT_TXCOL 0x0040
+#define BIT_STAT_CLR 0xFFFF
+
+#define BIT_STU_SENDOVER 0x0001
+#define BIT_STU_RECVFULL 0x0020
+
+#define CFG_SPI_ENABLE 1
+#define CFG_SPI_DISABLE 0
+
+#define CFG_SPI_OUTENABLE 1
+#define CFG_SPI_OUTDISABLE 0
+
+#define CFG_SPI_ACTLOW 1
+#define CFG_SPI_ACTHIGH 0
+
+#define CFG_SPI_PHASESTART 1
+#define CFG_SPI_PHASEMID 0
+
+#define CFG_SPI_MASTER 1
+#define CFG_SPI_SLAVE 0
+
+#define CFG_SPI_SENELAST 0
+#define CFG_SPI_SENDZERO 1
+
+#define CFG_SPI_RCVFLUSH 1
+#define CFG_SPI_RCVDISCARD 0
+
+#define CFG_SPI_LSBFIRST 1
+#define CFG_SPI_MSBFIRST 0
+
+#define CFG_SPI_WORDSIZE16 1
+#define CFG_SPI_WORDSIZE8 0
+
+#define CFG_SPI_MISOENABLE 1
+#define CFG_SPI_MISODISABLE 0
+
+#define CFG_SPI_READ 0x00
+#define CFG_SPI_WRITE 0x01
+#define CFG_SPI_DMAREAD 0x02
+#define CFG_SPI_DMAWRITE 0x03
+
+#define CFG_SPI_CSCLEARALL 0
+#define CFG_SPI_CHIPSEL1 1
+#define CFG_SPI_CHIPSEL2 2
+#define CFG_SPI_CHIPSEL3 3
+#define CFG_SPI_CHIPSEL4 4
+#define CFG_SPI_CHIPSEL5 5
+#define CFG_SPI_CHIPSEL6 6
+#define CFG_SPI_CHIPSEL7 7
+
+#define CFG_SPI_CS1VALUE 1
+#define CFG_SPI_CS2VALUE 2
+#define CFG_SPI_CS3VALUE 3
+#define CFG_SPI_CS4VALUE 4
+#define CFG_SPI_CS5VALUE 5
+#define CFG_SPI_CS6VALUE 6
+#define CFG_SPI_CS7VALUE 7
+
+/* device.platform_data for SSP controller devices */
+struct bfin5xx_spi_master {
+ u16 num_chipselect;
+ u8 enable_dma;
+};
+
+/* spi_board_info.controller_data for SPI slave devices,
+ * copied to spi_device.platform_data ... mostly for dma tuning
+ */
+struct bfin5xx_spi_chip {
+ u16 ctl_reg;
+ u8 enable_dma;
+ u8 bits_per_word;
+ u8 cs_change_per_word;
+ u8 cs_chg_udelay;
+};
+
+#endif /* _SPI_CHANNEL_H_ */
diff --git a/include/asm-blackfin/bfin_simple_timer.h b/include/asm-blackfin/bfin_simple_timer.h
new file mode 100644
index 0000000..fccbb59
--- /dev/null
+++ b/include/asm-blackfin/bfin_simple_timer.h
@@ -0,0 +1,13 @@
+#ifndef _bfin_simple_timer_h_
+#define _bfin_simple_timer_h_
+
+#include <linux/ioctl.h>
+
+#define BFIN_SIMPLE_TIMER_IOCTL_MAGIC 't'
+
+#define BFIN_SIMPLE_TIMER_SET_PERIOD _IO (BFIN_SIMPLE_TIMER_IOCTL_MAGIC, 2)
+#define BFIN_SIMPLE_TIMER_START _IO (BFIN_SIMPLE_TIMER_IOCTL_MAGIC, 6)
+#define BFIN_SIMPLE_TIMER_STOP _IO (BFIN_SIMPLE_TIMER_IOCTL_MAGIC, 8)
+#define BFIN_SIMPLE_TIMER_READ _IO (BFIN_SIMPLE_TIMER_IOCTL_MAGIC, 10)
+
+#endif
diff --git a/include/asm-blackfin/bfin_sport.h b/include/asm-blackfin/bfin_sport.h
new file mode 100644
index 0000000..c76ed8d
--- /dev/null
+++ b/include/asm-blackfin/bfin_sport.h
@@ -0,0 +1,175 @@
+/*
+ * File: include/asm-blackfin/bfin_sport.h
+ * Based on:
+ * Author: Roy Huang (roy.huang@analog.com)
+ *
+ * Created: Thu Aug. 24 2006
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __BFIN_SPORT_H__
+#define __BFIN_SPORT_H__
+
+#define SPORT_MAJOR 237
+#define SPORT_NR_DEVS 2
+
+/* Sport mode: it can be set to TDM, i2s or others */
+#define NORM_MODE 0x0
+#define TDM_MODE 0x1
+#define I2S_MODE 0x2
+
+/* Data format, normal, a-law or u-law */
+#define NORM_FORMAT 0x0
+#define ALAW_FORMAT 0x2
+#define ULAW_FORMAT 0x3
+struct sport_register;
+
+/* Function driver which use sport must initialize the structure */
+struct sport_config {
+ /*TDM (multichannels), I2S or other mode */
+ unsigned int mode:3;
+
+ /* if TDM mode is selected, channels must be set */
+ int channels; /* Must be in 8 units */
+ unsigned int frame_delay:4; /* Delay between frame sync pulse and first bit */
+
+ /* I2S mode */
+ unsigned int right_first:1; /* Right stereo channel first */
+
+ /* In mormal mode, the following item need to be set */
+ unsigned int lsb_first:1; /* order of transmit or receive data */
+ unsigned int fsync:1; /* Frame sync required */
+ unsigned int data_indep:1; /* data independent frame sync generated */
+ unsigned int act_low:1; /* Active low TFS */
+ unsigned int late_fsync:1; /* Late frame sync */
+ unsigned int tckfe:1;
+ unsigned int sec_en:1; /* Secondary side enabled */
+
+ /* Choose clock source */
+ unsigned int int_clk:1; /* Internal or external clock */
+
+ /* If external clock is used, the following fields are ignored */
+ int serial_clk;
+ int fsync_clk;
+
+ unsigned int data_format:2; /*Normal, u-law or a-law */
+
+ int word_len; /* How length of the word in bits, 3-32 bits */
+ int dma_enabled;
+};
+
+struct sport_register {
+ unsigned short tcr1;
+ unsigned short reserved0;
+ unsigned short tcr2;
+ unsigned short reserved1;
+ unsigned short tclkdiv;
+ unsigned short reserved2;
+ unsigned short tfsdiv;
+ unsigned short reserved3;
+ unsigned long tx;
+ unsigned long reserved_l0;
+ unsigned long rx;
+ unsigned long reserved_l1;
+ unsigned short rcr1;
+ unsigned short reserved4;
+ unsigned short rcr2;
+ unsigned short reserved5;
+ unsigned short rclkdiv;
+ unsigned short reserved6;
+ unsigned short rfsdiv;
+ unsigned short reserved7;
+ unsigned short stat;
+ unsigned short reserved8;
+ unsigned short chnl;
+ unsigned short reserved9;
+ unsigned short mcmc1;
+ unsigned short reserved10;
+ unsigned short mcmc2;
+ unsigned short reserved11;
+ unsigned long mtcs0;
+ unsigned long mtcs1;
+ unsigned long mtcs2;
+ unsigned long mtcs3;
+ unsigned long mrcs0;
+ unsigned long mrcs1;
+ unsigned long mrcs2;
+ unsigned long mrcs3;
+};
+
+#define SPORT_IOC_MAGIC 'P'
+#define SPORT_IOC_CONFIG _IOWR('P', 0x01, struct sport_config)
+
+/* Test purpose */
+#define ENABLE_AD73311 _IOWR('P', 0x02, int)
+
+struct sport_dev {
+ struct cdev cdev; /* Char device structure */
+
+ int sport_num;
+
+ int dma_rx_chan;
+ int dma_tx_chan;
+
+ int rx_irq;
+ unsigned char *rx_buf; /* Buffer store the received data */
+ int rx_len; /* How many bytes will be received */
+ int rx_received; /* How many bytes has been received */
+
+ int tx_irq;
+ const unsigned char *tx_buf;
+ int tx_len;
+ int tx_sent;
+
+ int sport_err_irq;
+
+ struct mutex mutex; /* mutual exclusion semaphore */
+ struct task_struct *task;
+
+ wait_queue_head_t waitq;
+ int wait_con;
+ struct sport_register *regs;
+ struct sport_config config;
+};
+
+#define SPORT_TCR1 0
+#define SPORT_TCR2 1
+#define SPORT_TCLKDIV 2
+#define SPORT_TFSDIV 3
+#define SPORT_RCR1 8
+#define SPORT_RCR2 9
+#define SPORT_RCLKDIV 10
+#define SPORT_RFSDIV 11
+#define SPORT_CHANNEL 13
+#define SPORT_MCMC1 14
+#define SPORT_MCMC2 15
+#define SPORT_MTCS0 16
+#define SPORT_MTCS1 17
+#define SPORT_MTCS2 18
+#define SPORT_MTCS3 19
+#define SPORT_MRCS0 20
+#define SPORT_MRCS1 21
+#define SPORT_MRCS2 22
+#define SPORT_MRCS3 23
+
+#endif /*__BFIN_SPORT_H__*/
diff --git a/include/asm-blackfin/bitops.h b/include/asm-blackfin/bitops.h
new file mode 100644
index 0000000..27c2d0e
--- /dev/null
+++ b/include/asm-blackfin/bitops.h
@@ -0,0 +1,213 @@
+#ifndef _BLACKFIN_BITOPS_H
+#define _BLACKFIN_BITOPS_H
+
+/*
+ * Copyright 1992, Linus Torvalds.
+ */
+
+#include <linux/compiler.h>
+#include <asm/byteorder.h> /* swab32 */
+#include <asm/system.h> /* save_flags */
+
+#ifdef __KERNEL__
+
+#include <asm-generic/bitops/ffs.h>
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/ffz.h>
+
+static __inline__ void set_bit(int nr, volatile unsigned long *addr)
+{
+ int *a = (int *)addr;
+ int mask;
+ unsigned long flags;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ local_irq_save(flags);
+ *a |= mask;
+ local_irq_restore(flags);
+}
+
+static __inline__ void __set_bit(int nr, volatile unsigned long *addr)
+{
+ int *a = (int *)addr;
+ int mask;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ *a |= mask;
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit() barrier()
+#define smp_mb__after_clear_bit() barrier()
+
+static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
+{
+ int *a = (int *)addr;
+ int mask;
+ unsigned long flags;
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ local_irq_save(flags);
+ *a &= ~mask;
+ local_irq_restore(flags);
+}
+
+static __inline__ void __clear_bit(int nr, volatile unsigned long *addr)
+{
+ int *a = (int *)addr;
+ int mask;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ *a &= ~mask;
+}
+
+static __inline__ void change_bit(int nr, volatile unsigned long *addr)
+{
+ int mask, flags;
+ unsigned long *ADDR = (unsigned long *)addr;
+
+ ADDR += nr >> 5;
+ mask = 1 << (nr & 31);
+ local_irq_save(flags);
+ *ADDR ^= mask;
+ local_irq_restore(flags);
+}
+
+static __inline__ void __change_bit(int nr, volatile unsigned long *addr)
+{
+ int mask;
+ unsigned long *ADDR = (unsigned long *)addr;
+
+ ADDR += nr >> 5;
+ mask = 1 << (nr & 31);
+ *ADDR ^= mask;
+}
+
+static __inline__ int test_and_set_bit(int nr, void *addr)
+{
+ int mask, retval;
+ volatile unsigned int *a = (volatile unsigned int *)addr;
+ unsigned long flags;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ local_irq_save(flags);
+ retval = (mask & *a) != 0;
+ *a |= mask;
+ local_irq_restore(flags);
+
+ return retval;
+}
+
+static __inline__ int __test_and_set_bit(int nr, volatile unsigned long *addr)
+{
+ int mask, retval;
+ volatile unsigned int *a = (volatile unsigned int *)addr;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ retval = (mask & *a) != 0;
+ *a |= mask;
+ return retval;
+}
+
+static __inline__ int test_and_clear_bit(int nr, volatile unsigned long *addr)
+{
+ int mask, retval;
+ volatile unsigned int *a = (volatile unsigned int *)addr;
+ unsigned long flags;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ local_irq_save(flags);
+ retval = (mask & *a) != 0;
+ *a &= ~mask;
+ local_irq_restore(flags);
+
+ return retval;
+}
+
+static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long *addr)
+{
+ int mask, retval;
+ volatile unsigned int *a = (volatile unsigned int *)addr;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ retval = (mask & *a) != 0;
+ *a &= ~mask;
+ return retval;
+}
+
+static __inline__ int test_and_change_bit(int nr, volatile unsigned long *addr)
+{
+ int mask, retval;
+ volatile unsigned int *a = (volatile unsigned int *)addr;
+ unsigned long flags;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ local_irq_save(flags);
+ retval = (mask & *a) != 0;
+ *a ^= mask;
+ local_irq_restore(flags);
+ return retval;
+}
+
+static __inline__ int __test_and_change_bit(int nr,
+ volatile unsigned long *addr)
+{
+ int mask, retval;
+ volatile unsigned int *a = (volatile unsigned int *)addr;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ retval = (mask & *a) != 0;
+ *a ^= mask;
+ return retval;
+}
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+static __inline__ int __constant_test_bit(int nr, const void *addr)
+{
+ return ((1UL << (nr & 31)) &
+ (((const volatile unsigned int *)addr)[nr >> 5])) != 0;
+}
+
+static __inline__ int __test_bit(int nr, const void *addr)
+{
+ int *a = (int *)addr;
+ int mask;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ return ((mask & *a) != 0);
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ __constant_test_bit((nr),(addr)) : \
+ __test_bit((nr),(addr)))
+
+#include <asm-generic/bitops/find.h>
+#include <asm-generic/bitops/hweight.h>
+
+#include <asm-generic/bitops/ext2-atomic.h>
+#include <asm-generic/bitops/ext2-non-atomic.h>
+
+#include <asm-generic/bitops/minix.h>
+
+#endif /* __KERNEL__ */
+
+#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/fls64.h>
+
+#endif /* _BLACKFIN_BITOPS_H */
diff --git a/include/asm-blackfin/blackfin.h b/include/asm-blackfin/blackfin.h
new file mode 100644
index 0000000..14e58de
--- /dev/null
+++ b/include/asm-blackfin/blackfin.h
@@ -0,0 +1,81 @@
+/*
+ * Common header file for blackfin family of processors.
+ *
+ */
+
+#ifndef _BLACKFIN_H_
+#define _BLACKFIN_H_
+
+#include <asm/macros.h>
+#include <asm/mach/blackfin.h>
+#include <asm/bfin-global.h>
+
+#ifndef __ASSEMBLY__
+
+/* SSYNC implementation for C file */
+#if defined(ANOMALY_05000312) && defined(ANOMALY_05000244)
+static inline void SSYNC (void)
+{
+ int _tmp;
+ __asm__ __volatile__ ("cli %0;\n\t"
+ "nop;nop;\n\t"
+ "ssync;\n\t"
+ "sti %0;\n\t"
+ :"=d"(_tmp):);
+}
+#elif defined(ANOMALY_05000312) && !defined(ANOMALY_05000244)
+static inline void SSYNC (void)
+{
+ int _tmp;
+ __asm__ __volatile__ ("cli %0;\n\t"
+ "ssync;\n\t"
+ "sti %0;\n\t"
+ :"=d"(_tmp):);
+}
+#elif !defined(ANOMALY_05000312) && defined(ANOMALY_05000244)
+static inline void SSYNC (void)
+{
+ __builtin_bfin_ssync();
+}
+#elif !defined(ANOMALY_05000312) && !defined(ANOMALY_05000244)
+static inline void SSYNC (void)
+{
+ __asm__ __volatile__ ("ssync;\n\t");
+}
+#endif
+
+/* CSYNC implementation for C file */
+#if defined(ANOMALY_05000312) && defined(ANOMALY_05000244)
+static inline void CSYNC (void)
+{
+ int _tmp;
+ __asm__ __volatile__ ("cli %0;\n\t"
+ "nop;nop;\n\t"
+ "csync;\n\t"
+ "sti %0;\n\t"
+ :"=d"(_tmp):);
+}
+#elif defined(ANOMALY_05000312) && !defined(ANOMALY_05000244)
+static inline void CSYNC (void)
+{
+ int _tmp;
+ __asm__ __volatile__ ("cli %0;\n\t"
+ "csync;\n\t"
+ "sti %0;\n\t"
+ :"=d"(_tmp):);
+}
+#elif !defined(ANOMALY_05000312) && defined(ANOMALY_05000244)
+static inline void CSYNC (void)
+{
+ __builtin_bfin_csync();
+}
+#elif !defined(ANOMALY_05000312) && !defined(ANOMALY_05000244)
+static inline void CSYNC (void)
+{
+ __asm__ __volatile__ ("csync;\n\t");
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _BLACKFIN_H_ */
diff --git a/include/asm-blackfin/bug.h b/include/asm-blackfin/bug.h
new file mode 100644
index 0000000..41e53b2
--- /dev/null
+++ b/include/asm-blackfin/bug.h
@@ -0,0 +1,4 @@
+#ifndef _BLACKFIN_BUG_H
+#define _BLACKFIN_BUG_H
+#include <asm-generic/bug.h>
+#endif
diff --git a/include/asm-blackfin/bugs.h b/include/asm-blackfin/bugs.h
new file mode 100644
index 0000000..9093c9c
--- /dev/null
+++ b/include/asm-blackfin/bugs.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-blackfin/bugs.h
+ *
+ * Copyright (C) 1994 Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ * void check_bugs(void);
+ */
+
+static void check_bugs(void)
+{
+}
diff --git a/include/asm-blackfin/byteorder.h b/include/asm-blackfin/byteorder.h
new file mode 100644
index 0000000..6a673d4
--- /dev/null
+++ b/include/asm-blackfin/byteorder.h
@@ -0,0 +1,48 @@
+#ifndef _BLACKFIN_BYTEORDER_H
+#define _BLACKFIN_BYTEORDER_H
+
+#include <asm/types.h>
+#include <linux/compiler.h>
+
+#ifdef __GNUC__
+
+static __inline__ __attribute_const__ __u32 ___arch__swahb32(__u32 xx)
+{
+ __u32 tmp;
+ __asm__("%1 = %0 >> 8 (V);\n\t"
+ "%0 = %0 << 8 (V);\n\t"
+ "%0 = %0 | %1;\n\t"
+ : "+d"(xx), "=&d"(tmp));
+ return xx;
+}
+
+static __inline__ __attribute_const__ __u32 ___arch__swahw32(__u32 xx)
+{
+ __u32 rv;
+ __asm__("%0 = PACK(%1.L, %1.H);\n\t": "=d"(rv): "d"(xx));
+ return rv;
+}
+
+#define __arch__swahb32(x) ___arch__swahb32(x)
+#define __arch__swahw32(x) ___arch__swahw32(x)
+#define __arch__swab32(x) ___arch__swahb32(___arch__swahw32(x))
+
+static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 xx)
+{
+ __u32 xw = xx;
+ __asm__("%0 <<= 8;\n %0.L = %0.L + %0.H (NS);\n": "+d"(xw));
+ return (__u16)xw;
+}
+
+#define __arch__swab16(x) ___arch__swab16(x)
+
+#endif
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+# define __BYTEORDER_HAS_U64__
+# define __SWAB_64_THRU_32__
+#endif
+
+#include <linux/byteorder/little_endian.h>
+
+#endif /* _BLACKFIN_BYTEORDER_H */
diff --git a/include/asm-blackfin/cache.h b/include/asm-blackfin/cache.h
new file mode 100644
index 0000000..023d721
--- /dev/null
+++ b/include/asm-blackfin/cache.h
@@ -0,0 +1,29 @@
+/*
+ * include/asm-blackfin/cache.h
+ */
+#ifndef __ARCH_BLACKFIN_CACHE_H
+#define __ARCH_BLACKFIN_CACHE_H
+
+/*
+ * Bytes per L1 cache line
+ * Blackfin loads 32 bytes for cache
+ */
+#define L1_CACHE_SHIFT 5
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+#define SMP_CACHE_BYTES L1_CACHE_BYTES
+
+/*
+ * Put cacheline_aliged data to L1 data memory
+ */
+#ifdef CONFIG_CACHELINE_ALIGNED_L1
+#define __cacheline_aligned \
+ __attribute__((__aligned__(L1_CACHE_BYTES), \
+ __section__(".data_l1.cacheline_aligned")))
+#endif
+
+/*
+ * largest L1 which this arch supports
+ */
+#define L1_CACHE_SHIFT_MAX 5
+
+#endif
diff --git a/include/asm-blackfin/cacheflush.h b/include/asm-blackfin/cacheflush.h
new file mode 100644
index 0000000..e5e000d
--- /dev/null
+++ b/include/asm-blackfin/cacheflush.h
@@ -0,0 +1,90 @@
+/*
+ * File: include/asm-blackfin/cacheflush.h
+ * Based on: include/asm-m68knommu/cacheflush.h
+ * Author: LG Soft India
+ * Copyright (C) 2004 Analog Devices Inc.
+ * Created: Tue Sep 21 2004
+ * Description: Blackfin low-level cache routines adapted from the i386
+ * and PPC versions by Greg Ungerer (gerg@snapgear.com)
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _BLACKFIN_CACHEFLUSH_H
+#define _BLACKFIN_CACHEFLUSH_H
+
+#include <asm/cplb.h>
+
+extern void blackfin_icache_dcache_flush_range(unsigned int, unsigned int);
+extern void blackfin_icache_flush_range(unsigned int, unsigned int);
+extern void blackfin_dcache_flush_range(unsigned int, unsigned int);
+extern void blackfin_dcache_invalidate_range(unsigned int, unsigned int);
+extern void blackfin_dflush_page(void *);
+
+#define flush_dcache_mmap_lock(mapping) do { } while (0)
+#define flush_dcache_mmap_unlock(mapping) do { } while (0)
+#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_range(vma, start, end) do { } while (0)
+#define flush_cache_page(vma, vmaddr) do { } while (0)
+#define flush_cache_vmap(start, end) do { } while (0)
+#define flush_cache_vunmap(start, end) do { } while (0)
+
+static inline void flush_icache_range(unsigned start, unsigned end)
+{
+#if defined(CONFIG_BLKFIN_DCACHE) && defined(CONFIG_BLKFIN_CACHE)
+
+# if defined(CONFIG_BLKFIN_WT)
+ blackfin_icache_flush_range((start), (end));
+# else
+ blackfin_icache_dcache_flush_range((start), (end));
+# endif
+
+#else
+
+# if defined(CONFIG_BLKFIN_CACHE)
+ blackfin_icache_flush_range((start), (end));
+# endif
+# if defined(CONFIG_BLKFIN_DCACHE)
+ blackfin_dcache_flush_range((start), (end));
+# endif
+
+#endif
+}
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+do { memcpy(dst, src, len); \
+ flush_icache_range ((unsigned) (dst), (unsigned) (dst) + (len)); \
+} while (0)
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) memcpy(dst, src, len)
+
+#if defined(CONFIG_BLKFIN_DCACHE)
+# define invalidate_dcache_range(start,end) blackfin_dcache_invalidate_range((start), (end))
+#else
+# define invalidate_dcache_range(start,end) do { } while (0)
+#endif
+#if defined(CONFIG_BLKFIN_DCACHE) && defined(CONFIG_BLKFIN_WB)
+# define flush_dcache_range(start,end) blackfin_dcache_flush_range((start), (end))
+# define flush_dcache_page(page) blackfin_dflush_page(page_address(page))
+#else
+# define flush_dcache_range(start,end) do { } while (0)
+# define flush_dcache_page(page) do { } while (0)
+#endif
+
+#endif /* _BLACKFIN_CACHEFLUSH_H */
diff --git a/include/asm-blackfin/checksum.h b/include/asm-blackfin/checksum.h
new file mode 100644
index 0000000..2638f25
--- /dev/null
+++ b/include/asm-blackfin/checksum.h
@@ -0,0 +1,101 @@
+#ifndef _BFIN_CHECKSUM_H
+#define _BFIN_CHECKSUM_H
+
+/*
+ * MODIFIED FOR BFIN April 30, 2001 akbar.hussain@lineo.com
+ *
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst,
+ int len, int sum);
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+extern unsigned int csum_partial_copy_from_user(const unsigned char *src,
+ unsigned char *dst, int len,
+ int sum, int *csum_err);
+
+#define csum_partial_copy_nocheck(src, dst, len, sum) \
+ csum_partial_copy((src), (dst), (len), (sum))
+
+unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl);
+
+/*
+ * Fold a partial checksum
+ */
+
+static inline unsigned int csum_fold(unsigned int sum)
+{
+ while (sum >> 16)
+ sum = (sum & 0xffff) + (sum >> 16);
+ return ((~(sum << 16)) >> 16);
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+
+static inline unsigned int
+csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
+ unsigned short proto, unsigned int sum)
+{
+
+ __asm__ ("%0 = %0 + %1;\n\t"
+ "CC = AC0;\n\t"
+ "if !CC jump 4;\n\t"
+ "%0 = %0 + %4;\n\t"
+ "%0 = %0 + %2;\n\t"
+ "CC = AC0;\n\t"
+ "if !CC jump 4;\n\t"
+ "%0 = %0 + %4;\n\t"
+ "%0 = %0 + %3;\n\t"
+ "CC = AC0;\n\t"
+ "if !CC jump 4;\n\t"
+ "%0 = %0 + %4;\n\t"
+ "NOP;\n\t"
+ : "=d" (sum)
+ : "d" (daddr), "d" (saddr), "d" ((ntohs(len)<<16)+proto*256), "d" (1), "0"(sum));
+
+ return (sum);
+}
+
+static inline unsigned short int
+csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
+ unsigned short proto, unsigned int sum)
+{
+ return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+extern unsigned short ip_compute_csum(const unsigned char *buff, int len);
+
+#endif /* _BFIN_CHECKSUM_H */
diff --git a/include/asm-blackfin/cplb.h b/include/asm-blackfin/cplb.h
new file mode 100644
index 0000000..e0dd56b
--- /dev/null
+++ b/include/asm-blackfin/cplb.h
@@ -0,0 +1,51 @@
+/************************************************************************
+ *
+ * cplb.h
+ *
+ * (c) Copyright 2002-2003 Analog Devices, Inc. All rights reserved.
+ *
+ ************************************************************************/
+
+/* Defines necessary for cplb initialisation routines. */
+
+#ifndef _CPLB_H
+#define _CPLB_H
+
+# include <asm/blackfin.h>
+
+#define CPLB_ENABLE_ICACHE_P 0
+#define CPLB_ENABLE_DCACHE_P 1
+#define CPLB_ENABLE_DCACHE2_P 2
+#define CPLB_ENABLE_CPLBS_P 3 /* Deprecated! */
+#define CPLB_ENABLE_ICPLBS_P 4
+#define CPLB_ENABLE_DCPLBS_P 5
+
+#define CPLB_ENABLE_ICACHE (1<<CPLB_ENABLE_ICACHE_P)
+#define CPLB_ENABLE_DCACHE (1<<CPLB_ENABLE_DCACHE_P)
+#define CPLB_ENABLE_DCACHE2 (1<<CPLB_ENABLE_DCACHE2_P)
+#define CPLB_ENABLE_CPLBS (1<<CPLB_ENABLE_CPLBS_P)
+#define CPLB_ENABLE_ICPLBS (1<<CPLB_ENABLE_ICPLBS_P)
+#define CPLB_ENABLE_DCPLBS (1<<CPLB_ENABLE_DCPLBS_P)
+#define CPLB_ENABLE_ANY_CPLBS CPLB_ENABLE_CPLBS | \
+ CPLB_ENABLE_ICPLBS | \
+ CPLB_ENABLE_DCPLBS
+
+#define CPLB_RELOADED 0x0000
+#define CPLB_NO_UNLOCKED 0x0001
+#define CPLB_NO_ADDR_MATCH 0x0002
+#define CPLB_PROT_VIOL 0x0003
+#define CPLB_UNKNOWN_ERR 0x0004
+
+#define CPLB_DEF_CACHE CPLB_L1_CHBL | CPLB_WT
+#define CPLB_CACHE_ENABLED CPLB_L1_CHBL | CPLB_DIRTY
+
+#define CPLB_ALL_ACCESS CPLB_SUPV_WR | CPLB_USER_RD | CPLB_USER_WR
+
+#define CPLB_I_PAGE_MGMT CPLB_LOCK | CPLB_VALID
+#define CPLB_D_PAGE_MGMT CPLB_LOCK | CPLB_ALL_ACCESS | CPLB_VALID
+#define CPLB_DNOCACHE CPLB_ALL_ACCESS | CPLB_VALID
+#define CPLB_DDOCACHE CPLB_DNOCACHE | CPLB_DEF_CACHE
+#define CPLB_INOCACHE CPLB_USER_RD | CPLB_VALID
+#define CPLB_IDOCACHE CPLB_INOCACHE | CPLB_L1_CHBL
+
+#endif /* _CPLB_H */
diff --git a/include/asm-blackfin/cplbinit.h b/include/asm-blackfin/cplbinit.h
new file mode 100644
index 0000000..3bad2d1
--- /dev/null
+++ b/include/asm-blackfin/cplbinit.h
@@ -0,0 +1,203 @@
+/*
+ * File: include/asm-blackfin/cplbinit.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <asm/blackfin.h>
+#include <asm/cplb.h>
+
+#define INITIAL_T 0x1
+#define SWITCH_T 0x2
+#define I_CPLB 0x4
+#define D_CPLB 0x8
+
+#define IN_KERNEL 1
+
+enum
+{ZERO_P, L1I_MEM, L1D_MEM, SDRAM_KERN , SDRAM_RAM_MTD, SDRAM_DMAZ, RES_MEM, ASYNC_MEM, L2_MEM};
+
+struct cplb_desc {
+ u32 start; /* start address */
+ u32 end; /* end address */
+ u32 psize; /* prefered size if any otherwise 1MB or 4MB*/
+ u16 attr;/* attributes */
+ u16 i_conf;/* I-CPLB DATA */
+ u16 d_conf;/* D-CPLB DATA */
+ u16 valid;/* valid */
+ const s8 name[30];/* name */
+};
+
+struct cplb_tab {
+ u_long *tab;
+ u16 pos;
+ u16 size;
+};
+
+u_long icplb_table[MAX_CPLBS+1];
+u_long dcplb_table[MAX_CPLBS+1];
+
+/* Till here we are discussing about the static memory management model.
+ * However, the operating envoronments commonly define more CPLB
+ * descriptors to cover the entire addressable memory than will fit into
+ * the available on-chip 16 CPLB MMRs. When this happens, the below table
+ * will be used which will hold all the potentially required CPLB descriptors
+ *
+ * This is how Page descriptor Table is implemented in uClinux/Blackfin.
+ */
+
+#ifdef CONFIG_CPLB_SWITCH_TAB_L1
+u_long ipdt_table[MAX_SWITCH_I_CPLBS+1]__attribute__((l1_data));
+u_long dpdt_table[MAX_SWITCH_D_CPLBS+1]__attribute__((l1_data));
+
+#ifdef CONFIG_CPLB_INFO
+u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS]__attribute__((l1_data));
+u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS]__attribute__((l1_data));
+#endif /* CONFIG_CPLB_INFO */
+
+#else
+
+u_long ipdt_table[MAX_SWITCH_I_CPLBS+1];
+u_long dpdt_table[MAX_SWITCH_D_CPLBS+1];
+
+#ifdef CONFIG_CPLB_INFO
+u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS];
+u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS];
+#endif /* CONFIG_CPLB_INFO */
+
+#endif /*CONFIG_CPLB_SWITCH_TAB_L1*/
+
+struct s_cplb {
+ struct cplb_tab init_i;
+ struct cplb_tab init_d;
+ struct cplb_tab switch_i;
+ struct cplb_tab switch_d;
+};
+
+#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
+static struct cplb_desc cplb_data[] = {
+ {
+ .start = 0,
+ .end = SIZE_4K,
+ .psize = SIZE_4K,
+ .attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
+ .i_conf = SDRAM_OOPS,
+ .d_conf = SDRAM_OOPS,
+#if defined(CONFIG_DEBUG_HUNT_FOR_ZERO)
+ .valid = 1,
+#else
+ .valid = 0,
+#endif
+ .name = "ZERO Pointer Saveguard",
+ },
+ {
+ .start = L1_CODE_START,
+ .end = L1_CODE_START + L1_CODE_LENGTH,
+ .psize = SIZE_4M,
+ .attr = INITIAL_T | SWITCH_T | I_CPLB,
+ .i_conf = L1_IMEMORY,
+ .d_conf = 0,
+ .valid = 1,
+ .name = "L1 I-Memory",
+ },
+ {
+ .start = L1_DATA_A_START,
+ .end = L1_DATA_B_START + L1_DATA_B_LENGTH,
+ .psize = SIZE_4M,
+ .attr = INITIAL_T | SWITCH_T | D_CPLB,
+ .i_conf = 0,
+ .d_conf = L1_DMEMORY,
+#if ((L1_DATA_A_LENGTH > 0) || (L1_DATA_B_LENGTH > 0))
+ .valid = 1,
+#else
+ .valid = 0,
+#endif
+ .name = "L1 D-Memory",
+ },
+ {
+ .start = 0,
+ .end = 0, /* dynamic */
+ .psize = 0,
+ .attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
+ .i_conf = SDRAM_IGENERIC,
+ .d_conf = SDRAM_DGENERIC,
+ .valid = 1,
+ .name = "SDRAM Kernel",
+ },
+ {
+ .start = 0, /* dynamic */
+ .end = 0, /* dynamic */
+ .psize = 0,
+ .attr = INITIAL_T | SWITCH_T | D_CPLB,
+ .i_conf = SDRAM_IGENERIC,
+ .d_conf = SDRAM_DNON_CHBL,
+ .valid = 1,
+ .name = "SDRAM RAM MTD",
+ },
+ {
+ .start = 0, /* dynamic */
+ .end = 0, /* dynamic */
+ .psize = SIZE_1M,
+ .attr = INITIAL_T | SWITCH_T | D_CPLB,
+ .d_conf = SDRAM_DNON_CHBL,
+ .valid = 1,//(DMA_UNCACHED_REGION > 0),
+ .name = "SDRAM Uncached DMA ZONE",
+ },
+ {
+ .start = 0, /* dynamic */
+ .end = 0, /* dynamic */
+ .psize = 0,
+ .attr = SWITCH_T | D_CPLB,
+ .i_conf = 0, /* dynamic */
+ .d_conf = 0, /* dynamic */
+ .valid = 1,
+ .name = "SDRAM Reserved Memory",
+ },
+ {
+ .start = ASYNC_BANK0_BASE,
+ .end = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE,
+ .psize = 0,
+ .attr = SWITCH_T | D_CPLB,
+ .d_conf = SDRAM_EBIU,
+ .valid = 1,
+ .name = "ASYNC Memory",
+ },
+ {
+#if defined(CONFIG_BF561)
+ .start = L2_SRAM,
+ .end = L2_SRAM_END,
+ .psize = SIZE_1M,
+ .attr = SWITCH_T | D_CPLB,
+ .i_conf = L2_MEMORY,
+ .d_conf = L2_MEMORY,
+ .valid = 1,
+#else
+ .valid = 0,
+#endif
+ .name = "L2 Memory",
+ }
+};
+#endif
diff --git a/include/asm-blackfin/cpumask.h b/include/asm-blackfin/cpumask.h
new file mode 100644
index 0000000..b20a8e9
--- /dev/null
+++ b/include/asm-blackfin/cpumask.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_BLACKFIN_CPUMASK_H
+#define _ASM_BLACKFIN_CPUMASK_H
+
+#include <asm-generic/cpumask.h>
+
+#endif /* _ASM_BLACKFIN_CPUMASK_H */
diff --git a/include/asm-blackfin/cputime.h b/include/asm-blackfin/cputime.h
new file mode 100644
index 0000000..2b19705
--- /dev/null
+++ b/include/asm-blackfin/cputime.h
@@ -0,0 +1,6 @@
+#ifndef __BLACKFIN_CPUTIME_H
+#define __BLACKFIN_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __BLACKFIN_CPUTIME_H */
diff --git a/include/asm-blackfin/current.h b/include/asm-blackfin/current.h
new file mode 100644
index 0000000..31918d2
--- /dev/null
+++ b/include/asm-blackfin/current.h
@@ -0,0 +1,23 @@
+#ifndef _BLACKFIN_CURRENT_H
+#define _BLACKFIN_CURRENT_H
+/*
+ * current.h
+ * (C) Copyright 2000, Lineo, David McCullough <davidm@lineo.com>
+ *
+ * rather than dedicate a register (as the m68k source does), we
+ * just keep a global, we should probably just change it all to be
+ * current and lose _current_task.
+ */
+#include <linux/thread_info.h>
+
+struct task_struct;
+
+static inline struct task_struct *get_current(void) __attribute__ ((__const__));
+static inline struct task_struct *get_current(void)
+{
+ return (current_thread_info()->task);
+}
+
+#define current (get_current())
+
+#endif /* _BLACKFIN_CURRENT_H */
diff --git a/include/asm-blackfin/delay.h b/include/asm-blackfin/delay.h
new file mode 100644
index 0000000..52e7a10
--- /dev/null
+++ b/include/asm-blackfin/delay.h
@@ -0,0 +1,44 @@
+#ifndef _BLACKFIN_DELAY_H
+#define _BLACKFIN_DELAY_H
+
+static inline void __delay(unsigned long loops)
+{
+
+/* FIXME: Currently the assembler doesn't recognize Loop Register Clobbers,
+ uncomment this as soon those are implemented */
+/*
+ __asm__ __volatile__ ( "\t LSETUP (1f,1f) LC0= %0\n\t"
+ "1:\t NOP;\n\t"
+ : :"a" (loops)
+ : "LT0","LB0","LC0");
+
+*/
+
+ __asm__ __volatile__("[--SP] = LC0;\n\t"
+ "[--SP] = LT0;\n\t"
+ "[--SP] = LB0;\n\t"
+ "LSETUP (1f,1f) LC0 = %0;\n\t"
+ "1:\t NOP;\n\t"
+ "LB0 = [SP++];\n\t"
+ "LT0 = [SP++];\n\t"
+ "LC0 = [SP++];\n"
+ :
+ :"a" (loops));
+}
+
+#include <linux/param.h> /* needed for HZ */
+
+/*
+ * Use only for very small delays ( < 1 msec). Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays. This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)
+ */
+static inline void udelay(unsigned long usecs)
+{
+ extern unsigned long loops_per_jiffy;
+ __delay(usecs * loops_per_jiffy / (1000000 / HZ));
+}
+
+#endif /* defined(_BLACKFIN_DELAY_H) */
diff --git a/include/asm-blackfin/device.h b/include/asm-blackfin/device.h
new file mode 100644
index 0000000..d8f9872
--- /dev/null
+++ b/include/asm-blackfin/device.h
@@ -0,0 +1,7 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ */
+#include <asm-generic/device.h>
+
diff --git a/include/asm-blackfin/div64.h b/include/asm-blackfin/div64.h
new file mode 100644
index 0000000..6cd978c
--- /dev/null
+++ b/include/asm-blackfin/div64.h
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff --git a/include/asm-blackfin/dma-mapping.h b/include/asm-blackfin/dma-mapping.h
new file mode 100644
index 0000000..7a77d7f
--- /dev/null
+++ b/include/asm-blackfin/dma-mapping.h
@@ -0,0 +1,66 @@
+#ifndef _BLACKFIN_DMA_MAPPING_H
+#define _BLACKFIN_DMA_MAPPING_H
+
+#include <asm/scatterlist.h>
+
+void dma_alloc_init(unsigned long start, unsigned long end);
+void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp);
+void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle);
+
+/*
+ * Now for the API extensions over the pci_ one
+ */
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+
+/*
+ * Map a single buffer of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Once the device is given the dma address, the device owns this memory
+ * until either pci_unmap_single or pci_dma_sync_single is performed.
+ */
+extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction);
+
+/*
+ * Unmap a single streaming mode DMA translation. The dma_addr and size
+ * must match what was provided for in a previous pci_map_single call. All
+ * other usages are undefined.
+ *
+ * After this call, reads by the cpu to the buffer are guarenteed to see
+ * whatever the device wrote there.
+ */
+extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction direction);
+
+/*
+ * Map a set of buffers described by scatterlist in streaming
+ * mode for DMA. This is the scather-gather version of the
+ * above pci_map_single interface. Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length. They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ * DMA address/length pairs than there are SG table elements.
+ * (for example via virtual mapping capabilities)
+ * The routine returns the number of addr/length pairs actually
+ * used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction);
+
+/*
+ * Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nhwentries, enum dma_data_direction direction);
+
+#endif /* _BLACKFIN_DMA_MAPPING_H */
diff --git a/include/asm-blackfin/dma.h b/include/asm-blackfin/dma.h
new file mode 100644
index 0000000..be0d913
--- /dev/null
+++ b/include/asm-blackfin/dma.h
@@ -0,0 +1,188 @@
+/*
+ * File: include/asm-blackfin/simple_bf533_dma.h
+ * Based on: none - original work
+ * Author: LG Soft India
+ * Copyright (C) 2004-2005 Analog Devices Inc.
+ * Created: Tue Sep 21 2004
+ * Description: This file contains the major Data structures and constants
+ * used for DMA Implementation in BF533
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _BLACKFIN_DMA_H_
+#define _BLACKFIN_DMA_H_
+
+#include <asm/io.h>
+#include <linux/slab.h>
+#include <asm/irq.h>
+#include <asm/signal.h>
+#include <asm/semaphore.h>
+
+#include <linux/kernel.h>
+#include <asm/mach/dma.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <asm/blackfin.h>
+
+#define MAX_DMA_ADDRESS PAGE_OFFSET
+
+/*****************************************************************************
+* Generic DMA Declarations
+*
+****************************************************************************/
+enum dma_chan_status {
+ DMA_CHANNEL_FREE,
+ DMA_CHANNEL_REQUESTED,
+ DMA_CHANNEL_ENABLED,
+};
+
+/*-------------------------
+ * config reg bits value
+ *-------------------------*/
+#define DATA_SIZE_8 0
+#define DATA_SIZE_16 1
+#define DATA_SIZE_32 2
+
+#define DMA_FLOW_STOP 0
+#define DMA_FLOW_AUTO 1
+#define DMA_FLOW_ARRAY 4
+#define DMA_FLOW_SMALL 6
+#define DMA_FLOW_LARGE 7
+
+#define DIMENSION_LINEAR 0
+#define DIMENSION_2D 1
+
+#define DIR_READ 0
+#define DIR_WRITE 1
+
+#define INTR_DISABLE 0
+#define INTR_ON_BUF 2
+#define INTR_ON_ROW 3
+
+struct dmasg {
+ unsigned long next_desc_addr;
+ unsigned long start_addr;
+ unsigned short cfg;
+ unsigned short x_count;
+ short x_modify;
+ unsigned short y_count;
+ short y_modify;
+} __attribute__((packed));
+
+struct dma_register {
+ unsigned long next_desc_ptr; /* DMA Next Descriptor Pointer register */
+ unsigned long start_addr; /* DMA Start address register */
+
+ unsigned short cfg; /* DMA Configuration register */
+ unsigned short dummy1; /* DMA Configuration register */
+
+ unsigned long reserved;
+
+ unsigned short x_count; /* DMA x_count register */
+ unsigned short dummy2;
+
+ short x_modify; /* DMA x_modify register */
+ unsigned short dummy3;
+
+ unsigned short y_count; /* DMA y_count register */
+ unsigned short dummy4;
+
+ short y_modify; /* DMA y_modify register */
+ unsigned short dummy5;
+
+ unsigned long curr_desc_ptr; /* DMA Current Descriptor Pointer
+ register */
+ unsigned short curr_addr_ptr_lo; /* DMA Current Address Pointer
+ register */
+ unsigned short curr_addr_ptr_hi; /* DMA Current Address Pointer
+ register */
+ unsigned short irq_status; /* DMA irq status register */
+ unsigned short dummy6;
+
+ unsigned short peripheral_map; /* DMA peripheral map register */
+ unsigned short dummy7;
+
+ unsigned short curr_x_count; /* DMA Current x-count register */
+ unsigned short dummy8;
+
+ unsigned long reserved2;
+
+ unsigned short curr_y_count; /* DMA Current y-count register */
+ unsigned short dummy9;
+
+ unsigned long reserved3;
+
+};
+
+typedef irqreturn_t(*dma_interrupt_t) (int irq, void *dev_id);
+
+struct dma_channel {
+ struct mutex dmalock;
+ char *device_id;
+ enum dma_chan_status chan_status;
+ struct dma_register *regs;
+ struct dmasg *sg; /* large mode descriptor */
+ unsigned int ctrl_num; /* controller number */
+ dma_interrupt_t irq_callback;
+ void *data;
+ unsigned int dma_enable_flag;
+ unsigned int loopback_flag;
+};
+
+/*******************************************************************************
+* DMA API's
+*******************************************************************************/
+/* functions to set register mode */
+void set_dma_start_addr(unsigned int channel, unsigned long addr);
+void set_dma_next_desc_addr(unsigned int channel, unsigned long addr);
+void set_dma_x_count(unsigned int channel, unsigned short x_count);
+void set_dma_x_modify(unsigned int channel, short x_modify);
+void set_dma_y_count(unsigned int channel, unsigned short y_count);
+void set_dma_y_modify(unsigned int channel, short y_modify);
+void set_dma_config(unsigned int channel, unsigned short config);
+unsigned short set_bfin_dma_config(char direction, char flow_mode,
+ char intr_mode, char dma_mode, char width);
+
+/* get curr status for polling */
+unsigned short get_dma_curr_irqstat(unsigned int channel);
+unsigned short get_dma_curr_xcount(unsigned int channel);
+unsigned short get_dma_curr_ycount(unsigned int channel);
+
+/* set large DMA mode descriptor */
+void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg);
+
+/* check if current channel is in use */
+int dma_channel_active(unsigned int channel);
+
+/* common functions must be called in any mode */
+void free_dma(unsigned int channel);
+int dma_channel_active(unsigned int channel); /* check if a channel is in use */
+void disable_dma(unsigned int channel);
+void enable_dma(unsigned int channel);
+int request_dma(unsigned int channel, char *device_id);
+int set_dma_callback(unsigned int channel, dma_interrupt_t callback,
+ void *data);
+void dma_disable_irq(unsigned int channel);
+void dma_enable_irq(unsigned int channel);
+void clear_dma_irqstat(unsigned int channel);
+void *dma_memcpy(void *dest, const void *src, size_t count);
+void *safe_dma_memcpy(void *dest, const void *src, size_t count);
+
+#endif
diff --git a/include/asm-blackfin/dpmc.h b/include/asm-blackfin/dpmc.h
new file mode 100644
index 0000000..f162edb
--- /dev/null
+++ b/include/asm-blackfin/dpmc.h
@@ -0,0 +1,70 @@
+/*
+ * include/asm-blackfin/dpmc.h - Miscellaneous IOCTL commands for Dynamic Power
+ * Management Controller Driver.
+ * Copyright (C) 2004 Analog Device Inc.
+ *
+ */
+#ifndef _BLACKFIN_DPMC_H_
+#define _BLACKFIN_DPMC_H_
+
+#define SLEEP_MODE 1
+#define DEEP_SLEEP_MODE 2
+#define ACTIVE_PLL_DISABLED 3
+#define FULLON_MODE 4
+#define ACTIVE_PLL_ENABLED 5
+#define HIBERNATE_MODE 6
+
+#define IOCTL_FULL_ON_MODE _IO('s', 0xA0)
+#define IOCTL_ACTIVE_MODE _IO('s', 0xA1)
+#define IOCTL_SLEEP_MODE _IO('s', 0xA2)
+#define IOCTL_DEEP_SLEEP_MODE _IO('s', 0xA3)
+#define IOCTL_HIBERNATE_MODE _IO('s', 0xA4)
+#define IOCTL_CHANGE_FREQUENCY _IOW('s', 0xA5, unsigned long)
+#define IOCTL_CHANGE_VOLTAGE _IOW('s', 0xA6, unsigned long)
+#define IOCTL_SET_CCLK _IOW('s', 0xA7, unsigned long)
+#define IOCTL_SET_SCLK _IOW('s', 0xA8, unsigned long)
+#define IOCTL_GET_PLLSTATUS _IOW('s', 0xA9, unsigned long)
+#define IOCTL_GET_CORECLOCK _IOW('s', 0xAA, unsigned long)
+#define IOCTL_GET_SYSTEMCLOCK _IOW('s', 0xAB, unsigned long)
+#define IOCTL_GET_VCO _IOW('s', 0xAC, unsigned long)
+#define IOCTL_DISABLE_WDOG_TIMER _IO('s', 0xAD)
+#define IOCTL_UNMASK_WDOG_WAKEUP_EVENT _IO('s',0xAE)
+#define IOCTL_PROGRAM_WDOG_TIMER _IOW('s',0xAF,unsigned long)
+#define IOCTL_CLEAR_WDOG_WAKEUP_EVENT _IO('s',0xB0)
+#define IOCTL_SLEEP_DEEPER_MODE _IO('s',0xB1)
+
+#define DPMC_MINOR 254
+
+#define ON 0
+#define OFF 1
+
+#ifdef __KERNEL__
+
+unsigned long calc_volt(void);
+int calc_vlev(int vlt);
+unsigned long change_voltage(unsigned long volt);
+int calc_msel(int vco_hz);
+unsigned long change_frequency(unsigned long vco_mhz);
+int set_pll_div(unsigned short sel, unsigned char flag);
+int get_vco(void);
+unsigned long change_system_clock(unsigned long clock);
+unsigned long change_core_clock(unsigned long clock);
+unsigned long get_pll_status(void);
+void change_baud(int baud);
+void fullon_mode(void);
+void active_mode(void);
+void sleep_mode(u32 sic_iwr);
+void deep_sleep(u32 sic_iwr);
+void hibernate_mode(u32 sic_iwr);
+void sleep_deeper(u32 sic_iwr);
+void program_wdog_timer(unsigned long);
+void unmask_wdog_wakeup_evt(void);
+void clear_wdog_wakeup_evt(void);
+void disable_wdog_timer(void);
+
+extern unsigned long get_cclk(void);
+extern unsigned long get_sclk(void);
+
+#endif /* __KERNEL__ */
+
+#endif /*_BLACKFIN_DPMC_H_*/
diff --git a/include/asm-blackfin/elf.h b/include/asm-blackfin/elf.h
new file mode 100644
index 0000000..5264b55
--- /dev/null
+++ b/include/asm-blackfin/elf.h
@@ -0,0 +1,127 @@
+/* Changes made by LG Soft Oct 2004*/
+
+#ifndef __ASMBFIN_ELF_H
+#define __ASMBFIN_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+/* Processor specific flags for the ELF header e_flags field. */
+#define EF_BFIN_PIC 0x00000001 /* -fpic */
+#define EF_BFIN_FDPIC 0x00000002 /* -mfdpic */
+#define EF_BFIN_CODE_IN_L1 0x00000010 /* --code-in-l1 */
+#define EF_BFIN_DATA_IN_L1 0x00000020 /* --data-in-l1 */
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_bfinfp_struct elf_fpregset_t;
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_BLACKFIN)
+
+#define elf_check_fdpic(x) ((x)->e_flags & EF_BFIN_FDPIC /* && !((x)->e_flags & EF_FRV_NON_PIC_RELOCS) */)
+#define elf_check_const_displacement(x) ((x)->e_flags & EF_BFIN_PIC)
+
+/* EM_BLACKFIN defined in linux/elf.h */
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2LSB
+#define ELF_ARCH EM_BLACKFIN
+
+#define ELF_PLAT_INIT(_r) _r->p1 = 0
+
+#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map_addr, _interp_map_addr, _dynamic_addr) \
+do { \
+ _regs->r7 = 0; \
+ _regs->p0 = _exec_map_addr; \
+ _regs->p1 = _interp_map_addr; \
+ _regs->p2 = _dynamic_addr; \
+} while(0)
+
+#define USE_ELF_CORE_DUMP
+#define ELF_FDPIC_CORE_EFLAGS EF_BFIN_FDPIC
+#define ELF_EXEC_PAGESIZE 4096
+
+#define R_unused0 0 /* relocation type 0 is not defined */
+#define R_pcrel5m2 1 /*LSETUP part a */
+#define R_unused1 2 /* relocation type 2 is not defined */
+#define R_pcrel10 3 /* type 3, if cc jump <target> */
+#define R_pcrel12_jump 4 /* type 4, jump <target> */
+#define R_rimm16 5 /* type 0x5, rN = <target> */
+#define R_luimm16 6 /* # 0x6, preg.l=<target> Load imm 16 to lower half */
+#define R_huimm16 7 /* # 0x7, preg.h=<target> Load imm 16 to upper half */
+#define R_pcrel12_jump_s 8 /* # 0x8 jump.s <target> */
+#define R_pcrel24_jump_x 9 /* # 0x9 jump.x <target> */
+#define R_pcrel24 10 /* # 0xa call <target> , not expandable */
+#define R_unusedb 11 /* # 0xb not generated */
+#define R_unusedc 12 /* # 0xc not used */
+#define R_pcrel24_jump_l 13 /*0xd jump.l <target> */
+#define R_pcrel24_call_x 14 /* 0xE, call.x <target> if <target> is above 24 bit limit call through P1 */
+#define R_var_eq_symb 15 /* 0xf, linker should treat it same as 0x12 */
+#define R_byte_data 16 /* 0x10, .byte var = symbol */
+#define R_byte2_data 17 /* 0x11, .byte2 var = symbol */
+#define R_byte4_data 18 /* 0x12, .byte4 var = symbol and .var var=symbol */
+#define R_pcrel11 19 /* 0x13, lsetup part b */
+#define R_unused14 20 /* 0x14, undefined */
+#define R_unused15 21 /* not generated by VDSP 3.5 */
+
+/* arithmetic relocations */
+#define R_push 0xE0
+#define R_const 0xE1
+#define R_add 0xE2
+#define R_sub 0xE3
+#define R_mult 0xE4
+#define R_div 0xE5
+#define R_mod 0xE6
+#define R_lshift 0xE7
+#define R_rshift 0xE8
+#define R_and 0xE9
+#define R_or 0xEA
+#define R_xor 0xEB
+#define R_land 0xEC
+#define R_lor 0xED
+#define R_len 0xEE
+#define R_neg 0xEF
+#define R_comp 0xF0
+#define R_page 0xF1
+#define R_hwpage 0xF2
+#define R_addr 0xF3
+
+/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
+ use of this is to invoke "./ld.so someprog" to test out a new version of
+ the loader. We need to make sure that it is out of the way of the program
+ that it will "exec", and that there is sufficient room for the brk. */
+
+#define ELF_ET_DYN_BASE 0xD0000000UL
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs) \
+ memcpy((char *) &pr_reg, (char *)regs, \
+ sizeof(struct pt_regs));
+
+/* This yields a mask that user programs can use to figure out what
+ instruction set this cpu supports. */
+
+#define ELF_HWCAP (0)
+
+/* This yields a string that ld.so will use to load implementation
+ specific libraries for optimization. This is more specific in
+ intent than poking at uname or /proc/cpuinfo. */
+
+#define ELF_PLATFORM (NULL)
+
+#ifdef __KERNEL__
+#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#endif
+
+#endif
diff --git a/include/asm-blackfin/emergency-restart.h b/include/asm-blackfin/emergency-restart.h
new file mode 100644
index 0000000..27f6c78
--- /dev/null
+++ b/include/asm-blackfin/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-blackfin/entry.h b/include/asm-blackfin/entry.h
new file mode 100644
index 0000000..562c6d3
--- /dev/null
+++ b/include/asm-blackfin/entry.h
@@ -0,0 +1,56 @@
+#ifndef __BFIN_ENTRY_H
+#define __BFIN_ENTRY_H
+
+#include <asm/setup.h>
+#include <asm/page.h>
+
+#ifdef __ASSEMBLY__
+
+#define LFLUSH_I_AND_D 0x00000808
+#define LSIGTRAP 5
+
+/* process bits for task_struct.flags */
+#define PF_TRACESYS_OFF 3
+#define PF_TRACESYS_BIT 5
+#define PF_PTRACED_OFF 3
+#define PF_PTRACED_BIT 4
+#define PF_DTRACE_OFF 1
+#define PF_DTRACE_BIT 5
+
+/* This one is used for exceptions, emulation, and NMI. It doesn't push
+ RETI and doesn't do cli. */
+#define SAVE_ALL_SYS save_context_no_interrupts
+/* This is used for all normal interrupts. It saves a minimum of registers
+ to the stack, loads the IRQ number, and jumps to common code. */
+#define INTERRUPT_ENTRY(N) \
+ [--sp] = SYSCFG; \
+ \
+ [--sp] = P0; /*orig_p0*/ \
+ [--sp] = R0; /*orig_r0*/ \
+ [--sp] = (R7:0,P5:0); \
+ R0 = (N); \
+ jump __common_int_entry;
+
+/* For timer interrupts, we need to save IPEND, since the user_mode
+ macro accesses it to determine where to account time. */
+#define TIMER_INTERRUPT_ENTRY(N) \
+ [--sp] = SYSCFG; \
+ \
+ [--sp] = P0; /*orig_p0*/ \
+ [--sp] = R0; /*orig_r0*/ \
+ [--sp] = (R7:0,P5:0); \
+ p0.l = lo(IPEND); \
+ p0.h = hi(IPEND); \
+ r1 = [p0]; \
+ R0 = (N); \
+ jump __common_int_entry;
+
+/* This one pushes RETI without using CLI. Interrupts are enabled. */
+#define SAVE_CONTEXT_SYSCALL save_context_syscall
+#define SAVE_CONTEXT save_context_with_interrupts
+
+#define RESTORE_ALL_SYS restore_context_no_interrupts
+#define RESTORE_CONTEXT restore_context_with_interrupts
+
+#endif /* __ASSEMBLY__ */
+#endif /* __BFIN_ENTRY_H */
diff --git a/include/asm-blackfin/errno.h b/include/asm-blackfin/errno.h
new file mode 100644
index 0000000..164e4f3
--- /dev/null
+++ b/include/asm-blackfin/errno.h
@@ -0,0 +1,6 @@
+#ifndef _BFIN_ERRNO_H
+#define _BFIN_ERRNO_H
+
+#include<asm-generic/errno.h>
+
+#endif /* _BFIN_ERRNO_H */
diff --git a/include/asm-blackfin/fcntl.h b/include/asm-blackfin/fcntl.h
new file mode 100644
index 0000000..9c40371
--- /dev/null
+++ b/include/asm-blackfin/fcntl.h
@@ -0,0 +1,13 @@
+#ifndef _BFIN_FCNTL_H
+#define _BFIN_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+ located on an ext2 file system */
+#define O_DIRECTORY 040000 /* must be a directory */
+#define O_NOFOLLOW 0100000 /* don't follow links */
+#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */
+#define O_LARGEFILE 0400000
+
+#include <asm-generic/fcntl.h>
+
+#endif
diff --git a/include/asm-blackfin/flat.h b/include/asm-blackfin/flat.h
new file mode 100644
index 0000000..e70074e
--- /dev/null
+++ b/include/asm-blackfin/flat.h
@@ -0,0 +1,58 @@
+/*
+ * include/asm-blackfin/flat.h -- uClinux flat-format executables
+ *
+ * Copyright (C) 2003,
+ *
+ */
+
+#ifndef __BLACKFIN_FLAT_H__
+#define __BLACKFIN_FLAT_H__
+
+#include <asm/unaligned.h>
+
+#define flat_stack_align(sp) /* nothing needed */
+#define flat_argvp_envp_on_stack() 0
+#define flat_old_ram_flag(flags) (flags)
+
+extern unsigned long bfin_get_addr_from_rp (unsigned long *ptr,
+ unsigned long relval,
+ unsigned long flags,
+ unsigned long *persistent);
+
+extern void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr,
+ unsigned long relval);
+
+/* The amount by which a relocation can exceed the program image limits
+ without being regarded as an error. */
+
+#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
+
+#define flat_get_addr_from_rp(rp, relval, flags, persistent) \
+ bfin_get_addr_from_rp(rp, relval, flags, persistent)
+#define flat_put_addr_at_rp(rp, val, relval) \
+ bfin_put_addr_at_rp(rp, val, relval)
+
+/* Convert a relocation entry into an address. */
+static inline unsigned long
+flat_get_relocate_addr (unsigned long relval)
+{
+ return relval & 0x03ffffff; /* Mask out top 6 bits */
+}
+
+static inline int flat_set_persistent(unsigned long relval,
+ unsigned long *persistent)
+{
+ int type = (relval >> 26) & 7;
+ if (type == 3) {
+ *persistent = relval << 16;
+ return 1;
+ }
+ return 0;
+}
+
+static inline int flat_addr_absolute(unsigned long relval)
+{
+ return (relval & (1 << 29)) != 0;
+}
+
+#endif /* __BLACKFIN_FLAT_H__ */
diff --git a/include/asm-blackfin/futex.h b/include/asm-blackfin/futex.h
new file mode 100644
index 0000000..6a332a9
--- /dev/null
+++ b/include/asm-blackfin/futex.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_FUTEX_H
+#define _ASM_FUTEX_H
+
+#include <asm-generic/futex.h>
+
+#endif
diff --git a/include/asm-blackfin/gpio.h b/include/asm-blackfin/gpio.h
new file mode 100644
index 0000000..d16fe3c
--- /dev/null
+++ b/include/asm-blackfin/gpio.h
@@ -0,0 +1,367 @@
+/*
+ * File: arch/blackfin/kernel/bfin_gpio.h
+ * Based on:
+ * Author: Michael Hennerich (hennerich@blackfin.uclinux.org)
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+* Number BF537/6/4 BF561 BF533/2/1
+*
+* GPIO_0 PF0 PF0 PF0
+* GPIO_1 PF1 PF1 PF1
+* GPIO_2 PF2 PF2 PF2
+* GPIO_3 PF3 PF3 PF3
+* GPIO_4 PF4 PF4 PF4
+* GPIO_5 PF5 PF5 PF5
+* GPIO_6 PF6 PF6 PF6
+* GPIO_7 PF7 PF7 PF7
+* GPIO_8 PF8 PF8 PF8
+* GPIO_9 PF9 PF9 PF9
+* GPIO_10 PF10 PF10 PF10
+* GPIO_11 PF11 PF11 PF11
+* GPIO_12 PF12 PF12 PF12
+* GPIO_13 PF13 PF13 PF13
+* GPIO_14 PF14 PF14 PF14
+* GPIO_15 PF15 PF15 PF15
+* GPIO_16 PG0 PF16
+* GPIO_17 PG1 PF17
+* GPIO_18 PG2 PF18
+* GPIO_19 PG3 PF19
+* GPIO_20 PG4 PF20
+* GPIO_21 PG5 PF21
+* GPIO_22 PG6 PF22
+* GPIO_23 PG7 PF23
+* GPIO_24 PG8 PF24
+* GPIO_25 PG9 PF25
+* GPIO_26 PG10 PF26
+* GPIO_27 PG11 PF27
+* GPIO_28 PG12 PF28
+* GPIO_29 PG13 PF29
+* GPIO_30 PG14 PF30
+* GPIO_31 PG15 PF31
+* GPIO_32 PH0 PF32
+* GPIO_33 PH1 PF33
+* GPIO_34 PH2 PF34
+* GPIO_35 PH3 PF35
+* GPIO_36 PH4 PF36
+* GPIO_37 PH5 PF37
+* GPIO_38 PH6 PF38
+* GPIO_39 PH7 PF39
+* GPIO_40 PH8 PF40
+* GPIO_41 PH9 PF41
+* GPIO_42 PH10 PF42
+* GPIO_43 PH11 PF43
+* GPIO_44 PH12 PF44
+* GPIO_45 PH13 PF45
+* GPIO_46 PH14 PF46
+* GPIO_47 PH15 PF47
+*/
+
+#ifndef __ARCH_BLACKFIN_GPIO_H__
+#define __ARCH_BLACKFIN_GPIO_H__
+
+#define gpio_bank(x) ((x) >> 4)
+#define gpio_bit(x) (1<<((x) & 0xF))
+#define gpio_sub_n(x) ((x) & 0xF)
+
+#define GPIO_BANKSIZE 16
+
+#define GPIO_0 0
+#define GPIO_1 1
+#define GPIO_2 2
+#define GPIO_3 3
+#define GPIO_4 4
+#define GPIO_5 5
+#define GPIO_6 6
+#define GPIO_7 7
+#define GPIO_8 8
+#define GPIO_9 9
+#define GPIO_10 10
+#define GPIO_11 11
+#define GPIO_12 12
+#define GPIO_13 13
+#define GPIO_14 14
+#define GPIO_15 15
+#define GPIO_16 16
+#define GPIO_17 17
+#define GPIO_18 18
+#define GPIO_19 19
+#define GPIO_20 20
+#define GPIO_21 21
+#define GPIO_22 22
+#define GPIO_23 23
+#define GPIO_24 24
+#define GPIO_25 25
+#define GPIO_26 26
+#define GPIO_27 27
+#define GPIO_28 28
+#define GPIO_29 29
+#define GPIO_30 30
+#define GPIO_31 31
+#define GPIO_32 32
+#define GPIO_33 33
+#define GPIO_34 34
+#define GPIO_35 35
+#define GPIO_36 36
+#define GPIO_37 37
+#define GPIO_38 38
+#define GPIO_39 39
+#define GPIO_40 40
+#define GPIO_41 41
+#define GPIO_42 42
+#define GPIO_43 43
+#define GPIO_44 44
+#define GPIO_45 45
+#define GPIO_46 46
+#define GPIO_47 47
+
+
+#define PERIPHERAL_USAGE 1
+#define GPIO_USAGE 0
+
+#ifdef BF533_FAMILY
+#define MAX_BLACKFIN_GPIOS 16
+#endif
+
+#ifdef BF537_FAMILY
+#define MAX_BLACKFIN_GPIOS 48
+#define PORT_F 0
+#define PORT_G 1
+#define PORT_H 2
+#define PORT_J 3
+
+#define GPIO_PF0 0
+#define GPIO_PF1 1
+#define GPIO_PF2 2
+#define GPIO_PF3 3
+#define GPIO_PF4 4
+#define GPIO_PF5 5
+#define GPIO_PF6 6
+#define GPIO_PF7 7
+#define GPIO_PF8 8
+#define GPIO_PF9 9
+#define GPIO_PF10 10
+#define GPIO_PF11 11
+#define GPIO_PF12 12
+#define GPIO_PF13 13
+#define GPIO_PF14 14
+#define GPIO_PF15 15
+#define GPIO_PG0 16
+#define GPIO_PG1 17
+#define GPIO_PG2 18
+#define GPIO_PG3 19
+#define GPIO_PG4 20
+#define GPIO_PG5 21
+#define GPIO_PG6 22
+#define GPIO_PG7 23
+#define GPIO_PG8 24
+#define GPIO_PG9 25
+#define GPIO_PG10 26
+#define GPIO_PG11 27
+#define GPIO_PG12 28
+#define GPIO_PG13 29
+#define GPIO_PG14 30
+#define GPIO_PG15 31
+#define GPIO_PH0 32
+#define GPIO_PH1 33
+#define GPIO_PH2 34
+#define GPIO_PH3 35
+#define GPIO_PH4 36
+#define GPIO_PH5 37
+#define GPIO_PH6 38
+#define GPIO_PH7 39
+#define GPIO_PH8 40
+#define GPIO_PH9 41
+#define GPIO_PH10 42
+#define GPIO_PH11 43
+#define GPIO_PH12 44
+#define GPIO_PH13 45
+#define GPIO_PH14 46
+#define GPIO_PH15 47
+
+#endif
+
+#ifdef BF561_FAMILY
+#define MAX_BLACKFIN_GPIOS 48
+#define PORT_FIO0 0
+#define PORT_FIO1 1
+#define PORT_FIO2 2
+#endif
+
+#ifndef __ASSEMBLY__
+
+/***********************************************************
+*
+* FUNCTIONS: Blackfin General Purpose Ports Access Functions
+*
+* INPUTS/OUTPUTS:
+* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
+*
+*
+* DESCRIPTION: These functions abstract direct register access
+* to Blackfin processor General Purpose
+* Ports Regsiters
+*
+* CAUTION: These functions do not belong to the GPIO Driver API
+*************************************************************
+* MODIFICATION HISTORY :
+**************************************************************/
+
+void set_gpio_dir(unsigned short, unsigned short);
+void set_gpio_inen(unsigned short, unsigned short);
+void set_gpio_polar(unsigned short, unsigned short);
+void set_gpio_edge(unsigned short, unsigned short);
+void set_gpio_both(unsigned short, unsigned short);
+void set_gpio_data(unsigned short, unsigned short);
+void set_gpio_maska(unsigned short, unsigned short);
+void set_gpio_maskb(unsigned short, unsigned short);
+void set_gpio_toggle(unsigned short);
+void set_gpiop_dir(unsigned short, unsigned short);
+void set_gpiop_inen(unsigned short, unsigned short);
+void set_gpiop_polar(unsigned short, unsigned short);
+void set_gpiop_edge(unsigned short, unsigned short);
+void set_gpiop_both(unsigned short, unsigned short);
+void set_gpiop_data(unsigned short, unsigned short);
+void set_gpiop_maska(unsigned short, unsigned short);
+void set_gpiop_maskb(unsigned short, unsigned short);
+unsigned short get_gpio_dir(unsigned short);
+unsigned short get_gpio_inen(unsigned short);
+unsigned short get_gpio_polar(unsigned short);
+unsigned short get_gpio_edge(unsigned short);
+unsigned short get_gpio_both(unsigned short);
+unsigned short get_gpio_maska(unsigned short);
+unsigned short get_gpio_maskb(unsigned short);
+unsigned short get_gpio_data(unsigned short);
+unsigned short get_gpiop_dir(unsigned short);
+unsigned short get_gpiop_inen(unsigned short);
+unsigned short get_gpiop_polar(unsigned short);
+unsigned short get_gpiop_edge(unsigned short);
+unsigned short get_gpiop_both(unsigned short);
+unsigned short get_gpiop_maska(unsigned short);
+unsigned short get_gpiop_maskb(unsigned short);
+unsigned short get_gpiop_data(unsigned short);
+
+struct gpio_port_t {
+ unsigned short data;
+ unsigned short dummy1;
+ unsigned short data_clear;
+ unsigned short dummy2;
+ unsigned short data_set;
+ unsigned short dummy3;
+ unsigned short toggle;
+ unsigned short dummy4;
+ unsigned short maska;
+ unsigned short dummy5;
+ unsigned short maska_clear;
+ unsigned short dummy6;
+ unsigned short maska_set;
+ unsigned short dummy7;
+ unsigned short maska_toggle;
+ unsigned short dummy8;
+ unsigned short maskb;
+ unsigned short dummy9;
+ unsigned short maskb_clear;
+ unsigned short dummy10;
+ unsigned short maskb_set;
+ unsigned short dummy11;
+ unsigned short maskb_toggle;
+ unsigned short dummy12;
+ unsigned short dir;
+ unsigned short dummy13;
+ unsigned short polar;
+ unsigned short dummy14;
+ unsigned short edge;
+ unsigned short dummy15;
+ unsigned short both;
+ unsigned short dummy16;
+ unsigned short inen;
+};
+
+#ifdef CONFIG_PM
+#define PM_WAKE_RISING 0x1
+#define PM_WAKE_FALLING 0x2
+#define PM_WAKE_HIGH 0x4
+#define PM_WAKE_LOW 0x8
+#define PM_WAKE_BOTH_EDGES (PM_WAKE_RISING | PM_WAKE_FALLING)
+
+int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type);
+void gpio_pm_wakeup_free(unsigned short gpio);
+unsigned int gpio_pm_setup(void);
+void gpio_pm_restore(void);
+
+struct gpio_port_s {
+ unsigned short data;
+ unsigned short data_clear;
+ unsigned short data_set;
+ unsigned short toggle;
+ unsigned short maska;
+ unsigned short maska_clear;
+ unsigned short maska_set;
+ unsigned short maska_toggle;
+ unsigned short maskb;
+ unsigned short maskb_clear;
+ unsigned short maskb_set;
+ unsigned short maskb_toggle;
+ unsigned short dir;
+ unsigned short polar;
+ unsigned short edge;
+ unsigned short both;
+ unsigned short inen;
+
+ unsigned short fer;
+};
+#endif /*CONFIG_PM*/
+
+/***********************************************************
+*
+* FUNCTIONS: Blackfin GPIO Driver
+*
+* INPUTS/OUTPUTS:
+* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
+*
+*
+* DESCRIPTION: Blackfin GPIO Driver API
+*
+* CAUTION:
+*************************************************************
+* MODIFICATION HISTORY :
+**************************************************************/
+
+int gpio_request(unsigned short, const char *);
+void gpio_free(unsigned short);
+
+void gpio_set_value(unsigned short gpio, unsigned short arg);
+unsigned short gpio_get_value(unsigned short gpio);
+
+#define gpio_get_value(gpio) get_gpio_data(gpio)
+#define gpio_set_value(gpio, value) set_gpio_data(gpio, value)
+
+void gpio_direction_input(unsigned short gpio);
+void gpio_direction_output(unsigned short gpio);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ARCH_BLACKFIN_GPIO_H__ */
diff --git a/include/asm-blackfin/hardirq.h b/include/asm-blackfin/hardirq.h
new file mode 100644
index 0000000..0cab0d3
--- /dev/null
+++ b/include/asm-blackfin/hardirq.h
@@ -0,0 +1,41 @@
+#ifndef __BFIN_HARDIRQ_H
+#define __BFIN_HARDIRQ_H
+
+#include <linux/cache.h>
+#include <linux/threads.h>
+#include <asm/irq.h>
+
+typedef struct {
+ unsigned int __softirq_pending;
+ unsigned int __syscall_count;
+ struct task_struct *__ksoftirqd_task;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+/*
+ * We put the hardirq and softirq counter into the preemption
+ * counter. The bitmask has the following meaning:
+ *
+ * - bits 0-7 are the preemption count (max preemption depth: 256)
+ * - bits 8-15 are the softirq count (max # of softirqs: 256)
+ * - bits 16-23 are the hardirq count (max # of hardirqs: 256)
+ *
+ * - ( bit 26 is the PREEMPT_ACTIVE flag. )
+ *
+ * PREEMPT_MASK: 0x000000ff
+ * HARDIRQ_MASK: 0x0000ff00
+ * SOFTIRQ_MASK: 0x00ff0000
+ */
+
+#define HARDIRQ_BITS 8
+
+#ifdef NR_IRQS
+# if (1 << HARDIRQ_BITS) < NR_IRQS
+# error HARDIRQ_BITS is too low!
+# endif
+#endif
+
+#define __ARCH_IRQ_EXIT_IRQS_DISABLED 1
+
+#endif
diff --git a/include/asm-blackfin/hw_irq.h b/include/asm-blackfin/hw_irq.h
new file mode 100644
index 0000000..5b51eae
--- /dev/null
+++ b/include/asm-blackfin/hw_irq.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_BFIN_HW_IRQ_H
+#define __ASM_BFIN_HW_IRQ_H
+
+/* Dummy include. */
+
+#endif
diff --git a/include/asm-blackfin/ide.h b/include/asm-blackfin/ide.h
new file mode 100644
index 0000000..41b2db4
--- /dev/null
+++ b/include/asm-blackfin/ide.h
@@ -0,0 +1,32 @@
+/****************************************************************************/
+
+/*
+ * linux/include/asm-blackfin/ide.h
+ *
+ * Copyright (C) 1994-1996 Linus Torvalds & authors
+ * Copyright (C) 2001 Lineo Inc., davidm@snapgear.com
+ * Copyright (C) 2002 Greg Ungerer (gerg@snapgear.com)
+ * Copyright (C) 2002 Yoshinori Sato (ysato@users.sourceforge.jp)
+ * Copyright (C) 2005 Hennerich Michael (hennerich@blackfin.uclinux.org)
+ */
+
+/****************************************************************************/
+#ifndef _BLACKFIN_IDE_H
+#define _BLACKFIN_IDE_H
+/****************************************************************************/
+#ifdef __KERNEL__
+/****************************************************************************/
+
+#define MAX_HWIFS 1
+
+/* Legacy ... BLK_DEV_IDECS */
+#define IDE_ARCH_OBSOLETE_INIT
+#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
+
+
+#include <asm-generic/ide_iops.h>
+
+/****************************************************************************/
+#endif /* __KERNEL__ */
+#endif /* _BLACKFIN_IDE_H */
+/****************************************************************************/
diff --git a/include/asm-blackfin/io.h b/include/asm-blackfin/io.h
new file mode 100644
index 0000000..7e6995e8
--- /dev/null
+++ b/include/asm-blackfin/io.h
@@ -0,0 +1,207 @@
+#ifndef _BFIN_IO_H
+#define _BFIN_IO_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#endif
+#include <linux/compiler.h>
+
+/*
+ * These are for ISA/PCI shared memory _only_ and should never be used
+ * on any other type of memory, including Zorro memory. They are meant to
+ * access the bus in the bus byte order which is little-endian!.
+ *
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the bfin architecture, we just read/write the
+ * memory location directly.
+ */
+#ifndef __ASSEMBLY__
+
+static inline unsigned char readb(void __iomem *addr)
+{
+ unsigned int val;
+ int tmp;
+
+ __asm__ __volatile__ ("cli %1;\n\t"
+ "NOP; NOP; SSYNC;\n\t"
+ "%0 = b [%2] (z);\n\t"
+ "sti %1;\n\t"
+ : "=d"(val), "=d"(tmp): "a"(addr)
+ );
+
+ return (unsigned char) val;
+}
+
+static inline unsigned short readw(void __iomem *addr)
+{
+ unsigned int val;
+ int tmp;
+
+ __asm__ __volatile__ ("cli %1;\n\t"
+ "NOP; NOP; SSYNC;\n\t"
+ "%0 = w [%2] (z);\n\t"
+ "sti %1;\n\t"
+ : "=d"(val), "=d"(tmp): "a"(addr)
+ );
+
+ return (unsigned short) val;
+}
+
+static inline unsigned int readl(void __iomem *addr)
+{
+ unsigned int val;
+ int tmp;
+
+ __asm__ __volatile__ ("cli %1;\n\t"
+ "NOP; NOP; SSYNC;\n\t"
+ "%0 = [%2];\n\t"
+ "sti %1;\n\t"
+ : "=d"(val), "=d"(tmp): "a"(addr)
+ );
+ return val;
+}
+
+#endif /* __ASSEMBLY__ */
+
+#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
+
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
+#define memset_io(a,b,c) memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
+
+#define inb(addr) readb(addr)
+#define inw(addr) readw(addr)
+#define inl(addr) readl(addr)
+#define outb(x,addr) ((void) writeb(x,addr))
+#define outw(x,addr) ((void) writew(x,addr))
+#define outl(x,addr) ((void) writel(x,addr))
+
+#define inb_p(addr) inb(addr)
+#define inw_p(addr) inw(addr)
+#define inl_p(addr) inl(addr)
+#define outb_p(x,addr) outb(x,addr)
+#define outw_p(x,addr) outw(x,addr)
+#define outl_p(x,addr) outl(x,addr)
+
+#define ioread8_rep(a,d,c) insb(a,d,c)
+#define ioread16_rep(a,d,c) insw(a,d,c)
+#define ioread32_rep(a,d,c) insl(a,d,c)
+#define iowrite8_rep(a,s,c) outsb(a,s,c)
+#define iowrite16_rep(a,s,c) outsw(a,s,c)
+#define iowrite32_rep(a,s,c) outsl(a,s,c)
+
+#define ioread8(X) readb(X)
+#define ioread16(X) readw(X)
+#define ioread32(X) readl(X)
+#define iowrite8(val,X) writeb(val,X)
+#define iowrite16(val,X) writew(val,X)
+#define iowrite32(val,X) writel(val,X)
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* Values for nocacheflag and cmode */
+#define IOMAP_NOCACHE_SER 1
+
+#ifndef __ASSEMBLY__
+
+extern void outsb(void __iomem *port, const void *addr, unsigned long count);
+extern void outsw(void __iomem *port, const void *addr, unsigned long count);
+extern void outsl(void __iomem *port, const void *addr, unsigned long count);
+
+extern void insb(const void __iomem *port, void *addr, unsigned long count);
+extern void insw(const void __iomem *port, void *addr, unsigned long count);
+extern void insl(const void __iomem *port, void *addr, unsigned long count);
+
+/*
+ * Map some physical address range into the kernel address space.
+ */
+static inline void __iomem *__ioremap(unsigned long physaddr, unsigned long size,
+ int cacheflag)
+{
+ return (void __iomem *)physaddr;
+}
+
+/*
+ * Unmap a ioremap()ed region again
+ */
+static inline void iounmap(void *addr)
+{
+}
+
+/*
+ * __iounmap unmaps nearly everything, so be careful
+ * it doesn't free currently pointer/page tables anymore but it
+ * wans't used anyway and might be added later.
+ */
+static inline void __iounmap(void *addr, unsigned long size)
+{
+}
+
+/*
+ * Set new cache mode for some kernel address space.
+ * The caller must push data for that range itself, if such data may already
+ * be in the cache.
+ */
+static inline void kernel_set_cachemode(void *addr, unsigned long size,
+ int cmode)
+{
+}
+
+static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
+{
+ return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+static inline void __iomem *ioremap_nocache(unsigned long physaddr,
+ unsigned long size)
+{
+ return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+
+extern void blkfin_inv_cache_all(void);
+
+#endif
+
+#define ioport_map(port, nr) ((void __iomem*)(port))
+#define ioport_unmap(addr)
+
+#define dma_cache_inv(_start,_size) do { blkfin_inv_cache_all();} while (0)
+#define dma_cache_wback(_start,_size) do { } while (0)
+#define dma_cache_wback_inv(_start,_size) do { blkfin_inv_cache_all();} while (0)
+
+/* Pages to physical address... */
+#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT)
+#define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT)
+
+#define mm_ptov(vaddr) ((void *) (vaddr))
+#define mm_vtop(vaddr) ((unsigned long) (vaddr))
+#define phys_to_virt(vaddr) ((void *) (vaddr))
+#define virt_to_phys(vaddr) ((unsigned long) (vaddr))
+
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p) __va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p) p
+
+#endif /* __KERNEL__ */
+
+#endif /* _BFIN_IO_H */
diff --git a/include/asm-blackfin/ioctl.h b/include/asm-blackfin/ioctl.h
new file mode 100644
index 0000000..b279fe0
--- /dev/null
+++ b/include/asm-blackfin/ioctl.h
@@ -0,0 +1 @@
+#include <asm-generic/ioctl.h>
diff --git a/include/asm-blackfin/ioctls.h b/include/asm-blackfin/ioctls.h
new file mode 100644
index 0000000..8356204
--- /dev/null
+++ b/include/asm-blackfin/ioctls.h
@@ -0,0 +1,82 @@
+#ifndef __ARCH_BFIN_IOCTLS_H__
+#define __ARCH_BFIN_IOCTLS_H__
+
+#include <asm/ioctl.h>
+
+/* 0x54 is just a magic number to make these relatively unique ('T') */
+
+#define TCGETS 0x5401
+#define TCSETS 0x5402
+#define TCSETSW 0x5403
+#define TCSETSF 0x5404
+#define TCGETA 0x5405
+#define TCSETA 0x5406
+#define TCSETAW 0x5407
+#define TCSETAF 0x5408
+#define TCSBRK 0x5409
+#define TCXONC 0x540A
+#define TCFLSH 0x540B
+#define TIOCEXCL 0x540C
+#define TIOCNXCL 0x540D
+#define TIOCSCTTY 0x540E
+#define TIOCGPGRP 0x540F
+#define TIOCSPGRP 0x5410
+#define TIOCOUTQ 0x5411
+#define TIOCSTI 0x5412
+#define TIOCGWINSZ 0x5413
+#define TIOCSWINSZ 0x5414
+#define TIOCMGET 0x5415
+#define TIOCMBIS 0x5416
+#define TIOCMBIC 0x5417
+#define TIOCMSET 0x5418
+#define TIOCGSOFTCAR 0x5419
+#define TIOCSSOFTCAR 0x541A
+#define FIONREAD 0x541B
+#define TIOCINQ FIONREAD
+#define TIOCLINUX 0x541C
+#define TIOCCONS 0x541D
+#define TIOCGSERIAL 0x541E
+#define TIOCSSERIAL 0x541F
+#define TIOCPKT 0x5420
+#define FIONBIO 0x5421
+#define TIOCNOTTY 0x5422
+#define TIOCSETD 0x5423
+#define TIOCGETD 0x5424
+#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
+#define TIOCSBRK 0x5427 /* BSD compatibility */
+#define TIOCCBRK 0x5428 /* BSD compatibility */
+#define TIOCGSID 0x5429 /* Return the session ID of FD */
+#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
+
+#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
+#define FIOCLEX 0x5451
+#define FIOASYNC 0x5452
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
+#define TIOCSERGETLSR 0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
+
+#define FIOQSIZE 0x545E
+
+/* Used for packet mode */
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+
+#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+
+#endif /* __ARCH_BFIN_IOCTLS_H__ */
diff --git a/include/asm-blackfin/ipc.h b/include/asm-blackfin/ipc.h
new file mode 100644
index 0000000..a46e3d9
--- /dev/null
+++ b/include/asm-blackfin/ipc.h
@@ -0,0 +1 @@
+#include <asm-generic/ipc.h>
diff --git a/include/asm-blackfin/ipcbuf.h b/include/asm-blackfin/ipcbuf.h
new file mode 100644
index 0000000..8f0899c
--- /dev/null
+++ b/include/asm-blackfin/ipcbuf.h
@@ -0,0 +1,30 @@
+/* Changes origined from m68k version. Lineo Inc. May 2001 */
+
+#ifndef __BFIN_IPCBUF_H__
+#define __BFIN_IPCBUF_H__
+
+/*
+ * The user_ipc_perm structure for m68k architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm {
+ __kernel_key_t key;
+ __kernel_uid32_t uid;
+ __kernel_gid32_t gid;
+ __kernel_uid32_t cuid;
+ __kernel_gid32_t cgid;
+ __kernel_mode_t mode;
+ unsigned short __pad1;
+ unsigned short seq;
+ unsigned short __pad2;
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+#endif /* __BFIN_IPCBUF_H__ */
diff --git a/include/asm-blackfin/irq.h b/include/asm-blackfin/irq.h
new file mode 100644
index 0000000..65480da
--- /dev/null
+++ b/include/asm-blackfin/irq.h
@@ -0,0 +1,70 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Changed by HuTao Apr18, 2003
+ *
+ * Copyright was missing when I got the code so took from MIPS arch ...MaTed---
+ * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle
+ * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 by Ralf Baechle
+ *
+ * Adapted for BlackFin (ADI) by Ted Ma <mated@sympatico.ca>
+ * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com)
+ * Copyright (c) 2002 Lineo, Inc. <mattw@lineo.com>
+ */
+
+#ifndef _BFIN_IRQ_H_
+#define _BFIN_IRQ_H_
+
+#include <asm/mach/irq.h>
+#include <asm/ptrace.h>
+
+/*******************************************************************************
+ ***** INTRODUCTION ***********
+ * On the Blackfin, the interrupt structure allows remmapping of the hardware
+ * levels.
+ * - I'm going to assume that the H/W level is going to stay at the default
+ * settings. If someone wants to go through and abstart this out, feel free
+ * to mod the interrupt numbering scheme.
+ * - I'm abstracting the interrupts so that uClinux does not know anything
+ * about the H/W levels. If you want to change the H/W AND keep the abstracted
+ * levels that uClinux sees, you should be able to do most of it here.
+ * - I've left the "abstract" numbering sparce in case someone wants to pull the
+ * interrupts apart (just the TX/RX for the various devices)
+ *******************************************************************************/
+
+/* SYS_IRQS and NR_IRQS are defined in <asm/mach-bf5xx/irq.h>*/
+
+/*
+ * Machine specific interrupt sources.
+ *
+ * Adding an interrupt service routine for a source with this bit
+ * set indicates a special machine specific interrupt source.
+ * The machine specific files define these sources.
+ *
+ * The IRQ_MACHSPEC bit is now gone - the only thing it did was to
+ * introduce unnecessary overhead.
+ *
+ * All interrupt handling is actually machine specific so it is better
+ * to use function pointers, as used by the Sparc port, and select the
+ * interrupt handling functions when initializing the kernel. This way
+ * we save some unnecessary overhead at run-time.
+ * 01/11/97 - Jes
+ */
+
+extern void ack_bad_irq(unsigned int irq);
+
+static __inline__ int irq_canonicalize(int irq)
+{
+ return irq;
+}
+
+/* count of spurious interrupts */
+/* extern volatile unsigned int num_spurious; */
+
+#ifndef NO_IRQ
+#define NO_IRQ ((unsigned int)(-1))
+#endif
+
+#endif /* _BFIN_IRQ_H_ */
diff --git a/include/asm-blackfin/irq_handler.h b/include/asm-blackfin/irq_handler.h
new file mode 100644
index 0000000..d830f0a
--- /dev/null
+++ b/include/asm-blackfin/irq_handler.h
@@ -0,0 +1,22 @@
+#ifndef _IRQ_HANDLER_H
+#define _IRQ_HANDLER_H
+
+/* BASE LEVEL interrupt handler routines */
+asmlinkage void evt_emulation(void);
+asmlinkage void evt_exception(void);
+asmlinkage void trap(void);
+asmlinkage void evt_ivhw(void);
+asmlinkage void evt_timer(void);
+asmlinkage void evt_evt2(void);
+asmlinkage void evt_evt7(void);
+asmlinkage void evt_evt8(void);
+asmlinkage void evt_evt9(void);
+asmlinkage void evt_evt10(void);
+asmlinkage void evt_evt11(void);
+asmlinkage void evt_evt12(void);
+asmlinkage void evt_evt13(void);
+asmlinkage void evt_soft_int1(void);
+asmlinkage void evt_system_call(void);
+asmlinkage void init_exception_buff(void);
+
+#endif
diff --git a/include/asm-blackfin/irq_regs.h b/include/asm-blackfin/irq_regs.h
new file mode 100644
index 0000000..3dd9c0b
--- /dev/null
+++ b/include/asm-blackfin/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/include/asm-blackfin/kdebug.h b/include/asm-blackfin/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-blackfin/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-blackfin/kmap_types.h b/include/asm-blackfin/kmap_types.h
new file mode 100644
index 0000000..e215f71
--- /dev/null
+++ b/include/asm-blackfin/kmap_types.h
@@ -0,0 +1,21 @@
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+enum km_type {
+ KM_BOUNCE_READ,
+ KM_SKB_SUNRPC_DATA,
+ KM_SKB_DATA_SOFTIRQ,
+ KM_USER0,
+ KM_USER1,
+ KM_BIO_SRC_IRQ,
+ KM_BIO_DST_IRQ,
+ KM_PTE0,
+ KM_PTE1,
+ KM_IRQ0,
+ KM_IRQ1,
+ KM_SOFTIRQ0,
+ KM_SOFTIRQ1,
+ KM_TYPE_NR
+};
+
+#endif
diff --git a/include/asm-blackfin/l1layout.h b/include/asm-blackfin/l1layout.h
new file mode 100644
index 0000000..c13ded7
--- /dev/null
+++ b/include/asm-blackfin/l1layout.h
@@ -0,0 +1,31 @@
+/*
+ * l1layout.h
+ * Defines a layout of L1 scratchpad memory that userspace can rely on.
+ */
+
+#ifndef _L1LAYOUT_H_
+#define _L1LAYOUT_H_
+
+#include <asm/blackfin.h>
+
+#ifndef __ASSEMBLY__
+
+/* Data that is "mapped" into the process VM at the start of the L1 scratch
+ memory, so that each process can access it at a fixed address. Used for
+ stack checking. */
+struct l1_scratch_task_info
+{
+ /* Points to the start of the stack. */
+ void *stack_start;
+ /* Not updated by the kernel; a user process can modify this to
+ keep track of the lowest address of the stack pointer during its
+ runtime. */
+ void *lowest_sp;
+};
+
+/* A pointer to the structure in memory. */
+#define L1_SCRATCH_TASK_INFO ((struct l1_scratch_task_info *)L1_SCRATCH_START)
+
+#endif
+
+#endif
diff --git a/include/asm-blackfin/linkage.h b/include/asm-blackfin/linkage.h
new file mode 100644
index 0000000..5a822bb
--- /dev/null
+++ b/include/asm-blackfin/linkage.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#define __ALIGN .align 4
+#define __ALIGN_STR ".align 4"
+
+#endif
diff --git a/include/asm-blackfin/local.h b/include/asm-blackfin/local.h
new file mode 100644
index 0000000..75afffb
--- /dev/null
+++ b/include/asm-blackfin/local.h
@@ -0,0 +1,6 @@
+#ifndef __BLACKFIN_LOCAL_H
+#define __BLACKFIN_LOCAL_H
+
+#include <asm-generic/local.h>
+
+#endif /* __BLACKFIN_LOCAL_H */
diff --git a/include/asm-blackfin/mach-bf533/anomaly.h b/include/asm-blackfin/mach-bf533/anomaly.h
new file mode 100644
index 0000000..a84d390
--- /dev/null
+++ b/include/asm-blackfin/mach-bf533/anomaly.h
@@ -0,0 +1,175 @@
+/*
+ * File: include/asm-blackfin/mach-bf533/anomaly.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* This file shoule be up to date with:
+ * - Revision U, May 17, 2006; ADSP-BF533 Blackfin Processor Anomaly List
+ * - Revision Y, May 17, 2006; ADSP-BF532 Blackfin Processor Anomaly List
+ * - Revision T, May 17, 2006; ADSP-BF531 Blackfin Processor Anomaly List
+ */
+
+#ifndef _MACH_ANOMALY_H_
+#define _MACH_ANOMALY_H_
+
+/* We do not support 0.1 or 0.2 silicon - sorry */
+#if (defined(CONFIG_BF_REV_0_1) || defined(CONFIG_BF_REV_0_2))
+#error Kernel will not work on BF533 Version 0.1 or 0.2
+#endif
+
+/* Issues that are common to 0.5, 0.4, and 0.3 silicon */
+#if (defined(CONFIG_BF_REV_0_5) || defined(CONFIG_BF_REV_0_4) || defined(CONFIG_BF_REV_0_3))
+#define ANOMALY_05000074 /* A multi issue instruction with dsp32shiftimm in
+ slot1 and store of a P register in slot 2 is not
+ supported */
+#define ANOMALY_05000105 /* Watchpoint Status Register (WPSTAT) bits are set on
+ every corresponding match */
+#define ANOMALY_05000119 /* DMA_RUN bit is not valid after a Peripheral Receive
+ Channel DMA stops */
+#define ANOMALY_05000122 /* Rx.H can not be used to access 16-bit System MMR
+ registers. */
+#define ANOMALY_05000166 /* PPI Data Lengths Between 8 and 16 do not zero out
+ upper bits*/
+#define ANOMALY_05000167 /* Turning Serial Ports on With External Frame Syncs */
+#define ANOMALY_05000180 /* PPI_DELAY not functional in PPI modes with 0 frame
+ syncs */
+#define ANOMALY_05000208 /* VSTAT status bit in PLL_STAT register is not
+ functional */
+#define ANOMALY_05000219 /* NMI event at boot time results in unpredictable
+ state */
+#define ANOMALY_05000229 /* SPI Slave Boot Mode modifies registers */
+#define ANOMALY_05000272 /* Certain data cache write through modes fail for
+ VDDint <=0.9V */
+#define ANOMALY_05000273 /* Writes to Synchronous SDRAM memory may be lost */
+#define ANOMALY_05000277 /* Writes to a flag data register one SCLK cycle after
+ an edge is detected may clear interrupt */
+#define ANOMALY_05000278 /* Disabling Peripherals with DMA running may cause
+ DMA system instability */
+#define ANOMALY_05000281 /* False Hardware Error Exception when ISR context is
+ not restored */
+#define ANOMALY_05000282 /* Memory DMA corruption with 32-bit data and traffic
+ control */
+#define ANOMALY_05000283 /* A system MMR write is stalled indefinitely when
+ killed in a particular stage*/
+#define ANOMALY_05000312 /* Errors when SSYNC, CSYNC, or loads to LT, LB and LC
+ registers are interrupted */
+#define ANOMALY_05000311 /* Erroneous flag pin operations under specific sequences*/
+
+#endif
+
+/* These issues only occur on 0.3 or 0.4 BF533 */
+#if (defined(CONFIG_BF_REV_0_4) || defined(CONFIG_BF_REV_0_3))
+#define ANOMALY_05000099 /* UART Line Status Register (UART_LSR) bits are not
+ updated at the same time. */
+#define ANOMALY_05000158 /* Boot fails when data cache enabled: Data from a Data
+ Cache Fill can be corrupted after or during
+ Instruction DMA if certain core stalls exist */
+#define ANOMALY_05000179 /* PPI_COUNT cannot be programmed to 0 in General
+ Purpose TX or RX modes */
+#define ANOMALY_05000198 /* Failing SYSTEM MMR accesses when stalled by
+ preceding memory read */
+#define ANOMALY_05000200 /* SPORT TFS and DT are incorrectly driven during
+ inactive channels in certain conditions */
+#define ANOMALY_05000202 /* Possible infinite stall with specific dual dag
+ situation */
+#define ANOMALY_05000215 /* UART TX Interrupt masked erroneously */
+#define ANOMALY_05000225 /* Incorrect pulse-width of UART start-bit */
+#define ANOMALY_05000227 /* Scratchpad memory bank reads may return incorrect
+ data*/
+#define ANOMALY_05000230 /* UART Receiver is less robust against Baudrate
+ Differences in certain Conditions */
+#define ANOMALY_05000231 /* UART STB bit incorrectly affects receiver setting */
+#define ANOMALY_05000242 /* DF bit in PLL_CTL register does not respond to
+ hardware reset */
+#define ANOMALY_05000244 /* With instruction cache enabled, a CSYNC or SSYNC or
+ IDLE around a Change of Control causes
+ unpredictable results */
+#define ANOMALY_05000245 /* Spurious Hardware Error from an access in the
+ shadow of a conditional branch */
+#define ANOMALY_05000246 /* Data CPLB's should prevent spurious hardware
+ errors */
+#define ANOMALY_05000253 /* Maximum external clock speed for Timers */
+#define ANOMALY_05000255 /* Entering Hibernate Mode with RTC Seconds event
+ interrupt not functional */
+#define ANOMALY_05000257 /* An interrupt or exception during short Hardware
+ loops may cause the instruction fetch unit to
+ malfunction */
+#define ANOMALY_05000258 /* Instruction Cache is corrupted when bit 9 and 12 of
+ the ICPLB Data registers differ */
+#define ANOMALY_05000260 /* ICPLB_STATUS MMR register may be corrupted */
+#define ANOMALY_05000261 /* DCPLB_FAULT_ADDR MMR register may be corrupted */
+#define ANOMALY_05000262 /* Stores to data cache may be lost */
+#define ANOMALY_05000263 /* Hardware loop corrupted when taking an ICPLB exception */
+#define ANOMALY_05000264 /* A Sync instruction (CSYNC, SSYNC) or an IDLE
+ instruction will cause an infinite stall in the
+ second to last instruction in a hardware loop */
+#define ANOMALY_05000265 /* Sensitivity to noise with slow input edge rates on
+ SPORT external receive and transmit clocks. */
+#define ANOMALY_05000269 /* High I/O activity causes the output voltage of the
+ internal voltage regulator (VDDint) to increase. */
+#define ANOMALY_05000270 /* High I/O activity causes the output voltage of the
+ internal voltage regulator (VDDint) to decrease */
+#endif
+
+/* These issues are only on 0.4 silicon */
+#if (defined(CONFIG_BF_REV_0_4))
+#define ANOMALY_05000234 /* Incorrect Revision Number in DSPID Register */
+#define ANOMALY_05000250 /* Incorrect Bit-Shift of Data Word in Multichannel
+ (TDM) */
+#endif
+
+/* These issues are only on 0.3 silicon */
+#if defined(CONFIG_BF_REV_0_3)
+#define ANOMALY_05000183 /* Timer Pin limitations for PPI TX Modes with
+ External Frame Syncs */
+#define ANOMALY_05000189 /* False Protection Exceptions caused by Speculative
+ Instruction or Data Fetches, or by Fetches at the
+ boundary of reserved memory space */
+#define ANOMALY_05000193 /* False Flag Pin Interrupts on Edge Sensitive Inputs
+ when polarity setting is changed */
+#define ANOMALY_05000194 /* Sport Restarting in specific modes may cause data
+ corruption */
+#define ANOMALY_05000199 /* DMA current address shows wrong value during carry
+ fix */
+#define ANOMALY_05000201 /* Receive frame sync not ignored during active
+ frames in sport MCM */
+#define ANOMALY_05000203 /* Specific sequence that can cause DMA error or DMA
+ stopping */
+#if defined(CONFIG_BF533)
+#define ANOMALY_05000204 /* Incorrect data read with write-through cache and
+ allocate cache lines on reads only mode */
+#endif /* CONFIG_BF533 */
+#define ANOMALY_05000207 /* Recovery from "brown-out" condition */
+#define ANOMALY_05000209 /* Speed-Path in computational unit affects certain
+ instructions */
+#define ANOMALY_05000233 /* PPI_FS3 is not driven in 2 or 3 internal Frame
+ Sync Transmit Mode */
+#define ANOMALY_05000271 /* Spontaneous reset of Internal Voltage Regulator */
+#endif
+
+#endif /* _MACH_ANOMALY_H_ */
diff --git a/include/asm-blackfin/mach-bf533/bf533.h b/include/asm-blackfin/mach-bf533/bf533.h
new file mode 100644
index 0000000..185fc12
--- /dev/null
+++ b/include/asm-blackfin/mach-bf533/bf533.h
@@ -0,0 +1,306 @@
+/*
+ * File: include/asm-blackfin/mach-bf533/bf533.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __MACH_BF533_H__
+#define __MACH_BF533_H__
+
+#define SUPPORTED_REVID 2
+
+#define OFFSET_(x) ((x) & 0x0000FFFF)
+
+/*some misc defines*/
+#define IMASK_IVG15 0x8000
+#define IMASK_IVG14 0x4000
+#define IMASK_IVG13 0x2000
+#define IMASK_IVG12 0x1000
+
+#define IMASK_IVG11 0x0800
+#define IMASK_IVG10 0x0400
+#define IMASK_IVG9 0x0200
+#define IMASK_IVG8 0x0100
+
+#define IMASK_IVG7 0x0080
+#define IMASK_IVGTMR 0x0040
+#define IMASK_IVGHW 0x0020
+
+/***************************/
+
+
+#define BLKFIN_DSUBBANKS 4
+#define BLKFIN_DWAYS 2
+#define BLKFIN_DLINES 64
+#define BLKFIN_ISUBBANKS 4
+#define BLKFIN_IWAYS 4
+#define BLKFIN_ILINES 32
+
+#define WAY0_L 0x1
+#define WAY1_L 0x2
+#define WAY01_L 0x3
+#define WAY2_L 0x4
+#define WAY02_L 0x5
+#define WAY12_L 0x6
+#define WAY012_L 0x7
+
+#define WAY3_L 0x8
+#define WAY03_L 0x9
+#define WAY13_L 0xA
+#define WAY013_L 0xB
+
+#define WAY32_L 0xC
+#define WAY320_L 0xD
+#define WAY321_L 0xE
+#define WAYALL_L 0xF
+
+#define DMC_ENABLE (2<<2) /*yes, 2, not 1 */
+
+/* IAR0 BIT FIELDS*/
+#define RTC_ERROR_BIT 0x0FFFFFFF
+#define UART_ERROR_BIT 0xF0FFFFFF
+#define SPORT1_ERROR_BIT 0xFF0FFFFF
+#define SPI_ERROR_BIT 0xFFF0FFFF
+#define SPORT0_ERROR_BIT 0xFFFF0FFF
+#define PPI_ERROR_BIT 0xFFFFF0FF
+#define DMA_ERROR_BIT 0xFFFFFF0F
+#define PLLWAKE_ERROR_BIT 0xFFFFFFFF
+
+/* IAR1 BIT FIELDS*/
+#define DMA7_UARTTX_BIT 0x0FFFFFFF
+#define DMA6_UARTRX_BIT 0xF0FFFFFF
+#define DMA5_SPI_BIT 0xFF0FFFFF
+#define DMA4_SPORT1TX_BIT 0xFFF0FFFF
+#define DMA3_SPORT1RX_BIT 0xFFFF0FFF
+#define DMA2_SPORT0TX_BIT 0xFFFFF0FF
+#define DMA1_SPORT0RX_BIT 0xFFFFFF0F
+#define DMA0_PPI_BIT 0xFFFFFFFF
+
+/* IAR2 BIT FIELDS*/
+#define WDTIMER_BIT 0x0FFFFFFF
+#define MEMDMA1_BIT 0xF0FFFFFF
+#define MEMDMA0_BIT 0xFF0FFFFF
+#define PFB_BIT 0xFFF0FFFF
+#define PFA_BIT 0xFFFF0FFF
+#define TIMER2_BIT 0xFFFFF0FF
+#define TIMER1_BIT 0xFFFFFF0F
+#define TIMER0_BIT 0xFFFFFFFF
+
+/********************************* EBIU Settings ************************************/
+#define AMBCTL0VAL ((CONFIG_BANK_1 << 16) | CONFIG_BANK_0)
+#define AMBCTL1VAL ((CONFIG_BANK_3 << 16) | CONFIG_BANK_2)
+
+#ifdef CONFIG_C_AMBEN_ALL
+#define V_AMBEN AMBEN_ALL
+#endif
+#ifdef CONFIG_C_AMBEN
+#define V_AMBEN 0x0
+#endif
+#ifdef CONFIG_C_AMBEN_B0
+#define V_AMBEN AMBEN_B0
+#endif
+#ifdef CONFIG_C_AMBEN_B0_B1
+#define V_AMBEN AMBEN_B0_B1
+#endif
+#ifdef CONFIG_C_AMBEN_B0_B1_B2
+#define V_AMBEN AMBEN_B0_B1_B2
+#endif
+#ifdef CONFIG_C_AMCKEN
+#define V_AMCKEN AMCKEN
+#else
+#define V_AMCKEN 0x0
+#endif
+#ifdef CONFIG_C_CDPRIO
+#define V_CDPRIO 0x100
+#else
+#define V_CDPRIO 0x0
+#endif
+
+#define AMGCTLVAL (V_AMBEN | V_AMCKEN | V_CDPRIO)
+
+#define MAX_VC 650000000
+#define MIN_VC 50000000
+
+#ifdef CONFIG_BFIN_KERNEL_CLOCK
+/********************************PLL Settings **************************************/
+#if (CONFIG_VCO_MULT < 0)
+#error "VCO Multiplier is less than 0. Please select a different value"
+#endif
+
+#if (CONFIG_VCO_MULT == 0)
+#error "VCO Multiplier should be greater than 0. Please select a different value"
+#endif
+
+#if (CONFIG_VCO_MULT > 64)
+#error "VCO Multiplier is more than 64. Please select a different value"
+#endif
+
+#ifndef CONFIG_CLKIN_HALF
+#define CONFIG_VCO_HZ (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)
+#else
+#define CONFIG_VCO_HZ ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)/2)
+#endif
+
+#ifndef CONFIG_PLL_BYPASS
+#define CONFIG_CCLK_HZ (CONFIG_VCO_HZ/CONFIG_CCLK_DIV)
+#define CONFIG_SCLK_HZ (CONFIG_VCO_HZ/CONFIG_SCLK_DIV)
+#else
+#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ
+#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ
+#endif
+
+#if (CONFIG_SCLK_DIV < 1)
+#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
+#endif
+
+#if (CONFIG_SCLK_DIV > 15)
+#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
+#endif
+
+#if (CONFIG_CCLK_DIV != 1)
+#if (CONFIG_CCLK_DIV != 2)
+#if (CONFIG_CCLK_DIV != 4)
+#if (CONFIG_CCLK_DIV != 8)
+#error "CCLK DIV can be 1,2,4 or 8 only. Please select a proper value"
+#endif
+#endif
+#endif
+#endif
+
+#if (CONFIG_VCO_HZ > MAX_VC)
+#error "VCO selected is more than maximum value. Please change the VCO multipler"
+#endif
+
+#if (CONFIG_SCLK_HZ > 133000000)
+#error "Sclk value selected is more than maximum. Please select a proper value for SCLK multiplier"
+#endif
+
+#if (CONFIG_SCLK_HZ < 27000000)
+#error "Sclk value selected is less than minimum. Please select a proper value for SCLK multiplier"
+#endif
+
+#if (CONFIG_SCLK_HZ > CONFIG_CCLK_HZ)
+#if (CONFIG_SCLK_HZ != CONFIG_CLKIN_HZ)
+#if (CONFIG_CCLK_HZ != CONFIG_CLKIN_HZ)
+#error "Please select sclk less than cclk"
+#endif
+#endif
+#endif
+
+#if (CONFIG_CCLK_DIV == 1)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV1
+#endif
+#if (CONFIG_CCLK_DIV == 2)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV2
+#endif
+#if (CONFIG_CCLK_DIV == 4)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV4
+#endif
+#if (CONFIG_CCLK_DIV == 8)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV8
+#endif
+#ifndef CONFIG_CCLK_ACT_DIV
+#define CONFIG_CCLK_ACT_DIV CONFIG_CCLK_DIV_not_defined_properly
+#endif
+
+#if defined(ANOMALY_05000273) && (CONFIG_CCLK_DIV == 1)
+#error ANOMALY 05000273, please make sure CCLK is at least 2x SCLK
+#endif
+
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+#ifdef CONFIG_BF533
+#define CPU "BF533"
+#define CPUID 0x027a5000
+#endif
+#ifdef CONFIG_BF532
+#define CPU "BF532"
+#define CPUID 0x0275A000
+#endif
+#ifdef CONFIG_BF531
+#define CPU "BF531"
+#define CPUID 0x027a5000
+#endif
+#ifndef CPU
+#define CPU "UNKNOWN"
+#define CPUID 0x0
+#endif
+
+#if (CONFIG_MEM_SIZE % 4)
+#error "SDRAM mem size must be multible of 4MB"
+#endif
+
+#define SDRAM_IGENERIC (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO)
+#define SDRAM_IKERNEL (SDRAM_IGENERIC | CPLB_LOCK)
+#define L1_IMEMORY ( CPLB_USER_RD | CPLB_VALID | CPLB_LOCK)
+#define SDRAM_INON_CHBL ( CPLB_USER_RD | CPLB_VALID)
+
+/*Use the menuconfig cache policy here - CONFIG_BLKFIN_WT/CONFIG_BLKFIN_WB*/
+
+#define ANOMALY_05000158_WORKAROUND 0x200
+#ifdef CONFIG_BLKFIN_WB /*Write Back Policy */
+#define SDRAM_DGENERIC (CPLB_L1_CHBL | CPLB_DIRTY \
+ | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)
+#else /*Write Through */
+#define SDRAM_DGENERIC (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_DIRTY \
+ | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)
+#endif
+
+#define L1_DMEMORY (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)
+#define SDRAM_DNON_CHBL (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY)
+#define SDRAM_EBIU (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY)
+#define SDRAM_OOPS (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)
+
+#define SIZE_1K 0x00000400 /* 1K */
+#define SIZE_4K 0x00001000 /* 4K */
+#define SIZE_1M 0x00100000 /* 1M */
+#define SIZE_4M 0x00400000 /* 4M */
+
+#define MAX_CPLBS (16 * 2)
+
+/*
+* Number of required data CPLB switchtable entries
+* MEMSIZE / 4 (we mostly install 4M page size CPLBs
+* approx 16 for smaller 1MB page size CPLBs for allignment purposes
+* 1 for L1 Data Memory
+* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
+* 1 for ASYNC Memory
+*/
+
+
+#define MAX_SWITCH_D_CPLBS (((CONFIG_MEM_SIZE / 4) + 16 + 1 + 1 + 1) * 2)
+
+/*
+* Number of required instruction CPLB switchtable entries
+* MEMSIZE / 4 (we mostly install 4M page size CPLBs
+* approx 12 for smaller 1MB page size CPLBs for allignment purposes
+* 1 for L1 Instruction Memory
+* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
+*/
+
+#define MAX_SWITCH_I_CPLBS (((CONFIG_MEM_SIZE / 4) + 12 + 1 + 1) * 2)
+
+#endif /* __MACH_BF533_H__ */
diff --git a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
new file mode 100644
index 0000000..23bf76a
--- /dev/null
+++ b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
@@ -0,0 +1,108 @@
+#include <linux/serial.h>
+#include <asm/dma.h>
+
+#define NR_PORTS 1
+
+#define OFFSET_THR 0x00 /* Transmit Holding register */
+#define OFFSET_RBR 0x00 /* Receive Buffer register */
+#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */
+#define OFFSET_IER 0x04 /* Interrupt Enable Register */
+#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */
+#define OFFSET_IIR 0x08 /* Interrupt Identification Register */
+#define OFFSET_LCR 0x0C /* Line Control Register */
+#define OFFSET_MCR 0x10 /* Modem Control Register */
+#define OFFSET_LSR 0x14 /* Line Status Register */
+#define OFFSET_MSR 0x18 /* Modem Status Register */
+#define OFFSET_SCR 0x1C /* SCR Scratch Register */
+#define OFFSET_GCTL 0x24 /* Global Control Register */
+
+#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR))
+#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL))
+#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER))
+#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
+#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR))
+#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
+#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR))
+#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
+
+#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v)
+#define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
+#define UART_PUT_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER),v)
+#define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
+#define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
+#define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
+
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+# define CONFIG_SERIAL_BFIN_CTSRTS
+# ifndef CONFIG_UART0_CTS_PIN
+# define CONFIG_UART0_CTS_PIN -1
+# endif
+# ifndef CONFIG_UART0_RTS_PIN
+# define CONFIG_UART0_RTS_PIN -1
+# endif
+#endif
+
+struct bfin_serial_port {
+ struct uart_port port;
+ unsigned int old_status;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ int tx_done;
+ int tx_count;
+ struct circ_buf rx_dma_buf;
+ struct timer_list rx_dma_timer;
+ int rx_dma_nrows;
+ unsigned int tx_dma_channel;
+ unsigned int rx_dma_channel;
+ struct work_struct tx_dma_workqueue;
+#else
+ struct work_struct cts_workqueue;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ int cts_pin;
+ int rts_pin;
+#endif
+};
+
+struct bfin_serial_port bfin_serial_ports[NR_PORTS];
+struct bfin_serial_res {
+ unsigned long uart_base_addr;
+ int uart_irq;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ unsigned int uart_tx_dma_channel;
+ unsigned int uart_rx_dma_channel;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ int uart_cts_pin;
+ int uart_rts_pin;
+#endif
+};
+
+struct bfin_serial_res bfin_serial_resource[] = {
+ 0xFFC00400,
+ IRQ_UART_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ CH_UART_TX,
+ CH_UART_RX,
+#endif
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+ CONFIG_UART0_CTS_PIN,
+ CONFIG_UART0_RTS_PIN,
+#endif
+};
+
+
+int nr_ports = NR_PORTS;
+static void bfin_serial_hw_init(struct bfin_serial_port *uart)
+{
+
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ if (uart->cts_pin >= 0) {
+ gpio_request(uart->cts_pin, NULL);
+ gpio_direction_input(uart->cts_pin);
+ }
+ if (uart->rts_pin >= 0) {
+ gpio_request(uart->rts_pin, NULL);
+ gpio_direction_input(uart->rts_pin);
+ }
+#endif
+}
diff --git a/include/asm-blackfin/mach-bf533/blackfin.h b/include/asm-blackfin/mach-bf533/blackfin.h
new file mode 100644
index 0000000..e438449
--- /dev/null
+++ b/include/asm-blackfin/mach-bf533/blackfin.h
@@ -0,0 +1,45 @@
+/*
+ * File: include/asm-blackfin/mach-bf533/blackfin.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MACH_BLACKFIN_H_
+#define _MACH_BLACKFIN_H_
+
+#define BF533_FAMILY
+
+#include "bf533.h"
+#include "mem_map.h"
+#include "defBF532.h"
+#include "anomaly.h"
+
+#if !(defined(__ASSEMBLY__) || defined(ASSEMBLY))
+#include "cdefBF532.h"
+#endif
+
+#endif /* _MACH_BLACKFIN_H_ */
diff --git a/include/asm-blackfin/mach-bf533/cdefBF532.h b/include/asm-blackfin/mach-bf533/cdefBF532.h
new file mode 100644
index 0000000..1d7c494
--- /dev/null
+++ b/include/asm-blackfin/mach-bf533/cdefBF532.h
@@ -0,0 +1,706 @@
+/*
+ * File: include/asm-blackfin/mach-bf533/cdefBF532.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _CDEF_BF532_H
+#define _CDEF_BF532_H
+/*
+#if !defined(__ADSPLPBLACKFIN__)
+#warning cdefBF532.h should only be included for 532 compatible chips.
+#endif
+*/
+/*include all Core registers and bit definitions*/
+#include "defBF532.h"
+
+/*include core specific register pointer definitions*/
+#include <asm/mach-common/cdef_LPBlackfin.h>
+
+#include <asm/system.h>
+
+/* Clock and System Control (0xFFC0 0400-0xFFC0 07FF) */
+#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL)
+#define bfin_write_PLL_CTL(val) bfin_write16(PLL_CTL,val)
+#define bfin_read_PLL_STAT() bfin_read16(PLL_STAT)
+#define bfin_write_PLL_STAT(val) bfin_write16(PLL_STAT,val)
+#define bfin_read_PLL_LOCKCNT() bfin_read16(PLL_LOCKCNT)
+#define bfin_write_PLL_LOCKCNT(val) bfin_write16(PLL_LOCKCNT,val)
+#define bfin_read_CHIPID() bfin_read32(CHIPID)
+#define bfin_read_SWRST() bfin_read16(SWRST)
+#define bfin_write_SWRST(val) bfin_write16(SWRST,val)
+#define bfin_read_SYSCR() bfin_read16(SYSCR)
+#define bfin_write_SYSCR(val) bfin_write16(SYSCR,val)
+#define bfin_read_PLL_DIV() bfin_read16(PLL_DIV)
+#define bfin_write_PLL_DIV(val) bfin_write16(PLL_DIV,val)
+#define bfin_read_VR_CTL() bfin_read16(VR_CTL)
+/* Writing to VR_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_VR_CTL(unsigned int val)
+{
+ unsigned long flags, iwr;
+
+ bfin_write16(VR_CTL, val);
+ __builtin_bfin_ssync();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr = bfin_read32(SIC_IWR);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SIC_IWR, IWR_ENABLE(0));
+ local_irq_save(flags);
+ asm("IDLE;");
+ local_irq_restore(flags);
+ bfin_write32(SIC_IWR, iwr);
+}
+
+/* System Interrupt Controller (0xFFC0 0C00-0xFFC0 0FFF) */
+#define bfin_read_SIC_IAR0() bfin_read32(SIC_IAR0)
+#define bfin_write_SIC_IAR0(val) bfin_write32(SIC_IAR0,val)
+#define bfin_read_SIC_IAR1() bfin_read32(SIC_IAR1)
+#define bfin_write_SIC_IAR1(val) bfin_write32(SIC_IAR1,val)
+#define bfin_read_SIC_IAR2() bfin_read32(SIC_IAR2)
+#define bfin_write_SIC_IAR2(val) bfin_write32(SIC_IAR2,val)
+#define bfin_read_SIC_IAR3() bfin_read32(SIC_IAR3)
+#define bfin_write_SIC_IAR3(val) bfin_write32(SIC_IAR3,val)
+#define bfin_read_SIC_IMASK() bfin_read32(SIC_IMASK)
+#define bfin_write_SIC_IMASK(val) bfin_write32(SIC_IMASK,val)
+#define bfin_read_SIC_ISR() bfin_read32(SIC_ISR)
+#define bfin_write_SIC_ISR(val) bfin_write32(SIC_ISR,val)
+#define bfin_read_SIC_IWR() bfin_read32(SIC_IWR)
+#define bfin_write_SIC_IWR(val) bfin_write32(SIC_IWR,val)
+
+/* Watchdog Timer (0xFFC0 1000-0xFFC0 13FF) */
+#define bfin_read_WDOG_CTL() bfin_read16(WDOG_CTL)
+#define bfin_write_WDOG_CTL(val) bfin_write16(WDOG_CTL,val)
+#define bfin_read_WDOG_CNT() bfin_read32(WDOG_CNT)
+#define bfin_write_WDOG_CNT(val) bfin_write32(WDOG_CNT,val)
+#define bfin_read_WDOG_STAT() bfin_read32(WDOG_STAT)
+#define bfin_write_WDOG_STAT(val) bfin_write32(WDOG_STAT,val)
+
+/* Real Time Clock (0xFFC0 1400-0xFFC0 17FF) */
+#define bfin_read_RTC_STAT() bfin_read32(RTC_STAT)
+#define bfin_write_RTC_STAT(val) bfin_write32(RTC_STAT,val)
+#define bfin_read_RTC_ICTL() bfin_read16(RTC_ICTL)
+#define bfin_write_RTC_ICTL(val) bfin_write16(RTC_ICTL,val)
+#define bfin_read_RTC_ISTAT() bfin_read16(RTC_ISTAT)
+#define bfin_write_RTC_ISTAT(val) bfin_write16(RTC_ISTAT,val)
+#define bfin_read_RTC_SWCNT() bfin_read16(RTC_SWCNT)
+#define bfin_write_RTC_SWCNT(val) bfin_write16(RTC_SWCNT,val)
+#define bfin_read_RTC_ALARM() bfin_read32(RTC_ALARM)
+#define bfin_write_RTC_ALARM(val) bfin_write32(RTC_ALARM,val)
+#define bfin_read_RTC_FAST() bfin_read16(RTC_FAST)
+#define bfin_write_RTC_FAST(val) bfin_write16(RTC_FAST,val)
+#define bfin_read_RTC_PREN() bfin_read16(RTC_PREN)
+#define bfin_write_RTC_PREN(val) bfin_write16(RTC_PREN,val)
+
+/* General Purpose IO (0xFFC0 2400-0xFFC0 27FF) */
+#define bfin_read_FIO_DIR() bfin_read16(FIO_DIR)
+#define bfin_write_FIO_DIR(val) bfin_write16(FIO_DIR,val)
+#define bfin_read_FIO_FLAG_C() bfin_read16(FIO_FLAG_C)
+#define bfin_write_FIO_FLAG_C(val) bfin_write16(FIO_FLAG_C,val)
+#define bfin_read_FIO_FLAG_S() bfin_read16(FIO_FLAG_S)
+#define bfin_write_FIO_FLAG_S(val) bfin_write16(FIO_FLAG_S,val)
+#define bfin_read_FIO_MASKA_C() bfin_read16(FIO_MASKA_C)
+#define bfin_write_FIO_MASKA_C(val) bfin_write16(FIO_MASKA_C,val)
+#define bfin_read_FIO_MASKA_S() bfin_read16(FIO_MASKA_S)
+#define bfin_write_FIO_MASKA_S(val) bfin_write16(FIO_MASKA_S,val)
+#define bfin_read_FIO_MASKB_C() bfin_read16(FIO_MASKB_C)
+#define bfin_write_FIO_MASKB_C(val) bfin_write16(FIO_MASKB_C,val)
+#define bfin_read_FIO_MASKB_S() bfin_read16(FIO_MASKB_S)
+#define bfin_write_FIO_MASKB_S(val) bfin_write16(FIO_MASKB_S,val)
+#define bfin_read_FIO_POLAR() bfin_read16(FIO_POLAR)
+#define bfin_write_FIO_POLAR(val) bfin_write16(FIO_POLAR,val)
+#define bfin_read_FIO_EDGE() bfin_read16(FIO_EDGE)
+#define bfin_write_FIO_EDGE(val) bfin_write16(FIO_EDGE,val)
+#define bfin_read_FIO_BOTH() bfin_read16(FIO_BOTH)
+#define bfin_write_FIO_BOTH(val) bfin_write16(FIO_BOTH,val)
+#define bfin_read_FIO_INEN() bfin_read16(FIO_INEN)
+#define bfin_write_FIO_INEN(val) bfin_write16(FIO_INEN,val)
+#define bfin_read_FIO_FLAG_D() bfin_read16(FIO_FLAG_D)
+#define bfin_write_FIO_FLAG_D(val) bfin_write16(FIO_FLAG_D,val)
+#define bfin_read_FIO_FLAG_T() bfin_read16(FIO_FLAG_T)
+#define bfin_write_FIO_FLAG_T(val) bfin_write16(FIO_FLAG_T,val)
+#define bfin_read_FIO_MASKA_D() bfin_read16(FIO_MASKA_D)
+#define bfin_write_FIO_MASKA_D(val) bfin_write16(FIO_MASKA_D,val)
+#define bfin_read_FIO_MASKA_T() bfin_read16(FIO_MASKA_T)
+#define bfin_write_FIO_MASKA_T(val) bfin_write16(FIO_MASKA_T,val)
+#define bfin_read_FIO_MASKB_D() bfin_read16(FIO_MASKB_D)
+#define bfin_write_FIO_MASKB_D(val) bfin_write16(FIO_MASKB_D,val)
+#define bfin_read_FIO_MASKB_T() bfin_read16(FIO_MASKB_T)
+#define bfin_write_FIO_MASKB_T(val) bfin_write16(FIO_MASKB_T,val)
+
+/* DMA Traffic controls */
+#define bfin_read_DMA_TCPER() bfin_read16(DMA_TCPER)
+#define bfin_write_DMA_TCPER(val) bfin_write16(DMA_TCPER,val)
+#define bfin_read_DMA_TCCNT() bfin_read16(DMA_TCCNT)
+#define bfin_write_DMA_TCCNT(val) bfin_write16(DMA_TCCNT,val)
+#define bfin_read_DMA_TC_PER() bfin_read16(DMA_TC_PER)
+#define bfin_write_DMA_TC_PER(val) bfin_write16(DMA_TC_PER,val)
+#define bfin_read_DMA_TC_CNT() bfin_read16(DMA_TC_CNT)
+#define bfin_write_DMA_TC_CNT(val) bfin_write16(DMA_TC_CNT,val)
+
+/* DMA Controller */
+#define bfin_read_DMA0_CONFIG() bfin_read16(DMA0_CONFIG)
+#define bfin_write_DMA0_CONFIG(val) bfin_write16(DMA0_CONFIG,val)
+#define bfin_read_DMA0_NEXT_DESC_PTR() bfin_read32(DMA0_NEXT_DESC_PTR)
+#define bfin_write_DMA0_NEXT_DESC_PTR(val) bfin_write32(DMA0_NEXT_DESC_PTR,val)
+#define bfin_read_DMA0_START_ADDR() bfin_read32(DMA0_START_ADDR)
+#define bfin_write_DMA0_START_ADDR(val) bfin_write32(DMA0_START_ADDR,val)
+#define bfin_read_DMA0_X_COUNT() bfin_read16(DMA0_X_COUNT)
+#define bfin_write_DMA0_X_COUNT(val) bfin_write16(DMA0_X_COUNT,val)
+#define bfin_read_DMA0_Y_COUNT() bfin_read16(DMA0_Y_COUNT)
+#define bfin_write_DMA0_Y_COUNT(val) bfin_write16(DMA0_Y_COUNT,val)
+#define bfin_read_DMA0_X_MODIFY() bfin_read16(DMA0_X_MODIFY)
+#define bfin_write_DMA0_X_MODIFY(val) bfin_write16(DMA0_X_MODIFY,val)
+#define bfin_read_DMA0_Y_MODIFY() bfin_read16(DMA0_Y_MODIFY)
+#define bfin_write_DMA0_Y_MODIFY(val) bfin_write16(DMA0_Y_MODIFY,val)
+#define bfin_read_DMA0_CURR_DESC_PTR() bfin_read32(DMA0_CURR_DESC_PTR)
+#define bfin_write_DMA0_CURR_DESC_PTR(val) bfin_write32(DMA0_CURR_DESC_PTR,val)
+#define bfin_read_DMA0_CURR_ADDR() bfin_read32(DMA0_CURR_ADDR)
+#define bfin_write_DMA0_CURR_ADDR(val) bfin_write32(DMA0_CURR_ADDR,val)
+#define bfin_read_DMA0_CURR_X_COUNT() bfin_read16(DMA0_CURR_X_COUNT)
+#define bfin_write_DMA0_CURR_X_COUNT(val) bfin_write16(DMA0_CURR_X_COUNT,val)
+#define bfin_read_DMA0_CURR_Y_COUNT() bfin_read16(DMA0_CURR_Y_COUNT)
+#define bfin_write_DMA0_CURR_Y_COUNT(val) bfin_write16(DMA0_CURR_Y_COUNT,val)
+#define bfin_read_DMA0_IRQ_STATUS() bfin_read16(DMA0_IRQ_STATUS)
+#define bfin_write_DMA0_IRQ_STATUS(val) bfin_write16(DMA0_IRQ_STATUS,val)
+#define bfin_read_DMA0_PERIPHERAL_MAP() bfin_read16(DMA0_PERIPHERAL_MAP)
+#define bfin_write_DMA0_PERIPHERAL_MAP(val) bfin_write16(DMA0_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA1_CONFIG() bfin_read16(DMA1_CONFIG)
+#define bfin_write_DMA1_CONFIG(val) bfin_write16(DMA1_CONFIG,val)
+#define bfin_read_DMA1_NEXT_DESC_PTR() bfin_read32(DMA1_NEXT_DESC_PTR)
+#define bfin_write_DMA1_NEXT_DESC_PTR(val) bfin_write32(DMA1_NEXT_DESC_PTR,val)
+#define bfin_read_DMA1_START_ADDR() bfin_read32(DMA1_START_ADDR)
+#define bfin_write_DMA1_START_ADDR(val) bfin_write32(DMA1_START_ADDR,val)
+#define bfin_read_DMA1_X_COUNT() bfin_read16(DMA1_X_COUNT)
+#define bfin_write_DMA1_X_COUNT(val) bfin_write16(DMA1_X_COUNT,val)
+#define bfin_read_DMA1_Y_COUNT() bfin_read16(DMA1_Y_COUNT)
+#define bfin_write_DMA1_Y_COUNT(val) bfin_write16(DMA1_Y_COUNT,val)
+#define bfin_read_DMA1_X_MODIFY() bfin_read16(DMA1_X_MODIFY)
+#define bfin_write_DMA1_X_MODIFY(val) bfin_write16(DMA1_X_MODIFY,val)
+#define bfin_read_DMA1_Y_MODIFY() bfin_read16(DMA1_Y_MODIFY)
+#define bfin_write_DMA1_Y_MODIFY(val) bfin_write16(DMA1_Y_MODIFY,val)
+#define bfin_read_DMA1_CURR_DESC_PTR() bfin_read32(DMA1_CURR_DESC_PTR)
+#define bfin_write_DMA1_CURR_DESC_PTR(val) bfin_write32(DMA1_CURR_DESC_PTR,val)
+#define bfin_read_DMA1_CURR_ADDR() bfin_read32(DMA1_CURR_ADDR)
+#define bfin_write_DMA1_CURR_ADDR(val) bfin_write32(DMA1_CURR_ADDR,val)
+#define bfin_read_DMA1_CURR_X_COUNT() bfin_read16(DMA1_CURR_X_COUNT)
+#define bfin_write_DMA1_CURR_X_COUNT(val) bfin_write16(DMA1_CURR_X_COUNT,val)
+#define bfin_read_DMA1_CURR_Y_COUNT() bfin_read16(DMA1_CURR_Y_COUNT)
+#define bfin_write_DMA1_CURR_Y_COUNT(val) bfin_write16(DMA1_CURR_Y_COUNT,val)
+#define bfin_read_DMA1_IRQ_STATUS() bfin_read16(DMA1_IRQ_STATUS)
+#define bfin_write_DMA1_IRQ_STATUS(val) bfin_write16(DMA1_IRQ_STATUS,val)
+#define bfin_read_DMA1_PERIPHERAL_MAP() bfin_read16(DMA1_PERIPHERAL_MAP)
+#define bfin_write_DMA1_PERIPHERAL_MAP(val) bfin_write16(DMA1_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA2_CONFIG() bfin_read16(DMA2_CONFIG)
+#define bfin_write_DMA2_CONFIG(val) bfin_write16(DMA2_CONFIG,val)
+#define bfin_read_DMA2_NEXT_DESC_PTR() bfin_read32(DMA2_NEXT_DESC_PTR)
+#define bfin_write_DMA2_NEXT_DESC_PTR(val) bfin_write32(DMA2_NEXT_DESC_PTR,val)
+#define bfin_read_DMA2_START_ADDR() bfin_read32(DMA2_START_ADDR)
+#define bfin_write_DMA2_START_ADDR(val) bfin_write32(DMA2_START_ADDR,val)
+#define bfin_read_DMA2_X_COUNT() bfin_read16(DMA2_X_COUNT)
+#define bfin_write_DMA2_X_COUNT(val) bfin_write16(DMA2_X_COUNT,val)
+#define bfin_read_DMA2_Y_COUNT() bfin_read16(DMA2_Y_COUNT)
+#define bfin_write_DMA2_Y_COUNT(val) bfin_write16(DMA2_Y_COUNT,val)
+#define bfin_read_DMA2_X_MODIFY() bfin_read16(DMA2_X_MODIFY)
+#define bfin_write_DMA2_X_MODIFY(val) bfin_write16(DMA2_X_MODIFY,val)
+#define bfin_read_DMA2_Y_MODIFY() bfin_read16(DMA2_Y_MODIFY)
+#define bfin_write_DMA2_Y_MODIFY(val) bfin_write16(DMA2_Y_MODIFY,val)
+#define bfin_read_DMA2_CURR_DESC_PTR() bfin_read32(DMA2_CURR_DESC_PTR)
+#define bfin_write_DMA2_CURR_DESC_PTR(val) bfin_write32(DMA2_CURR_DESC_PTR,val)
+#define bfin_read_DMA2_CURR_ADDR() bfin_read32(DMA2_CURR_ADDR)
+#define bfin_write_DMA2_CURR_ADDR(val) bfin_write32(DMA2_CURR_ADDR,val)
+#define bfin_read_DMA2_CURR_X_COUNT() bfin_read16(DMA2_CURR_X_COUNT)
+#define bfin_write_DMA2_CURR_X_COUNT(val) bfin_write16(DMA2_CURR_X_COUNT,val)
+#define bfin_read_DMA2_CURR_Y_COUNT() bfin_read16(DMA2_CURR_Y_COUNT)
+#define bfin_write_DMA2_CURR_Y_COUNT(val) bfin_write16(DMA2_CURR_Y_COUNT,val)
+#define bfin_read_DMA2_IRQ_STATUS() bfin_read16(DMA2_IRQ_STATUS)
+#define bfin_write_DMA2_IRQ_STATUS(val) bfin_write16(DMA2_IRQ_STATUS,val)
+#define bfin_read_DMA2_PERIPHERAL_MAP() bfin_read16(DMA2_PERIPHERAL_MAP)
+#define bfin_write_DMA2_PERIPHERAL_MAP(val) bfin_write16(DMA2_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA3_CONFIG() bfin_read16(DMA3_CONFIG)
+#define bfin_write_DMA3_CONFIG(val) bfin_write16(DMA3_CONFIG,val)
+#define bfin_read_DMA3_NEXT_DESC_PTR() bfin_read32(DMA3_NEXT_DESC_PTR)
+#define bfin_write_DMA3_NEXT_DESC_PTR(val) bfin_write32(DMA3_NEXT_DESC_PTR,val)
+#define bfin_read_DMA3_START_ADDR() bfin_read32(DMA3_START_ADDR)
+#define bfin_write_DMA3_START_ADDR(val) bfin_write32(DMA3_START_ADDR,val)
+#define bfin_read_DMA3_X_COUNT() bfin_read16(DMA3_X_COUNT)
+#define bfin_write_DMA3_X_COUNT(val) bfin_write16(DMA3_X_COUNT,val)
+#define bfin_read_DMA3_Y_COUNT() bfin_read16(DMA3_Y_COUNT)
+#define bfin_write_DMA3_Y_COUNT(val) bfin_write16(DMA3_Y_COUNT,val)
+#define bfin_read_DMA3_X_MODIFY() bfin_read16(DMA3_X_MODIFY)
+#define bfin_write_DMA3_X_MODIFY(val) bfin_write16(DMA3_X_MODIFY,val)
+#define bfin_read_DMA3_Y_MODIFY() bfin_read16(DMA3_Y_MODIFY)
+#define bfin_write_DMA3_Y_MODIFY(val) bfin_write16(DMA3_Y_MODIFY,val)
+#define bfin_read_DMA3_CURR_DESC_PTR() bfin_read32(DMA3_CURR_DESC_PTR)
+#define bfin_write_DMA3_CURR_DESC_PTR(val) bfin_write32(DMA3_CURR_DESC_PTR,val)
+#define bfin_read_DMA3_CURR_ADDR() bfin_read32(DMA3_CURR_ADDR)
+#define bfin_write_DMA3_CURR_ADDR(val) bfin_write32(DMA3_CURR_ADDR,val)
+#define bfin_read_DMA3_CURR_X_COUNT() bfin_read16(DMA3_CURR_X_COUNT)
+#define bfin_write_DMA3_CURR_X_COUNT(val) bfin_write16(DMA3_CURR_X_COUNT,val)
+#define bfin_read_DMA3_CURR_Y_COUNT() bfin_read16(DMA3_CURR_Y_COUNT)
+#define bfin_write_DMA3_CURR_Y_COUNT(val) bfin_write16(DMA3_CURR_Y_COUNT,val)
+#define bfin_read_DMA3_IRQ_STATUS() bfin_read16(DMA3_IRQ_STATUS)
+#define bfin_write_DMA3_IRQ_STATUS(val) bfin_write16(DMA3_IRQ_STATUS,val)
+#define bfin_read_DMA3_PERIPHERAL_MAP() bfin_read16(DMA3_PERIPHERAL_MAP)
+#define bfin_write_DMA3_PERIPHERAL_MAP(val) bfin_write16(DMA3_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA4_CONFIG() bfin_read16(DMA4_CONFIG)
+#define bfin_write_DMA4_CONFIG(val) bfin_write16(DMA4_CONFIG,val)
+#define bfin_read_DMA4_NEXT_DESC_PTR() bfin_read32(DMA4_NEXT_DESC_PTR)
+#define bfin_write_DMA4_NEXT_DESC_PTR(val) bfin_write32(DMA4_NEXT_DESC_PTR,val)
+#define bfin_read_DMA4_START_ADDR() bfin_read32(DMA4_START_ADDR)
+#define bfin_write_DMA4_START_ADDR(val) bfin_write32(DMA4_START_ADDR,val)
+#define bfin_read_DMA4_X_COUNT() bfin_read16(DMA4_X_COUNT)
+#define bfin_write_DMA4_X_COUNT(val) bfin_write16(DMA4_X_COUNT,val)
+#define bfin_read_DMA4_Y_COUNT() bfin_read16(DMA4_Y_COUNT)
+#define bfin_write_DMA4_Y_COUNT(val) bfin_write16(DMA4_Y_COUNT,val)
+#define bfin_read_DMA4_X_MODIFY() bfin_read16(DMA4_X_MODIFY)
+#define bfin_write_DMA4_X_MODIFY(val) bfin_write16(DMA4_X_MODIFY,val)
+#define bfin_read_DMA4_Y_MODIFY() bfin_read16(DMA4_Y_MODIFY)
+#define bfin_write_DMA4_Y_MODIFY(val) bfin_write16(DMA4_Y_MODIFY,val)
+#define bfin_read_DMA4_CURR_DESC_PTR() bfin_read32(DMA4_CURR_DESC_PTR)
+#define bfin_write_DMA4_CURR_DESC_PTR(val) bfin_write32(DMA4_CURR_DESC_PTR,val)
+#define bfin_read_DMA4_CURR_ADDR() bfin_read32(DMA4_CURR_ADDR)
+#define bfin_write_DMA4_CURR_ADDR(val) bfin_write32(DMA4_CURR_ADDR,val)
+#define bfin_read_DMA4_CURR_X_COUNT() bfin_read16(DMA4_CURR_X_COUNT)
+#define bfin_write_DMA4_CURR_X_COUNT(val) bfin_write16(DMA4_CURR_X_COUNT,val)
+#define bfin_read_DMA4_CURR_Y_COUNT() bfin_read16(DMA4_CURR_Y_COUNT)
+#define bfin_write_DMA4_CURR_Y_COUNT(val) bfin_write16(DMA4_CURR_Y_COUNT,val)
+#define bfin_read_DMA4_IRQ_STATUS() bfin_read16(DMA4_IRQ_STATUS)
+#define bfin_write_DMA4_IRQ_STATUS(val) bfin_write16(DMA4_IRQ_STATUS,val)
+#define bfin_read_DMA4_PERIPHERAL_MAP() bfin_read16(DMA4_PERIPHERAL_MAP)
+#define bfin_write_DMA4_PERIPHERAL_MAP(val) bfin_write16(DMA4_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA5_CONFIG() bfin_read16(DMA5_CONFIG)
+#define bfin_write_DMA5_CONFIG(val) bfin_write16(DMA5_CONFIG,val)
+#define bfin_read_DMA5_NEXT_DESC_PTR() bfin_read32(DMA5_NEXT_DESC_PTR)
+#define bfin_write_DMA5_NEXT_DESC_PTR(val) bfin_write32(DMA5_NEXT_DESC_PTR,val)
+#define bfin_read_DMA5_START_ADDR() bfin_read32(DMA5_START_ADDR)
+#define bfin_write_DMA5_START_ADDR(val) bfin_write32(DMA5_START_ADDR,val)
+#define bfin_read_DMA5_X_COUNT() bfin_read16(DMA5_X_COUNT)
+#define bfin_write_DMA5_X_COUNT(val) bfin_write16(DMA5_X_COUNT,val)
+#define bfin_read_DMA5_Y_COUNT() bfin_read16(DMA5_Y_COUNT)
+#define bfin_write_DMA5_Y_COUNT(val) bfin_write16(DMA5_Y_COUNT,val)
+#define bfin_read_DMA5_X_MODIFY() bfin_read16(DMA5_X_MODIFY)
+#define bfin_write_DMA5_X_MODIFY(val) bfin_write16(DMA5_X_MODIFY,val)
+#define bfin_read_DMA5_Y_MODIFY() bfin_read16(DMA5_Y_MODIFY)
+#define bfin_write_DMA5_Y_MODIFY(val) bfin_write16(DMA5_Y_MODIFY,val)
+#define bfin_read_DMA5_CURR_DESC_PTR() bfin_read32(DMA5_CURR_DESC_PTR)
+#define bfin_write_DMA5_CURR_DESC_PTR(val) bfin_write32(DMA5_CURR_DESC_PTR,val)
+#define bfin_read_DMA5_CURR_ADDR() bfin_read32(DMA5_CURR_ADDR)
+#define bfin_write_DMA5_CURR_ADDR(val) bfin_write32(DMA5_CURR_ADDR,val)
+#define bfin_read_DMA5_CURR_X_COUNT() bfin_read16(DMA5_CURR_X_COUNT)
+#define bfin_write_DMA5_CURR_X_COUNT(val) bfin_write16(DMA5_CURR_X_COUNT,val)
+#define bfin_read_DMA5_CURR_Y_COUNT() bfin_read16(DMA5_CURR_Y_COUNT)
+#define bfin_write_DMA5_CURR_Y_COUNT(val) bfin_write16(DMA5_CURR_Y_COUNT,val)
+#define bfin_read_DMA5_IRQ_STATUS() bfin_read16(DMA5_IRQ_STATUS)
+#define bfin_write_DMA5_IRQ_STATUS(val) bfin_write16(DMA5_IRQ_STATUS,val)
+#define bfin_read_DMA5_PERIPHERAL_MAP() bfin_read16(DMA5_PERIPHERAL_MAP)
+#define bfin_write_DMA5_PERIPHERAL_MAP(val) bfin_write16(DMA5_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA6_CONFIG() bfin_read16(DMA6_CONFIG)
+#define bfin_write_DMA6_CONFIG(val) bfin_write16(DMA6_CONFIG,val)
+#define bfin_read_DMA6_NEXT_DESC_PTR() bfin_read32(DMA6_NEXT_DESC_PTR)
+#define bfin_write_DMA6_NEXT_DESC_PTR(val) bfin_write32(DMA6_NEXT_DESC_PTR,val)
+#define bfin_read_DMA6_START_ADDR() bfin_read32(DMA6_START_ADDR)
+#define bfin_write_DMA6_START_ADDR(val) bfin_write32(DMA6_START_ADDR,val)
+#define bfin_read_DMA6_X_COUNT() bfin_read16(DMA6_X_COUNT)
+#define bfin_write_DMA6_X_COUNT(val) bfin_write16(DMA6_X_COUNT,val)
+#define bfin_read_DMA6_Y_COUNT() bfin_read16(DMA6_Y_COUNT)
+#define bfin_write_DMA6_Y_COUNT(val) bfin_write16(DMA6_Y_COUNT,val)
+#define bfin_read_DMA6_X_MODIFY() bfin_read16(DMA6_X_MODIFY)
+#define bfin_write_DMA6_X_MODIFY(val) bfin_write16(DMA6_X_MODIFY,val)
+#define bfin_read_DMA6_Y_MODIFY() bfin_read16(DMA6_Y_MODIFY)
+#define bfin_write_DMA6_Y_MODIFY(val) bfin_write16(DMA6_Y_MODIFY,val)
+#define bfin_read_DMA6_CURR_DESC_PTR() bfin_read32(DMA6_CURR_DESC_PTR)
+#define bfin_write_DMA6_CURR_DESC_PTR(val) bfin_write32(DMA6_CURR_DESC_PTR,val)
+#define bfin_read_DMA6_CURR_ADDR() bfin_read32(DMA6_CURR_ADDR)
+#define bfin_write_DMA6_CURR_ADDR(val) bfin_write32(DMA6_CURR_ADDR,val)
+#define bfin_read_DMA6_CURR_X_COUNT() bfin_read16(DMA6_CURR_X_COUNT)
+#define bfin_write_DMA6_CURR_X_COUNT(val) bfin_write16(DMA6_CURR_X_COUNT,val)
+#define bfin_read_DMA6_CURR_Y_COUNT() bfin_read16(DMA6_CURR_Y_COUNT)
+#define bfin_write_DMA6_CURR_Y_COUNT(val) bfin_write16(DMA6_CURR_Y_COUNT,val)
+#define bfin_read_DMA6_IRQ_STATUS() bfin_read16(DMA6_IRQ_STATUS)
+#define bfin_write_DMA6_IRQ_STATUS(val) bfin_write16(DMA6_IRQ_STATUS,val)
+#define bfin_read_DMA6_PERIPHERAL_MAP() bfin_read16(DMA6_PERIPHERAL_MAP)
+#define bfin_write_DMA6_PERIPHERAL_MAP(val) bfin_write16(DMA6_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA7_CONFIG() bfin_read16(DMA7_CONFIG)
+#define bfin_write_DMA7_CONFIG(val) bfin_write16(DMA7_CONFIG,val)
+#define bfin_read_DMA7_NEXT_DESC_PTR() bfin_read32(DMA7_NEXT_DESC_PTR)
+#define bfin_write_DMA7_NEXT_DESC_PTR(val) bfin_write32(DMA7_NEXT_DESC_PTR,val)
+#define bfin_read_DMA7_START_ADDR() bfin_read32(DMA7_START_ADDR)
+#define bfin_write_DMA7_START_ADDR(val) bfin_write32(DMA7_START_ADDR,val)
+#define bfin_read_DMA7_X_COUNT() bfin_read16(DMA7_X_COUNT)
+#define bfin_write_DMA7_X_COUNT(val) bfin_write16(DMA7_X_COUNT,val)
+#define bfin_read_DMA7_Y_COUNT() bfin_read16(DMA7_Y_COUNT)
+#define bfin_write_DMA7_Y_COUNT(val) bfin_write16(DMA7_Y_COUNT,val)
+#define bfin_read_DMA7_X_MODIFY() bfin_read16(DMA7_X_MODIFY)
+#define bfin_write_DMA7_X_MODIFY(val) bfin_write16(DMA7_X_MODIFY,val)
+#define bfin_read_DMA7_Y_MODIFY() bfin_read16(DMA7_Y_MODIFY)
+#define bfin_write_DMA7_Y_MODIFY(val) bfin_write16(DMA7_Y_MODIFY,val)
+#define bfin_read_DMA7_CURR_DESC_PTR() bfin_read32(DMA7_CURR_DESC_PTR)
+#define bfin_write_DMA7_CURR_DESC_PTR(val) bfin_write32(DMA7_CURR_DESC_PTR,val)
+#define bfin_read_DMA7_CURR_ADDR() bfin_read32(DMA7_CURR_ADDR)
+#define bfin_write_DMA7_CURR_ADDR(val) bfin_write32(DMA7_CURR_ADDR,val)
+#define bfin_read_DMA7_CURR_X_COUNT() bfin_read16(DMA7_CURR_X_COUNT)
+#define bfin_write_DMA7_CURR_X_COUNT(val) bfin_write16(DMA7_CURR_X_COUNT,val)
+#define bfin_read_DMA7_CURR_Y_COUNT() bfin_read16(DMA7_CURR_Y_COUNT)
+#define bfin_write_DMA7_CURR_Y_COUNT(val) bfin_write16(DMA7_CURR_Y_COUNT,val)
+#define bfin_read_DMA7_IRQ_STATUS() bfin_read16(DMA7_IRQ_STATUS)
+#define bfin_write_DMA7_IRQ_STATUS(val) bfin_write16(DMA7_IRQ_STATUS,val)
+#define bfin_read_DMA7_PERIPHERAL_MAP() bfin_read16(DMA7_PERIPHERAL_MAP)
+#define bfin_write_DMA7_PERIPHERAL_MAP(val) bfin_write16(DMA7_PERIPHERAL_MAP,val)
+
+#define bfin_read_MDMA_D1_CONFIG() bfin_read16(MDMA_D1_CONFIG)
+#define bfin_write_MDMA_D1_CONFIG(val) bfin_write16(MDMA_D1_CONFIG,val)
+#define bfin_read_MDMA_D1_NEXT_DESC_PTR() bfin_read32(MDMA_D1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA_D1_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_D1_START_ADDR() bfin_read32(MDMA_D1_START_ADDR)
+#define bfin_write_MDMA_D1_START_ADDR(val) bfin_write32(MDMA_D1_START_ADDR,val)
+#define bfin_read_MDMA_D1_X_COUNT() bfin_read16(MDMA_D1_X_COUNT)
+#define bfin_write_MDMA_D1_X_COUNT(val) bfin_write16(MDMA_D1_X_COUNT,val)
+#define bfin_read_MDMA_D1_Y_COUNT() bfin_read16(MDMA_D1_Y_COUNT)
+#define bfin_write_MDMA_D1_Y_COUNT(val) bfin_write16(MDMA_D1_Y_COUNT,val)
+#define bfin_read_MDMA_D1_X_MODIFY() bfin_read16(MDMA_D1_X_MODIFY)
+#define bfin_write_MDMA_D1_X_MODIFY(val) bfin_write16(MDMA_D1_X_MODIFY,val)
+#define bfin_read_MDMA_D1_Y_MODIFY() bfin_read16(MDMA_D1_Y_MODIFY)
+#define bfin_write_MDMA_D1_Y_MODIFY(val) bfin_write16(MDMA_D1_Y_MODIFY,val)
+#define bfin_read_MDMA_D1_CURR_DESC_PTR() bfin_read32(MDMA_D1_CURR_DESC_PTR)
+#define bfin_write_MDMA_D1_CURR_DESC_PTR(val) bfin_write32(MDMA_D1_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_D1_CURR_ADDR() bfin_read32(MDMA_D1_CURR_ADDR)
+#define bfin_write_MDMA_D1_CURR_ADDR(val) bfin_write32(MDMA_D1_CURR_ADDR,val)
+#define bfin_read_MDMA_D1_CURR_X_COUNT() bfin_read16(MDMA_D1_CURR_X_COUNT)
+#define bfin_write_MDMA_D1_CURR_X_COUNT(val) bfin_write16(MDMA_D1_CURR_X_COUNT,val)
+#define bfin_read_MDMA_D1_CURR_Y_COUNT() bfin_read16(MDMA_D1_CURR_Y_COUNT)
+#define bfin_write_MDMA_D1_CURR_Y_COUNT(val) bfin_write16(MDMA_D1_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_D1_IRQ_STATUS() bfin_read16(MDMA_D1_IRQ_STATUS)
+#define bfin_write_MDMA_D1_IRQ_STATUS(val) bfin_write16(MDMA_D1_IRQ_STATUS,val)
+#define bfin_read_MDMA_D1_PERIPHERAL_MAP() bfin_read16(MDMA_D1_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA_D1_PERIPHERAL_MAP,val)
+
+#define bfin_read_MDMA_S1_CONFIG() bfin_read16(MDMA_S1_CONFIG)
+#define bfin_write_MDMA_S1_CONFIG(val) bfin_write16(MDMA_S1_CONFIG,val)
+#define bfin_read_MDMA_S1_NEXT_DESC_PTR() bfin_read32(MDMA_S1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA_S1_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_S1_START_ADDR() bfin_read32(MDMA_S1_START_ADDR)
+#define bfin_write_MDMA_S1_START_ADDR(val) bfin_write32(MDMA_S1_START_ADDR,val)
+#define bfin_read_MDMA_S1_X_COUNT() bfin_read16(MDMA_S1_X_COUNT)
+#define bfin_write_MDMA_S1_X_COUNT(val) bfin_write16(MDMA_S1_X_COUNT,val)
+#define bfin_read_MDMA_S1_Y_COUNT() bfin_read16(MDMA_S1_Y_COUNT)
+#define bfin_write_MDMA_S1_Y_COUNT(val) bfin_write16(MDMA_S1_Y_COUNT,val)
+#define bfin_read_MDMA_S1_X_MODIFY() bfin_read16(MDMA_S1_X_MODIFY)
+#define bfin_write_MDMA_S1_X_MODIFY(val) bfin_write16(MDMA_S1_X_MODIFY,val)
+#define bfin_read_MDMA_S1_Y_MODIFY() bfin_read16(MDMA_S1_Y_MODIFY)
+#define bfin_write_MDMA_S1_Y_MODIFY(val) bfin_write16(MDMA_S1_Y_MODIFY,val)
+#define bfin_read_MDMA_S1_CURR_DESC_PTR() bfin_read32(MDMA_S1_CURR_DESC_PTR)
+#define bfin_write_MDMA_S1_CURR_DESC_PTR(val) bfin_write32(MDMA_S1_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_S1_CURR_ADDR() bfin_read32(MDMA_S1_CURR_ADDR)
+#define bfin_write_MDMA_S1_CURR_ADDR(val) bfin_write32(MDMA_S1_CURR_ADDR,val)
+#define bfin_read_MDMA_S1_CURR_X_COUNT() bfin_read16(MDMA_S1_CURR_X_COUNT)
+#define bfin_write_MDMA_S1_CURR_X_COUNT(val) bfin_write16(MDMA_S1_CURR_X_COUNT,val)
+#define bfin_read_MDMA_S1_CURR_Y_COUNT() bfin_read16(MDMA_S1_CURR_Y_COUNT)
+#define bfin_write_MDMA_S1_CURR_Y_COUNT(val) bfin_write16(MDMA_S1_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_S1_IRQ_STATUS() bfin_read16(MDMA_S1_IRQ_STATUS)
+#define bfin_write_MDMA_S1_IRQ_STATUS(val) bfin_write16(MDMA_S1_IRQ_STATUS,val)
+#define bfin_read_MDMA_S1_PERIPHERAL_MAP() bfin_read16(MDMA_S1_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA_S1_PERIPHERAL_MAP,val)
+
+#define bfin_read_MDMA_D0_CONFIG() bfin_read16(MDMA_D0_CONFIG)
+#define bfin_write_MDMA_D0_CONFIG(val) bfin_write16(MDMA_D0_CONFIG,val)
+#define bfin_read_MDMA_D0_NEXT_DESC_PTR() bfin_read32(MDMA_D0_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA_D0_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_D0_START_ADDR() bfin_read32(MDMA_D0_START_ADDR)
+#define bfin_write_MDMA_D0_START_ADDR(val) bfin_write32(MDMA_D0_START_ADDR,val)
+#define bfin_read_MDMA_D0_X_COUNT() bfin_read16(MDMA_D0_X_COUNT)
+#define bfin_write_MDMA_D0_X_COUNT(val) bfin_write16(MDMA_D0_X_COUNT,val)
+#define bfin_read_MDMA_D0_Y_COUNT() bfin_read16(MDMA_D0_Y_COUNT)
+#define bfin_write_MDMA_D0_Y_COUNT(val) bfin_write16(MDMA_D0_Y_COUNT,val)
+#define bfin_read_MDMA_D0_X_MODIFY() bfin_read16(MDMA_D0_X_MODIFY)
+#define bfin_write_MDMA_D0_X_MODIFY(val) bfin_write16(MDMA_D0_X_MODIFY,val)
+#define bfin_read_MDMA_D0_Y_MODIFY() bfin_read16(MDMA_D0_Y_MODIFY)
+#define bfin_write_MDMA_D0_Y_MODIFY(val) bfin_write16(MDMA_D0_Y_MODIFY,val)
+#define bfin_read_MDMA_D0_CURR_DESC_PTR() bfin_read32(MDMA_D0_CURR_DESC_PTR)
+#define bfin_write_MDMA_D0_CURR_DESC_PTR(val) bfin_write32(MDMA_D0_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_D0_CURR_ADDR() bfin_read32(MDMA_D0_CURR_ADDR)
+#define bfin_write_MDMA_D0_CURR_ADDR(val) bfin_write32(MDMA_D0_CURR_ADDR,val)
+#define bfin_read_MDMA_D0_CURR_X_COUNT() bfin_read16(MDMA_D0_CURR_X_COUNT)
+#define bfin_write_MDMA_D0_CURR_X_COUNT(val) bfin_write16(MDMA_D0_CURR_X_COUNT,val)
+#define bfin_read_MDMA_D0_CURR_Y_COUNT() bfin_read16(MDMA_D0_CURR_Y_COUNT)
+#define bfin_write_MDMA_D0_CURR_Y_COUNT(val) bfin_write16(MDMA_D0_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_D0_IRQ_STATUS() bfin_read16(MDMA_D0_IRQ_STATUS)
+#define bfin_write_MDMA_D0_IRQ_STATUS(val) bfin_write16(MDMA_D0_IRQ_STATUS,val)
+#define bfin_read_MDMA_D0_PERIPHERAL_MAP() bfin_read16(MDMA_D0_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA_D0_PERIPHERAL_MAP,val)
+
+#define bfin_read_MDMA_S0_CONFIG() bfin_read16(MDMA_S0_CONFIG)
+#define bfin_write_MDMA_S0_CONFIG(val) bfin_write16(MDMA_S0_CONFIG,val)
+#define bfin_read_MDMA_S0_NEXT_DESC_PTR() bfin_read32(MDMA_S0_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA_S0_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_S0_START_ADDR() bfin_read32(MDMA_S0_START_ADDR)
+#define bfin_write_MDMA_S0_START_ADDR(val) bfin_write32(MDMA_S0_START_ADDR,val)
+#define bfin_read_MDMA_S0_X_COUNT() bfin_read16(MDMA_S0_X_COUNT)
+#define bfin_write_MDMA_S0_X_COUNT(val) bfin_write16(MDMA_S0_X_COUNT,val)
+#define bfin_read_MDMA_S0_Y_COUNT() bfin_read16(MDMA_S0_Y_COUNT)
+#define bfin_write_MDMA_S0_Y_COUNT(val) bfin_write16(MDMA_S0_Y_COUNT,val)
+#define bfin_read_MDMA_S0_X_MODIFY() bfin_read16(MDMA_S0_X_MODIFY)
+#define bfin_write_MDMA_S0_X_MODIFY(val) bfin_write16(MDMA_S0_X_MODIFY,val)
+#define bfin_read_MDMA_S0_Y_MODIFY() bfin_read16(MDMA_S0_Y_MODIFY)
+#define bfin_write_MDMA_S0_Y_MODIFY(val) bfin_write16(MDMA_S0_Y_MODIFY,val)
+#define bfin_read_MDMA_S0_CURR_DESC_PTR() bfin_read32(MDMA_S0_CURR_DESC_PTR)
+#define bfin_write_MDMA_S0_CURR_DESC_PTR(val) bfin_write32(MDMA_S0_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_S0_CURR_ADDR() bfin_read32(MDMA_S0_CURR_ADDR)
+#define bfin_write_MDMA_S0_CURR_ADDR(val) bfin_write32(MDMA_S0_CURR_ADDR,val)
+#define bfin_read_MDMA_S0_CURR_X_COUNT() bfin_read16(MDMA_S0_CURR_X_COUNT)
+#define bfin_write_MDMA_S0_CURR_X_COUNT(val) bfin_write16(MDMA_S0_CURR_X_COUNT,val)
+#define bfin_read_MDMA_S0_CURR_Y_COUNT() bfin_read16(MDMA_S0_CURR_Y_COUNT)
+#define bfin_write_MDMA_S0_CURR_Y_COUNT(val) bfin_write16(MDMA_S0_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_S0_IRQ_STATUS() bfin_read16(MDMA_S0_IRQ_STATUS)
+#define bfin_write_MDMA_S0_IRQ_STATUS(val) bfin_write16(MDMA_S0_IRQ_STATUS,val)
+#define bfin_read_MDMA_S0_PERIPHERAL_MAP() bfin_read16(MDMA_S0_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA_S0_PERIPHERAL_MAP,val)
+
+/* Aysnchronous Memory Controller - External Bus Interface Unit (0xFFC0 3C00-0xFFC0 3FFF) */
+#define bfin_read_EBIU_AMGCTL() bfin_read16(EBIU_AMGCTL)
+#define bfin_write_EBIU_AMGCTL(val) bfin_write16(EBIU_AMGCTL,val)
+#define bfin_read_EBIU_AMBCTL0() bfin_read32(EBIU_AMBCTL0)
+#define bfin_write_EBIU_AMBCTL0(val) bfin_write32(EBIU_AMBCTL0,val)
+#define bfin_read_EBIU_AMBCTL1() bfin_read32(EBIU_AMBCTL1)
+#define bfin_write_EBIU_AMBCTL1(val) bfin_write32(EBIU_AMBCTL1,val)
+
+/* SDRAM Controller External Bus Interface Unit (0xFFC0 4C00-0xFFC0 4FFF) */
+#define bfin_read_EBIU_SDGCTL() bfin_read32(EBIU_SDGCTL)
+#define bfin_write_EBIU_SDGCTL(val) bfin_write32(EBIU_SDGCTL,val)
+#define bfin_read_EBIU_SDRRC() bfin_read16(EBIU_SDRRC)
+#define bfin_write_EBIU_SDRRC(val) bfin_write16(EBIU_SDRRC,val)
+#define bfin_read_EBIU_SDSTAT() bfin_read16(EBIU_SDSTAT)
+#define bfin_write_EBIU_SDSTAT(val) bfin_write16(EBIU_SDSTAT,val)
+#define bfin_read_EBIU_SDBCTL() bfin_read16(EBIU_SDBCTL)
+#define bfin_write_EBIU_SDBCTL(val) bfin_write16(EBIU_SDBCTL,val)
+
+/* UART Controller */
+#define bfin_read_UART_THR() bfin_read16(UART_THR)
+#define bfin_write_UART_THR(val) bfin_write16(UART_THR,val)
+#define bfin_read_UART_RBR() bfin_read16(UART_RBR)
+#define bfin_write_UART_RBR(val) bfin_write16(UART_RBR,val)
+#define bfin_read_UART_DLL() bfin_read16(UART_DLL)
+#define bfin_write_UART_DLL(val) bfin_write16(UART_DLL,val)
+#define bfin_read_UART_IER() bfin_read16(UART_IER)
+#define bfin_write_UART_IER(val) bfin_write16(UART_IER,val)
+#define bfin_read_UART_DLH() bfin_read16(UART_DLH)
+#define bfin_write_UART_DLH(val) bfin_write16(UART_DLH,val)
+#define bfin_read_UART_IIR() bfin_read16(UART_IIR)
+#define bfin_write_UART_IIR(val) bfin_write16(UART_IIR,val)
+#define bfin_read_UART_LCR() bfin_read16(UART_LCR)
+#define bfin_write_UART_LCR(val) bfin_write16(UART_LCR,val)
+#define bfin_read_UART_MCR() bfin_read16(UART_MCR)
+#define bfin_write_UART_MCR(val) bfin_write16(UART_MCR,val)
+#define bfin_read_UART_LSR() bfin_read16(UART_LSR)
+#define bfin_write_UART_LSR(val) bfin_write16(UART_LSR,val)
+/*
+#define UART_MSR
+*/
+#define bfin_read_UART_SCR() bfin_read16(UART_SCR)
+#define bfin_write_UART_SCR(val) bfin_write16(UART_SCR,val)
+#define bfin_read_UART_GCTL() bfin_read16(UART_GCTL)
+#define bfin_write_UART_GCTL(val) bfin_write16(UART_GCTL,val)
+
+/* SPI Controller */
+#define bfin_read_SPI_CTL() bfin_read16(SPI_CTL)
+#define bfin_write_SPI_CTL(val) bfin_write16(SPI_CTL,val)
+#define bfin_read_SPI_FLG() bfin_read16(SPI_FLG)
+#define bfin_write_SPI_FLG(val) bfin_write16(SPI_FLG,val)
+#define bfin_read_SPI_STAT() bfin_read16(SPI_STAT)
+#define bfin_write_SPI_STAT(val) bfin_write16(SPI_STAT,val)
+#define bfin_read_SPI_TDBR() bfin_read16(SPI_TDBR)
+#define bfin_write_SPI_TDBR(val) bfin_write16(SPI_TDBR,val)
+#define bfin_read_SPI_RDBR() bfin_read16(SPI_RDBR)
+#define bfin_write_SPI_RDBR(val) bfin_write16(SPI_RDBR,val)
+#define bfin_read_SPI_BAUD() bfin_read16(SPI_BAUD)
+#define bfin_write_SPI_BAUD(val) bfin_write16(SPI_BAUD,val)
+#define bfin_read_SPI_SHADOW() bfin_read16(SPI_SHADOW)
+#define bfin_write_SPI_SHADOW(val) bfin_write16(SPI_SHADOW,val)
+
+/* TIMER 0, 1, 2 Registers */
+#define bfin_read_TIMER0_CONFIG() bfin_read16(TIMER0_CONFIG)
+#define bfin_write_TIMER0_CONFIG(val) bfin_write16(TIMER0_CONFIG,val)
+#define bfin_read_TIMER0_COUNTER() bfin_read32(TIMER0_COUNTER)
+#define bfin_write_TIMER0_COUNTER(val) bfin_write32(TIMER0_COUNTER,val)
+#define bfin_read_TIMER0_PERIOD() bfin_read32(TIMER0_PERIOD)
+#define bfin_write_TIMER0_PERIOD(val) bfin_write32(TIMER0_PERIOD,val)
+#define bfin_read_TIMER0_WIDTH() bfin_read32(TIMER0_WIDTH)
+#define bfin_write_TIMER0_WIDTH(val) bfin_write32(TIMER0_WIDTH,val)
+
+#define bfin_read_TIMER1_CONFIG() bfin_read16(TIMER1_CONFIG)
+#define bfin_write_TIMER1_CONFIG(val) bfin_write16(TIMER1_CONFIG,val)
+#define bfin_read_TIMER1_COUNTER() bfin_read32(TIMER1_COUNTER)
+#define bfin_write_TIMER1_COUNTER(val) bfin_write32(TIMER1_COUNTER,val)
+#define bfin_read_TIMER1_PERIOD() bfin_read32(TIMER1_PERIOD)
+#define bfin_write_TIMER1_PERIOD(val) bfin_write32(TIMER1_PERIOD,val)
+#define bfin_read_TIMER1_WIDTH() bfin_read32(TIMER1_WIDTH)
+#define bfin_write_TIMER1_WIDTH(val) bfin_write32(TIMER1_WIDTH,val)
+
+#define bfin_read_TIMER2_CONFIG() bfin_read16(TIMER2_CONFIG)
+#define bfin_write_TIMER2_CONFIG(val) bfin_write16(TIMER2_CONFIG,val)
+#define bfin_read_TIMER2_COUNTER() bfin_read32(TIMER2_COUNTER)
+#define bfin_write_TIMER2_COUNTER(val) bfin_write32(TIMER2_COUNTER,val)
+#define bfin_read_TIMER2_PERIOD() bfin_read32(TIMER2_PERIOD)
+#define bfin_write_TIMER2_PERIOD(val) bfin_write32(TIMER2_PERIOD,val)
+#define bfin_read_TIMER2_WIDTH() bfin_read32(TIMER2_WIDTH)
+#define bfin_write_TIMER2_WIDTH(val) bfin_write32(TIMER2_WIDTH,val)
+
+#define bfin_read_TIMER_ENABLE() bfin_read16(TIMER_ENABLE)
+#define bfin_write_TIMER_ENABLE(val) bfin_write16(TIMER_ENABLE,val)
+#define bfin_read_TIMER_DISABLE() bfin_read16(TIMER_DISABLE)
+#define bfin_write_TIMER_DISABLE(val) bfin_write16(TIMER_DISABLE,val)
+#define bfin_read_TIMER_STATUS() bfin_read16(TIMER_STATUS)
+#define bfin_write_TIMER_STATUS(val) bfin_write16(TIMER_STATUS,val)
+
+/* SPORT0 Controller */
+#define bfin_read_SPORT0_TCR1() bfin_read16(SPORT0_TCR1)
+#define bfin_write_SPORT0_TCR1(val) bfin_write16(SPORT0_TCR1,val)
+#define bfin_read_SPORT0_TCR2() bfin_read16(SPORT0_TCR2)
+#define bfin_write_SPORT0_TCR2(val) bfin_write16(SPORT0_TCR2,val)
+#define bfin_read_SPORT0_TCLKDIV() bfin_read16(SPORT0_TCLKDIV)
+#define bfin_write_SPORT0_TCLKDIV(val) bfin_write16(SPORT0_TCLKDIV,val)
+#define bfin_read_SPORT0_TFSDIV() bfin_read16(SPORT0_TFSDIV)
+#define bfin_write_SPORT0_TFSDIV(val) bfin_write16(SPORT0_TFSDIV,val)
+#define bfin_read_SPORT0_TX() bfin_read32(SPORT0_TX)
+#define bfin_write_SPORT0_TX(val) bfin_write32(SPORT0_TX,val)
+#define bfin_read_SPORT0_RX() bfin_read32(SPORT0_RX)
+#define bfin_write_SPORT0_RX(val) bfin_write32(SPORT0_RX,val)
+#define bfin_read_SPORT0_TX32() bfin_read32(SPORT0_TX)
+#define bfin_write_SPORT0_TX32(val) bfin_write32(SPORT0_TX,val)
+#define bfin_read_SPORT0_RX32() bfin_read32(SPORT0_RX)
+#define bfin_write_SPORT0_RX32(val) bfin_write32(SPORT0_RX,val)
+#define bfin_read_SPORT0_TX16() bfin_read16(SPORT0_TX)
+#define bfin_write_SPORT0_TX16(val) bfin_write16(SPORT0_TX,val)
+#define bfin_read_SPORT0_RX16() bfin_read16(SPORT0_RX)
+#define bfin_write_SPORT0_RX16(val) bfin_write16(SPORT0_RX,val)
+#define bfin_read_SPORT0_RCR1() bfin_read16(SPORT0_RCR1)
+#define bfin_write_SPORT0_RCR1(val) bfin_write16(SPORT0_RCR1,val)
+#define bfin_read_SPORT0_RCR2() bfin_read16(SPORT0_RCR2)
+#define bfin_write_SPORT0_RCR2(val) bfin_write16(SPORT0_RCR2,val)
+#define bfin_read_SPORT0_RCLKDIV() bfin_read16(SPORT0_RCLKDIV)
+#define bfin_write_SPORT0_RCLKDIV(val) bfin_write16(SPORT0_RCLKDIV,val)
+#define bfin_read_SPORT0_RFSDIV() bfin_read16(SPORT0_RFSDIV)
+#define bfin_write_SPORT0_RFSDIV(val) bfin_write16(SPORT0_RFSDIV,val)
+#define bfin_read_SPORT0_STAT() bfin_read16(SPORT0_STAT)
+#define bfin_write_SPORT0_STAT(val) bfin_write16(SPORT0_STAT,val)
+#define bfin_read_SPORT0_CHNL() bfin_read16(SPORT0_CHNL)
+#define bfin_write_SPORT0_CHNL(val) bfin_write16(SPORT0_CHNL,val)
+#define bfin_read_SPORT0_MCMC1() bfin_read16(SPORT0_MCMC1)
+#define bfin_write_SPORT0_MCMC1(val) bfin_write16(SPORT0_MCMC1,val)
+#define bfin_read_SPORT0_MCMC2() bfin_read16(SPORT0_MCMC2)
+#define bfin_write_SPORT0_MCMC2(val) bfin_write16(SPORT0_MCMC2,val)
+#define bfin_read_SPORT0_MTCS0() bfin_read32(SPORT0_MTCS0)
+#define bfin_write_SPORT0_MTCS0(val) bfin_write32(SPORT0_MTCS0,val)
+#define bfin_read_SPORT0_MTCS1() bfin_read32(SPORT0_MTCS1)
+#define bfin_write_SPORT0_MTCS1(val) bfin_write32(SPORT0_MTCS1,val)
+#define bfin_read_SPORT0_MTCS2() bfin_read32(SPORT0_MTCS2)
+#define bfin_write_SPORT0_MTCS2(val) bfin_write32(SPORT0_MTCS2,val)
+#define bfin_read_SPORT0_MTCS3() bfin_read32(SPORT0_MTCS3)
+#define bfin_write_SPORT0_MTCS3(val) bfin_write32(SPORT0_MTCS3,val)
+#define bfin_read_SPORT0_MRCS0() bfin_read32(SPORT0_MRCS0)
+#define bfin_write_SPORT0_MRCS0(val) bfin_write32(SPORT0_MRCS0,val)
+#define bfin_read_SPORT0_MRCS1() bfin_read32(SPORT0_MRCS1)
+#define bfin_write_SPORT0_MRCS1(val) bfin_write32(SPORT0_MRCS1,val)
+#define bfin_read_SPORT0_MRCS2() bfin_read32(SPORT0_MRCS2)
+#define bfin_write_SPORT0_MRCS2(val) bfin_write32(SPORT0_MRCS2,val)
+#define bfin_read_SPORT0_MRCS3() bfin_read32(SPORT0_MRCS3)
+#define bfin_write_SPORT0_MRCS3(val) bfin_write32(SPORT0_MRCS3,val)
+
+/* SPORT1 Controller */
+#define bfin_read_SPORT1_TCR1() bfin_read16(SPORT1_TCR1)
+#define bfin_write_SPORT1_TCR1(val) bfin_write16(SPORT1_TCR1,val)
+#define bfin_read_SPORT1_TCR2() bfin_read16(SPORT1_TCR2)
+#define bfin_write_SPORT1_TCR2(val) bfin_write16(SPORT1_TCR2,val)
+#define bfin_read_SPORT1_TCLKDIV() bfin_read16(SPORT1_TCLKDIV)
+#define bfin_write_SPORT1_TCLKDIV(val) bfin_write16(SPORT1_TCLKDIV,val)
+#define bfin_read_SPORT1_TFSDIV() bfin_read16(SPORT1_TFSDIV)
+#define bfin_write_SPORT1_TFSDIV(val) bfin_write16(SPORT1_TFSDIV,val)
+#define bfin_read_SPORT1_TX() bfin_read32(SPORT1_TX)
+#define bfin_write_SPORT1_TX(val) bfin_write32(SPORT1_TX,val)
+#define bfin_read_SPORT1_RX() bfin_read32(SPORT1_RX)
+#define bfin_write_SPORT1_RX(val) bfin_write32(SPORT1_RX,val)
+#define bfin_read_SPORT1_TX32() bfin_read32(SPORT1_TX)
+#define bfin_write_SPORT1_TX32(val) bfin_write32(SPORT1_TX,val)
+#define bfin_read_SPORT1_RX32() bfin_read32(SPORT1_RX)
+#define bfin_write_SPORT1_RX32(val) bfin_write32(SPORT1_RX,val)
+#define bfin_read_SPORT1_TX16() bfin_read16(SPORT1_TX)
+#define bfin_write_SPORT1_TX16(val) bfin_write16(SPORT1_TX,val)
+#define bfin_read_SPORT1_RX16() bfin_read16(SPORT1_RX)
+#define bfin_write_SPORT1_RX16(val) bfin_write16(SPORT1_RX,val)
+#define bfin_read_SPORT1_RCR1() bfin_read16(SPORT1_RCR1)
+#define bfin_write_SPORT1_RCR1(val) bfin_write16(SPORT1_RCR1,val)
+#define bfin_read_SPORT1_RCR2() bfin_read16(SPORT1_RCR2)
+#define bfin_write_SPORT1_RCR2(val) bfin_write16(SPORT1_RCR2,val)
+#define bfin_read_SPORT1_RCLKDIV() bfin_read16(SPORT1_RCLKDIV)
+#define bfin_write_SPORT1_RCLKDIV(val) bfin_write16(SPORT1_RCLKDIV,val)
+#define bfin_read_SPORT1_RFSDIV() bfin_read16(SPORT1_RFSDIV)
+#define bfin_write_SPORT1_RFSDIV(val) bfin_write16(SPORT1_RFSDIV,val)
+#define bfin_read_SPORT1_STAT() bfin_read16(SPORT1_STAT)
+#define bfin_write_SPORT1_STAT(val) bfin_write16(SPORT1_STAT,val)
+#define bfin_read_SPORT1_CHNL() bfin_read16(SPORT1_CHNL)
+#define bfin_write_SPORT1_CHNL(val) bfin_write16(SPORT1_CHNL,val)
+#define bfin_read_SPORT1_MCMC1() bfin_read16(SPORT1_MCMC1)
+#define bfin_write_SPORT1_MCMC1(val) bfin_write16(SPORT1_MCMC1,val)
+#define bfin_read_SPORT1_MCMC2() bfin_read16(SPORT1_MCMC2)
+#define bfin_write_SPORT1_MCMC2(val) bfin_write16(SPORT1_MCMC2,val)
+#define bfin_read_SPORT1_MTCS0() bfin_read32(SPORT1_MTCS0)
+#define bfin_write_SPORT1_MTCS0(val) bfin_write32(SPORT1_MTCS0,val)
+#define bfin_read_SPORT1_MTCS1() bfin_read32(SPORT1_MTCS1)
+#define bfin_write_SPORT1_MTCS1(val) bfin_write32(SPORT1_MTCS1,val)
+#define bfin_read_SPORT1_MTCS2() bfin_read32(SPORT1_MTCS2)
+#define bfin_write_SPORT1_MTCS2(val) bfin_write32(SPORT1_MTCS2,val)
+#define bfin_read_SPORT1_MTCS3() bfin_read32(SPORT1_MTCS3)
+#define bfin_write_SPORT1_MTCS3(val) bfin_write32(SPORT1_MTCS3,val)
+#define bfin_read_SPORT1_MRCS0() bfin_read32(SPORT1_MRCS0)
+#define bfin_write_SPORT1_MRCS0(val) bfin_write32(SPORT1_MRCS0,val)
+#define bfin_read_SPORT1_MRCS1() bfin_read32(SPORT1_MRCS1)
+#define bfin_write_SPORT1_MRCS1(val) bfin_write32(SPORT1_MRCS1,val)
+#define bfin_read_SPORT1_MRCS2() bfin_read32(SPORT1_MRCS2)
+#define bfin_write_SPORT1_MRCS2(val) bfin_write32(SPORT1_MRCS2,val)
+#define bfin_read_SPORT1_MRCS3() bfin_read32(SPORT1_MRCS3)
+#define bfin_write_SPORT1_MRCS3(val) bfin_write32(SPORT1_MRCS3,val)
+
+/* Parallel Peripheral Interface (PPI) */
+#define bfin_read_PPI_CONTROL() bfin_read16(PPI_CONTROL)
+#define bfin_write_PPI_CONTROL(val) bfin_write16(PPI_CONTROL,val)
+#define bfin_read_PPI_STATUS() bfin_read16(PPI_STATUS)
+#define bfin_write_PPI_STATUS(val) bfin_write16(PPI_STATUS,val)
+#define bfin_clear_PPI_STATUS() bfin_read_PPI_STATUS()
+#define bfin_read_PPI_DELAY() bfin_read16(PPI_DELAY)
+#define bfin_write_PPI_DELAY(val) bfin_write16(PPI_DELAY,val)
+#define bfin_read_PPI_COUNT() bfin_read16(PPI_COUNT)
+#define bfin_write_PPI_COUNT(val) bfin_write16(PPI_COUNT,val)
+#define bfin_read_PPI_FRAME() bfin_read16(PPI_FRAME)
+#define bfin_write_PPI_FRAME(val) bfin_write16(PPI_FRAME,val)
+
+#endif /* _CDEF_BF532_H */
diff --git a/include/asm-blackfin/mach-bf533/defBF532.h b/include/asm-blackfin/mach-bf533/defBF532.h
new file mode 100644
index 0000000..b240a08
--- /dev/null
+++ b/include/asm-blackfin/mach-bf533/defBF532.h
@@ -0,0 +1,1175 @@
+/************************************************************************
+ *
+ * This file is subject to the terms and conditions of the GNU Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Non-GPL License also available as part of VisualDSP++
+ * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html
+ *
+ * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved
+ *
+ * This file under source code control, please send bugs or changes to:
+ * dsptools.support@analog.com
+ *
+ ************************************************************************/
+/*
+ * File: include/asm-blackfin/mach-bf533/defBF532.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/* SYSTEM & MM REGISTER BIT & ADDRESS DEFINITIONS FOR ADSP-BF532 */
+
+#ifndef _DEF_BF532_H
+#define _DEF_BF532_H
+/*
+#if !defined(__ADSPLPBLACKFIN__)
+#warning defBF532.h should only be included for 532 compatible chips
+#endif
+*/
+/* include all Core registers and bit definitions */
+#include <asm/mach-common/def_LPBlackfin.h>
+
+/*********************************************************************************** */
+/* System MMR Register Map */
+/*********************************************************************************** */
+/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */
+
+#define PLL_CTL 0xFFC00000 /* PLL Control register (16-bit) */
+#define PLL_DIV 0xFFC00004 /* PLL Divide Register (16-bit) */
+#define VR_CTL 0xFFC00008 /* Voltage Regulator Control Register (16-bit) */
+#define PLL_STAT 0xFFC0000C /* PLL Status register (16-bit) */
+#define PLL_LOCKCNT 0xFFC00010 /* PLL Lock Count register (16-bit) */
+#define CHIPID 0xFFC00014 /* Chip ID Register */
+#define SWRST 0xFFC00100 /* Software Reset Register (16-bit) */
+#define SYSCR 0xFFC00104 /* System Configuration registe */
+
+/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
+#define SIC_RVECT 0xFFC00108 /* Interrupt Reset Vector Address Register */
+#define SIC_IMASK 0xFFC0010C /* Interrupt Mask Register */
+#define SIC_IAR0 0xFFC00110 /* Interrupt Assignment Register 0 */
+#define SIC_IAR1 0xFFC00114 /* Interrupt Assignment Register 1 */
+#define SIC_IAR2 0xFFC00118 /* Interrupt Assignment Register 2 */
+#define SIC_ISR 0xFFC00120 /* Interrupt Status Register */
+#define SIC_IWR 0xFFC00124 /* Interrupt Wakeup Register */
+
+/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */
+#define WDOG_CTL 0xFFC00200 /* Watchdog Control Register */
+#define WDOG_CNT 0xFFC00204 /* Watchdog Count Register */
+#define WDOG_STAT 0xFFC00208 /* Watchdog Status Register */
+
+/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */
+#define RTC_STAT 0xFFC00300 /* RTC Status Register */
+#define RTC_ICTL 0xFFC00304 /* RTC Interrupt Control Register */
+#define RTC_ISTAT 0xFFC00308 /* RTC Interrupt Status Register */
+#define RTC_SWCNT 0xFFC0030C /* RTC Stopwatch Count Register */
+#define RTC_ALARM 0xFFC00310 /* RTC Alarm Time Register */
+#define RTC_FAST 0xFFC00314 /* RTC Prescaler Enable Register */
+#define RTC_PREN 0xFFC00314 /* RTC Prescaler Enable Register (alternate macro) */
+
+/* UART Controller (0xFFC00400 - 0xFFC004FF) */
+#define UART_THR 0xFFC00400 /* Transmit Holding register */
+#define UART_RBR 0xFFC00400 /* Receive Buffer register */
+#define UART_DLL 0xFFC00400 /* Divisor Latch (Low-Byte) */
+#define UART_IER 0xFFC00404 /* Interrupt Enable Register */
+#define UART_DLH 0xFFC00404 /* Divisor Latch (High-Byte) */
+#define UART_IIR 0xFFC00408 /* Interrupt Identification Register */
+#define UART_LCR 0xFFC0040C /* Line Control Register */
+#define UART_MCR 0xFFC00410 /* Modem Control Register */
+#define UART_LSR 0xFFC00414 /* Line Status Register */
+#if 0
+#define UART_MSR 0xFFC00418 /* Modem Status Register (UNUSED in ADSP-BF532) */
+#endif
+#define UART_SCR 0xFFC0041C /* SCR Scratch Register */
+#define UART_GCTL 0xFFC00424 /* Global Control Register */
+
+/* SPI Controller (0xFFC00500 - 0xFFC005FF) */
+#define SPI_CTL 0xFFC00500 /* SPI Control Register */
+#define SPI_FLG 0xFFC00504 /* SPI Flag register */
+#define SPI_STAT 0xFFC00508 /* SPI Status register */
+#define SPI_TDBR 0xFFC0050C /* SPI Transmit Data Buffer Register */
+#define SPI_RDBR 0xFFC00510 /* SPI Receive Data Buffer Register */
+#define SPI_BAUD 0xFFC00514 /* SPI Baud rate Register */
+#define SPI_SHADOW 0xFFC00518 /* SPI_RDBR Shadow Register */
+
+/* TIMER 0, 1, 2 Registers (0xFFC00600 - 0xFFC006FF) */
+
+#define TIMER0_CONFIG 0xFFC00600 /* Timer 0 Configuration Register */
+#define TIMER0_COUNTER 0xFFC00604 /* Timer 0 Counter Register */
+#define TIMER0_PERIOD 0xFFC00608 /* Timer 0 Period Register */
+#define TIMER0_WIDTH 0xFFC0060C /* Timer 0 Width Register */
+
+#define TIMER1_CONFIG 0xFFC00610 /* Timer 1 Configuration Register */
+#define TIMER1_COUNTER 0xFFC00614 /* Timer 1 Counter Register */
+#define TIMER1_PERIOD 0xFFC00618 /* Timer 1 Period Register */
+#define TIMER1_WIDTH 0xFFC0061C /* Timer 1 Width Register */
+
+#define TIMER2_CONFIG 0xFFC00620 /* Timer 2 Configuration Register */
+#define TIMER2_COUNTER 0xFFC00624 /* Timer 2 Counter Register */
+#define TIMER2_PERIOD 0xFFC00628 /* Timer 2 Period Register */
+#define TIMER2_WIDTH 0xFFC0062C /* Timer 2 Width Register */
+
+#define TIMER_ENABLE 0xFFC00640 /* Timer Enable Register */
+#define TIMER_DISABLE 0xFFC00644 /* Timer Disable Register */
+#define TIMER_STATUS 0xFFC00648 /* Timer Status Register */
+
+/* General Purpose IO (0xFFC00700 - 0xFFC007FF) */
+
+#define FIO_FLAG_D 0xFFC00700 /* Flag Mask to directly specify state of pins */
+#define FIO_FLAG_C 0xFFC00704 /* Peripheral Interrupt Flag Register (clear) */
+#define FIO_FLAG_S 0xFFC00708 /* Peripheral Interrupt Flag Register (set) */
+#define FIO_FLAG_T 0xFFC0070C /* Flag Mask to directly toggle state of pins */
+#define FIO_MASKA_D 0xFFC00710 /* Flag Mask Interrupt A Register (set directly) */
+#define FIO_MASKA_C 0xFFC00714 /* Flag Mask Interrupt A Register (clear) */
+#define FIO_MASKA_S 0xFFC00718 /* Flag Mask Interrupt A Register (set) */
+#define FIO_MASKA_T 0xFFC0071C /* Flag Mask Interrupt A Register (toggle) */
+#define FIO_MASKB_D 0xFFC00720 /* Flag Mask Interrupt B Register (set directly) */
+#define FIO_MASKB_C 0xFFC00724 /* Flag Mask Interrupt B Register (clear) */
+#define FIO_MASKB_S 0xFFC00728 /* Flag Mask Interrupt B Register (set) */
+#define FIO_MASKB_T 0xFFC0072C /* Flag Mask Interrupt B Register (toggle) */
+#define FIO_DIR 0xFFC00730 /* Peripheral Flag Direction Register */
+#define FIO_POLAR 0xFFC00734 /* Flag Source Polarity Register */
+#define FIO_EDGE 0xFFC00738 /* Flag Source Sensitivity Register */
+#define FIO_BOTH 0xFFC0073C /* Flag Set on BOTH Edges Register */
+#define FIO_INEN 0xFFC00740 /* Flag Input Enable Register */
+
+/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
+#define SPORT0_TCR1 0xFFC00800 /* SPORT0 Transmit Configuration 1 Register */
+#define SPORT0_TCR2 0xFFC00804 /* SPORT0 Transmit Configuration 2 Register */
+#define SPORT0_TCLKDIV 0xFFC00808 /* SPORT0 Transmit Clock Divider */
+#define SPORT0_TFSDIV 0xFFC0080C /* SPORT0 Transmit Frame Sync Divider */
+#define SPORT0_TX 0xFFC00810 /* SPORT0 TX Data Register */
+#define SPORT0_RX 0xFFC00818 /* SPORT0 RX Data Register */
+#define SPORT0_RCR1 0xFFC00820 /* SPORT0 Transmit Configuration 1 Register */
+#define SPORT0_RCR2 0xFFC00824 /* SPORT0 Transmit Configuration 2 Register */
+#define SPORT0_RCLKDIV 0xFFC00828 /* SPORT0 Receive Clock Divider */
+#define SPORT0_RFSDIV 0xFFC0082C /* SPORT0 Receive Frame Sync Divider */
+#define SPORT0_STAT 0xFFC00830 /* SPORT0 Status Register */
+#define SPORT0_CHNL 0xFFC00834 /* SPORT0 Current Channel Register */
+#define SPORT0_MCMC1 0xFFC00838 /* SPORT0 Multi-Channel Configuration Register 1 */
+#define SPORT0_MCMC2 0xFFC0083C /* SPORT0 Multi-Channel Configuration Register 2 */
+#define SPORT0_MTCS0 0xFFC00840 /* SPORT0 Multi-Channel Transmit Select Register 0 */
+#define SPORT0_MTCS1 0xFFC00844 /* SPORT0 Multi-Channel Transmit Select Register 1 */
+#define SPORT0_MTCS2 0xFFC00848 /* SPORT0 Multi-Channel Transmit Select Register 2 */
+#define SPORT0_MTCS3 0xFFC0084C /* SPORT0 Multi-Channel Transmit Select Register 3 */
+#define SPORT0_MRCS0 0xFFC00850 /* SPORT0 Multi-Channel Receive Select Register 0 */
+#define SPORT0_MRCS1 0xFFC00854 /* SPORT0 Multi-Channel Receive Select Register 1 */
+#define SPORT0_MRCS2 0xFFC00858 /* SPORT0 Multi-Channel Receive Select Register 2 */
+#define SPORT0_MRCS3 0xFFC0085C /* SPORT0 Multi-Channel Receive Select Register 3 */
+
+/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
+#define SPORT1_TCR1 0xFFC00900 /* SPORT1 Transmit Configuration 1 Register */
+#define SPORT1_TCR2 0xFFC00904 /* SPORT1 Transmit Configuration 2 Register */
+#define SPORT1_TCLKDIV 0xFFC00908 /* SPORT1 Transmit Clock Divider */
+#define SPORT1_TFSDIV 0xFFC0090C /* SPORT1 Transmit Frame Sync Divider */
+#define SPORT1_TX 0xFFC00910 /* SPORT1 TX Data Register */
+#define SPORT1_RX 0xFFC00918 /* SPORT1 RX Data Register */
+#define SPORT1_RCR1 0xFFC00920 /* SPORT1 Transmit Configuration 1 Register */
+#define SPORT1_RCR2 0xFFC00924 /* SPORT1 Transmit Configuration 2 Register */
+#define SPORT1_RCLKDIV 0xFFC00928 /* SPORT1 Receive Clock Divider */
+#define SPORT1_RFSDIV 0xFFC0092C /* SPORT1 Receive Frame Sync Divider */
+#define SPORT1_STAT 0xFFC00930 /* SPORT1 Status Register */
+#define SPORT1_CHNL 0xFFC00934 /* SPORT1 Current Channel Register */
+#define SPORT1_MCMC1 0xFFC00938 /* SPORT1 Multi-Channel Configuration Register 1 */
+#define SPORT1_MCMC2 0xFFC0093C /* SPORT1 Multi-Channel Configuration Register 2 */
+#define SPORT1_MTCS0 0xFFC00940 /* SPORT1 Multi-Channel Transmit Select Register 0 */
+#define SPORT1_MTCS1 0xFFC00944 /* SPORT1 Multi-Channel Transmit Select Register 1 */
+#define SPORT1_MTCS2 0xFFC00948 /* SPORT1 Multi-Channel Transmit Select Register 2 */
+#define SPORT1_MTCS3 0xFFC0094C /* SPORT1 Multi-Channel Transmit Select Register 3 */
+#define SPORT1_MRCS0 0xFFC00950 /* SPORT1 Multi-Channel Receive Select Register 0 */
+#define SPORT1_MRCS1 0xFFC00954 /* SPORT1 Multi-Channel Receive Select Register 1 */
+#define SPORT1_MRCS2 0xFFC00958 /* SPORT1 Multi-Channel Receive Select Register 2 */
+#define SPORT1_MRCS3 0xFFC0095C /* SPORT1 Multi-Channel Receive Select Register 3 */
+
+/* Asynchronous Memory Controller - External Bus Interface Unit */
+#define EBIU_AMGCTL 0xFFC00A00 /* Asynchronous Memory Global Control Register */
+#define EBIU_AMBCTL0 0xFFC00A04 /* Asynchronous Memory Bank Control Register 0 */
+#define EBIU_AMBCTL1 0xFFC00A08 /* Asynchronous Memory Bank Control Register 1 */
+
+/* SDRAM Controller External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
+
+#define EBIU_SDGCTL 0xFFC00A10 /* SDRAM Global Control Register */
+#define EBIU_SDBCTL 0xFFC00A14 /* SDRAM Bank Control Register */
+#define EBIU_SDRRC 0xFFC00A18 /* SDRAM Refresh Rate Control Register */
+#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */
+
+/* DMA Traffic controls */
+#define DMA_TCPER 0xFFC00B0C /* Traffic Control Periods Register */
+#define DMA_TCCNT 0xFFC00B10 /* Traffic Control Current Counts Register */
+#define DMA_TC_PER 0xFFC00B0C /* Traffic Control Periods Register */
+#define DMA_TC_CNT 0xFFC00B10 /* Traffic Control Current Counts Register */
+
+/* DMA Controller (0xFFC00C00 - 0xFFC00FFF) */
+#define DMA0_CONFIG 0xFFC00C08 /* DMA Channel 0 Configuration Register */
+#define DMA0_NEXT_DESC_PTR 0xFFC00C00 /* DMA Channel 0 Next Descriptor Pointer Register */
+#define DMA0_START_ADDR 0xFFC00C04 /* DMA Channel 0 Start Address Register */
+#define DMA0_X_COUNT 0xFFC00C10 /* DMA Channel 0 X Count Register */
+#define DMA0_Y_COUNT 0xFFC00C18 /* DMA Channel 0 Y Count Register */
+#define DMA0_X_MODIFY 0xFFC00C14 /* DMA Channel 0 X Modify Register */
+#define DMA0_Y_MODIFY 0xFFC00C1C /* DMA Channel 0 Y Modify Register */
+#define DMA0_CURR_DESC_PTR 0xFFC00C20 /* DMA Channel 0 Current Descriptor Pointer Register */
+#define DMA0_CURR_ADDR 0xFFC00C24 /* DMA Channel 0 Current Address Register */
+#define DMA0_CURR_X_COUNT 0xFFC00C30 /* DMA Channel 0 Current X Count Register */
+#define DMA0_CURR_Y_COUNT 0xFFC00C38 /* DMA Channel 0 Current Y Count Register */
+#define DMA0_IRQ_STATUS 0xFFC00C28 /* DMA Channel 0 Interrupt/Status Register */
+#define DMA0_PERIPHERAL_MAP 0xFFC00C2C /* DMA Channel 0 Peripheral Map Register */
+
+#define DMA1_CONFIG 0xFFC00C48 /* DMA Channel 1 Configuration Register */
+#define DMA1_NEXT_DESC_PTR 0xFFC00C40 /* DMA Channel 1 Next Descriptor Pointer Register */
+#define DMA1_START_ADDR 0xFFC00C44 /* DMA Channel 1 Start Address Register */
+#define DMA1_X_COUNT 0xFFC00C50 /* DMA Channel 1 X Count Register */
+#define DMA1_Y_COUNT 0xFFC00C58 /* DMA Channel 1 Y Count Register */
+#define DMA1_X_MODIFY 0xFFC00C54 /* DMA Channel 1 X Modify Register */
+#define DMA1_Y_MODIFY 0xFFC00C5C /* DMA Channel 1 Y Modify Register */
+#define DMA1_CURR_DESC_PTR 0xFFC00C60 /* DMA Channel 1 Current Descriptor Pointer Register */
+#define DMA1_CURR_ADDR 0xFFC00C64 /* DMA Channel 1 Current Address Register */
+#define DMA1_CURR_X_COUNT 0xFFC00C70 /* DMA Channel 1 Current X Count Register */
+#define DMA1_CURR_Y_COUNT 0xFFC00C78 /* DMA Channel 1 Current Y Count Register */
+#define DMA1_IRQ_STATUS 0xFFC00C68 /* DMA Channel 1 Interrupt/Status Register */
+#define DMA1_PERIPHERAL_MAP 0xFFC00C6C /* DMA Channel 1 Peripheral Map Register */
+
+#define DMA2_CONFIG 0xFFC00C88 /* DMA Channel 2 Configuration Register */
+#define DMA2_NEXT_DESC_PTR 0xFFC00C80 /* DMA Channel 2 Next Descriptor Pointer Register */
+#define DMA2_START_ADDR 0xFFC00C84 /* DMA Channel 2 Start Address Register */
+#define DMA2_X_COUNT 0xFFC00C90 /* DMA Channel 2 X Count Register */
+#define DMA2_Y_COUNT 0xFFC00C98 /* DMA Channel 2 Y Count Register */
+#define DMA2_X_MODIFY 0xFFC00C94 /* DMA Channel 2 X Modify Register */
+#define DMA2_Y_MODIFY 0xFFC00C9C /* DMA Channel 2 Y Modify Register */
+#define DMA2_CURR_DESC_PTR 0xFFC00CA0 /* DMA Channel 2 Current Descriptor Pointer Register */
+#define DMA2_CURR_ADDR 0xFFC00CA4 /* DMA Channel 2 Current Address Register */
+#define DMA2_CURR_X_COUNT 0xFFC00CB0 /* DMA Channel 2 Current X Count Register */
+#define DMA2_CURR_Y_COUNT 0xFFC00CB8 /* DMA Channel 2 Current Y Count Register */
+#define DMA2_IRQ_STATUS 0xFFC00CA8 /* DMA Channel 2 Interrupt/Status Register */
+#define DMA2_PERIPHERAL_MAP 0xFFC00CAC /* DMA Channel 2 Peripheral Map Register */
+
+#define DMA3_CONFIG 0xFFC00CC8 /* DMA Channel 3 Configuration Register */
+#define DMA3_NEXT_DESC_PTR 0xFFC00CC0 /* DMA Channel 3 Next Descriptor Pointer Register */
+#define DMA3_START_ADDR 0xFFC00CC4 /* DMA Channel 3 Start Address Register */
+#define DMA3_X_COUNT 0xFFC00CD0 /* DMA Channel 3 X Count Register */
+#define DMA3_Y_COUNT 0xFFC00CD8 /* DMA Channel 3 Y Count Register */
+#define DMA3_X_MODIFY 0xFFC00CD4 /* DMA Channel 3 X Modify Register */
+#define DMA3_Y_MODIFY 0xFFC00CDC /* DMA Channel 3 Y Modify Register */
+#define DMA3_CURR_DESC_PTR 0xFFC00CE0 /* DMA Channel 3 Current Descriptor Pointer Register */
+#define DMA3_CURR_ADDR 0xFFC00CE4 /* DMA Channel 3 Current Address Register */
+#define DMA3_CURR_X_COUNT 0xFFC00CF0 /* DMA Channel 3 Current X Count Register */
+#define DMA3_CURR_Y_COUNT 0xFFC00CF8 /* DMA Channel 3 Current Y Count Register */
+#define DMA3_IRQ_STATUS 0xFFC00CE8 /* DMA Channel 3 Interrupt/Status Register */
+#define DMA3_PERIPHERAL_MAP 0xFFC00CEC /* DMA Channel 3 Peripheral Map Register */
+
+#define DMA4_CONFIG 0xFFC00D08 /* DMA Channel 4 Configuration Register */
+#define DMA4_NEXT_DESC_PTR 0xFFC00D00 /* DMA Channel 4 Next Descriptor Pointer Register */
+#define DMA4_START_ADDR 0xFFC00D04 /* DMA Channel 4 Start Address Register */
+#define DMA4_X_COUNT 0xFFC00D10 /* DMA Channel 4 X Count Register */
+#define DMA4_Y_COUNT 0xFFC00D18 /* DMA Channel 4 Y Count Register */
+#define DMA4_X_MODIFY 0xFFC00D14 /* DMA Channel 4 X Modify Register */
+#define DMA4_Y_MODIFY 0xFFC00D1C /* DMA Channel 4 Y Modify Register */
+#define DMA4_CURR_DESC_PTR 0xFFC00D20 /* DMA Channel 4 Current Descriptor Pointer Register */
+#define DMA4_CURR_ADDR 0xFFC00D24 /* DMA Channel 4 Current Address Register */
+#define DMA4_CURR_X_COUNT 0xFFC00D30 /* DMA Channel 4 Current X Count Register */
+#define DMA4_CURR_Y_COUNT 0xFFC00D38 /* DMA Channel 4 Current Y Count Register */
+#define DMA4_IRQ_STATUS 0xFFC00D28 /* DMA Channel 4 Interrupt/Status Register */
+#define DMA4_PERIPHERAL_MAP 0xFFC00D2C /* DMA Channel 4 Peripheral Map Register */
+
+#define DMA5_CONFIG 0xFFC00D48 /* DMA Channel 5 Configuration Register */
+#define DMA5_NEXT_DESC_PTR 0xFFC00D40 /* DMA Channel 5 Next Descriptor Pointer Register */
+#define DMA5_START_ADDR 0xFFC00D44 /* DMA Channel 5 Start Address Register */
+#define DMA5_X_COUNT 0xFFC00D50 /* DMA Channel 5 X Count Register */
+#define DMA5_Y_COUNT 0xFFC00D58 /* DMA Channel 5 Y Count Register */
+#define DMA5_X_MODIFY 0xFFC00D54 /* DMA Channel 5 X Modify Register */
+#define DMA5_Y_MODIFY 0xFFC00D5C /* DMA Channel 5 Y Modify Register */
+#define DMA5_CURR_DESC_PTR 0xFFC00D60 /* DMA Channel 5 Current Descriptor Pointer Register */
+#define DMA5_CURR_ADDR 0xFFC00D64 /* DMA Channel 5 Current Address Register */
+#define DMA5_CURR_X_COUNT 0xFFC00D70 /* DMA Channel 5 Current X Count Register */
+#define DMA5_CURR_Y_COUNT 0xFFC00D78 /* DMA Channel 5 Current Y Count Register */
+#define DMA5_IRQ_STATUS 0xFFC00D68 /* DMA Channel 5 Interrupt/Status Register */
+#define DMA5_PERIPHERAL_MAP 0xFFC00D6C /* DMA Channel 5 Peripheral Map Register */
+
+#define DMA6_CONFIG 0xFFC00D88 /* DMA Channel 6 Configuration Register */
+#define DMA6_NEXT_DESC_PTR 0xFFC00D80 /* DMA Channel 6 Next Descriptor Pointer Register */
+#define DMA6_START_ADDR 0xFFC00D84 /* DMA Channel 6 Start Address Register */
+#define DMA6_X_COUNT 0xFFC00D90 /* DMA Channel 6 X Count Register */
+#define DMA6_Y_COUNT 0xFFC00D98 /* DMA Channel 6 Y Count Register */
+#define DMA6_X_MODIFY 0xFFC00D94 /* DMA Channel 6 X Modify Register */
+#define DMA6_Y_MODIFY 0xFFC00D9C /* DMA Channel 6 Y Modify Register */
+#define DMA6_CURR_DESC_PTR 0xFFC00DA0 /* DMA Channel 6 Current Descriptor Pointer Register */
+#define DMA6_CURR_ADDR 0xFFC00DA4 /* DMA Channel 6 Current Address Register */
+#define DMA6_CURR_X_COUNT 0xFFC00DB0 /* DMA Channel 6 Current X Count Register */
+#define DMA6_CURR_Y_COUNT 0xFFC00DB8 /* DMA Channel 6 Current Y Count Register */
+#define DMA6_IRQ_STATUS 0xFFC00DA8 /* DMA Channel 6 Interrupt/Status Register */
+#define DMA6_PERIPHERAL_MAP 0xFFC00DAC /* DMA Channel 6 Peripheral Map Register */
+
+#define DMA7_CONFIG 0xFFC00DC8 /* DMA Channel 7 Configuration Register */
+#define DMA7_NEXT_DESC_PTR 0xFFC00DC0 /* DMA Channel 7 Next Descriptor Pointer Register */
+#define DMA7_START_ADDR 0xFFC00DC4 /* DMA Channel 7 Start Address Register */
+#define DMA7_X_COUNT 0xFFC00DD0 /* DMA Channel 7 X Count Register */
+#define DMA7_Y_COUNT 0xFFC00DD8 /* DMA Channel 7 Y Count Register */
+#define DMA7_X_MODIFY 0xFFC00DD4 /* DMA Channel 7 X Modify Register */
+#define DMA7_Y_MODIFY 0xFFC00DDC /* DMA Channel 7 Y Modify Register */
+#define DMA7_CURR_DESC_PTR 0xFFC00DE0 /* DMA Channel 7 Current Descriptor Pointer Register */
+#define DMA7_CURR_ADDR 0xFFC00DE4 /* DMA Channel 7 Current Address Register */
+#define DMA7_CURR_X_COUNT 0xFFC00DF0 /* DMA Channel 7 Current X Count Register */
+#define DMA7_CURR_Y_COUNT 0xFFC00DF8 /* DMA Channel 7 Current Y Count Register */
+#define DMA7_IRQ_STATUS 0xFFC00DE8 /* DMA Channel 7 Interrupt/Status Register */
+#define DMA7_PERIPHERAL_MAP 0xFFC00DEC /* DMA Channel 7 Peripheral Map Register */
+
+#define MDMA_D1_CONFIG 0xFFC00E88 /* MemDMA Stream 1 Destination Configuration Register */
+#define MDMA_D1_NEXT_DESC_PTR 0xFFC00E80 /* MemDMA Stream 1 Destination Next Descriptor Pointer Register */
+#define MDMA_D1_START_ADDR 0xFFC00E84 /* MemDMA Stream 1 Destination Start Address Register */
+#define MDMA_D1_X_COUNT 0xFFC00E90 /* MemDMA Stream 1 Destination X Count Register */
+#define MDMA_D1_Y_COUNT 0xFFC00E98 /* MemDMA Stream 1 Destination Y Count Register */
+#define MDMA_D1_X_MODIFY 0xFFC00E94 /* MemDMA Stream 1 Destination X Modify Register */
+#define MDMA_D1_Y_MODIFY 0xFFC00E9C /* MemDMA Stream 1 Destination Y Modify Register */
+#define MDMA_D1_CURR_DESC_PTR 0xFFC00EA0 /* MemDMA Stream 1 Destination Current Descriptor Pointer Register */
+#define MDMA_D1_CURR_ADDR 0xFFC00EA4 /* MemDMA Stream 1 Destination Current Address Register */
+#define MDMA_D1_CURR_X_COUNT 0xFFC00EB0 /* MemDMA Stream 1 Destination Current X Count Register */
+#define MDMA_D1_CURR_Y_COUNT 0xFFC00EB8 /* MemDMA Stream 1 Destination Current Y Count Register */
+#define MDMA_D1_IRQ_STATUS 0xFFC00EA8 /* MemDMA Stream 1 Destination Interrupt/Status Register */
+#define MDMA_D1_PERIPHERAL_MAP 0xFFC00EAC /* MemDMA Stream 1 Destination Peripheral Map Register */
+
+#define MDMA_S1_CONFIG 0xFFC00EC8 /* MemDMA Stream 1 Source Configuration Register */
+#define MDMA_S1_NEXT_DESC_PTR 0xFFC00EC0 /* MemDMA Stream 1 Source Next Descriptor Pointer Register */
+#define MDMA_S1_START_ADDR 0xFFC00EC4 /* MemDMA Stream 1 Source Start Address Register */
+#define MDMA_S1_X_COUNT 0xFFC00ED0 /* MemDMA Stream 1 Source X Count Register */
+#define MDMA_S1_Y_COUNT 0xFFC00ED8 /* MemDMA Stream 1 Source Y Count Register */
+#define MDMA_S1_X_MODIFY 0xFFC00ED4 /* MemDMA Stream 1 Source X Modify Register */
+#define MDMA_S1_Y_MODIFY 0xFFC00EDC /* MemDMA Stream 1 Source Y Modify Register */
+#define MDMA_S1_CURR_DESC_PTR 0xFFC00EE0 /* MemDMA Stream 1 Source Current Descriptor Pointer Register */
+#define MDMA_S1_CURR_ADDR 0xFFC00EE4 /* MemDMA Stream 1 Source Current Address Register */
+#define MDMA_S1_CURR_X_COUNT 0xFFC00EF0 /* MemDMA Stream 1 Source Current X Count Register */
+#define MDMA_S1_CURR_Y_COUNT 0xFFC00EF8 /* MemDMA Stream 1 Source Current Y Count Register */
+#define MDMA_S1_IRQ_STATUS 0xFFC00EE8 /* MemDMA Stream 1 Source Interrupt/Status Register */
+#define MDMA_S1_PERIPHERAL_MAP 0xFFC00EEC /* MemDMA Stream 1 Source Peripheral Map Register */
+
+#define MDMA_D0_CONFIG 0xFFC00E08 /* MemDMA Stream 0 Destination Configuration Register */
+#define MDMA_D0_NEXT_DESC_PTR 0xFFC00E00 /* MemDMA Stream 0 Destination Next Descriptor Pointer Register */
+#define MDMA_D0_START_ADDR 0xFFC00E04 /* MemDMA Stream 0 Destination Start Address Register */
+#define MDMA_D0_X_COUNT 0xFFC00E10 /* MemDMA Stream 0 Destination X Count Register */
+#define MDMA_D0_Y_COUNT 0xFFC00E18 /* MemDMA Stream 0 Destination Y Count Register */
+#define MDMA_D0_X_MODIFY 0xFFC00E14 /* MemDMA Stream 0 Destination X Modify Register */
+#define MDMA_D0_Y_MODIFY 0xFFC00E1C /* MemDMA Stream 0 Destination Y Modify Register */
+#define MDMA_D0_CURR_DESC_PTR 0xFFC00E20 /* MemDMA Stream 0 Destination Current Descriptor Pointer Register */
+#define MDMA_D0_CURR_ADDR 0xFFC00E24 /* MemDMA Stream 0 Destination Current Address Register */
+#define MDMA_D0_CURR_X_COUNT 0xFFC00E30 /* MemDMA Stream 0 Destination Current X Count Register */
+#define MDMA_D0_CURR_Y_COUNT 0xFFC00E38 /* MemDMA Stream 0 Destination Current Y Count Register */
+#define MDMA_D0_IRQ_STATUS 0xFFC00E28 /* MemDMA Stream 0 Destination Interrupt/Status Register */
+#define MDMA_D0_PERIPHERAL_MAP 0xFFC00E2C /* MemDMA Stream 0 Destination Peripheral Map Register */
+
+#define MDMA_S0_CONFIG 0xFFC00E48 /* MemDMA Stream 0 Source Configuration Register */
+#define MDMA_S0_NEXT_DESC_PTR 0xFFC00E40 /* MemDMA Stream 0 Source Next Descriptor Pointer Register */
+#define MDMA_S0_START_ADDR 0xFFC00E44 /* MemDMA Stream 0 Source Start Address Register */
+#define MDMA_S0_X_COUNT 0xFFC00E50 /* MemDMA Stream 0 Source X Count Register */
+#define MDMA_S0_Y_COUNT 0xFFC00E58 /* MemDMA Stream 0 Source Y Count Register */
+#define MDMA_S0_X_MODIFY 0xFFC00E54 /* MemDMA Stream 0 Source X Modify Register */
+#define MDMA_S0_Y_MODIFY 0xFFC00E5C /* MemDMA Stream 0 Source Y Modify Register */
+#define MDMA_S0_CURR_DESC_PTR 0xFFC00E60 /* MemDMA Stream 0 Source Current Descriptor Pointer Register */
+#define MDMA_S0_CURR_ADDR 0xFFC00E64 /* MemDMA Stream 0 Source Current Address Register */
+#define MDMA_S0_CURR_X_COUNT 0xFFC00E70 /* MemDMA Stream 0 Source Current X Count Register */
+#define MDMA_S0_CURR_Y_COUNT 0xFFC00E78 /* MemDMA Stream 0 Source Current Y Count Register */
+#define MDMA_S0_IRQ_STATUS 0xFFC00E68 /* MemDMA Stream 0 Source Interrupt/Status Register */
+#define MDMA_S0_PERIPHERAL_MAP 0xFFC00E6C /* MemDMA Stream 0 Source Peripheral Map Register */
+
+/* Parallel Peripheral Interface (PPI) (0xFFC01000 - 0xFFC010FF) */
+
+#define PPI_CONTROL 0xFFC01000 /* PPI Control Register */
+#define PPI_STATUS 0xFFC01004 /* PPI Status Register */
+#define PPI_COUNT 0xFFC01008 /* PPI Transfer Count Register */
+#define PPI_DELAY 0xFFC0100C /* PPI Delay Count Register */
+#define PPI_FRAME 0xFFC01010 /* PPI Frame Length Register */
+
+/*********************************************************************************** */
+/* System MMR Register Bits */
+/******************************************************************************* */
+
+/* ********************* PLL AND RESET MASKS ************************ */
+
+/* PLL_CTL Masks */
+#define PLL_CLKIN 0x00000000 /* Pass CLKIN to PLL */
+#define PLL_CLKIN_DIV2 0x00000001 /* Pass CLKIN/2 to PLL */
+#define PLL_OFF 0x00000002 /* Shut off PLL clocks */
+#define STOPCK_OFF 0x00000008 /* Core clock off */
+#define PDWN 0x00000020 /* Put the PLL in a Deep Sleep state */
+#define BYPASS 0x00000100 /* Bypass the PLL */
+
+/* PLL_DIV Masks */
+
+#define SCLK_DIV(x) (x) /* SCLK = VCO / x */
+
+#define CCLK_DIV1 0x00000000 /* CCLK = VCO / 1 */
+#define CCLK_DIV2 0x00000010 /* CCLK = VCO / 2 */
+#define CCLK_DIV4 0x00000020 /* CCLK = VCO / 4 */
+#define CCLK_DIV8 0x00000030 /* CCLK = VCO / 8 */
+
+/* PLL_STAT Masks */
+#define ACTIVE_PLLENABLED 0x0001 /* Processor In Active Mode With PLL Enabled */
+#define FULL_ON 0x0002 /* Processor In Full On Mode */
+#define ACTIVE_PLLDISABLED 0x0004 /* Processor In Active Mode With PLL Disabled */
+#define PLL_LOCKED 0x0020 /* PLL_LOCKCNT Has Been Reached */
+
+/* CHIPID Masks */
+#define CHIPID_VERSION 0xF0000000
+#define CHIPID_FAMILY 0x0FFFF000
+#define CHIPID_MANUFACTURE 0x00000FFE
+
+/* SWRST Mask */
+#define SYSTEM_RESET 0x00000007 /* Initiates a system software reset */
+
+/* ************* SYSTEM INTERRUPT CONTROLLER MASKS ***************** */
+
+ /* SIC_IAR0 Masks */
+
+#define P0_IVG(x) ((x)-7) /* Peripheral #0 assigned IVG #x */
+#define P1_IVG(x) ((x)-7) << 0x4 /* Peripheral #1 assigned IVG #x */
+#define P2_IVG(x) ((x)-7) << 0x8 /* Peripheral #2 assigned IVG #x */
+#define P3_IVG(x) ((x)-7) << 0xC /* Peripheral #3 assigned IVG #x */
+#define P4_IVG(x) ((x)-7) << 0x10 /* Peripheral #4 assigned IVG #x */
+#define P5_IVG(x) ((x)-7) << 0x14 /* Peripheral #5 assigned IVG #x */
+#define P6_IVG(x) ((x)-7) << 0x18 /* Peripheral #6 assigned IVG #x */
+#define P7_IVG(x) ((x)-7) << 0x1C /* Peripheral #7 assigned IVG #x */
+
+/* SIC_IAR1 Masks */
+
+#define P8_IVG(x) ((x)-7) /* Peripheral #8 assigned IVG #x */
+#define P9_IVG(x) ((x)-7) << 0x4 /* Peripheral #9 assigned IVG #x */
+#define P10_IVG(x) ((x)-7) << 0x8 /* Peripheral #10 assigned IVG #x */
+#define P11_IVG(x) ((x)-7) << 0xC /* Peripheral #11 assigned IVG #x */
+#define P12_IVG(x) ((x)-7) << 0x10 /* Peripheral #12 assigned IVG #x */
+#define P13_IVG(x) ((x)-7) << 0x14 /* Peripheral #13 assigned IVG #x */
+#define P14_IVG(x) ((x)-7) << 0x18 /* Peripheral #14 assigned IVG #x */
+#define P15_IVG(x) ((x)-7) << 0x1C /* Peripheral #15 assigned IVG #x */
+
+/* SIC_IAR2 Masks */
+#define P16_IVG(x) ((x)-7) /* Peripheral #16 assigned IVG #x */
+#define P17_IVG(x) ((x)-7) << 0x4 /* Peripheral #17 assigned IVG #x */
+#define P18_IVG(x) ((x)-7) << 0x8 /* Peripheral #18 assigned IVG #x */
+#define P19_IVG(x) ((x)-7) << 0xC /* Peripheral #19 assigned IVG #x */
+#define P20_IVG(x) ((x)-7) << 0x10 /* Peripheral #20 assigned IVG #x */
+#define P21_IVG(x) ((x)-7) << 0x14 /* Peripheral #21 assigned IVG #x */
+#define P22_IVG(x) ((x)-7) << 0x18 /* Peripheral #22 assigned IVG #x */
+#define P23_IVG(x) ((x)-7) << 0x1C /* Peripheral #23 assigned IVG #x */
+
+/* SIC_IMASK Masks */
+#define SIC_UNMASK_ALL 0x00000000 /* Unmask all peripheral interrupts */
+#define SIC_MASK_ALL 0xFFFFFFFF /* Mask all peripheral interrupts */
+#define SIC_MASK(x) (1 << (x)) /* Mask Peripheral #x interrupt */
+#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << (x))) /* Unmask Peripheral #x interrupt */
+
+/* SIC_IWR Masks */
+#define IWR_DISABLE_ALL 0x00000000 /* Wakeup Disable all peripherals */
+#define IWR_ENABLE_ALL 0xFFFFFFFF /* Wakeup Enable all peripherals */
+#define IWR_ENABLE(x) (1 << (x)) /* Wakeup Enable Peripheral #x */
+#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << (x))) /* Wakeup Disable Peripheral #x */
+
+/* ********* WATCHDOG TIMER MASKS ********************8 */
+
+/* Watchdog Timer WDOG_CTL Register */
+#define ICTL(x) ((x<<1) & 0x0006)
+#define ENABLE_RESET 0x00000000 /* Set Watchdog Timer to generate reset */
+#define ENABLE_NMI 0x00000002 /* Set Watchdog Timer to generate non-maskable interrupt */
+#define ENABLE_GPI 0x00000004 /* Set Watchdog Timer to generate general-purpose interrupt */
+#define DISABLE_EVT 0x00000006 /* Disable Watchdog Timer interrupts */
+
+#define TMR_EN 0x0000
+#define TMR_DIS 0x0AD0
+#define TRO 0x8000
+
+#define ICTL_P0 0x01
+#define ICTL_P1 0x02
+#define TRO_P 0x0F
+
+/* ***************************** UART CONTROLLER MASKS ********************** */
+
+/* UART_LCR Register */
+
+#define DLAB 0x80
+#define SB 0x40
+#define STP 0x20
+#define EPS 0x10
+#define PEN 0x08
+#define STB 0x04
+#define WLS(x) ((x-5) & 0x03)
+
+#define DLAB_P 0x07
+#define SB_P 0x06
+#define STP_P 0x05
+#define EPS_P 0x04
+#define PEN_P 0x03
+#define STB_P 0x02
+#define WLS_P1 0x01
+#define WLS_P0 0x00
+
+/* UART_MCR Register */
+#define LOOP_ENA 0x10
+#define LOOP_ENA_P 0x04
+
+/* UART_LSR Register */
+#define TEMT 0x40
+#define THRE 0x20
+#define BI 0x10
+#define FE 0x08
+#define PE 0x04
+#define OE 0x02
+#define DR 0x01
+
+#define TEMP_P 0x06
+#define THRE_P 0x05
+#define BI_P 0x04
+#define FE_P 0x03
+#define PE_P 0x02
+#define OE_P 0x01
+#define DR_P 0x00
+
+/* UART_IER Register */
+#define ELSI 0x04
+#define ETBEI 0x02
+#define ERBFI 0x01
+
+#define ELSI_P 0x02
+#define ETBEI_P 0x01
+#define ERBFI_P 0x00
+
+/* UART_IIR Register */
+#define STATUS(x) ((x << 1) & 0x06)
+#define NINT 0x01
+#define STATUS_P1 0x02
+#define STATUS_P0 0x01
+#define NINT_P 0x00
+#define IIR_TX_READY 0x02 /* UART_THR empty */
+#define IIR_RX_READY 0x04 /* Receive data ready */
+#define IIR_LINE_CHANGE 0x06 /* Receive line status */
+#define IIR_STATUS 0x06
+
+/* UART_GCTL Register */
+#define FFE 0x20
+#define FPE 0x10
+#define RPOLC 0x08
+#define TPOLC 0x04
+#define IREN 0x02
+#define UCEN 0x01
+
+#define FFE_P 0x05
+#define FPE_P 0x04
+#define RPOLC_P 0x03
+#define TPOLC_P 0x02
+#define IREN_P 0x01
+#define UCEN_P 0x00
+
+/* ********** SERIAL PORT MASKS ********************** */
+
+/* SPORTx_TCR1 Masks */
+#define TSPEN 0x0001 /* TX enable */
+#define ITCLK 0x0002 /* Internal TX Clock Select */
+#define TDTYPE 0x000C /* TX Data Formatting Select */
+#define TLSBIT 0x0010 /* TX Bit Order */
+#define ITFS 0x0200 /* Internal TX Frame Sync Select */
+#define TFSR 0x0400 /* TX Frame Sync Required Select */
+#define DITFS 0x0800 /* Data Independent TX Frame Sync Select */
+#define LTFS 0x1000 /* Low TX Frame Sync Select */
+#define LATFS 0x2000 /* Late TX Frame Sync Select */
+#define TCKFE 0x4000 /* TX Clock Falling Edge Select */
+
+/* SPORTx_TCR2 Masks */
+#define SLEN 0x001F /*TX Word Length */
+#define TXSE 0x0100 /*TX Secondary Enable */
+#define TSFSE 0x0200 /*TX Stereo Frame Sync Enable */
+#define TRFST 0x0400 /*TX Right-First Data Order */
+
+/* SPORTx_RCR1 Masks */
+#define RSPEN 0x0001 /* RX enable */
+#define IRCLK 0x0002 /* Internal RX Clock Select */
+#define RDTYPE 0x000C /* RX Data Formatting Select */
+#define RULAW 0x0008 /* u-Law enable */
+#define RALAW 0x000C /* A-Law enable */
+#define RLSBIT 0x0010 /* RX Bit Order */
+#define IRFS 0x0200 /* Internal RX Frame Sync Select */
+#define RFSR 0x0400 /* RX Frame Sync Required Select */
+#define LRFS 0x1000 /* Low RX Frame Sync Select */
+#define LARFS 0x2000 /* Late RX Frame Sync Select */
+#define RCKFE 0x4000 /* RX Clock Falling Edge Select */
+
+/* SPORTx_RCR2 Masks */
+#define SLEN 0x001F /*RX Word Length */
+#define RXSE 0x0100 /*RX Secondary Enable */
+#define RSFSE 0x0200 /*RX Stereo Frame Sync Enable */
+#define RRFST 0x0400 /*Right-First Data Order */
+
+/*SPORTx_STAT Masks */
+#define RXNE 0x0001 /*RX FIFO Not Empty Status */
+#define RUVF 0x0002 /*RX Underflow Status */
+#define ROVF 0x0004 /*RX Overflow Status */
+#define TXF 0x0008 /*TX FIFO Full Status */
+#define TUVF 0x0010 /*TX Underflow Status */
+#define TOVF 0x0020 /*TX Overflow Status */
+#define TXHRE 0x0040 /*TX Hold Register Empty */
+
+/*SPORTx_MCMC1 Masks */
+#define SP_WSIZE 0x0000F000 /*Multichannel Window Size Field */
+#define SP_WOFF 0x000003FF /*Multichannel Window Offset Field */
+
+/*SPORTx_MCMC2 Masks */
+#define MCCRM 0x00000003 /*Multichannel Clock Recovery Mode */
+#define MCDTXPE 0x00000004 /*Multichannel DMA Transmit Packing */
+#define MCDRXPE 0x00000008 /*Multichannel DMA Receive Packing */
+#define MCMEN 0x00000010 /*Multichannel Frame Mode Enable */
+#define FSDR 0x00000080 /*Multichannel Frame Sync to Data Relationship */
+#define MFD 0x0000F000 /*Multichannel Frame Delay */
+
+/* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */
+
+/* PPI_CONTROL Masks */
+#define PORT_EN 0x00000001 /* PPI Port Enable */
+#define PORT_DIR 0x00000002 /* PPI Port Direction */
+#define XFR_TYPE 0x0000000C /* PPI Transfer Type */
+#define PORT_CFG 0x00000030 /* PPI Port Configuration */
+#define FLD_SEL 0x00000040 /* PPI Active Field Select */
+#define PACK_EN 0x00000080 /* PPI Packing Mode */
+#define DMA32 0x00000100 /* PPI 32-bit DMA Enable */
+#define SKIP_EN 0x00000200 /* PPI Skip Element Enable */
+#define SKIP_EO 0x00000400 /* PPI Skip Even/Odd Elements */
+#define DLENGTH 0x00003800 /* PPI Data Length */
+#define DLEN_8 0x0000 /* Data Length = 8 Bits */
+#define DLEN_10 0x0800 /* Data Length = 10 Bits */
+#define DLEN_11 0x1000 /* Data Length = 11 Bits */
+#define DLEN_12 0x1800 /* Data Length = 12 Bits */
+#define DLEN_13 0x2000 /* Data Length = 13 Bits */
+#define DLEN_14 0x2800 /* Data Length = 14 Bits */
+#define DLEN_15 0x3000 /* Data Length = 15 Bits */
+#define DLEN_16 0x3800 /* Data Length = 16 Bits */
+#define DLEN(x) (((x-9) & 0x07) << 11) /* PPI Data Length (only works for x=10-->x=16) */
+#define POL 0x0000C000 /* PPI Signal Polarities */
+
+/* PPI_STATUS Masks */
+#define FLD 0x00000400 /* Field Indicator */
+#define FT_ERR 0x00000800 /* Frame Track Error */
+#define OVR 0x00001000 /* FIFO Overflow Error */
+#define UNDR 0x00002000 /* FIFO Underrun Error */
+#define ERR_DET 0x00004000 /* Error Detected Indicator */
+#define ERR_NCOR 0x00008000 /* Error Not Corrected Indicator */
+
+/* ********** DMA CONTROLLER MASKS *********************8 */
+
+/*DMAx_CONFIG, MDMA_yy_CONFIG Masks */
+#define DMAEN 0x00000001 /* Channel Enable */
+#define WNR 0x00000002 /* Channel Direction (W/R*) */
+#define WDSIZE_8 0x00000000 /* Word Size 8 bits */
+#define WDSIZE_16 0x00000004 /* Word Size 16 bits */
+#define WDSIZE_32 0x00000008 /* Word Size 32 bits */
+#define DMA2D 0x00000010 /* 2D/1D* Mode */
+#define RESTART 0x00000020 /* Restart */
+#define DI_SEL 0x00000040 /* Data Interrupt Select */
+#define DI_EN 0x00000080 /* Data Interrupt Enable */
+#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */
+#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */
+#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */
+#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */
+#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */
+#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */
+#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */
+#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */
+#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */
+#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */
+#define NDSIZE 0x00000900 /* Next Descriptor Size */
+#define DMAFLOW 0x00007000 /* Flow Control */
+#define DMAFLOW_STOP 0x0000 /* Stop Mode */
+#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */
+#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */
+#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */
+#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */
+
+#define DMAEN_P 0 /* Channel Enable */
+#define WNR_P 1 /* Channel Direction (W/R*) */
+#define DMA2D_P 4 /* 2D/1D* Mode */
+#define RESTART_P 5 /* Restart */
+#define DI_SEL_P 6 /* Data Interrupt Select */
+#define DI_EN_P 7 /* Data Interrupt Enable */
+
+/*DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks */
+
+#define DMA_DONE 0x00000001 /* DMA Done Indicator */
+#define DMA_ERR 0x00000002 /* DMA Error Indicator */
+#define DFETCH 0x00000004 /* Descriptor Fetch Indicator */
+#define DMA_RUN 0x00000008 /* DMA Running Indicator */
+
+#define DMA_DONE_P 0 /* DMA Done Indicator */
+#define DMA_ERR_P 1 /* DMA Error Indicator */
+#define DFETCH_P 2 /* Descriptor Fetch Indicator */
+#define DMA_RUN_P 3 /* DMA Running Indicator */
+
+/*DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */
+
+#define CTYPE 0x00000040 /* DMA Channel Type Indicator */
+#define CTYPE_P 6 /* DMA Channel Type Indicator BIT POSITION */
+#define PCAP8 0x00000080 /* DMA 8-bit Operation Indicator */
+#define PCAP16 0x00000100 /* DMA 16-bit Operation Indicator */
+#define PCAP32 0x00000200 /* DMA 32-bit Operation Indicator */
+#define PCAPWR 0x00000400 /* DMA Write Operation Indicator */
+#define PCAPRD 0x00000800 /* DMA Read Operation Indicator */
+#define PMAP 0x00007000 /* DMA Peripheral Map Field */
+
+/* ************* GENERAL PURPOSE TIMER MASKS ******************** */
+
+/* PWM Timer bit definitions */
+
+/* TIMER_ENABLE Register */
+#define TIMEN0 0x0001
+#define TIMEN1 0x0002
+#define TIMEN2 0x0004
+
+#define TIMEN0_P 0x00
+#define TIMEN1_P 0x01
+#define TIMEN2_P 0x02
+
+/* TIMER_DISABLE Register */
+#define TIMDIS0 0x0001
+#define TIMDIS1 0x0002
+#define TIMDIS2 0x0004
+
+#define TIMDIS0_P 0x00
+#define TIMDIS1_P 0x01
+#define TIMDIS2_P 0x02
+
+/* TIMER_STATUS Register */
+#define TIMIL0 0x0001
+#define TIMIL1 0x0002
+#define TIMIL2 0x0004
+#define TOVL_ERR0 0x0010
+#define TOVL_ERR1 0x0020
+#define TOVL_ERR2 0x0040
+#define TRUN0 0x1000
+#define TRUN1 0x2000
+#define TRUN2 0x4000
+
+#define TIMIL0_P 0x00
+#define TIMIL1_P 0x01
+#define TIMIL2_P 0x02
+#define TOVL_ERR0_P 0x04
+#define TOVL_ERR1_P 0x05
+#define TOVL_ERR2_P 0x06
+#define TRUN0_P 0x0C
+#define TRUN1_P 0x0D
+#define TRUN2_P 0x0E
+
+/* TIMERx_CONFIG Registers */
+#define PWM_OUT 0x0001
+#define WDTH_CAP 0x0002
+#define EXT_CLK 0x0003
+#define PULSE_HI 0x0004
+#define PERIOD_CNT 0x0008
+#define IRQ_ENA 0x0010
+#define TIN_SEL 0x0020
+#define OUT_DIS 0x0040
+#define CLK_SEL 0x0080
+#define TOGGLE_HI 0x0100
+#define EMU_RUN 0x0200
+#define ERR_TYP(x) ((x & 0x03) << 14)
+
+#define TMODE_P0 0x00
+#define TMODE_P1 0x01
+#define PULSE_HI_P 0x02
+#define PERIOD_CNT_P 0x03
+#define IRQ_ENA_P 0x04
+#define TIN_SEL_P 0x05
+#define OUT_DIS_P 0x06
+#define CLK_SEL_P 0x07
+#define TOGGLE_HI_P 0x08
+#define EMU_RUN_P 0x09
+#define ERR_TYP_P0 0x0E
+#define ERR_TYP_P1 0x0F
+
+/*/ ****************** PROGRAMMABLE FLAG MASKS ********************* */
+
+/* General Purpose IO (0xFFC00700 - 0xFFC007FF) Masks */
+#define PF0 0x0001
+#define PF1 0x0002
+#define PF2 0x0004
+#define PF3 0x0008
+#define PF4 0x0010
+#define PF5 0x0020
+#define PF6 0x0040
+#define PF7 0x0080
+#define PF8 0x0100
+#define PF9 0x0200
+#define PF10 0x0400
+#define PF11 0x0800
+#define PF12 0x1000
+#define PF13 0x2000
+#define PF14 0x4000
+#define PF15 0x8000
+
+/* General Purpose IO (0xFFC00700 - 0xFFC007FF) BIT POSITIONS */
+#define PF0_P 0
+#define PF1_P 1
+#define PF2_P 2
+#define PF3_P 3
+#define PF4_P 4
+#define PF5_P 5
+#define PF6_P 6
+#define PF7_P 7
+#define PF8_P 8
+#define PF9_P 9
+#define PF10_P 10
+#define PF11_P 11
+#define PF12_P 12
+#define PF13_P 13
+#define PF14_P 14
+#define PF15_P 15
+
+/* *********** SERIAL PERIPHERAL INTERFACE (SPI) MASKS **************** */
+
+/* SPI_CTL Masks */
+#define TIMOD 0x00000003 /* Transfer initiation mode and interrupt generation */
+#define SZ 0x00000004 /* Send Zero (=0) or last (=1) word when TDBR empty. */
+#define GM 0x00000008 /* When RDBR full, get more (=1) data or discard (=0) incoming Data */
+#define PSSE 0x00000010 /* Enable (=1) Slave-Select input for Master. */
+#define EMISO 0x00000020 /* Enable (=1) MISO pin as an output. */
+#define SPI_LEN 0x00000100 /* Word length (0 => 8 bits, 1 => 16 bits) */
+#define LSBF 0x00000200 /* Data format (0 => MSB sent/received first 1 => LSB sent/received first) */
+#define CPHA 0x00000400 /* Clock phase (0 => SPICLK starts toggling in middle of xfer, 1 => SPICLK toggles at the beginning of xfer. */
+#define CPOL 0x00000800 /* Clock polarity (0 => active-high, 1 => active-low) */
+#define MSTR 0x00001000 /* Configures SPI as master (=1) or slave (=0) */
+#define WOM 0x00002000 /* Open drain (=1) data output enable (for MOSI and MISO) */
+#define SPE 0x00004000 /* SPI module enable (=1), disable (=0) */
+
+/* SPI_FLG Masks */
+#define FLS1 0x00000002 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */
+#define FLS2 0x00000004 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */
+#define FLS3 0x00000008 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */
+#define FLS4 0x00000010 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */
+#define FLS5 0x00000020 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */
+#define FLS6 0x00000040 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */
+#define FLS7 0x00000080 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */
+#define FLG1 0x00000200 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */
+#define FLG2 0x00000400 /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */
+#define FLG3 0x00000800 /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */
+#define FLG4 0x00001000 /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */
+#define FLG5 0x00002000 /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */
+#define FLG6 0x00004000 /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */
+#define FLG7 0x00008000 /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */
+
+/* SPI_FLG Bit Positions */
+#define FLS1_P 0x00000001 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */
+#define FLS2_P 0x00000002 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */
+#define FLS3_P 0x00000003 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */
+#define FLS4_P 0x00000004 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */
+#define FLS5_P 0x00000005 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */
+#define FLS6_P 0x00000006 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */
+#define FLS7_P 0x00000007 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */
+#define FLG1_P 0x00000009 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */
+#define FLG2_P 0x0000000A /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */
+#define FLG3_P 0x0000000B /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */
+#define FLG4_P 0x0000000C /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */
+#define FLG5_P 0x0000000D /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */
+#define FLG6_P 0x0000000E /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */
+#define FLG7_P 0x0000000F /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */
+
+/* SPI_STAT Masks */
+#define SPIF 0x00000001 /* Set (=1) when SPI single-word transfer complete */
+#define MODF 0x00000002 /* Set (=1) in a master device when some other device tries to become master */
+#define TXE 0x00000004 /* Set (=1) when transmission occurs with no new data in SPI_TDBR */
+#define TXS 0x00000008 /* SPI_TDBR Data Buffer Status (0=Empty, 1=Full) */
+#define RBSY 0x00000010 /* Set (=1) when data is received with RDBR full */
+#define RXS 0x00000020 /* SPI_RDBR Data Buffer Status (0=Empty, 1=Full) */
+#define TXCOL 0x00000040 /* When set (=1), corrupt data may have been transmitted */
+
+/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS ************* */
+
+/* AMGCTL Masks */
+#define AMCKEN 0x00000001 /* Enable CLKOUT */
+#define AMBEN_B0 0x00000002 /* Enable Asynchronous Memory Bank 0 only */
+#define AMBEN_B0_B1 0x00000004 /* Enable Asynchronous Memory Banks 0 & 1 only */
+#define AMBEN_B0_B1_B2 0x00000006 /* Enable Asynchronous Memory Banks 0, 1, and 2 */
+#define AMBEN_ALL 0x00000008 /* Enable Asynchronous Memory Banks (all) 0, 1, 2, and 3 */
+
+/* AMGCTL Bit Positions */
+#define AMCKEN_P 0x00000000 /* Enable CLKOUT */
+#define AMBEN_P0 0x00000001 /* Asynchronous Memory Enable, 000 - banks 0-3 disabled, 001 - Bank 0 enabled */
+#define AMBEN_P1 0x00000002 /* Asynchronous Memory Enable, 010 - banks 0&1 enabled, 011 - banks 0-3 enabled */
+#define AMBEN_P2 0x00000003 /* Asynchronous Memory Enable, 1xx - All banks (bank 0, 1, 2, and 3) enabled */
+
+/* AMBCTL0 Masks */
+#define B0RDYEN 0x00000001 /* Bank 0 RDY Enable, 0=disable, 1=enable */
+#define B0RDYPOL 0x00000002 /* Bank 0 RDY Active high, 0=active low, 1=active high */
+#define B0TT_1 0x00000004 /* Bank 0 Transition Time from Read to Write = 1 cycle */
+#define B0TT_2 0x00000008 /* Bank 0 Transition Time from Read to Write = 2 cycles */
+#define B0TT_3 0x0000000C /* Bank 0 Transition Time from Read to Write = 3 cycles */
+#define B0TT_4 0x00000000 /* Bank 0 Transition Time from Read to Write = 4 cycles */
+#define B0ST_1 0x00000010 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=1 cycle */
+#define B0ST_2 0x00000020 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=2 cycles */
+#define B0ST_3 0x00000030 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=3 cycles */
+#define B0ST_4 0x00000000 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=4 cycles */
+#define B0HT_1 0x00000040 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 1 cycle */
+#define B0HT_2 0x00000080 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 2 cycles */
+#define B0HT_3 0x000000C0 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 3 cycles */
+#define B0HT_0 0x00000000 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 0 cycles */
+#define B0RAT_1 0x00000100 /* Bank 0 Read Access Time = 1 cycle */
+#define B0RAT_2 0x00000200 /* Bank 0 Read Access Time = 2 cycles */
+#define B0RAT_3 0x00000300 /* Bank 0 Read Access Time = 3 cycles */
+#define B0RAT_4 0x00000400 /* Bank 0 Read Access Time = 4 cycles */
+#define B0RAT_5 0x00000500 /* Bank 0 Read Access Time = 5 cycles */
+#define B0RAT_6 0x00000600 /* Bank 0 Read Access Time = 6 cycles */
+#define B0RAT_7 0x00000700 /* Bank 0 Read Access Time = 7 cycles */
+#define B0RAT_8 0x00000800 /* Bank 0 Read Access Time = 8 cycles */
+#define B0RAT_9 0x00000900 /* Bank 0 Read Access Time = 9 cycles */
+#define B0RAT_10 0x00000A00 /* Bank 0 Read Access Time = 10 cycles */
+#define B0RAT_11 0x00000B00 /* Bank 0 Read Access Time = 11 cycles */
+#define B0RAT_12 0x00000C00 /* Bank 0 Read Access Time = 12 cycles */
+#define B0RAT_13 0x00000D00 /* Bank 0 Read Access Time = 13 cycles */
+#define B0RAT_14 0x00000E00 /* Bank 0 Read Access Time = 14 cycles */
+#define B0RAT_15 0x00000F00 /* Bank 0 Read Access Time = 15 cycles */
+#define B0WAT_1 0x00001000 /* Bank 0 Write Access Time = 1 cycle */
+#define B0WAT_2 0x00002000 /* Bank 0 Write Access Time = 2 cycles */
+#define B0WAT_3 0x00003000 /* Bank 0 Write Access Time = 3 cycles */
+#define B0WAT_4 0x00004000 /* Bank 0 Write Access Time = 4 cycles */
+#define B0WAT_5 0x00005000 /* Bank 0 Write Access Time = 5 cycles */
+#define B0WAT_6 0x00006000 /* Bank 0 Write Access Time = 6 cycles */
+#define B0WAT_7 0x00007000 /* Bank 0 Write Access Time = 7 cycles */
+#define B0WAT_8 0x00008000 /* Bank 0 Write Access Time = 8 cycles */
+#define B0WAT_9 0x00009000 /* Bank 0 Write Access Time = 9 cycles */
+#define B0WAT_10 0x0000A000 /* Bank 0 Write Access Time = 10 cycles */
+#define B0WAT_11 0x0000B000 /* Bank 0 Write Access Time = 11 cycles */
+#define B0WAT_12 0x0000C000 /* Bank 0 Write Access Time = 12 cycles */
+#define B0WAT_13 0x0000D000 /* Bank 0 Write Access Time = 13 cycles */
+#define B0WAT_14 0x0000E000 /* Bank 0 Write Access Time = 14 cycles */
+#define B0WAT_15 0x0000F000 /* Bank 0 Write Access Time = 15 cycles */
+#define B1RDYEN 0x00010000 /* Bank 1 RDY enable, 0=disable, 1=enable */
+#define B1RDYPOL 0x00020000 /* Bank 1 RDY Active high, 0=active low, 1=active high */
+#define B1TT_1 0x00040000 /* Bank 1 Transition Time from Read to Write = 1 cycle */
+#define B1TT_2 0x00080000 /* Bank 1 Transition Time from Read to Write = 2 cycles */
+#define B1TT_3 0x000C0000 /* Bank 1 Transition Time from Read to Write = 3 cycles */
+#define B1TT_4 0x00000000 /* Bank 1 Transition Time from Read to Write = 4 cycles */
+#define B1ST_1 0x00100000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */
+#define B1ST_2 0x00200000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */
+#define B1ST_3 0x00300000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */
+#define B1ST_4 0x00000000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */
+#define B1HT_1 0x00400000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */
+#define B1HT_2 0x00800000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */
+#define B1HT_3 0x00C00000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */
+#define B1HT_0 0x00000000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */
+#define B1RAT_1 0x01000000 /* Bank 1 Read Access Time = 1 cycle */
+#define B1RAT_2 0x02000000 /* Bank 1 Read Access Time = 2 cycles */
+#define B1RAT_3 0x03000000 /* Bank 1 Read Access Time = 3 cycles */
+#define B1RAT_4 0x04000000 /* Bank 1 Read Access Time = 4 cycles */
+#define B1RAT_5 0x05000000 /* Bank 1 Read Access Time = 5 cycles */
+#define B1RAT_6 0x06000000 /* Bank 1 Read Access Time = 6 cycles */
+#define B1RAT_7 0x07000000 /* Bank 1 Read Access Time = 7 cycles */
+#define B1RAT_8 0x08000000 /* Bank 1 Read Access Time = 8 cycles */
+#define B1RAT_9 0x09000000 /* Bank 1 Read Access Time = 9 cycles */
+#define B1RAT_10 0x0A000000 /* Bank 1 Read Access Time = 10 cycles */
+#define B1RAT_11 0x0B000000 /* Bank 1 Read Access Time = 11 cycles */
+#define B1RAT_12 0x0C000000 /* Bank 1 Read Access Time = 12 cycles */
+#define B1RAT_13 0x0D000000 /* Bank 1 Read Access Time = 13 cycles */
+#define B1RAT_14 0x0E000000 /* Bank 1 Read Access Time = 14 cycles */
+#define B1RAT_15 0x0F000000 /* Bank 1 Read Access Time = 15 cycles */
+#define B1WAT_1 0x10000000 /* Bank 1 Write Access Time = 1 cycle */
+#define B1WAT_2 0x20000000 /* Bank 1 Write Access Time = 2 cycles */
+#define B1WAT_3 0x30000000 /* Bank 1 Write Access Time = 3 cycles */
+#define B1WAT_4 0x40000000 /* Bank 1 Write Access Time = 4 cycles */
+#define B1WAT_5 0x50000000 /* Bank 1 Write Access Time = 5 cycles */
+#define B1WAT_6 0x60000000 /* Bank 1 Write Access Time = 6 cycles */
+#define B1WAT_7 0x70000000 /* Bank 1 Write Access Time = 7 cycles */
+#define B1WAT_8 0x80000000 /* Bank 1 Write Access Time = 8 cycles */
+#define B1WAT_9 0x90000000 /* Bank 1 Write Access Time = 9 cycles */
+#define B1WAT_10 0xA0000000 /* Bank 1 Write Access Time = 10 cycles */
+#define B1WAT_11 0xB0000000 /* Bank 1 Write Access Time = 11 cycles */
+#define B1WAT_12 0xC0000000 /* Bank 1 Write Access Time = 12 cycles */
+#define B1WAT_13 0xD0000000 /* Bank 1 Write Access Time = 13 cycles */
+#define B1WAT_14 0xE0000000 /* Bank 1 Write Access Time = 14 cycles */
+#define B1WAT_15 0xF0000000 /* Bank 1 Write Access Time = 15 cycles */
+
+/* AMBCTL1 Masks */
+#define B2RDYEN 0x00000001 /* Bank 2 RDY Enable, 0=disable, 1=enable */
+#define B2RDYPOL 0x00000002 /* Bank 2 RDY Active high, 0=active low, 1=active high */
+#define B2TT_1 0x00000004 /* Bank 2 Transition Time from Read to Write = 1 cycle */
+#define B2TT_2 0x00000008 /* Bank 2 Transition Time from Read to Write = 2 cycles */
+#define B2TT_3 0x0000000C /* Bank 2 Transition Time from Read to Write = 3 cycles */
+#define B2TT_4 0x00000000 /* Bank 2 Transition Time from Read to Write = 4 cycles */
+#define B2ST_1 0x00000010 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */
+#define B2ST_2 0x00000020 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */
+#define B2ST_3 0x00000030 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */
+#define B2ST_4 0x00000000 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */
+#define B2HT_1 0x00000040 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */
+#define B2HT_2 0x00000080 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */
+#define B2HT_3 0x000000C0 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */
+#define B2HT_0 0x00000000 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */
+#define B2RAT_1 0x00000100 /* Bank 2 Read Access Time = 1 cycle */
+#define B2RAT_2 0x00000200 /* Bank 2 Read Access Time = 2 cycles */
+#define B2RAT_3 0x00000300 /* Bank 2 Read Access Time = 3 cycles */
+#define B2RAT_4 0x00000400 /* Bank 2 Read Access Time = 4 cycles */
+#define B2RAT_5 0x00000500 /* Bank 2 Read Access Time = 5 cycles */
+#define B2RAT_6 0x00000600 /* Bank 2 Read Access Time = 6 cycles */
+#define B2RAT_7 0x00000700 /* Bank 2 Read Access Time = 7 cycles */
+#define B2RAT_8 0x00000800 /* Bank 2 Read Access Time = 8 cycles */
+#define B2RAT_9 0x00000900 /* Bank 2 Read Access Time = 9 cycles */
+#define B2RAT_10 0x00000A00 /* Bank 2 Read Access Time = 10 cycles */
+#define B2RAT_11 0x00000B00 /* Bank 2 Read Access Time = 11 cycles */
+#define B2RAT_12 0x00000C00 /* Bank 2 Read Access Time = 12 cycles */
+#define B2RAT_13 0x00000D00 /* Bank 2 Read Access Time = 13 cycles */
+#define B2RAT_14 0x00000E00 /* Bank 2 Read Access Time = 14 cycles */
+#define B2RAT_15 0x00000F00 /* Bank 2 Read Access Time = 15 cycles */
+#define B2WAT_1 0x00001000 /* Bank 2 Write Access Time = 1 cycle */
+#define B2WAT_2 0x00002000 /* Bank 2 Write Access Time = 2 cycles */
+#define B2WAT_3 0x00003000 /* Bank 2 Write Access Time = 3 cycles */
+#define B2WAT_4 0x00004000 /* Bank 2 Write Access Time = 4 cycles */
+#define B2WAT_5 0x00005000 /* Bank 2 Write Access Time = 5 cycles */
+#define B2WAT_6 0x00006000 /* Bank 2 Write Access Time = 6 cycles */
+#define B2WAT_7 0x00007000 /* Bank 2 Write Access Time = 7 cycles */
+#define B2WAT_8 0x00008000 /* Bank 2 Write Access Time = 8 cycles */
+#define B2WAT_9 0x00009000 /* Bank 2 Write Access Time = 9 cycles */
+#define B2WAT_10 0x0000A000 /* Bank 2 Write Access Time = 10 cycles */
+#define B2WAT_11 0x0000B000 /* Bank 2 Write Access Time = 11 cycles */
+#define B2WAT_12 0x0000C000 /* Bank 2 Write Access Time = 12 cycles */
+#define B2WAT_13 0x0000D000 /* Bank 2 Write Access Time = 13 cycles */
+#define B2WAT_14 0x0000E000 /* Bank 2 Write Access Time = 14 cycles */
+#define B2WAT_15 0x0000F000 /* Bank 2 Write Access Time = 15 cycles */
+#define B3RDYEN 0x00010000 /* Bank 3 RDY enable, 0=disable, 1=enable */
+#define B3RDYPOL 0x00020000 /* Bank 3 RDY Active high, 0=active low, 1=active high */
+#define B3TT_1 0x00040000 /* Bank 3 Transition Time from Read to Write = 1 cycle */
+#define B3TT_2 0x00080000 /* Bank 3 Transition Time from Read to Write = 2 cycles */
+#define B3TT_3 0x000C0000 /* Bank 3 Transition Time from Read to Write = 3 cycles */
+#define B3TT_4 0x00000000 /* Bank 3 Transition Time from Read to Write = 4 cycles */
+#define B3ST_1 0x00100000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */
+#define B3ST_2 0x00200000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */
+#define B3ST_3 0x00300000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */
+#define B3ST_4 0x00000000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */
+#define B3HT_1 0x00400000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */
+#define B3HT_2 0x00800000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */
+#define B3HT_3 0x00C00000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */
+#define B3HT_0 0x00000000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */
+#define B3RAT_1 0x01000000 /* Bank 3 Read Access Time = 1 cycle */
+#define B3RAT_2 0x02000000 /* Bank 3 Read Access Time = 2 cycles */
+#define B3RAT_3 0x03000000 /* Bank 3 Read Access Time = 3 cycles */
+#define B3RAT_4 0x04000000 /* Bank 3 Read Access Time = 4 cycles */
+#define B3RAT_5 0x05000000 /* Bank 3 Read Access Time = 5 cycles */
+#define B3RAT_6 0x06000000 /* Bank 3 Read Access Time = 6 cycles */
+#define B3RAT_7 0x07000000 /* Bank 3 Read Access Time = 7 cycles */
+#define B3RAT_8 0x08000000 /* Bank 3 Read Access Time = 8 cycles */
+#define B3RAT_9 0x09000000 /* Bank 3 Read Access Time = 9 cycles */
+#define B3RAT_10 0x0A000000 /* Bank 3 Read Access Time = 10 cycles */
+#define B3RAT_11 0x0B000000 /* Bank 3 Read Access Time = 11 cycles */
+#define B3RAT_12 0x0C000000 /* Bank 3 Read Access Time = 12 cycles */
+#define B3RAT_13 0x0D000000 /* Bank 3 Read Access Time = 13 cycles */
+#define B3RAT_14 0x0E000000 /* Bank 3 Read Access Time = 14 cycles */
+#define B3RAT_15 0x0F000000 /* Bank 3 Read Access Time = 15 cycles */
+#define B3WAT_1 0x10000000 /* Bank 3 Write Access Time = 1 cycle */
+#define B3WAT_2 0x20000000 /* Bank 3 Write Access Time = 2 cycles */
+#define B3WAT_3 0x30000000 /* Bank 3 Write Access Time = 3 cycles */
+#define B3WAT_4 0x40000000 /* Bank 3 Write Access Time = 4 cycles */
+#define B3WAT_5 0x50000000 /* Bank 3 Write Access Time = 5 cycles */
+#define B3WAT_6 0x60000000 /* Bank 3 Write Access Time = 6 cycles */
+#define B3WAT_7 0x70000000 /* Bank 3 Write Access Time = 7 cycles */
+#define B3WAT_8 0x80000000 /* Bank 3 Write Access Time = 8 cycles */
+#define B3WAT_9 0x90000000 /* Bank 3 Write Access Time = 9 cycles */
+#define B3WAT_10 0xA0000000 /* Bank 3 Write Access Time = 10 cycles */
+#define B3WAT_11 0xB0000000 /* Bank 3 Write Access Time = 11 cycles */
+#define B3WAT_12 0xC0000000 /* Bank 3 Write Access Time = 12 cycles */
+#define B3WAT_13 0xD0000000 /* Bank 3 Write Access Time = 13 cycles */
+#define B3WAT_14 0xE0000000 /* Bank 3 Write Access Time = 14 cycles */
+#define B3WAT_15 0xF0000000 /* Bank 3 Write Access Time = 15 cycles */
+
+/* ********************** SDRAM CONTROLLER MASKS *************************** */
+
+/* SDGCTL Masks */
+#define SCTLE 0x00000001 /* Enable SCLK[0], /SRAS, /SCAS, /SWE, SDQM[3:0] */
+#define CL_2 0x00000008 /* SDRAM CAS latency = 2 cycles */
+#define CL_3 0x0000000C /* SDRAM CAS latency = 3 cycles */
+#define PFE 0x00000010 /* Enable SDRAM prefetch */
+#define PFP 0x00000020 /* Prefetch has priority over AMC requests */
+#define TRAS_1 0x00000040 /* SDRAM tRAS = 1 cycle */
+#define TRAS_2 0x00000080 /* SDRAM tRAS = 2 cycles */
+#define TRAS_3 0x000000C0 /* SDRAM tRAS = 3 cycles */
+#define TRAS_4 0x00000100 /* SDRAM tRAS = 4 cycles */
+#define TRAS_5 0x00000140 /* SDRAM tRAS = 5 cycles */
+#define TRAS_6 0x00000180 /* SDRAM tRAS = 6 cycles */
+#define TRAS_7 0x000001C0 /* SDRAM tRAS = 7 cycles */
+#define TRAS_8 0x00000200 /* SDRAM tRAS = 8 cycles */
+#define TRAS_9 0x00000240 /* SDRAM tRAS = 9 cycles */
+#define TRAS_10 0x00000280 /* SDRAM tRAS = 10 cycles */
+#define TRAS_11 0x000002C0 /* SDRAM tRAS = 11 cycles */
+#define TRAS_12 0x00000300 /* SDRAM tRAS = 12 cycles */
+#define TRAS_13 0x00000340 /* SDRAM tRAS = 13 cycles */
+#define TRAS_14 0x00000380 /* SDRAM tRAS = 14 cycles */
+#define TRAS_15 0x000003C0 /* SDRAM tRAS = 15 cycles */
+#define TRP_1 0x00000800 /* SDRAM tRP = 1 cycle */
+#define TRP_2 0x00001000 /* SDRAM tRP = 2 cycles */
+#define TRP_3 0x00001800 /* SDRAM tRP = 3 cycles */
+#define TRP_4 0x00002000 /* SDRAM tRP = 4 cycles */
+#define TRP_5 0x00002800 /* SDRAM tRP = 5 cycles */
+#define TRP_6 0x00003000 /* SDRAM tRP = 6 cycles */
+#define TRP_7 0x00003800 /* SDRAM tRP = 7 cycles */
+#define TRCD_1 0x00008000 /* SDRAM tRCD = 1 cycle */
+#define TRCD_2 0x00010000 /* SDRAM tRCD = 2 cycles */
+#define TRCD_3 0x00018000 /* SDRAM tRCD = 3 cycles */
+#define TRCD_4 0x00020000 /* SDRAM tRCD = 4 cycles */
+#define TRCD_5 0x00028000 /* SDRAM tRCD = 5 cycles */
+#define TRCD_6 0x00030000 /* SDRAM tRCD = 6 cycles */
+#define TRCD_7 0x00038000 /* SDRAM tRCD = 7 cycles */
+#define TWR_1 0x00080000 /* SDRAM tWR = 1 cycle */
+#define TWR_2 0x00100000 /* SDRAM tWR = 2 cycles */
+#define TWR_3 0x00180000 /* SDRAM tWR = 3 cycles */
+#define PUPSD 0x00200000 /*Power-up start delay */
+#define PSM 0x00400000 /* SDRAM power-up sequence = Precharge, mode register set, 8 CBR refresh cycles */
+#define PSS 0x00800000 /* enable SDRAM power-up sequence on next SDRAM access */
+#define SRFS 0x01000000 /* Start SDRAM self-refresh mode */
+#define EBUFE 0x02000000 /* Enable external buffering timing */
+#define FBBRW 0x04000000 /* Fast back-to-back read write enable */
+#define EMREN 0x10000000 /* Extended mode register enable */
+#define TCSR 0x20000000 /* Temp compensated self refresh value 85 deg C */
+#define CDDBG 0x40000000 /* Tristate SDRAM controls during bus grant */
+
+/* EBIU_SDBCTL Masks */
+#define EBE 0x00000001 /* Enable SDRAM external bank */
+#define EBSZ_16 0x00000000 /* SDRAM external bank size = 16MB */
+#define EBSZ_32 0x00000002 /* SDRAM external bank size = 32MB */
+#define EBSZ_64 0x00000004 /* SDRAM external bank size = 64MB */
+#define EBSZ_128 0x00000006 /* SDRAM external bank size = 128MB */
+#define EBCAW_8 0x00000000 /* SDRAM external bank column address width = 8 bits */
+#define EBCAW_9 0x00000010 /* SDRAM external bank column address width = 9 bits */
+#define EBCAW_10 0x00000020 /* SDRAM external bank column address width = 9 bits */
+#define EBCAW_11 0x00000030 /* SDRAM external bank column address width = 9 bits */
+
+/* EBIU_SDSTAT Masks */
+#define SDCI 0x00000001 /* SDRAM controller is idle */
+#define SDSRA 0x00000002 /* SDRAM SDRAM self refresh is active */
+#define SDPUA 0x00000004 /* SDRAM power up active */
+#define SDRS 0x00000008 /* SDRAM is in reset state */
+#define SDEASE 0x00000010 /* SDRAM EAB sticky error status - W1C */
+#define BGSTAT 0x00000020 /* Bus granted */
+
+/*VR_CTL Masks*/
+#define WAKE 0x100
+#define VLEV_6 0x60
+#define VLEV_7 0x70
+#define VLEV_8 0x80
+#define VLEV_9 0x90
+#define VLEV_10 0xA0
+#define VLEV_11 0xB0
+#define VLEV_12 0xC0
+#define VLEV_13 0xD0
+#define VLEV_14 0xE0
+#define VLEV_15 0xF0
+#define FREQ_3 0x03
+
+#endif /* _DEF_BF532_H */
diff --git a/include/asm-blackfin/mach-bf533/dma.h b/include/asm-blackfin/mach-bf533/dma.h
new file mode 100644
index 0000000..bd9d5e9
--- /dev/null
+++ b/include/asm-blackfin/mach-bf533/dma.h
@@ -0,0 +1,54 @@
+/*****************************************************************************
+*
+* BF-533/2/1 Specific Declarations
+*
+****************************************************************************/
+/*
+ * File: include/asm-blackfin/mach-bf533/dma.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MACH_DMA_H_
+#define _MACH_DMA_H_
+
+#define MAX_BLACKFIN_DMA_CHANNEL 12
+
+#define CH_PPI 0
+#define CH_SPORT0_RX 1
+#define CH_SPORT0_TX 2
+#define CH_SPORT1_RX 3
+#define CH_SPORT1_TX 4
+#define CH_SPI 5
+#define CH_UART_RX 6
+#define CH_UART_TX 7
+#define CH_MEM_STREAM0_DEST 8 /* TX */
+#define CH_MEM_STREAM0_SRC 9 /* RX */
+#define CH_MEM_STREAM1_DEST 10 /* TX */
+#define CH_MEM_STREAM1_SRC 11 /* RX */
+
+#endif
diff --git a/include/asm-blackfin/mach-bf533/irq.h b/include/asm-blackfin/mach-bf533/irq.h
new file mode 100644
index 0000000..9879e68
--- /dev/null
+++ b/include/asm-blackfin/mach-bf533/irq.h
@@ -0,0 +1,177 @@
+/*
+ * File: include/asm-blackfin/mach-bf533/defBF532.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _BF533_IRQ_H_
+#define _BF533_IRQ_H_
+
+/*
+ * Interrupt source definitions
+ Event Source Core Event Name
+Core Emulation **
+ Events (highest priority) EMU 0
+ Reset RST 1
+ NMI NMI 2
+ Exception EVX 3
+ Reserved -- 4
+ Hardware Error IVHW 5
+ Core Timer IVTMR 6 *
+ PLL Wakeup Interrupt IVG7 7
+ DMA Error (generic) IVG7 8
+ PPI Error Interrupt IVG7 9
+ SPORT0 Error Interrupt IVG7 10
+ SPORT1 Error Interrupt IVG7 11
+ SPI Error Interrupt IVG7 12
+ UART Error Interrupt IVG7 13
+ RTC Interrupt IVG8 14
+ DMA0 Interrupt (PPI) IVG8 15
+ DMA1 (SPORT0 RX) IVG9 16
+ DMA2 (SPORT0 TX) IVG9 17
+ DMA3 (SPORT1 RX) IVG9 18
+ DMA4 (SPORT1 TX) IVG9 19
+ DMA5 (PPI) IVG10 20
+ DMA6 (UART RX) IVG10 21
+ DMA7 (UART TX) IVG10 22
+ Timer0 IVG11 23
+ Timer1 IVG11 24
+ Timer2 IVG11 25
+ PF Interrupt A IVG12 26
+ PF Interrupt B IVG12 27
+ DMA8/9 Interrupt IVG13 28
+ DMA10/11 Interrupt IVG13 29
+ Watchdog Timer IVG13 30
+ Software Interrupt 1 IVG14 31
+ Software Interrupt 2 --
+ (lowest priority) IVG15 32 *
+ */
+#define SYS_IRQS 32
+#define NR_PERI_INTS 24
+
+/* The ABSTRACT IRQ definitions */
+/** the first seven of the following are fixed, the rest you change if you need to **/
+#define IRQ_EMU 0 /*Emulation */
+#define IRQ_RST 1 /*reset */
+#define IRQ_NMI 2 /*Non Maskable */
+#define IRQ_EVX 3 /*Exception */
+#define IRQ_UNUSED 4 /*- unused interrupt*/
+#define IRQ_HWERR 5 /*Hardware Error */
+#define IRQ_CORETMR 6 /*Core timer */
+
+#define IRQ_PLL_WAKEUP 7 /*PLL Wakeup Interrupt */
+#define IRQ_DMA_ERROR 8 /*DMA Error (general) */
+#define IRQ_PPI_ERROR 9 /*PPI Error Interrupt */
+#define IRQ_SPORT0_ERROR 10 /*SPORT0 Error Interrupt */
+#define IRQ_SPORT1_ERROR 11 /*SPORT1 Error Interrupt */
+#define IRQ_SPI_ERROR 12 /*SPI Error Interrupt */
+#define IRQ_UART_ERROR 13 /*UART Error Interrupt */
+#define IRQ_RTC 14 /*RTC Interrupt */
+#define IRQ_PPI 15 /*DMA0 Interrupt (PPI) */
+#define IRQ_SPORT0_RX 16 /*DMA1 Interrupt (SPORT0 RX) */
+#define IRQ_SPORT0_TX 17 /*DMA2 Interrupt (SPORT0 TX) */
+#define IRQ_SPORT1_RX 18 /*DMA3 Interrupt (SPORT1 RX) */
+#define IRQ_SPORT1_TX 19 /*DMA4 Interrupt (SPORT1 TX) */
+#define IRQ_SPI 20 /*DMA5 Interrupt (SPI) */
+#define IRQ_UART_RX 21 /*DMA6 Interrupt (UART RX) */
+#define IRQ_UART_TX 22 /*DMA7 Interrupt (UART TX) */
+#define IRQ_TMR0 23 /*Timer 0 */
+#define IRQ_TMR1 24 /*Timer 1 */
+#define IRQ_TMR2 25 /*Timer 2 */
+#define IRQ_PROG_INTA 26 /*Programmable Flags A (8) */
+#define IRQ_PROG_INTB 27 /*Programmable Flags B (8) */
+#define IRQ_MEM_DMA0 28 /*DMA8/9 Interrupt (Memory DMA Stream 0) */
+#define IRQ_MEM_DMA1 29 /*DMA10/11 Interrupt (Memory DMA Stream 1) */
+#define IRQ_WATCH 30 /*Watch Dog Timer */
+
+#define IRQ_SW_INT1 31 /*Software Int 1 */
+#define IRQ_SW_INT2 32 /*Software Int 2 (reserved for SYSCALL) */
+
+#define IRQ_PF0 33
+#define IRQ_PF1 34
+#define IRQ_PF2 35
+#define IRQ_PF3 36
+#define IRQ_PF4 37
+#define IRQ_PF5 38
+#define IRQ_PF6 39
+#define IRQ_PF7 40
+#define IRQ_PF8 41
+#define IRQ_PF9 42
+#define IRQ_PF10 43
+#define IRQ_PF11 44
+#define IRQ_PF12 45
+#define IRQ_PF13 46
+#define IRQ_PF14 47
+#define IRQ_PF15 48
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+#define NR_IRQS (IRQ_PF15+1)
+#else
+#define NR_IRQS SYS_IRQS
+#endif
+
+#define IVG7 7
+#define IVG8 8
+#define IVG9 9
+#define IVG10 10
+#define IVG11 11
+#define IVG12 12
+#define IVG13 13
+#define IVG14 14
+#define IVG15 15
+
+/* IAR0 BIT FIELDS*/
+#define RTC_ERROR_POS 28
+#define UART_ERROR_POS 24
+#define SPORT1_ERROR_POS 20
+#define SPI_ERROR_POS 16
+#define SPORT0_ERROR_POS 12
+#define PPI_ERROR_POS 8
+#define DMA_ERROR_POS 4
+#define PLLWAKE_ERROR_POS 0
+
+/* IAR1 BIT FIELDS*/
+#define DMA7_UARTTX_POS 28
+#define DMA6_UARTRX_POS 24
+#define DMA5_SPI_POS 20
+#define DMA4_SPORT1TX_POS 16
+#define DMA3_SPORT1RX_POS 12
+#define DMA2_SPORT0TX_POS 8
+#define DMA1_SPORT0RX_POS 4
+#define DMA0_PPI_POS 0
+
+/* IAR2 BIT FIELDS*/
+#define WDTIMER_POS 28
+#define MEMDMA1_POS 24
+#define MEMDMA0_POS 20
+#define PFB_POS 16
+#define PFA_POS 12
+#define TIMER2_POS 8
+#define TIMER1_POS 4
+#define TIMER0_POS 0
+
+#endif /* _BF533_IRQ_H_ */
diff --git a/include/asm-blackfin/mach-bf533/mem_init.h b/include/asm-blackfin/mach-bf533/mem_init.h
new file mode 100644
index 0000000..1620dae
--- /dev/null
+++ b/include/asm-blackfin/mach-bf533/mem_init.h
@@ -0,0 +1,316 @@
+/*
+ * File: include/asm-blackfin/mach-bf533/mem_init.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#if (CONFIG_MEM_MT48LC16M16A2TG_75 || CONFIG_MEM_MT48LC64M4A2FB_7E || CONFIG_MEM_GENERIC_BOARD)
+#if (CONFIG_SCLK_HZ > 119402985)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_7
+#define SDRAM_tRAS_num 7
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 104477612) && (CONFIG_SCLK_HZ <= 119402985)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_6
+#define SDRAM_tRAS_num 6
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 8955223) && (CONFIG_SCLK_HZ <= 104477612)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_5
+#define SDRAM_tRAS_num 5
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 74626866) && (CONFIG_SCLK_HZ <= 89552239)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_4
+#define SDRAM_tRAS_num 4
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 66666667) && (CONFIG_SCLK_HZ <= 74626866)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_3
+#define SDRAM_tRAS_num 3
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 59701493) && (CONFIG_SCLK_HZ <= 66666667)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_4
+#define SDRAM_tRAS_num 3
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 44776119) && (CONFIG_SCLK_HZ <= 59701493)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_3
+#define SDRAM_tRAS_num 3
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 29850746) && (CONFIG_SCLK_HZ <= 44776119)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_2
+#define SDRAM_tRAS_num 2
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ <= 29850746)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_1
+#define SDRAM_tRAS_num 1
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#endif
+
+#if (CONFIG_MEM_MT48LC16M16A2TG_75)
+ /*SDRAM INFORMATION: */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC64M4A2FB_7E)
+ /*SDRAM INFORMATION: */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_GENERIC_BOARD)
+ /*SDRAM INFORMATION: Modify this for your board */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_SIZE == 128)
+#define SDRAM_SIZE EBSZ_128
+#endif
+#if (CONFIG_MEM_SIZE == 64)
+#define SDRAM_SIZE EBSZ_64
+#endif
+#if (CONFIG_MEM_SIZE == 32)
+#define SDRAM_SIZE EBSZ_32
+#endif
+#if (CONFIG_MEM_SIZE == 16)
+#define SDRAM_SIZE EBSZ_16
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 11)
+#define SDRAM_WIDTH EBCAW_11
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 10)
+#define SDRAM_WIDTH EBCAW_10
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 9)
+#define SDRAM_WIDTH EBCAW_9
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 8)
+#define SDRAM_WIDTH EBCAW_8
+#endif
+
+#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EBE)
+
+/* Equation from section 17 (p17-46) of BF533 HRM */
+#define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num)
+
+/* Enable SCLK Out */
+#define mem_SDGCTL (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS)
+
+#if defined CONFIG_CLKIN_HALF
+#define CLKIN_HALF 1
+#else
+#define CLKIN_HALF 0
+#endif
+
+#if defined CONFIG_PLL_BYPASS
+#define PLL_BYPASS 1
+#else
+#define PLL_BYPASS 0
+#endif
+
+/***************************************Currently Not Being Used *********************************/
+#define flash_EBIU_AMBCTL_WAT ((CONFIG_FLASH_SPEED_BWAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_RAT ((CONFIG_FLASH_SPEED_BRAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_HT ((CONFIG_FLASH_SPEED_BHT * 4) / (4000000000 / CONFIG_SCLK_HZ))
+#define flash_EBIU_AMBCTL_ST ((CONFIG_FLASH_SPEED_BST * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_TT ((CONFIG_FLASH_SPEED_BTT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+
+#if (flash_EBIU_AMBCTL_TT > 3)
+#define flash_EBIU_AMBCTL0_TT B0TT_4
+#endif
+#if (flash_EBIU_AMBCTL_TT == 3)
+#define flash_EBIU_AMBCTL0_TT B0TT_3
+#endif
+#if (flash_EBIU_AMBCTL_TT == 2)
+#define flash_EBIU_AMBCTL0_TT B0TT_2
+#endif
+#if (flash_EBIU_AMBCTL_TT < 2)
+#define flash_EBIU_AMBCTL0_TT B0TT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_ST > 3)
+#define flash_EBIU_AMBCTL0_ST B0ST_4
+#endif
+#if (flash_EBIU_AMBCTL_ST == 3)
+#define flash_EBIU_AMBCTL0_ST B0ST_3
+#endif
+#if (flash_EBIU_AMBCTL_ST == 2)
+#define flash_EBIU_AMBCTL0_ST B0ST_2
+#endif
+#if (flash_EBIU_AMBCTL_ST < 2)
+#define flash_EBIU_AMBCTL0_ST B0ST_1
+#endif
+
+#if (flash_EBIU_AMBCTL_HT > 2)
+#define flash_EBIU_AMBCTL0_HT B0HT_3
+#endif
+#if (flash_EBIU_AMBCTL_HT == 2)
+#define flash_EBIU_AMBCTL0_HT B0HT_2
+#endif
+#if (flash_EBIU_AMBCTL_HT == 1)
+#define flash_EBIU_AMBCTL0_HT B0HT_1
+#endif
+#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT == 0)
+#define flash_EBIU_AMBCTL0_HT B0HT_0
+#endif
+#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT != 0)
+#define flash_EBIU_AMBCTL0_HT B0HT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_WAT > 14)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_15
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 14)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_14
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 13)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_13
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 12)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_12
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 11)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_11
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 10)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_10
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 9)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_9
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 8)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_8
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 7)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_7
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 6)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_6
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 5)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_5
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 4)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_4
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 3)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_3
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 2)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_2
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 1)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_RAT > 14)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_15
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 14)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_14
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 13)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_13
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 12)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_12
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 11)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_11
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 10)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_10
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 9)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_9
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 8)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_8
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 7)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_7
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 6)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_6
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 5)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_5
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 4)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_4
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 3)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_3
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 2)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_2
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 1)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_1
+#endif
+
+#define flash_EBIU_AMBCTL0 \
+ (flash_EBIU_AMBCTL0_WAT | flash_EBIU_AMBCTL0_RAT | flash_EBIU_AMBCTL0_HT | \
+ flash_EBIU_AMBCTL0_ST | flash_EBIU_AMBCTL0_TT | CONFIG_FLASH_SPEED_RDYEN)
diff --git a/include/asm-blackfin/mach-bf533/mem_map.h b/include/asm-blackfin/mach-bf533/mem_map.h
new file mode 100644
index 0000000..e84baa3
--- /dev/null
+++ b/include/asm-blackfin/mach-bf533/mem_map.h
@@ -0,0 +1,168 @@
+
+/*
+ * File: include/asm-blackfin/mach-bf533/mem_map.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MEM_MAP_533_H_
+#define _MEM_MAP_533_H_
+
+#define COREMMR_BASE 0xFFE00000 /* Core MMRs */
+#define SYSMMR_BASE 0xFFC00000 /* System MMRs */
+
+/* Async Memory Banks */
+#define ASYNC_BANK3_BASE 0x20300000 /* Async Bank 3 */
+#define ASYNC_BANK3_SIZE 0x00100000 /* 1M */
+#define ASYNC_BANK2_BASE 0x20200000 /* Async Bank 2 */
+#define ASYNC_BANK2_SIZE 0x00100000 /* 1M */
+#define ASYNC_BANK1_BASE 0x20100000 /* Async Bank 1 */
+#define ASYNC_BANK1_SIZE 0x00100000 /* 1M */
+#define ASYNC_BANK0_BASE 0x20000000 /* Async Bank 0 */
+#define ASYNC_BANK0_SIZE 0x00100000 /* 1M */
+
+/* Boot ROM Memory */
+
+#define BOOT_ROM_START 0xEF000000
+
+/* Level 1 Memory */
+
+#ifdef CONFIG_BLKFIN_CACHE
+#define BLKFIN_ICACHESIZE (16*1024)
+#else
+#define BLKFIN_ICACHESIZE (0*1024)
+#endif
+
+/* Memory Map for ADSP-BF533 processors */
+
+#ifdef CONFIG_BF533
+#define L1_CODE_START 0xFFA00000
+#define L1_DATA_A_START 0xFF800000
+#define L1_DATA_B_START 0xFF900000
+
+#ifdef CONFIG_BLKFIN_CACHE
+#define L1_CODE_LENGTH (0x14000 - 0x4000)
+#else
+#define L1_CODE_LENGTH 0x14000
+#endif
+
+#ifdef CONFIG_BLKFIN_DCACHE
+
+#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH 0x8000
+#define BLKFIN_DCACHESIZE (16*1024)
+#define BLKFIN_DSUPBANKS 1
+#else
+#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH (0x8000 - 0x4000)
+#define BLKFIN_DCACHESIZE (32*1024)
+#define BLKFIN_DSUPBANKS 2
+#endif
+
+#else
+#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH 0x8000
+#define L1_DATA_B_LENGTH 0x8000
+#define BLKFIN_DCACHESIZE (0*1024)
+#define BLKFIN_DSUPBANKS 0
+#endif /*CONFIG_BLKFIN_DCACHE*/
+#endif
+
+/* Memory Map for ADSP-BF532 processors */
+
+#ifdef CONFIG_BF532
+#define L1_CODE_START 0xFFA08000
+#define L1_DATA_A_START 0xFF804000
+#define L1_DATA_B_START 0xFF904000
+
+#ifdef CONFIG_BLKFIN_CACHE
+#define L1_CODE_LENGTH (0xC000 - 0x4000)
+#else
+#define L1_CODE_LENGTH 0xC000
+#endif
+
+#ifdef CONFIG_BLKFIN_DCACHE
+
+#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x4000 - 0x4000)
+#define L1_DATA_B_LENGTH 0x4000
+#define BLKFIN_DCACHESIZE (16*1024)
+#define BLKFIN_DSUPBANKS 1
+
+#else
+#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x4000 - 0x4000)
+#define L1_DATA_B_LENGTH (0x4000 - 0x4000)
+#define BLKFIN_DCACHESIZE (32*1024)
+#define BLKFIN_DSUPBANKS 2
+#endif
+
+#else
+#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH 0x4000
+#define L1_DATA_B_LENGTH 0x4000
+#define BLKFIN_DCACHESIZE (0*1024)
+#define BLKFIN_DSUPBANKS 0
+#endif /*CONFIG_BLKFIN_DCACHE*/
+#endif
+
+/* Memory Map for ADSP-BF531 processors */
+
+#ifdef CONFIG_BF531
+#define L1_CODE_START 0xFFA08000
+#define L1_DATA_A_START 0xFF804000
+#define L1_DATA_B_START 0xFF904000
+#define L1_CODE_LENGTH 0x4000
+#define L1_DATA_B_LENGTH 0x0000
+
+
+#ifdef CONFIG_BLKFIN_DCACHE
+#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x4000 - 0x4000)
+#define BLKFIN_DCACHESIZE (16*1024)
+#define BLKFIN_DSUPBANKS 1
+#else
+#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH 0x4000
+#define BLKFIN_DCACHESIZE (0*1024)
+#define BLKFIN_DSUPBANKS 0
+#endif
+
+#endif
+
+/* Scratch Pad Memory */
+
+#if defined(CONFIG_BF533) || defined(CONFIG_BF532) || defined(CONFIG_BF531)
+#define L1_SCRATCH_START 0xFFB00000
+#define L1_SCRATCH_LENGTH 0x1000
+#endif
+
+#endif /* _MEM_MAP_533_H_ */
diff --git a/include/asm-blackfin/mach-bf537/anomaly.h b/include/asm-blackfin/mach-bf537/anomaly.h
new file mode 100644
index 0000000..7f040f5
--- /dev/null
+++ b/include/asm-blackfin/mach-bf537/anomaly.h
@@ -0,0 +1,120 @@
+
+/*
+ * File: include/asm-blackfin/mach-bf537/anomaly.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* This file shoule be up to date with:
+ * - Revision J, June 1, 2006; ADSP-BF537 Blackfin Processor Anomaly List
+ * - Revision I, June 1, 2006; ADSP-BF536 Blackfin Processor Anomaly List
+ * - Revision J, June 1, 2006; ADSP-BF534 Blackfin Processor Anomaly List
+ */
+
+#ifndef _MACH_ANOMALY_H_
+#define _MACH_ANOMALY_H_
+
+/* We do not support 0.1 silicon - sorry */
+#if (defined(CONFIG_BF_REV_0_1))
+#error Kernel will not work on BF537/6/4 Version 0.1
+#endif
+
+#if (defined(CONFIG_BF_REV_0_3) || defined(CONFIG_BF_REV_0_2))
+#define ANOMALY_05000074 /* A multi issue instruction with dsp32shiftimm in
+ slot1 and store of a P register in slot 2 is not
+ supported */
+#define ANOMALY_05000119 /* DMA_RUN bit is not valid after a Peripheral Receive
+ Channel DMA stops */
+#define ANOMALY_05000122 /* Rx.H can not be used to access 16-bit System MMR
+ registers. */
+#define ANOMALY_05000166 /* PPI Data Lengths Between 8 and 16 do not zero out
+ upper bits*/
+#define ANOMALY_05000180 /* PPI_DELAY not functional in PPI modes with 0 frame
+ syncs */
+#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
+#define ANOMALY_05000247 /* CLKIN Buffer Output Enable Reset Behavior Is
+ Changed */
+#endif
+#define ANOMALY_05000265 /* Sensitivity to noise with slow input edge rates on
+ SPORT external receive and transmit clocks. */
+#define ANOMALY_05000272 /* Certain data cache write through modes fail for
+ VDDint <=0.9V */
+#define ANOMALY_05000273 /* Writes to Synchronous SDRAM memory may be lost */
+#define ANOMALY_05000277 /* Writes to a flag data register one SCLK cycle after
+ an edge is detected may clear interrupt */
+#define ANOMALY_05000281 /* False Hardware Error Exception when ISR context is
+ not restored */
+#define ANOMALY_05000282 /* Memory DMA corruption with 32-bit data and traffic
+ control */
+#define ANOMALY_05000283 /* A system MMR write is stalled indefinitely when
+ killed in a particular stage*/
+#define ANOMALY_05000312 /* Errors when SSYNC, CSYNC, or loads to LT, LB and LC
+ registers are interrupted */
+#endif
+
+#if defined(CONFIG_BF_REV_0_2)
+#define ANOMALY_05000244 /* With instruction cache enabled, a CSYNC or SSYNC or
+ IDLE around a Change of Control causes
+ unpredictable results */
+#define ANOMALY_05000250 /* Incorrect Bit-Shift of Data Word in Multichannel
+ (TDM) */
+#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
+#define ANOMALY_05000252 /* EMAC Tx DMA error after an early frame abort */
+#endif
+#define ANOMALY_05000253 /* Maximum external clock speed for Timers */
+#define ANOMALY_05000255 /* Entering Hibernate Mode with RTC Seconds event
+ interrupt not functional */
+#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
+#define ANOMALY_05000256 /* EMAC MDIO input latched on wrong MDC edge */
+#endif
+#define ANOMALY_05000257 /* An interrupt or exception during short Hardware
+ loops may cause the instruction fetch unit to
+ malfunction */
+#define ANOMALY_05000258 /* Instruction Cache is corrupted when bit 9 and 12 of
+ the ICPLB Data registers differ */
+#define ANOMALY_05000260 /* ICPLB_STATUS MMR register may be corrupted */
+#define ANOMALY_05000261 /* DCPLB_FAULT_ADDR MMR register may be corrupted */
+#define ANOMALY_05000262 /* Stores to data cache may be lost */
+#define ANOMALY_05000263 /* Hardware loop corrupted when taking an ICPLB exception */
+#define ANOMALY_05000264 /* A Sync instruction (CSYNC, SSYNC) or an IDLE
+ instruction will cause an infinite stall in the
+ second to last instruction in a hardware loop */
+#define ANOMALY_05000268 /* Memory DMA error when peripheral DMA is running
+ and non-zero DEB_TRAFFIC_PERIOD value */
+#define ANOMALY_05000270 /* High I/O activity causes the output voltage of the
+ internal voltage regulator (VDDint) to decrease */
+#define ANOMALY_05000277 /* Writes to a flag data register one SCLK cycle after
+ an edge is detected may clear interrupt */
+#define ANOMALY_05000278 /* Disabling Peripherals with DMA running may cause
+ DMA system instability */
+#define ANOMALY_05000280 /* SPI Master boot mode does not work well with
+ Atmel Dataflash devices */
+
+#endif /* CONFIG_BF_REV_0_2 */
+
+#endif /* _MACH_ANOMALY_H_ */
diff --git a/include/asm-blackfin/mach-bf537/bf537.h b/include/asm-blackfin/mach-bf537/bf537.h
new file mode 100644
index 0000000..b8924cd
--- /dev/null
+++ b/include/asm-blackfin/mach-bf537/bf537.h
@@ -0,0 +1,287 @@
+/*
+ * File: include/asm-blackfin/mach-bf537/bf537.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF537
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __MACH_BF537_H__
+#define __MACH_BF537_H__
+
+#define SUPPORTED_REVID 2
+
+/* Masks for generic ERROR IRQ demultiplexing used in int-priority-sc.c */
+
+#define SPI_ERR_MASK (TXCOL | RBSY | MODF | TXE) /* SPI_STAT */
+#define SPORT_ERR_MASK (ROVF | RUVF | TOVF | TUVF) /* SPORTx_STAT */
+#define PPI_ERR_MASK (0xFFFF & ~FLD) /* PPI_STATUS */
+#define EMAC_ERR_MASK (PHYINT | MMCINT | RXFSINT | TXFSINT | WAKEDET | RXDMAERR | TXDMAERR | STMDONE) /* EMAC_SYSTAT */
+#define UART_ERR_MASK_STAT1 (0x4) /* UARTx_IIR */
+#define UART_ERR_MASK_STAT0 (0x2) /* UARTx_IIR */
+#define CAN_ERR_MASK (EWTIF | EWRIF | EPIF | BOIF | WUIF | UIAIF | AAIF | RMLIF | UCEIF | EXTIF | ADIF) /* CAN_GIF */
+
+#define OFFSET_(x) ((x) & 0x0000FFFF)
+
+/*some misc defines*/
+#define IMASK_IVG15 0x8000
+#define IMASK_IVG14 0x4000
+#define IMASK_IVG13 0x2000
+#define IMASK_IVG12 0x1000
+
+#define IMASK_IVG11 0x0800
+#define IMASK_IVG10 0x0400
+#define IMASK_IVG9 0x0200
+#define IMASK_IVG8 0x0100
+
+#define IMASK_IVG7 0x0080
+#define IMASK_IVGTMR 0x0040
+#define IMASK_IVGHW 0x0020
+
+/***************************/
+
+
+#define BLKFIN_DSUBBANKS 4
+#define BLKFIN_DWAYS 2
+#define BLKFIN_DLINES 64
+#define BLKFIN_ISUBBANKS 4
+#define BLKFIN_IWAYS 4
+#define BLKFIN_ILINES 32
+
+#define WAY0_L 0x1
+#define WAY1_L 0x2
+#define WAY01_L 0x3
+#define WAY2_L 0x4
+#define WAY02_L 0x5
+#define WAY12_L 0x6
+#define WAY012_L 0x7
+
+#define WAY3_L 0x8
+#define WAY03_L 0x9
+#define WAY13_L 0xA
+#define WAY013_L 0xB
+
+#define WAY32_L 0xC
+#define WAY320_L 0xD
+#define WAY321_L 0xE
+#define WAYALL_L 0xF
+
+#define DMC_ENABLE (2<<2) /*yes, 2, not 1 */
+
+/********************************* EBIU Settings ************************************/
+#define AMBCTL0VAL ((CONFIG_BANK_1 << 16) | CONFIG_BANK_0)
+#define AMBCTL1VAL ((CONFIG_BANK_3 << 16) | CONFIG_BANK_2)
+
+#ifdef CONFIG_C_AMBEN_ALL
+#define V_AMBEN AMBEN_ALL
+#endif
+#ifdef CONFIG_C_AMBEN
+#define V_AMBEN 0x0
+#endif
+#ifdef CONFIG_C_AMBEN_B0
+#define V_AMBEN AMBEN_B0
+#endif
+#ifdef CONFIG_C_AMBEN_B0_B1
+#define V_AMBEN AMBEN_B0_B1
+#endif
+#ifdef CONFIG_C_AMBEN_B0_B1_B2
+#define V_AMBEN AMBEN_B0_B1_B2
+#endif
+#ifdef CONFIG_C_AMCKEN
+#define V_AMCKEN AMCKEN
+#else
+#define V_AMCKEN 0x0
+#endif
+#ifdef CONFIG_C_CDPRIO
+#define V_CDPRIO 0x100
+#else
+#define V_CDPRIO 0x0
+#endif
+
+#define AMGCTLVAL (V_AMBEN | V_AMCKEN | V_CDPRIO)
+
+#define MAX_VC 650000000
+#define MIN_VC 50000000
+
+/********************************PLL Settings **************************************/
+#ifdef CONFIG_BFIN_KERNEL_CLOCK
+#if (CONFIG_VCO_MULT < 0)
+#error "VCO Multiplier is less than 0. Please select a different value"
+#endif
+
+#if (CONFIG_VCO_MULT == 0)
+#error "VCO Multiplier should be greater than 0. Please select a different value"
+#endif
+
+#if (CONFIG_VCO_MULT > 64)
+#error "VCO Multiplier is more than 64. Please select a different value"
+#endif
+
+#ifndef CONFIG_CLKIN_HALF
+#define CONFIG_VCO_HZ (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)
+#else
+#define CONFIG_VCO_HZ ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)/2)
+#endif
+
+#ifndef CONFIG_PLL_BYPASS
+#define CONFIG_CCLK_HZ (CONFIG_VCO_HZ/CONFIG_CCLK_DIV)
+#define CONFIG_SCLK_HZ (CONFIG_VCO_HZ/CONFIG_SCLK_DIV)
+#else
+#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ
+#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ
+#endif
+
+#if (CONFIG_SCLK_DIV < 1)
+#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
+#endif
+
+#if (CONFIG_SCLK_DIV > 15)
+#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
+#endif
+
+#if (CONFIG_CCLK_DIV != 1)
+#if (CONFIG_CCLK_DIV != 2)
+#if (CONFIG_CCLK_DIV != 4)
+#if (CONFIG_CCLK_DIV != 8)
+#error "CCLK DIV can be 1,2,4 or 8 only. Please select a proper value"
+#endif
+#endif
+#endif
+#endif
+
+#if (CONFIG_VCO_HZ > MAX_VC)
+#error "VCO selected is more than maximum value. Please change the VCO multipler"
+#endif
+
+#if (CONFIG_SCLK_HZ > 133000000)
+#error "Sclk value selected is more than maximum. Please select a proper value for SCLK multiplier"
+#endif
+
+#if (CONFIG_SCLK_HZ < 27000000)
+#error "Sclk value selected is less than minimum. Please select a proper value for SCLK multiplier"
+#endif
+
+#if (CONFIG_SCLK_HZ >= CONFIG_CCLK_HZ)
+#if (CONFIG_SCLK_HZ != CONFIG_CLKIN_HZ)
+#if (CONFIG_CCLK_HZ != CONFIG_CLKIN_HZ)
+#error "Please select sclk less than cclk"
+#endif
+#endif
+#endif
+
+#if (CONFIG_CCLK_DIV == 1)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV1
+#endif
+#if (CONFIG_CCLK_DIV == 2)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV2
+#endif
+#if (CONFIG_CCLK_DIV == 4)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV4
+#endif
+#if (CONFIG_CCLK_DIV == 8)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV8
+#endif
+#ifndef CONFIG_CCLK_ACT_DIV
+#define CONFIG_CCLK_ACT_DIV CONFIG_CCLK_DIV_not_defined_properly
+#endif
+
+#if defined(ANOMALY_05000273) && (CONFIG_CCLK_DIV == 1)
+#error ANOMALY 05000273, please make sure CCLK is at least 2x SCLK
+#endif
+
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+#ifdef CONFIG_BF537
+#define CPU "BF537"
+#define CPUID 0x027c8000
+#endif
+#ifdef CONFIG_BF536
+#define CPU "BF536"
+#define CPUID 0x027c8000
+#endif
+#ifdef CONFIG_BF534
+#define CPU "BF534"
+#define CPUID 0x027c6000
+#endif
+#ifndef CPU
+#define CPU "UNKNOWN"
+#define CPUID 0x0
+#endif
+
+#if (CONFIG_MEM_SIZE % 4)
+#error "SDRAM mem size must be multible of 4MB"
+#endif
+
+#define SDRAM_IGENERIC (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO)
+#define SDRAM_IKERNEL (SDRAM_IGENERIC | CPLB_LOCK)
+#define L1_IMEMORY ( CPLB_USER_RD | CPLB_VALID | CPLB_LOCK)
+#define SDRAM_INON_CHBL ( CPLB_USER_RD | CPLB_VALID)
+
+/*Use the menuconfig cache policy here - CONFIG_BLKFIN_WT/CONFIG_BLKFIN_WB*/
+
+#define ANOMALY_05000158_WORKAROUND 0x200
+#ifdef CONFIG_BLKFIN_WB /*Write Back Policy */
+#define SDRAM_DGENERIC (CPLB_L1_CHBL | CPLB_DIRTY \
+ | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)
+#else /*Write Through */
+#define SDRAM_DGENERIC (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW \
+ | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
+#endif
+
+
+#define L1_DMEMORY (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY )
+#define SDRAM_DNON_CHBL (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
+#define SDRAM_EBIU (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
+#define SDRAM_OOPS (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY )
+
+#define SIZE_1K 0x00000400 /* 1K */
+#define SIZE_4K 0x00001000 /* 4K */
+#define SIZE_1M 0x00100000 /* 1M */
+#define SIZE_4M 0x00400000 /* 4M */
+
+#define MAX_CPLBS (16 * 2)
+
+/*
+* Number of required data CPLB switchtable entries
+* MEMSIZE / 4 (we mostly install 4M page size CPLBs
+* approx 16 for smaller 1MB page size CPLBs for allignment purposes
+* 1 for L1 Data Memory
+* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
+* 1 for ASYNC Memory
+*/
+
+
+#define MAX_SWITCH_D_CPLBS (((CONFIG_MEM_SIZE / 4) + 16 + 1 + 1 + 1) * 2)
+
+/*
+* Number of required instruction CPLB switchtable entries
+* MEMSIZE / 4 (we mostly install 4M page size CPLBs
+* approx 12 for smaller 1MB page size CPLBs for allignment purposes
+* 1 for L1 Instruction Memory
+* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
+*/
+
+#define MAX_SWITCH_I_CPLBS (((CONFIG_MEM_SIZE / 4) + 12 + 1 + 1) * 2)
+
+#endif /* __MACH_BF537_H__ */
diff --git a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
new file mode 100644
index 0000000..8f5d9c4
--- /dev/null
+++ b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
@@ -0,0 +1,147 @@
+#include <linux/serial.h>
+#include <asm/dma.h>
+
+#define NR_PORTS 2
+
+#define OFFSET_THR 0x00 /* Transmit Holding register */
+#define OFFSET_RBR 0x00 /* Receive Buffer register */
+#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */
+#define OFFSET_IER 0x04 /* Interrupt Enable Register */
+#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */
+#define OFFSET_IIR 0x08 /* Interrupt Identification Register */
+#define OFFSET_LCR 0x0C /* Line Control Register */
+#define OFFSET_MCR 0x10 /* Modem Control Register */
+#define OFFSET_LSR 0x14 /* Line Status Register */
+#define OFFSET_MSR 0x18 /* Modem Status Register */
+#define OFFSET_SCR 0x1C /* SCR Scratch Register */
+#define OFFSET_GCTL 0x24 /* Global Control Register */
+
+#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR))
+#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL))
+#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER))
+#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
+#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR))
+#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
+#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR))
+#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
+
+#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v)
+#define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
+#define UART_PUT_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER),v)
+#define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
+#define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
+#define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
+
+#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
+# define CONFIG_SERIAL_BFIN_CTSRTS
+
+# ifndef CONFIG_UART0_CTS_PIN
+# define CONFIG_UART0_CTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART0_RTS_PIN
+# define CONFIG_UART0_RTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART1_CTS_PIN
+# define CONFIG_UART1_CTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART1_RTS_PIN
+# define CONFIG_UART1_RTS_PIN -1
+# endif
+#endif
+/*
+ * The pin configuration is different from schematic
+ */
+struct bfin_serial_port {
+ struct uart_port port;
+ unsigned int old_status;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ int tx_done;
+ int tx_count;
+ struct circ_buf rx_dma_buf;
+ struct timer_list rx_dma_timer;
+ int rx_dma_nrows;
+ unsigned int tx_dma_channel;
+ unsigned int rx_dma_channel;
+ struct work_struct tx_dma_workqueue;
+#else
+ struct work_struct cts_workqueue;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ int cts_pin;
+ int rts_pin;
+#endif
+};
+
+struct bfin_serial_port bfin_serial_ports[NR_PORTS];
+struct bfin_serial_res {
+ unsigned long uart_base_addr;
+ int uart_irq;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ unsigned int uart_tx_dma_channel;
+ unsigned int uart_rx_dma_channel;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ int uart_cts_pin;
+ int uart_rts_pin;
+#endif
+};
+
+struct bfin_serial_res bfin_serial_resource[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ {
+ 0xFFC00400,
+ IRQ_UART0_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ CH_UART0_TX,
+ CH_UART0_RX,
+#endif
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+ CONFIG_UART0_CTS_PIN,
+ CONFIG_UART0_RTS_PIN,
+#endif
+ },
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ {
+ 0xFFC02000,
+ IRQ_UART1_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ CH_UART1_TX,
+ CH_UART1_RX,
+#endif
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+ CONFIG_UART1_CTS_PIN,
+ CONFIG_UART1_RTS_PIN,
+#endif
+ },
+#endif
+};
+
+int nr_ports = ARRAY_SIZE(bfin_serial_resource);
+
+static void bfin_serial_hw_init(struct bfin_serial_port *uart)
+{
+ unsigned short val;
+ val = bfin_read16(BFIN_PORT_MUX);
+ val &= ~(PFDE | PFTE);
+ bfin_write16(BFIN_PORT_MUX, val);
+
+ val = bfin_read16(PORTF_FER);
+ val |= 0xF;
+ bfin_write16(PORTF_FER, val);
+
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ if (uart->cts_pin >= 0) {
+ gpio_request(uart->cts_pin, NULL);
+ gpio_direction_input(uart->cts_pin);
+ }
+
+ if (uart->rts_pin >= 0) {
+ gpio_request(uart->rts_pin, NULL);
+ gpio_direction_output(uart->rts_pin);
+ }
+#endif
+}
diff --git a/include/asm-blackfin/mach-bf537/blackfin.h b/include/asm-blackfin/mach-bf537/blackfin.h
new file mode 100644
index 0000000..bbd9705
--- /dev/null
+++ b/include/asm-blackfin/mach-bf537/blackfin.h
@@ -0,0 +1,430 @@
+/*
+ * File: include/asm-blackfin/mach-bf537/blackfin.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MACH_BLACKFIN_H_
+#define _MACH_BLACKFIN_H_
+
+#define BF537_FAMILY
+
+#include "bf537.h"
+#include "mem_map.h"
+#include "defBF534.h"
+#include "anomaly.h"
+
+#if defined(CONFIG_BF537) || defined(CONFIG_BF536)
+#include "defBF537.h"
+#endif
+
+#if !(defined(__ASSEMBLY__) || defined(ASSEMBLY))
+#include "cdefBF534.h"
+
+/* UART 0*/
+#define bfin_read_UART_THR() bfin_read_UART0_THR()
+#define bfin_write_UART_THR(val) bfin_write_UART0_THR(val)
+#define bfin_read_UART_RBR() bfin_read_UART0_RBR()
+#define bfin_write_UART_RBR(val) bfin_write_UART0_RBR(val)
+#define bfin_read_UART_DLL() bfin_read_UART0_DLL()
+#define bfin_write_UART_DLL(val) bfin_write_UART0_DLL(val)
+#define bfin_read_UART_IER() bfin_read_UART0_IER()
+#define bfin_write_UART_IER(val) bfin_write_UART0_IER(val)
+#define bfin_read_UART_DLH() bfin_read_UART0_DLH()
+#define bfin_write_UART_DLH(val) bfin_write_UART0_DLH(val)
+#define bfin_read_UART_IIR() bfin_read_UART0_IIR()
+#define bfin_write_UART_IIR(val) bfin_write_UART0_IIR(val)
+#define bfin_read_UART_LCR() bfin_read_UART0_LCR()
+#define bfin_write_UART_LCR(val) bfin_write_UART0_LCR(val)
+#define bfin_read_UART_MCR() bfin_read_UART0_MCR()
+#define bfin_write_UART_MCR(val) bfin_write_UART0_MCR(val)
+#define bfin_read_UART_LSR() bfin_read_UART0_LSR()
+#define bfin_write_UART_LSR(val) bfin_write_UART0_LSR(val)
+#define bfin_read_UART_SCR() bfin_read_UART0_SCR()
+#define bfin_write_UART_SCR(val) bfin_write_UART0_SCR(val)
+#define bfin_read_UART_GCTL() bfin_read_UART0_GCTL()
+#define bfin_write_UART_GCTL(val) bfin_write_UART0_GCTL(val)
+
+#if defined(CONFIG_BF537) || defined(CONFIG_BF536)
+#include "cdefBF537.h"
+#endif
+#endif
+
+/* MAP used DEFINES from BF533 to BF537 - so we don't need to change them in the driver, kernel, etc. */
+
+/* UART_IIR Register */
+#define STATUS(x) ((x << 1) & 0x06)
+#define STATUS_P1 0x02
+#define STATUS_P0 0x01
+
+/* UART 0*/
+
+/* DMA Channnel */
+#define bfin_read_CH_UART_RX() bfin_read_CH_UART0_RX()
+#define bfin_write_CH_UART_RX(val) bfin_write_CH_UART0_RX(val)
+#define CH_UART_RX CH_UART0_RX
+#define bfin_read_CH_UART_TX() bfin_read_CH_UART0_TX()
+#define bfin_write_CH_UART_TX(val) bfin_write_CH_UART0_TX(val)
+#define CH_UART_TX CH_UART0_TX
+
+/* System Interrupt Controller */
+#define bfin_read_IRQ_UART_RX() bfin_read_IRQ_UART0_RX()
+#define bfin_write_IRQ_UART_RX(val) bfin_write_IRQ_UART0_RX(val)
+#define IRQ_UART_RX IRQ_UART0_RX
+#define bfin_read_IRQ_UART_TX() bfin_read_IRQ_UART0_TX()
+#define bfin_write_IRQ_UART_TX(val) bfin_write_IRQ_UART0_TX(val)
+#define IRQ_UART_TX IRQ_UART0_TX
+#define bfin_read_IRQ_UART_ERROR() bfin_read_IRQ_UART0_ERROR()
+#define bfin_write_IRQ_UART_ERROR(val) bfin_write_IRQ_UART0_ERROR(val)
+#define IRQ_UART_ERROR IRQ_UART0_ERROR
+
+/* MMR Registers*/
+#define bfin_read_UART_THR() bfin_read_UART0_THR()
+#define bfin_write_UART_THR(val) bfin_write_UART0_THR(val)
+#define UART_THR UART0_THR
+#define bfin_read_UART_RBR() bfin_read_UART0_RBR()
+#define bfin_write_UART_RBR(val) bfin_write_UART0_RBR(val)
+#define UART_RBR UART0_RBR
+#define bfin_read_UART_DLL() bfin_read_UART0_DLL()
+#define bfin_write_UART_DLL(val) bfin_write_UART0_DLL(val)
+#define UART_DLL UART0_DLL
+#define bfin_read_UART_IER() bfin_read_UART0_IER()
+#define bfin_write_UART_IER(val) bfin_write_UART0_IER(val)
+#define UART_IER UART0_IER
+#define bfin_read_UART_DLH() bfin_read_UART0_DLH()
+#define bfin_write_UART_DLH(val) bfin_write_UART0_DLH(val)
+#define UART_DLH UART0_DLH
+#define bfin_read_UART_IIR() bfin_read_UART0_IIR()
+#define bfin_write_UART_IIR(val) bfin_write_UART0_IIR(val)
+#define UART_IIR UART0_IIR
+#define bfin_read_UART_LCR() bfin_read_UART0_LCR()
+#define bfin_write_UART_LCR(val) bfin_write_UART0_LCR(val)
+#define UART_LCR UART0_LCR
+#define bfin_read_UART_MCR() bfin_read_UART0_MCR()
+#define bfin_write_UART_MCR(val) bfin_write_UART0_MCR(val)
+#define UART_MCR UART0_MCR
+#define bfin_read_UART_LSR() bfin_read_UART0_LSR()
+#define bfin_write_UART_LSR(val) bfin_write_UART0_LSR(val)
+#define UART_LSR UART0_LSR
+#define bfin_read_UART_SCR() bfin_read_UART0_SCR()
+#define bfin_write_UART_SCR(val) bfin_write_UART0_SCR(val)
+#define UART_SCR UART0_SCR
+#define bfin_read_UART_GCTL() bfin_read_UART0_GCTL()
+#define bfin_write_UART_GCTL(val) bfin_write_UART0_GCTL(val)
+#define UART_GCTL UART0_GCTL
+
+/* DPMC*/
+#define bfin_read_STOPCK_OFF() bfin_read_STOPCK()
+#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val)
+#define STOPCK_OFF STOPCK
+
+/* FIO USE PORT F*/
+#ifdef CONFIG_BF537_PORT_F
+#define bfin_read_PORT_FER() bfin_read_PORTF_FER()
+#define bfin_write_PORT_FER(val) bfin_write_PORTF_FER(val)
+#define bfin_read_FIO_FLAG_D() bfin_read_PORTFIO()
+#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTFIO(val)
+#define bfin_read_FIO_FLAG_C() bfin_read_PORTFIO_CLEAR()
+#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTFIO_CLEAR(val)
+#define bfin_read_FIO_FLAG_S() bfin_read_PORTFIO_SET()
+#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTFIO_SET(val)
+#define bfin_read_FIO_FLAG_T() bfin_read_PORTFIO_TOGGLE()
+#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTFIO_TOGGLE(val)
+#define bfin_read_FIO_MASKA_D() bfin_read_PORTFIO_MASKA()
+#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTFIO_MASKA(val)
+#define bfin_read_FIO_MASKA_C() bfin_read_PORTFIO_MASKA_CLEAR()
+#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTFIO_MASKA_CLEAR(val)
+#define bfin_read_FIO_MASKA_S() bfin_read_PORTFIO_MASKA_SET()
+#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTFIO_MASKA_SET(val)
+#define bfin_read_FIO_MASKA_T() bfin_read_PORTFIO_MASKA_TOGGLE()
+#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTFIO_MASKA_TOGGLE(val)
+#define bfin_read_FIO_MASKB_D() bfin_read_PORTFIO_MASKB()
+#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTFIO_MASKB(val)
+#define bfin_read_FIO_MASKB_C() bfin_read_PORTFIO_MASKB_CLEAR()
+#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTFIO_MASKB_CLEAR(val)
+#define bfin_read_FIO_MASKB_S() bfin_read_PORTFIO_MASKB_SET()
+#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTFIO_MASKB_SET(val)
+#define bfin_read_FIO_MASKB_T() bfin_read_PORTFIO_MASKB_TOGGLE()
+#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTFIO_MASKB_TOGGLE(val)
+#define bfin_read_FIO_DIR() bfin_read_PORTFIO_DIR()
+#define bfin_write_FIO_DIR(val) bfin_write_PORTFIO_DIR(val)
+#define bfin_read_FIO_POLAR() bfin_read_PORTFIO_POLAR()
+#define bfin_write_FIO_POLAR(val) bfin_write_PORTFIO_POLAR(val)
+#define bfin_read_FIO_EDGE() bfin_read_PORTFIO_EDGE()
+#define bfin_write_FIO_EDGE(val) bfin_write_PORTFIO_EDGE(val)
+#define bfin_read_FIO_BOTH() bfin_read_PORTFIO_BOTH()
+#define bfin_write_FIO_BOTH(val) bfin_write_PORTFIO_BOTH(val)
+#define bfin_read_FIO_INEN() bfin_read_PORTFIO_INEN()
+#define bfin_write_FIO_INEN(val) bfin_write_PORTFIO_INEN(val)
+
+#define bfin_read_FIO_FLAG_D() bfin_read_PORTFIO()
+#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTFIO(val)
+#define FIO_FLAG_D PORTFIO
+#define bfin_read_FIO_FLAG_C() bfin_read_PORTFIO_CLEAR()
+#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTFIO_CLEAR(val)
+#define FIO_FLAG_C PORTFIO_CLEAR
+#define bfin_read_FIO_FLAG_S() bfin_read_PORTFIO_SET()
+#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTFIO_SET(val)
+#define FIO_FLAG_S PORTFIO_SET
+#define bfin_read_FIO_FLAG_T() bfin_read_PORTFIO_TOGGLE()
+#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTFIO_TOGGLE(val)
+#define FIO_FLAG_T PORTFIO_TOGGLE
+#define bfin_read_FIO_MASKA_D() bfin_read_PORTFIO_MASKA()
+#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTFIO_MASKA(val)
+#define FIO_MASKA_D PORTFIO_MASKA
+#define bfin_read_FIO_MASKA_C() bfin_read_PORTFIO_MASKA_CLEAR()
+#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTFIO_MASKA_CLEAR(val)
+#define FIO_MASKA_C PORTFIO_MASKA_CLEAR
+#define bfin_read_FIO_MASKA_S() bfin_read_PORTFIO_MASKA_SET()
+#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTFIO_MASKA_SET(val)
+#define FIO_MASKA_S PORTFIO_MASKA_SET
+#define bfin_read_FIO_MASKA_T() bfin_read_PORTFIO_MASKA_TOGGLE()
+#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTFIO_MASKA_TOGGLE(val)
+#define FIO_MASKA_T PORTFIO_MASKA_TOGGLE
+#define bfin_read_FIO_MASKB_D() bfin_read_PORTFIO_MASKB()
+#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTFIO_MASKB(val)
+#define FIO_MASKB_D PORTFIO_MASKB
+#define bfin_read_FIO_MASKB_C() bfin_read_PORTFIO_MASKB_CLEAR()
+#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTFIO_MASKB_CLEAR(val)
+#define FIO_MASKB_C PORTFIO_MASKB_CLEAR
+#define bfin_read_FIO_MASKB_S() bfin_read_PORTFIO_MASKB_SET()
+#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTFIO_MASKB_SET(val)
+#define FIO_MASKB_S PORTFIO_MASKB_SET
+#define bfin_read_FIO_MASKB_T() bfin_read_PORTFIO_MASKB_TOGGLE()
+#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTFIO_MASKB_TOGGLE(val)
+#define FIO_MASKB_T PORTFIO_MASKB_TOGGLE
+#define bfin_read_FIO_DIR() bfin_read_PORTFIO_DIR()
+#define bfin_write_FIO_DIR(val) bfin_write_PORTFIO_DIR(val)
+#define FIO_DIR PORTFIO_DIR
+#define bfin_read_FIO_POLAR() bfin_read_PORTFIO_POLAR()
+#define bfin_write_FIO_POLAR(val) bfin_write_PORTFIO_POLAR(val)
+#define FIO_POLAR PORTFIO_POLAR
+#define bfin_read_FIO_EDGE() bfin_read_PORTFIO_EDGE()
+#define bfin_write_FIO_EDGE(val) bfin_write_PORTFIO_EDGE(val)
+#define FIO_EDGE PORTFIO_EDGE
+#define bfin_read_FIO_BOTH() bfin_read_PORTFIO_BOTH()
+#define bfin_write_FIO_BOTH(val) bfin_write_PORTFIO_BOTH(val)
+#define FIO_BOTH PORTFIO_BOTH
+#define bfin_read_FIO_INEN() bfin_read_PORTFIO_INEN()
+#define bfin_write_FIO_INEN(val) bfin_write_PORTFIO_INEN(val)
+#define FIO_INEN PORTFIO_INEN
+#endif
+
+/* FIO USE PORT G*/
+#ifdef CONFIG_BF537_PORT_G
+#define bfin_read_PORT_FER() bfin_read_PORTG_FER()
+#define bfin_write_PORT_FER(val) bfin_write_PORTG_FER(val)
+#define bfin_read_FIO_FLAG_D() bfin_read_PORTGIO()
+#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTGIO(val)
+#define bfin_read_FIO_FLAG_C() bfin_read_PORTGIO_CLEAR()
+#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTGIO_CLEAR(val)
+#define bfin_read_FIO_FLAG_S() bfin_read_PORTGIO_SET()
+#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTGIO_SET(val)
+#define bfin_read_FIO_FLAG_T() bfin_read_PORTGIO_TOGGLE()
+#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTGIO_TOGGLE(val)
+#define bfin_read_FIO_MASKA_D() bfin_read_PORTGIO_MASKA()
+#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTGIO_MASKA(val)
+#define bfin_read_FIO_MASKA_C() bfin_read_PORTGIO_MASKA_CLEAR()
+#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTGIO_MASKA_CLEAR(val)
+#define bfin_read_FIO_MASKA_S() bfin_read_PORTGIO_MASKA_SET()
+#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTGIO_MASKA_SET(val)
+#define bfin_read_FIO_MASKA_T() bfin_read_PORTGIO_MASKA_TOGGLE()
+#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTGIO_MASKA_TOGGLE(val)
+#define bfin_read_FIO_MASKB_D() bfin_read_PORTGIO_MASKB()
+#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTGIO_MASKB(val)
+#define bfin_read_FIO_MASKB_C() bfin_read_PORTGIO_MASKB_CLEAR()
+#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTGIO_MASKB_CLEAR(val)
+#define bfin_read_FIO_MASKB_S() bfin_read_PORTGIO_MASKB_SET()
+#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTGIO_MASKB_SET(val)
+#define bfin_read_FIO_MASKB_T() bfin_read_PORTGIO_MASKB_TOGGLE()
+#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTGIO_MASKB_TOGGLE(val)
+#define bfin_read_FIO_DIR() bfin_read_PORTGIO_DIR()
+#define bfin_write_FIO_DIR(val) bfin_write_PORTGIO_DIR(val)
+#define bfin_read_FIO_POLAR() bfin_read_PORTGIO_POLAR()
+#define bfin_write_FIO_POLAR(val) bfin_write_PORTGIO_POLAR(val)
+#define bfin_read_FIO_EDGE() bfin_read_PORTGIO_EDGE()
+#define bfin_write_FIO_EDGE(val) bfin_write_PORTGIO_EDGE(val)
+#define bfin_read_FIO_BOTH() bfin_read_PORTGIO_BOTH()
+#define bfin_write_FIO_BOTH(val) bfin_write_PORTGIO_BOTH(val)
+#define bfin_read_FIO_INEN() bfin_read_PORTGIO_INEN()
+#define bfin_write_FIO_INEN(val) bfin_write_PORTGIO_INEN(val)
+
+#define bfin_read_FIO_FLAG_D() bfin_read_PORTGIO()
+#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTGIO(val)
+#define FIO_FLAG_D PORTGIO
+#define bfin_read_FIO_FLAG_C() bfin_read_PORTGIO_CLEAR()
+#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTGIO_CLEAR(val)
+#define FIO_FLAG_C PORTGIO_CLEAR
+#define bfin_read_FIO_FLAG_S() bfin_read_PORTGIO_SET()
+#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTGIO_SET(val)
+#define FIO_FLAG_S PORTGIO_SET
+#define bfin_read_FIO_FLAG_T() bfin_read_PORTGIO_TOGGLE()
+#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTGIO_TOGGLE(val)
+#define FIO_FLAG_T PORTGIO_TOGGLE
+#define bfin_read_FIO_MASKA_D() bfin_read_PORTGIO_MASKA()
+#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTGIO_MASKA(val)
+#define FIO_MASKA_D PORTGIO_MASKA
+#define bfin_read_FIO_MASKA_C() bfin_read_PORTGIO_MASKA_CLEAR()
+#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTGIO_MASKA_CLEAR(val)
+#define FIO_MASKA_C PORTGIO_MASKA_CLEAR
+#define bfin_read_FIO_MASKA_S() bfin_read_PORTGIO_MASKA_SET()
+#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTGIO_MASKA_SET(val)
+#define FIO_MASKA_S PORTGIO_MASKA_SET
+#define bfin_read_FIO_MASKA_T() bfin_read_PORTGIO_MASKA_TOGGLE()
+#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTGIO_MASKA_TOGGLE(val)
+#define FIO_MASKA_T PORTGIO_MASKA_TOGGLE
+#define bfin_read_FIO_MASKB_D() bfin_read_PORTGIO_MASKB()
+#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTGIO_MASKB(val)
+#define FIO_MASKB_D PORTGIO_MASKB
+#define bfin_read_FIO_MASKB_C() bfin_read_PORTGIO_MASKB_CLEAR()
+#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTGIO_MASKB_CLEAR(val)
+#define FIO_MASKB_C PORTGIO_MASKB_CLEAR
+#define bfin_read_FIO_MASKB_S() bfin_read_PORTGIO_MASKB_SET()
+#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTGIO_MASKB_SET(val)
+#define FIO_MASKB_S PORTGIO_MASKB_SET
+#define bfin_read_FIO_MASKB_T() bfin_read_PORTGIO_MASKB_TOGGLE()
+#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTGIO_MASKB_TOGGLE(val)
+#define FIO_MASKB_T PORTGIO_MASKB_TOGGLE
+#define bfin_read_FIO_DIR() bfin_read_PORTGIO_DIR()
+#define bfin_write_FIO_DIR(val) bfin_write_PORTGIO_DIR(val)
+#define FIO_DIR PORTGIO_DIR
+#define bfin_read_FIO_POLAR() bfin_read_PORTGIO_POLAR()
+#define bfin_write_FIO_POLAR(val) bfin_write_PORTGIO_POLAR(val)
+#define FIO_POLAR PORTGIO_POLAR
+#define bfin_read_FIO_EDGE() bfin_read_PORTGIO_EDGE()
+#define bfin_write_FIO_EDGE(val) bfin_write_PORTGIO_EDGE(val)
+#define FIO_EDGE PORTGIO_EDGE
+#define bfin_read_FIO_BOTH() bfin_read_PORTGIO_BOTH()
+#define bfin_write_FIO_BOTH(val) bfin_write_PORTGIO_BOTH(val)
+#define FIO_BOTH PORTGIO_BOTH
+#define bfin_read_FIO_INEN() bfin_read_PORTGIO_INEN()
+#define bfin_write_FIO_INEN(val) bfin_write_PORTGIO_INEN(val)
+#define FIO_INEN PORTGIO_INEN
+
+#endif
+
+/* FIO USE PORT H*/
+#ifdef CONFIG_BF537_PORT_H
+#define bfin_read_PORT_FER() bfin_read_PORTH_FER()
+#define bfin_write_PORT_FER(val) bfin_write_PORTH_FER(val)
+#define bfin_read_FIO_FLAG_D() bfin_read_PORTHIO()
+#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTHIO(val)
+#define bfin_read_FIO_FLAG_C() bfin_read_PORTHIO_CLEAR()
+#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTHIO_CLEAR(val)
+#define bfin_read_FIO_FLAG_S() bfin_read_PORTHIO_SET()
+#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTHIO_SET(val)
+#define bfin_read_FIO_FLAG_T() bfin_read_PORTHIO_TOGGLE()
+#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTHIO_TOGGLE(val)
+#define bfin_read_FIO_MASKA_D() bfin_read_PORTHIO_MASKA()
+#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTHIO_MASKA(val)
+#define bfin_read_FIO_MASKA_C() bfin_read_PORTHIO_MASKA_CLEAR()
+#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTHIO_MASKA_CLEAR(val)
+#define bfin_read_FIO_MASKA_S() bfin_read_PORTHIO_MASKA_SET()
+#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTHIO_MASKA_SET(val)
+#define bfin_read_FIO_MASKA_T() bfin_read_PORTHIO_MASKA_TOGGLE()
+#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTHIO_MASKA_TOGGLE(val)
+#define bfin_read_FIO_MASKB_D() bfin_read_PORTHIO_MASKB()
+#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTHIO_MASKB(val)
+#define bfin_read_FIO_MASKB_C() bfin_read_PORTHIO_MASKB_CLEAR()
+#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTHIO_MASKB_CLEAR(val)
+#define bfin_read_FIO_MASKB_S() bfin_read_PORTHIO_MASKB_SET()
+#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTHIO_MASKB_SET(val)
+#define bfin_read_FIO_MASKB_T() bfin_read_PORTHIO_MASKB_TOGGLE()
+#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTHIO_MASKB_TOGGLE(val)
+#define bfin_read_FIO_DIR() bfin_read_PORTHIO_DIR()
+#define bfin_write_FIO_DIR(val) bfin_write_PORTHIO_DIR(val)
+#define bfin_read_FIO_POLAR() bfin_read_PORTHIO_POLAR()
+#define bfin_write_FIO_POLAR(val) bfin_write_PORTHIO_POLAR(val)
+#define bfin_read_FIO_EDGE() bfin_read_PORTHIO_EDGE()
+#define bfin_write_FIO_EDGE(val) bfin_write_PORTHIO_EDGE(val)
+#define bfin_read_FIO_BOTH() bfin_read_PORTHIO_BOTH()
+#define bfin_write_FIO_BOTH(val) bfin_write_PORTHIO_BOTH(val)
+#define bfin_read_FIO_INEN() bfin_read_PORTHIO_INEN()
+#define bfin_write_FIO_INEN(val) bfin_write_PORTHIO_INEN(val)
+
+#define bfin_read_FIO_FLAG_D() bfin_read_PORTHIO()
+#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTHIO(val)
+#define FIO_FLAG_D PORTHIO
+#define bfin_read_FIO_FLAG_C() bfin_read_PORTHIO_CLEAR()
+#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTHIO_CLEAR(val)
+#define FIO_FLAG_C PORTHIO_CLEAR
+#define bfin_read_FIO_FLAG_S() bfin_read_PORTHIO_SET()
+#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTHIO_SET(val)
+#define FIO_FLAG_S PORTHIO_SET
+#define bfin_read_FIO_FLAG_T() bfin_read_PORTHIO_TOGGLE()
+#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTHIO_TOGGLE(val)
+#define FIO_FLAG_T PORTHIO_TOGGLE
+#define bfin_read_FIO_MASKA_D() bfin_read_PORTHIO_MASKA()
+#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTHIO_MASKA(val)
+#define FIO_MASKA_D PORTHIO_MASKA
+#define bfin_read_FIO_MASKA_C() bfin_read_PORTHIO_MASKA_CLEAR()
+#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTHIO_MASKA_CLEAR(val)
+#define FIO_MASKA_C PORTHIO_MASKA_CLEAR
+#define bfin_read_FIO_MASKA_S() bfin_read_PORTHIO_MASKA_SET()
+#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTHIO_MASKA_SET(val)
+#define FIO_MASKA_S PORTHIO_MASKA_SET
+#define bfin_read_FIO_MASKA_T() bfin_read_PORTHIO_MASKA_TOGGLE()
+#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTHIO_MASKA_TOGGLE(val)
+#define FIO_MASKA_T PORTHIO_MASKA_TOGGLE
+#define bfin_read_FIO_MASKB_D() bfin_read_PORTHIO_MASKB()
+#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTHIO_MASKB(val)
+#define FIO_MASKB_D PORTHIO_MASKB
+#define bfin_read_FIO_MASKB_C() bfin_read_PORTHIO_MASKB_CLEAR()
+#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTHIO_MASKB_CLEAR(val)
+#define FIO_MASKB_C PORTHIO_MASKB_CLEAR
+#define bfin_read_FIO_MASKB_S() bfin_read_PORTHIO_MASKB_SET()
+#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTHIO_MASKB_SET(val)
+#define FIO_MASKB_S PORTHIO_MASKB_SET
+#define bfin_read_FIO_MASKB_T() bfin_read_PORTHIO_MASKB_TOGGLE()
+#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTHIO_MASKB_TOGGLE(val)
+#define FIO_MASKB_T PORTHIO_MASKB_TOGGLE
+#define bfin_read_FIO_DIR() bfin_read_PORTHIO_DIR()
+#define bfin_write_FIO_DIR(val) bfin_write_PORTHIO_DIR(val)
+#define FIO_DIR PORTHIO_DIR
+#define bfin_read_FIO_POLAR() bfin_read_PORTHIO_POLAR()
+#define bfin_write_FIO_POLAR(val) bfin_write_PORTHIO_POLAR(val)
+#define FIO_POLAR PORTHIO_POLAR
+#define bfin_read_FIO_EDGE() bfin_read_PORTHIO_EDGE()
+#define bfin_write_FIO_EDGE(val) bfin_write_PORTHIO_EDGE(val)
+#define FIO_EDGE PORTHIO_EDGE
+#define bfin_read_FIO_BOTH() bfin_read_PORTHIO_BOTH()
+#define bfin_write_FIO_BOTH(val) bfin_write_PORTHIO_BOTH(val)
+#define FIO_BOTH PORTHIO_BOTH
+#define bfin_read_FIO_INEN() bfin_read_PORTHIO_INEN()
+#define bfin_write_FIO_INEN(val) bfin_write_PORTHIO_INEN(val)
+#define FIO_INEN PORTHIO_INEN
+
+#endif
+
+/* PLL_DIV Masks */
+#define CCLK_DIV1 CSEL_DIV1 /* CCLK = VCO / 1 */
+#define CCLK_DIV2 CSEL_DIV2 /* CCLK = VCO / 2 */
+#define CCLK_DIV4 CSEL_DIV4 /* CCLK = VCO / 4 */
+#define CCLK_DIV8 CSEL_DIV8 /* CCLK = VCO / 8 */
+
+#endif
diff --git a/include/asm-blackfin/mach-bf537/cdefBF534.h b/include/asm-blackfin/mach-bf537/cdefBF534.h
new file mode 100644
index 0000000..7b658c1
--- /dev/null
+++ b/include/asm-blackfin/mach-bf537/cdefBF534.h
@@ -0,0 +1,1823 @@
+/*
+ * File: include/asm-blackfin/mach-bf537/cdefbf534.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: system mmr register map
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _CDEF_BF534_H
+#define _CDEF_BF534_H
+
+/* Include all Core registers and bit definitions */
+#include "defBF534.h"
+
+/* Include core specific register pointer definitions */
+#include <asm/mach-common/cdef_LPBlackfin.h>
+
+#include <asm/system.h>
+
+/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */
+#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL)
+#define bfin_write_PLL_CTL(val) bfin_write16(PLL_CTL,val)
+#define bfin_read_PLL_DIV() bfin_read16(PLL_DIV)
+#define bfin_write_PLL_DIV(val) bfin_write16(PLL_DIV,val)
+#define bfin_read_VR_CTL() bfin_read16(VR_CTL)
+/* Writing to VR_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_VR_CTL(unsigned int val)
+{
+ unsigned long flags, iwr;
+
+ bfin_write16(VR_CTL, val);
+ __builtin_bfin_ssync();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr = bfin_read32(SIC_IWR);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SIC_IWR, IWR_ENABLE(0));
+ local_irq_save(flags);
+ asm("IDLE;");
+ local_irq_restore(flags);
+ bfin_write32(SIC_IWR, iwr);
+}
+#define bfin_read_PLL_STAT() bfin_read16(PLL_STAT)
+#define bfin_write_PLL_STAT(val) bfin_write16(PLL_STAT,val)
+#define bfin_read_PLL_LOCKCNT() bfin_read16(PLL_LOCKCNT)
+#define bfin_write_PLL_LOCKCNT(val) bfin_write16(PLL_LOCKCNT,val)
+#define bfin_read_CHIPID() bfin_read32(CHIPID)
+
+/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
+#define bfin_read_SWRST() bfin_read16(SWRST)
+#define bfin_write_SWRST(val) bfin_write16(SWRST,val)
+#define bfin_read_SYSCR() bfin_read16(SYSCR)
+#define bfin_write_SYSCR(val) bfin_write16(SYSCR,val)
+#define pSIC_RVECT ((void * volatile *)SIC_RVECT)
+#define bfin_read_SIC_RVECT() bfin_read32(SIC_RVECT)
+#define bfin_write_SIC_RVECT(val) bfin_write32(SIC_RVECT,val)
+#define bfin_read_SIC_IMASK() bfin_read32(SIC_IMASK)
+#define bfin_write_SIC_IMASK(val) bfin_write32(SIC_IMASK,val)
+#define bfin_read_SIC_IAR0() bfin_read32(SIC_IAR0)
+#define bfin_write_SIC_IAR0(val) bfin_write32(SIC_IAR0,val)
+#define bfin_read_SIC_IAR1() bfin_read32(SIC_IAR1)
+#define bfin_write_SIC_IAR1(val) bfin_write32(SIC_IAR1,val)
+#define bfin_read_SIC_IAR2() bfin_read32(SIC_IAR2)
+#define bfin_write_SIC_IAR2(val) bfin_write32(SIC_IAR2,val)
+#define bfin_read_SIC_IAR3() bfin_read32(SIC_IAR3)
+#define bfin_write_SIC_IAR3(val) bfin_write32(SIC_IAR3,val)
+#define bfin_read_SIC_ISR() bfin_read32(SIC_ISR)
+#define bfin_write_SIC_ISR(val) bfin_write32(SIC_ISR,val)
+#define bfin_read_SIC_IWR() bfin_read32(SIC_IWR)
+#define bfin_write_SIC_IWR(val) bfin_write32(SIC_IWR,val)
+
+/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */
+#define bfin_read_WDOG_CTL() bfin_read16(WDOG_CTL)
+#define bfin_write_WDOG_CTL(val) bfin_write16(WDOG_CTL,val)
+#define bfin_read_WDOG_CNT() bfin_read32(WDOG_CNT)
+#define bfin_write_WDOG_CNT(val) bfin_write32(WDOG_CNT,val)
+#define bfin_read_WDOG_STAT() bfin_read32(WDOG_STAT)
+#define bfin_write_WDOG_STAT(val) bfin_write32(WDOG_STAT,val)
+
+/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */
+#define bfin_read_RTC_STAT() bfin_read32(RTC_STAT)
+#define bfin_write_RTC_STAT(val) bfin_write32(RTC_STAT,val)
+#define bfin_read_RTC_ICTL() bfin_read16(RTC_ICTL)
+#define bfin_write_RTC_ICTL(val) bfin_write16(RTC_ICTL,val)
+#define bfin_read_RTC_ISTAT() bfin_read16(RTC_ISTAT)
+#define bfin_write_RTC_ISTAT(val) bfin_write16(RTC_ISTAT,val)
+#define bfin_read_RTC_SWCNT() bfin_read16(RTC_SWCNT)
+#define bfin_write_RTC_SWCNT(val) bfin_write16(RTC_SWCNT,val)
+#define bfin_read_RTC_ALARM() bfin_read32(RTC_ALARM)
+#define bfin_write_RTC_ALARM(val) bfin_write32(RTC_ALARM,val)
+#define bfin_read_RTC_FAST() bfin_read16(RTC_FAST)
+#define bfin_write_RTC_FAST(val) bfin_write16(RTC_FAST,val)
+#define bfin_read_RTC_PREN() bfin_read16(RTC_PREN)
+#define bfin_write_RTC_PREN(val) bfin_write16(RTC_PREN,val)
+
+/* UART0 Controller (0xFFC00400 - 0xFFC004FF) */
+#define bfin_read_UART0_THR() bfin_read16(UART0_THR)
+#define bfin_write_UART0_THR(val) bfin_write16(UART0_THR,val)
+#define bfin_read_UART0_RBR() bfin_read16(UART0_RBR)
+#define bfin_write_UART0_RBR(val) bfin_write16(UART0_RBR,val)
+#define bfin_read_UART0_DLL() bfin_read16(UART0_DLL)
+#define bfin_write_UART0_DLL(val) bfin_write16(UART0_DLL,val)
+#define bfin_read_UART0_IER() bfin_read16(UART0_IER)
+#define bfin_write_UART0_IER(val) bfin_write16(UART0_IER,val)
+#define bfin_read_UART0_DLH() bfin_read16(UART0_DLH)
+#define bfin_write_UART0_DLH(val) bfin_write16(UART0_DLH,val)
+#define bfin_read_UART0_IIR() bfin_read16(UART0_IIR)
+#define bfin_write_UART0_IIR(val) bfin_write16(UART0_IIR,val)
+#define bfin_read_UART0_LCR() bfin_read16(UART0_LCR)
+#define bfin_write_UART0_LCR(val) bfin_write16(UART0_LCR,val)
+#define bfin_read_UART0_MCR() bfin_read16(UART0_MCR)
+#define bfin_write_UART0_MCR(val) bfin_write16(UART0_MCR,val)
+#define bfin_read_UART0_LSR() bfin_read16(UART0_LSR)
+#define bfin_write_UART0_LSR(val) bfin_write16(UART0_LSR,val)
+#define bfin_read_UART0_MSR() bfin_read16(UART0_MSR)
+#define bfin_write_UART0_MSR(val) bfin_write16(UART0_MSR,val)
+#define bfin_read_UART0_SCR() bfin_read16(UART0_SCR)
+#define bfin_write_UART0_SCR(val) bfin_write16(UART0_SCR,val)
+#define bfin_read_UART0_GCTL() bfin_read16(UART0_GCTL)
+#define bfin_write_UART0_GCTL(val) bfin_write16(UART0_GCTL,val)
+
+/* SPI Controller (0xFFC00500 - 0xFFC005FF) */
+#define bfin_read_SPI_CTL() bfin_read16(SPI_CTL)
+#define bfin_write_SPI_CTL(val) bfin_write16(SPI_CTL,val)
+#define bfin_read_SPI_FLG() bfin_read16(SPI_FLG)
+#define bfin_write_SPI_FLG(val) bfin_write16(SPI_FLG,val)
+#define bfin_read_SPI_STAT() bfin_read16(SPI_STAT)
+#define bfin_write_SPI_STAT(val) bfin_write16(SPI_STAT,val)
+#define bfin_read_SPI_TDBR() bfin_read16(SPI_TDBR)
+#define bfin_write_SPI_TDBR(val) bfin_write16(SPI_TDBR,val)
+#define bfin_read_SPI_RDBR() bfin_read16(SPI_RDBR)
+#define bfin_write_SPI_RDBR(val) bfin_write16(SPI_RDBR,val)
+#define bfin_read_SPI_BAUD() bfin_read16(SPI_BAUD)
+#define bfin_write_SPI_BAUD(val) bfin_write16(SPI_BAUD,val)
+#define bfin_read_SPI_SHADOW() bfin_read16(SPI_SHADOW)
+#define bfin_write_SPI_SHADOW(val) bfin_write16(SPI_SHADOW,val)
+
+/* TIMER0-7 Registers (0xFFC00600 - 0xFFC006FF) */
+#define bfin_read_TIMER0_CONFIG() bfin_read16(TIMER0_CONFIG)
+#define bfin_write_TIMER0_CONFIG(val) bfin_write16(TIMER0_CONFIG,val)
+#define bfin_read_TIMER0_COUNTER() bfin_read32(TIMER0_COUNTER)
+#define bfin_write_TIMER0_COUNTER(val) bfin_write32(TIMER0_COUNTER,val)
+#define bfin_read_TIMER0_PERIOD() bfin_read32(TIMER0_PERIOD)
+#define bfin_write_TIMER0_PERIOD(val) bfin_write32(TIMER0_PERIOD,val)
+#define bfin_read_TIMER0_WIDTH() bfin_read32(TIMER0_WIDTH)
+#define bfin_write_TIMER0_WIDTH(val) bfin_write32(TIMER0_WIDTH,val)
+
+#define bfin_read_TIMER1_CONFIG() bfin_read16(TIMER1_CONFIG)
+#define bfin_write_TIMER1_CONFIG(val) bfin_write16(TIMER1_CONFIG,val)
+#define bfin_read_TIMER1_COUNTER() bfin_read32(TIMER1_COUNTER)
+#define bfin_write_TIMER1_COUNTER(val) bfin_write32(TIMER1_COUNTER,val)
+#define bfin_read_TIMER1_PERIOD() bfin_read32(TIMER1_PERIOD)
+#define bfin_write_TIMER1_PERIOD(val) bfin_write32(TIMER1_PERIOD,val)
+#define bfin_read_TIMER1_WIDTH() bfin_read32(TIMER1_WIDTH)
+#define bfin_write_TIMER1_WIDTH(val) bfin_write32(TIMER1_WIDTH,val)
+
+#define bfin_read_TIMER2_CONFIG() bfin_read16(TIMER2_CONFIG)
+#define bfin_write_TIMER2_CONFIG(val) bfin_write16(TIMER2_CONFIG,val)
+#define bfin_read_TIMER2_COUNTER() bfin_read32(TIMER2_COUNTER)
+#define bfin_write_TIMER2_COUNTER(val) bfin_write32(TIMER2_COUNTER,val)
+#define bfin_read_TIMER2_PERIOD() bfin_read32(TIMER2_PERIOD)
+#define bfin_write_TIMER2_PERIOD(val) bfin_write32(TIMER2_PERIOD,val)
+#define bfin_read_TIMER2_WIDTH() bfin_read32(TIMER2_WIDTH)
+#define bfin_write_TIMER2_WIDTH(val) bfin_write32(TIMER2_WIDTH,val)
+
+#define bfin_read_TIMER3_CONFIG() bfin_read16(TIMER3_CONFIG)
+#define bfin_write_TIMER3_CONFIG(val) bfin_write16(TIMER3_CONFIG,val)
+#define bfin_read_TIMER3_COUNTER() bfin_read32(TIMER3_COUNTER)
+#define bfin_write_TIMER3_COUNTER(val) bfin_write32(TIMER3_COUNTER,val)
+#define bfin_read_TIMER3_PERIOD() bfin_read32(TIMER3_PERIOD)
+#define bfin_write_TIMER3_PERIOD(val) bfin_write32(TIMER3_PERIOD,val)
+#define bfin_read_TIMER3_WIDTH() bfin_read32(TIMER3_WIDTH)
+#define bfin_write_TIMER3_WIDTH(val) bfin_write32(TIMER3_WIDTH,val)
+
+#define bfin_read_TIMER4_CONFIG() bfin_read16(TIMER4_CONFIG)
+#define bfin_write_TIMER4_CONFIG(val) bfin_write16(TIMER4_CONFIG,val)
+#define bfin_read_TIMER4_COUNTER() bfin_read32(TIMER4_COUNTER)
+#define bfin_write_TIMER4_COUNTER(val) bfin_write32(TIMER4_COUNTER,val)
+#define bfin_read_TIMER4_PERIOD() bfin_read32(TIMER4_PERIOD)
+#define bfin_write_TIMER4_PERIOD(val) bfin_write32(TIMER4_PERIOD,val)
+#define bfin_read_TIMER4_WIDTH() bfin_read32(TIMER4_WIDTH)
+#define bfin_write_TIMER4_WIDTH(val) bfin_write32(TIMER4_WIDTH,val)
+
+#define bfin_read_TIMER5_CONFIG() bfin_read16(TIMER5_CONFIG)
+#define bfin_write_TIMER5_CONFIG(val) bfin_write16(TIMER5_CONFIG,val)
+#define bfin_read_TIMER5_COUNTER() bfin_read32(TIMER5_COUNTER)
+#define bfin_write_TIMER5_COUNTER(val) bfin_write32(TIMER5_COUNTER,val)
+#define bfin_read_TIMER5_PERIOD() bfin_read32(TIMER5_PERIOD)
+#define bfin_write_TIMER5_PERIOD(val) bfin_write32(TIMER5_PERIOD,val)
+#define bfin_read_TIMER5_WIDTH() bfin_read32(TIMER5_WIDTH)
+#define bfin_write_TIMER5_WIDTH(val) bfin_write32(TIMER5_WIDTH,val)
+
+#define bfin_read_TIMER6_CONFIG() bfin_read16(TIMER6_CONFIG)
+#define bfin_write_TIMER6_CONFIG(val) bfin_write16(TIMER6_CONFIG,val)
+#define bfin_read_TIMER6_COUNTER() bfin_read32(TIMER6_COUNTER)
+#define bfin_write_TIMER6_COUNTER(val) bfin_write32(TIMER6_COUNTER,val)
+#define bfin_read_TIMER6_PERIOD() bfin_read32(TIMER6_PERIOD)
+#define bfin_write_TIMER6_PERIOD(val) bfin_write32(TIMER6_PERIOD,val)
+#define bfin_read_TIMER6_WIDTH() bfin_read32(TIMER6_WIDTH)
+#define bfin_write_TIMER6_WIDTH(val) bfin_write32(TIMER6_WIDTH,val)
+
+#define bfin_read_TIMER7_CONFIG() bfin_read16(TIMER7_CONFIG)
+#define bfin_write_TIMER7_CONFIG(val) bfin_write16(TIMER7_CONFIG,val)
+#define bfin_read_TIMER7_COUNTER() bfin_read32(TIMER7_COUNTER)
+#define bfin_write_TIMER7_COUNTER(val) bfin_write32(TIMER7_COUNTER,val)
+#define bfin_read_TIMER7_PERIOD() bfin_read32(TIMER7_PERIOD)
+#define bfin_write_TIMER7_PERIOD(val) bfin_write32(TIMER7_PERIOD,val)
+#define bfin_read_TIMER7_WIDTH() bfin_read32(TIMER7_WIDTH)
+#define bfin_write_TIMER7_WIDTH(val) bfin_write32(TIMER7_WIDTH,val)
+
+#define bfin_read_TIMER_ENABLE() bfin_read16(TIMER_ENABLE)
+#define bfin_write_TIMER_ENABLE(val) bfin_write16(TIMER_ENABLE,val)
+#define bfin_read_TIMER_DISABLE() bfin_read16(TIMER_DISABLE)
+#define bfin_write_TIMER_DISABLE(val) bfin_write16(TIMER_DISABLE,val)
+#define bfin_read_TIMER_STATUS() bfin_read32(TIMER_STATUS)
+#define bfin_write_TIMER_STATUS(val) bfin_write32(TIMER_STATUS,val)
+
+/* General Purpose I/O Port F (0xFFC00700 - 0xFFC007FF) */
+#define bfin_read_PORTFIO() bfin_read16(PORTFIO)
+#define bfin_write_PORTFIO(val) bfin_write16(PORTFIO,val)
+#define bfin_read_PORTFIO_CLEAR() bfin_read16(PORTFIO_CLEAR)
+#define bfin_write_PORTFIO_CLEAR(val) bfin_write16(PORTFIO_CLEAR,val)
+#define bfin_read_PORTFIO_SET() bfin_read16(PORTFIO_SET)
+#define bfin_write_PORTFIO_SET(val) bfin_write16(PORTFIO_SET,val)
+#define bfin_read_PORTFIO_TOGGLE() bfin_read16(PORTFIO_TOGGLE)
+#define bfin_write_PORTFIO_TOGGLE(val) bfin_write16(PORTFIO_TOGGLE,val)
+#define bfin_read_PORTFIO_MASKA() bfin_read16(PORTFIO_MASKA)
+#define bfin_write_PORTFIO_MASKA(val) bfin_write16(PORTFIO_MASKA,val)
+#define bfin_read_PORTFIO_MASKA_CLEAR() bfin_read16(PORTFIO_MASKA_CLEAR)
+#define bfin_write_PORTFIO_MASKA_CLEAR(val) bfin_write16(PORTFIO_MASKA_CLEAR,val)
+#define bfin_read_PORTFIO_MASKA_SET() bfin_read16(PORTFIO_MASKA_SET)
+#define bfin_write_PORTFIO_MASKA_SET(val) bfin_write16(PORTFIO_MASKA_SET,val)
+#define bfin_read_PORTFIO_MASKA_TOGGLE() bfin_read16(PORTFIO_MASKA_TOGGLE)
+#define bfin_write_PORTFIO_MASKA_TOGGLE(val) bfin_write16(PORTFIO_MASKA_TOGGLE,val)
+#define bfin_read_PORTFIO_MASKB() bfin_read16(PORTFIO_MASKB)
+#define bfin_write_PORTFIO_MASKB(val) bfin_write16(PORTFIO_MASKB,val)
+#define bfin_read_PORTFIO_MASKB_CLEAR() bfin_read16(PORTFIO_MASKB_CLEAR)
+#define bfin_write_PORTFIO_MASKB_CLEAR(val) bfin_write16(PORTFIO_MASKB_CLEAR,val)
+#define bfin_read_PORTFIO_MASKB_SET() bfin_read16(PORTFIO_MASKB_SET)
+#define bfin_write_PORTFIO_MASKB_SET(val) bfin_write16(PORTFIO_MASKB_SET,val)
+#define bfin_read_PORTFIO_MASKB_TOGGLE() bfin_read16(PORTFIO_MASKB_TOGGLE)
+#define bfin_write_PORTFIO_MASKB_TOGGLE(val) bfin_write16(PORTFIO_MASKB_TOGGLE,val)
+#define bfin_read_PORTFIO_DIR() bfin_read16(PORTFIO_DIR)
+#define bfin_write_PORTFIO_DIR(val) bfin_write16(PORTFIO_DIR,val)
+#define bfin_read_PORTFIO_POLAR() bfin_read16(PORTFIO_POLAR)
+#define bfin_write_PORTFIO_POLAR(val) bfin_write16(PORTFIO_POLAR,val)
+#define bfin_read_PORTFIO_EDGE() bfin_read16(PORTFIO_EDGE)
+#define bfin_write_PORTFIO_EDGE(val) bfin_write16(PORTFIO_EDGE,val)
+#define bfin_read_PORTFIO_BOTH() bfin_read16(PORTFIO_BOTH)
+#define bfin_write_PORTFIO_BOTH(val) bfin_write16(PORTFIO_BOTH,val)
+#define bfin_read_PORTFIO_INEN() bfin_read16(PORTFIO_INEN)
+#define bfin_write_PORTFIO_INEN(val) bfin_write16(PORTFIO_INEN,val)
+
+/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
+#define bfin_read_SPORT0_TCR1() bfin_read16(SPORT0_TCR1)
+#define bfin_write_SPORT0_TCR1(val) bfin_write16(SPORT0_TCR1,val)
+#define bfin_read_SPORT0_TCR2() bfin_read16(SPORT0_TCR2)
+#define bfin_write_SPORT0_TCR2(val) bfin_write16(SPORT0_TCR2,val)
+#define bfin_read_SPORT0_TCLKDIV() bfin_read16(SPORT0_TCLKDIV)
+#define bfin_write_SPORT0_TCLKDIV(val) bfin_write16(SPORT0_TCLKDIV,val)
+#define bfin_read_SPORT0_TFSDIV() bfin_read16(SPORT0_TFSDIV)
+#define bfin_write_SPORT0_TFSDIV(val) bfin_write16(SPORT0_TFSDIV,val)
+#define bfin_read_SPORT0_TX() bfin_read32(SPORT0_TX)
+#define bfin_write_SPORT0_TX(val) bfin_write32(SPORT0_TX,val)
+#define bfin_read_SPORT0_RX() bfin_read32(SPORT0_RX)
+#define bfin_write_SPORT0_RX(val) bfin_write32(SPORT0_RX,val)
+#define bfin_read_SPORT0_TX32() bfin_read32(SPORT0_TX)
+#define bfin_write_SPORT0_TX32(val) bfin_write32(SPORT0_TX,val)
+#define bfin_read_SPORT0_RX32() bfin_read32(SPORT0_RX)
+#define bfin_write_SPORT0_RX32(val) bfin_write32(SPORT0_RX,val)
+#define bfin_read_SPORT0_TX16() bfin_read16(SPORT0_TX)
+#define bfin_write_SPORT0_TX16(val) bfin_write16(SPORT0_TX,val)
+#define bfin_read_SPORT0_RX16() bfin_read16(SPORT0_RX)
+#define bfin_write_SPORT0_RX16(val) bfin_write16(SPORT0_RX,val)
+#define bfin_read_SPORT0_RCR1() bfin_read16(SPORT0_RCR1)
+#define bfin_write_SPORT0_RCR1(val) bfin_write16(SPORT0_RCR1,val)
+#define bfin_read_SPORT0_RCR2() bfin_read16(SPORT0_RCR2)
+#define bfin_write_SPORT0_RCR2(val) bfin_write16(SPORT0_RCR2,val)
+#define bfin_read_SPORT0_RCLKDIV() bfin_read16(SPORT0_RCLKDIV)
+#define bfin_write_SPORT0_RCLKDIV(val) bfin_write16(SPORT0_RCLKDIV,val)
+#define bfin_read_SPORT0_RFSDIV() bfin_read16(SPORT0_RFSDIV)
+#define bfin_write_SPORT0_RFSDIV(val) bfin_write16(SPORT0_RFSDIV,val)
+#define bfin_read_SPORT0_STAT() bfin_read16(SPORT0_STAT)
+#define bfin_write_SPORT0_STAT(val) bfin_write16(SPORT0_STAT,val)
+#define bfin_read_SPORT0_CHNL() bfin_read16(SPORT0_CHNL)
+#define bfin_write_SPORT0_CHNL(val) bfin_write16(SPORT0_CHNL,val)
+#define bfin_read_SPORT0_MCMC1() bfin_read16(SPORT0_MCMC1)
+#define bfin_write_SPORT0_MCMC1(val) bfin_write16(SPORT0_MCMC1,val)
+#define bfin_read_SPORT0_MCMC2() bfin_read16(SPORT0_MCMC2)
+#define bfin_write_SPORT0_MCMC2(val) bfin_write16(SPORT0_MCMC2,val)
+#define bfin_read_SPORT0_MTCS0() bfin_read32(SPORT0_MTCS0)
+#define bfin_write_SPORT0_MTCS0(val) bfin_write32(SPORT0_MTCS0,val)
+#define bfin_read_SPORT0_MTCS1() bfin_read32(SPORT0_MTCS1)
+#define bfin_write_SPORT0_MTCS1(val) bfin_write32(SPORT0_MTCS1,val)
+#define bfin_read_SPORT0_MTCS2() bfin_read32(SPORT0_MTCS2)
+#define bfin_write_SPORT0_MTCS2(val) bfin_write32(SPORT0_MTCS2,val)
+#define bfin_read_SPORT0_MTCS3() bfin_read32(SPORT0_MTCS3)
+#define bfin_write_SPORT0_MTCS3(val) bfin_write32(SPORT0_MTCS3,val)
+#define bfin_read_SPORT0_MRCS0() bfin_read32(SPORT0_MRCS0)
+#define bfin_write_SPORT0_MRCS0(val) bfin_write32(SPORT0_MRCS0,val)
+#define bfin_read_SPORT0_MRCS1() bfin_read32(SPORT0_MRCS1)
+#define bfin_write_SPORT0_MRCS1(val) bfin_write32(SPORT0_MRCS1,val)
+#define bfin_read_SPORT0_MRCS2() bfin_read32(SPORT0_MRCS2)
+#define bfin_write_SPORT0_MRCS2(val) bfin_write32(SPORT0_MRCS2,val)
+#define bfin_read_SPORT0_MRCS3() bfin_read32(SPORT0_MRCS3)
+#define bfin_write_SPORT0_MRCS3(val) bfin_write32(SPORT0_MRCS3,val)
+
+/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
+#define bfin_read_SPORT1_TCR1() bfin_read16(SPORT1_TCR1)
+#define bfin_write_SPORT1_TCR1(val) bfin_write16(SPORT1_TCR1,val)
+#define bfin_read_SPORT1_TCR2() bfin_read16(SPORT1_TCR2)
+#define bfin_write_SPORT1_TCR2(val) bfin_write16(SPORT1_TCR2,val)
+#define bfin_read_SPORT1_TCLKDIV() bfin_read16(SPORT1_TCLKDIV)
+#define bfin_write_SPORT1_TCLKDIV(val) bfin_write16(SPORT1_TCLKDIV,val)
+#define bfin_read_SPORT1_TFSDIV() bfin_read16(SPORT1_TFSDIV)
+#define bfin_write_SPORT1_TFSDIV(val) bfin_write16(SPORT1_TFSDIV,val)
+#define bfin_read_SPORT1_TX() bfin_read32(SPORT1_TX)
+#define bfin_write_SPORT1_TX(val) bfin_write32(SPORT1_TX,val)
+#define bfin_read_SPORT1_RX() bfin_read32(SPORT1_RX)
+#define bfin_write_SPORT1_RX(val) bfin_write32(SPORT1_RX,val)
+#define bfin_read_SPORT1_TX32() bfin_read32(SPORT1_TX)
+#define bfin_write_SPORT1_TX32(val) bfin_write32(SPORT1_TX,val)
+#define bfin_read_SPORT1_RX32() bfin_read32(SPORT1_RX)
+#define bfin_write_SPORT1_RX32(val) bfin_write32(SPORT1_RX,val)
+#define bfin_read_SPORT1_TX16() bfin_read16(SPORT1_TX)
+#define bfin_write_SPORT1_TX16(val) bfin_write16(SPORT1_TX,val)
+#define bfin_read_SPORT1_RX16() bfin_read16(SPORT1_RX)
+#define bfin_write_SPORT1_RX16(val) bfin_write16(SPORT1_RX,val)
+#define bfin_read_SPORT1_RCR1() bfin_read16(SPORT1_RCR1)
+#define bfin_write_SPORT1_RCR1(val) bfin_write16(SPORT1_RCR1,val)
+#define bfin_read_SPORT1_RCR2() bfin_read16(SPORT1_RCR2)
+#define bfin_write_SPORT1_RCR2(val) bfin_write16(SPORT1_RCR2,val)
+#define bfin_read_SPORT1_RCLKDIV() bfin_read16(SPORT1_RCLKDIV)
+#define bfin_write_SPORT1_RCLKDIV(val) bfin_write16(SPORT1_RCLKDIV,val)
+#define bfin_read_SPORT1_RFSDIV() bfin_read16(SPORT1_RFSDIV)
+#define bfin_write_SPORT1_RFSDIV(val) bfin_write16(SPORT1_RFSDIV,val)
+#define bfin_read_SPORT1_STAT() bfin_read16(SPORT1_STAT)
+#define bfin_write_SPORT1_STAT(val) bfin_write16(SPORT1_STAT,val)
+#define bfin_read_SPORT1_CHNL() bfin_read16(SPORT1_CHNL)
+#define bfin_write_SPORT1_CHNL(val) bfin_write16(SPORT1_CHNL,val)
+#define bfin_read_SPORT1_MCMC1() bfin_read16(SPORT1_MCMC1)
+#define bfin_write_SPORT1_MCMC1(val) bfin_write16(SPORT1_MCMC1,val)
+#define bfin_read_SPORT1_MCMC2() bfin_read16(SPORT1_MCMC2)
+#define bfin_write_SPORT1_MCMC2(val) bfin_write16(SPORT1_MCMC2,val)
+#define bfin_read_SPORT1_MTCS0() bfin_read32(SPORT1_MTCS0)
+#define bfin_write_SPORT1_MTCS0(val) bfin_write32(SPORT1_MTCS0,val)
+#define bfin_read_SPORT1_MTCS1() bfin_read32(SPORT1_MTCS1)
+#define bfin_write_SPORT1_MTCS1(val) bfin_write32(SPORT1_MTCS1,val)
+#define bfin_read_SPORT1_MTCS2() bfin_read32(SPORT1_MTCS2)
+#define bfin_write_SPORT1_MTCS2(val) bfin_write32(SPORT1_MTCS2,val)
+#define bfin_read_SPORT1_MTCS3() bfin_read32(SPORT1_MTCS3)
+#define bfin_write_SPORT1_MTCS3(val) bfin_write32(SPORT1_MTCS3,val)
+#define bfin_read_SPORT1_MRCS0() bfin_read32(SPORT1_MRCS0)
+#define bfin_write_SPORT1_MRCS0(val) bfin_write32(SPORT1_MRCS0,val)
+#define bfin_read_SPORT1_MRCS1() bfin_read32(SPORT1_MRCS1)
+#define bfin_write_SPORT1_MRCS1(val) bfin_write32(SPORT1_MRCS1,val)
+#define bfin_read_SPORT1_MRCS2() bfin_read32(SPORT1_MRCS2)
+#define bfin_write_SPORT1_MRCS2(val) bfin_write32(SPORT1_MRCS2,val)
+#define bfin_read_SPORT1_MRCS3() bfin_read32(SPORT1_MRCS3)
+#define bfin_write_SPORT1_MRCS3(val) bfin_write32(SPORT1_MRCS3,val)
+
+/* External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
+#define bfin_read_EBIU_AMGCTL() bfin_read16(EBIU_AMGCTL)
+#define bfin_write_EBIU_AMGCTL(val) bfin_write16(EBIU_AMGCTL,val)
+#define bfin_read_EBIU_AMBCTL0() bfin_read32(EBIU_AMBCTL0)
+#define bfin_write_EBIU_AMBCTL0(val) bfin_write32(EBIU_AMBCTL0,val)
+#define bfin_read_EBIU_AMBCTL1() bfin_read32(EBIU_AMBCTL1)
+#define bfin_write_EBIU_AMBCTL1(val) bfin_write32(EBIU_AMBCTL1,val)
+#define bfin_read_EBIU_SDGCTL() bfin_read32(EBIU_SDGCTL)
+#define bfin_write_EBIU_SDGCTL(val) bfin_write32(EBIU_SDGCTL,val)
+#define bfin_read_EBIU_SDBCTL() bfin_read16(EBIU_SDBCTL)
+#define bfin_write_EBIU_SDBCTL(val) bfin_write16(EBIU_SDBCTL,val)
+#define bfin_read_EBIU_SDRRC() bfin_read16(EBIU_SDRRC)
+#define bfin_write_EBIU_SDRRC(val) bfin_write16(EBIU_SDRRC,val)
+#define bfin_read_EBIU_SDSTAT() bfin_read16(EBIU_SDSTAT)
+#define bfin_write_EBIU_SDSTAT(val) bfin_write16(EBIU_SDSTAT,val)
+
+/* DMA Traffic Control Registers */
+#define pDMA_TCPER ((volatile unsigned short *)DMA_TCPER)
+#define bfin_read_DMA_TCPER() bfin_read16(DMA_TCPER)
+#define bfin_write_DMA_TCPER(val) bfin_write16(DMA_TCPER,val)
+#define pDMA_TCCNT ((volatile unsigned short *)DMA_TCCNT)
+#define bfin_read_DMA_TCCNT() bfin_read16(DMA_TCCNT)
+#define bfin_write_DMA_TCCNT(val) bfin_write16(DMA_TCCNT,val)
+
+/* DMA Controller */
+#define bfin_read_DMA0_CONFIG() bfin_read16(DMA0_CONFIG)
+#define bfin_write_DMA0_CONFIG(val) bfin_write16(DMA0_CONFIG,val)
+#define bfin_read_DMA0_NEXT_DESC_PTR() bfin_read32(DMA0_NEXT_DESC_PTR)
+#define bfin_write_DMA0_NEXT_DESC_PTR(val) bfin_write32(DMA0_NEXT_DESC_PTR,val)
+#define bfin_read_DMA0_START_ADDR() bfin_read32(DMA0_START_ADDR)
+#define bfin_write_DMA0_START_ADDR(val) bfin_write32(DMA0_START_ADDR,val)
+#define bfin_read_DMA0_X_COUNT() bfin_read16(DMA0_X_COUNT)
+#define bfin_write_DMA0_X_COUNT(val) bfin_write16(DMA0_X_COUNT,val)
+#define bfin_read_DMA0_Y_COUNT() bfin_read16(DMA0_Y_COUNT)
+#define bfin_write_DMA0_Y_COUNT(val) bfin_write16(DMA0_Y_COUNT,val)
+#define bfin_read_DMA0_X_MODIFY() bfin_read16(DMA0_X_MODIFY)
+#define bfin_write_DMA0_X_MODIFY(val) bfin_write16(DMA0_X_MODIFY,val)
+#define bfin_read_DMA0_Y_MODIFY() bfin_read16(DMA0_Y_MODIFY)
+#define bfin_write_DMA0_Y_MODIFY(val) bfin_write16(DMA0_Y_MODIFY,val)
+#define bfin_read_DMA0_CURR_DESC_PTR() bfin_read32(DMA0_CURR_DESC_PTR)
+#define bfin_write_DMA0_CURR_DESC_PTR(val) bfin_write32(DMA0_CURR_DESC_PTR,val)
+#define bfin_read_DMA0_CURR_ADDR() bfin_read32(DMA0_CURR_ADDR)
+#define bfin_write_DMA0_CURR_ADDR(val) bfin_write32(DMA0_CURR_ADDR,val)
+#define bfin_read_DMA0_CURR_X_COUNT() bfin_read16(DMA0_CURR_X_COUNT)
+#define bfin_write_DMA0_CURR_X_COUNT(val) bfin_write16(DMA0_CURR_X_COUNT,val)
+#define bfin_read_DMA0_CURR_Y_COUNT() bfin_read16(DMA0_CURR_Y_COUNT)
+#define bfin_write_DMA0_CURR_Y_COUNT(val) bfin_write16(DMA0_CURR_Y_COUNT,val)
+#define bfin_read_DMA0_IRQ_STATUS() bfin_read16(DMA0_IRQ_STATUS)
+#define bfin_write_DMA0_IRQ_STATUS(val) bfin_write16(DMA0_IRQ_STATUS,val)
+#define bfin_read_DMA0_PERIPHERAL_MAP() bfin_read16(DMA0_PERIPHERAL_MAP)
+#define bfin_write_DMA0_PERIPHERAL_MAP(val) bfin_write16(DMA0_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA1_CONFIG() bfin_read16(DMA1_CONFIG)
+#define bfin_write_DMA1_CONFIG(val) bfin_write16(DMA1_CONFIG,val)
+#define bfin_read_DMA1_NEXT_DESC_PTR() bfin_read32(DMA1_NEXT_DESC_PTR)
+#define bfin_write_DMA1_NEXT_DESC_PTR(val) bfin_write32(DMA1_NEXT_DESC_PTR,val)
+#define bfin_read_DMA1_START_ADDR() bfin_read32(DMA1_START_ADDR)
+#define bfin_write_DMA1_START_ADDR(val) bfin_write32(DMA1_START_ADDR,val)
+#define bfin_read_DMA1_X_COUNT() bfin_read16(DMA1_X_COUNT)
+#define bfin_write_DMA1_X_COUNT(val) bfin_write16(DMA1_X_COUNT,val)
+#define bfin_read_DMA1_Y_COUNT() bfin_read16(DMA1_Y_COUNT)
+#define bfin_write_DMA1_Y_COUNT(val) bfin_write16(DMA1_Y_COUNT,val)
+#define bfin_read_DMA1_X_MODIFY() bfin_read16(DMA1_X_MODIFY)
+#define bfin_write_DMA1_X_MODIFY(val) bfin_write16(DMA1_X_MODIFY,val)
+#define bfin_read_DMA1_Y_MODIFY() bfin_read16(DMA1_Y_MODIFY)
+#define bfin_write_DMA1_Y_MODIFY(val) bfin_write16(DMA1_Y_MODIFY,val)
+#define bfin_read_DMA1_CURR_DESC_PTR() bfin_read32(DMA1_CURR_DESC_PTR)
+#define bfin_write_DMA1_CURR_DESC_PTR(val) bfin_write32(DMA1_CURR_DESC_PTR,val)
+#define bfin_read_DMA1_CURR_ADDR() bfin_read32(DMA1_CURR_ADDR)
+#define bfin_write_DMA1_CURR_ADDR(val) bfin_write32(DMA1_CURR_ADDR,val)
+#define bfin_read_DMA1_CURR_X_COUNT() bfin_read16(DMA1_CURR_X_COUNT)
+#define bfin_write_DMA1_CURR_X_COUNT(val) bfin_write16(DMA1_CURR_X_COUNT,val)
+#define bfin_read_DMA1_CURR_Y_COUNT() bfin_read16(DMA1_CURR_Y_COUNT)
+#define bfin_write_DMA1_CURR_Y_COUNT(val) bfin_write16(DMA1_CURR_Y_COUNT,val)
+#define bfin_read_DMA1_IRQ_STATUS() bfin_read16(DMA1_IRQ_STATUS)
+#define bfin_write_DMA1_IRQ_STATUS(val) bfin_write16(DMA1_IRQ_STATUS,val)
+#define bfin_read_DMA1_PERIPHERAL_MAP() bfin_read16(DMA1_PERIPHERAL_MAP)
+#define bfin_write_DMA1_PERIPHERAL_MAP(val) bfin_write16(DMA1_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA2_CONFIG() bfin_read16(DMA2_CONFIG)
+#define bfin_write_DMA2_CONFIG(val) bfin_write16(DMA2_CONFIG,val)
+#define bfin_read_DMA2_NEXT_DESC_PTR() bfin_read32(DMA2_NEXT_DESC_PTR)
+#define bfin_write_DMA2_NEXT_DESC_PTR(val) bfin_write32(DMA2_NEXT_DESC_PTR,val)
+#define bfin_read_DMA2_START_ADDR() bfin_read32(DMA2_START_ADDR)
+#define bfin_write_DMA2_START_ADDR(val) bfin_write32(DMA2_START_ADDR,val)
+#define bfin_read_DMA2_X_COUNT() bfin_read16(DMA2_X_COUNT)
+#define bfin_write_DMA2_X_COUNT(val) bfin_write16(DMA2_X_COUNT,val)
+#define bfin_read_DMA2_Y_COUNT() bfin_read16(DMA2_Y_COUNT)
+#define bfin_write_DMA2_Y_COUNT(val) bfin_write16(DMA2_Y_COUNT,val)
+#define bfin_read_DMA2_X_MODIFY() bfin_read16(DMA2_X_MODIFY)
+#define bfin_write_DMA2_X_MODIFY(val) bfin_write16(DMA2_X_MODIFY,val)
+#define bfin_read_DMA2_Y_MODIFY() bfin_read16(DMA2_Y_MODIFY)
+#define bfin_write_DMA2_Y_MODIFY(val) bfin_write16(DMA2_Y_MODIFY,val)
+#define bfin_read_DMA2_CURR_DESC_PTR() bfin_read32(DMA2_CURR_DESC_PTR)
+#define bfin_write_DMA2_CURR_DESC_PTR(val) bfin_write32(DMA2_CURR_DESC_PTR,val)
+#define bfin_read_DMA2_CURR_ADDR() bfin_read32(DMA2_CURR_ADDR)
+#define bfin_write_DMA2_CURR_ADDR(val) bfin_write32(DMA2_CURR_ADDR,val)
+#define bfin_read_DMA2_CURR_X_COUNT() bfin_read16(DMA2_CURR_X_COUNT)
+#define bfin_write_DMA2_CURR_X_COUNT(val) bfin_write16(DMA2_CURR_X_COUNT,val)
+#define bfin_read_DMA2_CURR_Y_COUNT() bfin_read16(DMA2_CURR_Y_COUNT)
+#define bfin_write_DMA2_CURR_Y_COUNT(val) bfin_write16(DMA2_CURR_Y_COUNT,val)
+#define bfin_read_DMA2_IRQ_STATUS() bfin_read16(DMA2_IRQ_STATUS)
+#define bfin_write_DMA2_IRQ_STATUS(val) bfin_write16(DMA2_IRQ_STATUS,val)
+#define bfin_read_DMA2_PERIPHERAL_MAP() bfin_read16(DMA2_PERIPHERAL_MAP)
+#define bfin_write_DMA2_PERIPHERAL_MAP(val) bfin_write16(DMA2_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA3_CONFIG() bfin_read16(DMA3_CONFIG)
+#define bfin_write_DMA3_CONFIG(val) bfin_write16(DMA3_CONFIG,val)
+#define bfin_read_DMA3_NEXT_DESC_PTR() bfin_read32(DMA3_NEXT_DESC_PTR)
+#define bfin_write_DMA3_NEXT_DESC_PTR(val) bfin_write32(DMA3_NEXT_DESC_PTR,val)
+#define bfin_read_DMA3_START_ADDR() bfin_read32(DMA3_START_ADDR)
+#define bfin_write_DMA3_START_ADDR(val) bfin_write32(DMA3_START_ADDR,val)
+#define bfin_read_DMA3_X_COUNT() bfin_read16(DMA3_X_COUNT)
+#define bfin_write_DMA3_X_COUNT(val) bfin_write16(DMA3_X_COUNT,val)
+#define bfin_read_DMA3_Y_COUNT() bfin_read16(DMA3_Y_COUNT)
+#define bfin_write_DMA3_Y_COUNT(val) bfin_write16(DMA3_Y_COUNT,val)
+#define bfin_read_DMA3_X_MODIFY() bfin_read16(DMA3_X_MODIFY)
+#define bfin_write_DMA3_X_MODIFY(val) bfin_write16(DMA3_X_MODIFY,val)
+#define bfin_read_DMA3_Y_MODIFY() bfin_read16(DMA3_Y_MODIFY)
+#define bfin_write_DMA3_Y_MODIFY(val) bfin_write16(DMA3_Y_MODIFY,val)
+#define bfin_read_DMA3_CURR_DESC_PTR() bfin_read32(DMA3_CURR_DESC_PTR)
+#define bfin_write_DMA3_CURR_DESC_PTR(val) bfin_write32(DMA3_CURR_DESC_PTR,val)
+#define bfin_read_DMA3_CURR_ADDR() bfin_read32(DMA3_CURR_ADDR)
+#define bfin_write_DMA3_CURR_ADDR(val) bfin_write32(DMA3_CURR_ADDR,val)
+#define bfin_read_DMA3_CURR_X_COUNT() bfin_read16(DMA3_CURR_X_COUNT)
+#define bfin_write_DMA3_CURR_X_COUNT(val) bfin_write16(DMA3_CURR_X_COUNT,val)
+#define bfin_read_DMA3_CURR_Y_COUNT() bfin_read16(DMA3_CURR_Y_COUNT)
+#define bfin_write_DMA3_CURR_Y_COUNT(val) bfin_write16(DMA3_CURR_Y_COUNT,val)
+#define bfin_read_DMA3_IRQ_STATUS() bfin_read16(DMA3_IRQ_STATUS)
+#define bfin_write_DMA3_IRQ_STATUS(val) bfin_write16(DMA3_IRQ_STATUS,val)
+#define bfin_read_DMA3_PERIPHERAL_MAP() bfin_read16(DMA3_PERIPHERAL_MAP)
+#define bfin_write_DMA3_PERIPHERAL_MAP(val) bfin_write16(DMA3_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA4_CONFIG() bfin_read16(DMA4_CONFIG)
+#define bfin_write_DMA4_CONFIG(val) bfin_write16(DMA4_CONFIG,val)
+#define bfin_read_DMA4_NEXT_DESC_PTR() bfin_read32(DMA4_NEXT_DESC_PTR)
+#define bfin_write_DMA4_NEXT_DESC_PTR(val) bfin_write32(DMA4_NEXT_DESC_PTR,val)
+#define bfin_read_DMA4_START_ADDR() bfin_read32(DMA4_START_ADDR)
+#define bfin_write_DMA4_START_ADDR(val) bfin_write32(DMA4_START_ADDR,val)
+#define bfin_read_DMA4_X_COUNT() bfin_read16(DMA4_X_COUNT)
+#define bfin_write_DMA4_X_COUNT(val) bfin_write16(DMA4_X_COUNT,val)
+#define bfin_read_DMA4_Y_COUNT() bfin_read16(DMA4_Y_COUNT)
+#define bfin_write_DMA4_Y_COUNT(val) bfin_write16(DMA4_Y_COUNT,val)
+#define bfin_read_DMA4_X_MODIFY() bfin_read16(DMA4_X_MODIFY)
+#define bfin_write_DMA4_X_MODIFY(val) bfin_write16(DMA4_X_MODIFY,val)
+#define bfin_read_DMA4_Y_MODIFY() bfin_read16(DMA4_Y_MODIFY)
+#define bfin_write_DMA4_Y_MODIFY(val) bfin_write16(DMA4_Y_MODIFY,val)
+#define bfin_read_DMA4_CURR_DESC_PTR() bfin_read32(DMA4_CURR_DESC_PTR)
+#define bfin_write_DMA4_CURR_DESC_PTR(val) bfin_write32(DMA4_CURR_DESC_PTR,val)
+#define bfin_read_DMA4_CURR_ADDR() bfin_read32(DMA4_CURR_ADDR)
+#define bfin_write_DMA4_CURR_ADDR(val) bfin_write32(DMA4_CURR_ADDR,val)
+#define bfin_read_DMA4_CURR_X_COUNT() bfin_read16(DMA4_CURR_X_COUNT)
+#define bfin_write_DMA4_CURR_X_COUNT(val) bfin_write16(DMA4_CURR_X_COUNT,val)
+#define bfin_read_DMA4_CURR_Y_COUNT() bfin_read16(DMA4_CURR_Y_COUNT)
+#define bfin_write_DMA4_CURR_Y_COUNT(val) bfin_write16(DMA4_CURR_Y_COUNT,val)
+#define bfin_read_DMA4_IRQ_STATUS() bfin_read16(DMA4_IRQ_STATUS)
+#define bfin_write_DMA4_IRQ_STATUS(val) bfin_write16(DMA4_IRQ_STATUS,val)
+#define bfin_read_DMA4_PERIPHERAL_MAP() bfin_read16(DMA4_PERIPHERAL_MAP)
+#define bfin_write_DMA4_PERIPHERAL_MAP(val) bfin_write16(DMA4_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA5_CONFIG() bfin_read16(DMA5_CONFIG)
+#define bfin_write_DMA5_CONFIG(val) bfin_write16(DMA5_CONFIG,val)
+#define bfin_read_DMA5_NEXT_DESC_PTR() bfin_read32(DMA5_NEXT_DESC_PTR)
+#define bfin_write_DMA5_NEXT_DESC_PTR(val) bfin_write32(DMA5_NEXT_DESC_PTR,val)
+#define bfin_read_DMA5_START_ADDR() bfin_read32(DMA5_START_ADDR)
+#define bfin_write_DMA5_START_ADDR(val) bfin_write32(DMA5_START_ADDR,val)
+#define bfin_read_DMA5_X_COUNT() bfin_read16(DMA5_X_COUNT)
+#define bfin_write_DMA5_X_COUNT(val) bfin_write16(DMA5_X_COUNT,val)
+#define bfin_read_DMA5_Y_COUNT() bfin_read16(DMA5_Y_COUNT)
+#define bfin_write_DMA5_Y_COUNT(val) bfin_write16(DMA5_Y_COUNT,val)
+#define bfin_read_DMA5_X_MODIFY() bfin_read16(DMA5_X_MODIFY)
+#define bfin_write_DMA5_X_MODIFY(val) bfin_write16(DMA5_X_MODIFY,val)
+#define bfin_read_DMA5_Y_MODIFY() bfin_read16(DMA5_Y_MODIFY)
+#define bfin_write_DMA5_Y_MODIFY(val) bfin_write16(DMA5_Y_MODIFY,val)
+#define bfin_read_DMA5_CURR_DESC_PTR() bfin_read32(DMA5_CURR_DESC_PTR)
+#define bfin_write_DMA5_CURR_DESC_PTR(val) bfin_write32(DMA5_CURR_DESC_PTR,val)
+#define bfin_read_DMA5_CURR_ADDR() bfin_read32(DMA5_CURR_ADDR)
+#define bfin_write_DMA5_CURR_ADDR(val) bfin_write32(DMA5_CURR_ADDR,val)
+#define bfin_read_DMA5_CURR_X_COUNT() bfin_read16(DMA5_CURR_X_COUNT)
+#define bfin_write_DMA5_CURR_X_COUNT(val) bfin_write16(DMA5_CURR_X_COUNT,val)
+#define bfin_read_DMA5_CURR_Y_COUNT() bfin_read16(DMA5_CURR_Y_COUNT)
+#define bfin_write_DMA5_CURR_Y_COUNT(val) bfin_write16(DMA5_CURR_Y_COUNT,val)
+#define bfin_read_DMA5_IRQ_STATUS() bfin_read16(DMA5_IRQ_STATUS)
+#define bfin_write_DMA5_IRQ_STATUS(val) bfin_write16(DMA5_IRQ_STATUS,val)
+#define bfin_read_DMA5_PERIPHERAL_MAP() bfin_read16(DMA5_PERIPHERAL_MAP)
+#define bfin_write_DMA5_PERIPHERAL_MAP(val) bfin_write16(DMA5_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA6_CONFIG() bfin_read16(DMA6_CONFIG)
+#define bfin_write_DMA6_CONFIG(val) bfin_write16(DMA6_CONFIG,val)
+#define bfin_read_DMA6_NEXT_DESC_PTR() bfin_read32(DMA6_NEXT_DESC_PTR)
+#define bfin_write_DMA6_NEXT_DESC_PTR(val) bfin_write32(DMA6_NEXT_DESC_PTR,val)
+#define bfin_read_DMA6_START_ADDR() bfin_read32(DMA6_START_ADDR)
+#define bfin_write_DMA6_START_ADDR(val) bfin_write32(DMA6_START_ADDR,val)
+#define bfin_read_DMA6_X_COUNT() bfin_read16(DMA6_X_COUNT)
+#define bfin_write_DMA6_X_COUNT(val) bfin_write16(DMA6_X_COUNT,val)
+#define bfin_read_DMA6_Y_COUNT() bfin_read16(DMA6_Y_COUNT)
+#define bfin_write_DMA6_Y_COUNT(val) bfin_write16(DMA6_Y_COUNT,val)
+#define bfin_read_DMA6_X_MODIFY() bfin_read16(DMA6_X_MODIFY)
+#define bfin_write_DMA6_X_MODIFY(val) bfin_write16(DMA6_X_MODIFY,val)
+#define bfin_read_DMA6_Y_MODIFY() bfin_read16(DMA6_Y_MODIFY)
+#define bfin_write_DMA6_Y_MODIFY(val) bfin_write16(DMA6_Y_MODIFY,val)
+#define bfin_read_DMA6_CURR_DESC_PTR() bfin_read32(DMA6_CURR_DESC_PTR)
+#define bfin_write_DMA6_CURR_DESC_PTR(val) bfin_write32(DMA6_CURR_DESC_PTR,val)
+#define bfin_read_DMA6_CURR_ADDR() bfin_read32(DMA6_CURR_ADDR)
+#define bfin_write_DMA6_CURR_ADDR(val) bfin_write32(DMA6_CURR_ADDR,val)
+#define bfin_read_DMA6_CURR_X_COUNT() bfin_read16(DMA6_CURR_X_COUNT)
+#define bfin_write_DMA6_CURR_X_COUNT(val) bfin_write16(DMA6_CURR_X_COUNT,val)
+#define bfin_read_DMA6_CURR_Y_COUNT() bfin_read16(DMA6_CURR_Y_COUNT)
+#define bfin_write_DMA6_CURR_Y_COUNT(val) bfin_write16(DMA6_CURR_Y_COUNT,val)
+#define bfin_read_DMA6_IRQ_STATUS() bfin_read16(DMA6_IRQ_STATUS)
+#define bfin_write_DMA6_IRQ_STATUS(val) bfin_write16(DMA6_IRQ_STATUS,val)
+#define bfin_read_DMA6_PERIPHERAL_MAP() bfin_read16(DMA6_PERIPHERAL_MAP)
+#define bfin_write_DMA6_PERIPHERAL_MAP(val) bfin_write16(DMA6_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA7_CONFIG() bfin_read16(DMA7_CONFIG)
+#define bfin_write_DMA7_CONFIG(val) bfin_write16(DMA7_CONFIG,val)
+#define bfin_read_DMA7_NEXT_DESC_PTR() bfin_read32(DMA7_NEXT_DESC_PTR)
+#define bfin_write_DMA7_NEXT_DESC_PTR(val) bfin_write32(DMA7_NEXT_DESC_PTR,val)
+#define bfin_read_DMA7_START_ADDR() bfin_read32(DMA7_START_ADDR)
+#define bfin_write_DMA7_START_ADDR(val) bfin_write32(DMA7_START_ADDR,val)
+#define bfin_read_DMA7_X_COUNT() bfin_read16(DMA7_X_COUNT)
+#define bfin_write_DMA7_X_COUNT(val) bfin_write16(DMA7_X_COUNT,val)
+#define bfin_read_DMA7_Y_COUNT() bfin_read16(DMA7_Y_COUNT)
+#define bfin_write_DMA7_Y_COUNT(val) bfin_write16(DMA7_Y_COUNT,val)
+#define bfin_read_DMA7_X_MODIFY() bfin_read16(DMA7_X_MODIFY)
+#define bfin_write_DMA7_X_MODIFY(val) bfin_write16(DMA7_X_MODIFY,val)
+#define bfin_read_DMA7_Y_MODIFY() bfin_read16(DMA7_Y_MODIFY)
+#define bfin_write_DMA7_Y_MODIFY(val) bfin_write16(DMA7_Y_MODIFY,val)
+#define bfin_read_DMA7_CURR_DESC_PTR() bfin_read32(DMA7_CURR_DESC_PTR)
+#define bfin_write_DMA7_CURR_DESC_PTR(val) bfin_write32(DMA7_CURR_DESC_PTR,val)
+#define bfin_read_DMA7_CURR_ADDR() bfin_read32(DMA7_CURR_ADDR)
+#define bfin_write_DMA7_CURR_ADDR(val) bfin_write32(DMA7_CURR_ADDR,val)
+#define bfin_read_DMA7_CURR_X_COUNT() bfin_read16(DMA7_CURR_X_COUNT)
+#define bfin_write_DMA7_CURR_X_COUNT(val) bfin_write16(DMA7_CURR_X_COUNT,val)
+#define bfin_read_DMA7_CURR_Y_COUNT() bfin_read16(DMA7_CURR_Y_COUNT)
+#define bfin_write_DMA7_CURR_Y_COUNT(val) bfin_write16(DMA7_CURR_Y_COUNT,val)
+#define bfin_read_DMA7_IRQ_STATUS() bfin_read16(DMA7_IRQ_STATUS)
+#define bfin_write_DMA7_IRQ_STATUS(val) bfin_write16(DMA7_IRQ_STATUS,val)
+#define bfin_read_DMA7_PERIPHERAL_MAP() bfin_read16(DMA7_PERIPHERAL_MAP)
+#define bfin_write_DMA7_PERIPHERAL_MAP(val) bfin_write16(DMA7_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA8_CONFIG() bfin_read16(DMA8_CONFIG)
+#define bfin_write_DMA8_CONFIG(val) bfin_write16(DMA8_CONFIG,val)
+#define bfin_read_DMA8_NEXT_DESC_PTR() bfin_read32(DMA8_NEXT_DESC_PTR)
+#define bfin_write_DMA8_NEXT_DESC_PTR(val) bfin_write32(DMA8_NEXT_DESC_PTR,val)
+#define bfin_read_DMA8_START_ADDR() bfin_read32(DMA8_START_ADDR)
+#define bfin_write_DMA8_START_ADDR(val) bfin_write32(DMA8_START_ADDR,val)
+#define bfin_read_DMA8_X_COUNT() bfin_read16(DMA8_X_COUNT)
+#define bfin_write_DMA8_X_COUNT(val) bfin_write16(DMA8_X_COUNT,val)
+#define bfin_read_DMA8_Y_COUNT() bfin_read16(DMA8_Y_COUNT)
+#define bfin_write_DMA8_Y_COUNT(val) bfin_write16(DMA8_Y_COUNT,val)
+#define bfin_read_DMA8_X_MODIFY() bfin_read16(DMA8_X_MODIFY)
+#define bfin_write_DMA8_X_MODIFY(val) bfin_write16(DMA8_X_MODIFY,val)
+#define bfin_read_DMA8_Y_MODIFY() bfin_read16(DMA8_Y_MODIFY)
+#define bfin_write_DMA8_Y_MODIFY(val) bfin_write16(DMA8_Y_MODIFY,val)
+#define bfin_read_DMA8_CURR_DESC_PTR() bfin_read32(DMA8_CURR_DESC_PTR)
+#define bfin_write_DMA8_CURR_DESC_PTR(val) bfin_write32(DMA8_CURR_DESC_PTR,val)
+#define bfin_read_DMA8_CURR_ADDR() bfin_read32(DMA8_CURR_ADDR)
+#define bfin_write_DMA8_CURR_ADDR(val) bfin_write32(DMA8_CURR_ADDR,val)
+#define bfin_read_DMA8_CURR_X_COUNT() bfin_read16(DMA8_CURR_X_COUNT)
+#define bfin_write_DMA8_CURR_X_COUNT(val) bfin_write16(DMA8_CURR_X_COUNT,val)
+#define bfin_read_DMA8_CURR_Y_COUNT() bfin_read16(DMA8_CURR_Y_COUNT)
+#define bfin_write_DMA8_CURR_Y_COUNT(val) bfin_write16(DMA8_CURR_Y_COUNT,val)
+#define bfin_read_DMA8_IRQ_STATUS() bfin_read16(DMA8_IRQ_STATUS)
+#define bfin_write_DMA8_IRQ_STATUS(val) bfin_write16(DMA8_IRQ_STATUS,val)
+#define bfin_read_DMA8_PERIPHERAL_MAP() bfin_read16(DMA8_PERIPHERAL_MAP)
+#define bfin_write_DMA8_PERIPHERAL_MAP(val) bfin_write16(DMA8_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA9_CONFIG() bfin_read16(DMA9_CONFIG)
+#define bfin_write_DMA9_CONFIG(val) bfin_write16(DMA9_CONFIG,val)
+#define bfin_read_DMA9_NEXT_DESC_PTR() bfin_read32(DMA9_NEXT_DESC_PTR)
+#define bfin_write_DMA9_NEXT_DESC_PTR(val) bfin_write32(DMA9_NEXT_DESC_PTR,val)
+#define bfin_read_DMA9_START_ADDR() bfin_read32(DMA9_START_ADDR)
+#define bfin_write_DMA9_START_ADDR(val) bfin_write32(DMA9_START_ADDR,val)
+#define bfin_read_DMA9_X_COUNT() bfin_read16(DMA9_X_COUNT)
+#define bfin_write_DMA9_X_COUNT(val) bfin_write16(DMA9_X_COUNT,val)
+#define bfin_read_DMA9_Y_COUNT() bfin_read16(DMA9_Y_COUNT)
+#define bfin_write_DMA9_Y_COUNT(val) bfin_write16(DMA9_Y_COUNT,val)
+#define bfin_read_DMA9_X_MODIFY() bfin_read16(DMA9_X_MODIFY)
+#define bfin_write_DMA9_X_MODIFY(val) bfin_write16(DMA9_X_MODIFY,val)
+#define bfin_read_DMA9_Y_MODIFY() bfin_read16(DMA9_Y_MODIFY)
+#define bfin_write_DMA9_Y_MODIFY(val) bfin_write16(DMA9_Y_MODIFY,val)
+#define bfin_read_DMA9_CURR_DESC_PTR() bfin_read32(DMA9_CURR_DESC_PTR)
+#define bfin_write_DMA9_CURR_DESC_PTR(val) bfin_write32(DMA9_CURR_DESC_PTR,val)
+#define bfin_read_DMA9_CURR_ADDR() bfin_read32(DMA9_CURR_ADDR)
+#define bfin_write_DMA9_CURR_ADDR(val) bfin_write32(DMA9_CURR_ADDR,val)
+#define bfin_read_DMA9_CURR_X_COUNT() bfin_read16(DMA9_CURR_X_COUNT)
+#define bfin_write_DMA9_CURR_X_COUNT(val) bfin_write16(DMA9_CURR_X_COUNT,val)
+#define bfin_read_DMA9_CURR_Y_COUNT() bfin_read16(DMA9_CURR_Y_COUNT)
+#define bfin_write_DMA9_CURR_Y_COUNT(val) bfin_write16(DMA9_CURR_Y_COUNT,val)
+#define bfin_read_DMA9_IRQ_STATUS() bfin_read16(DMA9_IRQ_STATUS)
+#define bfin_write_DMA9_IRQ_STATUS(val) bfin_write16(DMA9_IRQ_STATUS,val)
+#define bfin_read_DMA9_PERIPHERAL_MAP() bfin_read16(DMA9_PERIPHERAL_MAP)
+#define bfin_write_DMA9_PERIPHERAL_MAP(val) bfin_write16(DMA9_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA10_CONFIG() bfin_read16(DMA10_CONFIG)
+#define bfin_write_DMA10_CONFIG(val) bfin_write16(DMA10_CONFIG,val)
+#define bfin_read_DMA10_NEXT_DESC_PTR() bfin_read32(DMA10_NEXT_DESC_PTR)
+#define bfin_write_DMA10_NEXT_DESC_PTR(val) bfin_write32(DMA10_NEXT_DESC_PTR,val)
+#define bfin_read_DMA10_START_ADDR() bfin_read32(DMA10_START_ADDR)
+#define bfin_write_DMA10_START_ADDR(val) bfin_write32(DMA10_START_ADDR,val)
+#define bfin_read_DMA10_X_COUNT() bfin_read16(DMA10_X_COUNT)
+#define bfin_write_DMA10_X_COUNT(val) bfin_write16(DMA10_X_COUNT,val)
+#define bfin_read_DMA10_Y_COUNT() bfin_read16(DMA10_Y_COUNT)
+#define bfin_write_DMA10_Y_COUNT(val) bfin_write16(DMA10_Y_COUNT,val)
+#define bfin_read_DMA10_X_MODIFY() bfin_read16(DMA10_X_MODIFY)
+#define bfin_write_DMA10_X_MODIFY(val) bfin_write16(DMA10_X_MODIFY,val)
+#define bfin_read_DMA10_Y_MODIFY() bfin_read16(DMA10_Y_MODIFY)
+#define bfin_write_DMA10_Y_MODIFY(val) bfin_write16(DMA10_Y_MODIFY,val)
+#define bfin_read_DMA10_CURR_DESC_PTR() bfin_read32(DMA10_CURR_DESC_PTR)
+#define bfin_write_DMA10_CURR_DESC_PTR(val) bfin_write32(DMA10_CURR_DESC_PTR,val)
+#define bfin_read_DMA10_CURR_ADDR() bfin_read32(DMA10_CURR_ADDR)
+#define bfin_write_DMA10_CURR_ADDR(val) bfin_write32(DMA10_CURR_ADDR,val)
+#define bfin_read_DMA10_CURR_X_COUNT() bfin_read16(DMA10_CURR_X_COUNT)
+#define bfin_write_DMA10_CURR_X_COUNT(val) bfin_write16(DMA10_CURR_X_COUNT,val)
+#define bfin_read_DMA10_CURR_Y_COUNT() bfin_read16(DMA10_CURR_Y_COUNT)
+#define bfin_write_DMA10_CURR_Y_COUNT(val) bfin_write16(DMA10_CURR_Y_COUNT,val)
+#define bfin_read_DMA10_IRQ_STATUS() bfin_read16(DMA10_IRQ_STATUS)
+#define bfin_write_DMA10_IRQ_STATUS(val) bfin_write16(DMA10_IRQ_STATUS,val)
+#define bfin_read_DMA10_PERIPHERAL_MAP() bfin_read16(DMA10_PERIPHERAL_MAP)
+#define bfin_write_DMA10_PERIPHERAL_MAP(val) bfin_write16(DMA10_PERIPHERAL_MAP,val)
+
+#define bfin_read_DMA11_CONFIG() bfin_read16(DMA11_CONFIG)
+#define bfin_write_DMA11_CONFIG(val) bfin_write16(DMA11_CONFIG,val)
+#define bfin_read_DMA11_NEXT_DESC_PTR() bfin_read32(DMA11_NEXT_DESC_PTR)
+#define bfin_write_DMA11_NEXT_DESC_PTR(val) bfin_write32(DMA11_NEXT_DESC_PTR,val)
+#define bfin_read_DMA11_START_ADDR() bfin_read32(DMA11_START_ADDR)
+#define bfin_write_DMA11_START_ADDR(val) bfin_write32(DMA11_START_ADDR,val)
+#define bfin_read_DMA11_X_COUNT() bfin_read16(DMA11_X_COUNT)
+#define bfin_write_DMA11_X_COUNT(val) bfin_write16(DMA11_X_COUNT,val)
+#define bfin_read_DMA11_Y_COUNT() bfin_read16(DMA11_Y_COUNT)
+#define bfin_write_DMA11_Y_COUNT(val) bfin_write16(DMA11_Y_COUNT,val)
+#define bfin_read_DMA11_X_MODIFY() bfin_read16(DMA11_X_MODIFY)
+#define bfin_write_DMA11_X_MODIFY(val) bfin_write16(DMA11_X_MODIFY,val)
+#define bfin_read_DMA11_Y_MODIFY() bfin_read16(DMA11_Y_MODIFY)
+#define bfin_write_DMA11_Y_MODIFY(val) bfin_write16(DMA11_Y_MODIFY,val)
+#define bfin_read_DMA11_CURR_DESC_PTR() bfin_read32(DMA11_CURR_DESC_PTR)
+#define bfin_write_DMA11_CURR_DESC_PTR(val) bfin_write32(DMA11_CURR_DESC_PTR,val)
+#define bfin_read_DMA11_CURR_ADDR() bfin_read32(DMA11_CURR_ADDR)
+#define bfin_write_DMA11_CURR_ADDR(val) bfin_write32(DMA11_CURR_ADDR,val)
+#define bfin_read_DMA11_CURR_X_COUNT() bfin_read16(DMA11_CURR_X_COUNT)
+#define bfin_write_DMA11_CURR_X_COUNT(val) bfin_write16(DMA11_CURR_X_COUNT,val)
+#define bfin_read_DMA11_CURR_Y_COUNT() bfin_read16(DMA11_CURR_Y_COUNT)
+#define bfin_write_DMA11_CURR_Y_COUNT(val) bfin_write16(DMA11_CURR_Y_COUNT,val)
+#define bfin_read_DMA11_IRQ_STATUS() bfin_read16(DMA11_IRQ_STATUS)
+#define bfin_write_DMA11_IRQ_STATUS(val) bfin_write16(DMA11_IRQ_STATUS,val)
+#define bfin_read_DMA11_PERIPHERAL_MAP() bfin_read16(DMA11_PERIPHERAL_MAP)
+#define bfin_write_DMA11_PERIPHERAL_MAP(val) bfin_write16(DMA11_PERIPHERAL_MAP,val)
+
+#define bfin_read_MDMA_D0_CONFIG() bfin_read16(MDMA_D0_CONFIG)
+#define bfin_write_MDMA_D0_CONFIG(val) bfin_write16(MDMA_D0_CONFIG,val)
+#define bfin_read_MDMA_D0_NEXT_DESC_PTR() bfin_read32(MDMA_D0_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA_D0_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_D0_START_ADDR() bfin_read32(MDMA_D0_START_ADDR)
+#define bfin_write_MDMA_D0_START_ADDR(val) bfin_write32(MDMA_D0_START_ADDR,val)
+#define bfin_read_MDMA_D0_X_COUNT() bfin_read16(MDMA_D0_X_COUNT)
+#define bfin_write_MDMA_D0_X_COUNT(val) bfin_write16(MDMA_D0_X_COUNT,val)
+#define bfin_read_MDMA_D0_Y_COUNT() bfin_read16(MDMA_D0_Y_COUNT)
+#define bfin_write_MDMA_D0_Y_COUNT(val) bfin_write16(MDMA_D0_Y_COUNT,val)
+#define bfin_read_MDMA_D0_X_MODIFY() bfin_read16(MDMA_D0_X_MODIFY)
+#define bfin_write_MDMA_D0_X_MODIFY(val) bfin_write16(MDMA_D0_X_MODIFY,val)
+#define bfin_read_MDMA_D0_Y_MODIFY() bfin_read16(MDMA_D0_Y_MODIFY)
+#define bfin_write_MDMA_D0_Y_MODIFY(val) bfin_write16(MDMA_D0_Y_MODIFY,val)
+#define bfin_read_MDMA_D0_CURR_DESC_PTR() bfin_read32(MDMA_D0_CURR_DESC_PTR)
+#define bfin_write_MDMA_D0_CURR_DESC_PTR(val) bfin_write32(MDMA_D0_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_D0_CURR_ADDR() bfin_read32(MDMA_D0_CURR_ADDR)
+#define bfin_write_MDMA_D0_CURR_ADDR(val) bfin_write32(MDMA_D0_CURR_ADDR,val)
+#define bfin_read_MDMA_D0_CURR_X_COUNT() bfin_read16(MDMA_D0_CURR_X_COUNT)
+#define bfin_write_MDMA_D0_CURR_X_COUNT(val) bfin_write16(MDMA_D0_CURR_X_COUNT,val)
+#define bfin_read_MDMA_D0_CURR_Y_COUNT() bfin_read16(MDMA_D0_CURR_Y_COUNT)
+#define bfin_write_MDMA_D0_CURR_Y_COUNT(val) bfin_write16(MDMA_D0_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_D0_IRQ_STATUS() bfin_read16(MDMA_D0_IRQ_STATUS)
+#define bfin_write_MDMA_D0_IRQ_STATUS(val) bfin_write16(MDMA_D0_IRQ_STATUS,val)
+#define bfin_read_MDMA_D0_PERIPHERAL_MAP() bfin_read16(MDMA_D0_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA_D0_PERIPHERAL_MAP,val)
+
+#define bfin_read_MDMA_S0_CONFIG() bfin_read16(MDMA_S0_CONFIG)
+#define bfin_write_MDMA_S0_CONFIG(val) bfin_write16(MDMA_S0_CONFIG,val)
+#define bfin_read_MDMA_S0_NEXT_DESC_PTR() bfin_read32(MDMA_S0_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA_S0_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_S0_START_ADDR() bfin_read32(MDMA_S0_START_ADDR)
+#define bfin_write_MDMA_S0_START_ADDR(val) bfin_write32(MDMA_S0_START_ADDR,val)
+#define bfin_read_MDMA_S0_X_COUNT() bfin_read16(MDMA_S0_X_COUNT)
+#define bfin_write_MDMA_S0_X_COUNT(val) bfin_write16(MDMA_S0_X_COUNT,val)
+#define bfin_read_MDMA_S0_Y_COUNT() bfin_read16(MDMA_S0_Y_COUNT)
+#define bfin_write_MDMA_S0_Y_COUNT(val) bfin_write16(MDMA_S0_Y_COUNT,val)
+#define bfin_read_MDMA_S0_X_MODIFY() bfin_read16(MDMA_S0_X_MODIFY)
+#define bfin_write_MDMA_S0_X_MODIFY(val) bfin_write16(MDMA_S0_X_MODIFY,val)
+#define bfin_read_MDMA_S0_Y_MODIFY() bfin_read16(MDMA_S0_Y_MODIFY)
+#define bfin_write_MDMA_S0_Y_MODIFY(val) bfin_write16(MDMA_S0_Y_MODIFY,val)
+#define bfin_read_MDMA_S0_CURR_DESC_PTR() bfin_read32(MDMA_S0_CURR_DESC_PTR)
+#define bfin_write_MDMA_S0_CURR_DESC_PTR(val) bfin_write32(MDMA_S0_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_S0_CURR_ADDR() bfin_read32(MDMA_S0_CURR_ADDR)
+#define bfin_write_MDMA_S0_CURR_ADDR(val) bfin_write32(MDMA_S0_CURR_ADDR,val)
+#define bfin_read_MDMA_S0_CURR_X_COUNT() bfin_read16(MDMA_S0_CURR_X_COUNT)
+#define bfin_write_MDMA_S0_CURR_X_COUNT(val) bfin_write16(MDMA_S0_CURR_X_COUNT,val)
+#define bfin_read_MDMA_S0_CURR_Y_COUNT() bfin_read16(MDMA_S0_CURR_Y_COUNT)
+#define bfin_write_MDMA_S0_CURR_Y_COUNT(val) bfin_write16(MDMA_S0_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_S0_IRQ_STATUS() bfin_read16(MDMA_S0_IRQ_STATUS)
+#define bfin_write_MDMA_S0_IRQ_STATUS(val) bfin_write16(MDMA_S0_IRQ_STATUS,val)
+#define bfin_read_MDMA_S0_PERIPHERAL_MAP() bfin_read16(MDMA_S0_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA_S0_PERIPHERAL_MAP,val)
+
+#define bfin_read_MDMA_D1_CONFIG() bfin_read16(MDMA_D1_CONFIG)
+#define bfin_write_MDMA_D1_CONFIG(val) bfin_write16(MDMA_D1_CONFIG,val)
+#define bfin_read_MDMA_D1_NEXT_DESC_PTR() bfin_read32(MDMA_D1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA_D1_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_D1_START_ADDR() bfin_read32(MDMA_D1_START_ADDR)
+#define bfin_write_MDMA_D1_START_ADDR(val) bfin_write32(MDMA_D1_START_ADDR,val)
+#define bfin_read_MDMA_D1_X_COUNT() bfin_read16(MDMA_D1_X_COUNT)
+#define bfin_write_MDMA_D1_X_COUNT(val) bfin_write16(MDMA_D1_X_COUNT,val)
+#define bfin_read_MDMA_D1_Y_COUNT() bfin_read16(MDMA_D1_Y_COUNT)
+#define bfin_write_MDMA_D1_Y_COUNT(val) bfin_write16(MDMA_D1_Y_COUNT,val)
+#define bfin_read_MDMA_D1_X_MODIFY() bfin_read16(MDMA_D1_X_MODIFY)
+#define bfin_write_MDMA_D1_X_MODIFY(val) bfin_write16(MDMA_D1_X_MODIFY,val)
+#define bfin_read_MDMA_D1_Y_MODIFY() bfin_read16(MDMA_D1_Y_MODIFY)
+#define bfin_write_MDMA_D1_Y_MODIFY(val) bfin_write16(MDMA_D1_Y_MODIFY,val)
+#define bfin_read_MDMA_D1_CURR_DESC_PTR() bfin_read32(MDMA_D1_CURR_DESC_PTR)
+#define bfin_write_MDMA_D1_CURR_DESC_PTR(val) bfin_write32(MDMA_D1_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_D1_CURR_ADDR() bfin_read32(MDMA_D1_CURR_ADDR)
+#define bfin_write_MDMA_D1_CURR_ADDR(val) bfin_write32(MDMA_D1_CURR_ADDR,val)
+#define bfin_read_MDMA_D1_CURR_X_COUNT() bfin_read16(MDMA_D1_CURR_X_COUNT)
+#define bfin_write_MDMA_D1_CURR_X_COUNT(val) bfin_write16(MDMA_D1_CURR_X_COUNT,val)
+#define bfin_read_MDMA_D1_CURR_Y_COUNT() bfin_read16(MDMA_D1_CURR_Y_COUNT)
+#define bfin_write_MDMA_D1_CURR_Y_COUNT(val) bfin_write16(MDMA_D1_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_D1_IRQ_STATUS() bfin_read16(MDMA_D1_IRQ_STATUS)
+#define bfin_write_MDMA_D1_IRQ_STATUS(val) bfin_write16(MDMA_D1_IRQ_STATUS,val)
+#define bfin_read_MDMA_D1_PERIPHERAL_MAP() bfin_read16(MDMA_D1_PERIPHERAL_MAP)
+#define bfin_write_MDMA_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA_D1_PERIPHERAL_MAP,val)
+
+#define bfin_read_MDMA_S1_CONFIG() bfin_read16(MDMA_S1_CONFIG)
+#define bfin_write_MDMA_S1_CONFIG(val) bfin_write16(MDMA_S1_CONFIG,val)
+#define bfin_read_MDMA_S1_NEXT_DESC_PTR() bfin_read32(MDMA_S1_NEXT_DESC_PTR)
+#define bfin_write_MDMA_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA_S1_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA_S1_START_ADDR() bfin_read32(MDMA_S1_START_ADDR)
+#define bfin_write_MDMA_S1_START_ADDR(val) bfin_write32(MDMA_S1_START_ADDR,val)
+#define bfin_read_MDMA_S1_X_COUNT() bfin_read16(MDMA_S1_X_COUNT)
+#define bfin_write_MDMA_S1_X_COUNT(val) bfin_write16(MDMA_S1_X_COUNT,val)
+#define bfin_read_MDMA_S1_Y_COUNT() bfin_read16(MDMA_S1_Y_COUNT)
+#define bfin_write_MDMA_S1_Y_COUNT(val) bfin_write16(MDMA_S1_Y_COUNT,val)
+#define bfin_read_MDMA_S1_X_MODIFY() bfin_read16(MDMA_S1_X_MODIFY)
+#define bfin_write_MDMA_S1_X_MODIFY(val) bfin_write16(MDMA_S1_X_MODIFY,val)
+#define bfin_read_MDMA_S1_Y_MODIFY() bfin_read16(MDMA_S1_Y_MODIFY)
+#define bfin_write_MDMA_S1_Y_MODIFY(val) bfin_write16(MDMA_S1_Y_MODIFY,val)
+#define bfin_read_MDMA_S1_CURR_DESC_PTR() bfin_read32(MDMA_S1_CURR_DESC_PTR)
+#define bfin_write_MDMA_S1_CURR_DESC_PTR(val) bfin_write32(MDMA_S1_CURR_DESC_PTR,val)
+#define bfin_read_MDMA_S1_CURR_ADDR() bfin_read32(MDMA_S1_CURR_ADDR)
+#define bfin_write_MDMA_S1_CURR_ADDR(val) bfin_write32(MDMA_S1_CURR_ADDR,val)
+#define bfin_read_MDMA_S1_CURR_X_COUNT() bfin_read16(MDMA_S1_CURR_X_COUNT)
+#define bfin_write_MDMA_S1_CURR_X_COUNT(val) bfin_write16(MDMA_S1_CURR_X_COUNT,val)
+#define bfin_read_MDMA_S1_CURR_Y_COUNT() bfin_read16(MDMA_S1_CURR_Y_COUNT)
+#define bfin_write_MDMA_S1_CURR_Y_COUNT(val) bfin_write16(MDMA_S1_CURR_Y_COUNT,val)
+#define bfin_read_MDMA_S1_IRQ_STATUS() bfin_read16(MDMA_S1_IRQ_STATUS)
+#define bfin_write_MDMA_S1_IRQ_STATUS(val) bfin_write16(MDMA_S1_IRQ_STATUS,val)
+#define bfin_read_MDMA_S1_PERIPHERAL_MAP() bfin_read16(MDMA_S1_PERIPHERAL_MAP)
+#define bfin_write_MDMA_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA_S1_PERIPHERAL_MAP,val)
+
+/* Parallel Peripheral Interface (0xFFC01000 - 0xFFC010FF) */
+#define bfin_read_PPI_CONTROL() bfin_read16(PPI_CONTROL)
+#define bfin_write_PPI_CONTROL(val) bfin_write16(PPI_CONTROL,val)
+#define bfin_read_PPI_STATUS() bfin_read16(PPI_STATUS)
+#define bfin_write_PPI_STATUS(val) bfin_write16(PPI_STATUS,val)
+#define bfin_clear_PPI_STATUS() bfin_write_PPI_STATUS(0xFFFF)
+#define bfin_read_PPI_DELAY() bfin_read16(PPI_DELAY)
+#define bfin_write_PPI_DELAY(val) bfin_write16(PPI_DELAY,val)
+#define bfin_read_PPI_COUNT() bfin_read16(PPI_COUNT)
+#define bfin_write_PPI_COUNT(val) bfin_write16(PPI_COUNT,val)
+#define bfin_read_PPI_FRAME() bfin_read16(PPI_FRAME)
+#define bfin_write_PPI_FRAME(val) bfin_write16(PPI_FRAME,val)
+
+/* Two-Wire Interface (0xFFC01400 - 0xFFC014FF) */
+#define bfin_read_TWI_CLKDIV() bfin_read16(TWI_CLKDIV)
+#define bfin_write_TWI_CLKDIV(val) bfin_write16(TWI_CLKDIV,val)
+#define bfin_read_TWI_CONTROL() bfin_read16(TWI_CONTROL)
+#define bfin_write_TWI_CONTROL(val) bfin_write16(TWI_CONTROL,val)
+#define bfin_read_TWI_SLAVE_CTL() bfin_read16(TWI_SLAVE_CTL)
+#define bfin_write_TWI_SLAVE_CTL(val) bfin_write16(TWI_SLAVE_CTL,val)
+#define bfin_read_TWI_SLAVE_STAT() bfin_read16(TWI_SLAVE_STAT)
+#define bfin_write_TWI_SLAVE_STAT(val) bfin_write16(TWI_SLAVE_STAT,val)
+#define bfin_read_TWI_SLAVE_ADDR() bfin_read16(TWI_SLAVE_ADDR)
+#define bfin_write_TWI_SLAVE_ADDR(val) bfin_write16(TWI_SLAVE_ADDR,val)
+#define bfin_read_TWI_MASTER_CTL() bfin_read16(TWI_MASTER_CTL)
+#define bfin_write_TWI_MASTER_CTL(val) bfin_write16(TWI_MASTER_CTL,val)
+#define bfin_read_TWI_MASTER_STAT() bfin_read16(TWI_MASTER_STAT)
+#define bfin_write_TWI_MASTER_STAT(val) bfin_write16(TWI_MASTER_STAT,val)
+#define bfin_read_TWI_MASTER_ADDR() bfin_read16(TWI_MASTER_ADDR)
+#define bfin_write_TWI_MASTER_ADDR(val) bfin_write16(TWI_MASTER_ADDR,val)
+#define bfin_read_TWI_INT_STAT() bfin_read16(TWI_INT_STAT)
+#define bfin_write_TWI_INT_STAT(val) bfin_write16(TWI_INT_STAT,val)
+#define bfin_read_TWI_INT_MASK() bfin_read16(TWI_INT_MASK)
+#define bfin_write_TWI_INT_MASK(val) bfin_write16(TWI_INT_MASK,val)
+#define bfin_read_TWI_FIFO_CTL() bfin_read16(TWI_FIFO_CTL)
+#define bfin_write_TWI_FIFO_CTL(val) bfin_write16(TWI_FIFO_CTL,val)
+#define bfin_read_TWI_FIFO_STAT() bfin_read16(TWI_FIFO_STAT)
+#define bfin_write_TWI_FIFO_STAT(val) bfin_write16(TWI_FIFO_STAT,val)
+#define bfin_read_TWI_XMT_DATA8() bfin_read16(TWI_XMT_DATA8)
+#define bfin_write_TWI_XMT_DATA8(val) bfin_write16(TWI_XMT_DATA8,val)
+#define bfin_read_TWI_XMT_DATA16() bfin_read16(TWI_XMT_DATA16)
+#define bfin_write_TWI_XMT_DATA16(val) bfin_write16(TWI_XMT_DATA16,val)
+#define bfin_read_TWI_RCV_DATA8() bfin_read16(TWI_RCV_DATA8)
+#define bfin_write_TWI_RCV_DATA8(val) bfin_write16(TWI_RCV_DATA8,val)
+#define bfin_read_TWI_RCV_DATA16() bfin_read16(TWI_RCV_DATA16)
+#define bfin_write_TWI_RCV_DATA16(val) bfin_write16(TWI_RCV_DATA16,val)
+
+/* General Purpose I/O Port G (0xFFC01500 - 0xFFC015FF) */
+#define bfin_read_PORTGIO() bfin_read16(PORTGIO)
+#define bfin_write_PORTGIO(val) bfin_write16(PORTGIO,val)
+#define bfin_read_PORTGIO_CLEAR() bfin_read16(PORTGIO_CLEAR)
+#define bfin_write_PORTGIO_CLEAR(val) bfin_write16(PORTGIO_CLEAR,val)
+#define bfin_read_PORTGIO_SET() bfin_read16(PORTGIO_SET)
+#define bfin_write_PORTGIO_SET(val) bfin_write16(PORTGIO_SET,val)
+#define bfin_read_PORTGIO_TOGGLE() bfin_read16(PORTGIO_TOGGLE)
+#define bfin_write_PORTGIO_TOGGLE(val) bfin_write16(PORTGIO_TOGGLE,val)
+#define bfin_read_PORTGIO_MASKA() bfin_read16(PORTGIO_MASKA)
+#define bfin_write_PORTGIO_MASKA(val) bfin_write16(PORTGIO_MASKA,val)
+#define bfin_read_PORTGIO_MASKA_CLEAR() bfin_read16(PORTGIO_MASKA_CLEAR)
+#define bfin_write_PORTGIO_MASKA_CLEAR(val) bfin_write16(PORTGIO_MASKA_CLEAR,val)
+#define bfin_read_PORTGIO_MASKA_SET() bfin_read16(PORTGIO_MASKA_SET)
+#define bfin_write_PORTGIO_MASKA_SET(val) bfin_write16(PORTGIO_MASKA_SET,val)
+#define bfin_read_PORTGIO_MASKA_TOGGLE() bfin_read16(PORTGIO_MASKA_TOGGLE)
+#define bfin_write_PORTGIO_MASKA_TOGGLE(val) bfin_write16(PORTGIO_MASKA_TOGGLE,val)
+#define bfin_read_PORTGIO_MASKB() bfin_read16(PORTGIO_MASKB)
+#define bfin_write_PORTGIO_MASKB(val) bfin_write16(PORTGIO_MASKB,val)
+#define bfin_read_PORTGIO_MASKB_CLEAR() bfin_read16(PORTGIO_MASKB_CLEAR)
+#define bfin_write_PORTGIO_MASKB_CLEAR(val) bfin_write16(PORTGIO_MASKB_CLEAR,val)
+#define bfin_read_PORTGIO_MASKB_SET() bfin_read16(PORTGIO_MASKB_SET)
+#define bfin_write_PORTGIO_MASKB_SET(val) bfin_write16(PORTGIO_MASKB_SET,val)
+#define bfin_read_PORTGIO_MASKB_TOGGLE() bfin_read16(PORTGIO_MASKB_TOGGLE)
+#define bfin_write_PORTGIO_MASKB_TOGGLE(val) bfin_write16(PORTGIO_MASKB_TOGGLE,val)
+#define bfin_read_PORTGIO_DIR() bfin_read16(PORTGIO_DIR)
+#define bfin_write_PORTGIO_DIR(val) bfin_write16(PORTGIO_DIR,val)
+#define bfin_read_PORTGIO_POLAR() bfin_read16(PORTGIO_POLAR)
+#define bfin_write_PORTGIO_POLAR(val) bfin_write16(PORTGIO_POLAR,val)
+#define bfin_read_PORTGIO_EDGE() bfin_read16(PORTGIO_EDGE)
+#define bfin_write_PORTGIO_EDGE(val) bfin_write16(PORTGIO_EDGE,val)
+#define bfin_read_PORTGIO_BOTH() bfin_read16(PORTGIO_BOTH)
+#define bfin_write_PORTGIO_BOTH(val) bfin_write16(PORTGIO_BOTH,val)
+#define bfin_read_PORTGIO_INEN() bfin_read16(PORTGIO_INEN)
+#define bfin_write_PORTGIO_INEN(val) bfin_write16(PORTGIO_INEN,val)
+
+/* General Purpose I/O Port H (0xFFC01700 - 0xFFC017FF) */
+#define bfin_read_PORTHIO() bfin_read16(PORTHIO)
+#define bfin_write_PORTHIO(val) bfin_write16(PORTHIO,val)
+#define bfin_read_PORTHIO_CLEAR() bfin_read16(PORTHIO_CLEAR)
+#define bfin_write_PORTHIO_CLEAR(val) bfin_write16(PORTHIO_CLEAR,val)
+#define bfin_read_PORTHIO_SET() bfin_read16(PORTHIO_SET)
+#define bfin_write_PORTHIO_SET(val) bfin_write16(PORTHIO_SET,val)
+#define bfin_read_PORTHIO_TOGGLE() bfin_read16(PORTHIO_TOGGLE)
+#define bfin_write_PORTHIO_TOGGLE(val) bfin_write16(PORTHIO_TOGGLE,val)
+#define bfin_read_PORTHIO_MASKA() bfin_read16(PORTHIO_MASKA)
+#define bfin_write_PORTHIO_MASKA(val) bfin_write16(PORTHIO_MASKA,val)
+#define bfin_read_PORTHIO_MASKA_CLEAR() bfin_read16(PORTHIO_MASKA_CLEAR)
+#define bfin_write_PORTHIO_MASKA_CLEAR(val) bfin_write16(PORTHIO_MASKA_CLEAR,val)
+#define bfin_read_PORTHIO_MASKA_SET() bfin_read16(PORTHIO_MASKA_SET)
+#define bfin_write_PORTHIO_MASKA_SET(val) bfin_write16(PORTHIO_MASKA_SET,val)
+#define bfin_read_PORTHIO_MASKA_TOGGLE() bfin_read16(PORTHIO_MASKA_TOGGLE)
+#define bfin_write_PORTHIO_MASKA_TOGGLE(val) bfin_write16(PORTHIO_MASKA_TOGGLE,val)
+#define bfin_read_PORTHIO_MASKB() bfin_read16(PORTHIO_MASKB)
+#define bfin_write_PORTHIO_MASKB(val) bfin_write16(PORTHIO_MASKB,val)
+#define bfin_read_PORTHIO_MASKB_CLEAR() bfin_read16(PORTHIO_MASKB_CLEAR)
+#define bfin_write_PORTHIO_MASKB_CLEAR(val) bfin_write16(PORTHIO_MASKB_CLEAR,val)
+#define bfin_read_PORTHIO_MASKB_SET() bfin_read16(PORTHIO_MASKB_SET)
+#define bfin_write_PORTHIO_MASKB_SET(val) bfin_write16(PORTHIO_MASKB_SET,val)
+#define bfin_read_PORTHIO_MASKB_TOGGLE() bfin_read16(PORTHIO_MASKB_TOGGLE)
+#define bfin_write_PORTHIO_MASKB_TOGGLE(val) bfin_write16(PORTHIO_MASKB_TOGGLE,val)
+#define bfin_read_PORTHIO_DIR() bfin_read16(PORTHIO_DIR)
+#define bfin_write_PORTHIO_DIR(val) bfin_write16(PORTHIO_DIR,val)
+#define bfin_read_PORTHIO_POLAR() bfin_read16(PORTHIO_POLAR)
+#define bfin_write_PORTHIO_POLAR(val) bfin_write16(PORTHIO_POLAR,val)
+#define bfin_read_PORTHIO_EDGE() bfin_read16(PORTHIO_EDGE)
+#define bfin_write_PORTHIO_EDGE(val) bfin_write16(PORTHIO_EDGE,val)
+#define bfin_read_PORTHIO_BOTH() bfin_read16(PORTHIO_BOTH)
+#define bfin_write_PORTHIO_BOTH(val) bfin_write16(PORTHIO_BOTH,val)
+#define bfin_read_PORTHIO_INEN() bfin_read16(PORTHIO_INEN)
+#define bfin_write_PORTHIO_INEN(val) bfin_write16(PORTHIO_INEN,val)
+
+/* UART1 Controller (0xFFC02000 - 0xFFC020FF) */
+#define bfin_read_UART1_THR() bfin_read16(UART1_THR)
+#define bfin_write_UART1_THR(val) bfin_write16(UART1_THR,val)
+#define bfin_read_UART1_RBR() bfin_read16(UART1_RBR)
+#define bfin_write_UART1_RBR(val) bfin_write16(UART1_RBR,val)
+#define bfin_read_UART1_DLL() bfin_read16(UART1_DLL)
+#define bfin_write_UART1_DLL(val) bfin_write16(UART1_DLL,val)
+#define bfin_read_UART1_IER() bfin_read16(UART1_IER)
+#define bfin_write_UART1_IER(val) bfin_write16(UART1_IER,val)
+#define bfin_read_UART1_DLH() bfin_read16(UART1_DLH)
+#define bfin_write_UART1_DLH(val) bfin_write16(UART1_DLH,val)
+#define bfin_read_UART1_IIR() bfin_read16(UART1_IIR)
+#define bfin_write_UART1_IIR(val) bfin_write16(UART1_IIR,val)
+#define bfin_read_UART1_LCR() bfin_read16(UART1_LCR)
+#define bfin_write_UART1_LCR(val) bfin_write16(UART1_LCR,val)
+#define bfin_read_UART1_MCR() bfin_read16(UART1_MCR)
+#define bfin_write_UART1_MCR(val) bfin_write16(UART1_MCR,val)
+#define bfin_read_UART1_LSR() bfin_read16(UART1_LSR)
+#define bfin_write_UART1_LSR(val) bfin_write16(UART1_LSR,val)
+#define bfin_read_UART1_MSR() bfin_read16(UART1_MSR)
+#define bfin_write_UART1_MSR(val) bfin_write16(UART1_MSR,val)
+#define bfin_read_UART1_SCR() bfin_read16(UART1_SCR)
+#define bfin_write_UART1_SCR(val) bfin_write16(UART1_SCR,val)
+#define bfin_read_UART1_GCTL() bfin_read16(UART1_GCTL)
+#define bfin_write_UART1_GCTL(val) bfin_write16(UART1_GCTL,val)
+
+/* CAN Controller (0xFFC02A00 - 0xFFC02FFF) */
+/* For Mailboxes 0-15 */
+#define bfin_read_CAN_MC1() bfin_read16(CAN_MC1)
+#define bfin_write_CAN_MC1(val) bfin_write16(CAN_MC1,val)
+#define bfin_read_CAN_MD1() bfin_read16(CAN_MD1)
+#define bfin_write_CAN_MD1(val) bfin_write16(CAN_MD1,val)
+#define bfin_read_CAN_TRS1() bfin_read16(CAN_TRS1)
+#define bfin_write_CAN_TRS1(val) bfin_write16(CAN_TRS1,val)
+#define bfin_read_CAN_TRR1() bfin_read16(CAN_TRR1)
+#define bfin_write_CAN_TRR1(val) bfin_write16(CAN_TRR1,val)
+#define bfin_read_CAN_TA1() bfin_read16(CAN_TA1)
+#define bfin_write_CAN_TA1(val) bfin_write16(CAN_TA1,val)
+#define bfin_read_CAN_AA1() bfin_read16(CAN_AA1)
+#define bfin_write_CAN_AA1(val) bfin_write16(CAN_AA1,val)
+#define bfin_read_CAN_RMP1() bfin_read16(CAN_RMP1)
+#define bfin_write_CAN_RMP1(val) bfin_write16(CAN_RMP1,val)
+#define bfin_read_CAN_RML1() bfin_read16(CAN_RML1)
+#define bfin_write_CAN_RML1(val) bfin_write16(CAN_RML1,val)
+#define bfin_read_CAN_MBTIF1() bfin_read16(CAN_MBTIF1)
+#define bfin_write_CAN_MBTIF1(val) bfin_write16(CAN_MBTIF1,val)
+#define bfin_read_CAN_MBRIF1() bfin_read16(CAN_MBRIF1)
+#define bfin_write_CAN_MBRIF1(val) bfin_write16(CAN_MBRIF1,val)
+#define bfin_read_CAN_MBIM1() bfin_read16(CAN_MBIM1)
+#define bfin_write_CAN_MBIM1(val) bfin_write16(CAN_MBIM1,val)
+#define bfin_read_CAN_RFH1() bfin_read16(CAN_RFH1)
+#define bfin_write_CAN_RFH1(val) bfin_write16(CAN_RFH1,val)
+#define bfin_read_CAN_OPSS1() bfin_read16(CAN_OPSS1)
+#define bfin_write_CAN_OPSS1(val) bfin_write16(CAN_OPSS1,val)
+
+/* For Mailboxes 16-31 */
+#define bfin_read_CAN_MC2() bfin_read16(CAN_MC2)
+#define bfin_write_CAN_MC2(val) bfin_write16(CAN_MC2,val)
+#define bfin_read_CAN_MD2() bfin_read16(CAN_MD2)
+#define bfin_write_CAN_MD2(val) bfin_write16(CAN_MD2,val)
+#define bfin_read_CAN_TRS2() bfin_read16(CAN_TRS2)
+#define bfin_write_CAN_TRS2(val) bfin_write16(CAN_TRS2,val)
+#define bfin_read_CAN_TRR2() bfin_read16(CAN_TRR2)
+#define bfin_write_CAN_TRR2(val) bfin_write16(CAN_TRR2,val)
+#define bfin_read_CAN_TA2() bfin_read16(CAN_TA2)
+#define bfin_write_CAN_TA2(val) bfin_write16(CAN_TA2,val)
+#define bfin_read_CAN_AA2() bfin_read16(CAN_AA2)
+#define bfin_write_CAN_AA2(val) bfin_write16(CAN_AA2,val)
+#define bfin_read_CAN_RMP2() bfin_read16(CAN_RMP2)
+#define bfin_write_CAN_RMP2(val) bfin_write16(CAN_RMP2,val)
+#define bfin_read_CAN_RML2() bfin_read16(CAN_RML2)
+#define bfin_write_CAN_RML2(val) bfin_write16(CAN_RML2,val)
+#define bfin_read_CAN_MBTIF2() bfin_read16(CAN_MBTIF2)
+#define bfin_write_CAN_MBTIF2(val) bfin_write16(CAN_MBTIF2,val)
+#define bfin_read_CAN_MBRIF2() bfin_read16(CAN_MBRIF2)
+#define bfin_write_CAN_MBRIF2(val) bfin_write16(CAN_MBRIF2,val)
+#define bfin_read_CAN_MBIM2() bfin_read16(CAN_MBIM2)
+#define bfin_write_CAN_MBIM2(val) bfin_write16(CAN_MBIM2,val)
+#define bfin_read_CAN_RFH2() bfin_read16(CAN_RFH2)
+#define bfin_write_CAN_RFH2(val) bfin_write16(CAN_RFH2,val)
+#define bfin_read_CAN_OPSS2() bfin_read16(CAN_OPSS2)
+#define bfin_write_CAN_OPSS2(val) bfin_write16(CAN_OPSS2,val)
+
+#define bfin_read_CAN_CLOCK() bfin_read16(CAN_CLOCK)
+#define bfin_write_CAN_CLOCK(val) bfin_write16(CAN_CLOCK,val)
+#define bfin_read_CAN_TIMING() bfin_read16(CAN_TIMING)
+#define bfin_write_CAN_TIMING(val) bfin_write16(CAN_TIMING,val)
+#define bfin_read_CAN_DEBUG() bfin_read16(CAN_DEBUG)
+#define bfin_write_CAN_DEBUG(val) bfin_write16(CAN_DEBUG,val)
+#define bfin_read_CAN_STATUS() bfin_read16(CAN_STATUS)
+#define bfin_write_CAN_STATUS(val) bfin_write16(CAN_STATUS,val)
+#define bfin_read_CAN_CEC() bfin_read16(CAN_CEC)
+#define bfin_write_CAN_CEC(val) bfin_write16(CAN_CEC,val)
+#define bfin_read_CAN_GIS() bfin_read16(CAN_GIS)
+#define bfin_write_CAN_GIS(val) bfin_write16(CAN_GIS,val)
+#define bfin_read_CAN_GIM() bfin_read16(CAN_GIM)
+#define bfin_write_CAN_GIM(val) bfin_write16(CAN_GIM,val)
+#define bfin_read_CAN_GIF() bfin_read16(CAN_GIF)
+#define bfin_write_CAN_GIF(val) bfin_write16(CAN_GIF,val)
+#define bfin_read_CAN_CONTROL() bfin_read16(CAN_CONTROL)
+#define bfin_write_CAN_CONTROL(val) bfin_write16(CAN_CONTROL,val)
+#define bfin_read_CAN_INTR() bfin_read16(CAN_INTR)
+#define bfin_write_CAN_INTR(val) bfin_write16(CAN_INTR,val)
+#define bfin_read_CAN_SFCMVER() bfin_read16(CAN_SFCMVER)
+#define bfin_write_CAN_SFCMVER(val) bfin_write16(CAN_SFCMVER,val)
+#define bfin_read_CAN_MBTD() bfin_read16(CAN_MBTD)
+#define bfin_write_CAN_MBTD(val) bfin_write16(CAN_MBTD,val)
+#define bfin_read_CAN_EWR() bfin_read16(CAN_EWR)
+#define bfin_write_CAN_EWR(val) bfin_write16(CAN_EWR,val)
+#define bfin_read_CAN_ESR() bfin_read16(CAN_ESR)
+#define bfin_write_CAN_ESR(val) bfin_write16(CAN_ESR,val)
+#define bfin_read_CAN_UCREG() bfin_read16(CAN_UCREG)
+#define bfin_write_CAN_UCREG(val) bfin_write16(CAN_UCREG,val)
+#define bfin_read_CAN_UCCNT() bfin_read16(CAN_UCCNT)
+#define bfin_write_CAN_UCCNT(val) bfin_write16(CAN_UCCNT,val)
+#define bfin_read_CAN_UCRC() bfin_read16(CAN_UCRC)
+#define bfin_write_CAN_UCRC(val) bfin_write16(CAN_UCRC,val)
+#define bfin_read_CAN_UCCNF() bfin_read16(CAN_UCCNF)
+#define bfin_write_CAN_UCCNF(val) bfin_write16(CAN_UCCNF,val)
+#define bfin_read_CAN_SFCMVER2() bfin_read16(CAN_SFCMVER2)
+#define bfin_write_CAN_SFCMVER2(val) bfin_write16(CAN_SFCMVER2,val)
+
+/* Mailbox Acceptance Masks */
+#define bfin_read_CAN_AM00L() bfin_read16(CAN_AM00L)
+#define bfin_write_CAN_AM00L(val) bfin_write16(CAN_AM00L,val)
+#define bfin_read_CAN_AM00H() bfin_read16(CAN_AM00H)
+#define bfin_write_CAN_AM00H(val) bfin_write16(CAN_AM00H,val)
+#define bfin_read_CAN_AM01L() bfin_read16(CAN_AM01L)
+#define bfin_write_CAN_AM01L(val) bfin_write16(CAN_AM01L,val)
+#define bfin_read_CAN_AM01H() bfin_read16(CAN_AM01H)
+#define bfin_write_CAN_AM01H(val) bfin_write16(CAN_AM01H,val)
+#define bfin_read_CAN_AM02L() bfin_read16(CAN_AM02L)
+#define bfin_write_CAN_AM02L(val) bfin_write16(CAN_AM02L,val)
+#define bfin_read_CAN_AM02H() bfin_read16(CAN_AM02H)
+#define bfin_write_CAN_AM02H(val) bfin_write16(CAN_AM02H,val)
+#define bfin_read_CAN_AM03L() bfin_read16(CAN_AM03L)
+#define bfin_write_CAN_AM03L(val) bfin_write16(CAN_AM03L,val)
+#define bfin_read_CAN_AM03H() bfin_read16(CAN_AM03H)
+#define bfin_write_CAN_AM03H(val) bfin_write16(CAN_AM03H,val)
+#define bfin_read_CAN_AM04L() bfin_read16(CAN_AM04L)
+#define bfin_write_CAN_AM04L(val) bfin_write16(CAN_AM04L,val)
+#define bfin_read_CAN_AM04H() bfin_read16(CAN_AM04H)
+#define bfin_write_CAN_AM04H(val) bfin_write16(CAN_AM04H,val)
+#define bfin_read_CAN_AM05L() bfin_read16(CAN_AM05L)
+#define bfin_write_CAN_AM05L(val) bfin_write16(CAN_AM05L,val)
+#define bfin_read_CAN_AM05H() bfin_read16(CAN_AM05H)
+#define bfin_write_CAN_AM05H(val) bfin_write16(CAN_AM05H,val)
+#define bfin_read_CAN_AM06L() bfin_read16(CAN_AM06L)
+#define bfin_write_CAN_AM06L(val) bfin_write16(CAN_AM06L,val)
+#define bfin_read_CAN_AM06H() bfin_read16(CAN_AM06H)
+#define bfin_write_CAN_AM06H(val) bfin_write16(CAN_AM06H,val)
+#define bfin_read_CAN_AM07L() bfin_read16(CAN_AM07L)
+#define bfin_write_CAN_AM07L(val) bfin_write16(CAN_AM07L,val)
+#define bfin_read_CAN_AM07H() bfin_read16(CAN_AM07H)
+#define bfin_write_CAN_AM07H(val) bfin_write16(CAN_AM07H,val)
+#define bfin_read_CAN_AM08L() bfin_read16(CAN_AM08L)
+#define bfin_write_CAN_AM08L(val) bfin_write16(CAN_AM08L,val)
+#define bfin_read_CAN_AM08H() bfin_read16(CAN_AM08H)
+#define bfin_write_CAN_AM08H(val) bfin_write16(CAN_AM08H,val)
+#define bfin_read_CAN_AM09L() bfin_read16(CAN_AM09L)
+#define bfin_write_CAN_AM09L(val) bfin_write16(CAN_AM09L,val)
+#define bfin_read_CAN_AM09H() bfin_read16(CAN_AM09H)
+#define bfin_write_CAN_AM09H(val) bfin_write16(CAN_AM09H,val)
+#define bfin_read_CAN_AM10L() bfin_read16(CAN_AM10L)
+#define bfin_write_CAN_AM10L(val) bfin_write16(CAN_AM10L,val)
+#define bfin_read_CAN_AM10H() bfin_read16(CAN_AM10H)
+#define bfin_write_CAN_AM10H(val) bfin_write16(CAN_AM10H,val)
+#define bfin_read_CAN_AM11L() bfin_read16(CAN_AM11L)
+#define bfin_write_CAN_AM11L(val) bfin_write16(CAN_AM11L,val)
+#define bfin_read_CAN_AM11H() bfin_read16(CAN_AM11H)
+#define bfin_write_CAN_AM11H(val) bfin_write16(CAN_AM11H,val)
+#define bfin_read_CAN_AM12L() bfin_read16(CAN_AM12L)
+#define bfin_write_CAN_AM12L(val) bfin_write16(CAN_AM12L,val)
+#define bfin_read_CAN_AM12H() bfin_read16(CAN_AM12H)
+#define bfin_write_CAN_AM12H(val) bfin_write16(CAN_AM12H,val)
+#define bfin_read_CAN_AM13L() bfin_read16(CAN_AM13L)
+#define bfin_write_CAN_AM13L(val) bfin_write16(CAN_AM13L,val)
+#define bfin_read_CAN_AM13H() bfin_read16(CAN_AM13H)
+#define bfin_write_CAN_AM13H(val) bfin_write16(CAN_AM13H,val)
+#define bfin_read_CAN_AM14L() bfin_read16(CAN_AM14L)
+#define bfin_write_CAN_AM14L(val) bfin_write16(CAN_AM14L,val)
+#define bfin_read_CAN_AM14H() bfin_read16(CAN_AM14H)
+#define bfin_write_CAN_AM14H(val) bfin_write16(CAN_AM14H,val)
+#define bfin_read_CAN_AM15L() bfin_read16(CAN_AM15L)
+#define bfin_write_CAN_AM15L(val) bfin_write16(CAN_AM15L,val)
+#define bfin_read_CAN_AM15H() bfin_read16(CAN_AM15H)
+#define bfin_write_CAN_AM15H(val) bfin_write16(CAN_AM15H,val)
+
+#define bfin_read_CAN_AM16L() bfin_read16(CAN_AM16L)
+#define bfin_write_CAN_AM16L(val) bfin_write16(CAN_AM16L,val)
+#define bfin_read_CAN_AM16H() bfin_read16(CAN_AM16H)
+#define bfin_write_CAN_AM16H(val) bfin_write16(CAN_AM16H,val)
+#define bfin_read_CAN_AM17L() bfin_read16(CAN_AM17L)
+#define bfin_write_CAN_AM17L(val) bfin_write16(CAN_AM17L,val)
+#define bfin_read_CAN_AM17H() bfin_read16(CAN_AM17H)
+#define bfin_write_CAN_AM17H(val) bfin_write16(CAN_AM17H,val)
+#define bfin_read_CAN_AM18L() bfin_read16(CAN_AM18L)
+#define bfin_write_CAN_AM18L(val) bfin_write16(CAN_AM18L,val)
+#define bfin_read_CAN_AM18H() bfin_read16(CAN_AM18H)
+#define bfin_write_CAN_AM18H(val) bfin_write16(CAN_AM18H,val)
+#define bfin_read_CAN_AM19L() bfin_read16(CAN_AM19L)
+#define bfin_write_CAN_AM19L(val) bfin_write16(CAN_AM19L,val)
+#define bfin_read_CAN_AM19H() bfin_read16(CAN_AM19H)
+#define bfin_write_CAN_AM19H(val) bfin_write16(CAN_AM19H,val)
+#define bfin_read_CAN_AM20L() bfin_read16(CAN_AM20L)
+#define bfin_write_CAN_AM20L(val) bfin_write16(CAN_AM20L,val)
+#define bfin_read_CAN_AM20H() bfin_read16(CAN_AM20H)
+#define bfin_write_CAN_AM20H(val) bfin_write16(CAN_AM20H,val)
+#define bfin_read_CAN_AM21L() bfin_read16(CAN_AM21L)
+#define bfin_write_CAN_AM21L(val) bfin_write16(CAN_AM21L,val)
+#define bfin_read_CAN_AM21H() bfin_read16(CAN_AM21H)
+#define bfin_write_CAN_AM21H(val) bfin_write16(CAN_AM21H,val)
+#define bfin_read_CAN_AM22L() bfin_read16(CAN_AM22L)
+#define bfin_write_CAN_AM22L(val) bfin_write16(CAN_AM22L,val)
+#define bfin_read_CAN_AM22H() bfin_read16(CAN_AM22H)
+#define bfin_write_CAN_AM22H(val) bfin_write16(CAN_AM22H,val)
+#define bfin_read_CAN_AM23L() bfin_read16(CAN_AM23L)
+#define bfin_write_CAN_AM23L(val) bfin_write16(CAN_AM23L,val)
+#define bfin_read_CAN_AM23H() bfin_read16(CAN_AM23H)
+#define bfin_write_CAN_AM23H(val) bfin_write16(CAN_AM23H,val)
+#define bfin_read_CAN_AM24L() bfin_read16(CAN_AM24L)
+#define bfin_write_CAN_AM24L(val) bfin_write16(CAN_AM24L,val)
+#define bfin_read_CAN_AM24H() bfin_read16(CAN_AM24H)
+#define bfin_write_CAN_AM24H(val) bfin_write16(CAN_AM24H,val)
+#define bfin_read_CAN_AM25L() bfin_read16(CAN_AM25L)
+#define bfin_write_CAN_AM25L(val) bfin_write16(CAN_AM25L,val)
+#define bfin_read_CAN_AM25H() bfin_read16(CAN_AM25H)
+#define bfin_write_CAN_AM25H(val) bfin_write16(CAN_AM25H,val)
+#define bfin_read_CAN_AM26L() bfin_read16(CAN_AM26L)
+#define bfin_write_CAN_AM26L(val) bfin_write16(CAN_AM26L,val)
+#define bfin_read_CAN_AM26H() bfin_read16(CAN_AM26H)
+#define bfin_write_CAN_AM26H(val) bfin_write16(CAN_AM26H,val)
+#define bfin_read_CAN_AM27L() bfin_read16(CAN_AM27L)
+#define bfin_write_CAN_AM27L(val) bfin_write16(CAN_AM27L,val)
+#define bfin_read_CAN_AM27H() bfin_read16(CAN_AM27H)
+#define bfin_write_CAN_AM27H(val) bfin_write16(CAN_AM27H,val)
+#define bfin_read_CAN_AM28L() bfin_read16(CAN_AM28L)
+#define bfin_write_CAN_AM28L(val) bfin_write16(CAN_AM28L,val)
+#define bfin_read_CAN_AM28H() bfin_read16(CAN_AM28H)
+#define bfin_write_CAN_AM28H(val) bfin_write16(CAN_AM28H,val)
+#define bfin_read_CAN_AM29L() bfin_read16(CAN_AM29L)
+#define bfin_write_CAN_AM29L(val) bfin_write16(CAN_AM29L,val)
+#define bfin_read_CAN_AM29H() bfin_read16(CAN_AM29H)
+#define bfin_write_CAN_AM29H(val) bfin_write16(CAN_AM29H,val)
+#define bfin_read_CAN_AM30L() bfin_read16(CAN_AM30L)
+#define bfin_write_CAN_AM30L(val) bfin_write16(CAN_AM30L,val)
+#define bfin_read_CAN_AM30H() bfin_read16(CAN_AM30H)
+#define bfin_write_CAN_AM30H(val) bfin_write16(CAN_AM30H,val)
+#define bfin_read_CAN_AM31L() bfin_read16(CAN_AM31L)
+#define bfin_write_CAN_AM31L(val) bfin_write16(CAN_AM31L,val)
+#define bfin_read_CAN_AM31H() bfin_read16(CAN_AM31H)
+#define bfin_write_CAN_AM31H(val) bfin_write16(CAN_AM31H,val)
+
+/* CAN Acceptance Mask Area Macros */
+#define bfin_read_CAN_AM_L(x)() bfin_read16(CAN_AM_L(x))
+#define bfin_write_CAN_AM_L(x)(val) bfin_write16(CAN_AM_L(x),val)
+#define bfin_read_CAN_AM_H(x)() bfin_read16(CAN_AM_H(x))
+#define bfin_write_CAN_AM_H(x)(val) bfin_write16(CAN_AM_H(x),val)
+
+/* Mailbox Registers */
+#define bfin_read_CAN_MB00_ID1() bfin_read16(CAN_MB00_ID1)
+#define bfin_write_CAN_MB00_ID1(val) bfin_write16(CAN_MB00_ID1,val)
+#define bfin_read_CAN_MB00_ID0() bfin_read16(CAN_MB00_ID0)
+#define bfin_write_CAN_MB00_ID0(val) bfin_write16(CAN_MB00_ID0,val)
+#define bfin_read_CAN_MB00_TIMESTAMP() bfin_read16(CAN_MB00_TIMESTAMP)
+#define bfin_write_CAN_MB00_TIMESTAMP(val) bfin_write16(CAN_MB00_TIMESTAMP,val)
+#define bfin_read_CAN_MB00_LENGTH() bfin_read16(CAN_MB00_LENGTH)
+#define bfin_write_CAN_MB00_LENGTH(val) bfin_write16(CAN_MB00_LENGTH,val)
+#define bfin_read_CAN_MB00_DATA3() bfin_read16(CAN_MB00_DATA3)
+#define bfin_write_CAN_MB00_DATA3(val) bfin_write16(CAN_MB00_DATA3,val)
+#define bfin_read_CAN_MB00_DATA2() bfin_read16(CAN_MB00_DATA2)
+#define bfin_write_CAN_MB00_DATA2(val) bfin_write16(CAN_MB00_DATA2,val)
+#define bfin_read_CAN_MB00_DATA1() bfin_read16(CAN_MB00_DATA1)
+#define bfin_write_CAN_MB00_DATA1(val) bfin_write16(CAN_MB00_DATA1,val)
+#define bfin_read_CAN_MB00_DATA0() bfin_read16(CAN_MB00_DATA0)
+#define bfin_write_CAN_MB00_DATA0(val) bfin_write16(CAN_MB00_DATA0,val)
+
+#define bfin_read_CAN_MB01_ID1() bfin_read16(CAN_MB01_ID1)
+#define bfin_write_CAN_MB01_ID1(val) bfin_write16(CAN_MB01_ID1,val)
+#define bfin_read_CAN_MB01_ID0() bfin_read16(CAN_MB01_ID0)
+#define bfin_write_CAN_MB01_ID0(val) bfin_write16(CAN_MB01_ID0,val)
+#define bfin_read_CAN_MB01_TIMESTAMP() bfin_read16(CAN_MB01_TIMESTAMP)
+#define bfin_write_CAN_MB01_TIMESTAMP(val) bfin_write16(CAN_MB01_TIMESTAMP,val)
+#define bfin_read_CAN_MB01_LENGTH() bfin_read16(CAN_MB01_LENGTH)
+#define bfin_write_CAN_MB01_LENGTH(val) bfin_write16(CAN_MB01_LENGTH,val)
+#define bfin_read_CAN_MB01_DATA3() bfin_read16(CAN_MB01_DATA3)
+#define bfin_write_CAN_MB01_DATA3(val) bfin_write16(CAN_MB01_DATA3,val)
+#define bfin_read_CAN_MB01_DATA2() bfin_read16(CAN_MB01_DATA2)
+#define bfin_write_CAN_MB01_DATA2(val) bfin_write16(CAN_MB01_DATA2,val)
+#define bfin_read_CAN_MB01_DATA1() bfin_read16(CAN_MB01_DATA1)
+#define bfin_write_CAN_MB01_DATA1(val) bfin_write16(CAN_MB01_DATA1,val)
+#define bfin_read_CAN_MB01_DATA0() bfin_read16(CAN_MB01_DATA0)
+#define bfin_write_CAN_MB01_DATA0(val) bfin_write16(CAN_MB01_DATA0,val)
+
+#define bfin_read_CAN_MB02_ID1() bfin_read16(CAN_MB02_ID1)
+#define bfin_write_CAN_MB02_ID1(val) bfin_write16(CAN_MB02_ID1,val)
+#define bfin_read_CAN_MB02_ID0() bfin_read16(CAN_MB02_ID0)
+#define bfin_write_CAN_MB02_ID0(val) bfin_write16(CAN_MB02_ID0,val)
+#define bfin_read_CAN_MB02_TIMESTAMP() bfin_read16(CAN_MB02_TIMESTAMP)
+#define bfin_write_CAN_MB02_TIMESTAMP(val) bfin_write16(CAN_MB02_TIMESTAMP,val)
+#define bfin_read_CAN_MB02_LENGTH() bfin_read16(CAN_MB02_LENGTH)
+#define bfin_write_CAN_MB02_LENGTH(val) bfin_write16(CAN_MB02_LENGTH,val)
+#define bfin_read_CAN_MB02_DATA3() bfin_read16(CAN_MB02_DATA3)
+#define bfin_write_CAN_MB02_DATA3(val) bfin_write16(CAN_MB02_DATA3,val)
+#define bfin_read_CAN_MB02_DATA2() bfin_read16(CAN_MB02_DATA2)
+#define bfin_write_CAN_MB02_DATA2(val) bfin_write16(CAN_MB02_DATA2,val)
+#define bfin_read_CAN_MB02_DATA1() bfin_read16(CAN_MB02_DATA1)
+#define bfin_write_CAN_MB02_DATA1(val) bfin_write16(CAN_MB02_DATA1,val)
+#define bfin_read_CAN_MB02_DATA0() bfin_read16(CAN_MB02_DATA0)
+#define bfin_write_CAN_MB02_DATA0(val) bfin_write16(CAN_MB02_DATA0,val)
+
+#define bfin_read_CAN_MB03_ID1() bfin_read16(CAN_MB03_ID1)
+#define bfin_write_CAN_MB03_ID1(val) bfin_write16(CAN_MB03_ID1,val)
+#define bfin_read_CAN_MB03_ID0() bfin_read16(CAN_MB03_ID0)
+#define bfin_write_CAN_MB03_ID0(val) bfin_write16(CAN_MB03_ID0,val)
+#define bfin_read_CAN_MB03_TIMESTAMP() bfin_read16(CAN_MB03_TIMESTAMP)
+#define bfin_write_CAN_MB03_TIMESTAMP(val) bfin_write16(CAN_MB03_TIMESTAMP,val)
+#define bfin_read_CAN_MB03_LENGTH() bfin_read16(CAN_MB03_LENGTH)
+#define bfin_write_CAN_MB03_LENGTH(val) bfin_write16(CAN_MB03_LENGTH,val)
+#define bfin_read_CAN_MB03_DATA3() bfin_read16(CAN_MB03_DATA3)
+#define bfin_write_CAN_MB03_DATA3(val) bfin_write16(CAN_MB03_DATA3,val)
+#define bfin_read_CAN_MB03_DATA2() bfin_read16(CAN_MB03_DATA2)
+#define bfin_write_CAN_MB03_DATA2(val) bfin_write16(CAN_MB03_DATA2,val)
+#define bfin_read_CAN_MB03_DATA1() bfin_read16(CAN_MB03_DATA1)
+#define bfin_write_CAN_MB03_DATA1(val) bfin_write16(CAN_MB03_DATA1,val)
+#define bfin_read_CAN_MB03_DATA0() bfin_read16(CAN_MB03_DATA0)
+#define bfin_write_CAN_MB03_DATA0(val) bfin_write16(CAN_MB03_DATA0,val)
+
+#define bfin_read_CAN_MB04_ID1() bfin_read16(CAN_MB04_ID1)
+#define bfin_write_CAN_MB04_ID1(val) bfin_write16(CAN_MB04_ID1,val)
+#define bfin_read_CAN_MB04_ID0() bfin_read16(CAN_MB04_ID0)
+#define bfin_write_CAN_MB04_ID0(val) bfin_write16(CAN_MB04_ID0,val)
+#define bfin_read_CAN_MB04_TIMESTAMP() bfin_read16(CAN_MB04_TIMESTAMP)
+#define bfin_write_CAN_MB04_TIMESTAMP(val) bfin_write16(CAN_MB04_TIMESTAMP,val)
+#define bfin_read_CAN_MB04_LENGTH() bfin_read16(CAN_MB04_LENGTH)
+#define bfin_write_CAN_MB04_LENGTH(val) bfin_write16(CAN_MB04_LENGTH,val)
+#define bfin_read_CAN_MB04_DATA3() bfin_read16(CAN_MB04_DATA3)
+#define bfin_write_CAN_MB04_DATA3(val) bfin_write16(CAN_MB04_DATA3,val)
+#define bfin_read_CAN_MB04_DATA2() bfin_read16(CAN_MB04_DATA2)
+#define bfin_write_CAN_MB04_DATA2(val) bfin_write16(CAN_MB04_DATA2,val)
+#define bfin_read_CAN_MB04_DATA1() bfin_read16(CAN_MB04_DATA1)
+#define bfin_write_CAN_MB04_DATA1(val) bfin_write16(CAN_MB04_DATA1,val)
+#define bfin_read_CAN_MB04_DATA0() bfin_read16(CAN_MB04_DATA0)
+#define bfin_write_CAN_MB04_DATA0(val) bfin_write16(CAN_MB04_DATA0,val)
+
+#define bfin_read_CAN_MB05_ID1() bfin_read16(CAN_MB05_ID1)
+#define bfin_write_CAN_MB05_ID1(val) bfin_write16(CAN_MB05_ID1,val)
+#define bfin_read_CAN_MB05_ID0() bfin_read16(CAN_MB05_ID0)
+#define bfin_write_CAN_MB05_ID0(val) bfin_write16(CAN_MB05_ID0,val)
+#define bfin_read_CAN_MB05_TIMESTAMP() bfin_read16(CAN_MB05_TIMESTAMP)
+#define bfin_write_CAN_MB05_TIMESTAMP(val) bfin_write16(CAN_MB05_TIMESTAMP,val)
+#define bfin_read_CAN_MB05_LENGTH() bfin_read16(CAN_MB05_LENGTH)
+#define bfin_write_CAN_MB05_LENGTH(val) bfin_write16(CAN_MB05_LENGTH,val)
+#define bfin_read_CAN_MB05_DATA3() bfin_read16(CAN_MB05_DATA3)
+#define bfin_write_CAN_MB05_DATA3(val) bfin_write16(CAN_MB05_DATA3,val)
+#define bfin_read_CAN_MB05_DATA2() bfin_read16(CAN_MB05_DATA2)
+#define bfin_write_CAN_MB05_DATA2(val) bfin_write16(CAN_MB05_DATA2,val)
+#define bfin_read_CAN_MB05_DATA1() bfin_read16(CAN_MB05_DATA1)
+#define bfin_write_CAN_MB05_DATA1(val) bfin_write16(CAN_MB05_DATA1,val)
+#define bfin_read_CAN_MB05_DATA0() bfin_read16(CAN_MB05_DATA0)
+#define bfin_write_CAN_MB05_DATA0(val) bfin_write16(CAN_MB05_DATA0,val)
+
+#define bfin_read_CAN_MB06_ID1() bfin_read16(CAN_MB06_ID1)
+#define bfin_write_CAN_MB06_ID1(val) bfin_write16(CAN_MB06_ID1,val)
+#define bfin_read_CAN_MB06_ID0() bfin_read16(CAN_MB06_ID0)
+#define bfin_write_CAN_MB06_ID0(val) bfin_write16(CAN_MB06_ID0,val)
+#define bfin_read_CAN_MB06_TIMESTAMP() bfin_read16(CAN_MB06_TIMESTAMP)
+#define bfin_write_CAN_MB06_TIMESTAMP(val) bfin_write16(CAN_MB06_TIMESTAMP,val)
+#define bfin_read_CAN_MB06_LENGTH() bfin_read16(CAN_MB06_LENGTH)
+#define bfin_write_CAN_MB06_LENGTH(val) bfin_write16(CAN_MB06_LENGTH,val)
+#define bfin_read_CAN_MB06_DATA3() bfin_read16(CAN_MB06_DATA3)
+#define bfin_write_CAN_MB06_DATA3(val) bfin_write16(CAN_MB06_DATA3,val)
+#define bfin_read_CAN_MB06_DATA2() bfin_read16(CAN_MB06_DATA2)
+#define bfin_write_CAN_MB06_DATA2(val) bfin_write16(CAN_MB06_DATA2,val)
+#define bfin_read_CAN_MB06_DATA1() bfin_read16(CAN_MB06_DATA1)
+#define bfin_write_CAN_MB06_DATA1(val) bfin_write16(CAN_MB06_DATA1,val)
+#define bfin_read_CAN_MB06_DATA0() bfin_read16(CAN_MB06_DATA0)
+#define bfin_write_CAN_MB06_DATA0(val) bfin_write16(CAN_MB06_DATA0,val)
+
+#define bfin_read_CAN_MB07_ID1() bfin_read16(CAN_MB07_ID1)
+#define bfin_write_CAN_MB07_ID1(val) bfin_write16(CAN_MB07_ID1,val)
+#define bfin_read_CAN_MB07_ID0() bfin_read16(CAN_MB07_ID0)
+#define bfin_write_CAN_MB07_ID0(val) bfin_write16(CAN_MB07_ID0,val)
+#define bfin_read_CAN_MB07_TIMESTAMP() bfin_read16(CAN_MB07_TIMESTAMP)
+#define bfin_write_CAN_MB07_TIMESTAMP(val) bfin_write16(CAN_MB07_TIMESTAMP,val)
+#define bfin_read_CAN_MB07_LENGTH() bfin_read16(CAN_MB07_LENGTH)
+#define bfin_write_CAN_MB07_LENGTH(val) bfin_write16(CAN_MB07_LENGTH,val)
+#define bfin_read_CAN_MB07_DATA3() bfin_read16(CAN_MB07_DATA3)
+#define bfin_write_CAN_MB07_DATA3(val) bfin_write16(CAN_MB07_DATA3,val)
+#define bfin_read_CAN_MB07_DATA2() bfin_read16(CAN_MB07_DATA2)
+#define bfin_write_CAN_MB07_DATA2(val) bfin_write16(CAN_MB07_DATA2,val)
+#define bfin_read_CAN_MB07_DATA1() bfin_read16(CAN_MB07_DATA1)
+#define bfin_write_CAN_MB07_DATA1(val) bfin_write16(CAN_MB07_DATA1,val)
+#define bfin_read_CAN_MB07_DATA0() bfin_read16(CAN_MB07_DATA0)
+#define bfin_write_CAN_MB07_DATA0(val) bfin_write16(CAN_MB07_DATA0,val)
+
+#define bfin_read_CAN_MB08_ID1() bfin_read16(CAN_MB08_ID1)
+#define bfin_write_CAN_MB08_ID1(val) bfin_write16(CAN_MB08_ID1,val)
+#define bfin_read_CAN_MB08_ID0() bfin_read16(CAN_MB08_ID0)
+#define bfin_write_CAN_MB08_ID0(val) bfin_write16(CAN_MB08_ID0,val)
+#define bfin_read_CAN_MB08_TIMESTAMP() bfin_read16(CAN_MB08_TIMESTAMP)
+#define bfin_write_CAN_MB08_TIMESTAMP(val) bfin_write16(CAN_MB08_TIMESTAMP,val)
+#define bfin_read_CAN_MB08_LENGTH() bfin_read16(CAN_MB08_LENGTH)
+#define bfin_write_CAN_MB08_LENGTH(val) bfin_write16(CAN_MB08_LENGTH,val)
+#define bfin_read_CAN_MB08_DATA3() bfin_read16(CAN_MB08_DATA3)
+#define bfin_write_CAN_MB08_DATA3(val) bfin_write16(CAN_MB08_DATA3,val)
+#define bfin_read_CAN_MB08_DATA2() bfin_read16(CAN_MB08_DATA2)
+#define bfin_write_CAN_MB08_DATA2(val) bfin_write16(CAN_MB08_DATA2,val)
+#define bfin_read_CAN_MB08_DATA1() bfin_read16(CAN_MB08_DATA1)
+#define bfin_write_CAN_MB08_DATA1(val) bfin_write16(CAN_MB08_DATA1,val)
+#define bfin_read_CAN_MB08_DATA0() bfin_read16(CAN_MB08_DATA0)
+#define bfin_write_CAN_MB08_DATA0(val) bfin_write16(CAN_MB08_DATA0,val)
+
+#define bfin_read_CAN_MB09_ID1() bfin_read16(CAN_MB09_ID1)
+#define bfin_write_CAN_MB09_ID1(val) bfin_write16(CAN_MB09_ID1,val)
+#define bfin_read_CAN_MB09_ID0() bfin_read16(CAN_MB09_ID0)
+#define bfin_write_CAN_MB09_ID0(val) bfin_write16(CAN_MB09_ID0,val)
+#define bfin_read_CAN_MB09_TIMESTAMP() bfin_read16(CAN_MB09_TIMESTAMP)
+#define bfin_write_CAN_MB09_TIMESTAMP(val) bfin_write16(CAN_MB09_TIMESTAMP,val)
+#define bfin_read_CAN_MB09_LENGTH() bfin_read16(CAN_MB09_LENGTH)
+#define bfin_write_CAN_MB09_LENGTH(val) bfin_write16(CAN_MB09_LENGTH,val)
+#define bfin_read_CAN_MB09_DATA3() bfin_read16(CAN_MB09_DATA3)
+#define bfin_write_CAN_MB09_DATA3(val) bfin_write16(CAN_MB09_DATA3,val)
+#define bfin_read_CAN_MB09_DATA2() bfin_read16(CAN_MB09_DATA2)
+#define bfin_write_CAN_MB09_DATA2(val) bfin_write16(CAN_MB09_DATA2,val)
+#define bfin_read_CAN_MB09_DATA1() bfin_read16(CAN_MB09_DATA1)
+#define bfin_write_CAN_MB09_DATA1(val) bfin_write16(CAN_MB09_DATA1,val)
+#define bfin_read_CAN_MB09_DATA0() bfin_read16(CAN_MB09_DATA0)
+#define bfin_write_CAN_MB09_DATA0(val) bfin_write16(CAN_MB09_DATA0,val)
+
+#define bfin_read_CAN_MB10_ID1() bfin_read16(CAN_MB10_ID1)
+#define bfin_write_CAN_MB10_ID1(val) bfin_write16(CAN_MB10_ID1,val)
+#define bfin_read_CAN_MB10_ID0() bfin_read16(CAN_MB10_ID0)
+#define bfin_write_CAN_MB10_ID0(val) bfin_write16(CAN_MB10_ID0,val)
+#define bfin_read_CAN_MB10_TIMESTAMP() bfin_read16(CAN_MB10_TIMESTAMP)
+#define bfin_write_CAN_MB10_TIMESTAMP(val) bfin_write16(CAN_MB10_TIMESTAMP,val)
+#define bfin_read_CAN_MB10_LENGTH() bfin_read16(CAN_MB10_LENGTH)
+#define bfin_write_CAN_MB10_LENGTH(val) bfin_write16(CAN_MB10_LENGTH,val)
+#define bfin_read_CAN_MB10_DATA3() bfin_read16(CAN_MB10_DATA3)
+#define bfin_write_CAN_MB10_DATA3(val) bfin_write16(CAN_MB10_DATA3,val)
+#define bfin_read_CAN_MB10_DATA2() bfin_read16(CAN_MB10_DATA2)
+#define bfin_write_CAN_MB10_DATA2(val) bfin_write16(CAN_MB10_DATA2,val)
+#define bfin_read_CAN_MB10_DATA1() bfin_read16(CAN_MB10_DATA1)
+#define bfin_write_CAN_MB10_DATA1(val) bfin_write16(CAN_MB10_DATA1,val)
+#define bfin_read_CAN_MB10_DATA0() bfin_read16(CAN_MB10_DATA0)
+#define bfin_write_CAN_MB10_DATA0(val) bfin_write16(CAN_MB10_DATA0,val)
+
+#define bfin_read_CAN_MB11_ID1() bfin_read16(CAN_MB11_ID1)
+#define bfin_write_CAN_MB11_ID1(val) bfin_write16(CAN_MB11_ID1,val)
+#define bfin_read_CAN_MB11_ID0() bfin_read16(CAN_MB11_ID0)
+#define bfin_write_CAN_MB11_ID0(val) bfin_write16(CAN_MB11_ID0,val)
+#define bfin_read_CAN_MB11_TIMESTAMP() bfin_read16(CAN_MB11_TIMESTAMP)
+#define bfin_write_CAN_MB11_TIMESTAMP(val) bfin_write16(CAN_MB11_TIMESTAMP,val)
+#define bfin_read_CAN_MB11_LENGTH() bfin_read16(CAN_MB11_LENGTH)
+#define bfin_write_CAN_MB11_LENGTH(val) bfin_write16(CAN_MB11_LENGTH,val)
+#define bfin_read_CAN_MB11_DATA3() bfin_read16(CAN_MB11_DATA3)
+#define bfin_write_CAN_MB11_DATA3(val) bfin_write16(CAN_MB11_DATA3,val)
+#define bfin_read_CAN_MB11_DATA2() bfin_read16(CAN_MB11_DATA2)
+#define bfin_write_CAN_MB11_DATA2(val) bfin_write16(CAN_MB11_DATA2,val)
+#define bfin_read_CAN_MB11_DATA1() bfin_read16(CAN_MB11_DATA1)
+#define bfin_write_CAN_MB11_DATA1(val) bfin_write16(CAN_MB11_DATA1,val)
+#define bfin_read_CAN_MB11_DATA0() bfin_read16(CAN_MB11_DATA0)
+#define bfin_write_CAN_MB11_DATA0(val) bfin_write16(CAN_MB11_DATA0,val)
+
+#define bfin_read_CAN_MB12_ID1() bfin_read16(CAN_MB12_ID1)
+#define bfin_write_CAN_MB12_ID1(val) bfin_write16(CAN_MB12_ID1,val)
+#define bfin_read_CAN_MB12_ID0() bfin_read16(CAN_MB12_ID0)
+#define bfin_write_CAN_MB12_ID0(val) bfin_write16(CAN_MB12_ID0,val)
+#define bfin_read_CAN_MB12_TIMESTAMP() bfin_read16(CAN_MB12_TIMESTAMP)
+#define bfin_write_CAN_MB12_TIMESTAMP(val) bfin_write16(CAN_MB12_TIMESTAMP,val)
+#define bfin_read_CAN_MB12_LENGTH() bfin_read16(CAN_MB12_LENGTH)
+#define bfin_write_CAN_MB12_LENGTH(val) bfin_write16(CAN_MB12_LENGTH,val)
+#define bfin_read_CAN_MB12_DATA3() bfin_read16(CAN_MB12_DATA3)
+#define bfin_write_CAN_MB12_DATA3(val) bfin_write16(CAN_MB12_DATA3,val)
+#define bfin_read_CAN_MB12_DATA2() bfin_read16(CAN_MB12_DATA2)
+#define bfin_write_CAN_MB12_DATA2(val) bfin_write16(CAN_MB12_DATA2,val)
+#define bfin_read_CAN_MB12_DATA1() bfin_read16(CAN_MB12_DATA1)
+#define bfin_write_CAN_MB12_DATA1(val) bfin_write16(CAN_MB12_DATA1,val)
+#define bfin_read_CAN_MB12_DATA0() bfin_read16(CAN_MB12_DATA0)
+#define bfin_write_CAN_MB12_DATA0(val) bfin_write16(CAN_MB12_DATA0,val)
+
+#define bfin_read_CAN_MB13_ID1() bfin_read16(CAN_MB13_ID1)
+#define bfin_write_CAN_MB13_ID1(val) bfin_write16(CAN_MB13_ID1,val)
+#define bfin_read_CAN_MB13_ID0() bfin_read16(CAN_MB13_ID0)
+#define bfin_write_CAN_MB13_ID0(val) bfin_write16(CAN_MB13_ID0,val)
+#define bfin_read_CAN_MB13_TIMESTAMP() bfin_read16(CAN_MB13_TIMESTAMP)
+#define bfin_write_CAN_MB13_TIMESTAMP(val) bfin_write16(CAN_MB13_TIMESTAMP,val)
+#define bfin_read_CAN_MB13_LENGTH() bfin_read16(CAN_MB13_LENGTH)
+#define bfin_write_CAN_MB13_LENGTH(val) bfin_write16(CAN_MB13_LENGTH,val)
+#define bfin_read_CAN_MB13_DATA3() bfin_read16(CAN_MB13_DATA3)
+#define bfin_write_CAN_MB13_DATA3(val) bfin_write16(CAN_MB13_DATA3,val)
+#define bfin_read_CAN_MB13_DATA2() bfin_read16(CAN_MB13_DATA2)
+#define bfin_write_CAN_MB13_DATA2(val) bfin_write16(CAN_MB13_DATA2,val)
+#define bfin_read_CAN_MB13_DATA1() bfin_read16(CAN_MB13_DATA1)
+#define bfin_write_CAN_MB13_DATA1(val) bfin_write16(CAN_MB13_DATA1,val)
+#define bfin_read_CAN_MB13_DATA0() bfin_read16(CAN_MB13_DATA0)
+#define bfin_write_CAN_MB13_DATA0(val) bfin_write16(CAN_MB13_DATA0,val)
+
+#define bfin_read_CAN_MB14_ID1() bfin_read16(CAN_MB14_ID1)
+#define bfin_write_CAN_MB14_ID1(val) bfin_write16(CAN_MB14_ID1,val)
+#define bfin_read_CAN_MB14_ID0() bfin_read16(CAN_MB14_ID0)
+#define bfin_write_CAN_MB14_ID0(val) bfin_write16(CAN_MB14_ID0,val)
+#define bfin_read_CAN_MB14_TIMESTAMP() bfin_read16(CAN_MB14_TIMESTAMP)
+#define bfin_write_CAN_MB14_TIMESTAMP(val) bfin_write16(CAN_MB14_TIMESTAMP,val)
+#define bfin_read_CAN_MB14_LENGTH() bfin_read16(CAN_MB14_LENGTH)
+#define bfin_write_CAN_MB14_LENGTH(val) bfin_write16(CAN_MB14_LENGTH,val)
+#define bfin_read_CAN_MB14_DATA3() bfin_read16(CAN_MB14_DATA3)
+#define bfin_write_CAN_MB14_DATA3(val) bfin_write16(CAN_MB14_DATA3,val)
+#define bfin_read_CAN_MB14_DATA2() bfin_read16(CAN_MB14_DATA2)
+#define bfin_write_CAN_MB14_DATA2(val) bfin_write16(CAN_MB14_DATA2,val)
+#define bfin_read_CAN_MB14_DATA1() bfin_read16(CAN_MB14_DATA1)
+#define bfin_write_CAN_MB14_DATA1(val) bfin_write16(CAN_MB14_DATA1,val)
+#define bfin_read_CAN_MB14_DATA0() bfin_read16(CAN_MB14_DATA0)
+#define bfin_write_CAN_MB14_DATA0(val) bfin_write16(CAN_MB14_DATA0,val)
+
+#define bfin_read_CAN_MB15_ID1() bfin_read16(CAN_MB15_ID1)
+#define bfin_write_CAN_MB15_ID1(val) bfin_write16(CAN_MB15_ID1,val)
+#define bfin_read_CAN_MB15_ID0() bfin_read16(CAN_MB15_ID0)
+#define bfin_write_CAN_MB15_ID0(val) bfin_write16(CAN_MB15_ID0,val)
+#define bfin_read_CAN_MB15_TIMESTAMP() bfin_read16(CAN_MB15_TIMESTAMP)
+#define bfin_write_CAN_MB15_TIMESTAMP(val) bfin_write16(CAN_MB15_TIMESTAMP,val)
+#define bfin_read_CAN_MB15_LENGTH() bfin_read16(CAN_MB15_LENGTH)
+#define bfin_write_CAN_MB15_LENGTH(val) bfin_write16(CAN_MB15_LENGTH,val)
+#define bfin_read_CAN_MB15_DATA3() bfin_read16(CAN_MB15_DATA3)
+#define bfin_write_CAN_MB15_DATA3(val) bfin_write16(CAN_MB15_DATA3,val)
+#define bfin_read_CAN_MB15_DATA2() bfin_read16(CAN_MB15_DATA2)
+#define bfin_write_CAN_MB15_DATA2(val) bfin_write16(CAN_MB15_DATA2,val)
+#define bfin_read_CAN_MB15_DATA1() bfin_read16(CAN_MB15_DATA1)
+#define bfin_write_CAN_MB15_DATA1(val) bfin_write16(CAN_MB15_DATA1,val)
+#define bfin_read_CAN_MB15_DATA0() bfin_read16(CAN_MB15_DATA0)
+#define bfin_write_CAN_MB15_DATA0(val) bfin_write16(CAN_MB15_DATA0,val)
+
+#define bfin_read_CAN_MB16_ID1() bfin_read16(CAN_MB16_ID1)
+#define bfin_write_CAN_MB16_ID1(val) bfin_write16(CAN_MB16_ID1,val)
+#define bfin_read_CAN_MB16_ID0() bfin_read16(CAN_MB16_ID0)
+#define bfin_write_CAN_MB16_ID0(val) bfin_write16(CAN_MB16_ID0,val)
+#define bfin_read_CAN_MB16_TIMESTAMP() bfin_read16(CAN_MB16_TIMESTAMP)
+#define bfin_write_CAN_MB16_TIMESTAMP(val) bfin_write16(CAN_MB16_TIMESTAMP,val)
+#define bfin_read_CAN_MB16_LENGTH() bfin_read16(CAN_MB16_LENGTH)
+#define bfin_write_CAN_MB16_LENGTH(val) bfin_write16(CAN_MB16_LENGTH,val)
+#define bfin_read_CAN_MB16_DATA3() bfin_read16(CAN_MB16_DATA3)
+#define bfin_write_CAN_MB16_DATA3(val) bfin_write16(CAN_MB16_DATA3,val)
+#define bfin_read_CAN_MB16_DATA2() bfin_read16(CAN_MB16_DATA2)
+#define bfin_write_CAN_MB16_DATA2(val) bfin_write16(CAN_MB16_DATA2,val)
+#define bfin_read_CAN_MB16_DATA1() bfin_read16(CAN_MB16_DATA1)
+#define bfin_write_CAN_MB16_DATA1(val) bfin_write16(CAN_MB16_DATA1,val)
+#define bfin_read_CAN_MB16_DATA0() bfin_read16(CAN_MB16_DATA0)
+#define bfin_write_CAN_MB16_DATA0(val) bfin_write16(CAN_MB16_DATA0,val)
+
+#define bfin_read_CAN_MB17_ID1() bfin_read16(CAN_MB17_ID1)
+#define bfin_write_CAN_MB17_ID1(val) bfin_write16(CAN_MB17_ID1,val)
+#define bfin_read_CAN_MB17_ID0() bfin_read16(CAN_MB17_ID0)
+#define bfin_write_CAN_MB17_ID0(val) bfin_write16(CAN_MB17_ID0,val)
+#define bfin_read_CAN_MB17_TIMESTAMP() bfin_read16(CAN_MB17_TIMESTAMP)
+#define bfin_write_CAN_MB17_TIMESTAMP(val) bfin_write16(CAN_MB17_TIMESTAMP,val)
+#define bfin_read_CAN_MB17_LENGTH() bfin_read16(CAN_MB17_LENGTH)
+#define bfin_write_CAN_MB17_LENGTH(val) bfin_write16(CAN_MB17_LENGTH,val)
+#define bfin_read_CAN_MB17_DATA3() bfin_read16(CAN_MB17_DATA3)
+#define bfin_write_CAN_MB17_DATA3(val) bfin_write16(CAN_MB17_DATA3,val)
+#define bfin_read_CAN_MB17_DATA2() bfin_read16(CAN_MB17_DATA2)
+#define bfin_write_CAN_MB17_DATA2(val) bfin_write16(CAN_MB17_DATA2,val)
+#define bfin_read_CAN_MB17_DATA1() bfin_read16(CAN_MB17_DATA1)
+#define bfin_write_CAN_MB17_DATA1(val) bfin_write16(CAN_MB17_DATA1,val)
+#define bfin_read_CAN_MB17_DATA0() bfin_read16(CAN_MB17_DATA0)
+#define bfin_write_CAN_MB17_DATA0(val) bfin_write16(CAN_MB17_DATA0,val)
+
+#define bfin_read_CAN_MB18_ID1() bfin_read16(CAN_MB18_ID1)
+#define bfin_write_CAN_MB18_ID1(val) bfin_write16(CAN_MB18_ID1,val)
+#define bfin_read_CAN_MB18_ID0() bfin_read16(CAN_MB18_ID0)
+#define bfin_write_CAN_MB18_ID0(val) bfin_write16(CAN_MB18_ID0,val)
+#define bfin_read_CAN_MB18_TIMESTAMP() bfin_read16(CAN_MB18_TIMESTAMP)
+#define bfin_write_CAN_MB18_TIMESTAMP(val) bfin_write16(CAN_MB18_TIMESTAMP,val)
+#define bfin_read_CAN_MB18_LENGTH() bfin_read16(CAN_MB18_LENGTH)
+#define bfin_write_CAN_MB18_LENGTH(val) bfin_write16(CAN_MB18_LENGTH,val)
+#define bfin_read_CAN_MB18_DATA3() bfin_read16(CAN_MB18_DATA3)
+#define bfin_write_CAN_MB18_DATA3(val) bfin_write16(CAN_MB18_DATA3,val)
+#define bfin_read_CAN_MB18_DATA2() bfin_read16(CAN_MB18_DATA2)
+#define bfin_write_CAN_MB18_DATA2(val) bfin_write16(CAN_MB18_DATA2,val)
+#define bfin_read_CAN_MB18_DATA1() bfin_read16(CAN_MB18_DATA1)
+#define bfin_write_CAN_MB18_DATA1(val) bfin_write16(CAN_MB18_DATA1,val)
+#define bfin_read_CAN_MB18_DATA0() bfin_read16(CAN_MB18_DATA0)
+#define bfin_write_CAN_MB18_DATA0(val) bfin_write16(CAN_MB18_DATA0,val)
+
+#define bfin_read_CAN_MB19_ID1() bfin_read16(CAN_MB19_ID1)
+#define bfin_write_CAN_MB19_ID1(val) bfin_write16(CAN_MB19_ID1,val)
+#define bfin_read_CAN_MB19_ID0() bfin_read16(CAN_MB19_ID0)
+#define bfin_write_CAN_MB19_ID0(val) bfin_write16(CAN_MB19_ID0,val)
+#define bfin_read_CAN_MB19_TIMESTAMP() bfin_read16(CAN_MB19_TIMESTAMP)
+#define bfin_write_CAN_MB19_TIMESTAMP(val) bfin_write16(CAN_MB19_TIMESTAMP,val)
+#define bfin_read_CAN_MB19_LENGTH() bfin_read16(CAN_MB19_LENGTH)
+#define bfin_write_CAN_MB19_LENGTH(val) bfin_write16(CAN_MB19_LENGTH,val)
+#define bfin_read_CAN_MB19_DATA3() bfin_read16(CAN_MB19_DATA3)
+#define bfin_write_CAN_MB19_DATA3(val) bfin_write16(CAN_MB19_DATA3,val)
+#define bfin_read_CAN_MB19_DATA2() bfin_read16(CAN_MB19_DATA2)
+#define bfin_write_CAN_MB19_DATA2(val) bfin_write16(CAN_MB19_DATA2,val)
+#define bfin_read_CAN_MB19_DATA1() bfin_read16(CAN_MB19_DATA1)
+#define bfin_write_CAN_MB19_DATA1(val) bfin_write16(CAN_MB19_DATA1,val)
+#define bfin_read_CAN_MB19_DATA0() bfin_read16(CAN_MB19_DATA0)
+#define bfin_write_CAN_MB19_DATA0(val) bfin_write16(CAN_MB19_DATA0,val)
+
+#define bfin_read_CAN_MB20_ID1() bfin_read16(CAN_MB20_ID1)
+#define bfin_write_CAN_MB20_ID1(val) bfin_write16(CAN_MB20_ID1,val)
+#define bfin_read_CAN_MB20_ID0() bfin_read16(CAN_MB20_ID0)
+#define bfin_write_CAN_MB20_ID0(val) bfin_write16(CAN_MB20_ID0,val)
+#define bfin_read_CAN_MB20_TIMESTAMP() bfin_read16(CAN_MB20_TIMESTAMP)
+#define bfin_write_CAN_MB20_TIMESTAMP(val) bfin_write16(CAN_MB20_TIMESTAMP,val)
+#define bfin_read_CAN_MB20_LENGTH() bfin_read16(CAN_MB20_LENGTH)
+#define bfin_write_CAN_MB20_LENGTH(val) bfin_write16(CAN_MB20_LENGTH,val)
+#define bfin_read_CAN_MB20_DATA3() bfin_read16(CAN_MB20_DATA3)
+#define bfin_write_CAN_MB20_DATA3(val) bfin_write16(CAN_MB20_DATA3,val)
+#define bfin_read_CAN_MB20_DATA2() bfin_read16(CAN_MB20_DATA2)
+#define bfin_write_CAN_MB20_DATA2(val) bfin_write16(CAN_MB20_DATA2,val)
+#define bfin_read_CAN_MB20_DATA1() bfin_read16(CAN_MB20_DATA1)
+#define bfin_write_CAN_MB20_DATA1(val) bfin_write16(CAN_MB20_DATA1,val)
+#define bfin_read_CAN_MB20_DATA0() bfin_read16(CAN_MB20_DATA0)
+#define bfin_write_CAN_MB20_DATA0(val) bfin_write16(CAN_MB20_DATA0,val)
+
+#define bfin_read_CAN_MB21_ID1() bfin_read16(CAN_MB21_ID1)
+#define bfin_write_CAN_MB21_ID1(val) bfin_write16(CAN_MB21_ID1,val)
+#define bfin_read_CAN_MB21_ID0() bfin_read16(CAN_MB21_ID0)
+#define bfin_write_CAN_MB21_ID0(val) bfin_write16(CAN_MB21_ID0,val)
+#define bfin_read_CAN_MB21_TIMESTAMP() bfin_read16(CAN_MB21_TIMESTAMP)
+#define bfin_write_CAN_MB21_TIMESTAMP(val) bfin_write16(CAN_MB21_TIMESTAMP,val)
+#define bfin_read_CAN_MB21_LENGTH() bfin_read16(CAN_MB21_LENGTH)
+#define bfin_write_CAN_MB21_LENGTH(val) bfin_write16(CAN_MB21_LENGTH,val)
+#define bfin_read_CAN_MB21_DATA3() bfin_read16(CAN_MB21_DATA3)
+#define bfin_write_CAN_MB21_DATA3(val) bfin_write16(CAN_MB21_DATA3,val)
+#define bfin_read_CAN_MB21_DATA2() bfin_read16(CAN_MB21_DATA2)
+#define bfin_write_CAN_MB21_DATA2(val) bfin_write16(CAN_MB21_DATA2,val)
+#define bfin_read_CAN_MB21_DATA1() bfin_read16(CAN_MB21_DATA1)
+#define bfin_write_CAN_MB21_DATA1(val) bfin_write16(CAN_MB21_DATA1,val)
+#define bfin_read_CAN_MB21_DATA0() bfin_read16(CAN_MB21_DATA0)
+#define bfin_write_CAN_MB21_DATA0(val) bfin_write16(CAN_MB21_DATA0,val)
+
+#define bfin_read_CAN_MB22_ID1() bfin_read16(CAN_MB22_ID1)
+#define bfin_write_CAN_MB22_ID1(val) bfin_write16(CAN_MB22_ID1,val)
+#define bfin_read_CAN_MB22_ID0() bfin_read16(CAN_MB22_ID0)
+#define bfin_write_CAN_MB22_ID0(val) bfin_write16(CAN_MB22_ID0,val)
+#define bfin_read_CAN_MB22_TIMESTAMP() bfin_read16(CAN_MB22_TIMESTAMP)
+#define bfin_write_CAN_MB22_TIMESTAMP(val) bfin_write16(CAN_MB22_TIMESTAMP,val)
+#define bfin_read_CAN_MB22_LENGTH() bfin_read16(CAN_MB22_LENGTH)
+#define bfin_write_CAN_MB22_LENGTH(val) bfin_write16(CAN_MB22_LENGTH,val)
+#define bfin_read_CAN_MB22_DATA3() bfin_read16(CAN_MB22_DATA3)
+#define bfin_write_CAN_MB22_DATA3(val) bfin_write16(CAN_MB22_DATA3,val)
+#define bfin_read_CAN_MB22_DATA2() bfin_read16(CAN_MB22_DATA2)
+#define bfin_write_CAN_MB22_DATA2(val) bfin_write16(CAN_MB22_DATA2,val)
+#define bfin_read_CAN_MB22_DATA1() bfin_read16(CAN_MB22_DATA1)
+#define bfin_write_CAN_MB22_DATA1(val) bfin_write16(CAN_MB22_DATA1,val)
+#define bfin_read_CAN_MB22_DATA0() bfin_read16(CAN_MB22_DATA0)
+#define bfin_write_CAN_MB22_DATA0(val) bfin_write16(CAN_MB22_DATA0,val)
+
+#define bfin_read_CAN_MB23_ID1() bfin_read16(CAN_MB23_ID1)
+#define bfin_write_CAN_MB23_ID1(val) bfin_write16(CAN_MB23_ID1,val)
+#define bfin_read_CAN_MB23_ID0() bfin_read16(CAN_MB23_ID0)
+#define bfin_write_CAN_MB23_ID0(val) bfin_write16(CAN_MB23_ID0,val)
+#define bfin_read_CAN_MB23_TIMESTAMP() bfin_read16(CAN_MB23_TIMESTAMP)
+#define bfin_write_CAN_MB23_TIMESTAMP(val) bfin_write16(CAN_MB23_TIMESTAMP,val)
+#define bfin_read_CAN_MB23_LENGTH() bfin_read16(CAN_MB23_LENGTH)
+#define bfin_write_CAN_MB23_LENGTH(val) bfin_write16(CAN_MB23_LENGTH,val)
+#define bfin_read_CAN_MB23_DATA3() bfin_read16(CAN_MB23_DATA3)
+#define bfin_write_CAN_MB23_DATA3(val) bfin_write16(CAN_MB23_DATA3,val)
+#define bfin_read_CAN_MB23_DATA2() bfin_read16(CAN_MB23_DATA2)
+#define bfin_write_CAN_MB23_DATA2(val) bfin_write16(CAN_MB23_DATA2,val)
+#define bfin_read_CAN_MB23_DATA1() bfin_read16(CAN_MB23_DATA1)
+#define bfin_write_CAN_MB23_DATA1(val) bfin_write16(CAN_MB23_DATA1,val)
+#define bfin_read_CAN_MB23_DATA0() bfin_read16(CAN_MB23_DATA0)
+#define bfin_write_CAN_MB23_DATA0(val) bfin_write16(CAN_MB23_DATA0,val)
+
+#define bfin_read_CAN_MB24_ID1() bfin_read16(CAN_MB24_ID1)
+#define bfin_write_CAN_MB24_ID1(val) bfin_write16(CAN_MB24_ID1,val)
+#define bfin_read_CAN_MB24_ID0() bfin_read16(CAN_MB24_ID0)
+#define bfin_write_CAN_MB24_ID0(val) bfin_write16(CAN_MB24_ID0,val)
+#define bfin_read_CAN_MB24_TIMESTAMP() bfin_read16(CAN_MB24_TIMESTAMP)
+#define bfin_write_CAN_MB24_TIMESTAMP(val) bfin_write16(CAN_MB24_TIMESTAMP,val)
+#define bfin_read_CAN_MB24_LENGTH() bfin_read16(CAN_MB24_LENGTH)
+#define bfin_write_CAN_MB24_LENGTH(val) bfin_write16(CAN_MB24_LENGTH,val)
+#define bfin_read_CAN_MB24_DATA3() bfin_read16(CAN_MB24_DATA3)
+#define bfin_write_CAN_MB24_DATA3(val) bfin_write16(CAN_MB24_DATA3,val)
+#define bfin_read_CAN_MB24_DATA2() bfin_read16(CAN_MB24_DATA2)
+#define bfin_write_CAN_MB24_DATA2(val) bfin_write16(CAN_MB24_DATA2,val)
+#define bfin_read_CAN_MB24_DATA1() bfin_read16(CAN_MB24_DATA1)
+#define bfin_write_CAN_MB24_DATA1(val) bfin_write16(CAN_MB24_DATA1,val)
+#define bfin_read_CAN_MB24_DATA0() bfin_read16(CAN_MB24_DATA0)
+#define bfin_write_CAN_MB24_DATA0(val) bfin_write16(CAN_MB24_DATA0,val)
+
+#define bfin_read_CAN_MB25_ID1() bfin_read16(CAN_MB25_ID1)
+#define bfin_write_CAN_MB25_ID1(val) bfin_write16(CAN_MB25_ID1,val)
+#define bfin_read_CAN_MB25_ID0() bfin_read16(CAN_MB25_ID0)
+#define bfin_write_CAN_MB25_ID0(val) bfin_write16(CAN_MB25_ID0,val)
+#define bfin_read_CAN_MB25_TIMESTAMP() bfin_read16(CAN_MB25_TIMESTAMP)
+#define bfin_write_CAN_MB25_TIMESTAMP(val) bfin_write16(CAN_MB25_TIMESTAMP,val)
+#define bfin_read_CAN_MB25_LENGTH() bfin_read16(CAN_MB25_LENGTH)
+#define bfin_write_CAN_MB25_LENGTH(val) bfin_write16(CAN_MB25_LENGTH,val)
+#define bfin_read_CAN_MB25_DATA3() bfin_read16(CAN_MB25_DATA3)
+#define bfin_write_CAN_MB25_DATA3(val) bfin_write16(CAN_MB25_DATA3,val)
+#define bfin_read_CAN_MB25_DATA2() bfin_read16(CAN_MB25_DATA2)
+#define bfin_write_CAN_MB25_DATA2(val) bfin_write16(CAN_MB25_DATA2,val)
+#define bfin_read_CAN_MB25_DATA1() bfin_read16(CAN_MB25_DATA1)
+#define bfin_write_CAN_MB25_DATA1(val) bfin_write16(CAN_MB25_DATA1,val)
+#define bfin_read_CAN_MB25_DATA0() bfin_read16(CAN_MB25_DATA0)
+#define bfin_write_CAN_MB25_DATA0(val) bfin_write16(CAN_MB25_DATA0,val)
+
+#define bfin_read_CAN_MB26_ID1() bfin_read16(CAN_MB26_ID1)
+#define bfin_write_CAN_MB26_ID1(val) bfin_write16(CAN_MB26_ID1,val)
+#define bfin_read_CAN_MB26_ID0() bfin_read16(CAN_MB26_ID0)
+#define bfin_write_CAN_MB26_ID0(val) bfin_write16(CAN_MB26_ID0,val)
+#define bfin_read_CAN_MB26_TIMESTAMP() bfin_read16(CAN_MB26_TIMESTAMP)
+#define bfin_write_CAN_MB26_TIMESTAMP(val) bfin_write16(CAN_MB26_TIMESTAMP,val)
+#define bfin_read_CAN_MB26_LENGTH() bfin_read16(CAN_MB26_LENGTH)
+#define bfin_write_CAN_MB26_LENGTH(val) bfin_write16(CAN_MB26_LENGTH,val)
+#define bfin_read_CAN_MB26_DATA3() bfin_read16(CAN_MB26_DATA3)
+#define bfin_write_CAN_MB26_DATA3(val) bfin_write16(CAN_MB26_DATA3,val)
+#define bfin_read_CAN_MB26_DATA2() bfin_read16(CAN_MB26_DATA2)
+#define bfin_write_CAN_MB26_DATA2(val) bfin_write16(CAN_MB26_DATA2,val)
+#define bfin_read_CAN_MB26_DATA1() bfin_read16(CAN_MB26_DATA1)
+#define bfin_write_CAN_MB26_DATA1(val) bfin_write16(CAN_MB26_DATA1,val)
+#define bfin_read_CAN_MB26_DATA0() bfin_read16(CAN_MB26_DATA0)
+#define bfin_write_CAN_MB26_DATA0(val) bfin_write16(CAN_MB26_DATA0,val)
+
+#define bfin_read_CAN_MB27_ID1() bfin_read16(CAN_MB27_ID1)
+#define bfin_write_CAN_MB27_ID1(val) bfin_write16(CAN_MB27_ID1,val)
+#define bfin_read_CAN_MB27_ID0() bfin_read16(CAN_MB27_ID0)
+#define bfin_write_CAN_MB27_ID0(val) bfin_write16(CAN_MB27_ID0,val)
+#define bfin_read_CAN_MB27_TIMESTAMP() bfin_read16(CAN_MB27_TIMESTAMP)
+#define bfin_write_CAN_MB27_TIMESTAMP(val) bfin_write16(CAN_MB27_TIMESTAMP,val)
+#define bfin_read_CAN_MB27_LENGTH() bfin_read16(CAN_MB27_LENGTH)
+#define bfin_write_CAN_MB27_LENGTH(val) bfin_write16(CAN_MB27_LENGTH,val)
+#define bfin_read_CAN_MB27_DATA3() bfin_read16(CAN_MB27_DATA3)
+#define bfin_write_CAN_MB27_DATA3(val) bfin_write16(CAN_MB27_DATA3,val)
+#define bfin_read_CAN_MB27_DATA2() bfin_read16(CAN_MB27_DATA2)
+#define bfin_write_CAN_MB27_DATA2(val) bfin_write16(CAN_MB27_DATA2,val)
+#define bfin_read_CAN_MB27_DATA1() bfin_read16(CAN_MB27_DATA1)
+#define bfin_write_CAN_MB27_DATA1(val) bfin_write16(CAN_MB27_DATA1,val)
+#define bfin_read_CAN_MB27_DATA0() bfin_read16(CAN_MB27_DATA0)
+#define bfin_write_CAN_MB27_DATA0(val) bfin_write16(CAN_MB27_DATA0,val)
+
+#define bfin_read_CAN_MB28_ID1() bfin_read16(CAN_MB28_ID1)
+#define bfin_write_CAN_MB28_ID1(val) bfin_write16(CAN_MB28_ID1,val)
+#define bfin_read_CAN_MB28_ID0() bfin_read16(CAN_MB28_ID0)
+#define bfin_write_CAN_MB28_ID0(val) bfin_write16(CAN_MB28_ID0,val)
+#define bfin_read_CAN_MB28_TIMESTAMP() bfin_read16(CAN_MB28_TIMESTAMP)
+#define bfin_write_CAN_MB28_TIMESTAMP(val) bfin_write16(CAN_MB28_TIMESTAMP,val)
+#define bfin_read_CAN_MB28_LENGTH() bfin_read16(CAN_MB28_LENGTH)
+#define bfin_write_CAN_MB28_LENGTH(val) bfin_write16(CAN_MB28_LENGTH,val)
+#define bfin_read_CAN_MB28_DATA3() bfin_read16(CAN_MB28_DATA3)
+#define bfin_write_CAN_MB28_DATA3(val) bfin_write16(CAN_MB28_DATA3,val)
+#define bfin_read_CAN_MB28_DATA2() bfin_read16(CAN_MB28_DATA2)
+#define bfin_write_CAN_MB28_DATA2(val) bfin_write16(CAN_MB28_DATA2,val)
+#define bfin_read_CAN_MB28_DATA1() bfin_read16(CAN_MB28_DATA1)
+#define bfin_write_CAN_MB28_DATA1(val) bfin_write16(CAN_MB28_DATA1,val)
+#define bfin_read_CAN_MB28_DATA0() bfin_read16(CAN_MB28_DATA0)
+#define bfin_write_CAN_MB28_DATA0(val) bfin_write16(CAN_MB28_DATA0,val)
+
+#define bfin_read_CAN_MB29_ID1() bfin_read16(CAN_MB29_ID1)
+#define bfin_write_CAN_MB29_ID1(val) bfin_write16(CAN_MB29_ID1,val)
+#define bfin_read_CAN_MB29_ID0() bfin_read16(CAN_MB29_ID0)
+#define bfin_write_CAN_MB29_ID0(val) bfin_write16(CAN_MB29_ID0,val)
+#define bfin_read_CAN_MB29_TIMESTAMP() bfin_read16(CAN_MB29_TIMESTAMP)
+#define bfin_write_CAN_MB29_TIMESTAMP(val) bfin_write16(CAN_MB29_TIMESTAMP,val)
+#define bfin_read_CAN_MB29_LENGTH() bfin_read16(CAN_MB29_LENGTH)
+#define bfin_write_CAN_MB29_LENGTH(val) bfin_write16(CAN_MB29_LENGTH,val)
+#define bfin_read_CAN_MB29_DATA3() bfin_read16(CAN_MB29_DATA3)
+#define bfin_write_CAN_MB29_DATA3(val) bfin_write16(CAN_MB29_DATA3,val)
+#define bfin_read_CAN_MB29_DATA2() bfin_read16(CAN_MB29_DATA2)
+#define bfin_write_CAN_MB29_DATA2(val) bfin_write16(CAN_MB29_DATA2,val)
+#define bfin_read_CAN_MB29_DATA1() bfin_read16(CAN_MB29_DATA1)
+#define bfin_write_CAN_MB29_DATA1(val) bfin_write16(CAN_MB29_DATA1,val)
+#define bfin_read_CAN_MB29_DATA0() bfin_read16(CAN_MB29_DATA0)
+#define bfin_write_CAN_MB29_DATA0(val) bfin_write16(CAN_MB29_DATA0,val)
+
+#define bfin_read_CAN_MB30_ID1() bfin_read16(CAN_MB30_ID1)
+#define bfin_write_CAN_MB30_ID1(val) bfin_write16(CAN_MB30_ID1,val)
+#define bfin_read_CAN_MB30_ID0() bfin_read16(CAN_MB30_ID0)
+#define bfin_write_CAN_MB30_ID0(val) bfin_write16(CAN_MB30_ID0,val)
+#define bfin_read_CAN_MB30_TIMESTAMP() bfin_read16(CAN_MB30_TIMESTAMP)
+#define bfin_write_CAN_MB30_TIMESTAMP(val) bfin_write16(CAN_MB30_TIMESTAMP,val)
+#define bfin_read_CAN_MB30_LENGTH() bfin_read16(CAN_MB30_LENGTH)
+#define bfin_write_CAN_MB30_LENGTH(val) bfin_write16(CAN_MB30_LENGTH,val)
+#define bfin_read_CAN_MB30_DATA3() bfin_read16(CAN_MB30_DATA3)
+#define bfin_write_CAN_MB30_DATA3(val) bfin_write16(CAN_MB30_DATA3,val)
+#define bfin_read_CAN_MB30_DATA2() bfin_read16(CAN_MB30_DATA2)
+#define bfin_write_CAN_MB30_DATA2(val) bfin_write16(CAN_MB30_DATA2,val)
+#define bfin_read_CAN_MB30_DATA1() bfin_read16(CAN_MB30_DATA1)
+#define bfin_write_CAN_MB30_DATA1(val) bfin_write16(CAN_MB30_DATA1,val)
+#define bfin_read_CAN_MB30_DATA0() bfin_read16(CAN_MB30_DATA0)
+#define bfin_write_CAN_MB30_DATA0(val) bfin_write16(CAN_MB30_DATA0,val)
+
+#define bfin_read_CAN_MB31_ID1() bfin_read16(CAN_MB31_ID1)
+#define bfin_write_CAN_MB31_ID1(val) bfin_write16(CAN_MB31_ID1,val)
+#define bfin_read_CAN_MB31_ID0() bfin_read16(CAN_MB31_ID0)
+#define bfin_write_CAN_MB31_ID0(val) bfin_write16(CAN_MB31_ID0,val)
+#define bfin_read_CAN_MB31_TIMESTAMP() bfin_read16(CAN_MB31_TIMESTAMP)
+#define bfin_write_CAN_MB31_TIMESTAMP(val) bfin_write16(CAN_MB31_TIMESTAMP,val)
+#define bfin_read_CAN_MB31_LENGTH() bfin_read16(CAN_MB31_LENGTH)
+#define bfin_write_CAN_MB31_LENGTH(val) bfin_write16(CAN_MB31_LENGTH,val)
+#define bfin_read_CAN_MB31_DATA3() bfin_read16(CAN_MB31_DATA3)
+#define bfin_write_CAN_MB31_DATA3(val) bfin_write16(CAN_MB31_DATA3,val)
+#define bfin_read_CAN_MB31_DATA2() bfin_read16(CAN_MB31_DATA2)
+#define bfin_write_CAN_MB31_DATA2(val) bfin_write16(CAN_MB31_DATA2,val)
+#define bfin_read_CAN_MB31_DATA1() bfin_read16(CAN_MB31_DATA1)
+#define bfin_write_CAN_MB31_DATA1(val) bfin_write16(CAN_MB31_DATA1,val)
+#define bfin_read_CAN_MB31_DATA0() bfin_read16(CAN_MB31_DATA0)
+#define bfin_write_CAN_MB31_DATA0(val) bfin_write16(CAN_MB31_DATA0,val)
+
+/* CAN Mailbox Area Macros */
+#define bfin_read_CAN_MB_ID1(x)() bfin_read16(CAN_MB_ID1(x))
+#define bfin_write_CAN_MB_ID1(x)(val) bfin_write16(CAN_MB_ID1(x),val)
+#define bfin_read_CAN_MB_ID0(x)() bfin_read16(CAN_MB_ID0(x))
+#define bfin_write_CAN_MB_ID0(x)(val) bfin_write16(CAN_MB_ID0(x),val)
+#define bfin_read_CAN_MB_TIMESTAMP(x)() bfin_read16(CAN_MB_TIMESTAMP(x))
+#define bfin_write_CAN_MB_TIMESTAMP(x)(val) bfin_write16(CAN_MB_TIMESTAMP(x),val)
+#define bfin_read_CAN_MB_LENGTH(x)() bfin_read16(CAN_MB_LENGTH(x))
+#define bfin_write_CAN_MB_LENGTH(x)(val) bfin_write16(CAN_MB_LENGTH(x),val)
+#define bfin_read_CAN_MB_DATA3(x)() bfin_read16(CAN_MB_DATA3(x))
+#define bfin_write_CAN_MB_DATA3(x)(val) bfin_write16(CAN_MB_DATA3(x),val)
+#define bfin_read_CAN_MB_DATA2(x)() bfin_read16(CAN_MB_DATA2(x))
+#define bfin_write_CAN_MB_DATA2(x)(val) bfin_write16(CAN_MB_DATA2(x),val)
+#define bfin_read_CAN_MB_DATA1(x)() bfin_read16(CAN_MB_DATA1(x))
+#define bfin_write_CAN_MB_DATA1(x)(val) bfin_write16(CAN_MB_DATA1(x),val)
+#define bfin_read_CAN_MB_DATA0(x)() bfin_read16(CAN_MB_DATA0(x))
+#define bfin_write_CAN_MB_DATA0(x)(val) bfin_write16(CAN_MB_DATA0(x),val)
+
+/* Pin Control Registers (0xFFC03200 - 0xFFC032FF) */
+#define bfin_read_PORTF_FER() bfin_read16(PORTF_FER)
+#define bfin_write_PORTF_FER(val) bfin_write16(PORTF_FER,val)
+#define bfin_read_PORTG_FER() bfin_read16(PORTG_FER)
+#define bfin_write_PORTG_FER(val) bfin_write16(PORTG_FER,val)
+#define bfin_read_PORTH_FER() bfin_read16(PORTH_FER)
+#define bfin_write_PORTH_FER(val) bfin_write16(PORTH_FER,val)
+#define bfin_read_PORT_MUX() bfin_read16(BFIN_PORT_MUX)
+#define bfin_write_PORT_MUX(val) bfin_write16(BFIN_PORT_MUX,val)
+
+/* Handshake MDMA Registers (0xFFC03300 - 0xFFC033FF) */
+#define bfin_read_HMDMA0_CONTROL() bfin_read16(HMDMA0_CONTROL)
+#define bfin_write_HMDMA0_CONTROL(val) bfin_write16(HMDMA0_CONTROL,val)
+#define bfin_read_HMDMA0_ECINIT() bfin_read16(HMDMA0_ECINIT)
+#define bfin_write_HMDMA0_ECINIT(val) bfin_write16(HMDMA0_ECINIT,val)
+#define bfin_read_HMDMA0_BCINIT() bfin_read16(HMDMA0_BCINIT)
+#define bfin_write_HMDMA0_BCINIT(val) bfin_write16(HMDMA0_BCINIT,val)
+#define bfin_read_HMDMA0_ECURGENT() bfin_read16(HMDMA0_ECURGENT)
+#define bfin_write_HMDMA0_ECURGENT(val) bfin_write16(HMDMA0_ECURGENT,val)
+#define bfin_read_HMDMA0_ECOVERFLOW() bfin_read16(HMDMA0_ECOVERFLOW)
+#define bfin_write_HMDMA0_ECOVERFLOW(val) bfin_write16(HMDMA0_ECOVERFLOW,val)
+#define bfin_read_HMDMA0_ECOUNT() bfin_read16(HMDMA0_ECOUNT)
+#define bfin_write_HMDMA0_ECOUNT(val) bfin_write16(HMDMA0_ECOUNT,val)
+#define bfin_read_HMDMA0_BCOUNT() bfin_read16(HMDMA0_BCOUNT)
+#define bfin_write_HMDMA0_BCOUNT(val) bfin_write16(HMDMA0_BCOUNT,val)
+
+#define bfin_read_HMDMA1_CONTROL() bfin_read16(HMDMA1_CONTROL)
+#define bfin_write_HMDMA1_CONTROL(val) bfin_write16(HMDMA1_CONTROL,val)
+#define bfin_read_HMDMA1_ECINIT() bfin_read16(HMDMA1_ECINIT)
+#define bfin_write_HMDMA1_ECINIT(val) bfin_write16(HMDMA1_ECINIT,val)
+#define bfin_read_HMDMA1_BCINIT() bfin_read16(HMDMA1_BCINIT)
+#define bfin_write_HMDMA1_BCINIT(val) bfin_write16(HMDMA1_BCINIT,val)
+#define bfin_read_HMDMA1_ECURGENT() bfin_read16(HMDMA1_ECURGENT)
+#define bfin_write_HMDMA1_ECURGENT(val) bfin_write16(HMDMA1_ECURGENT,val)
+#define bfin_read_HMDMA1_ECOVERFLOW() bfin_read16(HMDMA1_ECOVERFLOW)
+#define bfin_write_HMDMA1_ECOVERFLOW(val) bfin_write16(HMDMA1_ECOVERFLOW,val)
+#define bfin_read_HMDMA1_ECOUNT() bfin_read16(HMDMA1_ECOUNT)
+#define bfin_write_HMDMA1_ECOUNT(val) bfin_write16(HMDMA1_ECOUNT,val)
+#define bfin_read_HMDMA1_BCOUNT() bfin_read16(HMDMA1_BCOUNT)
+#define bfin_write_HMDMA1_BCOUNT(val) bfin_write16(HMDMA1_BCOUNT,val)
+
+#endif /* _CDEF_BF534_H */
diff --git a/include/asm-blackfin/mach-bf537/cdefBF537.h b/include/asm-blackfin/mach-bf537/cdefBF537.h
new file mode 100644
index 0000000..932a1b6
--- /dev/null
+++ b/include/asm-blackfin/mach-bf537/cdefBF537.h
@@ -0,0 +1,209 @@
+/*
+ * File: include/asm-blackfin/mach-bf537/cdefBF537.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ * System MMR Register Map
+ * Rev:
+ *
+ * Modified:
+ *
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _CDEF_BF537_H
+#define _CDEF_BF537_H
+
+/* Include MMRs Common to BF534 */
+#include "cdefBF534.h"
+
+/* Include all Core registers and bit definitions */
+#include "defBF537.h"
+
+/* Include Macro "Defines" For EMAC (Unique to BF536/BF537 */
+/* 10/100 Ethernet Controller (0xFFC03000 - 0xFFC031FF) */
+#define pEMAC_OPMODE ((volatile unsigned long *)EMAC_OPMODE)
+#define bfin_read_EMAC_OPMODE() bfin_read32(EMAC_OPMODE)
+#define bfin_write_EMAC_OPMODE(val) bfin_write32(EMAC_OPMODE,val)
+#define bfin_read_EMAC_ADDRLO() bfin_read32(EMAC_ADDRLO)
+#define bfin_write_EMAC_ADDRLO(val) bfin_write32(EMAC_ADDRLO,val)
+#define bfin_read_EMAC_ADDRHI() bfin_read32(EMAC_ADDRHI)
+#define bfin_write_EMAC_ADDRHI(val) bfin_write32(EMAC_ADDRHI,val)
+#define bfin_read_EMAC_HASHLO() bfin_read32(EMAC_HASHLO)
+#define bfin_write_EMAC_HASHLO(val) bfin_write32(EMAC_HASHLO,val)
+#define bfin_read_EMAC_HASHHI() bfin_read32(EMAC_HASHHI)
+#define bfin_write_EMAC_HASHHI(val) bfin_write32(EMAC_HASHHI,val)
+#define bfin_read_EMAC_STAADD() bfin_read32(EMAC_STAADD)
+#define bfin_write_EMAC_STAADD(val) bfin_write32(EMAC_STAADD,val)
+#define bfin_read_EMAC_STADAT() bfin_read32(EMAC_STADAT)
+#define bfin_write_EMAC_STADAT(val) bfin_write32(EMAC_STADAT,val)
+#define bfin_read_EMAC_FLC() bfin_read32(EMAC_FLC)
+#define bfin_write_EMAC_FLC(val) bfin_write32(EMAC_FLC,val)
+#define bfin_read_EMAC_VLAN1() bfin_read32(EMAC_VLAN1)
+#define bfin_write_EMAC_VLAN1(val) bfin_write32(EMAC_VLAN1,val)
+#define bfin_read_EMAC_VLAN2() bfin_read32(EMAC_VLAN2)
+#define bfin_write_EMAC_VLAN2(val) bfin_write32(EMAC_VLAN2,val)
+#define bfin_read_EMAC_WKUP_CTL() bfin_read32(EMAC_WKUP_CTL)
+#define bfin_write_EMAC_WKUP_CTL(val) bfin_write32(EMAC_WKUP_CTL,val)
+#define bfin_read_EMAC_WKUP_FFMSK0() bfin_read32(EMAC_WKUP_FFMSK0)
+#define bfin_write_EMAC_WKUP_FFMSK0(val) bfin_write32(EMAC_WKUP_FFMSK0,val)
+#define bfin_read_EMAC_WKUP_FFMSK1() bfin_read32(EMAC_WKUP_FFMSK1)
+#define bfin_write_EMAC_WKUP_FFMSK1(val) bfin_write32(EMAC_WKUP_FFMSK1,val)
+#define bfin_read_EMAC_WKUP_FFMSK2() bfin_read32(EMAC_WKUP_FFMSK2)
+#define bfin_write_EMAC_WKUP_FFMSK2(val) bfin_write32(EMAC_WKUP_FFMSK2,val)
+#define bfin_read_EMAC_WKUP_FFMSK3() bfin_read32(EMAC_WKUP_FFMSK3)
+#define bfin_write_EMAC_WKUP_FFMSK3(val) bfin_write32(EMAC_WKUP_FFMSK3,val)
+#define bfin_read_EMAC_WKUP_FFCMD() bfin_read32(EMAC_WKUP_FFCMD)
+#define bfin_write_EMAC_WKUP_FFCMD(val) bfin_write32(EMAC_WKUP_FFCMD,val)
+#define bfin_read_EMAC_WKUP_FFOFF() bfin_read32(EMAC_WKUP_FFOFF)
+#define bfin_write_EMAC_WKUP_FFOFF(val) bfin_write32(EMAC_WKUP_FFOFF,val)
+#define bfin_read_EMAC_WKUP_FFCRC0() bfin_read32(EMAC_WKUP_FFCRC0)
+#define bfin_write_EMAC_WKUP_FFCRC0(val) bfin_write32(EMAC_WKUP_FFCRC0,val)
+#define bfin_read_EMAC_WKUP_FFCRC1() bfin_read32(EMAC_WKUP_FFCRC1)
+#define bfin_write_EMAC_WKUP_FFCRC1(val) bfin_write32(EMAC_WKUP_FFCRC1,val)
+
+#define pEMAC_SYSCTL ((volatile unsigned long *)EMAC_SYSCTL)
+#define bfin_read_EMAC_SYSCTL() bfin_read32(EMAC_SYSCTL)
+#define bfin_write_EMAC_SYSCTL(val) bfin_write32(EMAC_SYSCTL,val)
+#define bfin_read_EMAC_SYSTAT() bfin_read32(EMAC_SYSTAT)
+#define bfin_write_EMAC_SYSTAT(val) bfin_write32(EMAC_SYSTAT,val)
+#define bfin_read_EMAC_RX_STAT() bfin_read32(EMAC_RX_STAT)
+#define bfin_write_EMAC_RX_STAT(val) bfin_write32(EMAC_RX_STAT,val)
+#define bfin_read_EMAC_RX_STKY() bfin_read32(EMAC_RX_STKY)
+#define bfin_write_EMAC_RX_STKY(val) bfin_write32(EMAC_RX_STKY,val)
+#define bfin_read_EMAC_RX_IRQE() bfin_read32(EMAC_RX_IRQE)
+#define bfin_write_EMAC_RX_IRQE(val) bfin_write32(EMAC_RX_IRQE,val)
+#define bfin_read_EMAC_TX_STAT() bfin_read32(EMAC_TX_STAT)
+#define bfin_write_EMAC_TX_STAT(val) bfin_write32(EMAC_TX_STAT,val)
+#define bfin_read_EMAC_TX_STKY() bfin_read32(EMAC_TX_STKY)
+#define bfin_write_EMAC_TX_STKY(val) bfin_write32(EMAC_TX_STKY,val)
+#define bfin_read_EMAC_TX_IRQE() bfin_read32(EMAC_TX_IRQE)
+#define bfin_write_EMAC_TX_IRQE(val) bfin_write32(EMAC_TX_IRQE,val)
+
+#define bfin_read_EMAC_MMC_CTL() bfin_read32(EMAC_MMC_CTL)
+#define bfin_write_EMAC_MMC_CTL(val) bfin_write32(EMAC_MMC_CTL,val)
+#define bfin_read_EMAC_MMC_RIRQS() bfin_read32(EMAC_MMC_RIRQS)
+#define bfin_write_EMAC_MMC_RIRQS(val) bfin_write32(EMAC_MMC_RIRQS,val)
+#define bfin_read_EMAC_MMC_RIRQE() bfin_read32(EMAC_MMC_RIRQE)
+#define bfin_write_EMAC_MMC_RIRQE(val) bfin_write32(EMAC_MMC_RIRQE,val)
+#define bfin_read_EMAC_MMC_TIRQS() bfin_read32(EMAC_MMC_TIRQS)
+#define bfin_write_EMAC_MMC_TIRQS(val) bfin_write32(EMAC_MMC_TIRQS,val)
+#define bfin_read_EMAC_MMC_TIRQE() bfin_read32(EMAC_MMC_TIRQE)
+#define bfin_write_EMAC_MMC_TIRQE(val) bfin_write32(EMAC_MMC_TIRQE,val)
+
+#define bfin_read_EMAC_RXC_OK() bfin_read32(EMAC_RXC_OK)
+#define bfin_write_EMAC_RXC_OK(val) bfin_write32(EMAC_RXC_OK,val)
+#define bfin_read_EMAC_RXC_FCS() bfin_read32(EMAC_RXC_FCS)
+#define bfin_write_EMAC_RXC_FCS(val) bfin_write32(EMAC_RXC_FCS,val)
+#define bfin_read_EMAC_RXC_ALIGN() bfin_read32(EMAC_RXC_ALIGN)
+#define bfin_write_EMAC_RXC_ALIGN(val) bfin_write32(EMAC_RXC_ALIGN,val)
+#define bfin_read_EMAC_RXC_OCTET() bfin_read32(EMAC_RXC_OCTET)
+#define bfin_write_EMAC_RXC_OCTET(val) bfin_write32(EMAC_RXC_OCTET,val)
+#define bfin_read_EMAC_RXC_DMAOVF() bfin_read32(EMAC_RXC_DMAOVF)
+#define bfin_write_EMAC_RXC_DMAOVF(val) bfin_write32(EMAC_RXC_DMAOVF,val)
+#define bfin_read_EMAC_RXC_UNICST() bfin_read32(EMAC_RXC_UNICST)
+#define bfin_write_EMAC_RXC_UNICST(val) bfin_write32(EMAC_RXC_UNICST,val)
+#define bfin_read_EMAC_RXC_MULTI() bfin_read32(EMAC_RXC_MULTI)
+#define bfin_write_EMAC_RXC_MULTI(val) bfin_write32(EMAC_RXC_MULTI,val)
+#define bfin_read_EMAC_RXC_BROAD() bfin_read32(EMAC_RXC_BROAD)
+#define bfin_write_EMAC_RXC_BROAD(val) bfin_write32(EMAC_RXC_BROAD,val)
+#define bfin_read_EMAC_RXC_LNERRI() bfin_read32(EMAC_RXC_LNERRI)
+#define bfin_write_EMAC_RXC_LNERRI(val) bfin_write32(EMAC_RXC_LNERRI,val)
+#define bfin_read_EMAC_RXC_LNERRO() bfin_read32(EMAC_RXC_LNERRO)
+#define bfin_write_EMAC_RXC_LNERRO(val) bfin_write32(EMAC_RXC_LNERRO,val)
+#define bfin_read_EMAC_RXC_LONG() bfin_read32(EMAC_RXC_LONG)
+#define bfin_write_EMAC_RXC_LONG(val) bfin_write32(EMAC_RXC_LONG,val)
+#define bfin_read_EMAC_RXC_MACCTL() bfin_read32(EMAC_RXC_MACCTL)
+#define bfin_write_EMAC_RXC_MACCTL(val) bfin_write32(EMAC_RXC_MACCTL,val)
+#define bfin_read_EMAC_RXC_OPCODE() bfin_read32(EMAC_RXC_OPCODE)
+#define bfin_write_EMAC_RXC_OPCODE(val) bfin_write32(EMAC_RXC_OPCODE,val)
+#define bfin_read_EMAC_RXC_PAUSE() bfin_read32(EMAC_RXC_PAUSE)
+#define bfin_write_EMAC_RXC_PAUSE(val) bfin_write32(EMAC_RXC_PAUSE,val)
+#define bfin_read_EMAC_RXC_ALLFRM() bfin_read32(EMAC_RXC_ALLFRM)
+#define bfin_write_EMAC_RXC_ALLFRM(val) bfin_write32(EMAC_RXC_ALLFRM,val)
+#define bfin_read_EMAC_RXC_ALLOCT() bfin_read32(EMAC_RXC_ALLOCT)
+#define bfin_write_EMAC_RXC_ALLOCT(val) bfin_write32(EMAC_RXC_ALLOCT,val)
+#define bfin_read_EMAC_RXC_TYPED() bfin_read32(EMAC_RXC_TYPED)
+#define bfin_write_EMAC_RXC_TYPED(val) bfin_write32(EMAC_RXC_TYPED,val)
+#define bfin_read_EMAC_RXC_SHORT() bfin_read32(EMAC_RXC_SHORT)
+#define bfin_write_EMAC_RXC_SHORT(val) bfin_write32(EMAC_RXC_SHORT,val)
+#define bfin_read_EMAC_RXC_EQ64() bfin_read32(EMAC_RXC_EQ64)
+#define bfin_write_EMAC_RXC_EQ64(val) bfin_write32(EMAC_RXC_EQ64,val)
+#define pEMAC_RXC_LT128 ((volatile unsigned long *)EMAC_RXC_LT128)
+#define bfin_read_EMAC_RXC_LT128() bfin_read32(EMAC_RXC_LT128)
+#define bfin_write_EMAC_RXC_LT128(val) bfin_write32(EMAC_RXC_LT128,val)
+#define bfin_read_EMAC_RXC_LT256() bfin_read32(EMAC_RXC_LT256)
+#define bfin_write_EMAC_RXC_LT256(val) bfin_write32(EMAC_RXC_LT256,val)
+#define bfin_read_EMAC_RXC_LT512() bfin_read32(EMAC_RXC_LT512)
+#define bfin_write_EMAC_RXC_LT512(val) bfin_write32(EMAC_RXC_LT512,val)
+#define bfin_read_EMAC_RXC_LT1024() bfin_read32(EMAC_RXC_LT1024)
+#define bfin_write_EMAC_RXC_LT1024(val) bfin_write32(EMAC_RXC_LT1024,val)
+#define bfin_read_EMAC_RXC_GE1024() bfin_read32(EMAC_RXC_GE1024)
+#define bfin_write_EMAC_RXC_GE1024(val) bfin_write32(EMAC_RXC_GE1024,val)
+
+#define bfin_read_EMAC_TXC_OK() bfin_read32(EMAC_TXC_OK)
+#define bfin_write_EMAC_TXC_OK(val) bfin_write32(EMAC_TXC_OK,val)
+#define bfin_read_EMAC_TXC_1COL() bfin_read32(EMAC_TXC_1COL)
+#define bfin_write_EMAC_TXC_1COL(val) bfin_write32(EMAC_TXC_1COL,val)
+#define bfin_read_EMAC_TXC_GT1COL() bfin_read32(EMAC_TXC_GT1COL)
+#define bfin_write_EMAC_TXC_GT1COL(val) bfin_write32(EMAC_TXC_GT1COL,val)
+#define bfin_read_EMAC_TXC_OCTET() bfin_read32(EMAC_TXC_OCTET)
+#define bfin_write_EMAC_TXC_OCTET(val) bfin_write32(EMAC_TXC_OCTET,val)
+#define bfin_read_EMAC_TXC_DEFER() bfin_read32(EMAC_TXC_DEFER)
+#define bfin_write_EMAC_TXC_DEFER(val) bfin_write32(EMAC_TXC_DEFER,val)
+#define bfin_read_EMAC_TXC_LATECL() bfin_read32(EMAC_TXC_LATECL)
+#define bfin_write_EMAC_TXC_LATECL(val) bfin_write32(EMAC_TXC_LATECL,val)
+#define bfin_read_EMAC_TXC_XS_COL() bfin_read32(EMAC_TXC_XS_COL)
+#define bfin_write_EMAC_TXC_XS_COL(val) bfin_write32(EMAC_TXC_XS_COL,val)
+#define bfin_read_EMAC_TXC_DMAUND() bfin_read32(EMAC_TXC_DMAUND)
+#define bfin_write_EMAC_TXC_DMAUND(val) bfin_write32(EMAC_TXC_DMAUND,val)
+#define bfin_read_EMAC_TXC_CRSERR() bfin_read32(EMAC_TXC_CRSERR)
+#define bfin_write_EMAC_TXC_CRSERR(val) bfin_write32(EMAC_TXC_CRSERR,val)
+#define bfin_read_EMAC_TXC_UNICST() bfin_read32(EMAC_TXC_UNICST)
+#define bfin_write_EMAC_TXC_UNICST(val) bfin_write32(EMAC_TXC_UNICST,val)
+#define bfin_read_EMAC_TXC_MULTI() bfin_read32(EMAC_TXC_MULTI)
+#define bfin_write_EMAC_TXC_MULTI(val) bfin_write32(EMAC_TXC_MULTI,val)
+#define bfin_read_EMAC_TXC_BROAD() bfin_read32(EMAC_TXC_BROAD)
+#define bfin_write_EMAC_TXC_BROAD(val) bfin_write32(EMAC_TXC_BROAD,val)
+#define bfin_read_EMAC_TXC_XS_DFR() bfin_read32(EMAC_TXC_XS_DFR)
+#define bfin_write_EMAC_TXC_XS_DFR(val) bfin_write32(EMAC_TXC_XS_DFR,val)
+#define bfin_read_EMAC_TXC_MACCTL() bfin_read32(EMAC_TXC_MACCTL)
+#define bfin_write_EMAC_TXC_MACCTL(val) bfin_write32(EMAC_TXC_MACCTL,val)
+#define bfin_read_EMAC_TXC_ALLFRM() bfin_read32(EMAC_TXC_ALLFRM)
+#define bfin_write_EMAC_TXC_ALLFRM(val) bfin_write32(EMAC_TXC_ALLFRM,val)
+#define bfin_read_EMAC_TXC_ALLOCT() bfin_read32(EMAC_TXC_ALLOCT)
+#define bfin_write_EMAC_TXC_ALLOCT(val) bfin_write32(EMAC_TXC_ALLOCT,val)
+#define bfin_read_EMAC_TXC_EQ64() bfin_read32(EMAC_TXC_EQ64)
+#define bfin_write_EMAC_TXC_EQ64(val) bfin_write32(EMAC_TXC_EQ64,val)
+#define bfin_read_EMAC_TXC_LT128() bfin_read32(EMAC_TXC_LT128)
+#define bfin_write_EMAC_TXC_LT128(val) bfin_write32(EMAC_TXC_LT128,val)
+#define bfin_read_EMAC_TXC_LT256() bfin_read32(EMAC_TXC_LT256)
+#define bfin_write_EMAC_TXC_LT256(val) bfin_write32(EMAC_TXC_LT256,val)
+#define bfin_read_EMAC_TXC_LT512() bfin_read32(EMAC_TXC_LT512)
+#define bfin_write_EMAC_TXC_LT512(val) bfin_write32(EMAC_TXC_LT512,val)
+#define bfin_read_EMAC_TXC_LT1024() bfin_read32(EMAC_TXC_LT1024)
+#define bfin_write_EMAC_TXC_LT1024(val) bfin_write32(EMAC_TXC_LT1024,val)
+#define bfin_read_EMAC_TXC_GE1024() bfin_read32(EMAC_TXC_GE1024)
+#define bfin_write_EMAC_TXC_GE1024(val) bfin_write32(EMAC_TXC_GE1024,val)
+#define bfin_read_EMAC_TXC_ABORT() bfin_read32(EMAC_TXC_ABORT)
+#define bfin_write_EMAC_TXC_ABORT(val) bfin_write32(EMAC_TXC_ABORT,val)
+
+#endif /* _CDEF_BF537_H */
diff --git a/include/asm-blackfin/mach-bf537/defBF534.h b/include/asm-blackfin/mach-bf537/defBF534.h
new file mode 100644
index 0000000..e605e970
--- /dev/null
+++ b/include/asm-blackfin/mach-bf537/defBF534.h
@@ -0,0 +1,2501 @@
+/*
+ * File: include/asm-blackfin/mach-bf537/cdefBF537.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _DEF_BF534_H
+#define _DEF_BF534_H
+
+/* Include all Core registers and bit definitions */
+#include <asm/mach-common/def_LPBlackfin.h>
+
+/************************************************************************************
+** System MMR Register Map
+*************************************************************************************/
+/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */
+#define PLL_CTL 0xFFC00000 /* PLL Control Register */
+#define PLL_DIV 0xFFC00004 /* PLL Divide Register */
+#define VR_CTL 0xFFC00008 /* Voltage Regulator Control Register */
+#define PLL_STAT 0xFFC0000C /* PLL Status Register */
+#define PLL_LOCKCNT 0xFFC00010 /* PLL Lock Count Register */
+#define CHIPID 0xFFC00014 /* Chip ID Register */
+
+/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
+#define SWRST 0xFFC00100 /* Software Reset Register */
+#define SYSCR 0xFFC00104 /* System Configuration Register */
+#define SIC_RVECT 0xFFC00108 /* Interrupt Reset Vector Address Register */
+#define SIC_IMASK 0xFFC0010C /* Interrupt Mask Register */
+#define SIC_IAR0 0xFFC00110 /* Interrupt Assignment Register 0 */
+#define SIC_IAR1 0xFFC00114 /* Interrupt Assignment Register 1 */
+#define SIC_IAR2 0xFFC00118 /* Interrupt Assignment Register 2 */
+#define SIC_IAR3 0xFFC0011C /* Interrupt Assignment Register 3 */
+#define SIC_ISR 0xFFC00120 /* Interrupt Status Register */
+#define SIC_IWR 0xFFC00124 /* Interrupt Wakeup Register */
+
+/* Watchdog Timer (0xFFC00200 - 0xFFC002FF) */
+#define WDOG_CTL 0xFFC00200 /* Watchdog Control Register */
+#define WDOG_CNT 0xFFC00204 /* Watchdog Count Register */
+#define WDOG_STAT 0xFFC00208 /* Watchdog Status Register */
+
+/* Real Time Clock (0xFFC00300 - 0xFFC003FF) */
+#define RTC_STAT 0xFFC00300 /* RTC Status Register */
+#define RTC_ICTL 0xFFC00304 /* RTC Interrupt Control Register */
+#define RTC_ISTAT 0xFFC00308 /* RTC Interrupt Status Register */
+#define RTC_SWCNT 0xFFC0030C /* RTC Stopwatch Count Register */
+#define RTC_ALARM 0xFFC00310 /* RTC Alarm Time Register */
+#define RTC_FAST 0xFFC00314 /* RTC Prescaler Enable Register */
+#define RTC_PREN 0xFFC00314 /* RTC Prescaler Enable Alternate Macro */
+
+/* UART0 Controller (0xFFC00400 - 0xFFC004FF) */
+#define UART0_THR 0xFFC00400 /* Transmit Holding register */
+#define UART0_RBR 0xFFC00400 /* Receive Buffer register */
+#define UART0_DLL 0xFFC00400 /* Divisor Latch (Low-Byte) */
+#define UART0_IER 0xFFC00404 /* Interrupt Enable Register */
+#define UART0_DLH 0xFFC00404 /* Divisor Latch (High-Byte) */
+#define UART0_IIR 0xFFC00408 /* Interrupt Identification Register */
+#define UART0_LCR 0xFFC0040C /* Line Control Register */
+#define UART0_MCR 0xFFC00410 /* Modem Control Register */
+#define UART0_LSR 0xFFC00414 /* Line Status Register */
+#define UART0_MSR 0xFFC00418 /* Modem Status Register */
+#define UART0_SCR 0xFFC0041C /* SCR Scratch Register */
+#define UART0_GCTL 0xFFC00424 /* Global Control Register */
+
+/* SPI Controller (0xFFC00500 - 0xFFC005FF) */
+#define SPI_CTL 0xFFC00500 /* SPI Control Register */
+#define SPI_FLG 0xFFC00504 /* SPI Flag register */
+#define SPI_STAT 0xFFC00508 /* SPI Status register */
+#define SPI_TDBR 0xFFC0050C /* SPI Transmit Data Buffer Register */
+#define SPI_RDBR 0xFFC00510 /* SPI Receive Data Buffer Register */
+#define SPI_BAUD 0xFFC00514 /* SPI Baud rate Register */
+#define SPI_SHADOW 0xFFC00518 /* SPI_RDBR Shadow Register */
+
+/* TIMER0-7 Registers (0xFFC00600 - 0xFFC006FF) */
+#define TIMER0_CONFIG 0xFFC00600 /* Timer 0 Configuration Register */
+#define TIMER0_COUNTER 0xFFC00604 /* Timer 0 Counter Register */
+#define TIMER0_PERIOD 0xFFC00608 /* Timer 0 Period Register */
+#define TIMER0_WIDTH 0xFFC0060C /* Timer 0 Width Register */
+
+#define TIMER1_CONFIG 0xFFC00610 /* Timer 1 Configuration Register */
+#define TIMER1_COUNTER 0xFFC00614 /* Timer 1 Counter Register */
+#define TIMER1_PERIOD 0xFFC00618 /* Timer 1 Period Register */
+#define TIMER1_WIDTH 0xFFC0061C /* Timer 1 Width Register */
+
+#define TIMER2_CONFIG 0xFFC00620 /* Timer 2 Configuration Register */
+#define TIMER2_COUNTER 0xFFC00624 /* Timer 2 Counter Register */
+#define TIMER2_PERIOD 0xFFC00628 /* Timer 2 Period Register */
+#define TIMER2_WIDTH 0xFFC0062C /* Timer 2 Width Register */
+
+#define TIMER3_CONFIG 0xFFC00630 /* Timer 3 Configuration Register */
+#define TIMER3_COUNTER 0xFFC00634 /* Timer 3 Counter Register */
+#define TIMER3_PERIOD 0xFFC00638 /* Timer 3 Period Register */
+#define TIMER3_WIDTH 0xFFC0063C /* Timer 3 Width Register */
+
+#define TIMER4_CONFIG 0xFFC00640 /* Timer 4 Configuration Register */
+#define TIMER4_COUNTER 0xFFC00644 /* Timer 4 Counter Register */
+#define TIMER4_PERIOD 0xFFC00648 /* Timer 4 Period Register */
+#define TIMER4_WIDTH 0xFFC0064C /* Timer 4 Width Register */
+
+#define TIMER5_CONFIG 0xFFC00650 /* Timer 5 Configuration Register */
+#define TIMER5_COUNTER 0xFFC00654 /* Timer 5 Counter Register */
+#define TIMER5_PERIOD 0xFFC00658 /* Timer 5 Period Register */
+#define TIMER5_WIDTH 0xFFC0065C /* Timer 5 Width Register */
+
+#define TIMER6_CONFIG 0xFFC00660 /* Timer 6 Configuration Register */
+#define TIMER6_COUNTER 0xFFC00664 /* Timer 6 Counter Register */
+#define TIMER6_PERIOD 0xFFC00668 /* Timer 6 Period Register */
+#define TIMER6_WIDTH 0xFFC0066C /* Timer 6 Width Register */
+
+#define TIMER7_CONFIG 0xFFC00670 /* Timer 7 Configuration Register */
+#define TIMER7_COUNTER 0xFFC00674 /* Timer 7 Counter Register */
+#define TIMER7_PERIOD 0xFFC00678 /* Timer 7 Period Register */
+#define TIMER7_WIDTH 0xFFC0067C /* Timer 7 Width Register */
+
+#define TIMER_ENABLE 0xFFC00680 /* Timer Enable Register */
+#define TIMER_DISABLE 0xFFC00684 /* Timer Disable Register */
+#define TIMER_STATUS 0xFFC00688 /* Timer Status Register */
+
+/* General Purpose I/O Port F (0xFFC00700 - 0xFFC007FF) */
+#define PORTFIO 0xFFC00700 /* Port F I/O Pin State Specify Register */
+#define PORTFIO_CLEAR 0xFFC00704 /* Port F I/O Peripheral Interrupt Clear Register */
+#define PORTFIO_SET 0xFFC00708 /* Port F I/O Peripheral Interrupt Set Register */
+#define PORTFIO_TOGGLE 0xFFC0070C /* Port F I/O Pin State Toggle Register */
+#define PORTFIO_MASKA 0xFFC00710 /* Port F I/O Mask State Specify Interrupt A Register */
+#define PORTFIO_MASKA_CLEAR 0xFFC00714 /* Port F I/O Mask Disable Interrupt A Register */
+#define PORTFIO_MASKA_SET 0xFFC00718 /* Port F I/O Mask Enable Interrupt A Register */
+#define PORTFIO_MASKA_TOGGLE 0xFFC0071C /* Port F I/O Mask Toggle Enable Interrupt A Register */
+#define PORTFIO_MASKB 0xFFC00720 /* Port F I/O Mask State Specify Interrupt B Register */
+#define PORTFIO_MASKB_CLEAR 0xFFC00724 /* Port F I/O Mask Disable Interrupt B Register */
+#define PORTFIO_MASKB_SET 0xFFC00728 /* Port F I/O Mask Enable Interrupt B Register */
+#define PORTFIO_MASKB_TOGGLE 0xFFC0072C /* Port F I/O Mask Toggle Enable Interrupt B Register */
+#define PORTFIO_DIR 0xFFC00730 /* Port F I/O Direction Register */
+#define PORTFIO_POLAR 0xFFC00734 /* Port F I/O Source Polarity Register */
+#define PORTFIO_EDGE 0xFFC00738 /* Port F I/O Source Sensitivity Register */
+#define PORTFIO_BOTH 0xFFC0073C /* Port F I/O Set on BOTH Edges Register */
+#define PORTFIO_INEN 0xFFC00740 /* Port F I/O Input Enable Register */
+
+/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
+#define SPORT0_TCR1 0xFFC00800 /* SPORT0 Transmit Configuration 1 Register */
+#define SPORT0_TCR2 0xFFC00804 /* SPORT0 Transmit Configuration 2 Register */
+#define SPORT0_TCLKDIV 0xFFC00808 /* SPORT0 Transmit Clock Divider */
+#define SPORT0_TFSDIV 0xFFC0080C /* SPORT0 Transmit Frame Sync Divider */
+#define SPORT0_TX 0xFFC00810 /* SPORT0 TX Data Register */
+#define SPORT0_RX 0xFFC00818 /* SPORT0 RX Data Register */
+#define SPORT0_RCR1 0xFFC00820 /* SPORT0 Transmit Configuration 1 Register */
+#define SPORT0_RCR2 0xFFC00824 /* SPORT0 Transmit Configuration 2 Register */
+#define SPORT0_RCLKDIV 0xFFC00828 /* SPORT0 Receive Clock Divider */
+#define SPORT0_RFSDIV 0xFFC0082C /* SPORT0 Receive Frame Sync Divider */
+#define SPORT0_STAT 0xFFC00830 /* SPORT0 Status Register */
+#define SPORT0_CHNL 0xFFC00834 /* SPORT0 Current Channel Register */
+#define SPORT0_MCMC1 0xFFC00838 /* SPORT0 Multi-Channel Configuration Register 1 */
+#define SPORT0_MCMC2 0xFFC0083C /* SPORT0 Multi-Channel Configuration Register 2 */
+#define SPORT0_MTCS0 0xFFC00840 /* SPORT0 Multi-Channel Transmit Select Register 0 */
+#define SPORT0_MTCS1 0xFFC00844 /* SPORT0 Multi-Channel Transmit Select Register 1 */
+#define SPORT0_MTCS2 0xFFC00848 /* SPORT0 Multi-Channel Transmit Select Register 2 */
+#define SPORT0_MTCS3 0xFFC0084C /* SPORT0 Multi-Channel Transmit Select Register 3 */
+#define SPORT0_MRCS0 0xFFC00850 /* SPORT0 Multi-Channel Receive Select Register 0 */
+#define SPORT0_MRCS1 0xFFC00854 /* SPORT0 Multi-Channel Receive Select Register 1 */
+#define SPORT0_MRCS2 0xFFC00858 /* SPORT0 Multi-Channel Receive Select Register 2 */
+#define SPORT0_MRCS3 0xFFC0085C /* SPORT0 Multi-Channel Receive Select Register 3 */
+
+/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
+#define SPORT1_TCR1 0xFFC00900 /* SPORT1 Transmit Configuration 1 Register */
+#define SPORT1_TCR2 0xFFC00904 /* SPORT1 Transmit Configuration 2 Register */
+#define SPORT1_TCLKDIV 0xFFC00908 /* SPORT1 Transmit Clock Divider */
+#define SPORT1_TFSDIV 0xFFC0090C /* SPORT1 Transmit Frame Sync Divider */
+#define SPORT1_TX 0xFFC00910 /* SPORT1 TX Data Register */
+#define SPORT1_RX 0xFFC00918 /* SPORT1 RX Data Register */
+#define SPORT1_RCR1 0xFFC00920 /* SPORT1 Transmit Configuration 1 Register */
+#define SPORT1_RCR2 0xFFC00924 /* SPORT1 Transmit Configuration 2 Register */
+#define SPORT1_RCLKDIV 0xFFC00928 /* SPORT1 Receive Clock Divider */
+#define SPORT1_RFSDIV 0xFFC0092C /* SPORT1 Receive Frame Sync Divider */
+#define SPORT1_STAT 0xFFC00930 /* SPORT1 Status Register */
+#define SPORT1_CHNL 0xFFC00934 /* SPORT1 Current Channel Register */
+#define SPORT1_MCMC1 0xFFC00938 /* SPORT1 Multi-Channel Configuration Register 1 */
+#define SPORT1_MCMC2 0xFFC0093C /* SPORT1 Multi-Channel Configuration Register 2 */
+#define SPORT1_MTCS0 0xFFC00940 /* SPORT1 Multi-Channel Transmit Select Register 0 */
+#define SPORT1_MTCS1 0xFFC00944 /* SPORT1 Multi-Channel Transmit Select Register 1 */
+#define SPORT1_MTCS2 0xFFC00948 /* SPORT1 Multi-Channel Transmit Select Register 2 */
+#define SPORT1_MTCS3 0xFFC0094C /* SPORT1 Multi-Channel Transmit Select Register 3 */
+#define SPORT1_MRCS0 0xFFC00950 /* SPORT1 Multi-Channel Receive Select Register 0 */
+#define SPORT1_MRCS1 0xFFC00954 /* SPORT1 Multi-Channel Receive Select Register 1 */
+#define SPORT1_MRCS2 0xFFC00958 /* SPORT1 Multi-Channel Receive Select Register 2 */
+#define SPORT1_MRCS3 0xFFC0095C /* SPORT1 Multi-Channel Receive Select Register 3 */
+
+/* External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
+#define EBIU_AMGCTL 0xFFC00A00 /* Asynchronous Memory Global Control Register */
+#define EBIU_AMBCTL0 0xFFC00A04 /* Asynchronous Memory Bank Control Register 0 */
+#define EBIU_AMBCTL1 0xFFC00A08 /* Asynchronous Memory Bank Control Register 1 */
+#define EBIU_SDGCTL 0xFFC00A10 /* SDRAM Global Control Register */
+#define EBIU_SDBCTL 0xFFC00A14 /* SDRAM Bank Control Register */
+#define EBIU_SDRRC 0xFFC00A18 /* SDRAM Refresh Rate Control Register */
+#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */
+
+/* DMA Traffic Control Registers */
+#define DMA_TCPER 0xFFC00B0C /* Traffic Control Periods Register */
+#define DMA_TCCNT 0xFFC00B10 /* Traffic Control Current Counts Register */
+
+/* DMA Controller (0xFFC00C00 - 0xFFC00FFF) */
+#define DMA0_NEXT_DESC_PTR 0xFFC00C00 /* DMA Channel 0 Next Descriptor Pointer Register */
+#define DMA0_START_ADDR 0xFFC00C04 /* DMA Channel 0 Start Address Register */
+#define DMA0_CONFIG 0xFFC00C08 /* DMA Channel 0 Configuration Register */
+#define DMA0_X_COUNT 0xFFC00C10 /* DMA Channel 0 X Count Register */
+#define DMA0_X_MODIFY 0xFFC00C14 /* DMA Channel 0 X Modify Register */
+#define DMA0_Y_COUNT 0xFFC00C18 /* DMA Channel 0 Y Count Register */
+#define DMA0_Y_MODIFY 0xFFC00C1C /* DMA Channel 0 Y Modify Register */
+#define DMA0_CURR_DESC_PTR 0xFFC00C20 /* DMA Channel 0 Current Descriptor Pointer Register */
+#define DMA0_CURR_ADDR 0xFFC00C24 /* DMA Channel 0 Current Address Register */
+#define DMA0_IRQ_STATUS 0xFFC00C28 /* DMA Channel 0 Interrupt/Status Register */
+#define DMA0_PERIPHERAL_MAP 0xFFC00C2C /* DMA Channel 0 Peripheral Map Register */
+#define DMA0_CURR_X_COUNT 0xFFC00C30 /* DMA Channel 0 Current X Count Register */
+#define DMA0_CURR_Y_COUNT 0xFFC00C38 /* DMA Channel 0 Current Y Count Register */
+
+#define DMA1_NEXT_DESC_PTR 0xFFC00C40 /* DMA Channel 1 Next Descriptor Pointer Register */
+#define DMA1_START_ADDR 0xFFC00C44 /* DMA Channel 1 Start Address Register */
+#define DMA1_CONFIG 0xFFC00C48 /* DMA Channel 1 Configuration Register */
+#define DMA1_X_COUNT 0xFFC00C50 /* DMA Channel 1 X Count Register */
+#define DMA1_X_MODIFY 0xFFC00C54 /* DMA Channel 1 X Modify Register */
+#define DMA1_Y_COUNT 0xFFC00C58 /* DMA Channel 1 Y Count Register */
+#define DMA1_Y_MODIFY 0xFFC00C5C /* DMA Channel 1 Y Modify Register */
+#define DMA1_CURR_DESC_PTR 0xFFC00C60 /* DMA Channel 1 Current Descriptor Pointer Register */
+#define DMA1_CURR_ADDR 0xFFC00C64 /* DMA Channel 1 Current Address Register */
+#define DMA1_IRQ_STATUS 0xFFC00C68 /* DMA Channel 1 Interrupt/Status Register */
+#define DMA1_PERIPHERAL_MAP 0xFFC00C6C /* DMA Channel 1 Peripheral Map Register */
+#define DMA1_CURR_X_COUNT 0xFFC00C70 /* DMA Channel 1 Current X Count Register */
+#define DMA1_CURR_Y_COUNT 0xFFC00C78 /* DMA Channel 1 Current Y Count Register */
+
+#define DMA2_NEXT_DESC_PTR 0xFFC00C80 /* DMA Channel 2 Next Descriptor Pointer Register */
+#define DMA2_START_ADDR 0xFFC00C84 /* DMA Channel 2 Start Address Register */
+#define DMA2_CONFIG 0xFFC00C88 /* DMA Channel 2 Configuration Register */
+#define DMA2_X_COUNT 0xFFC00C90 /* DMA Channel 2 X Count Register */
+#define DMA2_X_MODIFY 0xFFC00C94 /* DMA Channel 2 X Modify Register */
+#define DMA2_Y_COUNT 0xFFC00C98 /* DMA Channel 2 Y Count Register */
+#define DMA2_Y_MODIFY 0xFFC00C9C /* DMA Channel 2 Y Modify Register */
+#define DMA2_CURR_DESC_PTR 0xFFC00CA0 /* DMA Channel 2 Current Descriptor Pointer Register */
+#define DMA2_CURR_ADDR 0xFFC00CA4 /* DMA Channel 2 Current Address Register */
+#define DMA2_IRQ_STATUS 0xFFC00CA8 /* DMA Channel 2 Interrupt/Status Register */
+#define DMA2_PERIPHERAL_MAP 0xFFC00CAC /* DMA Channel 2 Peripheral Map Register */
+#define DMA2_CURR_X_COUNT 0xFFC00CB0 /* DMA Channel 2 Current X Count Register */
+#define DMA2_CURR_Y_COUNT 0xFFC00CB8 /* DMA Channel 2 Current Y Count Register */
+
+#define DMA3_NEXT_DESC_PTR 0xFFC00CC0 /* DMA Channel 3 Next Descriptor Pointer Register */
+#define DMA3_START_ADDR 0xFFC00CC4 /* DMA Channel 3 Start Address Register */
+#define DMA3_CONFIG 0xFFC00CC8 /* DMA Channel 3 Configuration Register */
+#define DMA3_X_COUNT 0xFFC00CD0 /* DMA Channel 3 X Count Register */
+#define DMA3_X_MODIFY 0xFFC00CD4 /* DMA Channel 3 X Modify Register */
+#define DMA3_Y_COUNT 0xFFC00CD8 /* DMA Channel 3 Y Count Register */
+#define DMA3_Y_MODIFY 0xFFC00CDC /* DMA Channel 3 Y Modify Register */
+#define DMA3_CURR_DESC_PTR 0xFFC00CE0 /* DMA Channel 3 Current Descriptor Pointer Register */
+#define DMA3_CURR_ADDR 0xFFC00CE4 /* DMA Channel 3 Current Address Register */
+#define DMA3_IRQ_STATUS 0xFFC00CE8 /* DMA Channel 3 Interrupt/Status Register */
+#define DMA3_PERIPHERAL_MAP 0xFFC00CEC /* DMA Channel 3 Peripheral Map Register */
+#define DMA3_CURR_X_COUNT 0xFFC00CF0 /* DMA Channel 3 Current X Count Register */
+#define DMA3_CURR_Y_COUNT 0xFFC00CF8 /* DMA Channel 3 Current Y Count Register */
+
+#define DMA4_NEXT_DESC_PTR 0xFFC00D00 /* DMA Channel 4 Next Descriptor Pointer Register */
+#define DMA4_START_ADDR 0xFFC00D04 /* DMA Channel 4 Start Address Register */
+#define DMA4_CONFIG 0xFFC00D08 /* DMA Channel 4 Configuration Register */
+#define DMA4_X_COUNT 0xFFC00D10 /* DMA Channel 4 X Count Register */
+#define DMA4_X_MODIFY 0xFFC00D14 /* DMA Channel 4 X Modify Register */
+#define DMA4_Y_COUNT 0xFFC00D18 /* DMA Channel 4 Y Count Register */
+#define DMA4_Y_MODIFY 0xFFC00D1C /* DMA Channel 4 Y Modify Register */
+#define DMA4_CURR_DESC_PTR 0xFFC00D20 /* DMA Channel 4 Current Descriptor Pointer Register */
+#define DMA4_CURR_ADDR 0xFFC00D24 /* DMA Channel 4 Current Address Register */
+#define DMA4_IRQ_STATUS 0xFFC00D28 /* DMA Channel 4 Interrupt/Status Register */
+#define DMA4_PERIPHERAL_MAP 0xFFC00D2C /* DMA Channel 4 Peripheral Map Register */
+#define DMA4_CURR_X_COUNT 0xFFC00D30 /* DMA Channel 4 Current X Count Register */
+#define DMA4_CURR_Y_COUNT 0xFFC00D38 /* DMA Channel 4 Current Y Count Register */
+
+#define DMA5_NEXT_DESC_PTR 0xFFC00D40 /* DMA Channel 5 Next Descriptor Pointer Register */
+#define DMA5_START_ADDR 0xFFC00D44 /* DMA Channel 5 Start Address Register */
+#define DMA5_CONFIG 0xFFC00D48 /* DMA Channel 5 Configuration Register */
+#define DMA5_X_COUNT 0xFFC00D50 /* DMA Channel 5 X Count Register */
+#define DMA5_X_MODIFY 0xFFC00D54 /* DMA Channel 5 X Modify Register */
+#define DMA5_Y_COUNT 0xFFC00D58 /* DMA Channel 5 Y Count Register */
+#define DMA5_Y_MODIFY 0xFFC00D5C /* DMA Channel 5 Y Modify Register */
+#define DMA5_CURR_DESC_PTR 0xFFC00D60 /* DMA Channel 5 Current Descriptor Pointer Register */
+#define DMA5_CURR_ADDR 0xFFC00D64 /* DMA Channel 5 Current Address Register */
+#define DMA5_IRQ_STATUS 0xFFC00D68 /* DMA Channel 5 Interrupt/Status Register */
+#define DMA5_PERIPHERAL_MAP 0xFFC00D6C /* DMA Channel 5 Peripheral Map Register */
+#define DMA5_CURR_X_COUNT 0xFFC00D70 /* DMA Channel 5 Current X Count Register */
+#define DMA5_CURR_Y_COUNT 0xFFC00D78 /* DMA Channel 5 Current Y Count Register */
+
+#define DMA6_NEXT_DESC_PTR 0xFFC00D80 /* DMA Channel 6 Next Descriptor Pointer Register */
+#define DMA6_START_ADDR 0xFFC00D84 /* DMA Channel 6 Start Address Register */
+#define DMA6_CONFIG 0xFFC00D88 /* DMA Channel 6 Configuration Register */
+#define DMA6_X_COUNT 0xFFC00D90 /* DMA Channel 6 X Count Register */
+#define DMA6_X_MODIFY 0xFFC00D94 /* DMA Channel 6 X Modify Register */
+#define DMA6_Y_COUNT 0xFFC00D98 /* DMA Channel 6 Y Count Register */
+#define DMA6_Y_MODIFY 0xFFC00D9C /* DMA Channel 6 Y Modify Register */
+#define DMA6_CURR_DESC_PTR 0xFFC00DA0 /* DMA Channel 6 Current Descriptor Pointer Register */
+#define DMA6_CURR_ADDR 0xFFC00DA4 /* DMA Channel 6 Current Address Register */
+#define DMA6_IRQ_STATUS 0xFFC00DA8 /* DMA Channel 6 Interrupt/Status Register */
+#define DMA6_PERIPHERAL_MAP 0xFFC00DAC /* DMA Channel 6 Peripheral Map Register */
+#define DMA6_CURR_X_COUNT 0xFFC00DB0 /* DMA Channel 6 Current X Count Register */
+#define DMA6_CURR_Y_COUNT 0xFFC00DB8 /* DMA Channel 6 Current Y Count Register */
+
+#define DMA7_NEXT_DESC_PTR 0xFFC00DC0 /* DMA Channel 7 Next Descriptor Pointer Register */
+#define DMA7_START_ADDR 0xFFC00DC4 /* DMA Channel 7 Start Address Register */
+#define DMA7_CONFIG 0xFFC00DC8 /* DMA Channel 7 Configuration Register */
+#define DMA7_X_COUNT 0xFFC00DD0 /* DMA Channel 7 X Count Register */
+#define DMA7_X_MODIFY 0xFFC00DD4 /* DMA Channel 7 X Modify Register */
+#define DMA7_Y_COUNT 0xFFC00DD8 /* DMA Channel 7 Y Count Register */
+#define DMA7_Y_MODIFY 0xFFC00DDC /* DMA Channel 7 Y Modify Register */
+#define DMA7_CURR_DESC_PTR 0xFFC00DE0 /* DMA Channel 7 Current Descriptor Pointer Register */
+#define DMA7_CURR_ADDR 0xFFC00DE4 /* DMA Channel 7 Current Address Register */
+#define DMA7_IRQ_STATUS 0xFFC00DE8 /* DMA Channel 7 Interrupt/Status Register */
+#define DMA7_PERIPHERAL_MAP 0xFFC00DEC /* DMA Channel 7 Peripheral Map Register */
+#define DMA7_CURR_X_COUNT 0xFFC00DF0 /* DMA Channel 7 Current X Count Register */
+#define DMA7_CURR_Y_COUNT 0xFFC00DF8 /* DMA Channel 7 Current Y Count Register */
+
+#define DMA8_NEXT_DESC_PTR 0xFFC00E00 /* DMA Channel 8 Next Descriptor Pointer Register */
+#define DMA8_START_ADDR 0xFFC00E04 /* DMA Channel 8 Start Address Register */
+#define DMA8_CONFIG 0xFFC00E08 /* DMA Channel 8 Configuration Register */
+#define DMA8_X_COUNT 0xFFC00E10 /* DMA Channel 8 X Count Register */
+#define DMA8_X_MODIFY 0xFFC00E14 /* DMA Channel 8 X Modify Register */
+#define DMA8_Y_COUNT 0xFFC00E18 /* DMA Channel 8 Y Count Register */
+#define DMA8_Y_MODIFY 0xFFC00E1C /* DMA Channel 8 Y Modify Register */
+#define DMA8_CURR_DESC_PTR 0xFFC00E20 /* DMA Channel 8 Current Descriptor Pointer Register */
+#define DMA8_CURR_ADDR 0xFFC00E24 /* DMA Channel 8 Current Address Register */
+#define DMA8_IRQ_STATUS 0xFFC00E28 /* DMA Channel 8 Interrupt/Status Register */
+#define DMA8_PERIPHERAL_MAP 0xFFC00E2C /* DMA Channel 8 Peripheral Map Register */
+#define DMA8_CURR_X_COUNT 0xFFC00E30 /* DMA Channel 8 Current X Count Register */
+#define DMA8_CURR_Y_COUNT 0xFFC00E38 /* DMA Channel 8 Current Y Count Register */
+
+#define DMA9_NEXT_DESC_PTR 0xFFC00E40 /* DMA Channel 9 Next Descriptor Pointer Register */
+#define DMA9_START_ADDR 0xFFC00E44 /* DMA Channel 9 Start Address Register */
+#define DMA9_CONFIG 0xFFC00E48 /* DMA Channel 9 Configuration Register */
+#define DMA9_X_COUNT 0xFFC00E50 /* DMA Channel 9 X Count Register */
+#define DMA9_X_MODIFY 0xFFC00E54 /* DMA Channel 9 X Modify Register */
+#define DMA9_Y_COUNT 0xFFC00E58 /* DMA Channel 9 Y Count Register */
+#define DMA9_Y_MODIFY 0xFFC00E5C /* DMA Channel 9 Y Modify Register */
+#define DMA9_CURR_DESC_PTR 0xFFC00E60 /* DMA Channel 9 Current Descriptor Pointer Register */
+#define DMA9_CURR_ADDR 0xFFC00E64 /* DMA Channel 9 Current Address Register */
+#define DMA9_IRQ_STATUS 0xFFC00E68 /* DMA Channel 9 Interrupt/Status Register */
+#define DMA9_PERIPHERAL_MAP 0xFFC00E6C /* DMA Channel 9 Peripheral Map Register */
+#define DMA9_CURR_X_COUNT 0xFFC00E70 /* DMA Channel 9 Current X Count Register */
+#define DMA9_CURR_Y_COUNT 0xFFC00E78 /* DMA Channel 9 Current Y Count Register */
+
+#define DMA10_NEXT_DESC_PTR 0xFFC00E80 /* DMA Channel 10 Next Descriptor Pointer Register */
+#define DMA10_START_ADDR 0xFFC00E84 /* DMA Channel 10 Start Address Register */
+#define DMA10_CONFIG 0xFFC00E88 /* DMA Channel 10 Configuration Register */
+#define DMA10_X_COUNT 0xFFC00E90 /* DMA Channel 10 X Count Register */
+#define DMA10_X_MODIFY 0xFFC00E94 /* DMA Channel 10 X Modify Register */
+#define DMA10_Y_COUNT 0xFFC00E98 /* DMA Channel 10 Y Count Register */
+#define DMA10_Y_MODIFY 0xFFC00E9C /* DMA Channel 10 Y Modify Register */
+#define DMA10_CURR_DESC_PTR 0xFFC00EA0 /* DMA Channel 10 Current Descriptor Pointer Register */
+#define DMA10_CURR_ADDR 0xFFC00EA4 /* DMA Channel 10 Current Address Register */
+#define DMA10_IRQ_STATUS 0xFFC00EA8 /* DMA Channel 10 Interrupt/Status Register */
+#define DMA10_PERIPHERAL_MAP 0xFFC00EAC /* DMA Channel 10 Peripheral Map Register */
+#define DMA10_CURR_X_COUNT 0xFFC00EB0 /* DMA Channel 10 Current X Count Register */
+#define DMA10_CURR_Y_COUNT 0xFFC00EB8 /* DMA Channel 10 Current Y Count Register */
+
+#define DMA11_NEXT_DESC_PTR 0xFFC00EC0 /* DMA Channel 11 Next Descriptor Pointer Register */
+#define DMA11_START_ADDR 0xFFC00EC4 /* DMA Channel 11 Start Address Register */
+#define DMA11_CONFIG 0xFFC00EC8 /* DMA Channel 11 Configuration Register */
+#define DMA11_X_COUNT 0xFFC00ED0 /* DMA Channel 11 X Count Register */
+#define DMA11_X_MODIFY 0xFFC00ED4 /* DMA Channel 11 X Modify Register */
+#define DMA11_Y_COUNT 0xFFC00ED8 /* DMA Channel 11 Y Count Register */
+#define DMA11_Y_MODIFY 0xFFC00EDC /* DMA Channel 11 Y Modify Register */
+#define DMA11_CURR_DESC_PTR 0xFFC00EE0 /* DMA Channel 11 Current Descriptor Pointer Register */
+#define DMA11_CURR_ADDR 0xFFC00EE4 /* DMA Channel 11 Current Address Register */
+#define DMA11_IRQ_STATUS 0xFFC00EE8 /* DMA Channel 11 Interrupt/Status Register */
+#define DMA11_PERIPHERAL_MAP 0xFFC00EEC /* DMA Channel 11 Peripheral Map Register */
+#define DMA11_CURR_X_COUNT 0xFFC00EF0 /* DMA Channel 11 Current X Count Register */
+#define DMA11_CURR_Y_COUNT 0xFFC00EF8 /* DMA Channel 11 Current Y Count Register */
+
+#define MDMA_D0_NEXT_DESC_PTR 0xFFC00F00 /* MemDMA Stream 0 Destination Next Descriptor Pointer Register */
+#define MDMA_D0_START_ADDR 0xFFC00F04 /* MemDMA Stream 0 Destination Start Address Register */
+#define MDMA_D0_CONFIG 0xFFC00F08 /* MemDMA Stream 0 Destination Configuration Register */
+#define MDMA_D0_X_COUNT 0xFFC00F10 /* MemDMA Stream 0 Destination X Count Register */
+#define MDMA_D0_X_MODIFY 0xFFC00F14 /* MemDMA Stream 0 Destination X Modify Register */
+#define MDMA_D0_Y_COUNT 0xFFC00F18 /* MemDMA Stream 0 Destination Y Count Register */
+#define MDMA_D0_Y_MODIFY 0xFFC00F1C /* MemDMA Stream 0 Destination Y Modify Register */
+#define MDMA_D0_CURR_DESC_PTR 0xFFC00F20 /* MemDMA Stream 0 Destination Current Descriptor Pointer Register */
+#define MDMA_D0_CURR_ADDR 0xFFC00F24 /* MemDMA Stream 0 Destination Current Address Register */
+#define MDMA_D0_IRQ_STATUS 0xFFC00F28 /* MemDMA Stream 0 Destination Interrupt/Status Register */
+#define MDMA_D0_PERIPHERAL_MAP 0xFFC00F2C /* MemDMA Stream 0 Destination Peripheral Map Register */
+#define MDMA_D0_CURR_X_COUNT 0xFFC00F30 /* MemDMA Stream 0 Destination Current X Count Register */
+#define MDMA_D0_CURR_Y_COUNT 0xFFC00F38 /* MemDMA Stream 0 Destination Current Y Count Register */
+
+#define MDMA_S0_NEXT_DESC_PTR 0xFFC00F40 /* MemDMA Stream 0 Source Next Descriptor Pointer Register */
+#define MDMA_S0_START_ADDR 0xFFC00F44 /* MemDMA Stream 0 Source Start Address Register */
+#define MDMA_S0_CONFIG 0xFFC00F48 /* MemDMA Stream 0 Source Configuration Register */
+#define MDMA_S0_X_COUNT 0xFFC00F50 /* MemDMA Stream 0 Source X Count Register */
+#define MDMA_S0_X_MODIFY 0xFFC00F54 /* MemDMA Stream 0 Source X Modify Register */
+#define MDMA_S0_Y_COUNT 0xFFC00F58 /* MemDMA Stream 0 Source Y Count Register */
+#define MDMA_S0_Y_MODIFY 0xFFC00F5C /* MemDMA Stream 0 Source Y Modify Register */
+#define MDMA_S0_CURR_DESC_PTR 0xFFC00F60 /* MemDMA Stream 0 Source Current Descriptor Pointer Register */
+#define MDMA_S0_CURR_ADDR 0xFFC00F64 /* MemDMA Stream 0 Source Current Address Register */
+#define MDMA_S0_IRQ_STATUS 0xFFC00F68 /* MemDMA Stream 0 Source Interrupt/Status Register */
+#define MDMA_S0_PERIPHERAL_MAP 0xFFC00F6C /* MemDMA Stream 0 Source Peripheral Map Register */
+#define MDMA_S0_CURR_X_COUNT 0xFFC00F70 /* MemDMA Stream 0 Source Current X Count Register */
+#define MDMA_S0_CURR_Y_COUNT 0xFFC00F78 /* MemDMA Stream 0 Source Current Y Count Register */
+
+#define MDMA_D1_NEXT_DESC_PTR 0xFFC00F80 /* MemDMA Stream 1 Destination Next Descriptor Pointer Register */
+#define MDMA_D1_START_ADDR 0xFFC00F84 /* MemDMA Stream 1 Destination Start Address Register */
+#define MDMA_D1_CONFIG 0xFFC00F88 /* MemDMA Stream 1 Destination Configuration Register */
+#define MDMA_D1_X_COUNT 0xFFC00F90 /* MemDMA Stream 1 Destination X Count Register */
+#define MDMA_D1_X_MODIFY 0xFFC00F94 /* MemDMA Stream 1 Destination X Modify Register */
+#define MDMA_D1_Y_COUNT 0xFFC00F98 /* MemDMA Stream 1 Destination Y Count Register */
+#define MDMA_D1_Y_MODIFY 0xFFC00F9C /* MemDMA Stream 1 Destination Y Modify Register */
+#define MDMA_D1_CURR_DESC_PTR 0xFFC00FA0 /* MemDMA Stream 1 Destination Current Descriptor Pointer Register */
+#define MDMA_D1_CURR_ADDR 0xFFC00FA4 /* MemDMA Stream 1 Destination Current Address Register */
+#define MDMA_D1_IRQ_STATUS 0xFFC00FA8 /* MemDMA Stream 1 Destination Interrupt/Status Register */
+#define MDMA_D1_PERIPHERAL_MAP 0xFFC00FAC /* MemDMA Stream 1 Destination Peripheral Map Register */
+#define MDMA_D1_CURR_X_COUNT 0xFFC00FB0 /* MemDMA Stream 1 Destination Current X Count Register */
+#define MDMA_D1_CURR_Y_COUNT 0xFFC00FB8 /* MemDMA Stream 1 Destination Current Y Count Register */
+
+#define MDMA_S1_NEXT_DESC_PTR 0xFFC00FC0 /* MemDMA Stream 1 Source Next Descriptor Pointer Register */
+#define MDMA_S1_START_ADDR 0xFFC00FC4 /* MemDMA Stream 1 Source Start Address Register */
+#define MDMA_S1_CONFIG 0xFFC00FC8 /* MemDMA Stream 1 Source Configuration Register */
+#define MDMA_S1_X_COUNT 0xFFC00FD0 /* MemDMA Stream 1 Source X Count Register */
+#define MDMA_S1_X_MODIFY 0xFFC00FD4 /* MemDMA Stream 1 Source X Modify Register */
+#define MDMA_S1_Y_COUNT 0xFFC00FD8 /* MemDMA Stream 1 Source Y Count Register */
+#define MDMA_S1_Y_MODIFY 0xFFC00FDC /* MemDMA Stream 1 Source Y Modify Register */
+#define MDMA_S1_CURR_DESC_PTR 0xFFC00FE0 /* MemDMA Stream 1 Source Current Descriptor Pointer Register */
+#define MDMA_S1_CURR_ADDR 0xFFC00FE4 /* MemDMA Stream 1 Source Current Address Register */
+#define MDMA_S1_IRQ_STATUS 0xFFC00FE8 /* MemDMA Stream 1 Source Interrupt/Status Register */
+#define MDMA_S1_PERIPHERAL_MAP 0xFFC00FEC /* MemDMA Stream 1 Source Peripheral Map Register */
+#define MDMA_S1_CURR_X_COUNT 0xFFC00FF0 /* MemDMA Stream 1 Source Current X Count Register */
+#define MDMA_S1_CURR_Y_COUNT 0xFFC00FF8 /* MemDMA Stream 1 Source Current Y Count Register */
+
+/* Parallel Peripheral Interface (0xFFC01000 - 0xFFC010FF) */
+#define PPI_CONTROL 0xFFC01000 /* PPI Control Register */
+#define PPI_STATUS 0xFFC01004 /* PPI Status Register */
+#define PPI_COUNT 0xFFC01008 /* PPI Transfer Count Register */
+#define PPI_DELAY 0xFFC0100C /* PPI Delay Count Register */
+#define PPI_FRAME 0xFFC01010 /* PPI Frame Length Register */
+
+/* Two-Wire Interface (0xFFC01400 - 0xFFC014FF) */
+#define TWI_CLKDIV 0xFFC01400 /* Serial Clock Divider Register */
+#define TWI_CONTROL 0xFFC01404 /* TWI Control Register */
+#define TWI_SLAVE_CTL 0xFFC01408 /* Slave Mode Control Register */
+#define TWI_SLAVE_STAT 0xFFC0140C /* Slave Mode Status Register */
+#define TWI_SLAVE_ADDR 0xFFC01410 /* Slave Mode Address Register */
+#define TWI_MASTER_CTL 0xFFC01414 /* Master Mode Control Register */
+#define TWI_MASTER_STAT 0xFFC01418 /* Master Mode Status Register */
+#define TWI_MASTER_ADDR 0xFFC0141C /* Master Mode Address Register */
+#define TWI_INT_STAT 0xFFC01420 /* TWI Interrupt Status Register */
+#define TWI_INT_MASK 0xFFC01424 /* TWI Master Interrupt Mask Register */
+#define TWI_FIFO_CTL 0xFFC01428 /* FIFO Control Register */
+#define TWI_FIFO_STAT 0xFFC0142C /* FIFO Status Register */
+#define TWI_XMT_DATA8 0xFFC01480 /* FIFO Transmit Data Single Byte Register */
+#define TWI_XMT_DATA16 0xFFC01484 /* FIFO Transmit Data Double Byte Register */
+#define TWI_RCV_DATA8 0xFFC01488 /* FIFO Receive Data Single Byte Register */
+#define TWI_RCV_DATA16 0xFFC0148C /* FIFO Receive Data Double Byte Register */
+
+/* General Purpose I/O Port G (0xFFC01500 - 0xFFC015FF) */
+#define PORTGIO 0xFFC01500 /* Port G I/O Pin State Specify Register */
+#define PORTGIO_CLEAR 0xFFC01504 /* Port G I/O Peripheral Interrupt Clear Register */
+#define PORTGIO_SET 0xFFC01508 /* Port G I/O Peripheral Interrupt Set Register */
+#define PORTGIO_TOGGLE 0xFFC0150C /* Port G I/O Pin State Toggle Register */
+#define PORTGIO_MASKA 0xFFC01510 /* Port G I/O Mask State Specify Interrupt A Register */
+#define PORTGIO_MASKA_CLEAR 0xFFC01514 /* Port G I/O Mask Disable Interrupt A Register */
+#define PORTGIO_MASKA_SET 0xFFC01518 /* Port G I/O Mask Enable Interrupt A Register */
+#define PORTGIO_MASKA_TOGGLE 0xFFC0151C /* Port G I/O Mask Toggle Enable Interrupt A Register */
+#define PORTGIO_MASKB 0xFFC01520 /* Port G I/O Mask State Specify Interrupt B Register */
+#define PORTGIO_MASKB_CLEAR 0xFFC01524 /* Port G I/O Mask Disable Interrupt B Register */
+#define PORTGIO_MASKB_SET 0xFFC01528 /* Port G I/O Mask Enable Interrupt B Register */
+#define PORTGIO_MASKB_TOGGLE 0xFFC0152C /* Port G I/O Mask Toggle Enable Interrupt B Register */
+#define PORTGIO_DIR 0xFFC01530 /* Port G I/O Direction Register */
+#define PORTGIO_POLAR 0xFFC01534 /* Port G I/O Source Polarity Register */
+#define PORTGIO_EDGE 0xFFC01538 /* Port G I/O Source Sensitivity Register */
+#define PORTGIO_BOTH 0xFFC0153C /* Port G I/O Set on BOTH Edges Register */
+#define PORTGIO_INEN 0xFFC01540 /* Port G I/O Input Enable Register */
+
+/* General Purpose I/O Port H (0xFFC01700 - 0xFFC017FF) */
+#define PORTHIO 0xFFC01700 /* Port H I/O Pin State Specify Register */
+#define PORTHIO_CLEAR 0xFFC01704 /* Port H I/O Peripheral Interrupt Clear Register */
+#define PORTHIO_SET 0xFFC01708 /* Port H I/O Peripheral Interrupt Set Register */
+#define PORTHIO_TOGGLE 0xFFC0170C /* Port H I/O Pin State Toggle Register */
+#define PORTHIO_MASKA 0xFFC01710 /* Port H I/O Mask State Specify Interrupt A Register */
+#define PORTHIO_MASKA_CLEAR 0xFFC01714 /* Port H I/O Mask Disable Interrupt A Register */
+#define PORTHIO_MASKA_SET 0xFFC01718 /* Port H I/O Mask Enable Interrupt A Register */
+#define PORTHIO_MASKA_TOGGLE 0xFFC0171C /* Port H I/O Mask Toggle Enable Interrupt A Register */
+#define PORTHIO_MASKB 0xFFC01720 /* Port H I/O Mask State Specify Interrupt B Register */
+#define PORTHIO_MASKB_CLEAR 0xFFC01724 /* Port H I/O Mask Disable Interrupt B Register */
+#define PORTHIO_MASKB_SET 0xFFC01728 /* Port H I/O Mask Enable Interrupt B Register */
+#define PORTHIO_MASKB_TOGGLE 0xFFC0172C /* Port H I/O Mask Toggle Enable Interrupt B Register */
+#define PORTHIO_DIR 0xFFC01730 /* Port H I/O Direction Register */
+#define PORTHIO_POLAR 0xFFC01734 /* Port H I/O Source Polarity Register */
+#define PORTHIO_EDGE 0xFFC01738 /* Port H I/O Source Sensitivity Register */
+#define PORTHIO_BOTH 0xFFC0173C /* Port H I/O Set on BOTH Edges Register */
+#define PORTHIO_INEN 0xFFC01740 /* Port H I/O Input Enable Register */
+
+/* UART1 Controller (0xFFC02000 - 0xFFC020FF) */
+#define UART1_THR 0xFFC02000 /* Transmit Holding register */
+#define UART1_RBR 0xFFC02000 /* Receive Buffer register */
+#define UART1_DLL 0xFFC02000 /* Divisor Latch (Low-Byte) */
+#define UART1_IER 0xFFC02004 /* Interrupt Enable Register */
+#define UART1_DLH 0xFFC02004 /* Divisor Latch (High-Byte) */
+#define UART1_IIR 0xFFC02008 /* Interrupt Identification Register */
+#define UART1_LCR 0xFFC0200C /* Line Control Register */
+#define UART1_MCR 0xFFC02010 /* Modem Control Register */
+#define UART1_LSR 0xFFC02014 /* Line Status Register */
+#define UART1_MSR 0xFFC02018 /* Modem Status Register */
+#define UART1_SCR 0xFFC0201C /* SCR Scratch Register */
+#define UART1_GCTL 0xFFC02024 /* Global Control Register */
+
+/* CAN Controller (0xFFC02A00 - 0xFFC02FFF) */
+/* For Mailboxes 0-15 */
+#define CAN_MC1 0xFFC02A00 /* Mailbox config reg 1 */
+#define CAN_MD1 0xFFC02A04 /* Mailbox direction reg 1 */
+#define CAN_TRS1 0xFFC02A08 /* Transmit Request Set reg 1 */
+#define CAN_TRR1 0xFFC02A0C /* Transmit Request Reset reg 1 */
+#define CAN_TA1 0xFFC02A10 /* Transmit Acknowledge reg 1 */
+#define CAN_AA1 0xFFC02A14 /* Transmit Abort Acknowledge reg 1 */
+#define CAN_RMP1 0xFFC02A18 /* Receive Message Pending reg 1 */
+#define CAN_RML1 0xFFC02A1C /* Receive Message Lost reg 1 */
+#define CAN_MBTIF1 0xFFC02A20 /* Mailbox Transmit Interrupt Flag reg 1 */
+#define CAN_MBRIF1 0xFFC02A24 /* Mailbox Receive Interrupt Flag reg 1 */
+#define CAN_MBIM1 0xFFC02A28 /* Mailbox Interrupt Mask reg 1 */
+#define CAN_RFH1 0xFFC02A2C /* Remote Frame Handling reg 1 */
+#define CAN_OPSS1 0xFFC02A30 /* Overwrite Protection Single Shot Xmit reg 1 */
+
+/* For Mailboxes 16-31 */
+#define CAN_MC2 0xFFC02A40 /* Mailbox config reg 2 */
+#define CAN_MD2 0xFFC02A44 /* Mailbox direction reg 2 */
+#define CAN_TRS2 0xFFC02A48 /* Transmit Request Set reg 2 */
+#define CAN_TRR2 0xFFC02A4C /* Transmit Request Reset reg 2 */
+#define CAN_TA2 0xFFC02A50 /* Transmit Acknowledge reg 2 */
+#define CAN_AA2 0xFFC02A54 /* Transmit Abort Acknowledge reg 2 */
+#define CAN_RMP2 0xFFC02A58 /* Receive Message Pending reg 2 */
+#define CAN_RML2 0xFFC02A5C /* Receive Message Lost reg 2 */
+#define CAN_MBTIF2 0xFFC02A60 /* Mailbox Transmit Interrupt Flag reg 2 */
+#define CAN_MBRIF2 0xFFC02A64 /* Mailbox Receive Interrupt Flag reg 2 */
+#define CAN_MBIM2 0xFFC02A68 /* Mailbox Interrupt Mask reg 2 */
+#define CAN_RFH2 0xFFC02A6C /* Remote Frame Handling reg 2 */
+#define CAN_OPSS2 0xFFC02A70 /* Overwrite Protection Single Shot Xmit reg 2 */
+
+/* CAN Configuration, Control, and Status Registers */
+#define CAN_CLOCK 0xFFC02A80 /* Bit Timing Configuration register 0 */
+#define CAN_TIMING 0xFFC02A84 /* Bit Timing Configuration register 1 */
+#define CAN_DEBUG 0xFFC02A88 /* Debug Register */
+#define CAN_STATUS 0xFFC02A8C /* Global Status Register */
+#define CAN_CEC 0xFFC02A90 /* Error Counter Register */
+#define CAN_GIS 0xFFC02A94 /* Global Interrupt Status Register */
+#define CAN_GIM 0xFFC02A98 /* Global Interrupt Mask Register */
+#define CAN_GIF 0xFFC02A9C /* Global Interrupt Flag Register */
+#define CAN_CONTROL 0xFFC02AA0 /* Master Control Register */
+#define CAN_INTR 0xFFC02AA4 /* Interrupt Pending Register */
+#define CAN_SFCMVER 0xFFC02AA8 /* Version Code Register */
+#define CAN_MBTD 0xFFC02AAC /* Mailbox Temporary Disable Feature */
+#define CAN_EWR 0xFFC02AB0 /* Programmable Warning Level */
+#define CAN_ESR 0xFFC02AB4 /* Error Status Register */
+#define CAN_UCREG 0xFFC02AC0 /* Universal Counter Register/Capture Register */
+#define CAN_UCCNT 0xFFC02AC4 /* Universal Counter */
+#define CAN_UCRC 0xFFC02AC8 /* Universal Counter Force Reload Register */
+#define CAN_UCCNF 0xFFC02ACC /* Universal Counter Configuration Register */
+
+/* Mailbox Acceptance Masks */
+#define CAN_AM00L 0xFFC02B00 /* Mailbox 0 Low Acceptance Mask */
+#define CAN_AM00H 0xFFC02B04 /* Mailbox 0 High Acceptance Mask */
+#define CAN_AM01L 0xFFC02B08 /* Mailbox 1 Low Acceptance Mask */
+#define CAN_AM01H 0xFFC02B0C /* Mailbox 1 High Acceptance Mask */
+#define CAN_AM02L 0xFFC02B10 /* Mailbox 2 Low Acceptance Mask */
+#define CAN_AM02H 0xFFC02B14 /* Mailbox 2 High Acceptance Mask */
+#define CAN_AM03L 0xFFC02B18 /* Mailbox 3 Low Acceptance Mask */
+#define CAN_AM03H 0xFFC02B1C /* Mailbox 3 High Acceptance Mask */
+#define CAN_AM04L 0xFFC02B20 /* Mailbox 4 Low Acceptance Mask */
+#define CAN_AM04H 0xFFC02B24 /* Mailbox 4 High Acceptance Mask */
+#define CAN_AM05L 0xFFC02B28 /* Mailbox 5 Low Acceptance Mask */
+#define CAN_AM05H 0xFFC02B2C /* Mailbox 5 High Acceptance Mask */
+#define CAN_AM06L 0xFFC02B30 /* Mailbox 6 Low Acceptance Mask */
+#define CAN_AM06H 0xFFC02B34 /* Mailbox 6 High Acceptance Mask */
+#define CAN_AM07L 0xFFC02B38 /* Mailbox 7 Low Acceptance Mask */
+#define CAN_AM07H 0xFFC02B3C /* Mailbox 7 High Acceptance Mask */
+#define CAN_AM08L 0xFFC02B40 /* Mailbox 8 Low Acceptance Mask */
+#define CAN_AM08H 0xFFC02B44 /* Mailbox 8 High Acceptance Mask */
+#define CAN_AM09L 0xFFC02B48 /* Mailbox 9 Low Acceptance Mask */
+#define CAN_AM09H 0xFFC02B4C /* Mailbox 9 High Acceptance Mask */
+#define CAN_AM10L 0xFFC02B50 /* Mailbox 10 Low Acceptance Mask */
+#define CAN_AM10H 0xFFC02B54 /* Mailbox 10 High Acceptance Mask */
+#define CAN_AM11L 0xFFC02B58 /* Mailbox 11 Low Acceptance Mask */
+#define CAN_AM11H 0xFFC02B5C /* Mailbox 11 High Acceptance Mask */
+#define CAN_AM12L 0xFFC02B60 /* Mailbox 12 Low Acceptance Mask */
+#define CAN_AM12H 0xFFC02B64 /* Mailbox 12 High Acceptance Mask */
+#define CAN_AM13L 0xFFC02B68 /* Mailbox 13 Low Acceptance Mask */
+#define CAN_AM13H 0xFFC02B6C /* Mailbox 13 High Acceptance Mask */
+#define CAN_AM14L 0xFFC02B70 /* Mailbox 14 Low Acceptance Mask */
+#define CAN_AM14H 0xFFC02B74 /* Mailbox 14 High Acceptance Mask */
+#define CAN_AM15L 0xFFC02B78 /* Mailbox 15 Low Acceptance Mask */
+#define CAN_AM15H 0xFFC02B7C /* Mailbox 15 High Acceptance Mask */
+
+#define CAN_AM16L 0xFFC02B80 /* Mailbox 16 Low Acceptance Mask */
+#define CAN_AM16H 0xFFC02B84 /* Mailbox 16 High Acceptance Mask */
+#define CAN_AM17L 0xFFC02B88 /* Mailbox 17 Low Acceptance Mask */
+#define CAN_AM17H 0xFFC02B8C /* Mailbox 17 High Acceptance Mask */
+#define CAN_AM18L 0xFFC02B90 /* Mailbox 18 Low Acceptance Mask */
+#define CAN_AM18H 0xFFC02B94 /* Mailbox 18 High Acceptance Mask */
+#define CAN_AM19L 0xFFC02B98 /* Mailbox 19 Low Acceptance Mask */
+#define CAN_AM19H 0xFFC02B9C /* Mailbox 19 High Acceptance Mask */
+#define CAN_AM20L 0xFFC02BA0 /* Mailbox 20 Low Acceptance Mask */
+#define CAN_AM20H 0xFFC02BA4 /* Mailbox 20 High Acceptance Mask */
+#define CAN_AM21L 0xFFC02BA8 /* Mailbox 21 Low Acceptance Mask */
+#define CAN_AM21H 0xFFC02BAC /* Mailbox 21 High Acceptance Mask */
+#define CAN_AM22L 0xFFC02BB0 /* Mailbox 22 Low Acceptance Mask */
+#define CAN_AM22H 0xFFC02BB4 /* Mailbox 22 High Acceptance Mask */
+#define CAN_AM23L 0xFFC02BB8 /* Mailbox 23 Low Acceptance Mask */
+#define CAN_AM23H 0xFFC02BBC /* Mailbox 23 High Acceptance Mask */
+#define CAN_AM24L 0xFFC02BC0 /* Mailbox 24 Low Acceptance Mask */
+#define CAN_AM24H 0xFFC02BC4 /* Mailbox 24 High Acceptance Mask */
+#define CAN_AM25L 0xFFC02BC8 /* Mailbox 25 Low Acceptance Mask */
+#define CAN_AM25H 0xFFC02BCC /* Mailbox 25 High Acceptance Mask */
+#define CAN_AM26L 0xFFC02BD0 /* Mailbox 26 Low Acceptance Mask */
+#define CAN_AM26H 0xFFC02BD4 /* Mailbox 26 High Acceptance Mask */
+#define CAN_AM27L 0xFFC02BD8 /* Mailbox 27 Low Acceptance Mask */
+#define CAN_AM27H 0xFFC02BDC /* Mailbox 27 High Acceptance Mask */
+#define CAN_AM28L 0xFFC02BE0 /* Mailbox 28 Low Acceptance Mask */
+#define CAN_AM28H 0xFFC02BE4 /* Mailbox 28 High Acceptance Mask */
+#define CAN_AM29L 0xFFC02BE8 /* Mailbox 29 Low Acceptance Mask */
+#define CAN_AM29H 0xFFC02BEC /* Mailbox 29 High Acceptance Mask */
+#define CAN_AM30L 0xFFC02BF0 /* Mailbox 30 Low Acceptance Mask */
+#define CAN_AM30H 0xFFC02BF4 /* Mailbox 30 High Acceptance Mask */
+#define CAN_AM31L 0xFFC02BF8 /* Mailbox 31 Low Acceptance Mask */
+#define CAN_AM31H 0xFFC02BFC /* Mailbox 31 High Acceptance Mask */
+
+/* CAN Acceptance Mask Macros */
+#define CAN_AM_L(x) (CAN_AM00L+((x)*0x8))
+#define CAN_AM_H(x) (CAN_AM00H+((x)*0x8))
+
+/* Mailbox Registers */
+#define CAN_MB00_DATA0 0xFFC02C00 /* Mailbox 0 Data Word 0 [15:0] Register */
+#define CAN_MB00_DATA1 0xFFC02C04 /* Mailbox 0 Data Word 1 [31:16] Register */
+#define CAN_MB00_DATA2 0xFFC02C08 /* Mailbox 0 Data Word 2 [47:32] Register */
+#define CAN_MB00_DATA3 0xFFC02C0C /* Mailbox 0 Data Word 3 [63:48] Register */
+#define CAN_MB00_LENGTH 0xFFC02C10 /* Mailbox 0 Data Length Code Register */
+#define CAN_MB00_TIMESTAMP 0xFFC02C14 /* Mailbox 0 Time Stamp Value Register */
+#define CAN_MB00_ID0 0xFFC02C18 /* Mailbox 0 Identifier Low Register */
+#define CAN_MB00_ID1 0xFFC02C1C /* Mailbox 0 Identifier High Register */
+
+#define CAN_MB01_DATA0 0xFFC02C20 /* Mailbox 1 Data Word 0 [15:0] Register */
+#define CAN_MB01_DATA1 0xFFC02C24 /* Mailbox 1 Data Word 1 [31:16] Register */
+#define CAN_MB01_DATA2 0xFFC02C28 /* Mailbox 1 Data Word 2 [47:32] Register */
+#define CAN_MB01_DATA3 0xFFC02C2C /* Mailbox 1 Data Word 3 [63:48] Register */
+#define CAN_MB01_LENGTH 0xFFC02C30 /* Mailbox 1 Data Length Code Register */
+#define CAN_MB01_TIMESTAMP 0xFFC02C34 /* Mailbox 1 Time Stamp Value Register */
+#define CAN_MB01_ID0 0xFFC02C38 /* Mailbox 1 Identifier Low Register */
+#define CAN_MB01_ID1 0xFFC02C3C /* Mailbox 1 Identifier High Register */
+
+#define CAN_MB02_DATA0 0xFFC02C40 /* Mailbox 2 Data Word 0 [15:0] Register */
+#define CAN_MB02_DATA1 0xFFC02C44 /* Mailbox 2 Data Word 1 [31:16] Register */
+#define CAN_MB02_DATA2 0xFFC02C48 /* Mailbox 2 Data Word 2 [47:32] Register */
+#define CAN_MB02_DATA3 0xFFC02C4C /* Mailbox 2 Data Word 3 [63:48] Register */
+#define CAN_MB02_LENGTH 0xFFC02C50 /* Mailbox 2 Data Length Code Register */
+#define CAN_MB02_TIMESTAMP 0xFFC02C54 /* Mailbox 2 Time Stamp Value Register */
+#define CAN_MB02_ID0 0xFFC02C58 /* Mailbox 2 Identifier Low Register */
+#define CAN_MB02_ID1 0xFFC02C5C /* Mailbox 2 Identifier High Register */
+
+#define CAN_MB03_DATA0 0xFFC02C60 /* Mailbox 3 Data Word 0 [15:0] Register */
+#define CAN_MB03_DATA1 0xFFC02C64 /* Mailbox 3 Data Word 1 [31:16] Register */
+#define CAN_MB03_DATA2 0xFFC02C68 /* Mailbox 3 Data Word 2 [47:32] Register */
+#define CAN_MB03_DATA3 0xFFC02C6C /* Mailbox 3 Data Word 3 [63:48] Register */
+#define CAN_MB03_LENGTH 0xFFC02C70 /* Mailbox 3 Data Length Code Register */
+#define CAN_MB03_TIMESTAMP 0xFFC02C74 /* Mailbox 3 Time Stamp Value Register */
+#define CAN_MB03_ID0 0xFFC02C78 /* Mailbox 3 Identifier Low Register */
+#define CAN_MB03_ID1 0xFFC02C7C /* Mailbox 3 Identifier High Register */
+
+#define CAN_MB04_DATA0 0xFFC02C80 /* Mailbox 4 Data Word 0 [15:0] Register */
+#define CAN_MB04_DATA1 0xFFC02C84 /* Mailbox 4 Data Word 1 [31:16] Register */
+#define CAN_MB04_DATA2 0xFFC02C88 /* Mailbox 4 Data Word 2 [47:32] Register */
+#define CAN_MB04_DATA3 0xFFC02C8C /* Mailbox 4 Data Word 3 [63:48] Register */
+#define CAN_MB04_LENGTH 0xFFC02C90 /* Mailbox 4 Data Length Code Register */
+#define CAN_MB04_TIMESTAMP 0xFFC02C94 /* Mailbox 4 Time Stamp Value Register */
+#define CAN_MB04_ID0 0xFFC02C98 /* Mailbox 4 Identifier Low Register */
+#define CAN_MB04_ID1 0xFFC02C9C /* Mailbox 4 Identifier High Register */
+
+#define CAN_MB05_DATA0 0xFFC02CA0 /* Mailbox 5 Data Word 0 [15:0] Register */
+#define CAN_MB05_DATA1 0xFFC02CA4 /* Mailbox 5 Data Word 1 [31:16] Register */
+#define CAN_MB05_DATA2 0xFFC02CA8 /* Mailbox 5 Data Word 2 [47:32] Register */
+#define CAN_MB05_DATA3 0xFFC02CAC /* Mailbox 5 Data Word 3 [63:48] Register */
+#define CAN_MB05_LENGTH 0xFFC02CB0 /* Mailbox 5 Data Length Code Register */
+#define CAN_MB05_TIMESTAMP 0xFFC02CB4 /* Mailbox 5 Time Stamp Value Register */
+#define CAN_MB05_ID0 0xFFC02CB8 /* Mailbox 5 Identifier Low Register */
+#define CAN_MB05_ID1 0xFFC02CBC /* Mailbox 5 Identifier High Register */
+
+#define CAN_MB06_DATA0 0xFFC02CC0 /* Mailbox 6 Data Word 0 [15:0] Register */
+#define CAN_MB06_DATA1 0xFFC02CC4 /* Mailbox 6 Data Word 1 [31:16] Register */
+#define CAN_MB06_DATA2 0xFFC02CC8 /* Mailbox 6 Data Word 2 [47:32] Register */
+#define CAN_MB06_DATA3 0xFFC02CCC /* Mailbox 6 Data Word 3 [63:48] Register */
+#define CAN_MB06_LENGTH 0xFFC02CD0 /* Mailbox 6 Data Length Code Register */
+#define CAN_MB06_TIMESTAMP 0xFFC02CD4 /* Mailbox 6 Time Stamp Value Register */
+#define CAN_MB06_ID0 0xFFC02CD8 /* Mailbox 6 Identifier Low Register */
+#define CAN_MB06_ID1 0xFFC02CDC /* Mailbox 6 Identifier High Register */
+
+#define CAN_MB07_DATA0 0xFFC02CE0 /* Mailbox 7 Data Word 0 [15:0] Register */
+#define CAN_MB07_DATA1 0xFFC02CE4 /* Mailbox 7 Data Word 1 [31:16] Register */
+#define CAN_MB07_DATA2 0xFFC02CE8 /* Mailbox 7 Data Word 2 [47:32] Register */
+#define CAN_MB07_DATA3 0xFFC02CEC /* Mailbox 7 Data Word 3 [63:48] Register */
+#define CAN_MB07_LENGTH 0xFFC02CF0 /* Mailbox 7 Data Length Code Register */
+#define CAN_MB07_TIMESTAMP 0xFFC02CF4 /* Mailbox 7 Time Stamp Value Register */
+#define CAN_MB07_ID0 0xFFC02CF8 /* Mailbox 7 Identifier Low Register */
+#define CAN_MB07_ID1 0xFFC02CFC /* Mailbox 7 Identifier High Register */
+
+#define CAN_MB08_DATA0 0xFFC02D00 /* Mailbox 8 Data Word 0 [15:0] Register */
+#define CAN_MB08_DATA1 0xFFC02D04 /* Mailbox 8 Data Word 1 [31:16] Register */
+#define CAN_MB08_DATA2 0xFFC02D08 /* Mailbox 8 Data Word 2 [47:32] Register */
+#define CAN_MB08_DATA3 0xFFC02D0C /* Mailbox 8 Data Word 3 [63:48] Register */
+#define CAN_MB08_LENGTH 0xFFC02D10 /* Mailbox 8 Data Length Code Register */
+#define CAN_MB08_TIMESTAMP 0xFFC02D14 /* Mailbox 8 Time Stamp Value Register */
+#define CAN_MB08_ID0 0xFFC02D18 /* Mailbox 8 Identifier Low Register */
+#define CAN_MB08_ID1 0xFFC02D1C /* Mailbox 8 Identifier High Register */
+
+#define CAN_MB09_DATA0 0xFFC02D20 /* Mailbox 9 Data Word 0 [15:0] Register */
+#define CAN_MB09_DATA1 0xFFC02D24 /* Mailbox 9 Data Word 1 [31:16] Register */
+#define CAN_MB09_DATA2 0xFFC02D28 /* Mailbox 9 Data Word 2 [47:32] Register */
+#define CAN_MB09_DATA3 0xFFC02D2C /* Mailbox 9 Data Word 3 [63:48] Register */
+#define CAN_MB09_LENGTH 0xFFC02D30 /* Mailbox 9 Data Length Code Register */
+#define CAN_MB09_TIMESTAMP 0xFFC02D34 /* Mailbox 9 Time Stamp Value Register */
+#define CAN_MB09_ID0 0xFFC02D38 /* Mailbox 9 Identifier Low Register */
+#define CAN_MB09_ID1 0xFFC02D3C /* Mailbox 9 Identifier High Register */
+
+#define CAN_MB10_DATA0 0xFFC02D40 /* Mailbox 10 Data Word 0 [15:0] Register */
+#define CAN_MB10_DATA1 0xFFC02D44 /* Mailbox 10 Data Word 1 [31:16] Register */
+#define CAN_MB10_DATA2 0xFFC02D48 /* Mailbox 10 Data Word 2 [47:32] Register */
+#define CAN_MB10_DATA3 0xFFC02D4C /* Mailbox 10 Data Word 3 [63:48] Register */
+#define CAN_MB10_LENGTH 0xFFC02D50 /* Mailbox 10 Data Length Code Register */
+#define CAN_MB10_TIMESTAMP 0xFFC02D54 /* Mailbox 10 Time Stamp Value Register */
+#define CAN_MB10_ID0 0xFFC02D58 /* Mailbox 10 Identifier Low Register */
+#define CAN_MB10_ID1 0xFFC02D5C /* Mailbox 10 Identifier High Register */
+
+#define CAN_MB11_DATA0 0xFFC02D60 /* Mailbox 11 Data Word 0 [15:0] Register */
+#define CAN_MB11_DATA1 0xFFC02D64 /* Mailbox 11 Data Word 1 [31:16] Register */
+#define CAN_MB11_DATA2 0xFFC02D68 /* Mailbox 11 Data Word 2 [47:32] Register */
+#define CAN_MB11_DATA3 0xFFC02D6C /* Mailbox 11 Data Word 3 [63:48] Register */
+#define CAN_MB11_LENGTH 0xFFC02D70 /* Mailbox 11 Data Length Code Register */
+#define CAN_MB11_TIMESTAMP 0xFFC02D74 /* Mailbox 11 Time Stamp Value Register */
+#define CAN_MB11_ID0 0xFFC02D78 /* Mailbox 11 Identifier Low Register */
+#define CAN_MB11_ID1 0xFFC02D7C /* Mailbox 11 Identifier High Register */
+
+#define CAN_MB12_DATA0 0xFFC02D80 /* Mailbox 12 Data Word 0 [15:0] Register */
+#define CAN_MB12_DATA1 0xFFC02D84 /* Mailbox 12 Data Word 1 [31:16] Register */
+#define CAN_MB12_DATA2 0xFFC02D88 /* Mailbox 12 Data Word 2 [47:32] Register */
+#define CAN_MB12_DATA3 0xFFC02D8C /* Mailbox 12 Data Word 3 [63:48] Register */
+#define CAN_MB12_LENGTH 0xFFC02D90 /* Mailbox 12 Data Length Code Register */
+#define CAN_MB12_TIMESTAMP 0xFFC02D94 /* Mailbox 12 Time Stamp Value Register */
+#define CAN_MB12_ID0 0xFFC02D98 /* Mailbox 12 Identifier Low Register */
+#define CAN_MB12_ID1 0xFFC02D9C /* Mailbox 12 Identifier High Register */
+
+#define CAN_MB13_DATA0 0xFFC02DA0 /* Mailbox 13 Data Word 0 [15:0] Register */
+#define CAN_MB13_DATA1 0xFFC02DA4 /* Mailbox 13 Data Word 1 [31:16] Register */
+#define CAN_MB13_DATA2 0xFFC02DA8 /* Mailbox 13 Data Word 2 [47:32] Register */
+#define CAN_MB13_DATA3 0xFFC02DAC /* Mailbox 13 Data Word 3 [63:48] Register */
+#define CAN_MB13_LENGTH 0xFFC02DB0 /* Mailbox 13 Data Length Code Register */
+#define CAN_MB13_TIMESTAMP 0xFFC02DB4 /* Mailbox 13 Time Stamp Value Register */
+#define CAN_MB13_ID0 0xFFC02DB8 /* Mailbox 13 Identifier Low Register */
+#define CAN_MB13_ID1 0xFFC02DBC /* Mailbox 13 Identifier High Register */
+
+#define CAN_MB14_DATA0 0xFFC02DC0 /* Mailbox 14 Data Word 0 [15:0] Register */
+#define CAN_MB14_DATA1 0xFFC02DC4 /* Mailbox 14 Data Word 1 [31:16] Register */
+#define CAN_MB14_DATA2 0xFFC02DC8 /* Mailbox 14 Data Word 2 [47:32] Register */
+#define CAN_MB14_DATA3 0xFFC02DCC /* Mailbox 14 Data Word 3 [63:48] Register */
+#define CAN_MB14_LENGTH 0xFFC02DD0 /* Mailbox 14 Data Length Code Register */
+#define CAN_MB14_TIMESTAMP 0xFFC02DD4 /* Mailbox 14 Time Stamp Value Register */
+#define CAN_MB14_ID0 0xFFC02DD8 /* Mailbox 14 Identifier Low Register */
+#define CAN_MB14_ID1 0xFFC02DDC /* Mailbox 14 Identifier High Register */
+
+#define CAN_MB15_DATA0 0xFFC02DE0 /* Mailbox 15 Data Word 0 [15:0] Register */
+#define CAN_MB15_DATA1 0xFFC02DE4 /* Mailbox 15 Data Word 1 [31:16] Register */
+#define CAN_MB15_DATA2 0xFFC02DE8 /* Mailbox 15 Data Word 2 [47:32] Register */
+#define CAN_MB15_DATA3 0xFFC02DEC /* Mailbox 15 Data Word 3 [63:48] Register */
+#define CAN_MB15_LENGTH 0xFFC02DF0 /* Mailbox 15 Data Length Code Register */
+#define CAN_MB15_TIMESTAMP 0xFFC02DF4 /* Mailbox 15 Time Stamp Value Register */
+#define CAN_MB15_ID0 0xFFC02DF8 /* Mailbox 15 Identifier Low Register */
+#define CAN_MB15_ID1 0xFFC02DFC /* Mailbox 15 Identifier High Register */
+
+#define CAN_MB16_DATA0 0xFFC02E00 /* Mailbox 16 Data Word 0 [15:0] Register */
+#define CAN_MB16_DATA1 0xFFC02E04 /* Mailbox 16 Data Word 1 [31:16] Register */
+#define CAN_MB16_DATA2 0xFFC02E08 /* Mailbox 16 Data Word 2 [47:32] Register */
+#define CAN_MB16_DATA3 0xFFC02E0C /* Mailbox 16 Data Word 3 [63:48] Register */
+#define CAN_MB16_LENGTH 0xFFC02E10 /* Mailbox 16 Data Length Code Register */
+#define CAN_MB16_TIMESTAMP 0xFFC02E14 /* Mailbox 16 Time Stamp Value Register */
+#define CAN_MB16_ID0 0xFFC02E18 /* Mailbox 16 Identifier Low Register */
+#define CAN_MB16_ID1 0xFFC02E1C /* Mailbox 16 Identifier High Register */
+
+#define CAN_MB17_DATA0 0xFFC02E20 /* Mailbox 17 Data Word 0 [15:0] Register */
+#define CAN_MB17_DATA1 0xFFC02E24 /* Mailbox 17 Data Word 1 [31:16] Register */
+#define CAN_MB17_DATA2 0xFFC02E28 /* Mailbox 17 Data Word 2 [47:32] Register */
+#define CAN_MB17_DATA3 0xFFC02E2C /* Mailbox 17 Data Word 3 [63:48] Register */
+#define CAN_MB17_LENGTH 0xFFC02E30 /* Mailbox 17 Data Length Code Register */
+#define CAN_MB17_TIMESTAMP 0xFFC02E34 /* Mailbox 17 Time Stamp Value Register */
+#define CAN_MB17_ID0 0xFFC02E38 /* Mailbox 17 Identifier Low Register */
+#define CAN_MB17_ID1 0xFFC02E3C /* Mailbox 17 Identifier High Register */
+
+#define CAN_MB18_DATA0 0xFFC02E40 /* Mailbox 18 Data Word 0 [15:0] Register */
+#define CAN_MB18_DATA1 0xFFC02E44 /* Mailbox 18 Data Word 1 [31:16] Register */
+#define CAN_MB18_DATA2 0xFFC02E48 /* Mailbox 18 Data Word 2 [47:32] Register */
+#define CAN_MB18_DATA3 0xFFC02E4C /* Mailbox 18 Data Word 3 [63:48] Register */
+#define CAN_MB18_LENGTH 0xFFC02E50 /* Mailbox 18 Data Length Code Register */
+#define CAN_MB18_TIMESTAMP 0xFFC02E54 /* Mailbox 18 Time Stamp Value Register */
+#define CAN_MB18_ID0 0xFFC02E58 /* Mailbox 18 Identifier Low Register */
+#define CAN_MB18_ID1 0xFFC02E5C /* Mailbox 18 Identifier High Register */
+
+#define CAN_MB19_DATA0 0xFFC02E60 /* Mailbox 19 Data Word 0 [15:0] Register */
+#define CAN_MB19_DATA1 0xFFC02E64 /* Mailbox 19 Data Word 1 [31:16] Register */
+#define CAN_MB19_DATA2 0xFFC02E68 /* Mailbox 19 Data Word 2 [47:32] Register */
+#define CAN_MB19_DATA3 0xFFC02E6C /* Mailbox 19 Data Word 3 [63:48] Register */
+#define CAN_MB19_LENGTH 0xFFC02E70 /* Mailbox 19 Data Length Code Register */
+#define CAN_MB19_TIMESTAMP 0xFFC02E74 /* Mailbox 19 Time Stamp Value Register */
+#define CAN_MB19_ID0 0xFFC02E78 /* Mailbox 19 Identifier Low Register */
+#define CAN_MB19_ID1 0xFFC02E7C /* Mailbox 19 Identifier High Register */
+
+#define CAN_MB20_DATA0 0xFFC02E80 /* Mailbox 20 Data Word 0 [15:0] Register */
+#define CAN_MB20_DATA1 0xFFC02E84 /* Mailbox 20 Data Word 1 [31:16] Register */
+#define CAN_MB20_DATA2 0xFFC02E88 /* Mailbox 20 Data Word 2 [47:32] Register */
+#define CAN_MB20_DATA3 0xFFC02E8C /* Mailbox 20 Data Word 3 [63:48] Register */
+#define CAN_MB20_LENGTH 0xFFC02E90 /* Mailbox 20 Data Length Code Register */
+#define CAN_MB20_TIMESTAMP 0xFFC02E94 /* Mailbox 20 Time Stamp Value Register */
+#define CAN_MB20_ID0 0xFFC02E98 /* Mailbox 20 Identifier Low Register */
+#define CAN_MB20_ID1 0xFFC02E9C /* Mailbox 20 Identifier High Register */
+
+#define CAN_MB21_DATA0 0xFFC02EA0 /* Mailbox 21 Data Word 0 [15:0] Register */
+#define CAN_MB21_DATA1 0xFFC02EA4 /* Mailbox 21 Data Word 1 [31:16] Register */
+#define CAN_MB21_DATA2 0xFFC02EA8 /* Mailbox 21 Data Word 2 [47:32] Register */
+#define CAN_MB21_DATA3 0xFFC02EAC /* Mailbox 21 Data Word 3 [63:48] Register */
+#define CAN_MB21_LENGTH 0xFFC02EB0 /* Mailbox 21 Data Length Code Register */
+#define CAN_MB21_TIMESTAMP 0xFFC02EB4 /* Mailbox 21 Time Stamp Value Register */
+#define CAN_MB21_ID0 0xFFC02EB8 /* Mailbox 21 Identifier Low Register */
+#define CAN_MB21_ID1 0xFFC02EBC /* Mailbox 21 Identifier High Register */
+
+#define CAN_MB22_DATA0 0xFFC02EC0 /* Mailbox 22 Data Word 0 [15:0] Register */
+#define CAN_MB22_DATA1 0xFFC02EC4 /* Mailbox 22 Data Word 1 [31:16] Register */
+#define CAN_MB22_DATA2 0xFFC02EC8 /* Mailbox 22 Data Word 2 [47:32] Register */
+#define CAN_MB22_DATA3 0xFFC02ECC /* Mailbox 22 Data Word 3 [63:48] Register */
+#define CAN_MB22_LENGTH 0xFFC02ED0 /* Mailbox 22 Data Length Code Register */
+#define CAN_MB22_TIMESTAMP 0xFFC02ED4 /* Mailbox 22 Time Stamp Value Register */
+#define CAN_MB22_ID0 0xFFC02ED8 /* Mailbox 22 Identifier Low Register */
+#define CAN_MB22_ID1 0xFFC02EDC /* Mailbox 22 Identifier High Register */
+
+#define CAN_MB23_DATA0 0xFFC02EE0 /* Mailbox 23 Data Word 0 [15:0] Register */
+#define CAN_MB23_DATA1 0xFFC02EE4 /* Mailbox 23 Data Word 1 [31:16] Register */
+#define CAN_MB23_DATA2 0xFFC02EE8 /* Mailbox 23 Data Word 2 [47:32] Register */
+#define CAN_MB23_DATA3 0xFFC02EEC /* Mailbox 23 Data Word 3 [63:48] Register */
+#define CAN_MB23_LENGTH 0xFFC02EF0 /* Mailbox 23 Data Length Code Register */
+#define CAN_MB23_TIMESTAMP 0xFFC02EF4 /* Mailbox 23 Time Stamp Value Register */
+#define CAN_MB23_ID0 0xFFC02EF8 /* Mailbox 23 Identifier Low Register */
+#define CAN_MB23_ID1 0xFFC02EFC /* Mailbox 23 Identifier High Register */
+
+#define CAN_MB24_DATA0 0xFFC02F00 /* Mailbox 24 Data Word 0 [15:0] Register */
+#define CAN_MB24_DATA1 0xFFC02F04 /* Mailbox 24 Data Word 1 [31:16] Register */
+#define CAN_MB24_DATA2 0xFFC02F08 /* Mailbox 24 Data Word 2 [47:32] Register */
+#define CAN_MB24_DATA3 0xFFC02F0C /* Mailbox 24 Data Word 3 [63:48] Register */
+#define CAN_MB24_LENGTH 0xFFC02F10 /* Mailbox 24 Data Length Code Register */
+#define CAN_MB24_TIMESTAMP 0xFFC02F14 /* Mailbox 24 Time Stamp Value Register */
+#define CAN_MB24_ID0 0xFFC02F18 /* Mailbox 24 Identifier Low Register */
+#define CAN_MB24_ID1 0xFFC02F1C /* Mailbox 24 Identifier High Register */
+
+#define CAN_MB25_DATA0 0xFFC02F20 /* Mailbox 25 Data Word 0 [15:0] Register */
+#define CAN_MB25_DATA1 0xFFC02F24 /* Mailbox 25 Data Word 1 [31:16] Register */
+#define CAN_MB25_DATA2 0xFFC02F28 /* Mailbox 25 Data Word 2 [47:32] Register */
+#define CAN_MB25_DATA3 0xFFC02F2C /* Mailbox 25 Data Word 3 [63:48] Register */
+#define CAN_MB25_LENGTH 0xFFC02F30 /* Mailbox 25 Data Length Code Register */
+#define CAN_MB25_TIMESTAMP 0xFFC02F34 /* Mailbox 25 Time Stamp Value Register */
+#define CAN_MB25_ID0 0xFFC02F38 /* Mailbox 25 Identifier Low Register */
+#define CAN_MB25_ID1 0xFFC02F3C /* Mailbox 25 Identifier High Register */
+
+#define CAN_MB26_DATA0 0xFFC02F40 /* Mailbox 26 Data Word 0 [15:0] Register */
+#define CAN_MB26_DATA1 0xFFC02F44 /* Mailbox 26 Data Word 1 [31:16] Register */
+#define CAN_MB26_DATA2 0xFFC02F48 /* Mailbox 26 Data Word 2 [47:32] Register */
+#define CAN_MB26_DATA3 0xFFC02F4C /* Mailbox 26 Data Word 3 [63:48] Register */
+#define CAN_MB26_LENGTH 0xFFC02F50 /* Mailbox 26 Data Length Code Register */
+#define CAN_MB26_TIMESTAMP 0xFFC02F54 /* Mailbox 26 Time Stamp Value Register */
+#define CAN_MB26_ID0 0xFFC02F58 /* Mailbox 26 Identifier Low Register */
+#define CAN_MB26_ID1 0xFFC02F5C /* Mailbox 26 Identifier High Register */
+
+#define CAN_MB27_DATA0 0xFFC02F60 /* Mailbox 27 Data Word 0 [15:0] Register */
+#define CAN_MB27_DATA1 0xFFC02F64 /* Mailbox 27 Data Word 1 [31:16] Register */
+#define CAN_MB27_DATA2 0xFFC02F68 /* Mailbox 27 Data Word 2 [47:32] Register */
+#define CAN_MB27_DATA3 0xFFC02F6C /* Mailbox 27 Data Word 3 [63:48] Register */
+#define CAN_MB27_LENGTH 0xFFC02F70 /* Mailbox 27 Data Length Code Register */
+#define CAN_MB27_TIMESTAMP 0xFFC02F74 /* Mailbox 27 Time Stamp Value Register */
+#define CAN_MB27_ID0 0xFFC02F78 /* Mailbox 27 Identifier Low Register */
+#define CAN_MB27_ID1 0xFFC02F7C /* Mailbox 27 Identifier High Register */
+
+#define CAN_MB28_DATA0 0xFFC02F80 /* Mailbox 28 Data Word 0 [15:0] Register */
+#define CAN_MB28_DATA1 0xFFC02F84 /* Mailbox 28 Data Word 1 [31:16] Register */
+#define CAN_MB28_DATA2 0xFFC02F88 /* Mailbox 28 Data Word 2 [47:32] Register */
+#define CAN_MB28_DATA3 0xFFC02F8C /* Mailbox 28 Data Word 3 [63:48] Register */
+#define CAN_MB28_LENGTH 0xFFC02F90 /* Mailbox 28 Data Length Code Register */
+#define CAN_MB28_TIMESTAMP 0xFFC02F94 /* Mailbox 28 Time Stamp Value Register */
+#define CAN_MB28_ID0 0xFFC02F98 /* Mailbox 28 Identifier Low Register */
+#define CAN_MB28_ID1 0xFFC02F9C /* Mailbox 28 Identifier High Register */
+
+#define CAN_MB29_DATA0 0xFFC02FA0 /* Mailbox 29 Data Word 0 [15:0] Register */
+#define CAN_MB29_DATA1 0xFFC02FA4 /* Mailbox 29 Data Word 1 [31:16] Register */
+#define CAN_MB29_DATA2 0xFFC02FA8 /* Mailbox 29 Data Word 2 [47:32] Register */
+#define CAN_MB29_DATA3 0xFFC02FAC /* Mailbox 29 Data Word 3 [63:48] Register */
+#define CAN_MB29_LENGTH 0xFFC02FB0 /* Mailbox 29 Data Length Code Register */
+#define CAN_MB29_TIMESTAMP 0xFFC02FB4 /* Mailbox 29 Time Stamp Value Register */
+#define CAN_MB29_ID0 0xFFC02FB8 /* Mailbox 29 Identifier Low Register */
+#define CAN_MB29_ID1 0xFFC02FBC /* Mailbox 29 Identifier High Register */
+
+#define CAN_MB30_DATA0 0xFFC02FC0 /* Mailbox 30 Data Word 0 [15:0] Register */
+#define CAN_MB30_DATA1 0xFFC02FC4 /* Mailbox 30 Data Word 1 [31:16] Register */
+#define CAN_MB30_DATA2 0xFFC02FC8 /* Mailbox 30 Data Word 2 [47:32] Register */
+#define CAN_MB30_DATA3 0xFFC02FCC /* Mailbox 30 Data Word 3 [63:48] Register */
+#define CAN_MB30_LENGTH 0xFFC02FD0 /* Mailbox 30 Data Length Code Register */
+#define CAN_MB30_TIMESTAMP 0xFFC02FD4 /* Mailbox 30 Time Stamp Value Register */
+#define CAN_MB30_ID0 0xFFC02FD8 /* Mailbox 30 Identifier Low Register */
+#define CAN_MB30_ID1 0xFFC02FDC /* Mailbox 30 Identifier High Register */
+
+#define CAN_MB31_DATA0 0xFFC02FE0 /* Mailbox 31 Data Word 0 [15:0] Register */
+#define CAN_MB31_DATA1 0xFFC02FE4 /* Mailbox 31 Data Word 1 [31:16] Register */
+#define CAN_MB31_DATA2 0xFFC02FE8 /* Mailbox 31 Data Word 2 [47:32] Register */
+#define CAN_MB31_DATA3 0xFFC02FEC /* Mailbox 31 Data Word 3 [63:48] Register */
+#define CAN_MB31_LENGTH 0xFFC02FF0 /* Mailbox 31 Data Length Code Register */
+#define CAN_MB31_TIMESTAMP 0xFFC02FF4 /* Mailbox 31 Time Stamp Value Register */
+#define CAN_MB31_ID0 0xFFC02FF8 /* Mailbox 31 Identifier Low Register */
+#define CAN_MB31_ID1 0xFFC02FFC /* Mailbox 31 Identifier High Register */
+
+/* CAN Mailbox Area Macros */
+#define CAN_MB_ID1(x) (CAN_MB00_ID1+((x)*0x20))
+#define CAN_MB_ID0(x) (CAN_MB00_ID0+((x)*0x20))
+#define CAN_MB_TIMESTAMP(x) (CAN_MB00_TIMESTAMP+((x)*0x20))
+#define CAN_MB_LENGTH(x) (CAN_MB00_LENGTH+((x)*0x20))
+#define CAN_MB_DATA3(x) (CAN_MB00_DATA3+((x)*0x20))
+#define CAN_MB_DATA2(x) (CAN_MB00_DATA2+((x)*0x20))
+#define CAN_MB_DATA1(x) (CAN_MB00_DATA1+((x)*0x20))
+#define CAN_MB_DATA0(x) (CAN_MB00_DATA0+((x)*0x20))
+
+/* Pin Control Registers (0xFFC03200 - 0xFFC032FF) */
+#define PORTF_FER 0xFFC03200 /* Port F Function Enable Register (Alternate/Flag*) */
+#define PORTG_FER 0xFFC03204 /* Port G Function Enable Register (Alternate/Flag*) */
+#define PORTH_FER 0xFFC03208 /* Port H Function Enable Register (Alternate/Flag*) */
+#define BFIN_PORT_MUX 0xFFC0320C /* Port Multiplexer Control Register */
+
+/* Handshake MDMA Registers (0xFFC03300 - 0xFFC033FF) */
+#define HMDMA0_CONTROL 0xFFC03300 /* Handshake MDMA0 Control Register */
+#define HMDMA0_ECINIT 0xFFC03304 /* HMDMA0 Initial Edge Count Register */
+#define HMDMA0_BCINIT 0xFFC03308 /* HMDMA0 Initial Block Count Register */
+#define HMDMA0_ECURGENT 0xFFC0330C /* HMDMA0 Urgent Edge Count Threshhold Register */
+#define HMDMA0_ECOVERFLOW 0xFFC03310 /* HMDMA0 Edge Count Overflow Interrupt Register */
+#define HMDMA0_ECOUNT 0xFFC03314 /* HMDMA0 Current Edge Count Register */
+#define HMDMA0_BCOUNT 0xFFC03318 /* HMDMA0 Current Block Count Register */
+
+#define HMDMA1_CONTROL 0xFFC03340 /* Handshake MDMA1 Control Register */
+#define HMDMA1_ECINIT 0xFFC03344 /* HMDMA1 Initial Edge Count Register */
+#define HMDMA1_BCINIT 0xFFC03348 /* HMDMA1 Initial Block Count Register */
+#define HMDMA1_ECURGENT 0xFFC0334C /* HMDMA1 Urgent Edge Count Threshhold Register */
+#define HMDMA1_ECOVERFLOW 0xFFC03350 /* HMDMA1 Edge Count Overflow Interrupt Register */
+#define HMDMA1_ECOUNT 0xFFC03354 /* HMDMA1 Current Edge Count Register */
+#define HMDMA1_BCOUNT 0xFFC03358 /* HMDMA1 Current Block Count Register */
+
+/***********************************************************************************
+** System MMR Register Bits And Macros
+**
+** Disclaimer: All macros are intended to make C and Assembly code more readable.
+** Use these macros carefully, as any that do left shifts for field
+** depositing will result in the lower order bits being destroyed. Any
+** macro that shifts left to properly position the bit-field should be
+** used as part of an OR to initialize a register and NOT as a dynamic
+** modifier UNLESS the lower order bits are saved and ORed back in when
+** the macro is used.
+*************************************************************************************/
+/*
+** ********************* PLL AND RESET MASKS ****************************************/
+/* PLL_CTL Masks */
+#define DF 0x0001 /* 0: PLL = CLKIN, 1: PLL = CLKIN/2 */
+#define PLL_OFF 0x0002 /* PLL Not Powered */
+#define STOPCK 0x0008 /* Core Clock Off */
+#define PDWN 0x0020 /* Enter Deep Sleep Mode */
+#define IN_DELAY 0x0040 /* Add 200ps Delay To EBIU Input Latches */
+#define OUT_DELAY 0x0080 /* Add 200ps Delay To EBIU Output Signals */
+#define BYPASS 0x0100 /* Bypass the PLL */
+#define MSEL 0x7E00 /* Multiplier Select For CCLK/VCO Factors */
+/* PLL_CTL Macros (Only Use With Logic OR While Setting Lower Order Bits) */
+#define SET_MSEL(x) (((x)&0x3F) << 0x9) /* Set MSEL = 0-63 --> VCO = CLKIN*MSEL */
+
+/* PLL_DIV Masks */
+#define SSEL 0x000F /* System Select */
+#define CSEL 0x0030 /* Core Select */
+#define CSEL_DIV1 0x0000 /* CCLK = VCO / 1 */
+#define CSEL_DIV2 0x0010 /* CCLK = VCO / 2 */
+#define CSEL_DIV4 0x0020 /* CCLK = VCO / 4 */
+#define CSEL_DIV8 0x0030 /* CCLK = VCO / 8 */
+/* PLL_DIV Macros */
+#define SET_SSEL(x) ((x)&0xF) /* Set SSEL = 0-15 --> SCLK = VCO/SSEL */
+
+/* VR_CTL Masks */
+#define FREQ 0x0003 /* Switching Oscillator Frequency For Regulator */
+#define HIBERNATE 0x0000 /* Powerdown/Bypass On-Board Regulation */
+#define FREQ_333 0x0001 /* Switching Frequency Is 333 kHz */
+#define FREQ_667 0x0002 /* Switching Frequency Is 667 kHz */
+#define FREQ_1000 0x0003 /* Switching Frequency Is 1 MHz */
+
+#define GAIN 0x000C /* Voltage Level Gain */
+#define GAIN_5 0x0000 /* GAIN = 5 */
+#define GAIN_10 0x0004 /* GAIN = 10 */
+#define GAIN_20 0x0008 /* GAIN = 20 */
+#define GAIN_50 0x000C /* GAIN = 50 */
+
+#define VLEV 0x00F0 /* Internal Voltage Level */
+#define VLEV_085 0x0060 /* VLEV = 0.85 V (-5% - +10% Accuracy) */
+#define VLEV_090 0x0070 /* VLEV = 0.90 V (-5% - +10% Accuracy) */
+#define VLEV_095 0x0080 /* VLEV = 0.95 V (-5% - +10% Accuracy) */
+#define VLEV_100 0x0090 /* VLEV = 1.00 V (-5% - +10% Accuracy) */
+#define VLEV_105 0x00A0 /* VLEV = 1.05 V (-5% - +10% Accuracy) */
+#define VLEV_110 0x00B0 /* VLEV = 1.10 V (-5% - +10% Accuracy) */
+#define VLEV_115 0x00C0 /* VLEV = 1.15 V (-5% - +10% Accuracy) */
+#define VLEV_120 0x00D0 /* VLEV = 1.20 V (-5% - +10% Accuracy) */
+#define VLEV_125 0x00E0 /* VLEV = 1.25 V (-5% - +10% Accuracy) */
+#define VLEV_130 0x00F0 /* VLEV = 1.30 V (-5% - +10% Accuracy) */
+
+#define WAKE 0x0100 /* Enable RTC/Reset Wakeup From Hibernate */
+#define PHYWE 0x0200 /* Enable PHY Wakeup From Hibernate */
+#define CANWE 0x0400 /* Enable CAN Wakeup From Hibernate */
+#define PHYCLKOE 0x4000 /* PHY Clock Output Enable */
+#define CKELOW 0x8000 /* Enable Drive CKE Low During Reset */
+
+/* PLL_STAT Masks */
+#define ACTIVE_PLLENABLED 0x0001 /* Processor In Active Mode With PLL Enabled */
+#define FULL_ON 0x0002 /* Processor In Full On Mode */
+#define ACTIVE_PLLDISABLED 0x0004 /* Processor In Active Mode With PLL Disabled */
+#define PLL_LOCKED 0x0020 /* PLL_LOCKCNT Has Been Reached */
+
+/* CHIPID Masks */
+#define CHIPID_VERSION 0xF0000000
+#define CHIPID_FAMILY 0x0FFFF000
+#define CHIPID_MANUFACTURE 0x00000FFE
+
+/* SWRST Masks */
+#define SYSTEM_RESET 0x0007 /* Initiates A System Software Reset */
+#define DOUBLE_FAULT 0x0008 /* Core Double Fault Causes Reset */
+#define RESET_DOUBLE 0x2000 /* SW Reset Generated By Core Double-Fault */
+#define RESET_WDOG 0x4000 /* SW Reset Generated By Watchdog Timer */
+#define RESET_SOFTWARE 0x8000 /* SW Reset Occurred Since Last Read Of SWRST */
+
+/* SYSCR Masks */
+#define BMODE 0x0006 /* Boot Mode - Latched During HW Reset From Mode Pins */
+#define NOBOOT 0x0010 /* Execute From L1 or ASYNC Bank 0 When BMODE = 0 */
+
+/* ************* SYSTEM INTERRUPT CONTROLLER MASKS *************************************/
+
+/* SIC_IAR0 Macros */
+#define P0_IVG(x) (((x)&0xF)-7) /* Peripheral #0 assigned IVG #x */
+#define P1_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #1 assigned IVG #x */
+#define P2_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #2 assigned IVG #x */
+#define P3_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #3 assigned IVG #x */
+#define P4_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #4 assigned IVG #x */
+#define P5_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #5 assigned IVG #x */
+#define P6_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #6 assigned IVG #x */
+#define P7_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #7 assigned IVG #x */
+
+/* SIC_IAR1 Macros */
+#define P8_IVG(x) (((x)&0xF)-7) /* Peripheral #8 assigned IVG #x */
+#define P9_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #9 assigned IVG #x */
+#define P10_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #10 assigned IVG #x */
+#define P11_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #11 assigned IVG #x */
+#define P12_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #12 assigned IVG #x */
+#define P13_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #13 assigned IVG #x */
+#define P14_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #14 assigned IVG #x */
+#define P15_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #15 assigned IVG #x */
+
+/* SIC_IAR2 Macros */
+#define P16_IVG(x) (((x)&0xF)-7) /* Peripheral #16 assigned IVG #x */
+#define P17_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #17 assigned IVG #x */
+#define P18_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #18 assigned IVG #x */
+#define P19_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #19 assigned IVG #x */
+#define P20_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #20 assigned IVG #x */
+#define P21_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #21 assigned IVG #x */
+#define P22_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #22 assigned IVG #x */
+#define P23_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #23 assigned IVG #x */
+
+/* SIC_IAR3 Macros */
+#define P24_IVG(x) (((x)&0xF)-7) /* Peripheral #24 assigned IVG #x */
+#define P25_IVG(x) (((x)&0xF)-7) << 0x4 /* Peripheral #25 assigned IVG #x */
+#define P26_IVG(x) (((x)&0xF)-7) << 0x8 /* Peripheral #26 assigned IVG #x */
+#define P27_IVG(x) (((x)&0xF)-7) << 0xC /* Peripheral #27 assigned IVG #x */
+#define P28_IVG(x) (((x)&0xF)-7) << 0x10 /* Peripheral #28 assigned IVG #x */
+#define P29_IVG(x) (((x)&0xF)-7) << 0x14 /* Peripheral #29 assigned IVG #x */
+#define P30_IVG(x) (((x)&0xF)-7) << 0x18 /* Peripheral #30 assigned IVG #x */
+#define P31_IVG(x) (((x)&0xF)-7) << 0x1C /* Peripheral #31 assigned IVG #x */
+
+/* SIC_IMASK Masks */
+#define SIC_UNMASK_ALL 0x00000000 /* Unmask all peripheral interrupts */
+#define SIC_MASK_ALL 0xFFFFFFFF /* Mask all peripheral interrupts */
+#define SIC_MASK(x) (1 << ((x)&0x1F)) /* Mask Peripheral #x interrupt */
+#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Unmask Peripheral #x interrupt */
+
+/* SIC_IWR Masks */
+#define IWR_DISABLE_ALL 0x00000000 /* Wakeup Disable all peripherals */
+#define IWR_ENABLE_ALL 0xFFFFFFFF /* Wakeup Enable all peripherals */
+#define IWR_ENABLE(x) (1 << ((x)&0x1F)) /* Wakeup Enable Peripheral #x */
+#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << ((x)&0x1F))) /* Wakeup Disable Peripheral #x */
+
+/* *************** WATCHDOG TIMER MASKS *******************************************/
+/* WDOG_CTL Masks */
+#define WDOG_RESET 0x0000 /* Generate Reset Event */
+#define WDOG_NMI 0x0002 /* Generate Non-Maskable Interrupt (NMI) Event */
+#define WDOG_GPI 0x0004 /* Generate General Purpose (GP) Interrupt */
+#define WDOG_NONE 0x0006 /* Disable Watchdog Timer Interrupts */
+#define TMR_EN 0x0FF0 /* Watchdog Counter Enable */
+#define TMR_DIS 0x0AD0 /* Watchdog Counter Disable */
+#define TRO 0x8000 /* Watchdog Expired */
+
+/* ************** UART CONTROLLER MASKS *************************/
+/* UARTx_LCR Masks */
+#define WLS(x) ((((x)&0x3)-5) & 0x03) /* Word Length Select */
+#define STB 0x04 /* Stop Bits */
+#define PEN 0x08 /* Parity Enable */
+#define EPS 0x10 /* Even Parity Select */
+#define STP 0x20 /* Stick Parity */
+#define SB 0x40 /* Set Break */
+#define DLAB 0x80 /* Divisor Latch Access */
+
+/* UARTx_MCR Mask */
+#define LOOP 0x10 /* Loopback Mode Enable */
+
+/* UARTx_LSR Masks */
+#define DR 0x01 /* Data Ready */
+#define OE 0x02 /* Overrun Error */
+#define PE 0x04 /* Parity Error */
+#define FE 0x08 /* Framing Error */
+#define BI 0x10 /* Break Interrupt */
+#define THRE 0x20 /* THR Empty */
+#define TEMT 0x40 /* TSR and UART_THR Empty */
+
+/* UARTx_IER Masks */
+#define ERBFI 0x01 /* Enable Receive Buffer Full Interrupt */
+#define ETBEI 0x02 /* Enable Transmit Buffer Empty Interrupt */
+#define ELSI 0x04 /* Enable RX Status Interrupt */
+
+/* UARTx_IIR Masks */
+#define NINT 0x01 /* Pending Interrupt */
+#define IIR_TX_READY 0x02 /* UART_THR empty */
+#define IIR_RX_READY 0x04 /* Receive data ready */
+#define IIR_LINE_CHANGE 0x06 /* Receive line status */
+#define IIR_STATUS 0x06
+
+/* UARTx_GCTL Masks */
+#define UCEN 0x01 /* Enable UARTx Clocks */
+#define IREN 0x02 /* Enable IrDA Mode */
+#define TPOLC 0x04 /* IrDA TX Polarity Change */
+#define RPOLC 0x08 /* IrDA RX Polarity Change */
+#define FPE 0x10 /* Force Parity Error On Transmit */
+#define FFE 0x20 /* Force Framing Error On Transmit */
+
+/* *********** SERIAL PERIPHERAL INTERFACE (SPI) MASKS ****************************/
+/* SPI_CTL Masks */
+#define TIMOD 0x0003 /* Transfer Initiate Mode */
+#define RDBR_CORE 0x0000 /* RDBR Read Initiates, IRQ When RDBR Full */
+#define TDBR_CORE 0x0001 /* TDBR Write Initiates, IRQ When TDBR Empty */
+#define RDBR_DMA 0x0002 /* DMA Read, DMA Until FIFO Empty */
+#define TDBR_DMA 0x0003 /* DMA Write, DMA Until FIFO Full */
+#define SZ 0x0004 /* Send Zero (When TDBR Empty, Send Zero/Last*) */
+#define GM 0x0008 /* Get More (When RDBR Full, Overwrite/Discard*) */
+#define PSSE 0x0010 /* Slave-Select Input Enable */
+#define EMISO 0x0020 /* Enable MISO As Output */
+#define SPI_SIZE 0x0100 /* Size of Words (16/8* Bits) */
+#define LSBF 0x0200 /* LSB First */
+#define CPHA 0x0400 /* Clock Phase */
+#define CPOL 0x0800 /* Clock Polarity */
+#define MSTR 0x1000 /* Master/Slave* */
+#define WOM 0x2000 /* Write Open Drain Master */
+#define SPE 0x4000 /* SPI Enable */
+
+/* SPI_FLG Masks */
+#define FLS1 0x0002 /* Enables SPI_FLOUT1 as SPI Slave-Select Output */
+#define FLS2 0x0004 /* Enables SPI_FLOUT2 as SPI Slave-Select Output */
+#define FLS3 0x0008 /* Enables SPI_FLOUT3 as SPI Slave-Select Output */
+#define FLS4 0x0010 /* Enables SPI_FLOUT4 as SPI Slave-Select Output */
+#define FLS5 0x0020 /* Enables SPI_FLOUT5 as SPI Slave-Select Output */
+#define FLS6 0x0040 /* Enables SPI_FLOUT6 as SPI Slave-Select Output */
+#define FLS7 0x0080 /* Enables SPI_FLOUT7 as SPI Slave-Select Output */
+#define FLG1 0xFDFF /* Activates SPI_FLOUT1 */
+#define FLG2 0xFBFF /* Activates SPI_FLOUT2 */
+#define FLG3 0xF7FF /* Activates SPI_FLOUT3 */
+#define FLG4 0xEFFF /* Activates SPI_FLOUT4 */
+#define FLG5 0xDFFF /* Activates SPI_FLOUT5 */
+#define FLG6 0xBFFF /* Activates SPI_FLOUT6 */
+#define FLG7 0x7FFF /* Activates SPI_FLOUT7 */
+
+/* SPI_STAT Masks */
+#define SPIF 0x0001 /* SPI Finished (Single-Word Transfer Complete) */
+#define MODF 0x0002 /* Mode Fault Error (Another Device Tried To Become Master) */
+#define TXE 0x0004 /* Transmission Error (Data Sent With No New Data In TDBR) */
+#define TXS 0x0008 /* SPI_TDBR Data Buffer Status (Full/Empty*) */
+#define RBSY 0x0010 /* Receive Error (Data Received With RDBR Full) */
+#define RXS 0x0020 /* SPI_RDBR Data Buffer Status (Full/Empty*) */
+#define TXCOL 0x0040 /* Transmit Collision Error (Corrupt Data May Have Been Sent) */
+
+/* **************** GENERAL PURPOSE TIMER MASKS **********************/
+/* TIMER_ENABLE Masks */
+#define TIMEN0 0x0001 /* Enable Timer 0 */
+#define TIMEN1 0x0002 /* Enable Timer 1 */
+#define TIMEN2 0x0004 /* Enable Timer 2 */
+#define TIMEN3 0x0008 /* Enable Timer 3 */
+#define TIMEN4 0x0010 /* Enable Timer 4 */
+#define TIMEN5 0x0020 /* Enable Timer 5 */
+#define TIMEN6 0x0040 /* Enable Timer 6 */
+#define TIMEN7 0x0080 /* Enable Timer 7 */
+
+/* TIMER_DISABLE Masks */
+#define TIMDIS0 TIMEN0 /* Disable Timer 0 */
+#define TIMDIS1 TIMEN1 /* Disable Timer 1 */
+#define TIMDIS2 TIMEN2 /* Disable Timer 2 */
+#define TIMDIS3 TIMEN3 /* Disable Timer 3 */
+#define TIMDIS4 TIMEN4 /* Disable Timer 4 */
+#define TIMDIS5 TIMEN5 /* Disable Timer 5 */
+#define TIMDIS6 TIMEN6 /* Disable Timer 6 */
+#define TIMDIS7 TIMEN7 /* Disable Timer 7 */
+
+/* TIMER_STATUS Masks */
+#define TIMIL0 0x00000001 /* Timer 0 Interrupt */
+#define TIMIL1 0x00000002 /* Timer 1 Interrupt */
+#define TIMIL2 0x00000004 /* Timer 2 Interrupt */
+#define TIMIL3 0x00000008 /* Timer 3 Interrupt */
+#define TOVL_ERR0 0x00000010 /* Timer 0 Counter Overflow */
+#define TOVL_ERR1 0x00000020 /* Timer 1 Counter Overflow */
+#define TOVL_ERR2 0x00000040 /* Timer 2 Counter Overflow */
+#define TOVL_ERR3 0x00000080 /* Timer 3 Counter Overflow */
+#define TRUN0 0x00001000 /* Timer 0 Slave Enable Status */
+#define TRUN1 0x00002000 /* Timer 1 Slave Enable Status */
+#define TRUN2 0x00004000 /* Timer 2 Slave Enable Status */
+#define TRUN3 0x00008000 /* Timer 3 Slave Enable Status */
+#define TIMIL4 0x00010000 /* Timer 4 Interrupt */
+#define TIMIL5 0x00020000 /* Timer 5 Interrupt */
+#define TIMIL6 0x00040000 /* Timer 6 Interrupt */
+#define TIMIL7 0x00080000 /* Timer 7 Interrupt */
+#define TOVL_ERR4 0x00100000 /* Timer 4 Counter Overflow */
+#define TOVL_ERR5 0x00200000 /* Timer 5 Counter Overflow */
+#define TOVL_ERR6 0x00400000 /* Timer 6 Counter Overflow */
+#define TOVL_ERR7 0x00800000 /* Timer 7 Counter Overflow */
+#define TRUN4 0x10000000 /* Timer 4 Slave Enable Status */
+#define TRUN5 0x20000000 /* Timer 5 Slave Enable Status */
+#define TRUN6 0x40000000 /* Timer 6 Slave Enable Status */
+#define TRUN7 0x80000000 /* Timer 7 Slave Enable Status */
+
+/* TIMERx_CONFIG Masks */
+#define PWM_OUT 0x0001 /* Pulse-Width Modulation Output Mode */
+#define WDTH_CAP 0x0002 /* Width Capture Input Mode */
+#define EXT_CLK 0x0003 /* External Clock Mode */
+#define PULSE_HI 0x0004 /* Action Pulse (Positive/Negative*) */
+#define PERIOD_CNT 0x0008 /* Period Count */
+#define IRQ_ENA 0x0010 /* Interrupt Request Enable */
+#define TIN_SEL 0x0020 /* Timer Input Select */
+#define OUT_DIS 0x0040 /* Output Pad Disable */
+#define CLK_SEL 0x0080 /* Timer Clock Select */
+#define TOGGLE_HI 0x0100 /* PWM_OUT PULSE_HI Toggle Mode */
+#define EMU_RUN 0x0200 /* Emulation Behavior Select */
+#define ERR_TYP 0xC000 /* Error Type */
+
+/* ****************** GPIO PORTS F, G, H MASKS ***********************/
+/* General Purpose IO (0xFFC00700 - 0xFFC007FF) Masks */
+/* Port F Masks */
+#define PF0 0x0001
+#define PF1 0x0002
+#define PF2 0x0004
+#define PF3 0x0008
+#define PF4 0x0010
+#define PF5 0x0020
+#define PF6 0x0040
+#define PF7 0x0080
+#define PF8 0x0100
+#define PF9 0x0200
+#define PF10 0x0400
+#define PF11 0x0800
+#define PF12 0x1000
+#define PF13 0x2000
+#define PF14 0x4000
+#define PF15 0x8000
+
+/* Port G Masks */
+#define PG0 0x0001
+#define PG1 0x0002
+#define PG2 0x0004
+#define PG3 0x0008
+#define PG4 0x0010
+#define PG5 0x0020
+#define PG6 0x0040
+#define PG7 0x0080
+#define PG8 0x0100
+#define PG9 0x0200
+#define PG10 0x0400
+#define PG11 0x0800
+#define PG12 0x1000
+#define PG13 0x2000
+#define PG14 0x4000
+#define PG15 0x8000
+
+/* Port H Masks */
+#define PH0 0x0001
+#define PH1 0x0002
+#define PH2 0x0004
+#define PH3 0x0008
+#define PH4 0x0010
+#define PH5 0x0020
+#define PH6 0x0040
+#define PH7 0x0080
+#define PH8 0x0100
+#define PH9 0x0200
+#define PH10 0x0400
+#define PH11 0x0800
+#define PH12 0x1000
+#define PH13 0x2000
+#define PH14 0x4000
+#define PH15 0x8000
+
+/* ******************* SERIAL PORT MASKS **************************************/
+/* SPORTx_TCR1 Masks */
+#define TSPEN 0x0001 /* Transmit Enable */
+#define ITCLK 0x0002 /* Internal Transmit Clock Select */
+#define DTYPE_NORM 0x0004 /* Data Format Normal */
+#define DTYPE_ULAW 0x0008 /* Compand Using u-Law */
+#define DTYPE_ALAW 0x000C /* Compand Using A-Law */
+#define TLSBIT 0x0010 /* Transmit Bit Order */
+#define ITFS 0x0200 /* Internal Transmit Frame Sync Select */
+#define TFSR 0x0400 /* Transmit Frame Sync Required Select */
+#define DITFS 0x0800 /* Data-Independent Transmit Frame Sync Select */
+#define LTFS 0x1000 /* Low Transmit Frame Sync Select */
+#define LATFS 0x2000 /* Late Transmit Frame Sync Select */
+#define TCKFE 0x4000 /* Clock Falling Edge Select */
+
+/* SPORTx_TCR2 Masks and Macro */
+#define SLEN(x) ((x)&0x1F) /* SPORT TX Word Length (2 - 31) */
+#define TXSE 0x0100 /* TX Secondary Enable */
+#define TSFSE 0x0200 /* Transmit Stereo Frame Sync Enable */
+#define TRFST 0x0400 /* Left/Right Order (1 = Right Channel 1st) */
+
+/* SPORTx_RCR1 Masks */
+#define RSPEN 0x0001 /* Receive Enable */
+#define IRCLK 0x0002 /* Internal Receive Clock Select */
+#define DTYPE_NORM 0x0004 /* Data Format Normal */
+#define DTYPE_ULAW 0x0008 /* Compand Using u-Law */
+#define DTYPE_ALAW 0x000C /* Compand Using A-Law */
+#define RLSBIT 0x0010 /* Receive Bit Order */
+#define IRFS 0x0200 /* Internal Receive Frame Sync Select */
+#define RFSR 0x0400 /* Receive Frame Sync Required Select */
+#define LRFS 0x1000 /* Low Receive Frame Sync Select */
+#define LARFS 0x2000 /* Late Receive Frame Sync Select */
+#define RCKFE 0x4000 /* Clock Falling Edge Select */
+
+/* SPORTx_RCR2 Masks */
+#define SLEN(x) ((x)&0x1F) /* SPORT RX Word Length (2 - 31) */
+#define RXSE 0x0100 /* RX Secondary Enable */
+#define RSFSE 0x0200 /* RX Stereo Frame Sync Enable */
+#define RRFST 0x0400 /* Right-First Data Order */
+
+/* SPORTx_STAT Masks */
+#define RXNE 0x0001 /* Receive FIFO Not Empty Status */
+#define RUVF 0x0002 /* Sticky Receive Underflow Status */
+#define ROVF 0x0004 /* Sticky Receive Overflow Status */
+#define TXF 0x0008 /* Transmit FIFO Full Status */
+#define TUVF 0x0010 /* Sticky Transmit Underflow Status */
+#define TOVF 0x0020 /* Sticky Transmit Overflow Status */
+#define TXHRE 0x0040 /* Transmit Hold Register Empty */
+
+/* SPORTx_MCMC1 Macros */
+#define SP_WOFF(x) ((x) & 0x3FF) /* Multichannel Window Offset Field */
+
+/* Only use WSIZE Macro With Logic OR While Setting Lower Order Bits */
+#define SP_WSIZE(x) (((((x)>>0x3)-1)&0xF) << 0xC) /* Multichannel Window Size = (x/8)-1 */
+
+/* SPORTx_MCMC2 Masks */
+#define REC_BYPASS 0x0000 /* Bypass Mode (No Clock Recovery) */
+#define REC_2FROM4 0x0002 /* Recover 2 MHz Clock from 4 MHz Clock */
+#define REC_8FROM16 0x0003 /* Recover 8 MHz Clock from 16 MHz Clock */
+#define MCDTXPE 0x0004 /* Multichannel DMA Transmit Packing */
+#define MCDRXPE 0x0008 /* Multichannel DMA Receive Packing */
+#define MCMEN 0x0010 /* Multichannel Frame Mode Enable */
+#define FSDR 0x0080 /* Multichannel Frame Sync to Data Relationship */
+#define MFD_0 0x0000 /* Multichannel Frame Delay = 0 */
+#define MFD_1 0x1000 /* Multichannel Frame Delay = 1 */
+#define MFD_2 0x2000 /* Multichannel Frame Delay = 2 */
+#define MFD_3 0x3000 /* Multichannel Frame Delay = 3 */
+#define MFD_4 0x4000 /* Multichannel Frame Delay = 4 */
+#define MFD_5 0x5000 /* Multichannel Frame Delay = 5 */
+#define MFD_6 0x6000 /* Multichannel Frame Delay = 6 */
+#define MFD_7 0x7000 /* Multichannel Frame Delay = 7 */
+#define MFD_8 0x8000 /* Multichannel Frame Delay = 8 */
+#define MFD_9 0x9000 /* Multichannel Frame Delay = 9 */
+#define MFD_10 0xA000 /* Multichannel Frame Delay = 10 */
+#define MFD_11 0xB000 /* Multichannel Frame Delay = 11 */
+#define MFD_12 0xC000 /* Multichannel Frame Delay = 12 */
+#define MFD_13 0xD000 /* Multichannel Frame Delay = 13 */
+#define MFD_14 0xE000 /* Multichannel Frame Delay = 14 */
+#define MFD_15 0xF000 /* Multichannel Frame Delay = 15 */
+
+/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS *************************/
+/* EBIU_AMGCTL Masks */
+#define AMCKEN 0x0001 /* Enable CLKOUT */
+#define AMBEN_NONE 0x0000 /* All Banks Disabled */
+#define AMBEN_B0 0x0002 /* Enable Async Memory Bank 0 only */
+#define AMBEN_B0_B1 0x0004 /* Enable Async Memory Banks 0 & 1 only */
+#define AMBEN_B0_B1_B2 0x0006 /* Enable Async Memory Banks 0, 1, and 2 */
+#define AMBEN_ALL 0x0008 /* Enable Async Memory Banks (all) 0, 1, 2, and 3 */
+
+/* EBIU_AMBCTL0 Masks */
+#define B0RDYEN 0x00000001 /* Bank 0 (B0) RDY Enable */
+#define B0RDYPOL 0x00000002 /* B0 RDY Active High */
+#define B0TT_1 0x00000004 /* B0 Transition Time (Read to Write) = 1 cycle */
+#define B0TT_2 0x00000008 /* B0 Transition Time (Read to Write) = 2 cycles */
+#define B0TT_3 0x0000000C /* B0 Transition Time (Read to Write) = 3 cycles */
+#define B0TT_4 0x00000000 /* B0 Transition Time (Read to Write) = 4 cycles */
+#define B0ST_1 0x00000010 /* B0 Setup Time (AOE to Read/Write) = 1 cycle */
+#define B0ST_2 0x00000020 /* B0 Setup Time (AOE to Read/Write) = 2 cycles */
+#define B0ST_3 0x00000030 /* B0 Setup Time (AOE to Read/Write) = 3 cycles */
+#define B0ST_4 0x00000000 /* B0 Setup Time (AOE to Read/Write) = 4 cycles */
+#define B0HT_1 0x00000040 /* B0 Hold Time (~Read/Write to ~AOE) = 1 cycle */
+#define B0HT_2 0x00000080 /* B0 Hold Time (~Read/Write to ~AOE) = 2 cycles */
+#define B0HT_3 0x000000C0 /* B0 Hold Time (~Read/Write to ~AOE) = 3 cycles */
+#define B0HT_0 0x00000000 /* B0 Hold Time (~Read/Write to ~AOE) = 0 cycles */
+#define B0RAT_1 0x00000100 /* B0 Read Access Time = 1 cycle */
+#define B0RAT_2 0x00000200 /* B0 Read Access Time = 2 cycles */
+#define B0RAT_3 0x00000300 /* B0 Read Access Time = 3 cycles */
+#define B0RAT_4 0x00000400 /* B0 Read Access Time = 4 cycles */
+#define B0RAT_5 0x00000500 /* B0 Read Access Time = 5 cycles */
+#define B0RAT_6 0x00000600 /* B0 Read Access Time = 6 cycles */
+#define B0RAT_7 0x00000700 /* B0 Read Access Time = 7 cycles */
+#define B0RAT_8 0x00000800 /* B0 Read Access Time = 8 cycles */
+#define B0RAT_9 0x00000900 /* B0 Read Access Time = 9 cycles */
+#define B0RAT_10 0x00000A00 /* B0 Read Access Time = 10 cycles */
+#define B0RAT_11 0x00000B00 /* B0 Read Access Time = 11 cycles */
+#define B0RAT_12 0x00000C00 /* B0 Read Access Time = 12 cycles */
+#define B0RAT_13 0x00000D00 /* B0 Read Access Time = 13 cycles */
+#define B0RAT_14 0x00000E00 /* B0 Read Access Time = 14 cycles */
+#define B0RAT_15 0x00000F00 /* B0 Read Access Time = 15 cycles */
+#define B0WAT_1 0x00001000 /* B0 Write Access Time = 1 cycle */
+#define B0WAT_2 0x00002000 /* B0 Write Access Time = 2 cycles */
+#define B0WAT_3 0x00003000 /* B0 Write Access Time = 3 cycles */
+#define B0WAT_4 0x00004000 /* B0 Write Access Time = 4 cycles */
+#define B0WAT_5 0x00005000 /* B0 Write Access Time = 5 cycles */
+#define B0WAT_6 0x00006000 /* B0 Write Access Time = 6 cycles */
+#define B0WAT_7 0x00007000 /* B0 Write Access Time = 7 cycles */
+#define B0WAT_8 0x00008000 /* B0 Write Access Time = 8 cycles */
+#define B0WAT_9 0x00009000 /* B0 Write Access Time = 9 cycles */
+#define B0WAT_10 0x0000A000 /* B0 Write Access Time = 10 cycles */
+#define B0WAT_11 0x0000B000 /* B0 Write Access Time = 11 cycles */
+#define B0WAT_12 0x0000C000 /* B0 Write Access Time = 12 cycles */
+#define B0WAT_13 0x0000D000 /* B0 Write Access Time = 13 cycles */
+#define B0WAT_14 0x0000E000 /* B0 Write Access Time = 14 cycles */
+#define B0WAT_15 0x0000F000 /* B0 Write Access Time = 15 cycles */
+
+#define B1RDYEN 0x00010000 /* Bank 1 (B1) RDY Enable */
+#define B1RDYPOL 0x00020000 /* B1 RDY Active High */
+#define B1TT_1 0x00040000 /* B1 Transition Time (Read to Write) = 1 cycle */
+#define B1TT_2 0x00080000 /* B1 Transition Time (Read to Write) = 2 cycles */
+#define B1TT_3 0x000C0000 /* B1 Transition Time (Read to Write) = 3 cycles */
+#define B1TT_4 0x00000000 /* B1 Transition Time (Read to Write) = 4 cycles */
+#define B1ST_1 0x00100000 /* B1 Setup Time (AOE to Read/Write) = 1 cycle */
+#define B1ST_2 0x00200000 /* B1 Setup Time (AOE to Read/Write) = 2 cycles */
+#define B1ST_3 0x00300000 /* B1 Setup Time (AOE to Read/Write) = 3 cycles */
+#define B1ST_4 0x00000000 /* B1 Setup Time (AOE to Read/Write) = 4 cycles */
+#define B1HT_1 0x00400000 /* B1 Hold Time (~Read/Write to ~AOE) = 1 cycle */
+#define B1HT_2 0x00800000 /* B1 Hold Time (~Read/Write to ~AOE) = 2 cycles */
+#define B1HT_3 0x00C00000 /* B1 Hold Time (~Read/Write to ~AOE) = 3 cycles */
+#define B1HT_0 0x00000000 /* B1 Hold Time (~Read/Write to ~AOE) = 0 cycles */
+#define B1RAT_1 0x01000000 /* B1 Read Access Time = 1 cycle */
+#define B1RAT_2 0x02000000 /* B1 Read Access Time = 2 cycles */
+#define B1RAT_3 0x03000000 /* B1 Read Access Time = 3 cycles */
+#define B1RAT_4 0x04000000 /* B1 Read Access Time = 4 cycles */
+#define B1RAT_5 0x05000000 /* B1 Read Access Time = 5 cycles */
+#define B1RAT_6 0x06000000 /* B1 Read Access Time = 6 cycles */
+#define B1RAT_7 0x07000000 /* B1 Read Access Time = 7 cycles */
+#define B1RAT_8 0x08000000 /* B1 Read Access Time = 8 cycles */
+#define B1RAT_9 0x09000000 /* B1 Read Access Time = 9 cycles */
+#define B1RAT_10 0x0A000000 /* B1 Read Access Time = 10 cycles */
+#define B1RAT_11 0x0B000000 /* B1 Read Access Time = 11 cycles */
+#define B1RAT_12 0x0C000000 /* B1 Read Access Time = 12 cycles */
+#define B1RAT_13 0x0D000000 /* B1 Read Access Time = 13 cycles */
+#define B1RAT_14 0x0E000000 /* B1 Read Access Time = 14 cycles */
+#define B1RAT_15 0x0F000000 /* B1 Read Access Time = 15 cycles */
+#define B1WAT_1 0x10000000 /* B1 Write Access Time = 1 cycle */
+#define B1WAT_2 0x20000000 /* B1 Write Access Time = 2 cycles */
+#define B1WAT_3 0x30000000 /* B1 Write Access Time = 3 cycles */
+#define B1WAT_4 0x40000000 /* B1 Write Access Time = 4 cycles */
+#define B1WAT_5 0x50000000 /* B1 Write Access Time = 5 cycles */
+#define B1WAT_6 0x60000000 /* B1 Write Access Time = 6 cycles */
+#define B1WAT_7 0x70000000 /* B1 Write Access Time = 7 cycles */
+#define B1WAT_8 0x80000000 /* B1 Write Access Time = 8 cycles */
+#define B1WAT_9 0x90000000 /* B1 Write Access Time = 9 cycles */
+#define B1WAT_10 0xA0000000 /* B1 Write Access Time = 10 cycles */
+#define B1WAT_11 0xB0000000 /* B1 Write Access Time = 11 cycles */
+#define B1WAT_12 0xC0000000 /* B1 Write Access Time = 12 cycles */
+#define B1WAT_13 0xD0000000 /* B1 Write Access Time = 13 cycles */
+#define B1WAT_14 0xE0000000 /* B1 Write Access Time = 14 cycles */
+#define B1WAT_15 0xF0000000 /* B1 Write Access Time = 15 cycles */
+
+/* EBIU_AMBCTL1 Masks */
+#define B2RDYEN 0x00000001 /* Bank 2 (B2) RDY Enable */
+#define B2RDYPOL 0x00000002 /* B2 RDY Active High */
+#define B2TT_1 0x00000004 /* B2 Transition Time (Read to Write) = 1 cycle */
+#define B2TT_2 0x00000008 /* B2 Transition Time (Read to Write) = 2 cycles */
+#define B2TT_3 0x0000000C /* B2 Transition Time (Read to Write) = 3 cycles */
+#define B2TT_4 0x00000000 /* B2 Transition Time (Read to Write) = 4 cycles */
+#define B2ST_1 0x00000010 /* B2 Setup Time (AOE to Read/Write) = 1 cycle */
+#define B2ST_2 0x00000020 /* B2 Setup Time (AOE to Read/Write) = 2 cycles */
+#define B2ST_3 0x00000030 /* B2 Setup Time (AOE to Read/Write) = 3 cycles */
+#define B2ST_4 0x00000000 /* B2 Setup Time (AOE to Read/Write) = 4 cycles */
+#define B2HT_1 0x00000040 /* B2 Hold Time (~Read/Write to ~AOE) = 1 cycle */
+#define B2HT_2 0x00000080 /* B2 Hold Time (~Read/Write to ~AOE) = 2 cycles */
+#define B2HT_3 0x000000C0 /* B2 Hold Time (~Read/Write to ~AOE) = 3 cycles */
+#define B2HT_0 0x00000000 /* B2 Hold Time (~Read/Write to ~AOE) = 0 cycles */
+#define B2RAT_1 0x00000100 /* B2 Read Access Time = 1 cycle */
+#define B2RAT_2 0x00000200 /* B2 Read Access Time = 2 cycles */
+#define B2RAT_3 0x00000300 /* B2 Read Access Time = 3 cycles */
+#define B2RAT_4 0x00000400 /* B2 Read Access Time = 4 cycles */
+#define B2RAT_5 0x00000500 /* B2 Read Access Time = 5 cycles */
+#define B2RAT_6 0x00000600 /* B2 Read Access Time = 6 cycles */
+#define B2RAT_7 0x00000700 /* B2 Read Access Time = 7 cycles */
+#define B2RAT_8 0x00000800 /* B2 Read Access Time = 8 cycles */
+#define B2RAT_9 0x00000900 /* B2 Read Access Time = 9 cycles */
+#define B2RAT_10 0x00000A00 /* B2 Read Access Time = 10 cycles */
+#define B2RAT_11 0x00000B00 /* B2 Read Access Time = 11 cycles */
+#define B2RAT_12 0x00000C00 /* B2 Read Access Time = 12 cycles */
+#define B2RAT_13 0x00000D00 /* B2 Read Access Time = 13 cycles */
+#define B2RAT_14 0x00000E00 /* B2 Read Access Time = 14 cycles */
+#define B2RAT_15 0x00000F00 /* B2 Read Access Time = 15 cycles */
+#define B2WAT_1 0x00001000 /* B2 Write Access Time = 1 cycle */
+#define B2WAT_2 0x00002000 /* B2 Write Access Time = 2 cycles */
+#define B2WAT_3 0x00003000 /* B2 Write Access Time = 3 cycles */
+#define B2WAT_4 0x00004000 /* B2 Write Access Time = 4 cycles */
+#define B2WAT_5 0x00005000 /* B2 Write Access Time = 5 cycles */
+#define B2WAT_6 0x00006000 /* B2 Write Access Time = 6 cycles */
+#define B2WAT_7 0x00007000 /* B2 Write Access Time = 7 cycles */
+#define B2WAT_8 0x00008000 /* B2 Write Access Time = 8 cycles */
+#define B2WAT_9 0x00009000 /* B2 Write Access Time = 9 cycles */
+#define B2WAT_10 0x0000A000 /* B2 Write Access Time = 10 cycles */
+#define B2WAT_11 0x0000B000 /* B2 Write Access Time = 11 cycles */
+#define B2WAT_12 0x0000C000 /* B2 Write Access Time = 12 cycles */
+#define B2WAT_13 0x0000D000 /* B2 Write Access Time = 13 cycles */
+#define B2WAT_14 0x0000E000 /* B2 Write Access Time = 14 cycles */
+#define B2WAT_15 0x0000F000 /* B2 Write Access Time = 15 cycles */
+
+#define B3RDYEN 0x00010000 /* Bank 3 (B3) RDY Enable */
+#define B3RDYPOL 0x00020000 /* B3 RDY Active High */
+#define B3TT_1 0x00040000 /* B3 Transition Time (Read to Write) = 1 cycle */
+#define B3TT_2 0x00080000 /* B3 Transition Time (Read to Write) = 2 cycles */
+#define B3TT_3 0x000C0000 /* B3 Transition Time (Read to Write) = 3 cycles */
+#define B3TT_4 0x00000000 /* B3 Transition Time (Read to Write) = 4 cycles */
+#define B3ST_1 0x00100000 /* B3 Setup Time (AOE to Read/Write) = 1 cycle */
+#define B3ST_2 0x00200000 /* B3 Setup Time (AOE to Read/Write) = 2 cycles */
+#define B3ST_3 0x00300000 /* B3 Setup Time (AOE to Read/Write) = 3 cycles */
+#define B3ST_4 0x00000000 /* B3 Setup Time (AOE to Read/Write) = 4 cycles */
+#define B3HT_1 0x00400000 /* B3 Hold Time (~Read/Write to ~AOE) = 1 cycle */
+#define B3HT_2 0x00800000 /* B3 Hold Time (~Read/Write to ~AOE) = 2 cycles */
+#define B3HT_3 0x00C00000 /* B3 Hold Time (~Read/Write to ~AOE) = 3 cycles */
+#define B3HT_0 0x00000000 /* B3 Hold Time (~Read/Write to ~AOE) = 0 cycles */
+#define B3RAT_1 0x01000000 /* B3 Read Access Time = 1 cycle */
+#define B3RAT_2 0x02000000 /* B3 Read Access Time = 2 cycles */
+#define B3RAT_3 0x03000000 /* B3 Read Access Time = 3 cycles */
+#define B3RAT_4 0x04000000 /* B3 Read Access Time = 4 cycles */
+#define B3RAT_5 0x05000000 /* B3 Read Access Time = 5 cycles */
+#define B3RAT_6 0x06000000 /* B3 Read Access Time = 6 cycles */
+#define B3RAT_7 0x07000000 /* B3 Read Access Time = 7 cycles */
+#define B3RAT_8 0x08000000 /* B3 Read Access Time = 8 cycles */
+#define B3RAT_9 0x09000000 /* B3 Read Access Time = 9 cycles */
+#define B3RAT_10 0x0A000000 /* B3 Read Access Time = 10 cycles */
+#define B3RAT_11 0x0B000000 /* B3 Read Access Time = 11 cycles */
+#define B3RAT_12 0x0C000000 /* B3 Read Access Time = 12 cycles */
+#define B3RAT_13 0x0D000000 /* B3 Read Access Time = 13 cycles */
+#define B3RAT_14 0x0E000000 /* B3 Read Access Time = 14 cycles */
+#define B3RAT_15 0x0F000000 /* B3 Read Access Time = 15 cycles */
+#define B3WAT_1 0x10000000 /* B3 Write Access Time = 1 cycle */
+#define B3WAT_2 0x20000000 /* B3 Write Access Time = 2 cycles */
+#define B3WAT_3 0x30000000 /* B3 Write Access Time = 3 cycles */
+#define B3WAT_4 0x40000000 /* B3 Write Access Time = 4 cycles */
+#define B3WAT_5 0x50000000 /* B3 Write Access Time = 5 cycles */
+#define B3WAT_6 0x60000000 /* B3 Write Access Time = 6 cycles */
+#define B3WAT_7 0x70000000 /* B3 Write Access Time = 7 cycles */
+#define B3WAT_8 0x80000000 /* B3 Write Access Time = 8 cycles */
+#define B3WAT_9 0x90000000 /* B3 Write Access Time = 9 cycles */
+#define B3WAT_10 0xA0000000 /* B3 Write Access Time = 10 cycles */
+#define B3WAT_11 0xB0000000 /* B3 Write Access Time = 11 cycles */
+#define B3WAT_12 0xC0000000 /* B3 Write Access Time = 12 cycles */
+#define B3WAT_13 0xD0000000 /* B3 Write Access Time = 13 cycles */
+#define B3WAT_14 0xE0000000 /* B3 Write Access Time = 14 cycles */
+#define B3WAT_15 0xF0000000 /* B3 Write Access Time = 15 cycles */
+
+/* ********************** SDRAM CONTROLLER MASKS **********************************************/
+/* EBIU_SDGCTL Masks */
+#define SCTLE 0x00000001 /* Enable SDRAM Signals */
+#define CL_2 0x00000008 /* SDRAM CAS Latency = 2 cycles */
+#define CL_3 0x0000000C /* SDRAM CAS Latency = 3 cycles */
+#define PASR_ALL 0x00000000 /* All 4 SDRAM Banks Refreshed In Self-Refresh */
+#define PASR_B0_B1 0x00000010 /* SDRAM Banks 0 and 1 Are Refreshed In Self-Refresh */
+#define PASR_B0 0x00000020 /* Only SDRAM Bank 0 Is Refreshed In Self-Refresh */
+#define TRAS_1 0x00000040 /* SDRAM tRAS = 1 cycle */
+#define TRAS_2 0x00000080 /* SDRAM tRAS = 2 cycles */
+#define TRAS_3 0x000000C0 /* SDRAM tRAS = 3 cycles */
+#define TRAS_4 0x00000100 /* SDRAM tRAS = 4 cycles */
+#define TRAS_5 0x00000140 /* SDRAM tRAS = 5 cycles */
+#define TRAS_6 0x00000180 /* SDRAM tRAS = 6 cycles */
+#define TRAS_7 0x000001C0 /* SDRAM tRAS = 7 cycles */
+#define TRAS_8 0x00000200 /* SDRAM tRAS = 8 cycles */
+#define TRAS_9 0x00000240 /* SDRAM tRAS = 9 cycles */
+#define TRAS_10 0x00000280 /* SDRAM tRAS = 10 cycles */
+#define TRAS_11 0x000002C0 /* SDRAM tRAS = 11 cycles */
+#define TRAS_12 0x00000300 /* SDRAM tRAS = 12 cycles */
+#define TRAS_13 0x00000340 /* SDRAM tRAS = 13 cycles */
+#define TRAS_14 0x00000380 /* SDRAM tRAS = 14 cycles */
+#define TRAS_15 0x000003C0 /* SDRAM tRAS = 15 cycles */
+#define TRP_1 0x00000800 /* SDRAM tRP = 1 cycle */
+#define TRP_2 0x00001000 /* SDRAM tRP = 2 cycles */
+#define TRP_3 0x00001800 /* SDRAM tRP = 3 cycles */
+#define TRP_4 0x00002000 /* SDRAM tRP = 4 cycles */
+#define TRP_5 0x00002800 /* SDRAM tRP = 5 cycles */
+#define TRP_6 0x00003000 /* SDRAM tRP = 6 cycles */
+#define TRP_7 0x00003800 /* SDRAM tRP = 7 cycles */
+#define TRCD_1 0x00008000 /* SDRAM tRCD = 1 cycle */
+#define TRCD_2 0x00010000 /* SDRAM tRCD = 2 cycles */
+#define TRCD_3 0x00018000 /* SDRAM tRCD = 3 cycles */
+#define TRCD_4 0x00020000 /* SDRAM tRCD = 4 cycles */
+#define TRCD_5 0x00028000 /* SDRAM tRCD = 5 cycles */
+#define TRCD_6 0x00030000 /* SDRAM tRCD = 6 cycles */
+#define TRCD_7 0x00038000 /* SDRAM tRCD = 7 cycles */
+#define TWR_1 0x00080000 /* SDRAM tWR = 1 cycle */
+#define TWR_2 0x00100000 /* SDRAM tWR = 2 cycles */
+#define TWR_3 0x00180000 /* SDRAM tWR = 3 cycles */
+#define PUPSD 0x00200000 /* Power-Up Start Delay (15 SCLK Cycles Delay) */
+#define PSM 0x00400000 /* Power-Up Sequence (Mode Register Before/After* Refresh) */
+#define PSS 0x00800000 /* Enable Power-Up Sequence on Next SDRAM Access */
+#define SRFS 0x01000000 /* Enable SDRAM Self-Refresh Mode */
+#define EBUFE 0x02000000 /* Enable External Buffering Timing */
+#define FBBRW 0x04000000 /* Enable Fast Back-To-Back Read To Write */
+#define EMREN 0x10000000 /* Extended Mode Register Enable */
+#define TCSR 0x20000000 /* Temp-Compensated Self-Refresh Value (85/45* Deg C) */
+#define CDDBG 0x40000000 /* Tristate SDRAM Controls During Bus Grant */
+
+/* EBIU_SDBCTL Masks */
+#define EBE 0x0001 /* Enable SDRAM External Bank */
+#define EBSZ_16 0x0000 /* SDRAM External Bank Size = 16MB */
+#define EBSZ_32 0x0002 /* SDRAM External Bank Size = 32MB */
+#define EBSZ_64 0x0004 /* SDRAM External Bank Size = 64MB */
+#define EBSZ_128 0x0006 /* SDRAM External Bank Size = 128MB */
+#define EBCAW_8 0x0000 /* SDRAM External Bank Column Address Width = 8 Bits */
+#define EBCAW_9 0x0010 /* SDRAM External Bank Column Address Width = 9 Bits */
+#define EBCAW_10 0x0020 /* SDRAM External Bank Column Address Width = 10 Bits */
+#define EBCAW_11 0x0030 /* SDRAM External Bank Column Address Width = 11 Bits */
+
+/* EBIU_SDSTAT Masks */
+#define SDCI 0x0001 /* SDRAM Controller Idle */
+#define SDSRA 0x0002 /* SDRAM Self-Refresh Active */
+#define SDPUA 0x0004 /* SDRAM Power-Up Active */
+#define SDRS 0x0008 /* SDRAM Will Power-Up On Next Access */
+#define SDEASE 0x0010 /* SDRAM EAB Sticky Error Status */
+#define BGSTAT 0x0020 /* Bus Grant Status */
+
+/* ************************** DMA CONTROLLER MASKS ********************************/
+/* DMAx_CONFIG, MDMA_yy_CONFIG Masks */
+#define DMAEN 0x0001 /* DMA Channel Enable */
+#define WNR 0x0002 /* Channel Direction (W/R*) */
+#define WDSIZE_8 0x0000 /* Transfer Word Size = 8 */
+#define WDSIZE_16 0x0004 /* Transfer Word Size = 16 */
+#define WDSIZE_32 0x0008 /* Transfer Word Size = 32 */
+#define DMA2D 0x0010 /* DMA Mode (2D/1D*) */
+#define RESTART 0x0020 /* DMA Buffer Clear */
+#define DI_SEL 0x0040 /* Data Interrupt Timing Select */
+#define DI_EN 0x0080 /* Data Interrupt Enable */
+#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */
+#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */
+#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */
+#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */
+#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */
+#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */
+#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */
+#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */
+#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */
+#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */
+#define NDSIZE 0x0900 /* Next Descriptor Size */
+
+#define DMAFLOW 0x7000 /* Flow Control */
+#define DMAFLOW_STOP 0x0000 /* Stop Mode */
+#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */
+#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */
+#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */
+#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */
+
+/* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */
+#define CTYPE 0x0040 /* DMA Channel Type Indicator (Memory/Peripheral*) */
+#define PMAP 0xF000 /* Peripheral Mapped To This Channel */
+#define PMAP_PPI 0x0000 /* PPI Port DMA */
+#define PMAP_EMACRX 0x1000 /* Ethernet Receive DMA */
+#define PMAP_EMACTX 0x2000 /* Ethernet Transmit DMA */
+#define PMAP_SPORT0RX 0x3000 /* SPORT0 Receive DMA */
+#define PMAP_SPORT0TX 0x4000 /* SPORT0 Transmit DMA */
+#define PMAP_SPORT1RX 0x5000 /* SPORT1 Receive DMA */
+#define PMAP_SPORT1TX 0x6000 /* SPORT1 Transmit DMA */
+#define PMAP_SPI 0x7000 /* SPI Port DMA */
+#define PMAP_UART0RX 0x8000 /* UART0 Port Receive DMA */
+#define PMAP_UART0TX 0x9000 /* UART0 Port Transmit DMA */
+#define PMAP_UART1RX 0xA000 /* UART1 Port Receive DMA */
+#define PMAP_UART1TX 0xB000 /* UART1 Port Transmit DMA */
+
+/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS Masks */
+#define DMA_DONE 0x0001 /* DMA Completion Interrupt Status */
+#define DMA_ERR 0x0002 /* DMA Error Interrupt Status */
+#define DFETCH 0x0004 /* DMA Descriptor Fetch Indicator */
+#define DMA_RUN 0x0008 /* DMA Channel Running Indicator */
+
+/* ************ PARALLEL PERIPHERAL INTERFACE (PPI) MASKS *************/
+/* PPI_CONTROL Masks */
+#define PORT_EN 0x0001 /* PPI Port Enable */
+#define PORT_DIR 0x0002 /* PPI Port Direction */
+#define XFR_TYPE 0x000C /* PPI Transfer Type */
+#define PORT_CFG 0x0030 /* PPI Port Configuration */
+#define FLD_SEL 0x0040 /* PPI Active Field Select */
+#define PACK_EN 0x0080 /* PPI Packing Mode */
+#define DMA32 0x0100 /* PPI 32-bit DMA Enable */
+#define SKIP_EN 0x0200 /* PPI Skip Element Enable */
+#define SKIP_EO 0x0400 /* PPI Skip Even/Odd Elements */
+#define DLENGTH 0x3800 /* PPI Data Length */
+#define DLEN_8 0x0000 /* Data Length = 8 Bits */
+#define DLEN_10 0x0800 /* Data Length = 10 Bits */
+#define DLEN_11 0x1000 /* Data Length = 11 Bits */
+#define DLEN_12 0x1800 /* Data Length = 12 Bits */
+#define DLEN_13 0x2000 /* Data Length = 13 Bits */
+#define DLEN_14 0x2800 /* Data Length = 14 Bits */
+#define DLEN_15 0x3000 /* Data Length = 15 Bits */
+#define DLEN_16 0x3800 /* Data Length = 16 Bits */
+#define POLC 0x4000 /* PPI Clock Polarity */
+#define POLS 0x8000 /* PPI Frame Sync Polarity */
+
+/* PPI_STATUS Masks */
+#define FLD 0x0400 /* Field Indicator */
+#define FT_ERR 0x0800 /* Frame Track Error */
+#define OVR 0x1000 /* FIFO Overflow Error */
+#define UNDR 0x2000 /* FIFO Underrun Error */
+#define ERR_DET 0x4000 /* Error Detected Indicator */
+#define ERR_NCOR 0x8000 /* Error Not Corrected Indicator */
+
+/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ***********************/
+/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */
+#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */
+#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */
+
+/* TWI_PRESCALE Masks */
+#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */
+#define TWI_ENA 0x0080 /* TWI Enable */
+#define SCCB 0x0200 /* SCCB Compatibility Enable */
+
+/* TWI_SLAVE_CTRL Masks */
+#define SEN 0x0001 /* Slave Enable */
+#define SADD_LEN 0x0002 /* Slave Address Length */
+#define STDVAL 0x0004 /* Slave Transmit Data Valid */
+#define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */
+#define GEN 0x0010 /* General Call Adrress Matching Enabled */
+
+/* TWI_SLAVE_STAT Masks */
+#define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */
+#define GCALL 0x0002 /* General Call Indicator */
+
+/* TWI_MASTER_CTRL Masks */
+#define MEN 0x0001 /* Master Mode Enable */
+#define MADD_LEN 0x0002 /* Master Address Length */
+#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */
+#define FAST 0x0008 /* Use Fast Mode Timing Specs */
+#define STOP 0x0010 /* Issue Stop Condition */
+#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */
+#define DCNT 0x3FC0 /* Data Bytes To Transfer */
+#define SDAOVR 0x4000 /* Serial Data Override */
+#define SCLOVR 0x8000 /* Serial Clock Override */
+
+/* TWI_MASTER_STAT Masks */
+#define MPROG 0x0001 /* Master Transfer In Progress */
+#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */
+#define ANAK 0x0004 /* Address Not Acknowledged */
+#define DNAK 0x0008 /* Data Not Acknowledged */
+#define BUFRDERR 0x0010 /* Buffer Read Error */
+#define BUFWRERR 0x0020 /* Buffer Write Error */
+#define SDASEN 0x0040 /* Serial Data Sense */
+#define SCLSEN 0x0080 /* Serial Clock Sense */
+#define BUSBUSY 0x0100 /* Bus Busy Indicator */
+
+/* TWI_INT_SRC and TWI_INT_ENABLE Masks */
+#define SINIT 0x0001 /* Slave Transfer Initiated */
+#define SCOMP 0x0002 /* Slave Transfer Complete */
+#define SERR 0x0004 /* Slave Transfer Error */
+#define SOVF 0x0008 /* Slave Overflow */
+#define MCOMP 0x0010 /* Master Transfer Complete */
+#define MERR 0x0020 /* Master Transfer Error */
+#define XMTSERV 0x0040 /* Transmit FIFO Service */
+#define RCVSERV 0x0080 /* Receive FIFO Service */
+
+/* TWI_FIFO_CTRL Masks */
+#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */
+#define RCVFLUSH 0x0002 /* Receive Buffer Flush */
+#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */
+#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */
+
+/* TWI_FIFO_STAT Masks */
+#define XMTSTAT 0x0003 /* Transmit FIFO Status */
+#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */
+#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */
+#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */
+
+#define RCVSTAT 0x000C /* Receive FIFO Status */
+#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */
+#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */
+#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */
+
+/* ************ CONTROLLER AREA NETWORK (CAN) MASKS ***************/
+/* CAN_CONTROL Masks */
+#define SRS 0x0001 /* Software Reset */
+#define DNM 0x0002 /* Device Net Mode */
+#define ABO 0x0004 /* Auto-Bus On Enable */
+#define TXPRIO 0x0008 /* TX Priority (Priority/Mailbox*) */
+#define WBA 0x0010 /* Wake-Up On CAN Bus Activity Enable */
+#define SMR 0x0020 /* Sleep Mode Request */
+#define CSR 0x0040 /* CAN Suspend Mode Request */
+#define CCR 0x0080 /* CAN Configuration Mode Request */
+
+/* CAN_STATUS Masks */
+#define WT 0x0001 /* TX Warning Flag */
+#define WR 0x0002 /* RX Warning Flag */
+#define EP 0x0004 /* Error Passive Mode */
+#define EBO 0x0008 /* Error Bus Off Mode */
+#define SMA 0x0020 /* Sleep Mode Acknowledge */
+#define CSA 0x0040 /* Suspend Mode Acknowledge */
+#define CCA 0x0080 /* Configuration Mode Acknowledge */
+#define MBPTR 0x1F00 /* Mailbox Pointer */
+#define TRM 0x4000 /* Transmit Mode */
+#define REC 0x8000 /* Receive Mode */
+
+/* CAN_CLOCK Masks */
+#define BRP 0x03FF /* Bit-Rate Pre-Scaler */
+
+/* CAN_TIMING Masks */
+#define TSEG1 0x000F /* Time Segment 1 */
+#define TSEG2 0x0070 /* Time Segment 2 */
+#define SAM 0x0080 /* Sampling */
+#define SJW 0x0300 /* Synchronization Jump Width */
+
+/* CAN_DEBUG Masks */
+#define DEC 0x0001 /* Disable CAN Error Counters */
+#define DRI 0x0002 /* Disable CAN RX Input */
+#define DTO 0x0004 /* Disable CAN TX Output */
+#define DIL 0x0008 /* Disable CAN Internal Loop */
+#define MAA 0x0010 /* Mode Auto-Acknowledge Enable */
+#define MRB 0x0020 /* Mode Read Back Enable */
+#define CDE 0x8000 /* CAN Debug Enable */
+
+/* CAN_CEC Masks */
+#define RXECNT 0x00FF /* Receive Error Counter */
+#define TXECNT 0xFF00 /* Transmit Error Counter */
+
+/* CAN_INTR Masks */
+#define MBRIF 0x0001 /* Mailbox Receive Interrupt */
+#define MBTIF 0x0002 /* Mailbox Transmit Interrupt */
+#define GIRQ 0x0004 /* Global Interrupt */
+#define SMACK 0x0008 /* Sleep Mode Acknowledge */
+#define CANTX 0x0040 /* CAN TX Bus Value */
+#define CANRX 0x0080 /* CAN RX Bus Value */
+
+/* CAN_MBxx_ID1 and CAN_MBxx_ID0 Masks */
+#define DFC 0xFFFF /* Data Filtering Code (If Enabled) (ID0) */
+#define EXTID_LO 0xFFFF /* Lower 16 Bits of Extended Identifier (ID0) */
+#define EXTID_HI 0x0003 /* Upper 2 Bits of Extended Identifier (ID1) */
+#define BASEID 0x1FFC /* Base Identifier */
+#define IDE 0x2000 /* Identifier Extension */
+#define RTR 0x4000 /* Remote Frame Transmission Request */
+#define AME 0x8000 /* Acceptance Mask Enable */
+
+/* CAN_MBxx_TIMESTAMP Masks */
+#define TSV 0xFFFF /* Timestamp */
+
+/* CAN_MBxx_LENGTH Masks */
+#define DLC 0x000F /* Data Length Code */
+
+/* CAN_AMxxH and CAN_AMxxL Masks */
+#define DFM 0xFFFF /* Data Field Mask (If Enabled) (CAN_AMxxL) */
+#define EXTID_LO 0xFFFF /* Lower 16 Bits of Extended Identifier (CAN_AMxxL) */
+#define EXTID_HI 0x0003 /* Upper 2 Bits of Extended Identifier (CAN_AMxxH) */
+#define BASEID 0x1FFC /* Base Identifier */
+#define AMIDE 0x2000 /* Acceptance Mask ID Extension Enable */
+#define FMD 0x4000 /* Full Mask Data Field Enable */
+#define FDF 0x8000 /* Filter On Data Field Enable */
+
+/* CAN_MC1 Masks */
+#define MC0 0x0001 /* Enable Mailbox 0 */
+#define MC1 0x0002 /* Enable Mailbox 1 */
+#define MC2 0x0004 /* Enable Mailbox 2 */
+#define MC3 0x0008 /* Enable Mailbox 3 */
+#define MC4 0x0010 /* Enable Mailbox 4 */
+#define MC5 0x0020 /* Enable Mailbox 5 */
+#define MC6 0x0040 /* Enable Mailbox 6 */
+#define MC7 0x0080 /* Enable Mailbox 7 */
+#define MC8 0x0100 /* Enable Mailbox 8 */
+#define MC9 0x0200 /* Enable Mailbox 9 */
+#define MC10 0x0400 /* Enable Mailbox 10 */
+#define MC11 0x0800 /* Enable Mailbox 11 */
+#define MC12 0x1000 /* Enable Mailbox 12 */
+#define MC13 0x2000 /* Enable Mailbox 13 */
+#define MC14 0x4000 /* Enable Mailbox 14 */
+#define MC15 0x8000 /* Enable Mailbox 15 */
+
+/* CAN_MC2 Masks */
+#define MC16 0x0001 /* Enable Mailbox 16 */
+#define MC17 0x0002 /* Enable Mailbox 17 */
+#define MC18 0x0004 /* Enable Mailbox 18 */
+#define MC19 0x0008 /* Enable Mailbox 19 */
+#define MC20 0x0010 /* Enable Mailbox 20 */
+#define MC21 0x0020 /* Enable Mailbox 21 */
+#define MC22 0x0040 /* Enable Mailbox 22 */
+#define MC23 0x0080 /* Enable Mailbox 23 */
+#define MC24 0x0100 /* Enable Mailbox 24 */
+#define MC25 0x0200 /* Enable Mailbox 25 */
+#define MC26 0x0400 /* Enable Mailbox 26 */
+#define MC27 0x0800 /* Enable Mailbox 27 */
+#define MC28 0x1000 /* Enable Mailbox 28 */
+#define MC29 0x2000 /* Enable Mailbox 29 */
+#define MC30 0x4000 /* Enable Mailbox 30 */
+#define MC31 0x8000 /* Enable Mailbox 31 */
+
+/* CAN_MD1 Masks */
+#define MD0 0x0001 /* Enable Mailbox 0 For Receive */
+#define MD1 0x0002 /* Enable Mailbox 1 For Receive */
+#define MD2 0x0004 /* Enable Mailbox 2 For Receive */
+#define MD3 0x0008 /* Enable Mailbox 3 For Receive */
+#define MD4 0x0010 /* Enable Mailbox 4 For Receive */
+#define MD5 0x0020 /* Enable Mailbox 5 For Receive */
+#define MD6 0x0040 /* Enable Mailbox 6 For Receive */
+#define MD7 0x0080 /* Enable Mailbox 7 For Receive */
+#define MD8 0x0100 /* Enable Mailbox 8 For Receive */
+#define MD9 0x0200 /* Enable Mailbox 9 For Receive */
+#define MD10 0x0400 /* Enable Mailbox 10 For Receive */
+#define MD11 0x0800 /* Enable Mailbox 11 For Receive */
+#define MD12 0x1000 /* Enable Mailbox 12 For Receive */
+#define MD13 0x2000 /* Enable Mailbox 13 For Receive */
+#define MD14 0x4000 /* Enable Mailbox 14 For Receive */
+#define MD15 0x8000 /* Enable Mailbox 15 For Receive */
+
+/* CAN_MD2 Masks */
+#define MD16 0x0001 /* Enable Mailbox 16 For Receive */
+#define MD17 0x0002 /* Enable Mailbox 17 For Receive */
+#define MD18 0x0004 /* Enable Mailbox 18 For Receive */
+#define MD19 0x0008 /* Enable Mailbox 19 For Receive */
+#define MD20 0x0010 /* Enable Mailbox 20 For Receive */
+#define MD21 0x0020 /* Enable Mailbox 21 For Receive */
+#define MD22 0x0040 /* Enable Mailbox 22 For Receive */
+#define MD23 0x0080 /* Enable Mailbox 23 For Receive */
+#define MD24 0x0100 /* Enable Mailbox 24 For Receive */
+#define MD25 0x0200 /* Enable Mailbox 25 For Receive */
+#define MD26 0x0400 /* Enable Mailbox 26 For Receive */
+#define MD27 0x0800 /* Enable Mailbox 27 For Receive */
+#define MD28 0x1000 /* Enable Mailbox 28 For Receive */
+#define MD29 0x2000 /* Enable Mailbox 29 For Receive */
+#define MD30 0x4000 /* Enable Mailbox 30 For Receive */
+#define MD31 0x8000 /* Enable Mailbox 31 For Receive */
+
+/* CAN_RMP1 Masks */
+#define RMP0 0x0001 /* RX Message Pending In Mailbox 0 */
+#define RMP1 0x0002 /* RX Message Pending In Mailbox 1 */
+#define RMP2 0x0004 /* RX Message Pending In Mailbox 2 */
+#define RMP3 0x0008 /* RX Message Pending In Mailbox 3 */
+#define RMP4 0x0010 /* RX Message Pending In Mailbox 4 */
+#define RMP5 0x0020 /* RX Message Pending In Mailbox 5 */
+#define RMP6 0x0040 /* RX Message Pending In Mailbox 6 */
+#define RMP7 0x0080 /* RX Message Pending In Mailbox 7 */
+#define RMP8 0x0100 /* RX Message Pending In Mailbox 8 */
+#define RMP9 0x0200 /* RX Message Pending In Mailbox 9 */
+#define RMP10 0x0400 /* RX Message Pending In Mailbox 10 */
+#define RMP11 0x0800 /* RX Message Pending In Mailbox 11 */
+#define RMP12 0x1000 /* RX Message Pending In Mailbox 12 */
+#define RMP13 0x2000 /* RX Message Pending In Mailbox 13 */
+#define RMP14 0x4000 /* RX Message Pending In Mailbox 14 */
+#define RMP15 0x8000 /* RX Message Pending In Mailbox 15 */
+
+/* CAN_RMP2 Masks */
+#define RMP16 0x0001 /* RX Message Pending In Mailbox 16 */
+#define RMP17 0x0002 /* RX Message Pending In Mailbox 17 */
+#define RMP18 0x0004 /* RX Message Pending In Mailbox 18 */
+#define RMP19 0x0008 /* RX Message Pending In Mailbox 19 */
+#define RMP20 0x0010 /* RX Message Pending In Mailbox 20 */
+#define RMP21 0x0020 /* RX Message Pending In Mailbox 21 */
+#define RMP22 0x0040 /* RX Message Pending In Mailbox 22 */
+#define RMP23 0x0080 /* RX Message Pending In Mailbox 23 */
+#define RMP24 0x0100 /* RX Message Pending In Mailbox 24 */
+#define RMP25 0x0200 /* RX Message Pending In Mailbox 25 */
+#define RMP26 0x0400 /* RX Message Pending In Mailbox 26 */
+#define RMP27 0x0800 /* RX Message Pending In Mailbox 27 */
+#define RMP28 0x1000 /* RX Message Pending In Mailbox 28 */
+#define RMP29 0x2000 /* RX Message Pending In Mailbox 29 */
+#define RMP30 0x4000 /* RX Message Pending In Mailbox 30 */
+#define RMP31 0x8000 /* RX Message Pending In Mailbox 31 */
+
+/* CAN_RML1 Masks */
+#define RML0 0x0001 /* RX Message Lost In Mailbox 0 */
+#define RML1 0x0002 /* RX Message Lost In Mailbox 1 */
+#define RML2 0x0004 /* RX Message Lost In Mailbox 2 */
+#define RML3 0x0008 /* RX Message Lost In Mailbox 3 */
+#define RML4 0x0010 /* RX Message Lost In Mailbox 4 */
+#define RML5 0x0020 /* RX Message Lost In Mailbox 5 */
+#define RML6 0x0040 /* RX Message Lost In Mailbox 6 */
+#define RML7 0x0080 /* RX Message Lost In Mailbox 7 */
+#define RML8 0x0100 /* RX Message Lost In Mailbox 8 */
+#define RML9 0x0200 /* RX Message Lost In Mailbox 9 */
+#define RML10 0x0400 /* RX Message Lost In Mailbox 10 */
+#define RML11 0x0800 /* RX Message Lost In Mailbox 11 */
+#define RML12 0x1000 /* RX Message Lost In Mailbox 12 */
+#define RML13 0x2000 /* RX Message Lost In Mailbox 13 */
+#define RML14 0x4000 /* RX Message Lost In Mailbox 14 */
+#define RML15 0x8000 /* RX Message Lost In Mailbox 15 */
+
+/* CAN_RML2 Masks */
+#define RML16 0x0001 /* RX Message Lost In Mailbox 16 */
+#define RML17 0x0002 /* RX Message Lost In Mailbox 17 */
+#define RML18 0x0004 /* RX Message Lost In Mailbox 18 */
+#define RML19 0x0008 /* RX Message Lost In Mailbox 19 */
+#define RML20 0x0010 /* RX Message Lost In Mailbox 20 */
+#define RML21 0x0020 /* RX Message Lost In Mailbox 21 */
+#define RML22 0x0040 /* RX Message Lost In Mailbox 22 */
+#define RML23 0x0080 /* RX Message Lost In Mailbox 23 */
+#define RML24 0x0100 /* RX Message Lost In Mailbox 24 */
+#define RML25 0x0200 /* RX Message Lost In Mailbox 25 */
+#define RML26 0x0400 /* RX Message Lost In Mailbox 26 */
+#define RML27 0x0800 /* RX Message Lost In Mailbox 27 */
+#define RML28 0x1000 /* RX Message Lost In Mailbox 28 */
+#define RML29 0x2000 /* RX Message Lost In Mailbox 29 */
+#define RML30 0x4000 /* RX Message Lost In Mailbox 30 */
+#define RML31 0x8000 /* RX Message Lost In Mailbox 31 */
+
+/* CAN_OPSS1 Masks */
+#define OPSS0 0x0001 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 0 */
+#define OPSS1 0x0002 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 1 */
+#define OPSS2 0x0004 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 2 */
+#define OPSS3 0x0008 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 3 */
+#define OPSS4 0x0010 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 4 */
+#define OPSS5 0x0020 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 5 */
+#define OPSS6 0x0040 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 6 */
+#define OPSS7 0x0080 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 7 */
+#define OPSS8 0x0100 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 8 */
+#define OPSS9 0x0200 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 9 */
+#define OPSS10 0x0400 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 10 */
+#define OPSS11 0x0800 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 11 */
+#define OPSS12 0x1000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 12 */
+#define OPSS13 0x2000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 13 */
+#define OPSS14 0x4000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 14 */
+#define OPSS15 0x8000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 15 */
+
+/* CAN_OPSS2 Masks */
+#define OPSS16 0x0001 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 16 */
+#define OPSS17 0x0002 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 17 */
+#define OPSS18 0x0004 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 18 */
+#define OPSS19 0x0008 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 19 */
+#define OPSS20 0x0010 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 20 */
+#define OPSS21 0x0020 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 21 */
+#define OPSS22 0x0040 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 22 */
+#define OPSS23 0x0080 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 23 */
+#define OPSS24 0x0100 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 24 */
+#define OPSS25 0x0200 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 25 */
+#define OPSS26 0x0400 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 26 */
+#define OPSS27 0x0800 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 27 */
+#define OPSS28 0x1000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 28 */
+#define OPSS29 0x2000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 29 */
+#define OPSS30 0x4000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 30 */
+#define OPSS31 0x8000 /* Enable RX Overwrite Protection or TX Single-Shot For Mailbox 31 */
+
+/* CAN_TRR1 Masks */
+#define TRR0 0x0001 /* Deny But Don't Lock Access To Mailbox 0 */
+#define TRR1 0x0002 /* Deny But Don't Lock Access To Mailbox 1 */
+#define TRR2 0x0004 /* Deny But Don't Lock Access To Mailbox 2 */
+#define TRR3 0x0008 /* Deny But Don't Lock Access To Mailbox 3 */
+#define TRR4 0x0010 /* Deny But Don't Lock Access To Mailbox 4 */
+#define TRR5 0x0020 /* Deny But Don't Lock Access To Mailbox 5 */
+#define TRR6 0x0040 /* Deny But Don't Lock Access To Mailbox 6 */
+#define TRR7 0x0080 /* Deny But Don't Lock Access To Mailbox 7 */
+#define TRR8 0x0100 /* Deny But Don't Lock Access To Mailbox 8 */
+#define TRR9 0x0200 /* Deny But Don't Lock Access To Mailbox 9 */
+#define TRR10 0x0400 /* Deny But Don't Lock Access To Mailbox 10 */
+#define TRR11 0x0800 /* Deny But Don't Lock Access To Mailbox 11 */
+#define TRR12 0x1000 /* Deny But Don't Lock Access To Mailbox 12 */
+#define TRR13 0x2000 /* Deny But Don't Lock Access To Mailbox 13 */
+#define TRR14 0x4000 /* Deny But Don't Lock Access To Mailbox 14 */
+#define TRR15 0x8000 /* Deny But Don't Lock Access To Mailbox 15 */
+
+/* CAN_TRR2 Masks */
+#define TRR16 0x0001 /* Deny But Don't Lock Access To Mailbox 16 */
+#define TRR17 0x0002 /* Deny But Don't Lock Access To Mailbox 17 */
+#define TRR18 0x0004 /* Deny But Don't Lock Access To Mailbox 18 */
+#define TRR19 0x0008 /* Deny But Don't Lock Access To Mailbox 19 */
+#define TRR20 0x0010 /* Deny But Don't Lock Access To Mailbox 20 */
+#define TRR21 0x0020 /* Deny But Don't Lock Access To Mailbox 21 */
+#define TRR22 0x0040 /* Deny But Don't Lock Access To Mailbox 22 */
+#define TRR23 0x0080 /* Deny But Don't Lock Access To Mailbox 23 */
+#define TRR24 0x0100 /* Deny But Don't Lock Access To Mailbox 24 */
+#define TRR25 0x0200 /* Deny But Don't Lock Access To Mailbox 25 */
+#define TRR26 0x0400 /* Deny But Don't Lock Access To Mailbox 26 */
+#define TRR27 0x0800 /* Deny But Don't Lock Access To Mailbox 27 */
+#define TRR28 0x1000 /* Deny But Don't Lock Access To Mailbox 28 */
+#define TRR29 0x2000 /* Deny But Don't Lock Access To Mailbox 29 */
+#define TRR30 0x4000 /* Deny But Don't Lock Access To Mailbox 30 */
+#define TRR31 0x8000 /* Deny But Don't Lock Access To Mailbox 31 */
+
+/* CAN_TRS1 Masks */
+#define TRS0 0x0001 /* Remote Frame Request For Mailbox 0 */
+#define TRS1 0x0002 /* Remote Frame Request For Mailbox 1 */
+#define TRS2 0x0004 /* Remote Frame Request For Mailbox 2 */
+#define TRS3 0x0008 /* Remote Frame Request For Mailbox 3 */
+#define TRS4 0x0010 /* Remote Frame Request For Mailbox 4 */
+#define TRS5 0x0020 /* Remote Frame Request For Mailbox 5 */
+#define TRS6 0x0040 /* Remote Frame Request For Mailbox 6 */
+#define TRS7 0x0080 /* Remote Frame Request For Mailbox 7 */
+#define TRS8 0x0100 /* Remote Frame Request For Mailbox 8 */
+#define TRS9 0x0200 /* Remote Frame Request For Mailbox 9 */
+#define TRS10 0x0400 /* Remote Frame Request For Mailbox 10 */
+#define TRS11 0x0800 /* Remote Frame Request For Mailbox 11 */
+#define TRS12 0x1000 /* Remote Frame Request For Mailbox 12 */
+#define TRS13 0x2000 /* Remote Frame Request For Mailbox 13 */
+#define TRS14 0x4000 /* Remote Frame Request For Mailbox 14 */
+#define TRS15 0x8000 /* Remote Frame Request For Mailbox 15 */
+
+/* CAN_TRS2 Masks */
+#define TRS16 0x0001 /* Remote Frame Request For Mailbox 16 */
+#define TRS17 0x0002 /* Remote Frame Request For Mailbox 17 */
+#define TRS18 0x0004 /* Remote Frame Request For Mailbox 18 */
+#define TRS19 0x0008 /* Remote Frame Request For Mailbox 19 */
+#define TRS20 0x0010 /* Remote Frame Request For Mailbox 20 */
+#define TRS21 0x0020 /* Remote Frame Request For Mailbox 21 */
+#define TRS22 0x0040 /* Remote Frame Request For Mailbox 22 */
+#define TRS23 0x0080 /* Remote Frame Request For Mailbox 23 */
+#define TRS24 0x0100 /* Remote Frame Request For Mailbox 24 */
+#define TRS25 0x0200 /* Remote Frame Request For Mailbox 25 */
+#define TRS26 0x0400 /* Remote Frame Request For Mailbox 26 */
+#define TRS27 0x0800 /* Remote Frame Request For Mailbox 27 */
+#define TRS28 0x1000 /* Remote Frame Request For Mailbox 28 */
+#define TRS29 0x2000 /* Remote Frame Request For Mailbox 29 */
+#define TRS30 0x4000 /* Remote Frame Request For Mailbox 30 */
+#define TRS31 0x8000 /* Remote Frame Request For Mailbox 31 */
+
+/* CAN_AA1 Masks */
+#define AA0 0x0001 /* Aborted Message In Mailbox 0 */
+#define AA1 0x0002 /* Aborted Message In Mailbox 1 */
+#define AA2 0x0004 /* Aborted Message In Mailbox 2 */
+#define AA3 0x0008 /* Aborted Message In Mailbox 3 */
+#define AA4 0x0010 /* Aborted Message In Mailbox 4 */
+#define AA5 0x0020 /* Aborted Message In Mailbox 5 */
+#define AA6 0x0040 /* Aborted Message In Mailbox 6 */
+#define AA7 0x0080 /* Aborted Message In Mailbox 7 */
+#define AA8 0x0100 /* Aborted Message In Mailbox 8 */
+#define AA9 0x0200 /* Aborted Message In Mailbox 9 */
+#define AA10 0x0400 /* Aborted Message In Mailbox 10 */
+#define AA11 0x0800 /* Aborted Message In Mailbox 11 */
+#define AA12 0x1000 /* Aborted Message In Mailbox 12 */
+#define AA13 0x2000 /* Aborted Message In Mailbox 13 */
+#define AA14 0x4000 /* Aborted Message In Mailbox 14 */
+#define AA15 0x8000 /* Aborted Message In Mailbox 15 */
+
+/* CAN_AA2 Masks */
+#define AA16 0x0001 /* Aborted Message In Mailbox 16 */
+#define AA17 0x0002 /* Aborted Message In Mailbox 17 */
+#define AA18 0x0004 /* Aborted Message In Mailbox 18 */
+#define AA19 0x0008 /* Aborted Message In Mailbox 19 */
+#define AA20 0x0010 /* Aborted Message In Mailbox 20 */
+#define AA21 0x0020 /* Aborted Message In Mailbox 21 */
+#define AA22 0x0040 /* Aborted Message In Mailbox 22 */
+#define AA23 0x0080 /* Aborted Message In Mailbox 23 */
+#define AA24 0x0100 /* Aborted Message In Mailbox 24 */
+#define AA25 0x0200 /* Aborted Message In Mailbox 25 */
+#define AA26 0x0400 /* Aborted Message In Mailbox 26 */
+#define AA27 0x0800 /* Aborted Message In Mailbox 27 */
+#define AA28 0x1000 /* Aborted Message In Mailbox 28 */
+#define AA29 0x2000 /* Aborted Message In Mailbox 29 */
+#define AA30 0x4000 /* Aborted Message In Mailbox 30 */
+#define AA31 0x8000 /* Aborted Message In Mailbox 31 */
+
+/* CAN_TA1 Masks */
+#define TA0 0x0001 /* Transmit Successful From Mailbox 0 */
+#define TA1 0x0002 /* Transmit Successful From Mailbox 1 */
+#define TA2 0x0004 /* Transmit Successful From Mailbox 2 */
+#define TA3 0x0008 /* Transmit Successful From Mailbox 3 */
+#define TA4 0x0010 /* Transmit Successful From Mailbox 4 */
+#define TA5 0x0020 /* Transmit Successful From Mailbox 5 */
+#define TA6 0x0040 /* Transmit Successful From Mailbox 6 */
+#define TA7 0x0080 /* Transmit Successful From Mailbox 7 */
+#define TA8 0x0100 /* Transmit Successful From Mailbox 8 */
+#define TA9 0x0200 /* Transmit Successful From Mailbox 9 */
+#define TA10 0x0400 /* Transmit Successful From Mailbox 10 */
+#define TA11 0x0800 /* Transmit Successful From Mailbox 11 */
+#define TA12 0x1000 /* Transmit Successful From Mailbox 12 */
+#define TA13 0x2000 /* Transmit Successful From Mailbox 13 */
+#define TA14 0x4000 /* Transmit Successful From Mailbox 14 */
+#define TA15 0x8000 /* Transmit Successful From Mailbox 15 */
+
+/* CAN_TA2 Masks */
+#define TA16 0x0001 /* Transmit Successful From Mailbox 16 */
+#define TA17 0x0002 /* Transmit Successful From Mailbox 17 */
+#define TA18 0x0004 /* Transmit Successful From Mailbox 18 */
+#define TA19 0x0008 /* Transmit Successful From Mailbox 19 */
+#define TA20 0x0010 /* Transmit Successful From Mailbox 20 */
+#define TA21 0x0020 /* Transmit Successful From Mailbox 21 */
+#define TA22 0x0040 /* Transmit Successful From Mailbox 22 */
+#define TA23 0x0080 /* Transmit Successful From Mailbox 23 */
+#define TA24 0x0100 /* Transmit Successful From Mailbox 24 */
+#define TA25 0x0200 /* Transmit Successful From Mailbox 25 */
+#define TA26 0x0400 /* Transmit Successful From Mailbox 26 */
+#define TA27 0x0800 /* Transmit Successful From Mailbox 27 */
+#define TA28 0x1000 /* Transmit Successful From Mailbox 28 */
+#define TA29 0x2000 /* Transmit Successful From Mailbox 29 */
+#define TA30 0x4000 /* Transmit Successful From Mailbox 30 */
+#define TA31 0x8000 /* Transmit Successful From Mailbox 31 */
+
+/* CAN_MBTD Masks */
+#define TDPTR 0x001F /* Mailbox To Temporarily Disable */
+#define TDA 0x0040 /* Temporary Disable Acknowledge */
+#define TDR 0x0080 /* Temporary Disable Request */
+
+/* CAN_RFH1 Masks */
+#define RFH0 0x0001 /* Enable Automatic Remote Frame Handling For Mailbox 0 */
+#define RFH1 0x0002 /* Enable Automatic Remote Frame Handling For Mailbox 1 */
+#define RFH2 0x0004 /* Enable Automatic Remote Frame Handling For Mailbox 2 */
+#define RFH3 0x0008 /* Enable Automatic Remote Frame Handling For Mailbox 3 */
+#define RFH4 0x0010 /* Enable Automatic Remote Frame Handling For Mailbox 4 */
+#define RFH5 0x0020 /* Enable Automatic Remote Frame Handling For Mailbox 5 */
+#define RFH6 0x0040 /* Enable Automatic Remote Frame Handling For Mailbox 6 */
+#define RFH7 0x0080 /* Enable Automatic Remote Frame Handling For Mailbox 7 */
+#define RFH8 0x0100 /* Enable Automatic Remote Frame Handling For Mailbox 8 */
+#define RFH9 0x0200 /* Enable Automatic Remote Frame Handling For Mailbox 9 */
+#define RFH10 0x0400 /* Enable Automatic Remote Frame Handling For Mailbox 10 */
+#define RFH11 0x0800 /* Enable Automatic Remote Frame Handling For Mailbox 11 */
+#define RFH12 0x1000 /* Enable Automatic Remote Frame Handling For Mailbox 12 */
+#define RFH13 0x2000 /* Enable Automatic Remote Frame Handling For Mailbox 13 */
+#define RFH14 0x4000 /* Enable Automatic Remote Frame Handling For Mailbox 14 */
+#define RFH15 0x8000 /* Enable Automatic Remote Frame Handling For Mailbox 15 */
+
+/* CAN_RFH2 Masks */
+#define RFH16 0x0001 /* Enable Automatic Remote Frame Handling For Mailbox 16 */
+#define RFH17 0x0002 /* Enable Automatic Remote Frame Handling For Mailbox 17 */
+#define RFH18 0x0004 /* Enable Automatic Remote Frame Handling For Mailbox 18 */
+#define RFH19 0x0008 /* Enable Automatic Remote Frame Handling For Mailbox 19 */
+#define RFH20 0x0010 /* Enable Automatic Remote Frame Handling For Mailbox 20 */
+#define RFH21 0x0020 /* Enable Automatic Remote Frame Handling For Mailbox 21 */
+#define RFH22 0x0040 /* Enable Automatic Remote Frame Handling For Mailbox 22 */
+#define RFH23 0x0080 /* Enable Automatic Remote Frame Handling For Mailbox 23 */
+#define RFH24 0x0100 /* Enable Automatic Remote Frame Handling For Mailbox 24 */
+#define RFH25 0x0200 /* Enable Automatic Remote Frame Handling For Mailbox 25 */
+#define RFH26 0x0400 /* Enable Automatic Remote Frame Handling For Mailbox 26 */
+#define RFH27 0x0800 /* Enable Automatic Remote Frame Handling For Mailbox 27 */
+#define RFH28 0x1000 /* Enable Automatic Remote Frame Handling For Mailbox 28 */
+#define RFH29 0x2000 /* Enable Automatic Remote Frame Handling For Mailbox 29 */
+#define RFH30 0x4000 /* Enable Automatic Remote Frame Handling For Mailbox 30 */
+#define RFH31 0x8000 /* Enable Automatic Remote Frame Handling For Mailbox 31 */
+
+/* CAN_MBTIF1 Masks */
+#define MBTIF0 0x0001 /* TX Interrupt Active In Mailbox 0 */
+#define MBTIF1 0x0002 /* TX Interrupt Active In Mailbox 1 */
+#define MBTIF2 0x0004 /* TX Interrupt Active In Mailbox 2 */
+#define MBTIF3 0x0008 /* TX Interrupt Active In Mailbox 3 */
+#define MBTIF4 0x0010 /* TX Interrupt Active In Mailbox 4 */
+#define MBTIF5 0x0020 /* TX Interrupt Active In Mailbox 5 */
+#define MBTIF6 0x0040 /* TX Interrupt Active In Mailbox 6 */
+#define MBTIF7 0x0080 /* TX Interrupt Active In Mailbox 7 */
+#define MBTIF8 0x0100 /* TX Interrupt Active In Mailbox 8 */
+#define MBTIF9 0x0200 /* TX Interrupt Active In Mailbox 9 */
+#define MBTIF10 0x0400 /* TX Interrupt Active In Mailbox 10 */
+#define MBTIF11 0x0800 /* TX Interrupt Active In Mailbox 11 */
+#define MBTIF12 0x1000 /* TX Interrupt Active In Mailbox 12 */
+#define MBTIF13 0x2000 /* TX Interrupt Active In Mailbox 13 */
+#define MBTIF14 0x4000 /* TX Interrupt Active In Mailbox 14 */
+#define MBTIF15 0x8000 /* TX Interrupt Active In Mailbox 15 */
+
+/* CAN_MBTIF2 Masks */
+#define MBTIF16 0x0001 /* TX Interrupt Active In Mailbox 16 */
+#define MBTIF17 0x0002 /* TX Interrupt Active In Mailbox 17 */
+#define MBTIF18 0x0004 /* TX Interrupt Active In Mailbox 18 */
+#define MBTIF19 0x0008 /* TX Interrupt Active In Mailbox 19 */
+#define MBTIF20 0x0010 /* TX Interrupt Active In Mailbox 20 */
+#define MBTIF21 0x0020 /* TX Interrupt Active In Mailbox 21 */
+#define MBTIF22 0x0040 /* TX Interrupt Active In Mailbox 22 */
+#define MBTIF23 0x0080 /* TX Interrupt Active In Mailbox 23 */
+#define MBTIF24 0x0100 /* TX Interrupt Active In Mailbox 24 */
+#define MBTIF25 0x0200 /* TX Interrupt Active In Mailbox 25 */
+#define MBTIF26 0x0400 /* TX Interrupt Active In Mailbox 26 */
+#define MBTIF27 0x0800 /* TX Interrupt Active In Mailbox 27 */
+#define MBTIF28 0x1000 /* TX Interrupt Active In Mailbox 28 */
+#define MBTIF29 0x2000 /* TX Interrupt Active In Mailbox 29 */
+#define MBTIF30 0x4000 /* TX Interrupt Active In Mailbox 30 */
+#define MBTIF31 0x8000 /* TX Interrupt Active In Mailbox 31 */
+
+/* CAN_MBRIF1 Masks */
+#define MBRIF0 0x0001 /* RX Interrupt Active In Mailbox 0 */
+#define MBRIF1 0x0002 /* RX Interrupt Active In Mailbox 1 */
+#define MBRIF2 0x0004 /* RX Interrupt Active In Mailbox 2 */
+#define MBRIF3 0x0008 /* RX Interrupt Active In Mailbox 3 */
+#define MBRIF4 0x0010 /* RX Interrupt Active In Mailbox 4 */
+#define MBRIF5 0x0020 /* RX Interrupt Active In Mailbox 5 */
+#define MBRIF6 0x0040 /* RX Interrupt Active In Mailbox 6 */
+#define MBRIF7 0x0080 /* RX Interrupt Active In Mailbox 7 */
+#define MBRIF8 0x0100 /* RX Interrupt Active In Mailbox 8 */
+#define MBRIF9 0x0200 /* RX Interrupt Active In Mailbox 9 */
+#define MBRIF10 0x0400 /* RX Interrupt Active In Mailbox 10 */
+#define MBRIF11 0x0800 /* RX Interrupt Active In Mailbox 11 */
+#define MBRIF12 0x1000 /* RX Interrupt Active In Mailbox 12 */
+#define MBRIF13 0x2000 /* RX Interrupt Active In Mailbox 13 */
+#define MBRIF14 0x4000 /* RX Interrupt Active In Mailbox 14 */
+#define MBRIF15 0x8000 /* RX Interrupt Active In Mailbox 15 */
+
+/* CAN_MBRIF2 Masks */
+#define MBRIF16 0x0001 /* RX Interrupt Active In Mailbox 16 */
+#define MBRIF17 0x0002 /* RX Interrupt Active In Mailbox 17 */
+#define MBRIF18 0x0004 /* RX Interrupt Active In Mailbox 18 */
+#define MBRIF19 0x0008 /* RX Interrupt Active In Mailbox 19 */
+#define MBRIF20 0x0010 /* RX Interrupt Active In Mailbox 20 */
+#define MBRIF21 0x0020 /* RX Interrupt Active In Mailbox 21 */
+#define MBRIF22 0x0040 /* RX Interrupt Active In Mailbox 22 */
+#define MBRIF23 0x0080 /* RX Interrupt Active In Mailbox 23 */
+#define MBRIF24 0x0100 /* RX Interrupt Active In Mailbox 24 */
+#define MBRIF25 0x0200 /* RX Interrupt Active In Mailbox 25 */
+#define MBRIF26 0x0400 /* RX Interrupt Active In Mailbox 26 */
+#define MBRIF27 0x0800 /* RX Interrupt Active In Mailbox 27 */
+#define MBRIF28 0x1000 /* RX Interrupt Active In Mailbox 28 */
+#define MBRIF29 0x2000 /* RX Interrupt Active In Mailbox 29 */
+#define MBRIF30 0x4000 /* RX Interrupt Active In Mailbox 30 */
+#define MBRIF31 0x8000 /* RX Interrupt Active In Mailbox 31 */
+
+/* CAN_MBIM1 Masks */
+#define MBIM0 0x0001 /* Enable Interrupt For Mailbox 0 */
+#define MBIM1 0x0002 /* Enable Interrupt For Mailbox 1 */
+#define MBIM2 0x0004 /* Enable Interrupt For Mailbox 2 */
+#define MBIM3 0x0008 /* Enable Interrupt For Mailbox 3 */
+#define MBIM4 0x0010 /* Enable Interrupt For Mailbox 4 */
+#define MBIM5 0x0020 /* Enable Interrupt For Mailbox 5 */
+#define MBIM6 0x0040 /* Enable Interrupt For Mailbox 6 */
+#define MBIM7 0x0080 /* Enable Interrupt For Mailbox 7 */
+#define MBIM8 0x0100 /* Enable Interrupt For Mailbox 8 */
+#define MBIM9 0x0200 /* Enable Interrupt For Mailbox 9 */
+#define MBIM10 0x0400 /* Enable Interrupt For Mailbox 10 */
+#define MBIM11 0x0800 /* Enable Interrupt For Mailbox 11 */
+#define MBIM12 0x1000 /* Enable Interrupt For Mailbox 12 */
+#define MBIM13 0x2000 /* Enable Interrupt For Mailbox 13 */
+#define MBIM14 0x4000 /* Enable Interrupt For Mailbox 14 */
+#define MBIM15 0x8000 /* Enable Interrupt For Mailbox 15 */
+
+/* CAN_MBIM2 Masks */
+#define MBIM16 0x0001 /* Enable Interrupt For Mailbox 16 */
+#define MBIM17 0x0002 /* Enable Interrupt For Mailbox 17 */
+#define MBIM18 0x0004 /* Enable Interrupt For Mailbox 18 */
+#define MBIM19 0x0008 /* Enable Interrupt For Mailbox 19 */
+#define MBIM20 0x0010 /* Enable Interrupt For Mailbox 20 */
+#define MBIM21 0x0020 /* Enable Interrupt For Mailbox 21 */
+#define MBIM22 0x0040 /* Enable Interrupt For Mailbox 22 */
+#define MBIM23 0x0080 /* Enable Interrupt For Mailbox 23 */
+#define MBIM24 0x0100 /* Enable Interrupt For Mailbox 24 */
+#define MBIM25 0x0200 /* Enable Interrupt For Mailbox 25 */
+#define MBIM26 0x0400 /* Enable Interrupt For Mailbox 26 */
+#define MBIM27 0x0800 /* Enable Interrupt For Mailbox 27 */
+#define MBIM28 0x1000 /* Enable Interrupt For Mailbox 28 */
+#define MBIM29 0x2000 /* Enable Interrupt For Mailbox 29 */
+#define MBIM30 0x4000 /* Enable Interrupt For Mailbox 30 */
+#define MBIM31 0x8000 /* Enable Interrupt For Mailbox 31 */
+
+/* CAN_GIM Masks */
+#define EWTIM 0x0001 /* Enable TX Error Count Interrupt */
+#define EWRIM 0x0002 /* Enable RX Error Count Interrupt */
+#define EPIM 0x0004 /* Enable Error-Passive Mode Interrupt */
+#define BOIM 0x0008 /* Enable Bus Off Interrupt */
+#define WUIM 0x0010 /* Enable Wake-Up Interrupt */
+#define UIAIM 0x0020 /* Enable Access To Unimplemented Address Interrupt */
+#define AAIM 0x0040 /* Enable Abort Acknowledge Interrupt */
+#define RMLIM 0x0080 /* Enable RX Message Lost Interrupt */
+#define UCEIM 0x0100 /* Enable Universal Counter Overflow Interrupt */
+#define EXTIM 0x0200 /* Enable External Trigger Output Interrupt */
+#define ADIM 0x0400 /* Enable Access Denied Interrupt */
+
+/* CAN_GIS Masks */
+#define EWTIS 0x0001 /* TX Error Count IRQ Status */
+#define EWRIS 0x0002 /* RX Error Count IRQ Status */
+#define EPIS 0x0004 /* Error-Passive Mode IRQ Status */
+#define BOIS 0x0008 /* Bus Off IRQ Status */
+#define WUIS 0x0010 /* Wake-Up IRQ Status */
+#define UIAIS 0x0020 /* Access To Unimplemented Address IRQ Status */
+#define AAIS 0x0040 /* Abort Acknowledge IRQ Status */
+#define RMLIS 0x0080 /* RX Message Lost IRQ Status */
+#define UCEIS 0x0100 /* Universal Counter Overflow IRQ Status */
+#define EXTIS 0x0200 /* External Trigger Output IRQ Status */
+#define ADIS 0x0400 /* Access Denied IRQ Status */
+
+/* CAN_GIF Masks */
+#define EWTIF 0x0001 /* TX Error Count IRQ Flag */
+#define EWRIF 0x0002 /* RX Error Count IRQ Flag */
+#define EPIF 0x0004 /* Error-Passive Mode IRQ Flag */
+#define BOIF 0x0008 /* Bus Off IRQ Flag */
+#define WUIF 0x0010 /* Wake-Up IRQ Flag */
+#define UIAIF 0x0020 /* Access To Unimplemented Address IRQ Flag */
+#define AAIF 0x0040 /* Abort Acknowledge IRQ Flag */
+#define RMLIF 0x0080 /* RX Message Lost IRQ Flag */
+#define UCEIF 0x0100 /* Universal Counter Overflow IRQ Flag */
+#define EXTIF 0x0200 /* External Trigger Output IRQ Flag */
+#define ADIF 0x0400 /* Access Denied IRQ Flag */
+
+/* CAN_UCCNF Masks */
+#define UCCNF 0x000F /* Universal Counter Mode */
+#define UC_STAMP 0x0001 /* Timestamp Mode */
+#define UC_WDOG 0x0002 /* Watchdog Mode */
+#define UC_AUTOTX 0x0003 /* Auto-Transmit Mode */
+#define UC_ERROR 0x0006 /* CAN Error Frame Count */
+#define UC_OVER 0x0007 /* CAN Overload Frame Count */
+#define UC_LOST 0x0008 /* Arbitration Lost During TX Count */
+#define UC_AA 0x0009 /* TX Abort Count */
+#define UC_TA 0x000A /* TX Successful Count */
+#define UC_REJECT 0x000B /* RX Message Rejected Count */
+#define UC_RML 0x000C /* RX Message Lost Count */
+#define UC_RX 0x000D /* Total Successful RX Messages Count */
+#define UC_RMP 0x000E /* Successful RX W/Matching ID Count */
+#define UC_ALL 0x000F /* Correct Message On CAN Bus Line Count */
+#define UCRC 0x0020 /* Universal Counter Reload/Clear */
+#define UCCT 0x0040 /* Universal Counter CAN Trigger */
+#define UCE 0x0080 /* Universal Counter Enable */
+
+/* CAN_ESR Masks */
+#define ACKE 0x0004 /* Acknowledge Error */
+#define SER 0x0008 /* Stuff Error */
+#define CRCE 0x0010 /* CRC Error */
+#define SA0 0x0020 /* Stuck At Dominant Error */
+#define BEF 0x0040 /* Bit Error Flag */
+#define FER 0x0080 /* Form Error Flag */
+
+/* CAN_EWR Masks */
+#define EWLREC 0x00FF /* RX Error Count Limit (For EWRIS) */
+#define EWLTEC 0xFF00 /* TX Error Count Limit (For EWTIS) */
+
+/* ******************* PIN CONTROL REGISTER MASKS ************************/
+/* PORT_MUX Masks */
+#define PJSE 0x0001 /* Port J SPI/SPORT Enable */
+#define PJSE_SPORT 0x0000 /* Enable TFS0/DT0PRI */
+#define PJSE_SPI 0x0001 /* Enable SPI_SSEL3:2 */
+
+#define PJCE(x) (((x)&0x3)<<1) /* Port J CAN/SPI/SPORT Enable */
+#define PJCE_SPORT 0x0000 /* Enable DR0SEC/DT0SEC */
+#define PJCE_CAN 0x0002 /* Enable CAN RX/TX */
+#define PJCE_SPI 0x0004 /* Enable SPI_SSEL7 */
+
+#define PFDE 0x0008 /* Port F DMA Request Enable */
+#define PGDE_UART 0x0000 /* Enable UART0 RX/TX */
+#define PGDE_DMA 0x0008 /* Enable DMAR1:0 */
+
+#define PFTE 0x0010 /* Port F Timer Enable */
+#define PFTE_UART 0x0000 /* Enable UART1 RX/TX */
+#define PFTE_TIMER 0x0010 /* Enable TMR7:6 */
+
+#define PFS6E 0x0020 /* Port F SPI SSEL 6 Enable */
+#define PFS6E_TIMER 0x0000 /* Enable TMR5 */
+#define PFS6E_SPI 0x0020 /* Enable SPI_SSEL6 */
+
+#define PFS5E 0x0040 /* Port F SPI SSEL 5 Enable */
+#define PFS5E_TIMER 0x0000 /* Enable TMR4 */
+#define PFS5E_SPI 0x0040 /* Enable SPI_SSEL5 */
+
+#define PFS4E 0x0080 /* Port F SPI SSEL 4 Enable */
+#define PFS4E_TIMER 0x0000 /* Enable TMR3 */
+#define PFS4E_SPI 0x0080 /* Enable SPI_SSEL4 */
+
+#define PFFE 0x0100 /* Port F PPI Frame Sync Enable */
+#define PFFE_TIMER 0x0000 /* Enable TMR2 */
+#define PFFE_PPI 0x0100 /* Enable PPI FS3 */
+
+#define PGSE 0x0200 /* Port G SPORT1 Secondary Enable */
+#define PGSE_PPI 0x0000 /* Enable PPI D9:8 */
+#define PGSE_SPORT 0x0200 /* Enable DR1SEC/DT1SEC */
+
+#define PGRE 0x0400 /* Port G SPORT1 Receive Enable */
+#define PGRE_PPI 0x0000 /* Enable PPI D12:10 */
+#define PGRE_SPORT 0x0400 /* Enable DR1PRI/RFS1/RSCLK1 */
+
+#define PGTE 0x0800 /* Port G SPORT1 Transmit Enable */
+#define PGTE_PPI 0x0000 /* Enable PPI D15:13 */
+#define PGTE_SPORT 0x0800 /* Enable DT1PRI/TFS1/TSCLK1 */
+
+/* ****************** HANDSHAKE DMA (HDMA) MASKS *********************/
+/* HDMAx_CTL Masks */
+#define HMDMAEN 0x0001 /* Enable Handshake DMA 0/1 */
+#define REP 0x0002 /* HDMA Request Polarity */
+#define UTE 0x0004 /* Urgency Threshold Enable */
+#define OIE 0x0010 /* Overflow Interrupt Enable */
+#define BDIE 0x0020 /* Block Done Interrupt Enable */
+#define MBDI 0x0040 /* Mask Block Done IRQ If Pending ECNT */
+#define DRQ 0x0300 /* HDMA Request Type */
+#define DRQ_NONE 0x0000 /* No Request */
+#define DRQ_SINGLE 0x0100 /* Channels Request Single */
+#define DRQ_MULTI 0x0200 /* Channels Request Multi (Default) */
+#define DRQ_URGENT 0x0300 /* Channels Request Multi Urgent */
+#define RBC 0x1000 /* Reload BCNT With IBCNT */
+#define PS 0x2000 /* HDMA Pin Status */
+#define OI 0x4000 /* Overflow Interrupt Generated */
+#define BDI 0x8000 /* Block Done Interrupt Generated */
+
+#endif /* _DEF_BF534_H */
diff --git a/include/asm-blackfin/mach-bf537/defBF537.h b/include/asm-blackfin/mach-bf537/defBF537.h
new file mode 100644
index 0000000..26f9c02
--- /dev/null
+++ b/include/asm-blackfin/mach-bf537/defBF537.h
@@ -0,0 +1,404 @@
+/*
+ * file: include/asm-blackfin/mach-bf537/defbf537.h
+ * based on:
+ * author:
+ *
+ * created:
+ * description:
+ * system mmr register map
+ * rev:
+ *
+ * modified:
+ *
+ *
+ * bugs: enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose. see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _DEF_BF537_H
+#define _DEF_BF537_H
+
+/*include all Core registers and bit definitions*/
+#include "defBF537.h"
+
+/*include core specific register pointer definitions*/
+#include <asm/mach-common/cdef_LPBlackfin.h>
+
+/************************************************************************************
+** Define EMAC Section Unique to BF536/BF537
+*************************************************************************************/
+
+/* 10/100 Ethernet Controller (0xFFC03000 - 0xFFC031FF) */
+#define EMAC_OPMODE 0xFFC03000 /* Operating Mode Register */
+#define EMAC_ADDRLO 0xFFC03004 /* Address Low (32 LSBs) Register */
+#define EMAC_ADDRHI 0xFFC03008 /* Address High (16 MSBs) Register */
+#define EMAC_HASHLO 0xFFC0300C /* Multicast Hash Table Low (Bins 31-0) Register */
+#define EMAC_HASHHI 0xFFC03010 /* Multicast Hash Table High (Bins 63-32) Register */
+#define EMAC_STAADD 0xFFC03014 /* Station Management Address Register */
+#define EMAC_STADAT 0xFFC03018 /* Station Management Data Register */
+#define EMAC_FLC 0xFFC0301C /* Flow Control Register */
+#define EMAC_VLAN1 0xFFC03020 /* VLAN1 Tag Register */
+#define EMAC_VLAN2 0xFFC03024 /* VLAN2 Tag Register */
+#define EMAC_WKUP_CTL 0xFFC0302C /* Wake-Up Control/Status Register */
+#define EMAC_WKUP_FFMSK0 0xFFC03030 /* Wake-Up Frame Filter 0 Byte Mask Register */
+#define EMAC_WKUP_FFMSK1 0xFFC03034 /* Wake-Up Frame Filter 1 Byte Mask Register */
+#define EMAC_WKUP_FFMSK2 0xFFC03038 /* Wake-Up Frame Filter 2 Byte Mask Register */
+#define EMAC_WKUP_FFMSK3 0xFFC0303C /* Wake-Up Frame Filter 3 Byte Mask Register */
+#define EMAC_WKUP_FFCMD 0xFFC03040 /* Wake-Up Frame Filter Commands Register */
+#define EMAC_WKUP_FFOFF 0xFFC03044 /* Wake-Up Frame Filter Offsets Register */
+#define EMAC_WKUP_FFCRC0 0xFFC03048 /* Wake-Up Frame Filter 0,1 CRC-16 Register */
+#define EMAC_WKUP_FFCRC1 0xFFC0304C /* Wake-Up Frame Filter 2,3 CRC-16 Register */
+
+#define EMAC_SYSCTL 0xFFC03060 /* EMAC System Control Register */
+#define EMAC_SYSTAT 0xFFC03064 /* EMAC System Status Register */
+#define EMAC_RX_STAT 0xFFC03068 /* RX Current Frame Status Register */
+#define EMAC_RX_STKY 0xFFC0306C /* RX Sticky Frame Status Register */
+#define EMAC_RX_IRQE 0xFFC03070 /* RX Frame Status Interrupt Enables Register */
+#define EMAC_TX_STAT 0xFFC03074 /* TX Current Frame Status Register */
+#define EMAC_TX_STKY 0xFFC03078 /* TX Sticky Frame Status Register */
+#define EMAC_TX_IRQE 0xFFC0307C /* TX Frame Status Interrupt Enables Register */
+
+#define EMAC_MMC_CTL 0xFFC03080 /* MMC Counter Control Register */
+#define EMAC_MMC_RIRQS 0xFFC03084 /* MMC RX Interrupt Status Register */
+#define EMAC_MMC_RIRQE 0xFFC03088 /* MMC RX Interrupt Enables Register */
+#define EMAC_MMC_TIRQS 0xFFC0308C /* MMC TX Interrupt Status Register */
+#define EMAC_MMC_TIRQE 0xFFC03090 /* MMC TX Interrupt Enables Register */
+
+#define EMAC_RXC_OK 0xFFC03100 /* RX Frame Successful Count */
+#define EMAC_RXC_FCS 0xFFC03104 /* RX Frame FCS Failure Count */
+#define EMAC_RXC_ALIGN 0xFFC03108 /* RX Alignment Error Count */
+#define EMAC_RXC_OCTET 0xFFC0310C /* RX Octets Successfully Received Count */
+#define EMAC_RXC_DMAOVF 0xFFC03110 /* Internal MAC Sublayer Error RX Frame Count */
+#define EMAC_RXC_UNICST 0xFFC03114 /* Unicast RX Frame Count */
+#define EMAC_RXC_MULTI 0xFFC03118 /* Multicast RX Frame Count */
+#define EMAC_RXC_BROAD 0xFFC0311C /* Broadcast RX Frame Count */
+#define EMAC_RXC_LNERRI 0xFFC03120 /* RX Frame In Range Error Count */
+#define EMAC_RXC_LNERRO 0xFFC03124 /* RX Frame Out Of Range Error Count */
+#define EMAC_RXC_LONG 0xFFC03128 /* RX Frame Too Long Count */
+#define EMAC_RXC_MACCTL 0xFFC0312C /* MAC Control RX Frame Count */
+#define EMAC_RXC_OPCODE 0xFFC03130 /* Unsupported Op-Code RX Frame Count */
+#define EMAC_RXC_PAUSE 0xFFC03134 /* MAC Control Pause RX Frame Count */
+#define EMAC_RXC_ALLFRM 0xFFC03138 /* Overall RX Frame Count */
+#define EMAC_RXC_ALLOCT 0xFFC0313C /* Overall RX Octet Count */
+#define EMAC_RXC_TYPED 0xFFC03140 /* Type/Length Consistent RX Frame Count */
+#define EMAC_RXC_SHORT 0xFFC03144 /* RX Frame Fragment Count - Byte Count x < 64 */
+#define EMAC_RXC_EQ64 0xFFC03148 /* Good RX Frame Count - Byte Count x = 64 */
+#define EMAC_RXC_LT128 0xFFC0314C /* Good RX Frame Count - Byte Count 64 <= x < 128 */
+#define EMAC_RXC_LT256 0xFFC03150 /* Good RX Frame Count - Byte Count 128 <= x < 256 */
+#define EMAC_RXC_LT512 0xFFC03154 /* Good RX Frame Count - Byte Count 256 <= x < 512 */
+#define EMAC_RXC_LT1024 0xFFC03158 /* Good RX Frame Count - Byte Count 512 <= x < 1024 */
+#define EMAC_RXC_GE1024 0xFFC0315C /* Good RX Frame Count - Byte Count x >= 1024 */
+
+#define EMAC_TXC_OK 0xFFC03180 /* TX Frame Successful Count */
+#define EMAC_TXC_1COL 0xFFC03184 /* TX Frames Successful After Single Collision Count */
+#define EMAC_TXC_GT1COL 0xFFC03188 /* TX Frames Successful After Multiple Collisions Count */
+#define EMAC_TXC_OCTET 0xFFC0318C /* TX Octets Successfully Received Count */
+#define EMAC_TXC_DEFER 0xFFC03190 /* TX Frame Delayed Due To Busy Count */
+#define EMAC_TXC_LATECL 0xFFC03194 /* Late TX Collisions Count */
+#define EMAC_TXC_XS_COL 0xFFC03198 /* TX Frame Failed Due To Excessive Collisions Count */
+#define EMAC_TXC_DMAUND 0xFFC0319C /* Internal MAC Sublayer Error TX Frame Count */
+#define EMAC_TXC_CRSERR 0xFFC031A0 /* Carrier Sense Deasserted During TX Frame Count */
+#define EMAC_TXC_UNICST 0xFFC031A4 /* Unicast TX Frame Count */
+#define EMAC_TXC_MULTI 0xFFC031A8 /* Multicast TX Frame Count */
+#define EMAC_TXC_BROAD 0xFFC031AC /* Broadcast TX Frame Count */
+#define EMAC_TXC_XS_DFR 0xFFC031B0 /* TX Frames With Excessive Deferral Count */
+#define EMAC_TXC_MACCTL 0xFFC031B4 /* MAC Control TX Frame Count */
+#define EMAC_TXC_ALLFRM 0xFFC031B8 /* Overall TX Frame Count */
+#define EMAC_TXC_ALLOCT 0xFFC031BC /* Overall TX Octet Count */
+#define EMAC_TXC_EQ64 0xFFC031C0 /* Good TX Frame Count - Byte Count x = 64 */
+#define EMAC_TXC_LT128 0xFFC031C4 /* Good TX Frame Count - Byte Count 64 <= x < 128 */
+#define EMAC_TXC_LT256 0xFFC031C8 /* Good TX Frame Count - Byte Count 128 <= x < 256 */
+#define EMAC_TXC_LT512 0xFFC031CC /* Good TX Frame Count - Byte Count 256 <= x < 512 */
+#define EMAC_TXC_LT1024 0xFFC031D0 /* Good TX Frame Count - Byte Count 512 <= x < 1024 */
+#define EMAC_TXC_GE1024 0xFFC031D4 /* Good TX Frame Count - Byte Count x >= 1024 */
+#define EMAC_TXC_ABORT 0xFFC031D8 /* Total TX Frames Aborted Count */
+
+/* Listing for IEEE-Supported Count Registers */
+#define FramesReceivedOK EMAC_RXC_OK /* RX Frame Successful Count */
+#define FrameCheckSequenceErrors EMAC_RXC_FCS /* RX Frame FCS Failure Count */
+#define AlignmentErrors EMAC_RXC_ALIGN /* RX Alignment Error Count */
+#define OctetsReceivedOK EMAC_RXC_OCTET /* RX Octets Successfully Received Count */
+#define FramesLostDueToIntMACRcvError EMAC_RXC_DMAOVF /* Internal MAC Sublayer Error RX Frame Count */
+#define UnicastFramesReceivedOK EMAC_RXC_UNICST /* Unicast RX Frame Count */
+#define MulticastFramesReceivedOK EMAC_RXC_MULTI /* Multicast RX Frame Count */
+#define BroadcastFramesReceivedOK EMAC_RXC_BROAD /* Broadcast RX Frame Count */
+#define InRangeLengthErrors EMAC_RXC_LNERRI /* RX Frame In Range Error Count */
+#define OutOfRangeLengthField EMAC_RXC_LNERRO /* RX Frame Out Of Range Error Count */
+#define FrameTooLongErrors EMAC_RXC_LONG /* RX Frame Too Long Count */
+#define MACControlFramesReceived EMAC_RXC_MACCTL /* MAC Control RX Frame Count */
+#define UnsupportedOpcodesReceived EMAC_RXC_OPCODE /* Unsupported Op-Code RX Frame Count */
+#define PAUSEMACCtrlFramesReceived EMAC_RXC_PAUSE /* MAC Control Pause RX Frame Count */
+#define FramesReceivedAll EMAC_RXC_ALLFRM /* Overall RX Frame Count */
+#define OctetsReceivedAll EMAC_RXC_ALLOCT /* Overall RX Octet Count */
+#define TypedFramesReceived EMAC_RXC_TYPED /* Type/Length Consistent RX Frame Count */
+#define FramesLenLt64Received EMAC_RXC_SHORT /* RX Frame Fragment Count - Byte Count x < 64 */
+#define FramesLenEq64Received EMAC_RXC_EQ64 /* Good RX Frame Count - Byte Count x = 64 */
+#define FramesLen65_127Received EMAC_RXC_LT128 /* Good RX Frame Count - Byte Count 64 <= x < 128 */
+#define FramesLen128_255Received EMAC_RXC_LT256 /* Good RX Frame Count - Byte Count 128 <= x < 256 */
+#define FramesLen256_511Received EMAC_RXC_LT512 /* Good RX Frame Count - Byte Count 256 <= x < 512 */
+#define FramesLen512_1023Received EMAC_RXC_LT1024 /* Good RX Frame Count - Byte Count 512 <= x < 1024 */
+#define FramesLen1024_MaxReceived EMAC_RXC_GE1024 /* Good RX Frame Count - Byte Count x >= 1024 */
+
+#define FramesTransmittedOK EMAC_TXC_OK /* TX Frame Successful Count */
+#define SingleCollisionFrames EMAC_TXC_1COL /* TX Frames Successful After Single Collision Count */
+#define MultipleCollisionFrames EMAC_TXC_GT1COL /* TX Frames Successful After Multiple Collisions Count */
+#define OctetsTransmittedOK EMAC_TXC_OCTET /* TX Octets Successfully Received Count */
+#define FramesWithDeferredXmissions EMAC_TXC_DEFER /* TX Frame Delayed Due To Busy Count */
+#define LateCollisions EMAC_TXC_LATECL /* Late TX Collisions Count */
+#define FramesAbortedDueToXSColls EMAC_TXC_XS_COL /* TX Frame Failed Due To Excessive Collisions Count */
+#define FramesLostDueToIntMacXmitError EMAC_TXC_DMAUND /* Internal MAC Sublayer Error TX Frame Count */
+#define CarrierSenseErrors EMAC_TXC_CRSERR /* Carrier Sense Deasserted During TX Frame Count */
+#define UnicastFramesXmittedOK EMAC_TXC_UNICST /* Unicast TX Frame Count */
+#define MulticastFramesXmittedOK EMAC_TXC_MULTI /* Multicast TX Frame Count */
+#define BroadcastFramesXmittedOK EMAC_TXC_BROAD /* Broadcast TX Frame Count */
+#define FramesWithExcessiveDeferral EMAC_TXC_XS_DFR /* TX Frames With Excessive Deferral Count */
+#define MACControlFramesTransmitted EMAC_TXC_MACCTL /* MAC Control TX Frame Count */
+#define FramesTransmittedAll EMAC_TXC_ALLFRM /* Overall TX Frame Count */
+#define OctetsTransmittedAll EMAC_TXC_ALLOCT /* Overall TX Octet Count */
+#define FramesLenEq64Transmitted EMAC_TXC_EQ64 /* Good TX Frame Count - Byte Count x = 64 */
+#define FramesLen65_127Transmitted EMAC_TXC_LT128 /* Good TX Frame Count - Byte Count 64 <= x < 128 */
+#define FramesLen128_255Transmitted EMAC_TXC_LT256 /* Good TX Frame Count - Byte Count 128 <= x < 256 */
+#define FramesLen256_511Transmitted EMAC_TXC_LT512 /* Good TX Frame Count - Byte Count 256 <= x < 512 */
+#define FramesLen512_1023Transmitted EMAC_TXC_LT1024 /* Good TX Frame Count - Byte Count 512 <= x < 1024 */
+#define FramesLen1024_MaxTransmitted EMAC_TXC_GE1024 /* Good TX Frame Count - Byte Count x >= 1024 */
+#define TxAbortedFrames EMAC_TXC_ABORT /* Total TX Frames Aborted Count */
+
+/***********************************************************************************
+** System MMR Register Bits And Macros
+**
+** Disclaimer: All macros are intended to make C and Assembly code more readable.
+** Use these macros carefully, as any that do left shifts for field
+** depositing will result in the lower order bits being destroyed. Any
+** macro that shifts left to properly position the bit-field should be
+** used as part of an OR to initialize a register and NOT as a dynamic
+** modifier UNLESS the lower order bits are saved and ORed back in when
+** the macro is used.
+*************************************************************************************/
+/************************ ETHERNET 10/100 CONTROLLER MASKS ************************/
+/* EMAC_OPMODE Masks */
+#define RE 0x00000001 /* Receiver Enable */
+#define ASTP 0x00000002 /* Enable Automatic Pad Stripping On RX Frames */
+#define HU 0x00000010 /* Hash Filter Unicast Address */
+#define HM 0x00000020 /* Hash Filter Multicast Address */
+#define PAM 0x00000040 /* Pass-All-Multicast Mode Enable */
+#define PR 0x00000080 /* Promiscuous Mode Enable */
+#define IFE 0x00000100 /* Inverse Filtering Enable */
+#define DBF 0x00000200 /* Disable Broadcast Frame Reception */
+#define PBF 0x00000400 /* Pass Bad Frames Enable */
+#define PSF 0x00000800 /* Pass Short Frames Enable */
+#define RAF 0x00001000 /* Receive-All Mode */
+#define TE 0x00010000 /* Transmitter Enable */
+#define DTXPAD 0x00020000 /* Disable Automatic TX Padding */
+#define DTXCRC 0x00040000 /* Disable Automatic TX CRC Generation */
+#define DC 0x00080000 /* Deferral Check */
+#define BOLMT 0x00300000 /* Back-Off Limit */
+#define BOLMT_10 0x00000000 /* 10-bit range */
+#define BOLMT_8 0x00100000 /* 8-bit range */
+#define BOLMT_4 0x00200000 /* 4-bit range */
+#define BOLMT_1 0x00300000 /* 1-bit range */
+#define DRTY 0x00400000 /* Disable TX Retry On Collision */
+#define LCTRE 0x00800000 /* Enable TX Retry On Late Collision */
+#define RMII 0x01000000 /* RMII/MII* Mode */
+#define RMII_10 0x02000000 /* Speed Select for RMII Port (10MBit/100MBit*) */
+#define FDMODE 0x04000000 /* Duplex Mode Enable (Full/Half*) */
+#define LB 0x08000000 /* Internal Loopback Enable */
+#define DRO 0x10000000 /* Disable Receive Own Frames (Half-Duplex Mode) */
+
+/* EMAC_STAADD Masks */
+#define STABUSY 0x00000001 /* Initiate Station Mgt Reg Access / STA Busy Stat */
+#define STAOP 0x00000002 /* Station Management Operation Code (Write/Read*) */
+#define STADISPRE 0x00000004 /* Disable Preamble Generation */
+#define STAIE 0x00000008 /* Station Mgt. Transfer Done Interrupt Enable */
+#define REGAD 0x000007C0 /* STA Register Address */
+#define PHYAD 0x0000F800 /* PHY Device Address */
+
+#define SET_REGAD(x) (((x)&0x1F)<< 6 ) /* Set STA Register Address */
+#define SET_PHYAD(x) (((x)&0x1F)<< 11 ) /* Set PHY Device Address */
+
+/* EMAC_STADAT Mask */
+#define STADATA 0x0000FFFF /* Station Management Data */
+
+/* EMAC_FLC Masks */
+#define FLCBUSY 0x00000001 /* Send Flow Ctrl Frame / Flow Ctrl Busy Status */
+#define FLCE 0x00000002 /* Flow Control Enable */
+#define PCF 0x00000004 /* Pass Control Frames */
+#define BKPRSEN 0x00000008 /* Enable Backpressure */
+#define FLCPAUSE 0xFFFF0000 /* Pause Time */
+
+#define SET_FLCPAUSE(x) (((x)&0xFFFF)<< 16) /* Set Pause Time */
+
+/* EMAC_WKUP_CTL Masks */
+#define CAPWKFRM 0x00000001 /* Capture Wake-Up Frames */
+#define MPKE 0x00000002 /* Magic Packet Enable */
+#define RWKE 0x00000004 /* Remote Wake-Up Frame Enable */
+#define GUWKE 0x00000008 /* Global Unicast Wake Enable */
+#define MPKS 0x00000020 /* Magic Packet Received Status */
+#define RWKS 0x00000F00 /* Wake-Up Frame Received Status, Filters 3:0 */
+
+/* EMAC_WKUP_FFCMD Masks */
+#define WF0_E 0x00000001 /* Enable Wake-Up Filter 0 */
+#define WF0_T 0x00000008 /* Wake-Up Filter 0 Addr Type (Multicast/Unicast*) */
+#define WF1_E 0x00000100 /* Enable Wake-Up Filter 1 */
+#define WF1_T 0x00000800 /* Wake-Up Filter 1 Addr Type (Multicast/Unicast*) */
+#define WF2_E 0x00010000 /* Enable Wake-Up Filter 2 */
+#define WF2_T 0x00080000 /* Wake-Up Filter 2 Addr Type (Multicast/Unicast*) */
+#define WF3_E 0x01000000 /* Enable Wake-Up Filter 3 */
+#define WF3_T 0x08000000 /* Wake-Up Filter 3 Addr Type (Multicast/Unicast*) */
+
+/* EMAC_WKUP_FFOFF Masks */
+#define WF0_OFF 0x000000FF /* Wake-Up Filter 0 Pattern Offset */
+#define WF1_OFF 0x0000FF00 /* Wake-Up Filter 1 Pattern Offset */
+#define WF2_OFF 0x00FF0000 /* Wake-Up Filter 2 Pattern Offset */
+#define WF3_OFF 0xFF000000 /* Wake-Up Filter 3 Pattern Offset */
+
+#define SET_WF0_OFF(x) (((x)&0xFF)<< 0 ) /* Set Wake-Up Filter 0 Byte Offset */
+#define SET_WF1_OFF(x) (((x)&0xFF)<< 8 ) /* Set Wake-Up Filter 1 Byte Offset */
+#define SET_WF2_OFF(x) (((x)&0xFF)<< 16 ) /* Set Wake-Up Filter 2 Byte Offset */
+#define SET_WF3_OFF(x) (((x)&0xFF)<< 24 ) /* Set Wake-Up Filter 3 Byte Offset */
+/* Set ALL Offsets */
+#define SET_WF_OFFS(x0,x1,x2,x3) (SET_WF0_OFF((x0))|SET_WF1_OFF((x1))|SET_WF2_OFF((x2))|SET_WF3_OFF((x3)))
+
+/* EMAC_WKUP_FFCRC0 Masks */
+#define WF0_CRC 0x0000FFFF /* Wake-Up Filter 0 Pattern CRC */
+#define WF1_CRC 0xFFFF0000 /* Wake-Up Filter 1 Pattern CRC */
+
+#define SET_WF0_CRC(x) (((x)&0xFFFF)<< 0 ) /* Set Wake-Up Filter 0 Target CRC */
+#define SET_WF1_CRC(x) (((x)&0xFFFF)<< 16 ) /* Set Wake-Up Filter 1 Target CRC */
+
+/* EMAC_WKUP_FFCRC1 Masks */
+#define WF2_CRC 0x0000FFFF /* Wake-Up Filter 2 Pattern CRC */
+#define WF3_CRC 0xFFFF0000 /* Wake-Up Filter 3 Pattern CRC */
+
+#define SET_WF2_CRC(x) (((x)&0xFFFF)<< 0 ) /* Set Wake-Up Filter 2 Target CRC */
+#define SET_WF3_CRC(x) (((x)&0xFFFF)<< 16 ) /* Set Wake-Up Filter 3 Target CRC */
+
+/* EMAC_SYSCTL Masks */
+#define PHYIE 0x00000001 /* PHY_INT Interrupt Enable */
+#define RXDWA 0x00000002 /* Receive Frame DMA Word Alignment (Odd/Even*) */
+#define RXCKS 0x00000004 /* Enable RX Frame TCP/UDP Checksum Computation */
+#define MDCDIV 0x00003F00 /* SCLK:MDC Clock Divisor [MDC=SCLK/(2*(N+1))] */
+
+#define SET_MDCDIV(x) (((x)&0x3F)<< 8) /* Set MDC Clock Divisor */
+
+/* EMAC_SYSTAT Masks */
+#define PHYINT 0x00000001 /* PHY_INT Interrupt Status */
+#define MMCINT 0x00000002 /* MMC Counter Interrupt Status */
+#define RXFSINT 0x00000004 /* RX Frame-Status Interrupt Status */
+#define TXFSINT 0x00000008 /* TX Frame-Status Interrupt Status */
+#define WAKEDET 0x00000010 /* Wake-Up Detected Status */
+#define RXDMAERR 0x00000020 /* RX DMA Direction Error Status */
+#define TXDMAERR 0x00000040 /* TX DMA Direction Error Status */
+#define STMDONE 0x00000080 /* Station Mgt. Transfer Done Interrupt Status */
+
+/* EMAC_RX_STAT, EMAC_RX_STKY, and EMAC_RX_IRQE Masks */
+#define RX_FRLEN 0x000007FF /* Frame Length In Bytes */
+#define RX_COMP 0x00001000 /* RX Frame Complete */
+#define RX_OK 0x00002000 /* RX Frame Received With No Errors */
+#define RX_LONG 0x00004000 /* RX Frame Too Long Error */
+#define RX_ALIGN 0x00008000 /* RX Frame Alignment Error */
+#define RX_CRC 0x00010000 /* RX Frame CRC Error */
+#define RX_LEN 0x00020000 /* RX Frame Length Error */
+#define RX_FRAG 0x00040000 /* RX Frame Fragment Error */
+#define RX_ADDR 0x00080000 /* RX Frame Address Filter Failed Error */
+#define RX_DMAO 0x00100000 /* RX Frame DMA Overrun Error */
+#define RX_PHY 0x00200000 /* RX Frame PHY Error */
+#define RX_LATE 0x00400000 /* RX Frame Late Collision Error */
+#define RX_RANGE 0x00800000 /* RX Frame Length Field Out of Range Error */
+#define RX_MULTI 0x01000000 /* RX Multicast Frame Indicator */
+#define RX_BROAD 0x02000000 /* RX Broadcast Frame Indicator */
+#define RX_CTL 0x04000000 /* RX Control Frame Indicator */
+#define RX_UCTL 0x08000000 /* Unsupported RX Control Frame Indicator */
+#define RX_TYPE 0x10000000 /* RX Typed Frame Indicator */
+#define RX_VLAN1 0x20000000 /* RX VLAN1 Frame Indicator */
+#define RX_VLAN2 0x40000000 /* RX VLAN2 Frame Indicator */
+#define RX_ACCEPT 0x80000000 /* RX Frame Accepted Indicator */
+
+/* EMAC_TX_STAT, EMAC_TX_STKY, and EMAC_TX_IRQE Masks */
+#define TX_COMP 0x00000001 /* TX Frame Complete */
+#define TX_OK 0x00000002 /* TX Frame Sent With No Errors */
+#define TX_ECOLL 0x00000004 /* TX Frame Excessive Collision Error */
+#define TX_LATE 0x00000008 /* TX Frame Late Collision Error */
+#define TX_DMAU 0x00000010 /* TX Frame DMA Underrun Error (STAT) */
+#define TX_MACE 0x00000010 /* Internal MAC Error Detected (STKY and IRQE) */
+#define TX_EDEFER 0x00000020 /* TX Frame Excessive Deferral Error */
+#define TX_BROAD 0x00000040 /* TX Broadcast Frame Indicator */
+#define TX_MULTI 0x00000080 /* TX Multicast Frame Indicator */
+#define TX_CCNT 0x00000F00 /* TX Frame Collision Count */
+#define TX_DEFER 0x00001000 /* TX Frame Deferred Indicator */
+#define TX_CRS 0x00002000 /* TX Frame Carrier Sense Not Asserted Error */
+#define TX_LOSS 0x00004000 /* TX Frame Carrier Lost During TX Error */
+#define TX_RETRY 0x00008000 /* TX Frame Successful After Retry */
+#define TX_FRLEN 0x07FF0000 /* TX Frame Length (Bytes) */
+
+/* EMAC_MMC_CTL Masks */
+#define RSTC 0x00000001 /* Reset All Counters */
+#define CROLL 0x00000002 /* Counter Roll-Over Enable */
+#define CCOR 0x00000004 /* Counter Clear-On-Read Mode Enable */
+#define MMCE 0x00000008 /* Enable MMC Counter Operation */
+
+/* EMAC_MMC_RIRQS and EMAC_MMC_RIRQE Masks */
+#define RX_OK_CNT 0x00000001 /* RX Frames Received With No Errors */
+#define RX_FCS_CNT 0x00000002 /* RX Frames W/Frame Check Sequence Errors */
+#define RX_ALIGN_CNT 0x00000004 /* RX Frames With Alignment Errors */
+#define RX_OCTET_CNT 0x00000008 /* RX Octets Received OK */
+#define RX_LOST_CNT 0x00000010 /* RX Frames Lost Due To Internal MAC RX Error */
+#define RX_UNI_CNT 0x00000020 /* Unicast RX Frames Received OK */
+#define RX_MULTI_CNT 0x00000040 /* Multicast RX Frames Received OK */
+#define RX_BROAD_CNT 0x00000080 /* Broadcast RX Frames Received OK */
+#define RX_IRL_CNT 0x00000100 /* RX Frames With In-Range Length Errors */
+#define RX_ORL_CNT 0x00000200 /* RX Frames With Out-Of-Range Length Errors */
+#define RX_LONG_CNT 0x00000400 /* RX Frames With Frame Too Long Errors */
+#define RX_MACCTL_CNT 0x00000800 /* MAC Control RX Frames Received */
+#define RX_OPCODE_CTL 0x00001000 /* Unsupported Op-Code RX Frames Received */
+#define RX_PAUSE_CNT 0x00002000 /* PAUSEMAC Control RX Frames Received */
+#define RX_ALLF_CNT 0x00004000 /* All RX Frames Received */
+#define RX_ALLO_CNT 0x00008000 /* All RX Octets Received */
+#define RX_TYPED_CNT 0x00010000 /* Typed RX Frames Received */
+#define RX_SHORT_CNT 0x00020000 /* RX Frame Fragments (< 64 Bytes) Received */
+#define RX_EQ64_CNT 0x00040000 /* 64-Byte RX Frames Received */
+#define RX_LT128_CNT 0x00080000 /* 65-127-Byte RX Frames Received */
+#define RX_LT256_CNT 0x00100000 /* 128-255-Byte RX Frames Received */
+#define RX_LT512_CNT 0x00200000 /* 256-511-Byte RX Frames Received */
+#define RX_LT1024_CNT 0x00400000 /* 512-1023-Byte RX Frames Received */
+#define RX_GE1024_CNT 0x00800000 /* 1024-Max-Byte RX Frames Received */
+
+/* EMAC_MMC_TIRQS and EMAC_MMC_TIRQE Masks */
+#define TX_OK_CNT 0x00000001 /* TX Frames Sent OK */
+#define TX_SCOLL_CNT 0x00000002 /* TX Frames With Single Collisions */
+#define TX_MCOLL_CNT 0x00000004 /* TX Frames With Multiple Collisions */
+#define TX_OCTET_CNT 0x00000008 /* TX Octets Sent OK */
+#define TX_DEFER_CNT 0x00000010 /* TX Frames With Deferred Transmission */
+#define TX_LATE_CNT 0x00000020 /* TX Frames With Late Collisions */
+#define TX_ABORTC_CNT 0x00000040 /* TX Frames Aborted Due To Excess Collisions */
+#define TX_LOST_CNT 0x00000080 /* TX Frames Lost Due To Internal MAC TX Error */
+#define TX_CRS_CNT 0x00000100 /* TX Frames With Carrier Sense Errors */
+#define TX_UNI_CNT 0x00000200 /* Unicast TX Frames Sent */
+#define TX_MULTI_CNT 0x00000400 /* Multicast TX Frames Sent */
+#define TX_BROAD_CNT 0x00000800 /* Broadcast TX Frames Sent */
+#define TX_EXDEF_CTL 0x00001000 /* TX Frames With Excessive Deferral */
+#define TX_MACCTL_CNT 0x00002000 /* MAC Control TX Frames Sent */
+#define TX_ALLF_CNT 0x00004000 /* All TX Frames Sent */
+#define TX_ALLO_CNT 0x00008000 /* All TX Octets Sent */
+#define TX_EQ64_CNT 0x00010000 /* 64-Byte TX Frames Sent */
+#define TX_LT128_CNT 0x00020000 /* 65-127-Byte TX Frames Sent */
+#define TX_LT256_CNT 0x00040000 /* 128-255-Byte TX Frames Sent */
+#define TX_LT512_CNT 0x00080000 /* 256-511-Byte TX Frames Sent */
+#define TX_LT1024_CNT 0x00100000 /* 512-1023-Byte TX Frames Sent */
+#define TX_GE1024_CNT 0x00200000 /* 1024-Max-Byte TX Frames Sent */
+#define TX_ABORT_CNT 0x00400000 /* TX Frames Aborted */
+
+#endif /* _DEF_BF537_H */
diff --git a/include/asm-blackfin/mach-bf537/dma.h b/include/asm-blackfin/mach-bf537/dma.h
new file mode 100644
index 0000000..7a96404
--- /dev/null
+++ b/include/asm-blackfin/mach-bf537/dma.h
@@ -0,0 +1,55 @@
+/*
+ * file: include/asm-blackfin/mach-bf537/dma.h
+ * based on:
+ * author:
+ *
+ * created:
+ * description:
+ * system mmr register map
+ * rev:
+ *
+ * modified:
+ *
+ *
+ * bugs: enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose. see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _MACH_DMA_H_
+#define _MACH_DMA_H_
+
+#define MAX_BLACKFIN_DMA_CHANNEL 16
+
+#define CH_PPI 0
+#define CH_EMAC_RX 1
+#define CH_EMAC_TX 2
+#define CH_SPORT0_RX 3
+#define CH_SPORT0_TX 4
+#define CH_SPORT1_RX 5
+#define CH_SPORT1_TX 6
+#define CH_SPI 7
+#define CH_UART0_RX 8
+#define CH_UART0_TX 9
+#define CH_UART1_RX 10
+#define CH_UART1_TX 11
+
+#define CH_MEM_STREAM0_DEST 12 /* TX */
+#define CH_MEM_STREAM0_SRC 13 /* RX */
+#define CH_MEM_STREAM1_DEST 14 /* TX */
+#define CH_MEM_STREAM1_SRC 15 /* RX */
+
+#endif
diff --git a/include/asm-blackfin/mach-bf537/irq.h b/include/asm-blackfin/mach-bf537/irq.h
new file mode 100644
index 0000000..8af2a83
--- /dev/null
+++ b/include/asm-blackfin/mach-bf537/irq.h
@@ -0,0 +1,219 @@
+/*
+ * file: include/asm-blackfin/mach-bf537/irq.h
+ * based on:
+ * author:
+ *
+ * created:
+ * description:
+ * system mmr register map
+ * rev:
+ *
+ * modified:
+ *
+ *
+ * bugs: enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose. see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _BF537_IRQ_H_
+#define _BF537_IRQ_H_
+
+/*
+ * Interrupt source definitions
+ Event Source Core Event Name
+Core Emulation **
+ Events (highest priority) EMU 0
+ Reset RST 1
+ NMI NMI 2
+ Exception EVX 3
+ Reserved -- 4
+ Hardware Error IVHW 5
+ Core Timer IVTMR 6 *
+
+.....
+
+ Software Interrupt 1 IVG14 31
+ Software Interrupt 2 --
+ (lowest priority) IVG15 32 *
+ */
+
+#define SYS_IRQS 41
+#define NR_PERI_INTS 32
+
+/* The ABSTRACT IRQ definitions */
+/** the first seven of the following are fixed, the rest you change if you need to **/
+#define IRQ_EMU 0 /*Emulation */
+#define IRQ_RST 1 /*reset */
+#define IRQ_NMI 2 /*Non Maskable */
+#define IRQ_EVX 3 /*Exception */
+#define IRQ_UNUSED 4 /*- unused interrupt*/
+#define IRQ_HWERR 5 /*Hardware Error */
+#define IRQ_CORETMR 6 /*Core timer */
+
+#define IRQ_PLL_WAKEUP 7 /*PLL Wakeup Interrupt */
+#define IRQ_DMA_ERROR 8 /*DMA Error (general) */
+#define IRQ_GENERIC_ERROR 9 /*GENERIC Error Interrupt */
+#define IRQ_RTC 10 /*RTC Interrupt */
+#define IRQ_PPI 11 /*DMA0 Interrupt (PPI) */
+#define IRQ_SPORT0_RX 12 /*DMA3 Interrupt (SPORT0 RX) */
+#define IRQ_SPORT0_TX 13 /*DMA4 Interrupt (SPORT0 TX) */
+#define IRQ_SPORT1_RX 14 /*DMA5 Interrupt (SPORT1 RX) */
+#define IRQ_SPORT1_TX 15 /*DMA6 Interrupt (SPORT1 TX) */
+#define IRQ_TWI 16 /*TWI Interrupt */
+#define IRQ_SPI 17 /*DMA7 Interrupt (SPI) */
+#define IRQ_UART0_RX 18 /*DMA8 Interrupt (UART0 RX) */
+#define IRQ_UART0_TX 19 /*DMA9 Interrupt (UART0 TX) */
+#define IRQ_UART1_RX 20 /*DMA10 Interrupt (UART1 RX) */
+#define IRQ_UART1_TX 21 /*DMA11 Interrupt (UART1 TX) */
+#define IRQ_CAN_RX 22 /*CAN Receive Interrupt */
+#define IRQ_CAN_TX 23 /*CAN Transmit Interrupt */
+#define IRQ_MAC_RX 24 /*DMA1 (Ethernet RX) Interrupt */
+#define IRQ_MAC_TX 25 /*DMA2 (Ethernet TX) Interrupt */
+#define IRQ_TMR0 26 /*Timer 0 */
+#define IRQ_TMR1 27 /*Timer 1 */
+#define IRQ_TMR2 28 /*Timer 2 */
+#define IRQ_TMR3 29 /*Timer 3 */
+#define IRQ_TMR4 30 /*Timer 4 */
+#define IRQ_TMR5 31 /*Timer 5 */
+#define IRQ_TMR6 32 /*Timer 6 */
+#define IRQ_TMR7 33 /*Timer 7 */
+#define IRQ_PROG_INTA 34 /* PF Ports F&G (PF15:0) Interrupt A */
+#define IRQ_PORTG_INTB 35 /* PF Port G (PF15:0) Interrupt B */
+#define IRQ_MEM_DMA0 36 /*(Memory DMA Stream 0) */
+#define IRQ_MEM_DMA1 37 /*(Memory DMA Stream 1) */
+#define IRQ_PROG_INTB 38 /* PF Ports F (PF15:0) Interrupt B */
+#define IRQ_WATCH 38 /*Watch Dog Timer */
+#define IRQ_SW_INT1 40 /*Software Int 1 */
+#define IRQ_SW_INT2 41 /*Software Int 2 (reserved for SYSCALL) */
+
+#define IRQ_PPI_ERROR 42 /*PPI Error Interrupt */
+#define IRQ_CAN_ERROR 43 /*CAN Error Interrupt */
+#define IRQ_MAC_ERROR 44 /*PPI Error Interrupt */
+#define IRQ_SPORT0_ERROR 45 /*SPORT0 Error Interrupt */
+#define IRQ_SPORT1_ERROR 46 /*SPORT1 Error Interrupt */
+#define IRQ_SPI_ERROR 47 /*SPI Error Interrupt */
+#define IRQ_UART0_ERROR 48 /*UART Error Interrupt */
+#define IRQ_UART1_ERROR 49 /*UART Error Interrupt */
+
+#define IRQ_PF0 50
+#define IRQ_PF1 51
+#define IRQ_PF2 52
+#define IRQ_PF3 53
+#define IRQ_PF4 54
+#define IRQ_PF5 55
+#define IRQ_PF6 56
+#define IRQ_PF7 57
+#define IRQ_PF8 58
+#define IRQ_PF9 59
+#define IRQ_PF10 60
+#define IRQ_PF11 61
+#define IRQ_PF12 62
+#define IRQ_PF13 63
+#define IRQ_PF14 64
+#define IRQ_PF15 65
+
+#define IRQ_PG0 66
+#define IRQ_PG1 67
+#define IRQ_PG2 68
+#define IRQ_PG3 69
+#define IRQ_PG4 70
+#define IRQ_PG5 71
+#define IRQ_PG6 72
+#define IRQ_PG7 73
+#define IRQ_PG8 74
+#define IRQ_PG9 75
+#define IRQ_PG10 76
+#define IRQ_PG11 77
+#define IRQ_PG12 78
+#define IRQ_PG13 79
+#define IRQ_PG14 80
+#define IRQ_PG15 81
+
+#define IRQ_PH0 82
+#define IRQ_PH1 83
+#define IRQ_PH2 84
+#define IRQ_PH3 85
+#define IRQ_PH4 86
+#define IRQ_PH5 87
+#define IRQ_PH6 88
+#define IRQ_PH7 89
+#define IRQ_PH8 90
+#define IRQ_PH9 91
+#define IRQ_PH10 92
+#define IRQ_PH11 93
+#define IRQ_PH12 94
+#define IRQ_PH13 95
+#define IRQ_PH14 96
+#define IRQ_PH15 97
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+#define NR_IRQS (IRQ_PH15+1)
+#else
+#define NR_IRQS (IRQ_UART1_ERROR+1)
+#endif
+
+#define IVG7 7
+#define IVG8 8
+#define IVG9 9
+#define IVG10 10
+#define IVG11 11
+#define IVG12 12
+#define IVG13 13
+#define IVG14 14
+#define IVG15 15
+
+/* IAR0 BIT FIELDS*/
+#define IRQ_PLL_WAKEUP_POS 0
+#define IRQ_DMA_ERROR_POS 4
+#define IRQ_ERROR_POS 8
+#define IRQ_RTC_POS 12
+#define IRQ_PPI_POS 16
+#define IRQ_SPORT0_RX_POS 20
+#define IRQ_SPORT0_TX_POS 24
+#define IRQ_SPORT1_RX_POS 28
+
+/* IAR1 BIT FIELDS*/
+#define IRQ_SPORT1_TX_POS 0
+#define IRQ_TWI_POS 4
+#define IRQ_SPI_POS 8
+#define IRQ_UART0_RX_POS 12
+#define IRQ_UART0_TX_POS 16
+#define IRQ_UART1_RX_POS 20
+#define IRQ_UART1_TX_POS 24
+#define IRQ_CAN_RX_POS 28
+
+/* IAR2 BIT FIELDS*/
+#define IRQ_CAN_TX_POS 0
+#define IRQ_MAC_RX_POS 4
+#define IRQ_MAC_TX_POS 8
+#define IRQ_TMR0_POS 12
+#define IRQ_TMR1_POS 16
+#define IRQ_TMR2_POS 20
+#define IRQ_TMR3_POS 24
+#define IRQ_TMR4_POS 28
+
+/* IAR3 BIT FIELDS*/
+#define IRQ_TMR5_POS 0
+#define IRQ_TMR6_POS 4
+#define IRQ_TMR7_POS 8
+#define IRQ_PROG_INTA_POS 12
+#define IRQ_PORTG_INTB_POS 16
+#define IRQ_MEM_DMA0_POS 20
+#define IRQ_MEM_DMA1_POS 24
+#define IRQ_WATCH_POS 28
+
+#endif /* _BF537_IRQ_H_ */
diff --git a/include/asm-blackfin/mach-bf537/mem_init.h b/include/asm-blackfin/mach-bf537/mem_init.h
new file mode 100644
index 0000000..9ad979d
--- /dev/null
+++ b/include/asm-blackfin/mach-bf537/mem_init.h
@@ -0,0 +1,330 @@
+/*
+ * File: include/asm-blackfin/mach-bf537/mem_init.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#if (CONFIG_MEM_MT48LC16M16A2TG_75 || CONFIG_MEM_MT48LC64M4A2FB_7E || CONFIG_MEM_MT48LC16M8A2TG_75 || CONFIG_MEM_GENERIC_BOARD || CONFIG_MEM_MT48LC32M8A2_75)
+#if (CONFIG_SCLK_HZ > 119402985)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_7
+#define SDRAM_tRAS_num 7
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 104477612) && (CONFIG_SCLK_HZ <= 119402985)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_6
+#define SDRAM_tRAS_num 6
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 89552239) && (CONFIG_SCLK_HZ <= 104477612)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_5
+#define SDRAM_tRAS_num 5
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 74626866) && (CONFIG_SCLK_HZ <= 89552239)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_4
+#define SDRAM_tRAS_num 4
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 66666667) && (CONFIG_SCLK_HZ <= 74626866)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_3
+#define SDRAM_tRAS_num 3
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 59701493) && (CONFIG_SCLK_HZ <= 66666667)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_4
+#define SDRAM_tRAS_num 3
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 44776119) && (CONFIG_SCLK_HZ <= 59701493)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_3
+#define SDRAM_tRAS_num 3
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 29850746) && (CONFIG_SCLK_HZ <= 44776119)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_2
+#define SDRAM_tRAS_num 2
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ <= 29850746)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_1
+#define SDRAM_tRAS_num 1
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#endif
+
+#if (CONFIG_MEM_MT48LC16M16A2TG_75)
+ /*SDRAM INFORMATION: */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC16M8A2TG_75)
+ /*SDRAM INFORMATION: */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 4096 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC32M8A2_75)
+ /*SDRAM INFORMATION: */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC64M4A2FB_7E)
+ /*SDRAM INFORMATION: */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_GENERIC_BOARD)
+ /*SDRAM INFORMATION: Modify this for your board */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_SIZE == 128)
+#define SDRAM_SIZE EBSZ_128
+#endif
+#if (CONFIG_MEM_SIZE == 64)
+#define SDRAM_SIZE EBSZ_64
+#endif
+#if (CONFIG_MEM_SIZE == 32)
+#define SDRAM_SIZE EBSZ_32
+#endif
+#if (CONFIG_MEM_SIZE == 16)
+#define SDRAM_SIZE EBSZ_16
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 11)
+#define SDRAM_WIDTH EBCAW_11
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 10)
+#define SDRAM_WIDTH EBCAW_10
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 9)
+#define SDRAM_WIDTH EBCAW_9
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 8)
+#define SDRAM_WIDTH EBCAW_8
+#endif
+
+#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EBE)
+
+/* Equation from section 17 (p17-46) of BF533 HRM */
+#define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num)
+
+/* Enable SCLK Out */
+#define mem_SDGCTL (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS)
+
+#if defined CONFIG_CLKIN_HALF
+#define CLKIN_HALF 1
+#else
+#define CLKIN_HALF 0
+#endif
+
+#if defined CONFIG_PLL_BYPASS
+#define PLL_BYPASS 1
+#else
+#define PLL_BYPASS 0
+#endif
+
+/***************************************Currently Not Being Used *********************************/
+#define flash_EBIU_AMBCTL_WAT ((CONFIG_FLASH_SPEED_BWAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_RAT ((CONFIG_FLASH_SPEED_BRAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_HT ((CONFIG_FLASH_SPEED_BHT * 4) / (4000000000 / CONFIG_SCLK_HZ))
+#define flash_EBIU_AMBCTL_ST ((CONFIG_FLASH_SPEED_BST * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_TT ((CONFIG_FLASH_SPEED_BTT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+
+#if (flash_EBIU_AMBCTL_TT > 3)
+#define flash_EBIU_AMBCTL0_TT B0TT_4
+#endif
+#if (flash_EBIU_AMBCTL_TT == 3)
+#define flash_EBIU_AMBCTL0_TT B0TT_3
+#endif
+#if (flash_EBIU_AMBCTL_TT == 2)
+#define flash_EBIU_AMBCTL0_TT B0TT_2
+#endif
+#if (flash_EBIU_AMBCTL_TT < 2)
+#define flash_EBIU_AMBCTL0_TT B0TT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_ST > 3)
+#define flash_EBIU_AMBCTL0_ST B0ST_4
+#endif
+#if (flash_EBIU_AMBCTL_ST == 3)
+#define flash_EBIU_AMBCTL0_ST B0ST_3
+#endif
+#if (flash_EBIU_AMBCTL_ST == 2)
+#define flash_EBIU_AMBCTL0_ST B0ST_2
+#endif
+#if (flash_EBIU_AMBCTL_ST < 2)
+#define flash_EBIU_AMBCTL0_ST B0ST_1
+#endif
+
+#if (flash_EBIU_AMBCTL_HT > 2)
+#define flash_EBIU_AMBCTL0_HT B0HT_3
+#endif
+#if (flash_EBIU_AMBCTL_HT == 2)
+#define flash_EBIU_AMBCTL0_HT B0HT_2
+#endif
+#if (flash_EBIU_AMBCTL_HT == 1)
+#define flash_EBIU_AMBCTL0_HT B0HT_1
+#endif
+#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT == 0)
+#define flash_EBIU_AMBCTL0_HT B0HT_0
+#endif
+#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT != 0)
+#define flash_EBIU_AMBCTL0_HT B0HT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_WAT > 14)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_15
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 14)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_14
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 13)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_13
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 12)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_12
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 11)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_11
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 10)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_10
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 9)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_9
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 8)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_8
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 7)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_7
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 6)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_6
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 5)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_5
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 4)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_4
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 3)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_3
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 2)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_2
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 1)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_RAT > 14)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_15
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 14)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_14
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 13)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_13
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 12)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_12
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 11)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_11
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 10)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_10
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 9)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_9
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 8)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_8
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 7)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_7
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 6)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_6
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 5)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_5
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 4)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_4
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 3)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_3
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 2)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_2
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 1)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_1
+#endif
+
+#define flash_EBIU_AMBCTL0 \
+ (flash_EBIU_AMBCTL0_WAT | flash_EBIU_AMBCTL0_RAT | flash_EBIU_AMBCTL0_HT | \
+ flash_EBIU_AMBCTL0_ST | flash_EBIU_AMBCTL0_TT | CONFIG_FLASH_SPEED_RDYEN)
diff --git a/include/asm-blackfin/mach-bf537/mem_map.h b/include/asm-blackfin/mach-bf537/mem_map.h
new file mode 100644
index 0000000..2a808c1
--- /dev/null
+++ b/include/asm-blackfin/mach-bf537/mem_map.h
@@ -0,0 +1,175 @@
+/*
+ * file: include/asm-blackfin/mach-bf537/mem_map.h
+ * based on:
+ * author:
+ *
+ * created:
+ * description:
+ * Memory MAP Common header file for blackfin BF537/6/4 of processors.
+ * rev:
+ *
+ * modified:
+ *
+ * bugs: enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose. see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _MEM_MAP_537_H_
+#define _MEM_MAP_537_H_
+
+#define COREMMR_BASE 0xFFE00000 /* Core MMRs */
+#define SYSMMR_BASE 0xFFC00000 /* System MMRs */
+
+/* Async Memory Banks */
+#define ASYNC_BANK3_BASE 0x20300000 /* Async Bank 3 */
+#define ASYNC_BANK3_SIZE 0x00100000 /* 1M */
+#define ASYNC_BANK2_BASE 0x20200000 /* Async Bank 2 */
+#define ASYNC_BANK2_SIZE 0x00100000 /* 1M */
+#define ASYNC_BANK1_BASE 0x20100000 /* Async Bank 1 */
+#define ASYNC_BANK1_SIZE 0x00100000 /* 1M */
+#define ASYNC_BANK0_BASE 0x20000000 /* Async Bank 0 */
+#define ASYNC_BANK0_SIZE 0x00100000 /* 1M */
+
+/* Boot ROM Memory */
+
+#define BOOT_ROM_START 0xEF000000
+
+/* Level 1 Memory */
+
+/* Memory Map for ADSP-BF537 processors */
+
+#ifdef CONFIG_BLKFIN_CACHE
+#define BLKFIN_ICACHESIZE (16*1024)
+#else
+#define BLKFIN_ICACHESIZE (0*1024)
+#endif
+
+
+#ifdef CONFIG_BF537
+#define L1_CODE_START 0xFFA00000
+#define L1_DATA_A_START 0xFF800000
+#define L1_DATA_B_START 0xFF900000
+
+#define L1_CODE_LENGTH 0xC000
+
+#ifdef CONFIG_BLKFIN_DCACHE
+
+#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH 0x8000
+#define BLKFIN_DCACHESIZE (16*1024)
+#define BLKFIN_DSUPBANKS 1
+#else
+#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH (0x8000 - 0x4000)
+#define BLKFIN_DCACHESIZE (32*1024)
+#define BLKFIN_DSUPBANKS 2
+#endif
+
+#else
+#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH 0x8000
+#define L1_DATA_B_LENGTH 0x8000
+#define BLKFIN_DCACHESIZE (0*1024)
+#define BLKFIN_DSUPBANKS 0
+#endif /*CONFIG_BLKFIN_DCACHE*/
+
+#endif /*CONFIG_BF537*/
+
+/* Memory Map for ADSP-BF536 processors */
+
+#ifdef CONFIG_BF536
+#define L1_CODE_START 0xFFA00000
+#define L1_DATA_A_START 0xFF804000
+#define L1_DATA_B_START 0xFF904000
+
+#define L1_CODE_LENGTH 0xC000
+
+
+#ifdef CONFIG_BLKFIN_DCACHE
+
+#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x4000 - 0x4000)
+#define L1_DATA_B_LENGTH 0x4000
+#define BLKFIN_DCACHESIZE (16*1024)
+#define BLKFIN_DSUPBANKS 1
+
+#else
+#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x4000 - 0x4000)
+#define L1_DATA_B_LENGTH (0x4000 - 0x4000)
+#define BLKFIN_DCACHESIZE (32*1024)
+#define BLKFIN_DSUPBANKS 2
+#endif
+
+#else
+#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH 0x4000
+#define L1_DATA_B_LENGTH 0x4000
+#define BLKFIN_DCACHESIZE (0*1024)
+#define BLKFIN_DSUPBANKS 0
+#endif /*CONFIG_BLKFIN_DCACHE*/
+
+#endif
+
+/* Memory Map for ADSP-BF534 processors */
+
+#ifdef CONFIG_BF534
+#define L1_CODE_START 0xFFA00000
+#define L1_DATA_A_START 0xFF800000
+#define L1_DATA_B_START 0xFF900000
+
+#define L1_CODE_LENGTH 0xC000
+
+#ifdef CONFIG_BLKFIN_DCACHE
+
+#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH 0x8000
+#define BLKFIN_DCACHESIZE (16*1024)
+#define BLKFIN_DSUPBANKS 1
+
+#else
+#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH (0x8000 - 0x4000)
+#define BLKFIN_DCACHESIZE (32*1024)
+#define BLKFIN_DSUPBANKS 2
+#endif
+
+#else
+#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH 0x8000
+#define L1_DATA_B_LENGTH 0x8000
+#define BLKFIN_DCACHESIZE (0*1024)
+#define BLKFIN_DSUPBANKS 0
+#endif /*CONFIG_BLKFIN_DCACHE*/
+
+#endif
+
+/* Scratch Pad Memory */
+
+#if defined(CONFIG_BF537) || defined(CONFIG_BF536) || defined(CONFIG_BF534)
+#define L1_SCRATCH_START 0xFFB00000
+#define L1_SCRATCH_LENGTH 0x1000
+#endif
+
+#endif /* _MEM_MAP_537_H_ */
diff --git a/include/asm-blackfin/mach-bf561/anomaly.h b/include/asm-blackfin/mach-bf561/anomaly.h
new file mode 100644
index 0000000..f5b32d6
--- /dev/null
+++ b/include/asm-blackfin/mach-bf561/anomaly.h
@@ -0,0 +1,184 @@
+
+/*
+ * File: include/asm-blackfin/mach-bf561/anomaly.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* This file shoule be up to date with:
+ * - Revision L, 10Aug2006; ADSP-BF561 Silicon Anomaly List
+ */
+
+#ifndef _MACH_ANOMALY_H_
+#define _MACH_ANOMALY_H_
+
+/* We do not support 0.1 or 0.4 silicon - sorry */
+#if (defined(CONFIG_BF_REV_0_1) || defined(CONFIG_BF_REV_0_2) || defined(CONFIG_BF_REV_0_4))
+#error Kernel will not work on BF561 Version 0.1, 0.2, or 0.4
+#endif
+
+/* Issues that are common to 0.5 and 0.3 silicon */
+#if (defined(CONFIG_BF_REV_0_5) || defined(CONFIG_BF_REV_0_3))
+#define ANOMALY_05000074 /* A multi issue instruction with dsp32shiftimm in
+ slot1 and store of a P register in slot 2 is not
+ supported */
+#define ANOMALY_05000099 /* UART Line Status Register (UART_LSR) bits are not
+ updated at the same time. */
+#define ANOMALY_05000120 /* Testset instructions restricted to 32-bit aligned
+ memory locations */
+#define ANOMALY_05000122 /* Rx.H cannot be used to access 16-bit System MMR
+ registers */
+#define ANOMALY_05000127 /* Signbits instruction not functional under certain
+ conditions */
+#define ANOMALY_05000149 /* IMDMA S1/D1 channel may stall */
+#define ANOMALY_05000166 /* PPI Data Lengths Between 8 and 16 do not zero out
+ upper bits */
+#define ANOMALY_05000167 /* Turning Serial Ports on With External Frame Syncs */
+#define ANOMALY_05000180 /* PPI_DELAY not functional in PPI modes with 0 frame
+ syncs */
+#define ANOMALY_05000182 /* IMDMA does not operate to full speed for 600MHz
+ and higher devices */
+#define ANOMALY_05000187 /* IMDMA Corrupted Data after a Halt */
+#define ANOMALY_05000190 /* PPI not functional at core voltage < 1Volt */
+#define ANOMALY_05000208 /* VSTAT status bit in PLL_STAT register is not
+ functional */
+#define ANOMALY_05000245 /* Spurious Hardware Error from an access in the
+ shadow of a conditional branch */
+#define ANOMALY_05000257 /* Interrupt/Exception during short hardware loop
+ may cause bad instruction fetches */
+#define ANOMALY_05000265 /* Sensitivity to noise with slow input edge rates on
+ external SPORT TX and RX clocks */
+#define ANOMALY_05000267 /* IMDMA may corrupt data under certain conditions */
+#define ANOMALY_05000269 /* High I/O activity causes output voltage of internal
+ voltage regulator (VDDint) to increase */
+#define ANOMALY_05000270 /* High I/O activity causes output voltage of internal
+ voltage regulator (VDDint) to decrease */
+#define ANOMALY_05000272 /* Certain data cache write through modes fail for
+ VDDint <=0.9V */
+#define ANOMALY_05000274 /* Data cache write back to external synchronous memory
+ may be lost */
+#define ANOMALY_05000275 /* PPI Timing and sampling informaton updates */
+#define ANOMALY_05000312 /* Errors when SSYNC, CSYNC, or loads to LT, LB and LC
+ registers are interrupted */
+
+#endif /* (defined(CONFIG_BF_REV_0_5) || defined(CONFIG_BF_REV_0_3)) */
+
+#if (defined(CONFIG_BF_REV_0_5))
+#define ANOMALY_05000254 /* Incorrect Timer Pulse Width in Single-Shot PWM_OUT
+ mode with external clock */
+#define ANOMALY_05000266 /* IMDMA destination IRQ status must be read prior to
+ using IMDMA */
+#endif
+
+#if (defined(CONFIG_BF_REV_0_3))
+#define ANOMALY_05000156 /* Timers in PWM-Out Mode with PPI GP Receive (Input)
+ Mode with 0 Frame Syncs */
+#define ANOMALY_05000168 /* SDRAM auto-refresh and subsequent Power Ups */
+#define ANOMALY_05000169 /* DATA CPLB page miss can result in lost write-through
+ cache data writes */
+#define ANOMALY_05000171 /* Boot-ROM code modifies SICA_IWRx wakeup registers */
+#define ANOMALY_05000174 /* Cache Fill Buffer Data lost */
+#define ANOMALY_05000175 /* Overlapping Sequencer and Memory Stalls */
+#define ANOMALY_05000176 /* Multiplication of (-1) by (-1) followed by an
+ accumulator saturation */
+#define ANOMALY_05000179 /* PPI_COUNT cannot be programmed to 0 in General
+ Purpose TX or RX modes */
+#define ANOMALY_05000181 /* Disabling the PPI resets the PPI configuration
+ registers */
+#define ANOMALY_05000184 /* Timer Pin limitations for PPI TX Modes with
+ External Frame Syncs */
+#define ANOMALY_05000185 /* PPI TX Mode with 2 External Frame Syncs */
+#define ANOMALY_05000186 /* PPI packing with Data Length greater than 8 bits
+ (not a meaningful mode) */
+#define ANOMALY_05000188 /* IMDMA Restrictions on Descriptor and Buffer
+ Placement in Memory */
+#define ANOMALY_05000189 /* False Protection Exception */
+#define ANOMALY_05000193 /* False Flag Pin Interrupts on Edge Sensitive Inputs
+ when polarity setting is changed */
+#define ANOMALY_05000194 /* Restarting SPORT in specific modes may cause data
+ corruption */
+#define ANOMALY_05000198 /* Failing MMR accesses when stalled by preceding
+ memory read */
+#define ANOMALY_05000199 /* DMA current address shows wrong value during carry
+ fix */
+#define ANOMALY_05000200 /* SPORT TFS and DT are incorrectly driven during
+ inactive channels in certain conditions */
+#define ANOMALY_05000202 /* Possible infinite stall with specific dual-DAG
+ situation */
+#define ANOMALY_05000204 /* Incorrect data read with write-through cache and
+ allocate cache lines on reads only mode */
+#define ANOMALY_05000205 /* Specific sequence that can cause DMA error or DMA
+ stopping */
+#define ANOMALY_05000207 /* Recovery from "brown-out" condition */
+#define ANOMALY_05000209 /* Speed-Path in computational unit affects certain
+ instructions */
+#define ANOMALY_05000215 /* UART TX Interrupt masked erroneously */
+#define ANOMALY_05000219 /* NMI event at boot time results in unpredictable
+ state */
+#define ANOMALY_05000220 /* Data Corruption with Cached External Memory and
+ Non-Cached On-Chip L2 Memory */
+#define ANOMALY_05000225 /* Incorrect pulse-width of UART start-bit */
+#define ANOMALY_05000227 /* Scratchpad memory bank reads may return incorrect
+ data */
+#define ANOMALY_05000230 /* UART Receiver is less robust against Baudrate
+ Differences in certain Conditions */
+#define ANOMALY_05000231 /* UART STB bit incorrectly affects receiver setting */
+#define ANOMALY_05000232 /* SPORT data transmit lines are incorrectly driven in
+ multichannel mode */
+#define ANOMALY_05000242 /* DF bit in PLL_CTL register does not respond to
+ hardware reset */
+#define ANOMALY_05000244 /* If i-cache is on, CSYNC/SSYNC/IDLE around Change of
+ Control causes failures */
+#define ANOMALY_05000248 /* TESTSET operation forces stall on the other core */
+#define ANOMALY_05000250 /* Incorrect Bit-Shift of Data Word in Multichannel
+ (TDM) mode in certain conditions */
+#define ANOMALY_05000251 /* Exception not generated for MMR accesses in
+ reserved region */
+#define ANOMALY_05000253 /* Maximum external clock speed for Timers */
+#define ANOMALY_05000258 /* Instruction Cache is corrupted when bits 9 and 12
+ of the ICPLB Data registers differ */
+#define ANOMALY_05000260 /* ICPLB_STATUS MMR register may be corrupted */
+#define ANOMALY_05000261 /* DCPLB_FAULT_ADDR MMR register may be corrupted */
+#define ANOMALY_05000262 /* Stores to data cache may be lost */
+#define ANOMALY_05000263 /* Hardware loop corrupted when taking an ICPLB
+ exception */
+#define ANOMALY_05000264 /* CSYNC/SSYNC/IDLE causes infinite stall in second
+ to last instruction in hardware loop */
+#define ANOMALY_05000276 /* Timing requirements change for External Frame
+ Sync PPI Modes with non-zero PPI_DELAY */
+#define ANOMALY_05000278 /* Disabling Peripherals with DMA running may cause
+ DMA system instability */
+#define ANOMALY_05000281 /* False Hardware Error Exception when ISR context is
+ not restored */
+#define ANOMALY_05000283 /* An MMR write is stalled indefinitely when killed
+ in a particular stage */
+#define ANOMALY_05000287 /* A read will receive incorrect data under certain
+ conditions */
+#define ANOMALY_05000288 /* SPORTs may receive bad data if FIFOs fill up */
+#endif
+
+#endif /* _MACH_ANOMALY_H_ */
diff --git a/include/asm-blackfin/mach-bf561/bf561.h b/include/asm-blackfin/mach-bf561/bf561.h
new file mode 100644
index 0000000..96a5d3a
--- /dev/null
+++ b/include/asm-blackfin/mach-bf561/bf561.h
@@ -0,0 +1,408 @@
+/*
+ * File: include/asm-blackfin/mach-bf561/bf561.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __MACH_BF561_H__
+#define __MACH_BF561_H__
+
+#define SUPPORTED_REVID 0x3
+
+#define OFFSET_(x) ((x) & 0x0000FFFF)
+#define L1_ISRAM 0xFFA00000
+#define L1_ISRAM_END 0xFFA04000
+#define DATA_BANKA_SRAM 0xFF800000
+#define DATA_BANKA_SRAM_END 0xFF804000
+#define DATA_BANKB_SRAM 0xFF900000
+#define DATA_BANKB_SRAM_END 0xFF904000
+#define L1_DSRAMA 0xFF800000
+#define L1_DSRAMA_END 0xFF804000
+#define L1_DSRAMB 0xFF900000
+#define L1_DSRAMB_END 0xFF904000
+#define L2_SRAM 0xFEB00000
+#define L2_SRAM_END 0xFEB20000
+#define AMB_FLASH 0x20000000
+#define AMB_FLASH_END 0x21000000
+#define AMB_FLASH_LENGTH 0x01000000
+#define L1_ISRAM_LENGTH 0x4000
+#define L1_DSRAMA_LENGTH 0x4000
+#define L1_DSRAMB_LENGTH 0x4000
+#define L2_SRAM_LENGTH 0x20000
+
+/*some misc defines*/
+#define IMASK_IVG15 0x8000
+#define IMASK_IVG14 0x4000
+#define IMASK_IVG13 0x2000
+#define IMASK_IVG12 0x1000
+
+#define IMASK_IVG11 0x0800
+#define IMASK_IVG10 0x0400
+#define IMASK_IVG9 0x0200
+#define IMASK_IVG8 0x0100
+
+#define IMASK_IVG7 0x0080
+#define IMASK_IVGTMR 0x0040
+#define IMASK_IVGHW 0x0020
+
+/***************************
+ * Blackfin Cache setup
+ */
+
+
+#define BLKFIN_ISUBBANKS 4
+#define BLKFIN_IWAYS 4
+#define BLKFIN_ILINES 32
+
+#define BLKFIN_DSUBBANKS 4
+#define BLKFIN_DWAYS 2
+#define BLKFIN_DLINES 64
+
+#define WAY0_L 0x1
+#define WAY1_L 0x2
+#define WAY01_L 0x3
+#define WAY2_L 0x4
+#define WAY02_L 0x5
+#define WAY12_L 0x6
+#define WAY012_L 0x7
+
+#define WAY3_L 0x8
+#define WAY03_L 0x9
+#define WAY13_L 0xA
+#define WAY013_L 0xB
+
+#define WAY32_L 0xC
+#define WAY320_L 0xD
+#define WAY321_L 0xE
+#define WAYALL_L 0xF
+
+#define DMC_ENABLE (2<<2) /*yes, 2, not 1 */
+
+/* IAR0 BIT FIELDS */
+#define PLL_WAKEUP_BIT 0xFFFFFFFF
+#define DMA1_ERROR_BIT 0xFFFFFF0F
+#define DMA2_ERROR_BIT 0xFFFFF0FF
+#define IMDMA_ERROR_BIT 0xFFFF0FFF
+#define PPI1_ERROR_BIT 0xFFF0FFFF
+#define PPI2_ERROR_BIT 0xFF0FFFFF
+#define SPORT0_ERROR_BIT 0xF0FFFFFF
+#define SPORT1_ERROR_BIT 0x0FFFFFFF
+/* IAR1 BIT FIELDS */
+#define SPI_ERROR_BIT 0xFFFFFFFF
+#define UART_ERROR_BIT 0xFFFFFF0F
+#define RESERVED_ERROR_BIT 0xFFFFF0FF
+#define DMA1_0_BIT 0xFFFF0FFF
+#define DMA1_1_BIT 0xFFF0FFFF
+#define DMA1_2_BIT 0xFF0FFFFF
+#define DMA1_3_BIT 0xF0FFFFFF
+#define DMA1_4_BIT 0x0FFFFFFF
+/* IAR2 BIT FIELDS */
+#define DMA1_5_BIT 0xFFFFFFFF
+#define DMA1_6_BIT 0xFFFFFF0F
+#define DMA1_7_BIT 0xFFFFF0FF
+#define DMA1_8_BIT 0xFFFF0FFF
+#define DMA1_9_BIT 0xFFF0FFFF
+#define DMA1_10_BIT 0xFF0FFFFF
+#define DMA1_11_BIT 0xF0FFFFFF
+#define DMA2_0_BIT 0x0FFFFFFF
+/* IAR3 BIT FIELDS */
+#define DMA2_1_BIT 0xFFFFFFFF
+#define DMA2_2_BIT 0xFFFFFF0F
+#define DMA2_3_BIT 0xFFFFF0FF
+#define DMA2_4_BIT 0xFFFF0FFF
+#define DMA2_5_BIT 0xFFF0FFFF
+#define DMA2_6_BIT 0xFF0FFFFF
+#define DMA2_7_BIT 0xF0FFFFFF
+#define DMA2_8_BIT 0x0FFFFFFF
+/* IAR4 BIT FIELDS */
+#define DMA2_9_BIT 0xFFFFFFFF
+#define DMA2_10_BIT 0xFFFFFF0F
+#define DMA2_11_BIT 0xFFFFF0FF
+#define TIMER0_BIT 0xFFFF0FFF
+#define TIMER1_BIT 0xFFF0FFFF
+#define TIMER2_BIT 0xFF0FFFFF
+#define TIMER3_BIT 0xF0FFFFFF
+#define TIMER4_BIT 0x0FFFFFFF
+/* IAR5 BIT FIELDS */
+#define TIMER5_BIT 0xFFFFFFFF
+#define TIMER6_BIT 0xFFFFFF0F
+#define TIMER7_BIT 0xFFFFF0FF
+#define TIMER8_BIT 0xFFFF0FFF
+#define TIMER9_BIT 0xFFF0FFFF
+#define TIMER10_BIT 0xFF0FFFFF
+#define TIMER11_BIT 0xF0FFFFFF
+#define PROG0_INTA_BIT 0x0FFFFFFF
+/* IAR6 BIT FIELDS */
+#define PROG0_INTB_BIT 0xFFFFFFFF
+#define PROG1_INTA_BIT 0xFFFFFF0F
+#define PROG1_INTB_BIT 0xFFFFF0FF
+#define PROG2_INTA_BIT 0xFFFF0FFF
+#define PROG2_INTB_BIT 0xFFF0FFFF
+#define DMA1_WRRD0_BIT 0xFF0FFFFF
+#define DMA1_WRRD1_BIT 0xF0FFFFFF
+#define DMA2_WRRD0_BIT 0x0FFFFFFF
+/* IAR7 BIT FIELDS */
+#define DMA2_WRRD1_BIT 0xFFFFFFFF
+#define IMDMA_WRRD0_BIT 0xFFFFFF0F
+#define IMDMA_WRRD1_BIT 0xFFFFF0FF
+#define WATCH_BIT 0xFFFF0FFF
+#define RESERVED_1_BIT 0xFFF0FFFF
+#define RESERVED_2_BIT 0xFF0FFFFF
+#define SUPPLE_0_BIT 0xF0FFFFFF
+#define SUPPLE_1_BIT 0x0FFFFFFF
+
+/* Miscellaneous Values */
+
+/****************************** EBIU Settings ********************************/
+#define AMBCTL0VAL ((CONFIG_BANK_1 << 16) | CONFIG_BANK_0)
+#define AMBCTL1VAL ((CONFIG_BANK_3 << 16) | CONFIG_BANK_2)
+
+#if defined(CONFIG_C_AMBEN_ALL)
+#define V_AMBEN AMBEN_ALL
+#elif defined(CONFIG_C_AMBEN)
+#define V_AMBEN 0x0
+#elif defined(CONFIG_C_AMBEN_B0)
+#define V_AMBEN AMBEN_B0
+#elif defined(CONFIG_C_AMBEN_B0_B1)
+#define V_AMBEN AMBEN_B0_B1
+#elif defined(CONFIG_C_AMBEN_B0_B1_B2)
+#define V_AMBEN AMBEN_B0_B1_B2
+#endif
+
+#ifdef CONFIG_C_AMCKEN
+#define V_AMCKEN AMCKEN
+#else
+#define V_AMCKEN 0x0
+#endif
+
+#ifdef CONFIG_C_B0PEN
+#define V_B0PEN 0x10
+#else
+#define V_B0PEN 0x00
+#endif
+
+#ifdef CONFIG_C_B1PEN
+#define V_B1PEN 0x20
+#else
+#define V_B1PEN 0x00
+#endif
+
+#ifdef CONFIG_C_B2PEN
+#define V_B2PEN 0x40
+#else
+#define V_B2PEN 0x00
+#endif
+
+#ifdef CONFIG_C_B3PEN
+#define V_B3PEN 0x80
+#else
+#define V_B3PEN 0x00
+#endif
+
+#ifdef CONFIG_C_CDPRIO
+#define V_CDPRIO 0x100
+#else
+#define V_CDPRIO 0x0
+#endif
+
+#define AMGCTLVAL (V_AMBEN | V_AMCKEN | V_CDPRIO | V_B0PEN | V_B1PEN | V_B2PEN | V_B3PEN | 0x0002)
+
+#define MAX_VC 600000000
+#define MIN_VC 50000000
+
+/******************************* PLL Settings ********************************/
+#ifdef CONFIG_BFIN_KERNEL_CLOCK
+#if (CONFIG_VCO_MULT < 0)
+#error "VCO Multiplier is less than 0. Please select a different value"
+#endif
+
+#if (CONFIG_VCO_MULT == 0)
+#error "VCO Multiplier should be greater than 0. Please select a different value"
+#endif
+
+#ifndef CONFIG_CLKIN_HALF
+#define CONFIG_VCO_HZ (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)
+#else
+#define CONFIG_VCO_HZ ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)/2)
+#endif
+
+#ifndef CONFIG_PLL_BYPASS
+#define CONFIG_CCLK_HZ (CONFIG_VCO_HZ/CONFIG_CCLK_DIV)
+#define CONFIG_SCLK_HZ (CONFIG_VCO_HZ/CONFIG_SCLK_DIV)
+#else
+#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ
+#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ
+#endif
+
+#if (CONFIG_SCLK_DIV < 1)
+#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
+#endif
+
+#if (CONFIG_SCLK_DIV > 15)
+#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
+#endif
+
+#if (CONFIG_CCLK_DIV != 1)
+#if (CONFIG_CCLK_DIV != 2)
+#if (CONFIG_CCLK_DIV != 4)
+#if (CONFIG_CCLK_DIV != 8)
+#error "CCLK DIV can be 1,2,4 or 8 only. Please select a proper value"
+#endif
+#endif
+#endif
+#endif
+
+#if (CONFIG_VCO_HZ > MAX_VC)
+#error "VCO selected is more than maximum value. Please change the VCO multipler"
+#endif
+
+#if (CONFIG_SCLK_HZ > 133000000)
+#error "Sclk value selected is more than maximum. Please select a proper value for SCLK multiplier"
+#endif
+
+#if (CONFIG_SCLK_HZ < 27000000)
+#error "Sclk value selected is less than minimum. Please select a proper value for SCLK multiplier"
+#endif
+
+#if (CONFIG_SCLK_HZ >= CONFIG_CCLK_HZ)
+#if (CONFIG_SCLK_HZ != CONFIG_CLKIN_HZ)
+#if (CONFIG_CCLK_HZ != CONFIG_CLKIN_HZ)
+#error "Please select sclk less than cclk"
+#endif
+#endif
+#endif
+
+#if (CONFIG_CCLK_DIV == 1)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV1
+#endif
+#if (CONFIG_CCLK_DIV == 2)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV2
+#endif
+#if (CONFIG_CCLK_DIV == 4)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV4
+#endif
+#if (CONFIG_CCLK_DIV == 8)
+#define CONFIG_CCLK_ACT_DIV CCLK_DIV8
+#endif
+#ifndef CONFIG_CCLK_ACT_DIV
+#define CONFIG_CCLK_ACT_DIV CONFIG_CCLK_DIV_not_defined_properly
+#endif
+
+#if defined(ANOMALY_05000273) && (CONFIG_CCLK_DIV == 1)
+#error ANOMALY 05000273, please make sure CCLK is at least 2x SCLK
+#endif
+
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+#ifdef CONFIG_BF561
+#define CPU "BF561"
+#define CPUID 0x027bb000
+#endif
+#ifndef CPU
+#define CPU "UNKNOWN"
+#define CPUID 0x0
+#endif
+
+#if (CONFIG_MEM_SIZE % 4)
+#error "SDRAM memory size must be a multiple of 4MB!"
+#endif
+#define SDRAM_IGENERIC (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO)
+#define SDRAM_IKERNEL (SDRAM_IGENERIC | CPLB_LOCK)
+#define L1_IMEMORY ( CPLB_USER_RD | CPLB_VALID | CPLB_LOCK)
+#define SDRAM_INON_CHBL ( CPLB_USER_RD | CPLB_VALID)
+
+/*Use the menuconfig cache policy here - CONFIG_BLKFIN_WT/CONFIG_BLKFIN_WB*/
+
+#define ANOMALY_05000158_WORKAROUND 0x200
+#ifdef CONFIG_BLKFIN_WB /*Write Back Policy */
+#define SDRAM_DGENERIC (CPLB_L1_CHBL | CPLB_DIRTY \
+ | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)
+#else /*Write Through */
+#define SDRAM_DGENERIC (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_DIRTY \
+ | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)
+#endif
+
+
+#define L1_DMEMORY (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)
+#define SDRAM_DNON_CHBL (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY)
+#define SDRAM_EBIU (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY)
+#define SDRAM_OOPS (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)
+
+#define L2_MEMORY (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY)
+
+#define SIZE_1K 0x00000400 /* 1K */
+#define SIZE_4K 0x00001000 /* 4K */
+#define SIZE_1M 0x00100000 /* 1M */
+#define SIZE_4M 0x00400000 /* 4M */
+
+#define MAX_CPLBS (16 * 2)
+
+/*
+* Number of required data CPLB switchtable entries
+* MEMSIZE / 4 (we mostly install 4M page size CPLBs
+* approx 16 for smaller 1MB page size CPLBs for allignment purposes
+* 1 for L1 Data Memory
+* 1 for L2 Data Memory
+* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
+* 64 for ASYNC Memory
+*/
+
+
+#define MAX_SWITCH_D_CPLBS (((CONFIG_MEM_SIZE / 4) + 16 + 1 + 1 + 1 + 64) * 2)
+
+/*
+* Number of required instruction CPLB switchtable entries
+* MEMSIZE / 4 (we mostly install 4M page size CPLBs
+* approx 12 for smaller 1MB page size CPLBs for allignment purposes
+* 1 for L1 Instruction Memory
+* 1 for L2 Instruction Memory
+* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
+*/
+
+#define MAX_SWITCH_I_CPLBS (((CONFIG_MEM_SIZE / 4) + 12 + 1 + 1 + 1) * 2)
+
+#if 0 /* comment by mhfan */
+/* Event Vector Table Address */
+#define EVT_EMULATION_ADDR 0xffe02000
+#define EVT_RESET_ADDR 0xffe02004
+#define EVT_NMI_ADDR 0xffe02008
+#define EVT_EXCEPTION_ADDR 0xffe0200c
+#define EVT_GLOBAL_INT_ENB_ADDR 0xffe02010
+#define EVT_HARDWARE_ERROR_ADDR 0xffe02014
+#define EVT_TIMER_ADDR 0xffe02018
+#define EVT_IVG7_ADDR 0xffe0201c
+#define EVT_IVG8_ADDR 0xffe02020
+#define EVT_IVG9_ADDR 0xffe02024
+#define EVT_IVG10_ADDR 0xffe02028
+#define EVT_IVG11_ADDR 0xffe0202c
+#define EVT_IVG12_ADDR 0xffe02030
+#define EVT_IVG13_ADDR 0xffe02034
+#define EVT_IVG14_ADDR 0xffe02038
+#define EVT_IVG15_ADDR 0xffe0203c
+#define EVT_OVERRIDE_ADDR 0xffe02100
+#endif /* comment by mhfan */
+
+#endif /* __MACH_BF561_H__ */
diff --git a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
new file mode 100644
index 0000000..23bf76a
--- /dev/null
+++ b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
@@ -0,0 +1,108 @@
+#include <linux/serial.h>
+#include <asm/dma.h>
+
+#define NR_PORTS 1
+
+#define OFFSET_THR 0x00 /* Transmit Holding register */
+#define OFFSET_RBR 0x00 /* Receive Buffer register */
+#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */
+#define OFFSET_IER 0x04 /* Interrupt Enable Register */
+#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */
+#define OFFSET_IIR 0x08 /* Interrupt Identification Register */
+#define OFFSET_LCR 0x0C /* Line Control Register */
+#define OFFSET_MCR 0x10 /* Modem Control Register */
+#define OFFSET_LSR 0x14 /* Line Status Register */
+#define OFFSET_MSR 0x18 /* Modem Status Register */
+#define OFFSET_SCR 0x1C /* SCR Scratch Register */
+#define OFFSET_GCTL 0x24 /* Global Control Register */
+
+#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR))
+#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL))
+#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER))
+#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
+#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR))
+#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
+#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR))
+#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
+
+#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v)
+#define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
+#define UART_PUT_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER),v)
+#define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
+#define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
+#define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
+
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+# define CONFIG_SERIAL_BFIN_CTSRTS
+# ifndef CONFIG_UART0_CTS_PIN
+# define CONFIG_UART0_CTS_PIN -1
+# endif
+# ifndef CONFIG_UART0_RTS_PIN
+# define CONFIG_UART0_RTS_PIN -1
+# endif
+#endif
+
+struct bfin_serial_port {
+ struct uart_port port;
+ unsigned int old_status;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ int tx_done;
+ int tx_count;
+ struct circ_buf rx_dma_buf;
+ struct timer_list rx_dma_timer;
+ int rx_dma_nrows;
+ unsigned int tx_dma_channel;
+ unsigned int rx_dma_channel;
+ struct work_struct tx_dma_workqueue;
+#else
+ struct work_struct cts_workqueue;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ int cts_pin;
+ int rts_pin;
+#endif
+};
+
+struct bfin_serial_port bfin_serial_ports[NR_PORTS];
+struct bfin_serial_res {
+ unsigned long uart_base_addr;
+ int uart_irq;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ unsigned int uart_tx_dma_channel;
+ unsigned int uart_rx_dma_channel;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ int uart_cts_pin;
+ int uart_rts_pin;
+#endif
+};
+
+struct bfin_serial_res bfin_serial_resource[] = {
+ 0xFFC00400,
+ IRQ_UART_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ CH_UART_TX,
+ CH_UART_RX,
+#endif
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+ CONFIG_UART0_CTS_PIN,
+ CONFIG_UART0_RTS_PIN,
+#endif
+};
+
+
+int nr_ports = NR_PORTS;
+static void bfin_serial_hw_init(struct bfin_serial_port *uart)
+{
+
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ if (uart->cts_pin >= 0) {
+ gpio_request(uart->cts_pin, NULL);
+ gpio_direction_input(uart->cts_pin);
+ }
+ if (uart->rts_pin >= 0) {
+ gpio_request(uart->rts_pin, NULL);
+ gpio_direction_input(uart->rts_pin);
+ }
+#endif
+}
diff --git a/include/asm-blackfin/mach-bf561/blackfin.h b/include/asm-blackfin/mach-bf561/blackfin.h
new file mode 100644
index 0000000..2537c84
--- /dev/null
+++ b/include/asm-blackfin/mach-bf561/blackfin.h
@@ -0,0 +1,52 @@
+/*
+ * File: include/asm-blackfin/mach-bf561/blackfin.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MACH_BLACKFIN_H_
+#define _MACH_BLACKFIN_H_
+
+#define BF561_FAMILY
+
+#include "bf561.h"
+#include "mem_map.h"
+#include "defBF561.h"
+#include "anomaly.h"
+
+#if !(defined(__ASSEMBLY__) || defined(ASSEMBLY))
+#include "cdefBF561.h"
+#endif
+
+#define bfin_read_FIO_FLAG_D() bfin_read_FIO0_FLAG_D()
+#define bfin_write_FIO_FLAG_D(val) bfin_write_FIO0_FLAG_D(val)
+#define bfin_read_FIO_DIR() bfin_read_FIO0_DIR()
+#define bfin_write_FIO_DIR(val) bfin_write_FIO0_DIR(val)
+#define bfin_read_FIO_INEN() bfin_read_FIO0_INEN()
+#define bfin_write_FIO_INEN(val) bfin_write_FIO0_INEN(val)
+
+#endif /* _MACH_BLACKFIN_H_ */
diff --git a/include/asm-blackfin/mach-bf561/cdefBF561.h b/include/asm-blackfin/mach-bf561/cdefBF561.h
new file mode 100644
index 0000000..5dc0ed8
--- /dev/null
+++ b/include/asm-blackfin/mach-bf561/cdefBF561.h
@@ -0,0 +1,1543 @@
+/*
+ * File: include/asm-blackfin/mach-bf561/cdefBF561.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: C POINTERS TO SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _CDEF_BF561_H
+#define _CDEF_BF561_H
+
+/*
+#if !defined(__ADSPBF561__)
+#warning cdefBF561.h should only be included for BF561 chip.
+#endif
+*/
+/* include all Core registers and bit definitions */
+#include "defBF561.h"
+
+/*include core specific register pointer definitions*/
+#include <asm/mach-common/cdef_LPBlackfin.h>
+
+#include <asm/system.h>
+
+/*********************************************************************************** */
+/* System MMR Register Map */
+/*********************************************************************************** */
+
+/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */
+#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL)
+#define bfin_write_PLL_CTL(val) bfin_write16(PLL_CTL,val)
+#define bfin_read_PLL_DIV() bfin_read16(PLL_DIV)
+#define bfin_write_PLL_DIV(val) bfin_write16(PLL_DIV,val)
+#define bfin_read_VR_CTL() bfin_read16(VR_CTL)
+/* Writing to VR_CTL initiates a PLL relock sequence. */
+static __inline__ void bfin_write_VR_CTL(unsigned int val)
+{
+ unsigned long flags, iwr;
+
+ bfin_write16(VR_CTL, val);
+ __builtin_bfin_ssync();
+ /* Enable the PLL Wakeup bit in SIC IWR */
+ iwr = bfin_read32(SICA_IWR0);
+ /* Only allow PPL Wakeup) */
+ bfin_write32(SICA_IWR0, IWR_ENABLE(0));
+ local_irq_save(flags);
+ asm("IDLE;");
+ local_irq_restore(flags);
+ bfin_write32(SICA_IWR0, iwr);
+}
+#define bfin_read_PLL_STAT() bfin_read16(PLL_STAT)
+#define bfin_write_PLL_STAT(val) bfin_write16(PLL_STAT,val)
+#define bfin_read_PLL_LOCKCNT() bfin_read16(PLL_LOCKCNT)
+#define bfin_write_PLL_LOCKCNT(val) bfin_write16(PLL_LOCKCNT,val)
+#define bfin_read_CHIPID() bfin_read32(CHIPID)
+
+/* System Reset and Interrupt Controller registers for core A (0xFFC0 0100-0xFFC0 01FF) */
+#define bfin_read_SICA_SWRST() bfin_read16(SICA_SWRST)
+#define bfin_write_SICA_SWRST(val) bfin_write16(SICA_SWRST,val)
+#define bfin_read_SICA_SYSCR() bfin_read16(SICA_SYSCR)
+#define bfin_write_SICA_SYSCR(val) bfin_write16(SICA_SYSCR,val)
+#define bfin_read_SICA_RVECT() bfin_read16(SICA_RVECT)
+#define bfin_write_SICA_RVECT(val) bfin_write16(SICA_RVECT,val)
+#define bfin_read_SICA_IMASK() bfin_read32(SICA_IMASK)
+#define bfin_write_SICA_IMASK(val) bfin_write32(SICA_IMASK,val)
+#define bfin_read_SICA_IMASK0() bfin_read32(SICA_IMASK0)
+#define bfin_write_SICA_IMASK0(val) bfin_write32(SICA_IMASK0,val)
+#define bfin_read_SICA_IMASK1() bfin_read32(SICA_IMASK1)
+#define bfin_write_SICA_IMASK1(val) bfin_write32(SICA_IMASK1,val)
+#define bfin_read_SICA_IAR0() bfin_read32(SICA_IAR0)
+#define bfin_write_SICA_IAR0(val) bfin_write32(SICA_IAR0,val)
+#define bfin_read_SICA_IAR1() bfin_read32(SICA_IAR1)
+#define bfin_write_SICA_IAR1(val) bfin_write32(SICA_IAR1,val)
+#define bfin_read_SICA_IAR2() bfin_read32(SICA_IAR2)
+#define bfin_write_SICA_IAR2(val) bfin_write32(SICA_IAR2,val)
+#define bfin_read_SICA_IAR3() bfin_read32(SICA_IAR3)
+#define bfin_write_SICA_IAR3(val) bfin_write32(SICA_IAR3,val)
+#define bfin_read_SICA_IAR4() bfin_read32(SICA_IAR4)
+#define bfin_write_SICA_IAR4(val) bfin_write32(SICA_IAR4,val)
+#define bfin_read_SICA_IAR5() bfin_read32(SICA_IAR5)
+#define bfin_write_SICA_IAR5(val) bfin_write32(SICA_IAR5,val)
+#define bfin_read_SICA_IAR6() bfin_read32(SICA_IAR6)
+#define bfin_write_SICA_IAR6(val) bfin_write32(SICA_IAR6,val)
+#define bfin_read_SICA_IAR7() bfin_read32(SICA_IAR7)
+#define bfin_write_SICA_IAR7(val) bfin_write32(SICA_IAR7,val)
+#define bfin_read_SICA_ISR0() bfin_read32(SICA_ISR0)
+#define bfin_write_SICA_ISR0(val) bfin_write32(SICA_ISR0,val)
+#define bfin_read_SICA_ISR1() bfin_read32(SICA_ISR1)
+#define bfin_write_SICA_ISR1(val) bfin_write32(SICA_ISR1,val)
+#define bfin_read_SICA_IWR0() bfin_read32(SICA_IWR0)
+#define bfin_write_SICA_IWR0(val) bfin_write32(SICA_IWR0,val)
+#define bfin_read_SICA_IWR1() bfin_read32(SICA_IWR1)
+#define bfin_write_SICA_IWR1(val) bfin_write32(SICA_IWR1,val)
+
+/* System Reset and Interrupt Controller registers for Core B (0xFFC0 1100-0xFFC0 11FF) */
+#define bfin_read_SICB_SWRST() bfin_read16(SICB_SWRST)
+#define bfin_write_SICB_SWRST(val) bfin_write16(SICB_SWRST,val)
+#define bfin_read_SICB_SYSCR() bfin_read16(SICB_SYSCR)
+#define bfin_write_SICB_SYSCR(val) bfin_write16(SICB_SYSCR,val)
+#define bfin_read_SICB_RVECT() bfin_read16(SICB_RVECT)
+#define bfin_write_SICB_RVECT(val) bfin_write16(SICB_RVECT,val)
+#define bfin_read_SICB_IMASK0() bfin_read32(SICB_IMASK0)
+#define bfin_write_SICB_IMASK0(val) bfin_write32(SICB_IMASK0,val)
+#define bfin_read_SICB_IMASK1() bfin_read32(SICB_IMASK1)
+#define bfin_write_SICB_IMASK1(val) bfin_write32(SICB_IMASK1,val)
+#define bfin_read_SICB_IAR0() bfin_read32(SICB_IAR0)
+#define bfin_write_SICB_IAR0(val) bfin_write32(SICB_IAR0,val)
+#define bfin_read_SICB_IAR1() bfin_read32(SICB_IAR1)
+#define bfin_write_SICB_IAR1(val) bfin_write32(SICB_IAR1,val)
+#define bfin_read_SICB_IAR2() bfin_read32(SICB_IAR2)
+#define bfin_write_SICB_IAR2(val) bfin_write32(SICB_IAR2,val)
+#define bfin_read_SICB_IAR3() bfin_read32(SICB_IAR3)
+#define bfin_write_SICB_IAR3(val) bfin_write32(SICB_IAR3,val)
+#define bfin_read_SICB_IAR4() bfin_read32(SICB_IAR4)
+#define bfin_write_SICB_IAR4(val) bfin_write32(SICB_IAR4,val)
+#define bfin_read_SICB_IAR5() bfin_read32(SICB_IAR5)
+#define bfin_write_SICB_IAR5(val) bfin_write32(SICB_IAR5,val)
+#define bfin_read_SICB_IAR6() bfin_read32(SICB_IAR6)
+#define bfin_write_SICB_IAR6(val) bfin_write32(SICB_IAR6,val)
+#define bfin_read_SICB_IAR7() bfin_read32(SICB_IAR7)
+#define bfin_write_SICB_IAR7(val) bfin_write32(SICB_IAR7,val)
+#define bfin_read_SICB_ISR0() bfin_read32(SICB_ISR0)
+#define bfin_write_SICB_ISR0(val) bfin_write32(SICB_ISR0,val)
+#define bfin_read_SICB_ISR1() bfin_read32(SICB_ISR1)
+#define bfin_write_SICB_ISR1(val) bfin_write32(SICB_ISR1,val)
+#define bfin_read_SICB_IWR0() bfin_read32(SICB_IWR0)
+#define bfin_write_SICB_IWR0(val) bfin_write32(SICB_IWR0,val)
+#define bfin_read_SICB_IWR1() bfin_read32(SICB_IWR1)
+#define bfin_write_SICB_IWR1(val) bfin_write32(SICB_IWR1,val)
+/* Watchdog Timer registers for Core A (0xFFC0 0200-0xFFC0 02FF) */
+#define bfin_read_WDOGA_CTL() bfin_read16(WDOGA_CTL)
+#define bfin_write_WDOGA_CTL(val) bfin_write16(WDOGA_CTL,val)
+#define bfin_read_WDOGA_CNT() bfin_read32(WDOGA_CNT)
+#define bfin_write_WDOGA_CNT(val) bfin_write32(WDOGA_CNT,val)
+#define bfin_read_WDOGA_STAT() bfin_read32(WDOGA_STAT)
+#define bfin_write_WDOGA_STAT(val) bfin_write32(WDOGA_STAT,val)
+
+/* Watchdog Timer registers for Core B (0xFFC0 1200-0xFFC0 12FF) */
+#define bfin_read_WDOGB_CTL() bfin_read16(WDOGB_CTL)
+#define bfin_write_WDOGB_CTL(val) bfin_write16(WDOGB_CTL,val)
+#define bfin_read_WDOGB_CNT() bfin_read32(WDOGB_CNT)
+#define bfin_write_WDOGB_CNT(val) bfin_write32(WDOGB_CNT,val)
+#define bfin_read_WDOGB_STAT() bfin_read32(WDOGB_STAT)
+#define bfin_write_WDOGB_STAT(val) bfin_write32(WDOGB_STAT,val)
+
+/* UART Controller (0xFFC00400 - 0xFFC004FF) */
+#define bfin_read_UART_THR() bfin_read16(UART_THR)
+#define bfin_write_UART_THR(val) bfin_write16(UART_THR,val)
+#define bfin_read_UART_RBR() bfin_read16(UART_RBR)
+#define bfin_write_UART_RBR(val) bfin_write16(UART_RBR,val)
+#define bfin_read_UART_DLL() bfin_read16(UART_DLL)
+#define bfin_write_UART_DLL(val) bfin_write16(UART_DLL,val)
+#define bfin_read_UART_IER() bfin_read16(UART_IER)
+#define bfin_write_UART_IER(val) bfin_write16(UART_IER,val)
+#define bfin_read_UART_DLH() bfin_read16(UART_DLH)
+#define bfin_write_UART_DLH(val) bfin_write16(UART_DLH,val)
+#define bfin_read_UART_IIR() bfin_read16(UART_IIR)
+#define bfin_write_UART_IIR(val) bfin_write16(UART_IIR,val)
+#define bfin_read_UART_LCR() bfin_read16(UART_LCR)
+#define bfin_write_UART_LCR(val) bfin_write16(UART_LCR,val)
+#define bfin_read_UART_MCR() bfin_read16(UART_MCR)
+#define bfin_write_UART_MCR(val) bfin_write16(UART_MCR,val)
+#define bfin_read_UART_LSR() bfin_read16(UART_LSR)
+#define bfin_write_UART_LSR(val) bfin_write16(UART_LSR,val)
+#define bfin_read_UART_MSR() bfin_read16(UART_MSR)
+#define bfin_write_UART_MSR(val) bfin_write16(UART_MSR,val)
+#define bfin_read_UART_SCR() bfin_read16(UART_SCR)
+#define bfin_write_UART_SCR(val) bfin_write16(UART_SCR,val)
+#define bfin_read_UART_GCTL() bfin_read16(UART_GCTL)
+#define bfin_write_UART_GCTL(val) bfin_write16(UART_GCTL,val)
+
+/* SPI Controller (0xFFC00500 - 0xFFC005FF) */
+#define bfin_read_SPI_CTL() bfin_read16(SPI_CTL)
+#define bfin_write_SPI_CTL(val) bfin_write16(SPI_CTL,val)
+#define bfin_read_SPI_FLG() bfin_read16(SPI_FLG)
+#define bfin_write_SPI_FLG(val) bfin_write16(SPI_FLG,val)
+#define bfin_read_SPI_STAT() bfin_read16(SPI_STAT)
+#define bfin_write_SPI_STAT(val) bfin_write16(SPI_STAT,val)
+#define bfin_read_SPI_TDBR() bfin_read16(SPI_TDBR)
+#define bfin_write_SPI_TDBR(val) bfin_write16(SPI_TDBR,val)
+#define bfin_read_SPI_RDBR() bfin_read16(SPI_RDBR)
+#define bfin_write_SPI_RDBR(val) bfin_write16(SPI_RDBR,val)
+#define bfin_read_SPI_BAUD() bfin_read16(SPI_BAUD)
+#define bfin_write_SPI_BAUD(val) bfin_write16(SPI_BAUD,val)
+#define bfin_read_SPI_SHADOW() bfin_read16(SPI_SHADOW)
+#define bfin_write_SPI_SHADOW(val) bfin_write16(SPI_SHADOW,val)
+
+/* Timer 0-7 registers (0xFFC0 0600-0xFFC0 06FF) */
+#define bfin_read_TIMER0_CONFIG() bfin_read16(TIMER0_CONFIG)
+#define bfin_write_TIMER0_CONFIG(val) bfin_write16(TIMER0_CONFIG,val)
+#define bfin_read_TIMER0_COUNTER() bfin_read32(TIMER0_COUNTER)
+#define bfin_write_TIMER0_COUNTER(val) bfin_write32(TIMER0_COUNTER,val)
+#define bfin_read_TIMER0_PERIOD() bfin_read32(TIMER0_PERIOD)
+#define bfin_write_TIMER0_PERIOD(val) bfin_write32(TIMER0_PERIOD,val)
+#define bfin_read_TIMER0_WIDTH() bfin_read32(TIMER0_WIDTH)
+#define bfin_write_TIMER0_WIDTH(val) bfin_write32(TIMER0_WIDTH,val)
+#define bfin_read_TIMER1_CONFIG() bfin_read16(TIMER1_CONFIG)
+#define bfin_write_TIMER1_CONFIG(val) bfin_write16(TIMER1_CONFIG,val)
+#define bfin_read_TIMER1_COUNTER() bfin_read32(TIMER1_COUNTER)
+#define bfin_write_TIMER1_COUNTER(val) bfin_write32(TIMER1_COUNTER,val)
+#define bfin_read_TIMER1_PERIOD() bfin_read32(TIMER1_PERIOD)
+#define bfin_write_TIMER1_PERIOD(val) bfin_write32(TIMER1_PERIOD,val)
+#define bfin_read_TIMER1_WIDTH() bfin_read32(TIMER1_WIDTH)
+#define bfin_write_TIMER1_WIDTH(val) bfin_write32(TIMER1_WIDTH,val)
+#define bfin_read_TIMER2_CONFIG() bfin_read16(TIMER2_CONFIG)
+#define bfin_write_TIMER2_CONFIG(val) bfin_write16(TIMER2_CONFIG,val)
+#define bfin_read_TIMER2_COUNTER() bfin_read32(TIMER2_COUNTER)
+#define bfin_write_TIMER2_COUNTER(val) bfin_write32(TIMER2_COUNTER,val)
+#define bfin_read_TIMER2_PERIOD() bfin_read32(TIMER2_PERIOD)
+#define bfin_write_TIMER2_PERIOD(val) bfin_write32(TIMER2_PERIOD,val)
+#define bfin_read_TIMER2_WIDTH() bfin_read32(TIMER2_WIDTH)
+#define bfin_write_TIMER2_WIDTH(val) bfin_write32(TIMER2_WIDTH,val)
+#define bfin_read_TIMER3_CONFIG() bfin_read16(TIMER3_CONFIG)
+#define bfin_write_TIMER3_CONFIG(val) bfin_write16(TIMER3_CONFIG,val)
+#define bfin_read_TIMER3_COUNTER() bfin_read32(TIMER3_COUNTER)
+#define bfin_write_TIMER3_COUNTER(val) bfin_write32(TIMER3_COUNTER,val)
+#define bfin_read_TIMER3_PERIOD() bfin_read32(TIMER3_PERIOD)
+#define bfin_write_TIMER3_PERIOD(val) bfin_write32(TIMER3_PERIOD,val)
+#define bfin_read_TIMER3_WIDTH() bfin_read32(TIMER3_WIDTH)
+#define bfin_write_TIMER3_WIDTH(val) bfin_write32(TIMER3_WIDTH,val)
+#define bfin_read_TIMER4_CONFIG() bfin_read16(TIMER4_CONFIG)
+#define bfin_write_TIMER4_CONFIG(val) bfin_write16(TIMER4_CONFIG,val)
+#define bfin_read_TIMER4_COUNTER() bfin_read32(TIMER4_COUNTER)
+#define bfin_write_TIMER4_COUNTER(val) bfin_write32(TIMER4_COUNTER,val)
+#define bfin_read_TIMER4_PERIOD() bfin_read32(TIMER4_PERIOD)
+#define bfin_write_TIMER4_PERIOD(val) bfin_write32(TIMER4_PERIOD,val)
+#define bfin_read_TIMER4_WIDTH() bfin_read32(TIMER4_WIDTH)
+#define bfin_write_TIMER4_WIDTH(val) bfin_write32(TIMER4_WIDTH,val)
+#define bfin_read_TIMER5_CONFIG() bfin_read16(TIMER5_CONFIG)
+#define bfin_write_TIMER5_CONFIG(val) bfin_write16(TIMER5_CONFIG,val)
+#define bfin_read_TIMER5_COUNTER() bfin_read32(TIMER5_COUNTER)
+#define bfin_write_TIMER5_COUNTER(val) bfin_write32(TIMER5_COUNTER,val)
+#define bfin_read_TIMER5_PERIOD() bfin_read32(TIMER5_PERIOD)
+#define bfin_write_TIMER5_PERIOD(val) bfin_write32(TIMER5_PERIOD,val)
+#define bfin_read_TIMER5_WIDTH() bfin_read32(TIMER5_WIDTH)
+#define bfin_write_TIMER5_WIDTH(val) bfin_write32(TIMER5_WIDTH,val)
+#define bfin_read_TIMER6_CONFIG() bfin_read16(TIMER6_CONFIG)
+#define bfin_write_TIMER6_CONFIG(val) bfin_write16(TIMER6_CONFIG,val)
+#define bfin_read_TIMER6_COUNTER() bfin_read32(TIMER6_COUNTER)
+#define bfin_write_TIMER6_COUNTER(val) bfin_write32(TIMER6_COUNTER,val)
+#define bfin_read_TIMER6_PERIOD() bfin_read32(TIMER6_PERIOD)
+#define bfin_write_TIMER6_PERIOD(val) bfin_write32(TIMER6_PERIOD,val)
+#define bfin_read_TIMER6_WIDTH() bfin_read32(TIMER6_WIDTH)
+#define bfin_write_TIMER6_WIDTH(val) bfin_write32(TIMER6_WIDTH,val)
+#define bfin_read_TIMER7_CONFIG() bfin_read16(TIMER7_CONFIG)
+#define bfin_write_TIMER7_CONFIG(val) bfin_write16(TIMER7_CONFIG,val)
+#define bfin_read_TIMER7_COUNTER() bfin_read32(TIMER7_COUNTER)
+#define bfin_write_TIMER7_COUNTER(val) bfin_write32(TIMER7_COUNTER,val)
+#define bfin_read_TIMER7_PERIOD() bfin_read32(TIMER7_PERIOD)
+#define bfin_write_TIMER7_PERIOD(val) bfin_write32(TIMER7_PERIOD,val)
+#define bfin_read_TIMER7_WIDTH() bfin_read32(TIMER7_WIDTH)
+#define bfin_write_TIMER7_WIDTH(val) bfin_write32(TIMER7_WIDTH,val)
+
+/* Timer registers 8-11 (0xFFC0 1600-0xFFC0 16FF) */
+#define bfin_read_TMRS8_ENABLE() bfin_read16(TMRS8_ENABLE)
+#define bfin_write_TMRS8_ENABLE(val) bfin_write16(TMRS8_ENABLE,val)
+#define bfin_read_TMRS8_DISABLE() bfin_read16(TMRS8_DISABLE)
+#define bfin_write_TMRS8_DISABLE(val) bfin_write16(TMRS8_DISABLE,val)
+#define bfin_read_TMRS8_STATUS() bfin_read32(TMRS8_STATUS)
+#define bfin_write_TMRS8_STATUS(val) bfin_write32(TMRS8_STATUS,val)
+#define bfin_read_TIMER8_CONFIG() bfin_read16(TIMER8_CONFIG)
+#define bfin_write_TIMER8_CONFIG(val) bfin_write16(TIMER8_CONFIG,val)
+#define bfin_read_TIMER8_COUNTER() bfin_read32(TIMER8_COUNTER)
+#define bfin_write_TIMER8_COUNTER(val) bfin_write32(TIMER8_COUNTER,val)
+#define bfin_read_TIMER8_PERIOD() bfin_read32(TIMER8_PERIOD)
+#define bfin_write_TIMER8_PERIOD(val) bfin_write32(TIMER8_PERIOD,val)
+#define bfin_read_TIMER8_WIDTH() bfin_read32(TIMER8_WIDTH)
+#define bfin_write_TIMER8_WIDTH(val) bfin_write32(TIMER8_WIDTH,val)
+#define bfin_read_TIMER9_CONFIG() bfin_read16(TIMER9_CONFIG)
+#define bfin_write_TIMER9_CONFIG(val) bfin_write16(TIMER9_CONFIG,val)
+#define bfin_read_TIMER9_COUNTER() bfin_read32(TIMER9_COUNTER)
+#define bfin_write_TIMER9_COUNTER(val) bfin_write32(TIMER9_COUNTER,val)
+#define bfin_read_TIMER9_PERIOD() bfin_read32(TIMER9_PERIOD)
+#define bfin_write_TIMER9_PERIOD(val) bfin_write32(TIMER9_PERIOD,val)
+#define bfin_read_TIMER9_WIDTH() bfin_read32(TIMER9_WIDTH)
+#define bfin_write_TIMER9_WIDTH(val) bfin_write32(TIMER9_WIDTH,val)
+#define bfin_read_TIMER10_CONFIG() bfin_read16(TIMER10_CONFIG)
+#define bfin_write_TIMER10_CONFIG(val) bfin_write16(TIMER10_CONFIG,val)
+#define bfin_read_TIMER10_COUNTER() bfin_read32(TIMER10_COUNTER)
+#define bfin_write_TIMER10_COUNTER(val) bfin_write32(TIMER10_COUNTER,val)
+#define bfin_read_TIMER10_PERIOD() bfin_read32(TIMER10_PERIOD)
+#define bfin_write_TIMER10_PERIOD(val) bfin_write32(TIMER10_PERIOD,val)
+#define bfin_read_TIMER10_WIDTH() bfin_read32(TIMER10_WIDTH)
+#define bfin_write_TIMER10_WIDTH(val) bfin_write32(TIMER10_WIDTH,val)
+#define bfin_read_TIMER11_CONFIG() bfin_read16(TIMER11_CONFIG)
+#define bfin_write_TIMER11_CONFIG(val) bfin_write16(TIMER11_CONFIG,val)
+#define bfin_read_TIMER11_COUNTER() bfin_read32(TIMER11_COUNTER)
+#define bfin_write_TIMER11_COUNTER(val) bfin_write32(TIMER11_COUNTER,val)
+#define bfin_read_TIMER11_PERIOD() bfin_read32(TIMER11_PERIOD)
+#define bfin_write_TIMER11_PERIOD(val) bfin_write32(TIMER11_PERIOD,val)
+#define bfin_read_TIMER11_WIDTH() bfin_read32(TIMER11_WIDTH)
+#define bfin_write_TIMER11_WIDTH(val) bfin_write32(TIMER11_WIDTH,val)
+#define bfin_read_TMRS4_ENABLE() bfin_read16(TMRS4_ENABLE)
+#define bfin_write_TMRS4_ENABLE(val) bfin_write16(TMRS4_ENABLE,val)
+#define bfin_read_TMRS4_DISABLE() bfin_read16(TMRS4_DISABLE)
+#define bfin_write_TMRS4_DISABLE(val) bfin_write16(TMRS4_DISABLE,val)
+#define bfin_read_TMRS4_STATUS() bfin_read32(TMRS4_STATUS)
+#define bfin_write_TMRS4_STATUS(val) bfin_write32(TMRS4_STATUS,val)
+
+/* Programmable Flag 0 registers (0xFFC0 0700-0xFFC0 07FF) */
+#define bfin_read_FIO0_FLAG_D() bfin_read16(FIO0_FLAG_D)
+#define bfin_write_FIO0_FLAG_D(val) bfin_write16(FIO0_FLAG_D,val)
+#define bfin_read_FIO0_FLAG_C() bfin_read16(FIO0_FLAG_C)
+#define bfin_write_FIO0_FLAG_C(val) bfin_write16(FIO0_FLAG_C,val)
+#define bfin_read_FIO0_FLAG_S() bfin_read16(FIO0_FLAG_S)
+#define bfin_write_FIO0_FLAG_S(val) bfin_write16(FIO0_FLAG_S,val)
+#define bfin_read_FIO0_FLAG_T() bfin_read16(FIO0_FLAG_T)
+#define bfin_write_FIO0_FLAG_T(val) bfin_write16(FIO0_FLAG_T,val)
+#define bfin_read_FIO0_MASKA_D() bfin_read16(FIO0_MASKA_D)
+#define bfin_write_FIO0_MASKA_D(val) bfin_write16(FIO0_MASKA_D,val)
+#define bfin_read_FIO0_MASKA_C() bfin_read16(FIO0_MASKA_C)
+#define bfin_write_FIO0_MASKA_C(val) bfin_write16(FIO0_MASKA_C,val)
+#define bfin_read_FIO0_MASKA_S() bfin_read16(FIO0_MASKA_S)
+#define bfin_write_FIO0_MASKA_S(val) bfin_write16(FIO0_MASKA_S,val)
+#define bfin_read_FIO0_MASKA_T() bfin_read16(FIO0_MASKA_T)
+#define bfin_write_FIO0_MASKA_T(val) bfin_write16(FIO0_MASKA_T,val)
+#define bfin_read_FIO0_MASKB_D() bfin_read16(FIO0_MASKB_D)
+#define bfin_write_FIO0_MASKB_D(val) bfin_write16(FIO0_MASKB_D,val)
+#define bfin_read_FIO0_MASKB_C() bfin_read16(FIO0_MASKB_C)
+#define bfin_write_FIO0_MASKB_C(val) bfin_write16(FIO0_MASKB_C,val)
+#define bfin_read_FIO0_MASKB_S() bfin_read16(FIO0_MASKB_S)
+#define bfin_write_FIO0_MASKB_S(val) bfin_write16(FIO0_MASKB_S,val)
+#define bfin_read_FIO0_MASKB_T() bfin_read16(FIO0_MASKB_T)
+#define bfin_write_FIO0_MASKB_T(val) bfin_write16(FIO0_MASKB_T,val)
+#define bfin_read_FIO0_DIR() bfin_read16(FIO0_DIR)
+#define bfin_write_FIO0_DIR(val) bfin_write16(FIO0_DIR,val)
+#define bfin_read_FIO0_POLAR() bfin_read16(FIO0_POLAR)
+#define bfin_write_FIO0_POLAR(val) bfin_write16(FIO0_POLAR,val)
+#define bfin_read_FIO0_EDGE() bfin_read16(FIO0_EDGE)
+#define bfin_write_FIO0_EDGE(val) bfin_write16(FIO0_EDGE,val)
+#define bfin_read_FIO0_BOTH() bfin_read16(FIO0_BOTH)
+#define bfin_write_FIO0_BOTH(val) bfin_write16(FIO0_BOTH,val)
+#define bfin_read_FIO0_INEN() bfin_read16(FIO0_INEN)
+#define bfin_write_FIO0_INEN(val) bfin_write16(FIO0_INEN,val)
+/* Programmable Flag 1 registers (0xFFC0 1500-0xFFC0 15FF) */
+#define bfin_read_FIO1_FLAG_D() bfin_read16(FIO1_FLAG_D)
+#define bfin_write_FIO1_FLAG_D(val) bfin_write16(FIO1_FLAG_D,val)
+#define bfin_read_FIO1_FLAG_C() bfin_read16(FIO1_FLAG_C)
+#define bfin_write_FIO1_FLAG_C(val) bfin_write16(FIO1_FLAG_C,val)
+#define bfin_read_FIO1_FLAG_S() bfin_read16(FIO1_FLAG_S)
+#define bfin_write_FIO1_FLAG_S(val) bfin_write16(FIO1_FLAG_S,val)
+#define bfin_read_FIO1_FLAG_T() bfin_read16(FIO1_FLAG_T)
+#define bfin_write_FIO1_FLAG_T(val) bfin_write16(FIO1_FLAG_T,val)
+#define bfin_read_FIO1_MASKA_D() bfin_read16(FIO1_MASKA_D)
+#define bfin_write_FIO1_MASKA_D(val) bfin_write16(FIO1_MASKA_D,val)
+#define bfin_read_FIO1_MASKA_C() bfin_read16(FIO1_MASKA_C)
+#define bfin_write_FIO1_MASKA_C(val) bfin_write16(FIO1_MASKA_C,val)
+#define bfin_read_FIO1_MASKA_S() bfin_read16(FIO1_MASKA_S)
+#define bfin_write_FIO1_MASKA_S(val) bfin_write16(FIO1_MASKA_S,val)
+#define bfin_read_FIO1_MASKA_T() bfin_read16(FIO1_MASKA_T)
+#define bfin_write_FIO1_MASKA_T(val) bfin_write16(FIO1_MASKA_T,val)
+#define bfin_read_FIO1_MASKB_D() bfin_read16(FIO1_MASKB_D)
+#define bfin_write_FIO1_MASKB_D(val) bfin_write16(FIO1_MASKB_D,val)
+#define bfin_read_FIO1_MASKB_C() bfin_read16(FIO1_MASKB_C)
+#define bfin_write_FIO1_MASKB_C(val) bfin_write16(FIO1_MASKB_C,val)
+#define bfin_read_FIO1_MASKB_S() bfin_read16(FIO1_MASKB_S)
+#define bfin_write_FIO1_MASKB_S(val) bfin_write16(FIO1_MASKB_S,val)
+#define bfin_read_FIO1_MASKB_T() bfin_read16(FIO1_MASKB_T)
+#define bfin_write_FIO1_MASKB_T(val) bfin_write16(FIO1_MASKB_T,val)
+#define bfin_read_FIO1_DIR() bfin_read16(FIO1_DIR)
+#define bfin_write_FIO1_DIR(val) bfin_write16(FIO1_DIR,val)
+#define bfin_read_FIO1_POLAR() bfin_read16(FIO1_POLAR)
+#define bfin_write_FIO1_POLAR(val) bfin_write16(FIO1_POLAR,val)
+#define bfin_read_FIO1_EDGE() bfin_read16(FIO1_EDGE)
+#define bfin_write_FIO1_EDGE(val) bfin_write16(FIO1_EDGE,val)
+#define bfin_read_FIO1_BOTH() bfin_read16(FIO1_BOTH)
+#define bfin_write_FIO1_BOTH(val) bfin_write16(FIO1_BOTH,val)
+#define bfin_read_FIO1_INEN() bfin_read16(FIO1_INEN)
+#define bfin_write_FIO1_INEN(val) bfin_write16(FIO1_INEN,val)
+/* Programmable Flag registers (0xFFC0 1700-0xFFC0 17FF) */
+#define bfin_read_FIO2_FLAG_D() bfin_read16(FIO2_FLAG_D)
+#define bfin_write_FIO2_FLAG_D(val) bfin_write16(FIO2_FLAG_D,val)
+#define bfin_read_FIO2_FLAG_C() bfin_read16(FIO2_FLAG_C)
+#define bfin_write_FIO2_FLAG_C(val) bfin_write16(FIO2_FLAG_C,val)
+#define bfin_read_FIO2_FLAG_S() bfin_read16(FIO2_FLAG_S)
+#define bfin_write_FIO2_FLAG_S(val) bfin_write16(FIO2_FLAG_S,val)
+#define bfin_read_FIO2_FLAG_T() bfin_read16(FIO2_FLAG_T)
+#define bfin_write_FIO2_FLAG_T(val) bfin_write16(FIO2_FLAG_T,val)
+#define bfin_read_FIO2_MASKA_D() bfin_read16(FIO2_MASKA_D)
+#define bfin_write_FIO2_MASKA_D(val) bfin_write16(FIO2_MASKA_D,val)
+#define bfin_read_FIO2_MASKA_C() bfin_read16(FIO2_MASKA_C)
+#define bfin_write_FIO2_MASKA_C(val) bfin_write16(FIO2_MASKA_C,val)
+#define bfin_read_FIO2_MASKA_S() bfin_read16(FIO2_MASKA_S)
+#define bfin_write_FIO2_MASKA_S(val) bfin_write16(FIO2_MASKA_S,val)
+#define bfin_read_FIO2_MASKA_T() bfin_read16(FIO2_MASKA_T)
+#define bfin_write_FIO2_MASKA_T(val) bfin_write16(FIO2_MASKA_T,val)
+#define bfin_read_FIO2_MASKB_D() bfin_read16(FIO2_MASKB_D)
+#define bfin_write_FIO2_MASKB_D(val) bfin_write16(FIO2_MASKB_D,val)
+#define bfin_read_FIO2_MASKB_C() bfin_read16(FIO2_MASKB_C)
+#define bfin_write_FIO2_MASKB_C(val) bfin_write16(FIO2_MASKB_C,val)
+#define bfin_read_FIO2_MASKB_S() bfin_read16(FIO2_MASKB_S)
+#define bfin_write_FIO2_MASKB_S(val) bfin_write16(FIO2_MASKB_S,val)
+#define bfin_read_FIO2_MASKB_T() bfin_read16(FIO2_MASKB_T)
+#define bfin_write_FIO2_MASKB_T(val) bfin_write16(FIO2_MASKB_T,val)
+#define bfin_read_FIO2_DIR() bfin_read16(FIO2_DIR)
+#define bfin_write_FIO2_DIR(val) bfin_write16(FIO2_DIR,val)
+#define bfin_read_FIO2_POLAR() bfin_read16(FIO2_POLAR)
+#define bfin_write_FIO2_POLAR(val) bfin_write16(FIO2_POLAR,val)
+#define bfin_read_FIO2_EDGE() bfin_read16(FIO2_EDGE)
+#define bfin_write_FIO2_EDGE(val) bfin_write16(FIO2_EDGE,val)
+#define bfin_read_FIO2_BOTH() bfin_read16(FIO2_BOTH)
+#define bfin_write_FIO2_BOTH(val) bfin_write16(FIO2_BOTH,val)
+#define bfin_read_FIO2_INEN() bfin_read16(FIO2_INEN)
+#define bfin_write_FIO2_INEN(val) bfin_write16(FIO2_INEN,val)
+/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
+#define bfin_read_SPORT0_TCR1() bfin_read16(SPORT0_TCR1)
+#define bfin_write_SPORT0_TCR1(val) bfin_write16(SPORT0_TCR1,val)
+#define bfin_read_SPORT0_TCR2() bfin_read16(SPORT0_TCR2)
+#define bfin_write_SPORT0_TCR2(val) bfin_write16(SPORT0_TCR2,val)
+#define bfin_read_SPORT0_TCLKDIV() bfin_read16(SPORT0_TCLKDIV)
+#define bfin_write_SPORT0_TCLKDIV(val) bfin_write16(SPORT0_TCLKDIV,val)
+#define bfin_read_SPORT0_TFSDIV() bfin_read16(SPORT0_TFSDIV)
+#define bfin_write_SPORT0_TFSDIV(val) bfin_write16(SPORT0_TFSDIV,val)
+#define bfin_read_SPORT0_TX() bfin_read32(SPORT0_TX)
+#define bfin_write_SPORT0_TX(val) bfin_write32(SPORT0_TX,val)
+#define bfin_read_SPORT0_RX() bfin_read32(SPORT0_RX)
+#define bfin_write_SPORT0_RX(val) bfin_write32(SPORT0_RX,val)
+#define bfin_read_SPORT0_TX32() bfin_read32(SPORT0_TX)
+#define bfin_write_SPORT0_TX32(val) bfin_write32(SPORT0_TX,val)
+#define bfin_read_SPORT0_RX32() bfin_read32(SPORT0_RX)
+#define bfin_write_SPORT0_RX32(val) bfin_write32(SPORT0_RX,val)
+#define bfin_read_SPORT0_TX16() bfin_read16(SPORT0_TX)
+#define bfin_write_SPORT0_TX16(val) bfin_write16(SPORT0_TX,val)
+#define bfin_read_SPORT0_RX16() bfin_read16(SPORT0_RX)
+#define bfin_write_SPORT0_RX16(val) bfin_write16(SPORT0_RX,val)
+#define bfin_read_SPORT0_RCR1() bfin_read16(SPORT0_RCR1)
+#define bfin_write_SPORT0_RCR1(val) bfin_write16(SPORT0_RCR1,val)
+#define bfin_read_SPORT0_RCR2() bfin_read16(SPORT0_RCR2)
+#define bfin_write_SPORT0_RCR2(val) bfin_write16(SPORT0_RCR2,val)
+#define bfin_read_SPORT0_RCLKDIV() bfin_read16(SPORT0_RCLKDIV)
+#define bfin_write_SPORT0_RCLKDIV(val) bfin_write16(SPORT0_RCLKDIV,val)
+#define bfin_read_SPORT0_RFSDIV() bfin_read16(SPORT0_RFSDIV)
+#define bfin_write_SPORT0_RFSDIV(val) bfin_write16(SPORT0_RFSDIV,val)
+#define bfin_read_SPORT0_STAT() bfin_read16(SPORT0_STAT)
+#define bfin_write_SPORT0_STAT(val) bfin_write16(SPORT0_STAT,val)
+#define bfin_read_SPORT0_CHNL() bfin_read16(SPORT0_CHNL)
+#define bfin_write_SPORT0_CHNL(val) bfin_write16(SPORT0_CHNL,val)
+#define bfin_read_SPORT0_MCMC1() bfin_read16(SPORT0_MCMC1)
+#define bfin_write_SPORT0_MCMC1(val) bfin_write16(SPORT0_MCMC1,val)
+#define bfin_read_SPORT0_MCMC2() bfin_read16(SPORT0_MCMC2)
+#define bfin_write_SPORT0_MCMC2(val) bfin_write16(SPORT0_MCMC2,val)
+#define bfin_read_SPORT0_MTCS0() bfin_read32(SPORT0_MTCS0)
+#define bfin_write_SPORT0_MTCS0(val) bfin_write32(SPORT0_MTCS0,val)
+#define bfin_read_SPORT0_MTCS1() bfin_read32(SPORT0_MTCS1)
+#define bfin_write_SPORT0_MTCS1(val) bfin_write32(SPORT0_MTCS1,val)
+#define bfin_read_SPORT0_MTCS2() bfin_read32(SPORT0_MTCS2)
+#define bfin_write_SPORT0_MTCS2(val) bfin_write32(SPORT0_MTCS2,val)
+#define bfin_read_SPORT0_MTCS3() bfin_read32(SPORT0_MTCS3)
+#define bfin_write_SPORT0_MTCS3(val) bfin_write32(SPORT0_MTCS3,val)
+#define bfin_read_SPORT0_MRCS0() bfin_read32(SPORT0_MRCS0)
+#define bfin_write_SPORT0_MRCS0(val) bfin_write32(SPORT0_MRCS0,val)
+#define bfin_read_SPORT0_MRCS1() bfin_read32(SPORT0_MRCS1)
+#define bfin_write_SPORT0_MRCS1(val) bfin_write32(SPORT0_MRCS1,val)
+#define bfin_read_SPORT0_MRCS2() bfin_read32(SPORT0_MRCS2)
+#define bfin_write_SPORT0_MRCS2(val) bfin_write32(SPORT0_MRCS2,val)
+#define bfin_read_SPORT0_MRCS3() bfin_read32(SPORT0_MRCS3)
+#define bfin_write_SPORT0_MRCS3(val) bfin_write32(SPORT0_MRCS3,val)
+/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
+#define bfin_read_SPORT1_TCR1() bfin_read16(SPORT1_TCR1)
+#define bfin_write_SPORT1_TCR1(val) bfin_write16(SPORT1_TCR1,val)
+#define bfin_read_SPORT1_TCR2() bfin_read16(SPORT1_TCR2)
+#define bfin_write_SPORT1_TCR2(val) bfin_write16(SPORT1_TCR2,val)
+#define bfin_read_SPORT1_TCLKDIV() bfin_read16(SPORT1_TCLKDIV)
+#define bfin_write_SPORT1_TCLKDIV(val) bfin_write16(SPORT1_TCLKDIV,val)
+#define bfin_read_SPORT1_TFSDIV() bfin_read16(SPORT1_TFSDIV)
+#define bfin_write_SPORT1_TFSDIV(val) bfin_write16(SPORT1_TFSDIV,val)
+#define bfin_read_SPORT1_TX() bfin_read32(SPORT1_TX)
+#define bfin_write_SPORT1_TX(val) bfin_write32(SPORT1_TX,val)
+#define bfin_read_SPORT1_RX() bfin_read32(SPORT1_RX)
+#define bfin_write_SPORT1_RX(val) bfin_write32(SPORT1_RX,val)
+#define bfin_read_SPORT1_TX32() bfin_read32(SPORT1_TX)
+#define bfin_write_SPORT1_TX32(val) bfin_write32(SPORT1_TX,val)
+#define bfin_read_SPORT1_RX32() bfin_read32(SPORT1_RX)
+#define bfin_write_SPORT1_RX32(val) bfin_write32(SPORT1_RX,val)
+#define bfin_read_SPORT1_TX16() bfin_read16(SPORT1_TX)
+#define bfin_write_SPORT1_TX16(val) bfin_write16(SPORT1_TX,val)
+#define bfin_read_SPORT1_RX16() bfin_read16(SPORT1_RX)
+#define bfin_write_SPORT1_RX16(val) bfin_write16(SPORT1_RX,val)
+#define bfin_read_SPORT1_RCR1() bfin_read16(SPORT1_RCR1)
+#define bfin_write_SPORT1_RCR1(val) bfin_write16(SPORT1_RCR1,val)
+#define bfin_read_SPORT1_RCR2() bfin_read16(SPORT1_RCR2)
+#define bfin_write_SPORT1_RCR2(val) bfin_write16(SPORT1_RCR2,val)
+#define bfin_read_SPORT1_RCLKDIV() bfin_read16(SPORT1_RCLKDIV)
+#define bfin_write_SPORT1_RCLKDIV(val) bfin_write16(SPORT1_RCLKDIV,val)
+#define bfin_read_SPORT1_RFSDIV() bfin_read16(SPORT1_RFSDIV)
+#define bfin_write_SPORT1_RFSDIV(val) bfin_write16(SPORT1_RFSDIV,val)
+#define bfin_read_SPORT1_STAT() bfin_read16(SPORT1_STAT)
+#define bfin_write_SPORT1_STAT(val) bfin_write16(SPORT1_STAT,val)
+#define bfin_read_SPORT1_CHNL() bfin_read16(SPORT1_CHNL)
+#define bfin_write_SPORT1_CHNL(val) bfin_write16(SPORT1_CHNL,val)
+#define bfin_read_SPORT1_MCMC1() bfin_read16(SPORT1_MCMC1)
+#define bfin_write_SPORT1_MCMC1(val) bfin_write16(SPORT1_MCMC1,val)
+#define bfin_read_SPORT1_MCMC2() bfin_read16(SPORT1_MCMC2)
+#define bfin_write_SPORT1_MCMC2(val) bfin_write16(SPORT1_MCMC2,val)
+#define bfin_read_SPORT1_MTCS0() bfin_read32(SPORT1_MTCS0)
+#define bfin_write_SPORT1_MTCS0(val) bfin_write32(SPORT1_MTCS0,val)
+#define bfin_read_SPORT1_MTCS1() bfin_read32(SPORT1_MTCS1)
+#define bfin_write_SPORT1_MTCS1(val) bfin_write32(SPORT1_MTCS1,val)
+#define bfin_read_SPORT1_MTCS2() bfin_read32(SPORT1_MTCS2)
+#define bfin_write_SPORT1_MTCS2(val) bfin_write32(SPORT1_MTCS2,val)
+#define bfin_read_SPORT1_MTCS3() bfin_read32(SPORT1_MTCS3)
+#define bfin_write_SPORT1_MTCS3(val) bfin_write32(SPORT1_MTCS3,val)
+#define bfin_read_SPORT1_MRCS0() bfin_read32(SPORT1_MRCS0)
+#define bfin_write_SPORT1_MRCS0(val) bfin_write32(SPORT1_MRCS0,val)
+#define bfin_read_SPORT1_MRCS1() bfin_read32(SPORT1_MRCS1)
+#define bfin_write_SPORT1_MRCS1(val) bfin_write32(SPORT1_MRCS1,val)
+#define bfin_read_SPORT1_MRCS2() bfin_read32(SPORT1_MRCS2)
+#define bfin_write_SPORT1_MRCS2(val) bfin_write32(SPORT1_MRCS2,val)
+#define bfin_read_SPORT1_MRCS3() bfin_read32(SPORT1_MRCS3)
+#define bfin_write_SPORT1_MRCS3(val) bfin_write32(SPORT1_MRCS3,val)
+/* Asynchronous Memory Controller - External Bus Interface Unit */
+#define bfin_read_EBIU_AMGCTL() bfin_read16(EBIU_AMGCTL)
+#define bfin_write_EBIU_AMGCTL(val) bfin_write16(EBIU_AMGCTL,val)
+#define bfin_read_EBIU_AMBCTL0() bfin_read32(EBIU_AMBCTL0)
+#define bfin_write_EBIU_AMBCTL0(val) bfin_write32(EBIU_AMBCTL0,val)
+#define bfin_read_EBIU_AMBCTL1() bfin_read32(EBIU_AMBCTL1)
+#define bfin_write_EBIU_AMBCTL1(val) bfin_write32(EBIU_AMBCTL1,val)
+/* SDRAM Controller External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
+#define bfin_read_EBIU_SDGCTL() bfin_read32(EBIU_SDGCTL)
+#define bfin_write_EBIU_SDGCTL(val) bfin_write32(EBIU_SDGCTL,val)
+#define bfin_read_EBIU_SDBCTL() bfin_read32(EBIU_SDBCTL)
+#define bfin_write_EBIU_SDBCTL(val) bfin_write32(EBIU_SDBCTL,val)
+#define bfin_read_EBIU_SDRRC() bfin_read16(EBIU_SDRRC)
+#define bfin_write_EBIU_SDRRC(val) bfin_write16(EBIU_SDRRC,val)
+#define bfin_read_EBIU_SDSTAT() bfin_read16(EBIU_SDSTAT)
+#define bfin_write_EBIU_SDSTAT(val) bfin_write16(EBIU_SDSTAT,val)
+/* Parallel Peripheral Interface (PPI) 0 registers (0xFFC0 1000-0xFFC0 10FF) */
+#define bfin_read_PPI0_CONTROL() bfin_read16(PPI0_CONTROL)
+#define bfin_write_PPI0_CONTROL(val) bfin_write16(PPI0_CONTROL,val)
+#define bfin_read_PPI0_STATUS() bfin_read16(PPI0_STATUS)
+#define bfin_write_PPI0_STATUS(val) bfin_write16(PPI0_STATUS,val)
+#define bfin_read_PPI0_COUNT() bfin_read16(PPI0_COUNT)
+#define bfin_write_PPI0_COUNT(val) bfin_write16(PPI0_COUNT,val)
+#define bfin_read_PPI0_DELAY() bfin_read16(PPI0_DELAY)
+#define bfin_write_PPI0_DELAY(val) bfin_write16(PPI0_DELAY,val)
+#define bfin_read_PPI0_FRAME() bfin_read16(PPI0_FRAME)
+#define bfin_write_PPI0_FRAME(val) bfin_write16(PPI0_FRAME,val)
+/* Parallel Peripheral Interface (PPI) 1 registers (0xFFC0 1300-0xFFC0 13FF) */
+#define bfin_read_PPI1_CONTROL() bfin_read16(PPI1_CONTROL)
+#define bfin_write_PPI1_CONTROL(val) bfin_write16(PPI1_CONTROL,val)
+#define bfin_read_PPI1_STATUS() bfin_read16(PPI1_STATUS)
+#define bfin_write_PPI1_STATUS(val) bfin_write16(PPI1_STATUS,val)
+#define bfin_read_PPI1_COUNT() bfin_read16(PPI1_COUNT)
+#define bfin_write_PPI1_COUNT(val) bfin_write16(PPI1_COUNT,val)
+#define bfin_read_PPI1_DELAY() bfin_read16(PPI1_DELAY)
+#define bfin_write_PPI1_DELAY(val) bfin_write16(PPI1_DELAY,val)
+#define bfin_read_PPI1_FRAME() bfin_read16(PPI1_FRAME)
+#define bfin_write_PPI1_FRAME(val) bfin_write16(PPI1_FRAME,val)
+/*DMA traffic control registers */
+#define bfin_read_DMA1_TC_PER() bfin_read16(DMA1_TC_PER)
+#define bfin_write_DMA1_TC_PER(val) bfin_write16(DMA1_TC_PER,val)
+#define bfin_read_DMA1_TC_CNT() bfin_read16(DMA1_TC_CNT)
+#define bfin_write_DMA1_TC_CNT(val) bfin_write16(DMA1_TC_CNT,val)
+#define bfin_read_DMA2_TC_PER() bfin_read16(DMA2_TC_PER)
+#define bfin_write_DMA2_TC_PER(val) bfin_write16(DMA2_TC_PER,val)
+#define bfin_read_DMA2_TC_CNT() bfin_read16(DMA2_TC_CNT)
+#define bfin_write_DMA2_TC_CNT(val) bfin_write16(DMA2_TC_CNT,val)
+/* DMA1 Controller registers (0xFFC0 1C00-0xFFC0 1FFF) */
+#define bfin_read_DMA1_0_CONFIG() bfin_read16(DMA1_0_CONFIG)
+#define bfin_write_DMA1_0_CONFIG(val) bfin_write16(DMA1_0_CONFIG,val)
+#define bfin_read_DMA1_0_NEXT_DESC_PTR() bfin_read32(DMA1_0_NEXT_DESC_PTR)
+#define bfin_write_DMA1_0_NEXT_DESC_PTR(val) bfin_write32(DMA1_0_NEXT_DESC_PTR,val)
+#define bfin_read_DMA1_0_START_ADDR() bfin_read32(DMA1_0_START_ADDR)
+#define bfin_write_DMA1_0_START_ADDR(val) bfin_write32(DMA1_0_START_ADDR,val)
+#define bfin_read_DMA1_0_X_COUNT() bfin_read16(DMA1_0_X_COUNT)
+#define bfin_write_DMA1_0_X_COUNT(val) bfin_write16(DMA1_0_X_COUNT,val)
+#define bfin_read_DMA1_0_Y_COUNT() bfin_read16(DMA1_0_Y_COUNT)
+#define bfin_write_DMA1_0_Y_COUNT(val) bfin_write16(DMA1_0_Y_COUNT,val)
+#define bfin_read_DMA1_0_X_MODIFY() bfin_read16(DMA1_0_X_MODIFY)
+#define bfin_write_DMA1_0_X_MODIFY(val) bfin_write16(DMA1_0_X_MODIFY,val)
+#define bfin_read_DMA1_0_Y_MODIFY() bfin_read16(DMA1_0_Y_MODIFY)
+#define bfin_write_DMA1_0_Y_MODIFY(val) bfin_write16(DMA1_0_Y_MODIFY,val)
+#define bfin_read_DMA1_0_CURR_DESC_PTR() bfin_read32(DMA1_0_CURR_DESC_PTR)
+#define bfin_write_DMA1_0_CURR_DESC_PTR(val) bfin_write32(DMA1_0_CURR_DESC_PTR,val)
+#define bfin_read_DMA1_0_CURR_ADDR() bfin_read32(DMA1_0_CURR_ADDR)
+#define bfin_write_DMA1_0_CURR_ADDR(val) bfin_write32(DMA1_0_CURR_ADDR,val)
+#define bfin_read_DMA1_0_CURR_X_COUNT() bfin_read16(DMA1_0_CURR_X_COUNT)
+#define bfin_write_DMA1_0_CURR_X_COUNT(val) bfin_write16(DMA1_0_CURR_X_COUNT,val)
+#define bfin_read_DMA1_0_CURR_Y_COUNT() bfin_read16(DMA1_0_CURR_Y_COUNT)
+#define bfin_write_DMA1_0_CURR_Y_COUNT(val) bfin_write16(DMA1_0_CURR_Y_COUNT,val)
+#define bfin_read_DMA1_0_IRQ_STATUS() bfin_read16(DMA1_0_IRQ_STATUS)
+#define bfin_write_DMA1_0_IRQ_STATUS(val) bfin_write16(DMA1_0_IRQ_STATUS,val)
+#define bfin_read_DMA1_0_PERIPHERAL_MAP() bfin_read16(DMA1_0_PERIPHERAL_MAP)
+#define bfin_write_DMA1_0_PERIPHERAL_MAP(val) bfin_write16(DMA1_0_PERIPHERAL_MAP,val)
+#define bfin_read_DMA1_1_CONFIG() bfin_read16(DMA1_1_CONFIG)
+#define bfin_write_DMA1_1_CONFIG(val) bfin_write16(DMA1_1_CONFIG,val)
+#define bfin_read_DMA1_1_NEXT_DESC_PTR() bfin_read32(DMA1_1_NEXT_DESC_PTR)
+#define bfin_write_DMA1_1_NEXT_DESC_PTR(val) bfin_write32(DMA1_1_NEXT_DESC_PTR,val)
+#define bfin_read_DMA1_1_START_ADDR() bfin_read32(DMA1_1_START_ADDR)
+#define bfin_write_DMA1_1_START_ADDR(val) bfin_write32(DMA1_1_START_ADDR,val)
+#define bfin_read_DMA1_1_X_COUNT() bfin_read16(DMA1_1_X_COUNT)
+#define bfin_write_DMA1_1_X_COUNT(val) bfin_write16(DMA1_1_X_COUNT,val)
+#define bfin_read_DMA1_1_Y_COUNT() bfin_read16(DMA1_1_Y_COUNT)
+#define bfin_write_DMA1_1_Y_COUNT(val) bfin_write16(DMA1_1_Y_COUNT,val)
+#define bfin_read_DMA1_1_X_MODIFY() bfin_read16(DMA1_1_X_MODIFY)
+#define bfin_write_DMA1_1_X_MODIFY(val) bfin_write16(DMA1_1_X_MODIFY,val)
+#define bfin_read_DMA1_1_Y_MODIFY() bfin_read16(DMA1_1_Y_MODIFY)
+#define bfin_write_DMA1_1_Y_MODIFY(val) bfin_write16(DMA1_1_Y_MODIFY,val)
+#define bfin_read_DMA1_1_CURR_DESC_PTR() bfin_read32(DMA1_1_CURR_DESC_PTR)
+#define bfin_write_DMA1_1_CURR_DESC_PTR(val) bfin_write32(DMA1_1_CURR_DESC_PTR,val)
+#define bfin_read_DMA1_1_CURR_ADDR() bfin_read32(DMA1_1_CURR_ADDR)
+#define bfin_write_DMA1_1_CURR_ADDR(val) bfin_write32(DMA1_1_CURR_ADDR,val)
+#define bfin_read_DMA1_1_CURR_X_COUNT() bfin_read16(DMA1_1_CURR_X_COUNT)
+#define bfin_write_DMA1_1_CURR_X_COUNT(val) bfin_write16(DMA1_1_CURR_X_COUNT,val)
+#define bfin_read_DMA1_1_CURR_Y_COUNT() bfin_read16(DMA1_1_CURR_Y_COUNT)
+#define bfin_write_DMA1_1_CURR_Y_COUNT(val) bfin_write16(DMA1_1_CURR_Y_COUNT,val)
+#define bfin_read_DMA1_1_IRQ_STATUS() bfin_read16(DMA1_1_IRQ_STATUS)
+#define bfin_write_DMA1_1_IRQ_STATUS(val) bfin_write16(DMA1_1_IRQ_STATUS,val)
+#define bfin_read_DMA1_1_PERIPHERAL_MAP() bfin_read16(DMA1_1_PERIPHERAL_MAP)
+#define bfin_write_DMA1_1_PERIPHERAL_MAP(val) bfin_write16(DMA1_1_PERIPHERAL_MAP,val)
+#define bfin_read_DMA1_2_CONFIG() bfin_read16(DMA1_2_CONFIG)
+#define bfin_write_DMA1_2_CONFIG(val) bfin_write16(DMA1_2_CONFIG,val)
+#define bfin_read_DMA1_2_NEXT_DESC_PTR() bfin_read32(DMA1_2_NEXT_DESC_PTR)
+#define bfin_write_DMA1_2_NEXT_DESC_PTR(val) bfin_write32(DMA1_2_NEXT_DESC_PTR,val)
+#define bfin_read_DMA1_2_START_ADDR() bfin_read32(DMA1_2_START_ADDR)
+#define bfin_write_DMA1_2_START_ADDR(val) bfin_write32(DMA1_2_START_ADDR,val)
+#define bfin_read_DMA1_2_X_COUNT() bfin_read16(DMA1_2_X_COUNT)
+#define bfin_write_DMA1_2_X_COUNT(val) bfin_write16(DMA1_2_X_COUNT,val)
+#define bfin_read_DMA1_2_Y_COUNT() bfin_read16(DMA1_2_Y_COUNT)
+#define bfin_write_DMA1_2_Y_COUNT(val) bfin_write16(DMA1_2_Y_COUNT,val)
+#define bfin_read_DMA1_2_X_MODIFY() bfin_read16(DMA1_2_X_MODIFY)
+#define bfin_write_DMA1_2_X_MODIFY(val) bfin_write16(DMA1_2_X_MODIFY,val)
+#define bfin_read_DMA1_2_Y_MODIFY() bfin_read16(DMA1_2_Y_MODIFY)
+#define bfin_write_DMA1_2_Y_MODIFY(val) bfin_write16(DMA1_2_Y_MODIFY,val)
+#define bfin_read_DMA1_2_CURR_DESC_PTR() bfin_read32(DMA1_2_CURR_DESC_PTR)
+#define bfin_write_DMA1_2_CURR_DESC_PTR(val) bfin_write32(DMA1_2_CURR_DESC_PTR,val)
+#define bfin_read_DMA1_2_CURR_ADDR() bfin_read32(DMA1_2_CURR_ADDR)
+#define bfin_write_DMA1_2_CURR_ADDR(val) bfin_write32(DMA1_2_CURR_ADDR,val)
+#define bfin_read_DMA1_2_CURR_X_COUNT() bfin_read16(DMA1_2_CURR_X_COUNT)
+#define bfin_write_DMA1_2_CURR_X_COUNT(val) bfin_write16(DMA1_2_CURR_X_COUNT,val)
+#define bfin_read_DMA1_2_CURR_Y_COUNT() bfin_read16(DMA1_2_CURR_Y_COUNT)
+#define bfin_write_DMA1_2_CURR_Y_COUNT(val) bfin_write16(DMA1_2_CURR_Y_COUNT,val)
+#define bfin_read_DMA1_2_IRQ_STATUS() bfin_read16(DMA1_2_IRQ_STATUS)
+#define bfin_write_DMA1_2_IRQ_STATUS(val) bfin_write16(DMA1_2_IRQ_STATUS,val)
+#define bfin_read_DMA1_2_PERIPHERAL_MAP() bfin_read16(DMA1_2_PERIPHERAL_MAP)
+#define bfin_write_DMA1_2_PERIPHERAL_MAP(val) bfin_write16(DMA1_2_PERIPHERAL_MAP,val)
+#define bfin_read_DMA1_3_CONFIG() bfin_read16(DMA1_3_CONFIG)
+#define bfin_write_DMA1_3_CONFIG(val) bfin_write16(DMA1_3_CONFIG,val)
+#define bfin_read_DMA1_3_NEXT_DESC_PTR() bfin_read32(DMA1_3_NEXT_DESC_PTR)
+#define bfin_write_DMA1_3_NEXT_DESC_PTR(val) bfin_write32(DMA1_3_NEXT_DESC_PTR,val)
+#define bfin_read_DMA1_3_START_ADDR() bfin_read32(DMA1_3_START_ADDR)
+#define bfin_write_DMA1_3_START_ADDR(val) bfin_write32(DMA1_3_START_ADDR,val)
+#define bfin_read_DMA1_3_X_COUNT() bfin_read16(DMA1_3_X_COUNT)
+#define bfin_write_DMA1_3_X_COUNT(val) bfin_write16(DMA1_3_X_COUNT,val)
+#define bfin_read_DMA1_3_Y_COUNT() bfin_read16(DMA1_3_Y_COUNT)
+#define bfin_write_DMA1_3_Y_COUNT(val) bfin_write16(DMA1_3_Y_COUNT,val)
+#define bfin_read_DMA1_3_X_MODIFY() bfin_read16(DMA1_3_X_MODIFY)
+#define bfin_write_DMA1_3_X_MODIFY(val) bfin_write16(DMA1_3_X_MODIFY,val)
+#define bfin_read_DMA1_3_Y_MODIFY() bfin_read16(DMA1_3_Y_MODIFY)
+#define bfin_write_DMA1_3_Y_MODIFY(val) bfin_write16(DMA1_3_Y_MODIFY,val)
+#define bfin_read_DMA1_3_CURR_DESC_PTR() bfin_read32(DMA1_3_CURR_DESC_PTR)
+#define bfin_write_DMA1_3_CURR_DESC_PTR(val) bfin_write32(DMA1_3_CURR_DESC_PTR,val)
+#define bfin_read_DMA1_3_CURR_ADDR() bfin_read32(DMA1_3_CURR_ADDR)
+#define bfin_write_DMA1_3_CURR_ADDR(val) bfin_write32(DMA1_3_CURR_ADDR,val)
+#define bfin_read_DMA1_3_CURR_X_COUNT() bfin_read16(DMA1_3_CURR_X_COUNT)
+#define bfin_write_DMA1_3_CURR_X_COUNT(val) bfin_write16(DMA1_3_CURR_X_COUNT,val)
+#define bfin_read_DMA1_3_CURR_Y_COUNT() bfin_read16(DMA1_3_CURR_Y_COUNT)
+#define bfin_write_DMA1_3_CURR_Y_COUNT(val) bfin_write16(DMA1_3_CURR_Y_COUNT,val)
+#define bfin_read_DMA1_3_IRQ_STATUS() bfin_read16(DMA1_3_IRQ_STATUS)
+#define bfin_write_DMA1_3_IRQ_STATUS(val) bfin_write16(DMA1_3_IRQ_STATUS,val)
+#define bfin_read_DMA1_3_PERIPHERAL_MAP() bfin_read16(DMA1_3_PERIPHERAL_MAP)
+#define bfin_write_DMA1_3_PERIPHERAL_MAP(val) bfin_write16(DMA1_3_PERIPHERAL_MAP,val)
+#define bfin_read_DMA1_4_CONFIG() bfin_read16(DMA1_4_CONFIG)
+#define bfin_write_DMA1_4_CONFIG(val) bfin_write16(DMA1_4_CONFIG,val)
+#define bfin_read_DMA1_4_NEXT_DESC_PTR() bfin_read32(DMA1_4_NEXT_DESC_PTR)
+#define bfin_write_DMA1_4_NEXT_DESC_PTR(val) bfin_write32(DMA1_4_NEXT_DESC_PTR,val)
+#define bfin_read_DMA1_4_START_ADDR() bfin_read32(DMA1_4_START_ADDR)
+#define bfin_write_DMA1_4_START_ADDR(val) bfin_write32(DMA1_4_START_ADDR,val)
+#define bfin_read_DMA1_4_X_COUNT() bfin_read16(DMA1_4_X_COUNT)
+#define bfin_write_DMA1_4_X_COUNT(val) bfin_write16(DMA1_4_X_COUNT,val)
+#define bfin_read_DMA1_4_Y_COUNT() bfin_read16(DMA1_4_Y_COUNT)
+#define bfin_write_DMA1_4_Y_COUNT(val) bfin_write16(DMA1_4_Y_COUNT,val)
+#define bfin_read_DMA1_4_X_MODIFY() bfin_read16(DMA1_4_X_MODIFY)
+#define bfin_write_DMA1_4_X_MODIFY(val) bfin_write16(DMA1_4_X_MODIFY,val)
+#define bfin_read_DMA1_4_Y_MODIFY() bfin_read16(DMA1_4_Y_MODIFY)
+#define bfin_write_DMA1_4_Y_MODIFY(val) bfin_write16(DMA1_4_Y_MODIFY,val)
+#define bfin_read_DMA1_4_CURR_DESC_PTR() bfin_read32(DMA1_4_CURR_DESC_PTR)
+#define bfin_write_DMA1_4_CURR_DESC_PTR(val) bfin_write32(DMA1_4_CURR_DESC_PTR,val)
+#define bfin_read_DMA1_4_CURR_ADDR() bfin_read32(DMA1_4_CURR_ADDR)
+#define bfin_write_DMA1_4_CURR_ADDR(val) bfin_write32(DMA1_4_CURR_ADDR,val)
+#define bfin_read_DMA1_4_CURR_X_COUNT() bfin_read16(DMA1_4_CURR_X_COUNT)
+#define bfin_write_DMA1_4_CURR_X_COUNT(val) bfin_write16(DMA1_4_CURR_X_COUNT,val)
+#define bfin_read_DMA1_4_CURR_Y_COUNT() bfin_read16(DMA1_4_CURR_Y_COUNT)
+#define bfin_write_DMA1_4_CURR_Y_COUNT(val) bfin_write16(DMA1_4_CURR_Y_COUNT,val)
+#define bfin_read_DMA1_4_IRQ_STATUS() bfin_read16(DMA1_4_IRQ_STATUS)
+#define bfin_write_DMA1_4_IRQ_STATUS(val) bfin_write16(DMA1_4_IRQ_STATUS,val)
+#define bfin_read_DMA1_4_PERIPHERAL_MAP() bfin_read16(DMA1_4_PERIPHERAL_MAP)
+#define bfin_write_DMA1_4_PERIPHERAL_MAP(val) bfin_write16(DMA1_4_PERIPHERAL_MAP,val)
+#define bfin_read_DMA1_5_CONFIG() bfin_read16(DMA1_5_CONFIG)
+#define bfin_write_DMA1_5_CONFIG(val) bfin_write16(DMA1_5_CONFIG,val)
+#define bfin_read_DMA1_5_NEXT_DESC_PTR() bfin_read32(DMA1_5_NEXT_DESC_PTR)
+#define bfin_write_DMA1_5_NEXT_DESC_PTR(val) bfin_write32(DMA1_5_NEXT_DESC_PTR,val)
+#define bfin_read_DMA1_5_START_ADDR() bfin_read32(DMA1_5_START_ADDR)
+#define bfin_write_DMA1_5_START_ADDR(val) bfin_write32(DMA1_5_START_ADDR,val)
+#define bfin_read_DMA1_5_X_COUNT() bfin_read16(DMA1_5_X_COUNT)
+#define bfin_write_DMA1_5_X_COUNT(val) bfin_write16(DMA1_5_X_COUNT,val)
+#define bfin_read_DMA1_5_Y_COUNT() bfin_read16(DMA1_5_Y_COUNT)
+#define bfin_write_DMA1_5_Y_COUNT(val) bfin_write16(DMA1_5_Y_COUNT,val)
+#define bfin_read_DMA1_5_X_MODIFY() bfin_read16(DMA1_5_X_MODIFY)
+#define bfin_write_DMA1_5_X_MODIFY(val) bfin_write16(DMA1_5_X_MODIFY,val)
+#define bfin_read_DMA1_5_Y_MODIFY() bfin_read16(DMA1_5_Y_MODIFY)
+#define bfin_write_DMA1_5_Y_MODIFY(val) bfin_write16(DMA1_5_Y_MODIFY,val)
+#define bfin_read_DMA1_5_CURR_DESC_PTR() bfin_read32(DMA1_5_CURR_DESC_PTR)
+#define bfin_write_DMA1_5_CURR_DESC_PTR(val) bfin_write32(DMA1_5_CURR_DESC_PTR,val)
+#define bfin_read_DMA1_5_CURR_ADDR() bfin_read32(DMA1_5_CURR_ADDR)
+#define bfin_write_DMA1_5_CURR_ADDR(val) bfin_write32(DMA1_5_CURR_ADDR,val)
+#define bfin_read_DMA1_5_CURR_X_COUNT() bfin_read16(DMA1_5_CURR_X_COUNT)
+#define bfin_write_DMA1_5_CURR_X_COUNT(val) bfin_write16(DMA1_5_CURR_X_COUNT,val)
+#define bfin_read_DMA1_5_CURR_Y_COUNT() bfin_read16(DMA1_5_CURR_Y_COUNT)
+#define bfin_write_DMA1_5_CURR_Y_COUNT(val) bfin_write16(DMA1_5_CURR_Y_COUNT,val)
+#define bfin_read_DMA1_5_IRQ_STATUS() bfin_read16(DMA1_5_IRQ_STATUS)
+#define bfin_write_DMA1_5_IRQ_STATUS(val) bfin_write16(DMA1_5_IRQ_STATUS,val)
+#define bfin_read_DMA1_5_PERIPHERAL_MAP() bfin_read16(DMA1_5_PERIPHERAL_MAP)
+#define bfin_write_DMA1_5_PERIPHERAL_MAP(val) bfin_write16(DMA1_5_PERIPHERAL_MAP,val)
+#define bfin_read_DMA1_6_CONFIG() bfin_read16(DMA1_6_CONFIG)
+#define bfin_write_DMA1_6_CONFIG(val) bfin_write16(DMA1_6_CONFIG,val)
+#define bfin_read_DMA1_6_NEXT_DESC_PTR() bfin_read32(DMA1_6_NEXT_DESC_PTR)
+#define bfin_write_DMA1_6_NEXT_DESC_PTR(val) bfin_write32(DMA1_6_NEXT_DESC_PTR,val)
+#define bfin_read_DMA1_6_START_ADDR() bfin_read32(DMA1_6_START_ADDR)
+#define bfin_write_DMA1_6_START_ADDR(val) bfin_write32(DMA1_6_START_ADDR,val)
+#define bfin_read_DMA1_6_X_COUNT() bfin_read16(DMA1_6_X_COUNT)
+#define bfin_write_DMA1_6_X_COUNT(val) bfin_write16(DMA1_6_X_COUNT,val)
+#define bfin_read_DMA1_6_Y_COUNT() bfin_read16(DMA1_6_Y_COUNT)
+#define bfin_write_DMA1_6_Y_COUNT(val) bfin_write16(DMA1_6_Y_COUNT,val)
+#define bfin_read_DMA1_6_X_MODIFY() bfin_read16(DMA1_6_X_MODIFY)
+#define bfin_write_DMA1_6_X_MODIFY(val) bfin_write16(DMA1_6_X_MODIFY,val)
+#define bfin_read_DMA1_6_Y_MODIFY() bfin_read16(DMA1_6_Y_MODIFY)
+#define bfin_write_DMA1_6_Y_MODIFY(val) bfin_write16(DMA1_6_Y_MODIFY,val)
+#define bfin_read_DMA1_6_CURR_DESC_PTR() bfin_read32(DMA1_6_CURR_DESC_PTR)
+#define bfin_write_DMA1_6_CURR_DESC_PTR(val) bfin_write32(DMA1_6_CURR_DESC_PTR,val)
+#define bfin_read_DMA1_6_CURR_ADDR() bfin_read32(DMA1_6_CURR_ADDR)
+#define bfin_write_DMA1_6_CURR_ADDR(val) bfin_write32(DMA1_6_CURR_ADDR,val)
+#define bfin_read_DMA1_6_CURR_X_COUNT() bfin_read16(DMA1_6_CURR_X_COUNT)
+#define bfin_write_DMA1_6_CURR_X_COUNT(val) bfin_write16(DMA1_6_CURR_X_COUNT,val)
+#define bfin_read_DMA1_6_CURR_Y_COUNT() bfin_read16(DMA1_6_CURR_Y_COUNT)
+#define bfin_write_DMA1_6_CURR_Y_COUNT(val) bfin_write16(DMA1_6_CURR_Y_COUNT,val)
+#define bfin_read_DMA1_6_IRQ_STATUS() bfin_read16(DMA1_6_IRQ_STATUS)
+#define bfin_write_DMA1_6_IRQ_STATUS(val) bfin_write16(DMA1_6_IRQ_STATUS,val)
+#define bfin_read_DMA1_6_PERIPHERAL_MAP() bfin_read16(DMA1_6_PERIPHERAL_MAP)
+#define bfin_write_DMA1_6_PERIPHERAL_MAP(val) bfin_write16(DMA1_6_PERIPHERAL_MAP,val)
+#define bfin_read_DMA1_7_CONFIG() bfin_read16(DMA1_7_CONFIG)
+#define bfin_write_DMA1_7_CONFIG(val) bfin_write16(DMA1_7_CONFIG,val)
+#define bfin_read_DMA1_7_NEXT_DESC_PTR() bfin_read32(DMA1_7_NEXT_DESC_PTR)
+#define bfin_write_DMA1_7_NEXT_DESC_PTR(val) bfin_write32(DMA1_7_NEXT_DESC_PTR,val)
+#define bfin_read_DMA1_7_START_ADDR() bfin_read32(DMA1_7_START_ADDR)
+#define bfin_write_DMA1_7_START_ADDR(val) bfin_write32(DMA1_7_START_ADDR,val)
+#define bfin_read_DMA1_7_X_COUNT() bfin_read16(DMA1_7_X_COUNT)
+#define bfin_write_DMA1_7_X_COUNT(val) bfin_write16(DMA1_7_X_COUNT,val)
+#define bfin_read_DMA1_7_Y_COUNT() bfin_read16(DMA1_7_Y_COUNT)
+#define bfin_write_DMA1_7_Y_COUNT(val) bfin_write16(DMA1_7_Y_COUNT,val)
+#define bfin_read_DMA1_7_X_MODIFY() bfin_read16(DMA1_7_X_MODIFY)
+#define bfin_write_DMA1_7_X_MODIFY(val) bfin_write16(DMA1_7_X_MODIFY,val)
+#define bfin_read_DMA1_7_Y_MODIFY() bfin_read16(DMA1_7_Y_MODIFY)
+#define bfin_write_DMA1_7_Y_MODIFY(val) bfin_write16(DMA1_7_Y_MODIFY,val)
+#define bfin_read_DMA1_7_CURR_DESC_PTR() bfin_read32(DMA1_7_CURR_DESC_PTR)
+#define bfin_write_DMA1_7_CURR_DESC_PTR(val) bfin_write32(DMA1_7_CURR_DESC_PTR,val)
+#define bfin_read_DMA1_7_CURR_ADDR() bfin_read32(DMA1_7_CURR_ADDR)
+#define bfin_write_DMA1_7_CURR_ADDR(val) bfin_write32(DMA1_7_CURR_ADDR,val)
+#define bfin_read_DMA1_7_CURR_X_COUNT() bfin_read16(DMA1_7_CURR_X_COUNT)
+#define bfin_write_DMA1_7_CURR_X_COUNT(val) bfin_write16(DMA1_7_CURR_X_COUNT,val)
+#define bfin_read_DMA1_7_CURR_Y_COUNT() bfin_read16(DMA1_7_CURR_Y_COUNT)
+#define bfin_write_DMA1_7_CURR_Y_COUNT(val) bfin_write16(DMA1_7_CURR_Y_COUNT,val)
+#define bfin_read_DMA1_7_IRQ_STATUS() bfin_read16(DMA1_7_IRQ_STATUS)
+#define bfin_write_DMA1_7_IRQ_STATUS(val) bfin_write16(DMA1_7_IRQ_STATUS,val)
+#define bfin_read_DMA1_7_PERIPHERAL_MAP() bfin_read16(DMA1_7_PERIPHERAL_MAP)
+#define bfin_write_DMA1_7_PERIPHERAL_MAP(val) bfin_write16(DMA1_7_PERIPHERAL_MAP,val)
+#define bfin_read_DMA1_8_CONFIG() bfin_read16(DMA1_8_CONFIG)
+#define bfin_write_DMA1_8_CONFIG(val) bfin_write16(DMA1_8_CONFIG,val)
+#define bfin_read_DMA1_8_NEXT_DESC_PTR() bfin_read32(DMA1_8_NEXT_DESC_PTR)
+#define bfin_write_DMA1_8_NEXT_DESC_PTR(val) bfin_write32(DMA1_8_NEXT_DESC_PTR,val)
+#define bfin_read_DMA1_8_START_ADDR() bfin_read32(DMA1_8_START_ADDR)
+#define bfin_write_DMA1_8_START_ADDR(val) bfin_write32(DMA1_8_START_ADDR,val)
+#define bfin_read_DMA1_8_X_COUNT() bfin_read16(DMA1_8_X_COUNT)
+#define bfin_write_DMA1_8_X_COUNT(val) bfin_write16(DMA1_8_X_COUNT,val)
+#define bfin_read_DMA1_8_Y_COUNT() bfin_read16(DMA1_8_Y_COUNT)
+#define bfin_write_DMA1_8_Y_COUNT(val) bfin_write16(DMA1_8_Y_COUNT,val)
+#define bfin_read_DMA1_8_X_MODIFY() bfin_read16(DMA1_8_X_MODIFY)
+#define bfin_write_DMA1_8_X_MODIFY(val) bfin_write16(DMA1_8_X_MODIFY,val)
+#define bfin_read_DMA1_8_Y_MODIFY() bfin_read16(DMA1_8_Y_MODIFY)
+#define bfin_write_DMA1_8_Y_MODIFY(val) bfin_write16(DMA1_8_Y_MODIFY,val)
+#define bfin_read_DMA1_8_CURR_DESC_PTR() bfin_read32(DMA1_8_CURR_DESC_PTR)
+#define bfin_write_DMA1_8_CURR_DESC_PTR(val) bfin_write32(DMA1_8_CURR_DESC_PTR,val)
+#define bfin_read_DMA1_8_CURR_ADDR() bfin_read32(DMA1_8_CURR_ADDR)
+#define bfin_write_DMA1_8_CURR_ADDR(val) bfin_write32(DMA1_8_CURR_ADDR,val)
+#define bfin_read_DMA1_8_CURR_X_COUNT() bfin_read16(DMA1_8_CURR_X_COUNT)
+#define bfin_write_DMA1_8_CURR_X_COUNT(val) bfin_write16(DMA1_8_CURR_X_COUNT,val)
+#define bfin_read_DMA1_8_CURR_Y_COUNT() bfin_read16(DMA1_8_CURR_Y_COUNT)
+#define bfin_write_DMA1_8_CURR_Y_COUNT(val) bfin_write16(DMA1_8_CURR_Y_COUNT,val)
+#define bfin_read_DMA1_8_IRQ_STATUS() bfin_read16(DMA1_8_IRQ_STATUS)
+#define bfin_write_DMA1_8_IRQ_STATUS(val) bfin_write16(DMA1_8_IRQ_STATUS,val)
+#define bfin_read_DMA1_8_PERIPHERAL_MAP() bfin_read16(DMA1_8_PERIPHERAL_MAP)
+#define bfin_write_DMA1_8_PERIPHERAL_MAP(val) bfin_write16(DMA1_8_PERIPHERAL_MAP,val)
+#define bfin_read_DMA1_9_CONFIG() bfin_read16(DMA1_9_CONFIG)
+#define bfin_write_DMA1_9_CONFIG(val) bfin_write16(DMA1_9_CONFIG,val)
+#define bfin_read_DMA1_9_NEXT_DESC_PTR() bfin_read32(DMA1_9_NEXT_DESC_PTR)
+#define bfin_write_DMA1_9_NEXT_DESC_PTR(val) bfin_write32(DMA1_9_NEXT_DESC_PTR,val)
+#define bfin_read_DMA1_9_START_ADDR() bfin_read32(DMA1_9_START_ADDR)
+#define bfin_write_DMA1_9_START_ADDR(val) bfin_write32(DMA1_9_START_ADDR,val)
+#define bfin_read_DMA1_9_X_COUNT() bfin_read16(DMA1_9_X_COUNT)
+#define bfin_write_DMA1_9_X_COUNT(val) bfin_write16(DMA1_9_X_COUNT,val)
+#define bfin_read_DMA1_9_Y_COUNT() bfin_read16(DMA1_9_Y_COUNT)
+#define bfin_write_DMA1_9_Y_COUNT(val) bfin_write16(DMA1_9_Y_COUNT,val)
+#define bfin_read_DMA1_9_X_MODIFY() bfin_read16(DMA1_9_X_MODIFY)
+#define bfin_write_DMA1_9_X_MODIFY(val) bfin_write16(DMA1_9_X_MODIFY,val)
+#define bfin_read_DMA1_9_Y_MODIFY() bfin_read16(DMA1_9_Y_MODIFY)
+#define bfin_write_DMA1_9_Y_MODIFY(val) bfin_write16(DMA1_9_Y_MODIFY,val)
+#define bfin_read_DMA1_9_CURR_DESC_PTR() bfin_read32(DMA1_9_CURR_DESC_PTR)
+#define bfin_write_DMA1_9_CURR_DESC_PTR(val) bfin_write32(DMA1_9_CURR_DESC_PTR,val)
+#define bfin_read_DMA1_9_CURR_ADDR() bfin_read32(DMA1_9_CURR_ADDR)
+#define bfin_write_DMA1_9_CURR_ADDR(val) bfin_write32(DMA1_9_CURR_ADDR,val)
+#define bfin_read_DMA1_9_CURR_X_COUNT() bfin_read16(DMA1_9_CURR_X_COUNT)
+#define bfin_write_DMA1_9_CURR_X_COUNT(val) bfin_write16(DMA1_9_CURR_X_COUNT,val)
+#define bfin_read_DMA1_9_CURR_Y_COUNT() bfin_read16(DMA1_9_CURR_Y_COUNT)
+#define bfin_write_DMA1_9_CURR_Y_COUNT(val) bfin_write16(DMA1_9_CURR_Y_COUNT,val)
+#define bfin_read_DMA1_9_IRQ_STATUS() bfin_read16(DMA1_9_IRQ_STATUS)
+#define bfin_write_DMA1_9_IRQ_STATUS(val) bfin_write16(DMA1_9_IRQ_STATUS,val)
+#define bfin_read_DMA1_9_PERIPHERAL_MAP() bfin_read16(DMA1_9_PERIPHERAL_MAP)
+#define bfin_write_DMA1_9_PERIPHERAL_MAP(val) bfin_write16(DMA1_9_PERIPHERAL_MAP,val)
+#define bfin_read_DMA1_10_CONFIG() bfin_read16(DMA1_10_CONFIG)
+#define bfin_write_DMA1_10_CONFIG(val) bfin_write16(DMA1_10_CONFIG,val)
+#define bfin_read_DMA1_10_NEXT_DESC_PTR() bfin_read32(DMA1_10_NEXT_DESC_PTR)
+#define bfin_write_DMA1_10_NEXT_DESC_PTR(val) bfin_write32(DMA1_10_NEXT_DESC_PTR,val)
+#define bfin_read_DMA1_10_START_ADDR() bfin_read32(DMA1_10_START_ADDR)
+#define bfin_write_DMA1_10_START_ADDR(val) bfin_write32(DMA1_10_START_ADDR,val)
+#define bfin_read_DMA1_10_X_COUNT() bfin_read16(DMA1_10_X_COUNT)
+#define bfin_write_DMA1_10_X_COUNT(val) bfin_write16(DMA1_10_X_COUNT,val)
+#define bfin_read_DMA1_10_Y_COUNT() bfin_read16(DMA1_10_Y_COUNT)
+#define bfin_write_DMA1_10_Y_COUNT(val) bfin_write16(DMA1_10_Y_COUNT,val)
+#define bfin_read_DMA1_10_X_MODIFY() bfin_read16(DMA1_10_X_MODIFY)
+#define bfin_write_DMA1_10_X_MODIFY(val) bfin_write16(DMA1_10_X_MODIFY,val)
+#define bfin_read_DMA1_10_Y_MODIFY() bfin_read16(DMA1_10_Y_MODIFY)
+#define bfin_write_DMA1_10_Y_MODIFY(val) bfin_write16(DMA1_10_Y_MODIFY,val)
+#define bfin_read_DMA1_10_CURR_DESC_PTR() bfin_read32(DMA1_10_CURR_DESC_PTR)
+#define bfin_write_DMA1_10_CURR_DESC_PTR(val) bfin_write32(DMA1_10_CURR_DESC_PTR,val)
+#define bfin_read_DMA1_10_CURR_ADDR() bfin_read32(DMA1_10_CURR_ADDR)
+#define bfin_write_DMA1_10_CURR_ADDR(val) bfin_write32(DMA1_10_CURR_ADDR,val)
+#define bfin_read_DMA1_10_CURR_X_COUNT() bfin_read16(DMA1_10_CURR_X_COUNT)
+#define bfin_write_DMA1_10_CURR_X_COUNT(val) bfin_write16(DMA1_10_CURR_X_COUNT,val)
+#define bfin_read_DMA1_10_CURR_Y_COUNT() bfin_read16(DMA1_10_CURR_Y_COUNT)
+#define bfin_write_DMA1_10_CURR_Y_COUNT(val) bfin_write16(DMA1_10_CURR_Y_COUNT,val)
+#define bfin_read_DMA1_10_IRQ_STATUS() bfin_read16(DMA1_10_IRQ_STATUS)
+#define bfin_write_DMA1_10_IRQ_STATUS(val) bfin_write16(DMA1_10_IRQ_STATUS,val)
+#define bfin_read_DMA1_10_PERIPHERAL_MAP() bfin_read16(DMA1_10_PERIPHERAL_MAP)
+#define bfin_write_DMA1_10_PERIPHERAL_MAP(val) bfin_write16(DMA1_10_PERIPHERAL_MAP,val)
+#define bfin_read_DMA1_11_CONFIG() bfin_read16(DMA1_11_CONFIG)
+#define bfin_write_DMA1_11_CONFIG(val) bfin_write16(DMA1_11_CONFIG,val)
+#define bfin_read_DMA1_11_NEXT_DESC_PTR() bfin_read32(DMA1_11_NEXT_DESC_PTR)
+#define bfin_write_DMA1_11_NEXT_DESC_PTR(val) bfin_write32(DMA1_11_NEXT_DESC_PTR,val)
+#define bfin_read_DMA1_11_START_ADDR() bfin_read32(DMA1_11_START_ADDR)
+#define bfin_write_DMA1_11_START_ADDR(val) bfin_write32(DMA1_11_START_ADDR,val)
+#define bfin_read_DMA1_11_X_COUNT() bfin_read16(DMA1_11_X_COUNT)
+#define bfin_write_DMA1_11_X_COUNT(val) bfin_write16(DMA1_11_X_COUNT,val)
+#define bfin_read_DMA1_11_Y_COUNT() bfin_read16(DMA1_11_Y_COUNT)
+#define bfin_write_DMA1_11_Y_COUNT(val) bfin_write16(DMA1_11_Y_COUNT,val)
+#define bfin_read_DMA1_11_X_MODIFY() bfin_read16(DMA1_11_X_MODIFY)
+#define bfin_write_DMA1_11_X_MODIFY(val) bfin_write16(DMA1_11_X_MODIFY,val)
+#define bfin_read_DMA1_11_Y_MODIFY() bfin_read16(DMA1_11_Y_MODIFY)
+#define bfin_write_DMA1_11_Y_MODIFY(val) bfin_write16(DMA1_11_Y_MODIFY,val)
+#define bfin_read_DMA1_11_CURR_DESC_PTR() bfin_read32(DMA1_11_CURR_DESC_PTR)
+#define bfin_write_DMA1_11_CURR_DESC_PTR(val) bfin_write32(DMA1_11_CURR_DESC_PTR,val)
+#define bfin_read_DMA1_11_CURR_ADDR() bfin_read32(DMA1_11_CURR_ADDR)
+#define bfin_write_DMA1_11_CURR_ADDR(val) bfin_write32(DMA1_11_CURR_ADDR,val)
+#define bfin_read_DMA1_11_CURR_X_COUNT() bfin_read16(DMA1_11_CURR_X_COUNT)
+#define bfin_write_DMA1_11_CURR_X_COUNT(val) bfin_write16(DMA1_11_CURR_X_COUNT,val)
+#define bfin_read_DMA1_11_CURR_Y_COUNT() bfin_read16(DMA1_11_CURR_Y_COUNT)
+#define bfin_write_DMA1_11_CURR_Y_COUNT(val) bfin_write16(DMA1_11_CURR_Y_COUNT,val)
+#define bfin_read_DMA1_11_IRQ_STATUS() bfin_read16(DMA1_11_IRQ_STATUS)
+#define bfin_write_DMA1_11_IRQ_STATUS(val) bfin_write16(DMA1_11_IRQ_STATUS,val)
+#define bfin_read_DMA1_11_PERIPHERAL_MAP() bfin_read16(DMA1_11_PERIPHERAL_MAP)
+#define bfin_write_DMA1_11_PERIPHERAL_MAP(val) bfin_write16(DMA1_11_PERIPHERAL_MAP,val)
+/* Memory DMA1 Controller registers (0xFFC0 1E80-0xFFC0 1FFF) */
+#define bfin_read_MDMA1_D0_CONFIG() bfin_read16(MDMA1_D0_CONFIG)
+#define bfin_write_MDMA1_D0_CONFIG(val) bfin_write16(MDMA1_D0_CONFIG,val)
+#define bfin_read_MDMA1_D0_NEXT_DESC_PTR() bfin_read32(MDMA1_D0_NEXT_DESC_PTR)
+#define bfin_write_MDMA1_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA1_D0_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA1_D0_START_ADDR() bfin_read32(MDMA1_D0_START_ADDR)
+#define bfin_write_MDMA1_D0_START_ADDR(val) bfin_write32(MDMA1_D0_START_ADDR,val)
+#define bfin_read_MDMA1_D0_X_COUNT() bfin_read16(MDMA1_D0_X_COUNT)
+#define bfin_write_MDMA1_D0_X_COUNT(val) bfin_write16(MDMA1_D0_X_COUNT,val)
+#define bfin_read_MDMA1_D0_Y_COUNT() bfin_read16(MDMA1_D0_Y_COUNT)
+#define bfin_write_MDMA1_D0_Y_COUNT(val) bfin_write16(MDMA1_D0_Y_COUNT,val)
+#define bfin_read_MDMA1_D0_X_MODIFY() bfin_read16(MDMA1_D0_X_MODIFY)
+#define bfin_write_MDMA1_D0_X_MODIFY(val) bfin_write16(MDMA1_D0_X_MODIFY,val)
+#define bfin_read_MDMA1_D0_Y_MODIFY() bfin_read16(MDMA1_D0_Y_MODIFY)
+#define bfin_write_MDMA1_D0_Y_MODIFY(val) bfin_write16(MDMA1_D0_Y_MODIFY,val)
+#define bfin_read_MDMA1_D0_CURR_DESC_PTR() bfin_read32(MDMA1_D0_CURR_DESC_PTR)
+#define bfin_write_MDMA1_D0_CURR_DESC_PTR(val) bfin_write32(MDMA1_D0_CURR_DESC_PTR,val)
+#define bfin_read_MDMA1_D0_CURR_ADDR() bfin_read32(MDMA1_D0_CURR_ADDR)
+#define bfin_write_MDMA1_D0_CURR_ADDR(val) bfin_write32(MDMA1_D0_CURR_ADDR,val)
+#define bfin_read_MDMA1_D0_CURR_X_COUNT() bfin_read16(MDMA1_D0_CURR_X_COUNT)
+#define bfin_write_MDMA1_D0_CURR_X_COUNT(val) bfin_write16(MDMA1_D0_CURR_X_COUNT,val)
+#define bfin_read_MDMA1_D0_CURR_Y_COUNT() bfin_read16(MDMA1_D0_CURR_Y_COUNT)
+#define bfin_write_MDMA1_D0_CURR_Y_COUNT(val) bfin_write16(MDMA1_D0_CURR_Y_COUNT,val)
+#define bfin_read_MDMA1_D0_IRQ_STATUS() bfin_read16(MDMA1_D0_IRQ_STATUS)
+#define bfin_write_MDMA1_D0_IRQ_STATUS(val) bfin_write16(MDMA1_D0_IRQ_STATUS,val)
+#define bfin_read_MDMA1_D0_PERIPHERAL_MAP() bfin_read16(MDMA1_D0_PERIPHERAL_MAP)
+#define bfin_write_MDMA1_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA1_D0_PERIPHERAL_MAP,val)
+#define bfin_read_MDMA1_S0_CONFIG() bfin_read16(MDMA1_S0_CONFIG)
+#define bfin_write_MDMA1_S0_CONFIG(val) bfin_write16(MDMA1_S0_CONFIG,val)
+#define bfin_read_MDMA1_S0_NEXT_DESC_PTR() bfin_read32(MDMA1_S0_NEXT_DESC_PTR)
+#define bfin_write_MDMA1_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA1_S0_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA1_S0_START_ADDR() bfin_read32(MDMA1_S0_START_ADDR)
+#define bfin_write_MDMA1_S0_START_ADDR(val) bfin_write32(MDMA1_S0_START_ADDR,val)
+#define bfin_read_MDMA1_S0_X_COUNT() bfin_read16(MDMA1_S0_X_COUNT)
+#define bfin_write_MDMA1_S0_X_COUNT(val) bfin_write16(MDMA1_S0_X_COUNT,val)
+#define bfin_read_MDMA1_S0_Y_COUNT() bfin_read16(MDMA1_S0_Y_COUNT)
+#define bfin_write_MDMA1_S0_Y_COUNT(val) bfin_write16(MDMA1_S0_Y_COUNT,val)
+#define bfin_read_MDMA1_S0_X_MODIFY() bfin_read16(MDMA1_S0_X_MODIFY)
+#define bfin_write_MDMA1_S0_X_MODIFY(val) bfin_write16(MDMA1_S0_X_MODIFY,val)
+#define bfin_read_MDMA1_S0_Y_MODIFY() bfin_read16(MDMA1_S0_Y_MODIFY)
+#define bfin_write_MDMA1_S0_Y_MODIFY(val) bfin_write16(MDMA1_S0_Y_MODIFY,val)
+#define bfin_read_MDMA1_S0_CURR_DESC_PTR() bfin_read32(MDMA1_S0_CURR_DESC_PTR)
+#define bfin_write_MDMA1_S0_CURR_DESC_PTR(val) bfin_write32(MDMA1_S0_CURR_DESC_PTR,val)
+#define bfin_read_MDMA1_S0_CURR_ADDR() bfin_read32(MDMA1_S0_CURR_ADDR)
+#define bfin_write_MDMA1_S0_CURR_ADDR(val) bfin_write32(MDMA1_S0_CURR_ADDR,val)
+#define bfin_read_MDMA1_S0_CURR_X_COUNT() bfin_read16(MDMA1_S0_CURR_X_COUNT)
+#define bfin_write_MDMA1_S0_CURR_X_COUNT(val) bfin_write16(MDMA1_S0_CURR_X_COUNT,val)
+#define bfin_read_MDMA1_S0_CURR_Y_COUNT() bfin_read16(MDMA1_S0_CURR_Y_COUNT)
+#define bfin_write_MDMA1_S0_CURR_Y_COUNT(val) bfin_write16(MDMA1_S0_CURR_Y_COUNT,val)
+#define bfin_read_MDMA1_S0_IRQ_STATUS() bfin_read16(MDMA1_S0_IRQ_STATUS)
+#define bfin_write_MDMA1_S0_IRQ_STATUS(val) bfin_write16(MDMA1_S0_IRQ_STATUS,val)
+#define bfin_read_MDMA1_S0_PERIPHERAL_MAP() bfin_read16(MDMA1_S0_PERIPHERAL_MAP)
+#define bfin_write_MDMA1_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA1_S0_PERIPHERAL_MAP,val)
+#define bfin_read_MDMA1_D1_CONFIG() bfin_read16(MDMA1_D1_CONFIG)
+#define bfin_write_MDMA1_D1_CONFIG(val) bfin_write16(MDMA1_D1_CONFIG,val)
+#define bfin_read_MDMA1_D1_NEXT_DESC_PTR() bfin_read32(MDMA1_D1_NEXT_DESC_PTR)
+#define bfin_write_MDMA1_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA1_D1_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA1_D1_START_ADDR() bfin_read32(MDMA1_D1_START_ADDR)
+#define bfin_write_MDMA1_D1_START_ADDR(val) bfin_write32(MDMA1_D1_START_ADDR,val)
+#define bfin_read_MDMA1_D1_X_COUNT() bfin_read16(MDMA1_D1_X_COUNT)
+#define bfin_write_MDMA1_D1_X_COUNT(val) bfin_write16(MDMA1_D1_X_COUNT,val)
+#define bfin_read_MDMA1_D1_Y_COUNT() bfin_read16(MDMA1_D1_Y_COUNT)
+#define bfin_write_MDMA1_D1_Y_COUNT(val) bfin_write16(MDMA1_D1_Y_COUNT,val)
+#define bfin_read_MDMA1_D1_X_MODIFY() bfin_read16(MDMA1_D1_X_MODIFY)
+#define bfin_write_MDMA1_D1_X_MODIFY(val) bfin_write16(MDMA1_D1_X_MODIFY,val)
+#define bfin_read_MDMA1_D1_Y_MODIFY() bfin_read16(MDMA1_D1_Y_MODIFY)
+#define bfin_write_MDMA1_D1_Y_MODIFY(val) bfin_write16(MDMA1_D1_Y_MODIFY,val)
+#define bfin_read_MDMA1_D1_CURR_DESC_PTR() bfin_read32(MDMA1_D1_CURR_DESC_PTR)
+#define bfin_write_MDMA1_D1_CURR_DESC_PTR(val) bfin_write32(MDMA1_D1_CURR_DESC_PTR,val)
+#define bfin_read_MDMA1_D1_CURR_ADDR() bfin_read32(MDMA1_D1_CURR_ADDR)
+#define bfin_write_MDMA1_D1_CURR_ADDR(val) bfin_write32(MDMA1_D1_CURR_ADDR,val)
+#define bfin_read_MDMA1_D1_CURR_X_COUNT() bfin_read16(MDMA1_D1_CURR_X_COUNT)
+#define bfin_write_MDMA1_D1_CURR_X_COUNT(val) bfin_write16(MDMA1_D1_CURR_X_COUNT,val)
+#define bfin_read_MDMA1_D1_CURR_Y_COUNT() bfin_read16(MDMA1_D1_CURR_Y_COUNT)
+#define bfin_write_MDMA1_D1_CURR_Y_COUNT(val) bfin_write16(MDMA1_D1_CURR_Y_COUNT,val)
+#define bfin_read_MDMA1_D1_IRQ_STATUS() bfin_read16(MDMA1_D1_IRQ_STATUS)
+#define bfin_write_MDMA1_D1_IRQ_STATUS(val) bfin_write16(MDMA1_D1_IRQ_STATUS,val)
+#define bfin_read_MDMA1_D1_PERIPHERAL_MAP() bfin_read16(MDMA1_D1_PERIPHERAL_MAP)
+#define bfin_write_MDMA1_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA1_D1_PERIPHERAL_MAP,val)
+#define bfin_read_MDMA1_S1_CONFIG() bfin_read16(MDMA1_S1_CONFIG)
+#define bfin_write_MDMA1_S1_CONFIG(val) bfin_write16(MDMA1_S1_CONFIG,val)
+#define bfin_read_MDMA1_S1_NEXT_DESC_PTR() bfin_read32(MDMA1_S1_NEXT_DESC_PTR)
+#define bfin_write_MDMA1_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA1_S1_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA1_S1_START_ADDR() bfin_read32(MDMA1_S1_START_ADDR)
+#define bfin_write_MDMA1_S1_START_ADDR(val) bfin_write32(MDMA1_S1_START_ADDR,val)
+#define bfin_read_MDMA1_S1_X_COUNT() bfin_read16(MDMA1_S1_X_COUNT)
+#define bfin_write_MDMA1_S1_X_COUNT(val) bfin_write16(MDMA1_S1_X_COUNT,val)
+#define bfin_read_MDMA1_S1_Y_COUNT() bfin_read16(MDMA1_S1_Y_COUNT)
+#define bfin_write_MDMA1_S1_Y_COUNT(val) bfin_write16(MDMA1_S1_Y_COUNT,val)
+#define bfin_read_MDMA1_S1_X_MODIFY() bfin_read16(MDMA1_S1_X_MODIFY)
+#define bfin_write_MDMA1_S1_X_MODIFY(val) bfin_write16(MDMA1_S1_X_MODIFY,val)
+#define bfin_read_MDMA1_S1_Y_MODIFY() bfin_read16(MDMA1_S1_Y_MODIFY)
+#define bfin_write_MDMA1_S1_Y_MODIFY(val) bfin_write16(MDMA1_S1_Y_MODIFY,val)
+#define bfin_read_MDMA1_S1_CURR_DESC_PTR() bfin_read32(MDMA1_S1_CURR_DESC_PTR)
+#define bfin_write_MDMA1_S1_CURR_DESC_PTR(val) bfin_write32(MDMA1_S1_CURR_DESC_PTR,val)
+#define bfin_read_MDMA1_S1_CURR_ADDR() bfin_read32(MDMA1_S1_CURR_ADDR)
+#define bfin_write_MDMA1_S1_CURR_ADDR(val) bfin_write32(MDMA1_S1_CURR_ADDR,val)
+#define bfin_read_MDMA1_S1_CURR_X_COUNT() bfin_read16(MDMA1_S1_CURR_X_COUNT)
+#define bfin_write_MDMA1_S1_CURR_X_COUNT(val) bfin_write16(MDMA1_S1_CURR_X_COUNT,val)
+#define bfin_read_MDMA1_S1_CURR_Y_COUNT() bfin_read16(MDMA1_S1_CURR_Y_COUNT)
+#define bfin_write_MDMA1_S1_CURR_Y_COUNT(val) bfin_write16(MDMA1_S1_CURR_Y_COUNT,val)
+#define bfin_read_MDMA1_S1_IRQ_STATUS() bfin_read16(MDMA1_S1_IRQ_STATUS)
+#define bfin_write_MDMA1_S1_IRQ_STATUS(val) bfin_write16(MDMA1_S1_IRQ_STATUS,val)
+#define bfin_read_MDMA1_S1_PERIPHERAL_MAP() bfin_read16(MDMA1_S1_PERIPHERAL_MAP)
+#define bfin_write_MDMA1_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA1_S1_PERIPHERAL_MAP,val)
+/* DMA2 Controller registers (0xFFC0 0C00-0xFFC0 0DFF) */
+#define bfin_read_DMA2_0_CONFIG() bfin_read16(DMA2_0_CONFIG)
+#define bfin_write_DMA2_0_CONFIG(val) bfin_write16(DMA2_0_CONFIG,val)
+#define bfin_read_DMA2_0_NEXT_DESC_PTR() bfin_read32(DMA2_0_NEXT_DESC_PTR)
+#define bfin_write_DMA2_0_NEXT_DESC_PTR(val) bfin_write32(DMA2_0_NEXT_DESC_PTR,val)
+#define bfin_read_DMA2_0_START_ADDR() bfin_read32(DMA2_0_START_ADDR)
+#define bfin_write_DMA2_0_START_ADDR(val) bfin_write32(DMA2_0_START_ADDR,val)
+#define bfin_read_DMA2_0_X_COUNT() bfin_read16(DMA2_0_X_COUNT)
+#define bfin_write_DMA2_0_X_COUNT(val) bfin_write16(DMA2_0_X_COUNT,val)
+#define bfin_read_DMA2_0_Y_COUNT() bfin_read16(DMA2_0_Y_COUNT)
+#define bfin_write_DMA2_0_Y_COUNT(val) bfin_write16(DMA2_0_Y_COUNT,val)
+#define bfin_read_DMA2_0_X_MODIFY() bfin_read16(DMA2_0_X_MODIFY)
+#define bfin_write_DMA2_0_X_MODIFY(val) bfin_write16(DMA2_0_X_MODIFY,val)
+#define bfin_read_DMA2_0_Y_MODIFY() bfin_read16(DMA2_0_Y_MODIFY)
+#define bfin_write_DMA2_0_Y_MODIFY(val) bfin_write16(DMA2_0_Y_MODIFY,val)
+#define bfin_read_DMA2_0_CURR_DESC_PTR() bfin_read32(DMA2_0_CURR_DESC_PTR)
+#define bfin_write_DMA2_0_CURR_DESC_PTR(val) bfin_write32(DMA2_0_CURR_DESC_PTR,val)
+#define bfin_read_DMA2_0_CURR_ADDR() bfin_read32(DMA2_0_CURR_ADDR)
+#define bfin_write_DMA2_0_CURR_ADDR(val) bfin_write32(DMA2_0_CURR_ADDR,val)
+#define bfin_read_DMA2_0_CURR_X_COUNT() bfin_read16(DMA2_0_CURR_X_COUNT)
+#define bfin_write_DMA2_0_CURR_X_COUNT(val) bfin_write16(DMA2_0_CURR_X_COUNT,val)
+#define bfin_read_DMA2_0_CURR_Y_COUNT() bfin_read16(DMA2_0_CURR_Y_COUNT)
+#define bfin_write_DMA2_0_CURR_Y_COUNT(val) bfin_write16(DMA2_0_CURR_Y_COUNT,val)
+#define bfin_read_DMA2_0_IRQ_STATUS() bfin_read16(DMA2_0_IRQ_STATUS)
+#define bfin_write_DMA2_0_IRQ_STATUS(val) bfin_write16(DMA2_0_IRQ_STATUS,val)
+#define bfin_read_DMA2_0_PERIPHERAL_MAP() bfin_read16(DMA2_0_PERIPHERAL_MAP)
+#define bfin_write_DMA2_0_PERIPHERAL_MAP(val) bfin_write16(DMA2_0_PERIPHERAL_MAP,val)
+#define bfin_read_DMA2_1_CONFIG() bfin_read16(DMA2_1_CONFIG)
+#define bfin_write_DMA2_1_CONFIG(val) bfin_write16(DMA2_1_CONFIG,val)
+#define bfin_read_DMA2_1_NEXT_DESC_PTR() bfin_read32(DMA2_1_NEXT_DESC_PTR)
+#define bfin_write_DMA2_1_NEXT_DESC_PTR(val) bfin_write32(DMA2_1_NEXT_DESC_PTR,val)
+#define bfin_read_DMA2_1_START_ADDR() bfin_read32(DMA2_1_START_ADDR)
+#define bfin_write_DMA2_1_START_ADDR(val) bfin_write32(DMA2_1_START_ADDR,val)
+#define bfin_read_DMA2_1_X_COUNT() bfin_read16(DMA2_1_X_COUNT)
+#define bfin_write_DMA2_1_X_COUNT(val) bfin_write16(DMA2_1_X_COUNT,val)
+#define bfin_read_DMA2_1_Y_COUNT() bfin_read16(DMA2_1_Y_COUNT)
+#define bfin_write_DMA2_1_Y_COUNT(val) bfin_write16(DMA2_1_Y_COUNT,val)
+#define bfin_read_DMA2_1_X_MODIFY() bfin_read16(DMA2_1_X_MODIFY)
+#define bfin_write_DMA2_1_X_MODIFY(val) bfin_write16(DMA2_1_X_MODIFY,val)
+#define bfin_read_DMA2_1_Y_MODIFY() bfin_read16(DMA2_1_Y_MODIFY)
+#define bfin_write_DMA2_1_Y_MODIFY(val) bfin_write16(DMA2_1_Y_MODIFY,val)
+#define bfin_read_DMA2_1_CURR_DESC_PTR() bfin_read32(DMA2_1_CURR_DESC_PTR)
+#define bfin_write_DMA2_1_CURR_DESC_PTR(val) bfin_write32(DMA2_1_CURR_DESC_PTR,val)
+#define bfin_read_DMA2_1_CURR_ADDR() bfin_read32(DMA2_1_CURR_ADDR)
+#define bfin_write_DMA2_1_CURR_ADDR(val) bfin_write32(DMA2_1_CURR_ADDR,val)
+#define bfin_read_DMA2_1_CURR_X_COUNT() bfin_read16(DMA2_1_CURR_X_COUNT)
+#define bfin_write_DMA2_1_CURR_X_COUNT(val) bfin_write16(DMA2_1_CURR_X_COUNT,val)
+#define bfin_read_DMA2_1_CURR_Y_COUNT() bfin_read16(DMA2_1_CURR_Y_COUNT)
+#define bfin_write_DMA2_1_CURR_Y_COUNT(val) bfin_write16(DMA2_1_CURR_Y_COUNT,val)
+#define bfin_read_DMA2_1_IRQ_STATUS() bfin_read16(DMA2_1_IRQ_STATUS)
+#define bfin_write_DMA2_1_IRQ_STATUS(val) bfin_write16(DMA2_1_IRQ_STATUS,val)
+#define bfin_read_DMA2_1_PERIPHERAL_MAP() bfin_read16(DMA2_1_PERIPHERAL_MAP)
+#define bfin_write_DMA2_1_PERIPHERAL_MAP(val) bfin_write16(DMA2_1_PERIPHERAL_MAP,val)
+#define bfin_read_DMA2_2_CONFIG() bfin_read16(DMA2_2_CONFIG)
+#define bfin_write_DMA2_2_CONFIG(val) bfin_write16(DMA2_2_CONFIG,val)
+#define bfin_read_DMA2_2_NEXT_DESC_PTR() bfin_read32(DMA2_2_NEXT_DESC_PTR)
+#define bfin_write_DMA2_2_NEXT_DESC_PTR(val) bfin_write32(DMA2_2_NEXT_DESC_PTR,val)
+#define bfin_read_DMA2_2_START_ADDR() bfin_read32(DMA2_2_START_ADDR)
+#define bfin_write_DMA2_2_START_ADDR(val) bfin_write32(DMA2_2_START_ADDR,val)
+#define bfin_read_DMA2_2_X_COUNT() bfin_read16(DMA2_2_X_COUNT)
+#define bfin_write_DMA2_2_X_COUNT(val) bfin_write16(DMA2_2_X_COUNT,val)
+#define bfin_read_DMA2_2_Y_COUNT() bfin_read16(DMA2_2_Y_COUNT)
+#define bfin_write_DMA2_2_Y_COUNT(val) bfin_write16(DMA2_2_Y_COUNT,val)
+#define bfin_read_DMA2_2_X_MODIFY() bfin_read16(DMA2_2_X_MODIFY)
+#define bfin_write_DMA2_2_X_MODIFY(val) bfin_write16(DMA2_2_X_MODIFY,val)
+#define bfin_read_DMA2_2_Y_MODIFY() bfin_read16(DMA2_2_Y_MODIFY)
+#define bfin_write_DMA2_2_Y_MODIFY(val) bfin_write16(DMA2_2_Y_MODIFY,val)
+#define bfin_read_DMA2_2_CURR_DESC_PTR() bfin_read32(DMA2_2_CURR_DESC_PTR)
+#define bfin_write_DMA2_2_CURR_DESC_PTR(val) bfin_write32(DMA2_2_CURR_DESC_PTR,val)
+#define bfin_read_DMA2_2_CURR_ADDR() bfin_read32(DMA2_2_CURR_ADDR)
+#define bfin_write_DMA2_2_CURR_ADDR(val) bfin_write32(DMA2_2_CURR_ADDR,val)
+#define bfin_read_DMA2_2_CURR_X_COUNT() bfin_read16(DMA2_2_CURR_X_COUNT)
+#define bfin_write_DMA2_2_CURR_X_COUNT(val) bfin_write16(DMA2_2_CURR_X_COUNT,val)
+#define bfin_read_DMA2_2_CURR_Y_COUNT() bfin_read16(DMA2_2_CURR_Y_COUNT)
+#define bfin_write_DMA2_2_CURR_Y_COUNT(val) bfin_write16(DMA2_2_CURR_Y_COUNT,val)
+#define bfin_read_DMA2_2_IRQ_STATUS() bfin_read16(DMA2_2_IRQ_STATUS)
+#define bfin_write_DMA2_2_IRQ_STATUS(val) bfin_write16(DMA2_2_IRQ_STATUS,val)
+#define bfin_read_DMA2_2_PERIPHERAL_MAP() bfin_read16(DMA2_2_PERIPHERAL_MAP)
+#define bfin_write_DMA2_2_PERIPHERAL_MAP(val) bfin_write16(DMA2_2_PERIPHERAL_MAP,val)
+#define bfin_read_DMA2_3_CONFIG() bfin_read16(DMA2_3_CONFIG)
+#define bfin_write_DMA2_3_CONFIG(val) bfin_write16(DMA2_3_CONFIG,val)
+#define bfin_read_DMA2_3_NEXT_DESC_PTR() bfin_read32(DMA2_3_NEXT_DESC_PTR)
+#define bfin_write_DMA2_3_NEXT_DESC_PTR(val) bfin_write32(DMA2_3_NEXT_DESC_PTR,val)
+#define bfin_read_DMA2_3_START_ADDR() bfin_read32(DMA2_3_START_ADDR)
+#define bfin_write_DMA2_3_START_ADDR(val) bfin_write32(DMA2_3_START_ADDR,val)
+#define bfin_read_DMA2_3_X_COUNT() bfin_read16(DMA2_3_X_COUNT)
+#define bfin_write_DMA2_3_X_COUNT(val) bfin_write16(DMA2_3_X_COUNT,val)
+#define bfin_read_DMA2_3_Y_COUNT() bfin_read16(DMA2_3_Y_COUNT)
+#define bfin_write_DMA2_3_Y_COUNT(val) bfin_write16(DMA2_3_Y_COUNT,val)
+#define bfin_read_DMA2_3_X_MODIFY() bfin_read16(DMA2_3_X_MODIFY)
+#define bfin_write_DMA2_3_X_MODIFY(val) bfin_write16(DMA2_3_X_MODIFY,val)
+#define bfin_read_DMA2_3_Y_MODIFY() bfin_read16(DMA2_3_Y_MODIFY)
+#define bfin_write_DMA2_3_Y_MODIFY(val) bfin_write16(DMA2_3_Y_MODIFY,val)
+#define bfin_read_DMA2_3_CURR_DESC_PTR() bfin_read32(DMA2_3_CURR_DESC_PTR)
+#define bfin_write_DMA2_3_CURR_DESC_PTR(val) bfin_write32(DMA2_3_CURR_DESC_PTR,val)
+#define bfin_read_DMA2_3_CURR_ADDR() bfin_read32(DMA2_3_CURR_ADDR)
+#define bfin_write_DMA2_3_CURR_ADDR(val) bfin_write32(DMA2_3_CURR_ADDR,val)
+#define bfin_read_DMA2_3_CURR_X_COUNT() bfin_read16(DMA2_3_CURR_X_COUNT)
+#define bfin_write_DMA2_3_CURR_X_COUNT(val) bfin_write16(DMA2_3_CURR_X_COUNT,val)
+#define bfin_read_DMA2_3_CURR_Y_COUNT() bfin_read16(DMA2_3_CURR_Y_COUNT)
+#define bfin_write_DMA2_3_CURR_Y_COUNT(val) bfin_write16(DMA2_3_CURR_Y_COUNT,val)
+#define bfin_read_DMA2_3_IRQ_STATUS() bfin_read16(DMA2_3_IRQ_STATUS)
+#define bfin_write_DMA2_3_IRQ_STATUS(val) bfin_write16(DMA2_3_IRQ_STATUS,val)
+#define bfin_read_DMA2_3_PERIPHERAL_MAP() bfin_read16(DMA2_3_PERIPHERAL_MAP)
+#define bfin_write_DMA2_3_PERIPHERAL_MAP(val) bfin_write16(DMA2_3_PERIPHERAL_MAP,val)
+#define bfin_read_DMA2_4_CONFIG() bfin_read16(DMA2_4_CONFIG)
+#define bfin_write_DMA2_4_CONFIG(val) bfin_write16(DMA2_4_CONFIG,val)
+#define bfin_read_DMA2_4_NEXT_DESC_PTR() bfin_read32(DMA2_4_NEXT_DESC_PTR)
+#define bfin_write_DMA2_4_NEXT_DESC_PTR(val) bfin_write32(DMA2_4_NEXT_DESC_PTR,val)
+#define bfin_read_DMA2_4_START_ADDR() bfin_read32(DMA2_4_START_ADDR)
+#define bfin_write_DMA2_4_START_ADDR(val) bfin_write32(DMA2_4_START_ADDR,val)
+#define bfin_read_DMA2_4_X_COUNT() bfin_read16(DMA2_4_X_COUNT)
+#define bfin_write_DMA2_4_X_COUNT(val) bfin_write16(DMA2_4_X_COUNT,val)
+#define bfin_read_DMA2_4_Y_COUNT() bfin_read16(DMA2_4_Y_COUNT)
+#define bfin_write_DMA2_4_Y_COUNT(val) bfin_write16(DMA2_4_Y_COUNT,val)
+#define bfin_read_DMA2_4_X_MODIFY() bfin_read16(DMA2_4_X_MODIFY)
+#define bfin_write_DMA2_4_X_MODIFY(val) bfin_write16(DMA2_4_X_MODIFY,val)
+#define bfin_read_DMA2_4_Y_MODIFY() bfin_read16(DMA2_4_Y_MODIFY)
+#define bfin_write_DMA2_4_Y_MODIFY(val) bfin_write16(DMA2_4_Y_MODIFY,val)
+#define bfin_read_DMA2_4_CURR_DESC_PTR() bfin_read32(DMA2_4_CURR_DESC_PTR)
+#define bfin_write_DMA2_4_CURR_DESC_PTR(val) bfin_write32(DMA2_4_CURR_DESC_PTR,val)
+#define bfin_read_DMA2_4_CURR_ADDR() bfin_read32(DMA2_4_CURR_ADDR)
+#define bfin_write_DMA2_4_CURR_ADDR(val) bfin_write32(DMA2_4_CURR_ADDR,val)
+#define bfin_read_DMA2_4_CURR_X_COUNT() bfin_read16(DMA2_4_CURR_X_COUNT)
+#define bfin_write_DMA2_4_CURR_X_COUNT(val) bfin_write16(DMA2_4_CURR_X_COUNT,val)
+#define bfin_read_DMA2_4_CURR_Y_COUNT() bfin_read16(DMA2_4_CURR_Y_COUNT)
+#define bfin_write_DMA2_4_CURR_Y_COUNT(val) bfin_write16(DMA2_4_CURR_Y_COUNT,val)
+#define bfin_read_DMA2_4_IRQ_STATUS() bfin_read16(DMA2_4_IRQ_STATUS)
+#define bfin_write_DMA2_4_IRQ_STATUS(val) bfin_write16(DMA2_4_IRQ_STATUS,val)
+#define bfin_read_DMA2_4_PERIPHERAL_MAP() bfin_read16(DMA2_4_PERIPHERAL_MAP)
+#define bfin_write_DMA2_4_PERIPHERAL_MAP(val) bfin_write16(DMA2_4_PERIPHERAL_MAP,val)
+#define bfin_read_DMA2_5_CONFIG() bfin_read16(DMA2_5_CONFIG)
+#define bfin_write_DMA2_5_CONFIG(val) bfin_write16(DMA2_5_CONFIG,val)
+#define bfin_read_DMA2_5_NEXT_DESC_PTR() bfin_read32(DMA2_5_NEXT_DESC_PTR)
+#define bfin_write_DMA2_5_NEXT_DESC_PTR(val) bfin_write32(DMA2_5_NEXT_DESC_PTR,val)
+#define bfin_read_DMA2_5_START_ADDR() bfin_read32(DMA2_5_START_ADDR)
+#define bfin_write_DMA2_5_START_ADDR(val) bfin_write32(DMA2_5_START_ADDR,val)
+#define bfin_read_DMA2_5_X_COUNT() bfin_read16(DMA2_5_X_COUNT)
+#define bfin_write_DMA2_5_X_COUNT(val) bfin_write16(DMA2_5_X_COUNT,val)
+#define bfin_read_DMA2_5_Y_COUNT() bfin_read16(DMA2_5_Y_COUNT)
+#define bfin_write_DMA2_5_Y_COUNT(val) bfin_write16(DMA2_5_Y_COUNT,val)
+#define bfin_read_DMA2_5_X_MODIFY() bfin_read16(DMA2_5_X_MODIFY)
+#define bfin_write_DMA2_5_X_MODIFY(val) bfin_write16(DMA2_5_X_MODIFY,val)
+#define bfin_read_DMA2_5_Y_MODIFY() bfin_read16(DMA2_5_Y_MODIFY)
+#define bfin_write_DMA2_5_Y_MODIFY(val) bfin_write16(DMA2_5_Y_MODIFY,val)
+#define bfin_read_DMA2_5_CURR_DESC_PTR() bfin_read32(DMA2_5_CURR_DESC_PTR)
+#define bfin_write_DMA2_5_CURR_DESC_PTR(val) bfin_write32(DMA2_5_CURR_DESC_PTR,val)
+#define bfin_read_DMA2_5_CURR_ADDR() bfin_read32(DMA2_5_CURR_ADDR)
+#define bfin_write_DMA2_5_CURR_ADDR(val) bfin_write32(DMA2_5_CURR_ADDR,val)
+#define bfin_read_DMA2_5_CURR_X_COUNT() bfin_read16(DMA2_5_CURR_X_COUNT)
+#define bfin_write_DMA2_5_CURR_X_COUNT(val) bfin_write16(DMA2_5_CURR_X_COUNT,val)
+#define bfin_read_DMA2_5_CURR_Y_COUNT() bfin_read16(DMA2_5_CURR_Y_COUNT)
+#define bfin_write_DMA2_5_CURR_Y_COUNT(val) bfin_write16(DMA2_5_CURR_Y_COUNT,val)
+#define bfin_read_DMA2_5_IRQ_STATUS() bfin_read16(DMA2_5_IRQ_STATUS)
+#define bfin_write_DMA2_5_IRQ_STATUS(val) bfin_write16(DMA2_5_IRQ_STATUS,val)
+#define bfin_read_DMA2_5_PERIPHERAL_MAP() bfin_read16(DMA2_5_PERIPHERAL_MAP)
+#define bfin_write_DMA2_5_PERIPHERAL_MAP(val) bfin_write16(DMA2_5_PERIPHERAL_MAP,val)
+#define bfin_read_DMA2_6_CONFIG() bfin_read16(DMA2_6_CONFIG)
+#define bfin_write_DMA2_6_CONFIG(val) bfin_write16(DMA2_6_CONFIG,val)
+#define bfin_read_DMA2_6_NEXT_DESC_PTR() bfin_read32(DMA2_6_NEXT_DESC_PTR)
+#define bfin_write_DMA2_6_NEXT_DESC_PTR(val) bfin_write32(DMA2_6_NEXT_DESC_PTR,val)
+#define bfin_read_DMA2_6_START_ADDR() bfin_read32(DMA2_6_START_ADDR)
+#define bfin_write_DMA2_6_START_ADDR(val) bfin_write32(DMA2_6_START_ADDR,val)
+#define bfin_read_DMA2_6_X_COUNT() bfin_read16(DMA2_6_X_COUNT)
+#define bfin_write_DMA2_6_X_COUNT(val) bfin_write16(DMA2_6_X_COUNT,val)
+#define bfin_read_DMA2_6_Y_COUNT() bfin_read16(DMA2_6_Y_COUNT)
+#define bfin_write_DMA2_6_Y_COUNT(val) bfin_write16(DMA2_6_Y_COUNT,val)
+#define bfin_read_DMA2_6_X_MODIFY() bfin_read16(DMA2_6_X_MODIFY)
+#define bfin_write_DMA2_6_X_MODIFY(val) bfin_write16(DMA2_6_X_MODIFY,val)
+#define bfin_read_DMA2_6_Y_MODIFY() bfin_read16(DMA2_6_Y_MODIFY)
+#define bfin_write_DMA2_6_Y_MODIFY(val) bfin_write16(DMA2_6_Y_MODIFY,val)
+#define bfin_read_DMA2_6_CURR_DESC_PTR() bfin_read32(DMA2_6_CURR_DESC_PTR)
+#define bfin_write_DMA2_6_CURR_DESC_PTR(val) bfin_write32(DMA2_6_CURR_DESC_PTR,val)
+#define bfin_read_DMA2_6_CURR_ADDR() bfin_read32(DMA2_6_CURR_ADDR)
+#define bfin_write_DMA2_6_CURR_ADDR(val) bfin_write32(DMA2_6_CURR_ADDR,val)
+#define bfin_read_DMA2_6_CURR_X_COUNT() bfin_read16(DMA2_6_CURR_X_COUNT)
+#define bfin_write_DMA2_6_CURR_X_COUNT(val) bfin_write16(DMA2_6_CURR_X_COUNT,val)
+#define bfin_read_DMA2_6_CURR_Y_COUNT() bfin_read16(DMA2_6_CURR_Y_COUNT)
+#define bfin_write_DMA2_6_CURR_Y_COUNT(val) bfin_write16(DMA2_6_CURR_Y_COUNT,val)
+#define bfin_read_DMA2_6_IRQ_STATUS() bfin_read16(DMA2_6_IRQ_STATUS)
+#define bfin_write_DMA2_6_IRQ_STATUS(val) bfin_write16(DMA2_6_IRQ_STATUS,val)
+#define bfin_read_DMA2_6_PERIPHERAL_MAP() bfin_read16(DMA2_6_PERIPHERAL_MAP)
+#define bfin_write_DMA2_6_PERIPHERAL_MAP(val) bfin_write16(DMA2_6_PERIPHERAL_MAP,val)
+#define bfin_read_DMA2_7_CONFIG() bfin_read16(DMA2_7_CONFIG)
+#define bfin_write_DMA2_7_CONFIG(val) bfin_write16(DMA2_7_CONFIG,val)
+#define bfin_read_DMA2_7_NEXT_DESC_PTR() bfin_read32(DMA2_7_NEXT_DESC_PTR)
+#define bfin_write_DMA2_7_NEXT_DESC_PTR(val) bfin_write32(DMA2_7_NEXT_DESC_PTR,val)
+#define bfin_read_DMA2_7_START_ADDR() bfin_read32(DMA2_7_START_ADDR)
+#define bfin_write_DMA2_7_START_ADDR(val) bfin_write32(DMA2_7_START_ADDR,val)
+#define bfin_read_DMA2_7_X_COUNT() bfin_read16(DMA2_7_X_COUNT)
+#define bfin_write_DMA2_7_X_COUNT(val) bfin_write16(DMA2_7_X_COUNT,val)
+#define bfin_read_DMA2_7_Y_COUNT() bfin_read16(DMA2_7_Y_COUNT)
+#define bfin_write_DMA2_7_Y_COUNT(val) bfin_write16(DMA2_7_Y_COUNT,val)
+#define bfin_read_DMA2_7_X_MODIFY() bfin_read16(DMA2_7_X_MODIFY)
+#define bfin_write_DMA2_7_X_MODIFY(val) bfin_write16(DMA2_7_X_MODIFY,val)
+#define bfin_read_DMA2_7_Y_MODIFY() bfin_read16(DMA2_7_Y_MODIFY)
+#define bfin_write_DMA2_7_Y_MODIFY(val) bfin_write16(DMA2_7_Y_MODIFY,val)
+#define bfin_read_DMA2_7_CURR_DESC_PTR() bfin_read32(DMA2_7_CURR_DESC_PTR)
+#define bfin_write_DMA2_7_CURR_DESC_PTR(val) bfin_write32(DMA2_7_CURR_DESC_PTR,val)
+#define bfin_read_DMA2_7_CURR_ADDR() bfin_read32(DMA2_7_CURR_ADDR)
+#define bfin_write_DMA2_7_CURR_ADDR(val) bfin_write32(DMA2_7_CURR_ADDR,val)
+#define bfin_read_DMA2_7_CURR_X_COUNT() bfin_read16(DMA2_7_CURR_X_COUNT)
+#define bfin_write_DMA2_7_CURR_X_COUNT(val) bfin_write16(DMA2_7_CURR_X_COUNT,val)
+#define bfin_read_DMA2_7_CURR_Y_COUNT() bfin_read16(DMA2_7_CURR_Y_COUNT)
+#define bfin_write_DMA2_7_CURR_Y_COUNT(val) bfin_write16(DMA2_7_CURR_Y_COUNT,val)
+#define bfin_read_DMA2_7_IRQ_STATUS() bfin_read16(DMA2_7_IRQ_STATUS)
+#define bfin_write_DMA2_7_IRQ_STATUS(val) bfin_write16(DMA2_7_IRQ_STATUS,val)
+#define bfin_read_DMA2_7_PERIPHERAL_MAP() bfin_read16(DMA2_7_PERIPHERAL_MAP)
+#define bfin_write_DMA2_7_PERIPHERAL_MAP(val) bfin_write16(DMA2_7_PERIPHERAL_MAP,val)
+#define bfin_read_DMA2_8_CONFIG() bfin_read16(DMA2_8_CONFIG)
+#define bfin_write_DMA2_8_CONFIG(val) bfin_write16(DMA2_8_CONFIG,val)
+#define bfin_read_DMA2_8_NEXT_DESC_PTR() bfin_read32(DMA2_8_NEXT_DESC_PTR)
+#define bfin_write_DMA2_8_NEXT_DESC_PTR(val) bfin_write32(DMA2_8_NEXT_DESC_PTR,val)
+#define bfin_read_DMA2_8_START_ADDR() bfin_read32(DMA2_8_START_ADDR)
+#define bfin_write_DMA2_8_START_ADDR(val) bfin_write32(DMA2_8_START_ADDR,val)
+#define bfin_read_DMA2_8_X_COUNT() bfin_read16(DMA2_8_X_COUNT)
+#define bfin_write_DMA2_8_X_COUNT(val) bfin_write16(DMA2_8_X_COUNT,val)
+#define bfin_read_DMA2_8_Y_COUNT() bfin_read16(DMA2_8_Y_COUNT)
+#define bfin_write_DMA2_8_Y_COUNT(val) bfin_write16(DMA2_8_Y_COUNT,val)
+#define bfin_read_DMA2_8_X_MODIFY() bfin_read16(DMA2_8_X_MODIFY)
+#define bfin_write_DMA2_8_X_MODIFY(val) bfin_write16(DMA2_8_X_MODIFY,val)
+#define bfin_read_DMA2_8_Y_MODIFY() bfin_read16(DMA2_8_Y_MODIFY)
+#define bfin_write_DMA2_8_Y_MODIFY(val) bfin_write16(DMA2_8_Y_MODIFY,val)
+#define bfin_read_DMA2_8_CURR_DESC_PTR() bfin_read32(DMA2_8_CURR_DESC_PTR)
+#define bfin_write_DMA2_8_CURR_DESC_PTR(val) bfin_write32(DMA2_8_CURR_DESC_PTR,val)
+#define bfin_read_DMA2_8_CURR_ADDR() bfin_read32(DMA2_8_CURR_ADDR)
+#define bfin_write_DMA2_8_CURR_ADDR(val) bfin_write32(DMA2_8_CURR_ADDR,val)
+#define bfin_read_DMA2_8_CURR_X_COUNT() bfin_read16(DMA2_8_CURR_X_COUNT)
+#define bfin_write_DMA2_8_CURR_X_COUNT(val) bfin_write16(DMA2_8_CURR_X_COUNT,val)
+#define bfin_read_DMA2_8_CURR_Y_COUNT() bfin_read16(DMA2_8_CURR_Y_COUNT)
+#define bfin_write_DMA2_8_CURR_Y_COUNT(val) bfin_write16(DMA2_8_CURR_Y_COUNT,val)
+#define bfin_read_DMA2_8_IRQ_STATUS() bfin_read16(DMA2_8_IRQ_STATUS)
+#define bfin_write_DMA2_8_IRQ_STATUS(val) bfin_write16(DMA2_8_IRQ_STATUS,val)
+#define bfin_read_DMA2_8_PERIPHERAL_MAP() bfin_read16(DMA2_8_PERIPHERAL_MAP)
+#define bfin_write_DMA2_8_PERIPHERAL_MAP(val) bfin_write16(DMA2_8_PERIPHERAL_MAP,val)
+#define bfin_read_DMA2_9_CONFIG() bfin_read16(DMA2_9_CONFIG)
+#define bfin_write_DMA2_9_CONFIG(val) bfin_write16(DMA2_9_CONFIG,val)
+#define bfin_read_DMA2_9_NEXT_DESC_PTR() bfin_read32(DMA2_9_NEXT_DESC_PTR)
+#define bfin_write_DMA2_9_NEXT_DESC_PTR(val) bfin_write32(DMA2_9_NEXT_DESC_PTR,val)
+#define bfin_read_DMA2_9_START_ADDR() bfin_read32(DMA2_9_START_ADDR)
+#define bfin_write_DMA2_9_START_ADDR(val) bfin_write32(DMA2_9_START_ADDR,val)
+#define bfin_read_DMA2_9_X_COUNT() bfin_read16(DMA2_9_X_COUNT)
+#define bfin_write_DMA2_9_X_COUNT(val) bfin_write16(DMA2_9_X_COUNT,val)
+#define bfin_read_DMA2_9_Y_COUNT() bfin_read16(DMA2_9_Y_COUNT)
+#define bfin_write_DMA2_9_Y_COUNT(val) bfin_write16(DMA2_9_Y_COUNT,val)
+#define bfin_read_DMA2_9_X_MODIFY() bfin_read16(DMA2_9_X_MODIFY)
+#define bfin_write_DMA2_9_X_MODIFY(val) bfin_write16(DMA2_9_X_MODIFY,val)
+#define bfin_read_DMA2_9_Y_MODIFY() bfin_read16(DMA2_9_Y_MODIFY)
+#define bfin_write_DMA2_9_Y_MODIFY(val) bfin_write16(DMA2_9_Y_MODIFY,val)
+#define bfin_read_DMA2_9_CURR_DESC_PTR() bfin_read32(DMA2_9_CURR_DESC_PTR)
+#define bfin_write_DMA2_9_CURR_DESC_PTR(val) bfin_write32(DMA2_9_CURR_DESC_PTR,val)
+#define bfin_read_DMA2_9_CURR_ADDR() bfin_read32(DMA2_9_CURR_ADDR)
+#define bfin_write_DMA2_9_CURR_ADDR(val) bfin_write32(DMA2_9_CURR_ADDR,val)
+#define bfin_read_DMA2_9_CURR_X_COUNT() bfin_read16(DMA2_9_CURR_X_COUNT)
+#define bfin_write_DMA2_9_CURR_X_COUNT(val) bfin_write16(DMA2_9_CURR_X_COUNT,val)
+#define bfin_read_DMA2_9_CURR_Y_COUNT() bfin_read16(DMA2_9_CURR_Y_COUNT)
+#define bfin_write_DMA2_9_CURR_Y_COUNT(val) bfin_write16(DMA2_9_CURR_Y_COUNT,val)
+#define bfin_read_DMA2_9_IRQ_STATUS() bfin_read16(DMA2_9_IRQ_STATUS)
+#define bfin_write_DMA2_9_IRQ_STATUS(val) bfin_write16(DMA2_9_IRQ_STATUS,val)
+#define bfin_read_DMA2_9_PERIPHERAL_MAP() bfin_read16(DMA2_9_PERIPHERAL_MAP)
+#define bfin_write_DMA2_9_PERIPHERAL_MAP(val) bfin_write16(DMA2_9_PERIPHERAL_MAP,val)
+#define bfin_read_DMA2_10_CONFIG() bfin_read16(DMA2_10_CONFIG)
+#define bfin_write_DMA2_10_CONFIG(val) bfin_write16(DMA2_10_CONFIG,val)
+#define bfin_read_DMA2_10_NEXT_DESC_PTR() bfin_read32(DMA2_10_NEXT_DESC_PTR)
+#define bfin_write_DMA2_10_NEXT_DESC_PTR(val) bfin_write32(DMA2_10_NEXT_DESC_PTR,val)
+#define bfin_read_DMA2_10_START_ADDR() bfin_read32(DMA2_10_START_ADDR)
+#define bfin_write_DMA2_10_START_ADDR(val) bfin_write32(DMA2_10_START_ADDR,val)
+#define bfin_read_DMA2_10_X_COUNT() bfin_read16(DMA2_10_X_COUNT)
+#define bfin_write_DMA2_10_X_COUNT(val) bfin_write16(DMA2_10_X_COUNT,val)
+#define bfin_read_DMA2_10_Y_COUNT() bfin_read16(DMA2_10_Y_COUNT)
+#define bfin_write_DMA2_10_Y_COUNT(val) bfin_write16(DMA2_10_Y_COUNT,val)
+#define bfin_read_DMA2_10_X_MODIFY() bfin_read16(DMA2_10_X_MODIFY)
+#define bfin_write_DMA2_10_X_MODIFY(val) bfin_write16(DMA2_10_X_MODIFY,val)
+#define bfin_read_DMA2_10_Y_MODIFY() bfin_read16(DMA2_10_Y_MODIFY)
+#define bfin_write_DMA2_10_Y_MODIFY(val) bfin_write16(DMA2_10_Y_MODIFY,val)
+#define bfin_read_DMA2_10_CURR_DESC_PTR() bfin_read32(DMA2_10_CURR_DESC_PTR)
+#define bfin_write_DMA2_10_CURR_DESC_PTR(val) bfin_write32(DMA2_10_CURR_DESC_PTR,val)
+#define bfin_read_DMA2_10_CURR_ADDR() bfin_read32(DMA2_10_CURR_ADDR)
+#define bfin_write_DMA2_10_CURR_ADDR(val) bfin_write32(DMA2_10_CURR_ADDR,val)
+#define bfin_read_DMA2_10_CURR_X_COUNT() bfin_read16(DMA2_10_CURR_X_COUNT)
+#define bfin_write_DMA2_10_CURR_X_COUNT(val) bfin_write16(DMA2_10_CURR_X_COUNT,val)
+#define bfin_read_DMA2_10_CURR_Y_COUNT() bfin_read16(DMA2_10_CURR_Y_COUNT)
+#define bfin_write_DMA2_10_CURR_Y_COUNT(val) bfin_write16(DMA2_10_CURR_Y_COUNT,val)
+#define bfin_read_DMA2_10_IRQ_STATUS() bfin_read16(DMA2_10_IRQ_STATUS)
+#define bfin_write_DMA2_10_IRQ_STATUS(val) bfin_write16(DMA2_10_IRQ_STATUS,val)
+#define bfin_read_DMA2_10_PERIPHERAL_MAP() bfin_read16(DMA2_10_PERIPHERAL_MAP)
+#define bfin_write_DMA2_10_PERIPHERAL_MAP(val) bfin_write16(DMA2_10_PERIPHERAL_MAP,val)
+#define bfin_read_DMA2_11_CONFIG() bfin_read16(DMA2_11_CONFIG)
+#define bfin_write_DMA2_11_CONFIG(val) bfin_write16(DMA2_11_CONFIG,val)
+#define bfin_read_DMA2_11_NEXT_DESC_PTR() bfin_read32(DMA2_11_NEXT_DESC_PTR)
+#define bfin_write_DMA2_11_NEXT_DESC_PTR(val) bfin_write32(DMA2_11_NEXT_DESC_PTR,val)
+#define bfin_read_DMA2_11_START_ADDR() bfin_read32(DMA2_11_START_ADDR)
+#define bfin_write_DMA2_11_START_ADDR(val) bfin_write32(DMA2_11_START_ADDR,val)
+#define bfin_read_DMA2_11_X_COUNT() bfin_read16(DMA2_11_X_COUNT)
+#define bfin_write_DMA2_11_X_COUNT(val) bfin_write16(DMA2_11_X_COUNT,val)
+#define bfin_read_DMA2_11_Y_COUNT() bfin_read16(DMA2_11_Y_COUNT)
+#define bfin_write_DMA2_11_Y_COUNT(val) bfin_write16(DMA2_11_Y_COUNT,val)
+#define bfin_read_DMA2_11_X_MODIFY() bfin_read16(DMA2_11_X_MODIFY)
+#define bfin_write_DMA2_11_X_MODIFY(val) bfin_write16(DMA2_11_X_MODIFY,val)
+#define bfin_read_DMA2_11_Y_MODIFY() bfin_read16(DMA2_11_Y_MODIFY)
+#define bfin_write_DMA2_11_Y_MODIFY(val) bfin_write16(DMA2_11_Y_MODIFY,val)
+#define bfin_read_DMA2_11_CURR_DESC_PTR() bfin_read32(DMA2_11_CURR_DESC_PTR)
+#define bfin_write_DMA2_11_CURR_DESC_PTR(val) bfin_write32(DMA2_11_CURR_DESC_PTR,val)
+#define bfin_read_DMA2_11_CURR_ADDR() bfin_read32(DMA2_11_CURR_ADDR)
+#define bfin_write_DMA2_11_CURR_ADDR(val) bfin_write32(DMA2_11_CURR_ADDR,val)
+#define bfin_read_DMA2_11_CURR_X_COUNT() bfin_read16(DMA2_11_CURR_X_COUNT)
+#define bfin_write_DMA2_11_CURR_X_COUNT(val) bfin_write16(DMA2_11_CURR_X_COUNT,val)
+#define bfin_read_DMA2_11_CURR_Y_COUNT() bfin_read16(DMA2_11_CURR_Y_COUNT)
+#define bfin_write_DMA2_11_CURR_Y_COUNT(val) bfin_write16(DMA2_11_CURR_Y_COUNT,val)
+#define bfin_read_DMA2_11_IRQ_STATUS() bfin_read16(DMA2_11_IRQ_STATUS)
+#define bfin_write_DMA2_11_IRQ_STATUS(val) bfin_write16(DMA2_11_IRQ_STATUS,val)
+#define bfin_read_DMA2_11_PERIPHERAL_MAP() bfin_read16(DMA2_11_PERIPHERAL_MAP)
+#define bfin_write_DMA2_11_PERIPHERAL_MAP(val) bfin_write16(DMA2_11_PERIPHERAL_MAP,val)
+/* Memory DMA2 Controller registers (0xFFC0 0E80-0xFFC0 0FFF) */
+#define bfin_read_MDMA2_D0_CONFIG() bfin_read16(MDMA2_D0_CONFIG)
+#define bfin_write_MDMA2_D0_CONFIG(val) bfin_write16(MDMA2_D0_CONFIG,val)
+#define bfin_read_MDMA2_D0_NEXT_DESC_PTR() bfin_read32(MDMA2_D0_NEXT_DESC_PTR)
+#define bfin_write_MDMA2_D0_NEXT_DESC_PTR(val) bfin_write32(MDMA2_D0_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA2_D0_START_ADDR() bfin_read32(MDMA2_D0_START_ADDR)
+#define bfin_write_MDMA2_D0_START_ADDR(val) bfin_write32(MDMA2_D0_START_ADDR,val)
+#define bfin_read_MDMA2_D0_X_COUNT() bfin_read16(MDMA2_D0_X_COUNT)
+#define bfin_write_MDMA2_D0_X_COUNT(val) bfin_write16(MDMA2_D0_X_COUNT,val)
+#define bfin_read_MDMA2_D0_Y_COUNT() bfin_read16(MDMA2_D0_Y_COUNT)
+#define bfin_write_MDMA2_D0_Y_COUNT(val) bfin_write16(MDMA2_D0_Y_COUNT,val)
+#define bfin_read_MDMA2_D0_X_MODIFY() bfin_read16(MDMA2_D0_X_MODIFY)
+#define bfin_write_MDMA2_D0_X_MODIFY(val) bfin_write16(MDMA2_D0_X_MODIFY,val)
+#define bfin_read_MDMA2_D0_Y_MODIFY() bfin_read16(MDMA2_D0_Y_MODIFY)
+#define bfin_write_MDMA2_D0_Y_MODIFY(val) bfin_write16(MDMA2_D0_Y_MODIFY,val)
+#define bfin_read_MDMA2_D0_CURR_DESC_PTR() bfin_read32(MDMA2_D0_CURR_DESC_PTR)
+#define bfin_write_MDMA2_D0_CURR_DESC_PTR(val) bfin_write32(MDMA2_D0_CURR_DESC_PTR,val)
+#define bfin_read_MDMA2_D0_CURR_ADDR() bfin_read32(MDMA2_D0_CURR_ADDR)
+#define bfin_write_MDMA2_D0_CURR_ADDR(val) bfin_write32(MDMA2_D0_CURR_ADDR,val)
+#define bfin_read_MDMA2_D0_CURR_X_COUNT() bfin_read16(MDMA2_D0_CURR_X_COUNT)
+#define bfin_write_MDMA2_D0_CURR_X_COUNT(val) bfin_write16(MDMA2_D0_CURR_X_COUNT,val)
+#define bfin_read_MDMA2_D0_CURR_Y_COUNT() bfin_read16(MDMA2_D0_CURR_Y_COUNT)
+#define bfin_write_MDMA2_D0_CURR_Y_COUNT(val) bfin_write16(MDMA2_D0_CURR_Y_COUNT,val)
+#define bfin_read_MDMA2_D0_IRQ_STATUS() bfin_read16(MDMA2_D0_IRQ_STATUS)
+#define bfin_write_MDMA2_D0_IRQ_STATUS(val) bfin_write16(MDMA2_D0_IRQ_STATUS,val)
+#define bfin_read_MDMA2_D0_PERIPHERAL_MAP() bfin_read16(MDMA2_D0_PERIPHERAL_MAP)
+#define bfin_write_MDMA2_D0_PERIPHERAL_MAP(val) bfin_write16(MDMA2_D0_PERIPHERAL_MAP,val)
+#define bfin_read_MDMA2_S0_CONFIG() bfin_read16(MDMA2_S0_CONFIG)
+#define bfin_write_MDMA2_S0_CONFIG(val) bfin_write16(MDMA2_S0_CONFIG,val)
+#define bfin_read_MDMA2_S0_NEXT_DESC_PTR() bfin_read32(MDMA2_S0_NEXT_DESC_PTR)
+#define bfin_write_MDMA2_S0_NEXT_DESC_PTR(val) bfin_write32(MDMA2_S0_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA2_S0_START_ADDR() bfin_read32(MDMA2_S0_START_ADDR)
+#define bfin_write_MDMA2_S0_START_ADDR(val) bfin_write32(MDMA2_S0_START_ADDR,val)
+#define bfin_read_MDMA2_S0_X_COUNT() bfin_read16(MDMA2_S0_X_COUNT)
+#define bfin_write_MDMA2_S0_X_COUNT(val) bfin_write16(MDMA2_S0_X_COUNT,val)
+#define bfin_read_MDMA2_S0_Y_COUNT() bfin_read16(MDMA2_S0_Y_COUNT)
+#define bfin_write_MDMA2_S0_Y_COUNT(val) bfin_write16(MDMA2_S0_Y_COUNT,val)
+#define bfin_read_MDMA2_S0_X_MODIFY() bfin_read16(MDMA2_S0_X_MODIFY)
+#define bfin_write_MDMA2_S0_X_MODIFY(val) bfin_write16(MDMA2_S0_X_MODIFY,val)
+#define bfin_read_MDMA2_S0_Y_MODIFY() bfin_read16(MDMA2_S0_Y_MODIFY)
+#define bfin_write_MDMA2_S0_Y_MODIFY(val) bfin_write16(MDMA2_S0_Y_MODIFY,val)
+#define bfin_read_MDMA2_S0_CURR_DESC_PTR() bfin_read32(MDMA2_S0_CURR_DESC_PTR)
+#define bfin_write_MDMA2_S0_CURR_DESC_PTR(val) bfin_write32(MDMA2_S0_CURR_DESC_PTR,val)
+#define bfin_read_MDMA2_S0_CURR_ADDR() bfin_read32(MDMA2_S0_CURR_ADDR)
+#define bfin_write_MDMA2_S0_CURR_ADDR(val) bfin_write32(MDMA2_S0_CURR_ADDR,val)
+#define bfin_read_MDMA2_S0_CURR_X_COUNT() bfin_read16(MDMA2_S0_CURR_X_COUNT)
+#define bfin_write_MDMA2_S0_CURR_X_COUNT(val) bfin_write16(MDMA2_S0_CURR_X_COUNT,val)
+#define bfin_read_MDMA2_S0_CURR_Y_COUNT() bfin_read16(MDMA2_S0_CURR_Y_COUNT)
+#define bfin_write_MDMA2_S0_CURR_Y_COUNT(val) bfin_write16(MDMA2_S0_CURR_Y_COUNT,val)
+#define bfin_read_MDMA2_S0_IRQ_STATUS() bfin_read16(MDMA2_S0_IRQ_STATUS)
+#define bfin_write_MDMA2_S0_IRQ_STATUS(val) bfin_write16(MDMA2_S0_IRQ_STATUS,val)
+#define bfin_read_MDMA2_S0_PERIPHERAL_MAP() bfin_read16(MDMA2_S0_PERIPHERAL_MAP)
+#define bfin_write_MDMA2_S0_PERIPHERAL_MAP(val) bfin_write16(MDMA2_S0_PERIPHERAL_MAP,val)
+#define bfin_read_MDMA2_D1_CONFIG() bfin_read16(MDMA2_D1_CONFIG)
+#define bfin_write_MDMA2_D1_CONFIG(val) bfin_write16(MDMA2_D1_CONFIG,val)
+#define bfin_read_MDMA2_D1_NEXT_DESC_PTR() bfin_read32(MDMA2_D1_NEXT_DESC_PTR)
+#define bfin_write_MDMA2_D1_NEXT_DESC_PTR(val) bfin_write32(MDMA2_D1_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA2_D1_START_ADDR() bfin_read32(MDMA2_D1_START_ADDR)
+#define bfin_write_MDMA2_D1_START_ADDR(val) bfin_write32(MDMA2_D1_START_ADDR,val)
+#define bfin_read_MDMA2_D1_X_COUNT() bfin_read16(MDMA2_D1_X_COUNT)
+#define bfin_write_MDMA2_D1_X_COUNT(val) bfin_write16(MDMA2_D1_X_COUNT,val)
+#define bfin_read_MDMA2_D1_Y_COUNT() bfin_read16(MDMA2_D1_Y_COUNT)
+#define bfin_write_MDMA2_D1_Y_COUNT(val) bfin_write16(MDMA2_D1_Y_COUNT,val)
+#define bfin_read_MDMA2_D1_X_MODIFY() bfin_read16(MDMA2_D1_X_MODIFY)
+#define bfin_write_MDMA2_D1_X_MODIFY(val) bfin_write16(MDMA2_D1_X_MODIFY,val)
+#define bfin_read_MDMA2_D1_Y_MODIFY() bfin_read16(MDMA2_D1_Y_MODIFY)
+#define bfin_write_MDMA2_D1_Y_MODIFY(val) bfin_write16(MDMA2_D1_Y_MODIFY,val)
+#define bfin_read_MDMA2_D1_CURR_DESC_PTR() bfin_read32(MDMA2_D1_CURR_DESC_PTR)
+#define bfin_write_MDMA2_D1_CURR_DESC_PTR(val) bfin_write32(MDMA2_D1_CURR_DESC_PTR,val)
+#define bfin_read_MDMA2_D1_CURR_ADDR() bfin_read32(MDMA2_D1_CURR_ADDR)
+#define bfin_write_MDMA2_D1_CURR_ADDR(val) bfin_write32(MDMA2_D1_CURR_ADDR,val)
+#define bfin_read_MDMA2_D1_CURR_X_COUNT() bfin_read16(MDMA2_D1_CURR_X_COUNT)
+#define bfin_write_MDMA2_D1_CURR_X_COUNT(val) bfin_write16(MDMA2_D1_CURR_X_COUNT,val)
+#define bfin_read_MDMA2_D1_CURR_Y_COUNT() bfin_read16(MDMA2_D1_CURR_Y_COUNT)
+#define bfin_write_MDMA2_D1_CURR_Y_COUNT(val) bfin_write16(MDMA2_D1_CURR_Y_COUNT,val)
+#define bfin_read_MDMA2_D1_IRQ_STATUS() bfin_read16(MDMA2_D1_IRQ_STATUS)
+#define bfin_write_MDMA2_D1_IRQ_STATUS(val) bfin_write16(MDMA2_D1_IRQ_STATUS,val)
+#define bfin_read_MDMA2_D1_PERIPHERAL_MAP() bfin_read16(MDMA2_D1_PERIPHERAL_MAP)
+#define bfin_write_MDMA2_D1_PERIPHERAL_MAP(val) bfin_write16(MDMA2_D1_PERIPHERAL_MAP,val)
+#define bfin_read_MDMA2_S1_CONFIG() bfin_read16(MDMA2_S1_CONFIG)
+#define bfin_write_MDMA2_S1_CONFIG(val) bfin_write16(MDMA2_S1_CONFIG,val)
+#define bfin_read_MDMA2_S1_NEXT_DESC_PTR() bfin_read32(MDMA2_S1_NEXT_DESC_PTR)
+#define bfin_write_MDMA2_S1_NEXT_DESC_PTR(val) bfin_write32(MDMA2_S1_NEXT_DESC_PTR,val)
+#define bfin_read_MDMA2_S1_START_ADDR() bfin_read32(MDMA2_S1_START_ADDR)
+#define bfin_write_MDMA2_S1_START_ADDR(val) bfin_write32(MDMA2_S1_START_ADDR,val)
+#define bfin_read_MDMA2_S1_X_COUNT() bfin_read16(MDMA2_S1_X_COUNT)
+#define bfin_write_MDMA2_S1_X_COUNT(val) bfin_write16(MDMA2_S1_X_COUNT,val)
+#define bfin_read_MDMA2_S1_Y_COUNT() bfin_read16(MDMA2_S1_Y_COUNT)
+#define bfin_write_MDMA2_S1_Y_COUNT(val) bfin_write16(MDMA2_S1_Y_COUNT,val)
+#define bfin_read_MDMA2_S1_X_MODIFY() bfin_read16(MDMA2_S1_X_MODIFY)
+#define bfin_write_MDMA2_S1_X_MODIFY(val) bfin_write16(MDMA2_S1_X_MODIFY,val)
+#define bfin_read_MDMA2_S1_Y_MODIFY() bfin_read16(MDMA2_S1_Y_MODIFY)
+#define bfin_write_MDMA2_S1_Y_MODIFY(val) bfin_write16(MDMA2_S1_Y_MODIFY,val)
+#define bfin_read_MDMA2_S1_CURR_DESC_PTR() bfin_read32(MDMA2_S1_CURR_DESC_PTR)
+#define bfin_write_MDMA2_S1_CURR_DESC_PTR(val) bfin_write32(MDMA2_S1_CURR_DESC_PTR,val)
+#define bfin_read_MDMA2_S1_CURR_ADDR() bfin_read32(MDMA2_S1_CURR_ADDR)
+#define bfin_write_MDMA2_S1_CURR_ADDR(val) bfin_write32(MDMA2_S1_CURR_ADDR,val)
+#define bfin_read_MDMA2_S1_CURR_X_COUNT() bfin_read16(MDMA2_S1_CURR_X_COUNT)
+#define bfin_write_MDMA2_S1_CURR_X_COUNT(val) bfin_write16(MDMA2_S1_CURR_X_COUNT,val)
+#define bfin_read_MDMA2_S1_CURR_Y_COUNT() bfin_read16(MDMA2_S1_CURR_Y_COUNT)
+#define bfin_write_MDMA2_S1_CURR_Y_COUNT(val) bfin_write16(MDMA2_S1_CURR_Y_COUNT,val)
+#define bfin_read_MDMA2_S1_IRQ_STATUS() bfin_read16(MDMA2_S1_IRQ_STATUS)
+#define bfin_write_MDMA2_S1_IRQ_STATUS(val) bfin_write16(MDMA2_S1_IRQ_STATUS,val)
+#define bfin_read_MDMA2_S1_PERIPHERAL_MAP() bfin_read16(MDMA2_S1_PERIPHERAL_MAP)
+#define bfin_write_MDMA2_S1_PERIPHERAL_MAP(val) bfin_write16(MDMA2_S1_PERIPHERAL_MAP,val)
+/* Internal Memory DMA Registers (0xFFC0_1800 - 0xFFC0_19FF) */
+#define bfin_read_IMDMA_D0_CONFIG() bfin_read16(IMDMA_D0_CONFIG)
+#define bfin_write_IMDMA_D0_CONFIG(val) bfin_write16(IMDMA_D0_CONFIG,val)
+#define bfin_read_IMDMA_D0_NEXT_DESC_PTR() bfin_read32(IMDMA_D0_NEXT_DESC_PTR)
+#define bfin_write_IMDMA_D0_NEXT_DESC_PTR(val) bfin_write32(IMDMA_D0_NEXT_DESC_PTR,val)
+#define bfin_read_IMDMA_D0_START_ADDR() bfin_read32(IMDMA_D0_START_ADDR)
+#define bfin_write_IMDMA_D0_START_ADDR(val) bfin_write32(IMDMA_D0_START_ADDR,val)
+#define bfin_read_IMDMA_D0_X_COUNT() bfin_read16(IMDMA_D0_X_COUNT)
+#define bfin_write_IMDMA_D0_X_COUNT(val) bfin_write16(IMDMA_D0_X_COUNT,val)
+#define bfin_read_IMDMA_D0_Y_COUNT() bfin_read16(IMDMA_D0_Y_COUNT)
+#define bfin_write_IMDMA_D0_Y_COUNT(val) bfin_write16(IMDMA_D0_Y_COUNT,val)
+#define bfin_read_IMDMA_D0_X_MODIFY() bfin_read16(IMDMA_D0_X_MODIFY)
+#define bfin_write_IMDMA_D0_X_MODIFY(val) bfin_write16(IMDMA_D0_X_MODIFY,val)
+#define bfin_read_IMDMA_D0_Y_MODIFY() bfin_read16(IMDMA_D0_Y_MODIFY)
+#define bfin_write_IMDMA_D0_Y_MODIFY(val) bfin_write16(IMDMA_D0_Y_MODIFY,val)
+#define bfin_read_IMDMA_D0_CURR_DESC_PTR() bfin_read32(IMDMA_D0_CURR_DESC_PTR)
+#define bfin_write_IMDMA_D0_CURR_DESC_PTR(val) bfin_write32(IMDMA_D0_CURR_DESC_PTR,val)
+#define bfin_read_IMDMA_D0_CURR_ADDR() bfin_read32(IMDMA_D0_CURR_ADDR)
+#define bfin_write_IMDMA_D0_CURR_ADDR(val) bfin_write32(IMDMA_D0_CURR_ADDR,val)
+#define bfin_read_IMDMA_D0_CURR_X_COUNT() bfin_read16(IMDMA_D0_CURR_X_COUNT)
+#define bfin_write_IMDMA_D0_CURR_X_COUNT(val) bfin_write16(IMDMA_D0_CURR_X_COUNT,val)
+#define bfin_read_IMDMA_D0_CURR_Y_COUNT() bfin_read16(IMDMA_D0_CURR_Y_COUNT)
+#define bfin_write_IMDMA_D0_CURR_Y_COUNT(val) bfin_write16(IMDMA_D0_CURR_Y_COUNT,val)
+#define bfin_read_IMDMA_D0_IRQ_STATUS() bfin_read16(IMDMA_D0_IRQ_STATUS)
+#define bfin_write_IMDMA_D0_IRQ_STATUS(val) bfin_write16(IMDMA_D0_IRQ_STATUS,val)
+#define bfin_read_IMDMA_S0_CONFIG() bfin_read16(IMDMA_S0_CONFIG)
+#define bfin_write_IMDMA_S0_CONFIG(val) bfin_write16(IMDMA_S0_CONFIG,val)
+#define bfin_read_IMDMA_S0_NEXT_DESC_PTR() bfin_read32(IMDMA_S0_NEXT_DESC_PTR)
+#define bfin_write_IMDMA_S0_NEXT_DESC_PTR(val) bfin_write32(IMDMA_S0_NEXT_DESC_PTR,val)
+#define bfin_read_IMDMA_S0_START_ADDR() bfin_read32(IMDMA_S0_START_ADDR)
+#define bfin_write_IMDMA_S0_START_ADDR(val) bfin_write32(IMDMA_S0_START_ADDR,val)
+#define bfin_read_IMDMA_S0_X_COUNT() bfin_read16(IMDMA_S0_X_COUNT)
+#define bfin_write_IMDMA_S0_X_COUNT(val) bfin_write16(IMDMA_S0_X_COUNT,val)
+#define bfin_read_IMDMA_S0_Y_COUNT() bfin_read16(IMDMA_S0_Y_COUNT)
+#define bfin_write_IMDMA_S0_Y_COUNT(val) bfin_write16(IMDMA_S0_Y_COUNT,val)
+#define bfin_read_IMDMA_S0_X_MODIFY() bfin_read16(IMDMA_S0_X_MODIFY)
+#define bfin_write_IMDMA_S0_X_MODIFY(val) bfin_write16(IMDMA_S0_X_MODIFY,val)
+#define bfin_read_IMDMA_S0_Y_MODIFY() bfin_read16(IMDMA_S0_Y_MODIFY)
+#define bfin_write_IMDMA_S0_Y_MODIFY(val) bfin_write16(IMDMA_S0_Y_MODIFY,val)
+#define bfin_read_IMDMA_S0_CURR_DESC_PTR() bfin_read32(IMDMA_S0_CURR_DESC_PTR)
+#define bfin_write_IMDMA_S0_CURR_DESC_PTR(val) bfin_write32(IMDMA_S0_CURR_DESC_PTR,val)
+#define bfin_read_IMDMA_S0_CURR_ADDR() bfin_read32(IMDMA_S0_CURR_ADDR)
+#define bfin_write_IMDMA_S0_CURR_ADDR(val) bfin_write32(IMDMA_S0_CURR_ADDR,val)
+#define bfin_read_IMDMA_S0_CURR_X_COUNT() bfin_read16(IMDMA_S0_CURR_X_COUNT)
+#define bfin_write_IMDMA_S0_CURR_X_COUNT(val) bfin_write16(IMDMA_S0_CURR_X_COUNT,val)
+#define bfin_read_IMDMA_S0_CURR_Y_COUNT() bfin_read16(IMDMA_S0_CURR_Y_COUNT)
+#define bfin_write_IMDMA_S0_CURR_Y_COUNT(val) bfin_write16(IMDMA_S0_CURR_Y_COUNT,val)
+#define bfin_read_IMDMA_S0_IRQ_STATUS() bfin_read16(IMDMA_S0_IRQ_STATUS)
+#define bfin_write_IMDMA_S0_IRQ_STATUS(val) bfin_write16(IMDMA_S0_IRQ_STATUS,val)
+#define bfin_read_IMDMA_D1_CONFIG() bfin_read16(IMDMA_D1_CONFIG)
+#define bfin_write_IMDMA_D1_CONFIG(val) bfin_write16(IMDMA_D1_CONFIG,val)
+#define bfin_read_IMDMA_D1_NEXT_DESC_PTR() bfin_read32(IMDMA_D1_NEXT_DESC_PTR)
+#define bfin_write_IMDMA_D1_NEXT_DESC_PTR(val) bfin_write32(IMDMA_D1_NEXT_DESC_PTR,val)
+#define bfin_read_IMDMA_D1_START_ADDR() bfin_read32(IMDMA_D1_START_ADDR)
+#define bfin_write_IMDMA_D1_START_ADDR(val) bfin_write32(IMDMA_D1_START_ADDR,val)
+#define bfin_read_IMDMA_D1_X_COUNT() bfin_read16(IMDMA_D1_X_COUNT)
+#define bfin_write_IMDMA_D1_X_COUNT(val) bfin_write16(IMDMA_D1_X_COUNT,val)
+#define bfin_read_IMDMA_D1_Y_COUNT() bfin_read16(IMDMA_D1_Y_COUNT)
+#define bfin_write_IMDMA_D1_Y_COUNT(val) bfin_write16(IMDMA_D1_Y_COUNT,val)
+#define bfin_read_IMDMA_D1_X_MODIFY() bfin_read16(IMDMA_D1_X_MODIFY)
+#define bfin_write_IMDMA_D1_X_MODIFY(val) bfin_write16(IMDMA_D1_X_MODIFY,val)
+#define bfin_read_IMDMA_D1_Y_MODIFY() bfin_read16(IMDMA_D1_Y_MODIFY)
+#define bfin_write_IMDMA_D1_Y_MODIFY(val) bfin_write16(IMDMA_D1_Y_MODIFY,val)
+#define bfin_read_IMDMA_D1_CURR_DESC_PTR() bfin_read32(IMDMA_D1_CURR_DESC_PTR)
+#define bfin_write_IMDMA_D1_CURR_DESC_PTR(val) bfin_write32(IMDMA_D1_CURR_DESC_PTR,val)
+#define bfin_read_IMDMA_D1_CURR_ADDR() bfin_read32(IMDMA_D1_CURR_ADDR)
+#define bfin_write_IMDMA_D1_CURR_ADDR(val) bfin_write32(IMDMA_D1_CURR_ADDR,val)
+#define bfin_read_IMDMA_D1_CURR_X_COUNT() bfin_read16(IMDMA_D1_CURR_X_COUNT)
+#define bfin_write_IMDMA_D1_CURR_X_COUNT(val) bfin_write16(IMDMA_D1_CURR_X_COUNT,val)
+#define bfin_read_IMDMA_D1_CURR_Y_COUNT() bfin_read16(IMDMA_D1_CURR_Y_COUNT)
+#define bfin_write_IMDMA_D1_CURR_Y_COUNT(val) bfin_write16(IMDMA_D1_CURR_Y_COUNT,val)
+#define bfin_read_IMDMA_D1_IRQ_STATUS() bfin_read16(IMDMA_D1_IRQ_STATUS)
+#define bfin_write_IMDMA_D1_IRQ_STATUS(val) bfin_write16(IMDMA_D1_IRQ_STATUS,val)
+#define bfin_read_IMDMA_S1_CONFIG() bfin_read16(IMDMA_S1_CONFIG)
+#define bfin_write_IMDMA_S1_CONFIG(val) bfin_write16(IMDMA_S1_CONFIG,val)
+#define bfin_read_IMDMA_S1_NEXT_DESC_PTR() bfin_read32(IMDMA_S1_NEXT_DESC_PTR)
+#define bfin_write_IMDMA_S1_NEXT_DESC_PTR(val) bfin_write32(IMDMA_S1_NEXT_DESC_PTR,val)
+#define bfin_read_IMDMA_S1_START_ADDR() bfin_read32(IMDMA_S1_START_ADDR)
+#define bfin_write_IMDMA_S1_START_ADDR(val) bfin_write32(IMDMA_S1_START_ADDR,val)
+#define bfin_read_IMDMA_S1_X_COUNT() bfin_read16(IMDMA_S1_X_COUNT)
+#define bfin_write_IMDMA_S1_X_COUNT(val) bfin_write16(IMDMA_S1_X_COUNT,val)
+#define bfin_read_IMDMA_S1_Y_COUNT() bfin_read16(IMDMA_S1_Y_COUNT)
+#define bfin_write_IMDMA_S1_Y_COUNT(val) bfin_write16(IMDMA_S1_Y_COUNT,val)
+#define bfin_read_IMDMA_S1_X_MODIFY() bfin_read16(IMDMA_S1_X_MODIFY)
+#define bfin_write_IMDMA_S1_X_MODIFY(val) bfin_write16(IMDMA_S1_X_MODIFY,val)
+#define bfin_read_IMDMA_S1_Y_MODIFY() bfin_read16(IMDMA_S1_Y_MODIFY)
+#define bfin_write_IMDMA_S1_Y_MODIFY(val) bfin_write16(IMDMA_S1_Y_MODIFY,val)
+#define bfin_read_IMDMA_S1_CURR_DESC_PTR() bfin_read32(IMDMA_S1_CURR_DESC_PTR)
+#define bfin_write_IMDMA_S1_CURR_DESC_PTR(val) bfin_write32(IMDMA_S1_CURR_DESC_PTR,val)
+#define bfin_read_IMDMA_S1_CURR_ADDR() bfin_read32(IMDMA_S1_CURR_ADDR)
+#define bfin_write_IMDMA_S1_CURR_ADDR(val) bfin_write32(IMDMA_S1_CURR_ADDR,val)
+#define bfin_read_IMDMA_S1_CURR_X_COUNT() bfin_read16(IMDMA_S1_CURR_X_COUNT)
+#define bfin_write_IMDMA_S1_CURR_X_COUNT(val) bfin_write16(IMDMA_S1_CURR_X_COUNT,val)
+#define bfin_read_IMDMA_S1_CURR_Y_COUNT() bfin_read16(IMDMA_S1_CURR_Y_COUNT)
+#define bfin_write_IMDMA_S1_CURR_Y_COUNT(val) bfin_write16(IMDMA_S1_CURR_Y_COUNT,val)
+#define bfin_read_IMDMA_S1_IRQ_STATUS() bfin_read16(IMDMA_S1_IRQ_STATUS)
+#define bfin_write_IMDMA_S1_IRQ_STATUS(val) bfin_write16(IMDMA_S1_IRQ_STATUS,val)
+
+#define bfin_read_MDMA_S0_CONFIG() bfin_read_MDMA1_S0_CONFIG()
+#define bfin_write_MDMA_S0_CONFIG(val) bfin_write_MDMA1_S0_CONFIG(val)
+#define bfin_read_MDMA_S0_IRQ_STATUS() bfin_read_MDMA1_S0_IRQ_STATUS()
+#define bfin_write_MDMA_S0_IRQ_STATUS(val) bfin_write_MDMA1_S0_IRQ_STATUS(val)
+#define bfin_read_MDMA_S0_X_MODIFY() bfin_read_MDMA1_S0_X_MODIFY()
+#define bfin_write_MDMA_S0_X_MODIFY(val) bfin_write_MDMA1_S0_X_MODIFY(val)
+#define bfin_read_MDMA_S0_Y_MODIFY() bfin_read_MDMA1_S0_Y_MODIFY()
+#define bfin_write_MDMA_S0_Y_MODIFY(val) bfin_write_MDMA1_S0_Y_MODIFY(val)
+#define bfin_read_MDMA_S0_X_COUNT() bfin_read_MDMA1_S0_X_COUNT()
+#define bfin_write_MDMA_S0_X_COUNT(val) bfin_write_MDMA1_S0_X_COUNT(val)
+#define bfin_read_MDMA_S0_Y_COUNT() bfin_read_MDMA1_S0_Y_COUNT()
+#define bfin_write_MDMA_S0_Y_COUNT(val) bfin_write_MDMA1_S0_Y_COUNT(val)
+#define bfin_read_MDMA_S0_START_ADDR() bfin_read_MDMA1_S0_START_ADDR()
+#define bfin_write_MDMA_S0_START_ADDR(val) bfin_write_MDMA1_S0_START_ADDR(val)
+#define bfin_read_MDMA_D0_CONFIG() bfin_read_MDMA1_D0_CONFIG()
+#define bfin_write_MDMA_D0_CONFIG(val) bfin_write_MDMA1_D0_CONFIG(val)
+#define bfin_read_MDMA_D0_IRQ_STATUS() bfin_read_MDMA1_D0_IRQ_STATUS()
+#define bfin_write_MDMA_D0_IRQ_STATUS(val) bfin_write_MDMA1_D0_IRQ_STATUS(val)
+#define bfin_read_MDMA_D0_X_MODIFY() bfin_read_MDMA1_D0_X_MODIFY()
+#define bfin_write_MDMA_D0_X_MODIFY(val) bfin_write_MDMA1_D0_X_MODIFY(val)
+#define bfin_read_MDMA_D0_Y_MODIFY() bfin_read_MDMA1_D0_Y_MODIFY()
+#define bfin_write_MDMA_D0_Y_MODIFY(val) bfin_write_MDMA1_D0_Y_MODIFY(val)
+#define bfin_read_MDMA_D0_X_COUNT() bfin_read_MDMA1_D0_X_COUNT()
+#define bfin_write_MDMA_D0_X_COUNT(val) bfin_write_MDMA1_D0_X_COUNT(val)
+#define bfin_read_MDMA_D0_Y_COUNT() bfin_read_MDMA1_D0_Y_COUNT()
+#define bfin_write_MDMA_D0_Y_COUNT(val) bfin_write_MDMA1_D0_Y_COUNT(val)
+#define bfin_read_MDMA_D0_START_ADDR() bfin_read_MDMA1_D0_START_ADDR()
+#define bfin_write_MDMA_D0_START_ADDR(val) bfin_write_MDMA1_D0_START_ADDR(val)
+
+#endif /* _CDEF_BF561_H */
diff --git a/include/asm-blackfin/mach-bf561/defBF561.h b/include/asm-blackfin/mach-bf561/defBF561.h
new file mode 100644
index 0000000..a6de4c6
--- /dev/null
+++ b/include/asm-blackfin/mach-bf561/defBF561.h
@@ -0,0 +1,1717 @@
+
+/*
+ * File: include/asm-blackfin/mach-bf561/defBF561.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ * SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
+ * Rev:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _DEF_BF561_H
+#define _DEF_BF561_H
+/*
+#if !defined(__ADSPBF561__)
+#warning defBF561.h should only be included for BF561 chip.
+#endif
+*/
+/* include all Core registers and bit definitions */
+#include <asm/mach-common/def_LPBlackfin.h>
+
+/*********************************************************************************** */
+/* System MMR Register Map */
+/*********************************************************************************** */
+
+/* Clock and System Control (0xFFC00000 - 0xFFC000FF) */
+
+#define PLL_CTL 0xFFC00000 /* PLL Control register (16-bit) */
+#define PLL_DIV 0xFFC00004 /* PLL Divide Register (16-bit) */
+#define VR_CTL 0xFFC00008 /* Voltage Regulator Control Register (16-bit) */
+#define PLL_STAT 0xFFC0000C /* PLL Status register (16-bit) */
+#define PLL_LOCKCNT 0xFFC00010 /* PLL Lock Count register (16-bit) */
+#define CHIPID 0xFFC00014 /* Chip ID Register */
+
+/* System Reset and Interrupt Controller registers for core A (0xFFC0 0100-0xFFC0 01FF) */
+#define SICA_SWRST 0xFFC00100 /* Software Reset register */
+#define SICA_SYSCR 0xFFC00104 /* System Reset Configuration register */
+#define SICA_RVECT 0xFFC00108 /* SIC Reset Vector Address Register */
+#define SICA_IMASK 0xFFC0010C /* SIC Interrupt Mask register 0 - hack to fix old tests */
+#define SICA_IMASK0 0xFFC0010C /* SIC Interrupt Mask register 0 */
+#define SICA_IMASK1 0xFFC00110 /* SIC Interrupt Mask register 1 */
+#define SICA_IAR0 0xFFC00124 /* SIC Interrupt Assignment Register 0 */
+#define SICA_IAR1 0xFFC00128 /* SIC Interrupt Assignment Register 1 */
+#define SICA_IAR2 0xFFC0012C /* SIC Interrupt Assignment Register 2 */
+#define SICA_IAR3 0xFFC00130 /* SIC Interrupt Assignment Register 3 */
+#define SICA_IAR4 0xFFC00134 /* SIC Interrupt Assignment Register 4 */
+#define SICA_IAR5 0xFFC00138 /* SIC Interrupt Assignment Register 5 */
+#define SICA_IAR6 0xFFC0013C /* SIC Interrupt Assignment Register 6 */
+#define SICA_IAR7 0xFFC00140 /* SIC Interrupt Assignment Register 7 */
+#define SICA_ISR0 0xFFC00114 /* SIC Interrupt Status register 0 */
+#define SICA_ISR1 0xFFC00118 /* SIC Interrupt Status register 1 */
+#define SICA_IWR0 0xFFC0011C /* SIC Interrupt Wakeup-Enable register 0 */
+#define SICA_IWR1 0xFFC00120 /* SIC Interrupt Wakeup-Enable register 1 */
+
+/* System Reset and Interrupt Controller registers for Core B (0xFFC0 1100-0xFFC0 11FF) */
+#define SICB_SWRST 0xFFC01100 /* reserved */
+#define SICB_SYSCR 0xFFC01104 /* reserved */
+#define SICB_RVECT 0xFFC01108 /* SIC Reset Vector Address Register */
+#define SICB_IMASK0 0xFFC0110C /* SIC Interrupt Mask register 0 */
+#define SICB_IMASK1 0xFFC01110 /* SIC Interrupt Mask register 1 */
+#define SICB_IAR0 0xFFC01124 /* SIC Interrupt Assignment Register 0 */
+#define SICB_IAR1 0xFFC01128 /* SIC Interrupt Assignment Register 1 */
+#define SICB_IAR2 0xFFC0112C /* SIC Interrupt Assignment Register 2 */
+#define SICB_IAR3 0xFFC01130 /* SIC Interrupt Assignment Register 3 */
+#define SICB_IAR4 0xFFC01134 /* SIC Interrupt Assignment Register 4 */
+#define SICB_IAR5 0xFFC01138 /* SIC Interrupt Assignment Register 5 */
+#define SICB_IAR6 0xFFC0113C /* SIC Interrupt Assignment Register 6 */
+#define SICB_IAR7 0xFFC01140 /* SIC Interrupt Assignment Register 7 */
+#define SICB_ISR0 0xFFC01114 /* SIC Interrupt Status register 0 */
+#define SICB_ISR1 0xFFC01118 /* SIC Interrupt Status register 1 */
+#define SICB_IWR0 0xFFC0111C /* SIC Interrupt Wakeup-Enable register 0 */
+#define SICB_IWR1 0xFFC01120 /* SIC Interrupt Wakeup-Enable register 1 */
+
+/* Watchdog Timer registers for Core A (0xFFC0 0200-0xFFC0 02FF) */
+#define WDOGA_CTL 0xFFC00200 /* Watchdog Control register */
+#define WDOGA_CNT 0xFFC00204 /* Watchdog Count register */
+#define WDOGA_STAT 0xFFC00208 /* Watchdog Status register */
+
+/* Watchdog Timer registers for Core B (0xFFC0 1200-0xFFC0 12FF) */
+#define WDOGB_CTL 0xFFC01200 /* Watchdog Control register */
+#define WDOGB_CNT 0xFFC01204 /* Watchdog Count register */
+#define WDOGB_STAT 0xFFC01208 /* Watchdog Status register */
+
+/* UART Controller (0xFFC00400 - 0xFFC004FF) */
+#define UART_THR 0xFFC00400 /* Transmit Holding register */
+#define UART_RBR 0xFFC00400 /* Receive Buffer register */
+#define UART_DLL 0xFFC00400 /* Divisor Latch (Low-Byte) */
+#define UART_IER 0xFFC00404 /* Interrupt Enable Register */
+#define UART_DLH 0xFFC00404 /* Divisor Latch (High-Byte) */
+#define UART_IIR 0xFFC00408 /* Interrupt Identification Register */
+#define UART_LCR 0xFFC0040C /* Line Control Register */
+#define UART_MCR 0xFFC00410 /* Modem Control Register */
+#define UART_LSR 0xFFC00414 /* Line Status Register */
+#define UART_MSR 0xFFC00418 /* Modem Status Register */
+#define UART_SCR 0xFFC0041C /* SCR Scratch Register */
+#define UART_GCTL 0xFFC00424 /* Global Control Register */
+
+/* SPI Controller (0xFFC00500 - 0xFFC005FF) */
+#define SPI_CTL 0xFFC00500 /* SPI Control Register */
+#define SPI_FLG 0xFFC00504 /* SPI Flag register */
+#define SPI_STAT 0xFFC00508 /* SPI Status register */
+#define SPI_TDBR 0xFFC0050C /* SPI Transmit Data Buffer Register */
+#define SPI_RDBR 0xFFC00510 /* SPI Receive Data Buffer Register */
+#define SPI_BAUD 0xFFC00514 /* SPI Baud rate Register */
+#define SPI_SHADOW 0xFFC00518 /* SPI_RDBR Shadow Register */
+
+/* Timer 0-7 registers (0xFFC0 0600-0xFFC0 06FF) */
+#define TIMER0_CONFIG 0xFFC00600 /* Timer0 Configuration register */
+#define TIMER0_COUNTER 0xFFC00604 /* Timer0 Counter register */
+#define TIMER0_PERIOD 0xFFC00608 /* Timer0 Period register */
+#define TIMER0_WIDTH 0xFFC0060C /* Timer0 Width register */
+
+#define TIMER1_CONFIG 0xFFC00610 /* Timer1 Configuration register */
+#define TIMER1_COUNTER 0xFFC00614 /* Timer1 Counter register */
+#define TIMER1_PERIOD 0xFFC00618 /* Timer1 Period register */
+#define TIMER1_WIDTH 0xFFC0061C /* Timer1 Width register */
+
+#define TIMER2_CONFIG 0xFFC00620 /* Timer2 Configuration register */
+#define TIMER2_COUNTER 0xFFC00624 /* Timer2 Counter register */
+#define TIMER2_PERIOD 0xFFC00628 /* Timer2 Period register */
+#define TIMER2_WIDTH 0xFFC0062C /* Timer2 Width register */
+
+#define TIMER3_CONFIG 0xFFC00630 /* Timer3 Configuration register */
+#define TIMER3_COUNTER 0xFFC00634 /* Timer3 Counter register */
+#define TIMER3_PERIOD 0xFFC00638 /* Timer3 Period register */
+#define TIMER3_WIDTH 0xFFC0063C /* Timer3 Width register */
+
+#define TIMER4_CONFIG 0xFFC00640 /* Timer4 Configuration register */
+#define TIMER4_COUNTER 0xFFC00644 /* Timer4 Counter register */
+#define TIMER4_PERIOD 0xFFC00648 /* Timer4 Period register */
+#define TIMER4_WIDTH 0xFFC0064C /* Timer4 Width register */
+
+#define TIMER5_CONFIG 0xFFC00650 /* Timer5 Configuration register */
+#define TIMER5_COUNTER 0xFFC00654 /* Timer5 Counter register */
+#define TIMER5_PERIOD 0xFFC00658 /* Timer5 Period register */
+#define TIMER5_WIDTH 0xFFC0065C /* Timer5 Width register */
+
+#define TIMER6_CONFIG 0xFFC00660 /* Timer6 Configuration register */
+#define TIMER6_COUNTER 0xFFC00664 /* Timer6 Counter register */
+#define TIMER6_PERIOD 0xFFC00668 /* Timer6 Period register */
+#define TIMER6_WIDTH 0xFFC0066C /* Timer6 Width register */
+
+#define TIMER7_CONFIG 0xFFC00670 /* Timer7 Configuration register */
+#define TIMER7_COUNTER 0xFFC00674 /* Timer7 Counter register */
+#define TIMER7_PERIOD 0xFFC00678 /* Timer7 Period register */
+#define TIMER7_WIDTH 0xFFC0067C /* Timer7 Width register */
+
+#define TMRS8_ENABLE 0xFFC00680 /* Timer Enable Register */
+#define TMRS8_DISABLE 0xFFC00684 /* Timer Disable register */
+#define TMRS8_STATUS 0xFFC00688 /* Timer Status register */
+
+/* Timer registers 8-11 (0xFFC0 1600-0xFFC0 16FF) */
+#define TIMER8_CONFIG 0xFFC01600 /* Timer8 Configuration register */
+#define TIMER8_COUNTER 0xFFC01604 /* Timer8 Counter register */
+#define TIMER8_PERIOD 0xFFC01608 /* Timer8 Period register */
+#define TIMER8_WIDTH 0xFFC0160C /* Timer8 Width register */
+
+#define TIMER9_CONFIG 0xFFC01610 /* Timer9 Configuration register */
+#define TIMER9_COUNTER 0xFFC01614 /* Timer9 Counter register */
+#define TIMER9_PERIOD 0xFFC01618 /* Timer9 Period register */
+#define TIMER9_WIDTH 0xFFC0161C /* Timer9 Width register */
+
+#define TIMER10_CONFIG 0xFFC01620 /* Timer10 Configuration register */
+#define TIMER10_COUNTER 0xFFC01624 /* Timer10 Counter register */
+#define TIMER10_PERIOD 0xFFC01628 /* Timer10 Period register */
+#define TIMER10_WIDTH 0xFFC0162C /* Timer10 Width register */
+
+#define TIMER11_CONFIG 0xFFC01630 /* Timer11 Configuration register */
+#define TIMER11_COUNTER 0xFFC01634 /* Timer11 Counter register */
+#define TIMER11_PERIOD 0xFFC01638 /* Timer11 Period register */
+#define TIMER11_WIDTH 0xFFC0163C /* Timer11 Width register */
+
+#define TMRS4_ENABLE 0xFFC01640 /* Timer Enable Register */
+#define TMRS4_DISABLE 0xFFC01644 /* Timer Disable register */
+#define TMRS4_STATUS 0xFFC01648 /* Timer Status register */
+
+/* Programmable Flag 0 registers (0xFFC0 0700-0xFFC0 07FF) */
+#define FIO0_FLAG_D 0xFFC00700 /* Flag Data register */
+#define FIO0_FLAG_C 0xFFC00704 /* Flag Clear register */
+#define FIO0_FLAG_S 0xFFC00708 /* Flag Set register */
+#define FIO0_FLAG_T 0xFFC0070C /* Flag Toggle register */
+#define FIO0_MASKA_D 0xFFC00710 /* Flag Mask Interrupt A Data register */
+#define FIO0_MASKA_C 0xFFC00714 /* Flag Mask Interrupt A Clear register */
+#define FIO0_MASKA_S 0xFFC00718 /* Flag Mask Interrupt A Set register */
+#define FIO0_MASKA_T 0xFFC0071C /* Flag Mask Interrupt A Toggle register */
+#define FIO0_MASKB_D 0xFFC00720 /* Flag Mask Interrupt B Data register */
+#define FIO0_MASKB_C 0xFFC00724 /* Flag Mask Interrupt B Clear register */
+#define FIO0_MASKB_S 0xFFC00728 /* Flag Mask Interrupt B Set register */
+#define FIO0_MASKB_T 0xFFC0072C /* Flag Mask Interrupt B Toggle register */
+#define FIO0_DIR 0xFFC00730 /* Flag Direction register */
+#define FIO0_POLAR 0xFFC00734 /* Flag Polarity register */
+#define FIO0_EDGE 0xFFC00738 /* Flag Interrupt Sensitivity register */
+#define FIO0_BOTH 0xFFC0073C /* Flag Set on Both Edges register */
+#define FIO0_INEN 0xFFC00740 /* Flag Input Enable register */
+
+/* Programmable Flag 1 registers (0xFFC0 1500-0xFFC0 15FF) */
+#define FIO1_FLAG_D 0xFFC01500 /* Flag Data register (mask used to directly */
+#define FIO1_FLAG_C 0xFFC01504 /* Flag Clear register */
+#define FIO1_FLAG_S 0xFFC01508 /* Flag Set register */
+#define FIO1_FLAG_T 0xFFC0150C /* Flag Toggle register (mask used to */
+#define FIO1_MASKA_D 0xFFC01510 /* Flag Mask Interrupt A Data register */
+#define FIO1_MASKA_C 0xFFC01514 /* Flag Mask Interrupt A Clear register */
+#define FIO1_MASKA_S 0xFFC01518 /* Flag Mask Interrupt A Set register */
+#define FIO1_MASKA_T 0xFFC0151C /* Flag Mask Interrupt A Toggle register */
+#define FIO1_MASKB_D 0xFFC01520 /* Flag Mask Interrupt B Data register */
+#define FIO1_MASKB_C 0xFFC01524 /* Flag Mask Interrupt B Clear register */
+#define FIO1_MASKB_S 0xFFC01528 /* Flag Mask Interrupt B Set register */
+#define FIO1_MASKB_T 0xFFC0152C /* Flag Mask Interrupt B Toggle register */
+#define FIO1_DIR 0xFFC01530 /* Flag Direction register */
+#define FIO1_POLAR 0xFFC01534 /* Flag Polarity register */
+#define FIO1_EDGE 0xFFC01538 /* Flag Interrupt Sensitivity register */
+#define FIO1_BOTH 0xFFC0153C /* Flag Set on Both Edges register */
+#define FIO1_INEN 0xFFC01540 /* Flag Input Enable register */
+
+/* Programmable Flag registers (0xFFC0 1700-0xFFC0 17FF) */
+#define FIO2_FLAG_D 0xFFC01700 /* Flag Data register (mask used to directly */
+#define FIO2_FLAG_C 0xFFC01704 /* Flag Clear register */
+#define FIO2_FLAG_S 0xFFC01708 /* Flag Set register */
+#define FIO2_FLAG_T 0xFFC0170C /* Flag Toggle register (mask used to */
+#define FIO2_MASKA_D 0xFFC01710 /* Flag Mask Interrupt A Data register */
+#define FIO2_MASKA_C 0xFFC01714 /* Flag Mask Interrupt A Clear register */
+#define FIO2_MASKA_S 0xFFC01718 /* Flag Mask Interrupt A Set register */
+#define FIO2_MASKA_T 0xFFC0171C /* Flag Mask Interrupt A Toggle register */
+#define FIO2_MASKB_D 0xFFC01720 /* Flag Mask Interrupt B Data register */
+#define FIO2_MASKB_C 0xFFC01724 /* Flag Mask Interrupt B Clear register */
+#define FIO2_MASKB_S 0xFFC01728 /* Flag Mask Interrupt B Set register */
+#define FIO2_MASKB_T 0xFFC0172C /* Flag Mask Interrupt B Toggle register */
+#define FIO2_DIR 0xFFC01730 /* Flag Direction register */
+#define FIO2_POLAR 0xFFC01734 /* Flag Polarity register */
+#define FIO2_EDGE 0xFFC01738 /* Flag Interrupt Sensitivity register */
+#define FIO2_BOTH 0xFFC0173C /* Flag Set on Both Edges register */
+#define FIO2_INEN 0xFFC01740 /* Flag Input Enable register */
+
+/* SPORT0 Controller (0xFFC00800 - 0xFFC008FF) */
+#define SPORT0_TCR1 0xFFC00800 /* SPORT0 Transmit Configuration 1 Register */
+#define SPORT0_TCR2 0xFFC00804 /* SPORT0 Transmit Configuration 2 Register */
+#define SPORT0_TCLKDIV 0xFFC00808 /* SPORT0 Transmit Clock Divider */
+#define SPORT0_TFSDIV 0xFFC0080C /* SPORT0 Transmit Frame Sync Divider */
+#define SPORT0_TX 0xFFC00810 /* SPORT0 TX Data Register */
+#define SPORT0_RX 0xFFC00818 /* SPORT0 RX Data Register */
+#define SPORT0_RCR1 0xFFC00820 /* SPORT0 Transmit Configuration 1 Register */
+#define SPORT0_RCR2 0xFFC00824 /* SPORT0 Transmit Configuration 2 Register */
+#define SPORT0_RCLKDIV 0xFFC00828 /* SPORT0 Receive Clock Divider */
+#define SPORT0_RFSDIV 0xFFC0082C /* SPORT0 Receive Frame Sync Divider */
+#define SPORT0_STAT 0xFFC00830 /* SPORT0 Status Register */
+#define SPORT0_CHNL 0xFFC00834 /* SPORT0 Current Channel Register */
+#define SPORT0_MCMC1 0xFFC00838 /* SPORT0 Multi-Channel Configuration Register 1 */
+#define SPORT0_MCMC2 0xFFC0083C /* SPORT0 Multi-Channel Configuration Register 2 */
+#define SPORT0_MTCS0 0xFFC00840 /* SPORT0 Multi-Channel Transmit Select Register 0 */
+#define SPORT0_MTCS1 0xFFC00844 /* SPORT0 Multi-Channel Transmit Select Register 1 */
+#define SPORT0_MTCS2 0xFFC00848 /* SPORT0 Multi-Channel Transmit Select Register 2 */
+#define SPORT0_MTCS3 0xFFC0084C /* SPORT0 Multi-Channel Transmit Select Register 3 */
+#define SPORT0_MRCS0 0xFFC00850 /* SPORT0 Multi-Channel Receive Select Register 0 */
+#define SPORT0_MRCS1 0xFFC00854 /* SPORT0 Multi-Channel Receive Select Register 1 */
+#define SPORT0_MRCS2 0xFFC00858 /* SPORT0 Multi-Channel Receive Select Register 2 */
+#define SPORT0_MRCS3 0xFFC0085C /* SPORT0 Multi-Channel Receive Select Register 3 */
+
+/* SPORT1 Controller (0xFFC00900 - 0xFFC009FF) */
+#define SPORT1_TCR1 0xFFC00900 /* SPORT1 Transmit Configuration 1 Register */
+#define SPORT1_TCR2 0xFFC00904 /* SPORT1 Transmit Configuration 2 Register */
+#define SPORT1_TCLKDIV 0xFFC00908 /* SPORT1 Transmit Clock Divider */
+#define SPORT1_TFSDIV 0xFFC0090C /* SPORT1 Transmit Frame Sync Divider */
+#define SPORT1_TX 0xFFC00910 /* SPORT1 TX Data Register */
+#define SPORT1_RX 0xFFC00918 /* SPORT1 RX Data Register */
+#define SPORT1_RCR1 0xFFC00920 /* SPORT1 Transmit Configuration 1 Register */
+#define SPORT1_RCR2 0xFFC00924 /* SPORT1 Transmit Configuration 2 Register */
+#define SPORT1_RCLKDIV 0xFFC00928 /* SPORT1 Receive Clock Divider */
+#define SPORT1_RFSDIV 0xFFC0092C /* SPORT1 Receive Frame Sync Divider */
+#define SPORT1_STAT 0xFFC00930 /* SPORT1 Status Register */
+#define SPORT1_CHNL 0xFFC00934 /* SPORT1 Current Channel Register */
+#define SPORT1_MCMC1 0xFFC00938 /* SPORT1 Multi-Channel Configuration Register 1 */
+#define SPORT1_MCMC2 0xFFC0093C /* SPORT1 Multi-Channel Configuration Register 2 */
+#define SPORT1_MTCS0 0xFFC00940 /* SPORT1 Multi-Channel Transmit Select Register 0 */
+#define SPORT1_MTCS1 0xFFC00944 /* SPORT1 Multi-Channel Transmit Select Register 1 */
+#define SPORT1_MTCS2 0xFFC00948 /* SPORT1 Multi-Channel Transmit Select Register 2 */
+#define SPORT1_MTCS3 0xFFC0094C /* SPORT1 Multi-Channel Transmit Select Register 3 */
+#define SPORT1_MRCS0 0xFFC00950 /* SPORT1 Multi-Channel Receive Select Register 0 */
+#define SPORT1_MRCS1 0xFFC00954 /* SPORT1 Multi-Channel Receive Select Register 1 */
+#define SPORT1_MRCS2 0xFFC00958 /* SPORT1 Multi-Channel Receive Select Register 2 */
+#define SPORT1_MRCS3 0xFFC0095C /* SPORT1 Multi-Channel Receive Select Register 3 */
+
+/* Asynchronous Memory Controller - External Bus Interface Unit */
+#define EBIU_AMGCTL 0xFFC00A00 /* Asynchronous Memory Global Control Register */
+#define EBIU_AMBCTL0 0xFFC00A04 /* Asynchronous Memory Bank Control Register 0 */
+#define EBIU_AMBCTL1 0xFFC00A08 /* Asynchronous Memory Bank Control Register 1 */
+
+/* SDRAM Controller External Bus Interface Unit (0xFFC00A00 - 0xFFC00AFF) */
+#define EBIU_SDGCTL 0xFFC00A10 /* SDRAM Global Control Register */
+#define EBIU_SDBCTL 0xFFC00A14 /* SDRAM Bank Control Register */
+#define EBIU_SDRRC 0xFFC00A18 /* SDRAM Refresh Rate Control Register */
+#define EBIU_SDSTAT 0xFFC00A1C /* SDRAM Status Register */
+
+/* Parallel Peripheral Interface (PPI) 0 registers (0xFFC0 1000-0xFFC0 10FF) */
+#define PPI0_CONTROL 0xFFC01000 /* PPI0 Control register */
+#define PPI0_STATUS 0xFFC01004 /* PPI0 Status register */
+#define PPI0_COUNT 0xFFC01008 /* PPI0 Transfer Count register */
+#define PPI0_DELAY 0xFFC0100C /* PPI0 Delay Count register */
+#define PPI0_FRAME 0xFFC01010 /* PPI0 Frame Length register */
+
+/*Parallel Peripheral Interface (PPI) 1 registers (0xFFC0 1300-0xFFC0 13FF) */
+#define PPI1_CONTROL 0xFFC01300 /* PPI1 Control register */
+#define PPI1_STATUS 0xFFC01304 /* PPI1 Status register */
+#define PPI1_COUNT 0xFFC01308 /* PPI1 Transfer Count register */
+#define PPI1_DELAY 0xFFC0130C /* PPI1 Delay Count register */
+#define PPI1_FRAME 0xFFC01310 /* PPI1 Frame Length register */
+
+/*DMA traffic control registers */
+#define DMA1_TC_PER 0xFFC01B0C /* Traffic control periods */
+#define DMA1_TC_CNT 0xFFC01B10 /* Traffic control current counts */
+#define DMA2_TC_PER 0xFFC00B0C /* Traffic control periods */
+#define DMA2_TC_CNT 0xFFC00B10 /* Traffic control current counts */
+
+/* DMA1 Controller registers (0xFFC0 1C00-0xFFC0 1FFF) */
+#define DMA1_0_CONFIG 0xFFC01C08 /* DMA1 Channel 0 Configuration register */
+#define DMA1_0_NEXT_DESC_PTR 0xFFC01C00 /* DMA1 Channel 0 Next Descripter Ptr Reg */
+#define DMA1_0_START_ADDR 0xFFC01C04 /* DMA1 Channel 0 Start Address */
+#define DMA1_0_X_COUNT 0xFFC01C10 /* DMA1 Channel 0 Inner Loop Count */
+#define DMA1_0_Y_COUNT 0xFFC01C18 /* DMA1 Channel 0 Outer Loop Count */
+#define DMA1_0_X_MODIFY 0xFFC01C14 /* DMA1 Channel 0 Inner Loop Addr Increment */
+#define DMA1_0_Y_MODIFY 0xFFC01C1C /* DMA1 Channel 0 Outer Loop Addr Increment */
+#define DMA1_0_CURR_DESC_PTR 0xFFC01C20 /* DMA1 Channel 0 Current Descriptor Pointer */
+#define DMA1_0_CURR_ADDR 0xFFC01C24 /* DMA1 Channel 0 Current Address Pointer */
+#define DMA1_0_CURR_X_COUNT 0xFFC01C30 /* DMA1 Channel 0 Current Inner Loop Count */
+#define DMA1_0_CURR_Y_COUNT 0xFFC01C38 /* DMA1 Channel 0 Current Outer Loop Count */
+#define DMA1_0_IRQ_STATUS 0xFFC01C28 /* DMA1 Channel 0 Interrupt/Status Register */
+#define DMA1_0_PERIPHERAL_MAP 0xFFC01C2C /* DMA1 Channel 0 Peripheral Map Register */
+
+#define DMA1_1_CONFIG 0xFFC01C48 /* DMA1 Channel 1 Configuration register */
+#define DMA1_1_NEXT_DESC_PTR 0xFFC01C40 /* DMA1 Channel 1 Next Descripter Ptr Reg */
+#define DMA1_1_START_ADDR 0xFFC01C44 /* DMA1 Channel 1 Start Address */
+#define DMA1_1_X_COUNT 0xFFC01C50 /* DMA1 Channel 1 Inner Loop Count */
+#define DMA1_1_Y_COUNT 0xFFC01C58 /* DMA1 Channel 1 Outer Loop Count */
+#define DMA1_1_X_MODIFY 0xFFC01C54 /* DMA1 Channel 1 Inner Loop Addr Increment */
+#define DMA1_1_Y_MODIFY 0xFFC01C5C /* DMA1 Channel 1 Outer Loop Addr Increment */
+#define DMA1_1_CURR_DESC_PTR 0xFFC01C60 /* DMA1 Channel 1 Current Descriptor Pointer */
+#define DMA1_1_CURR_ADDR 0xFFC01C64 /* DMA1 Channel 1 Current Address Pointer */
+#define DMA1_1_CURR_X_COUNT 0xFFC01C70 /* DMA1 Channel 1 Current Inner Loop Count */
+#define DMA1_1_CURR_Y_COUNT 0xFFC01C78 /* DMA1 Channel 1 Current Outer Loop Count */
+#define DMA1_1_IRQ_STATUS 0xFFC01C68 /* DMA1 Channel 1 Interrupt/Status Register */
+#define DMA1_1_PERIPHERAL_MAP 0xFFC01C6C /* DMA1 Channel 1 Peripheral Map Register */
+
+#define DMA1_2_CONFIG 0xFFC01C88 /* DMA1 Channel 2 Configuration register */
+#define DMA1_2_NEXT_DESC_PTR 0xFFC01C80 /* DMA1 Channel 2 Next Descripter Ptr Reg */
+#define DMA1_2_START_ADDR 0xFFC01C84 /* DMA1 Channel 2 Start Address */
+#define DMA1_2_X_COUNT 0xFFC01C90 /* DMA1 Channel 2 Inner Loop Count */
+#define DMA1_2_Y_COUNT 0xFFC01C98 /* DMA1 Channel 2 Outer Loop Count */
+#define DMA1_2_X_MODIFY 0xFFC01C94 /* DMA1 Channel 2 Inner Loop Addr Increment */
+#define DMA1_2_Y_MODIFY 0xFFC01C9C /* DMA1 Channel 2 Outer Loop Addr Increment */
+#define DMA1_2_CURR_DESC_PTR 0xFFC01CA0 /* DMA1 Channel 2 Current Descriptor Pointer */
+#define DMA1_2_CURR_ADDR 0xFFC01CA4 /* DMA1 Channel 2 Current Address Pointer */
+#define DMA1_2_CURR_X_COUNT 0xFFC01CB0 /* DMA1 Channel 2 Current Inner Loop Count */
+#define DMA1_2_CURR_Y_COUNT 0xFFC01CB8 /* DMA1 Channel 2 Current Outer Loop Count */
+#define DMA1_2_IRQ_STATUS 0xFFC01CA8 /* DMA1 Channel 2 Interrupt/Status Register */
+#define DMA1_2_PERIPHERAL_MAP 0xFFC01CAC /* DMA1 Channel 2 Peripheral Map Register */
+
+#define DMA1_3_CONFIG 0xFFC01CC8 /* DMA1 Channel 3 Configuration register */
+#define DMA1_3_NEXT_DESC_PTR 0xFFC01CC0 /* DMA1 Channel 3 Next Descripter Ptr Reg */
+#define DMA1_3_START_ADDR 0xFFC01CC4 /* DMA1 Channel 3 Start Address */
+#define DMA1_3_X_COUNT 0xFFC01CD0 /* DMA1 Channel 3 Inner Loop Count */
+#define DMA1_3_Y_COUNT 0xFFC01CD8 /* DMA1 Channel 3 Outer Loop Count */
+#define DMA1_3_X_MODIFY 0xFFC01CD4 /* DMA1 Channel 3 Inner Loop Addr Increment */
+#define DMA1_3_Y_MODIFY 0xFFC01CDC /* DMA1 Channel 3 Outer Loop Addr Increment */
+#define DMA1_3_CURR_DESC_PTR 0xFFC01CE0 /* DMA1 Channel 3 Current Descriptor Pointer */
+#define DMA1_3_CURR_ADDR 0xFFC01CE4 /* DMA1 Channel 3 Current Address Pointer */
+#define DMA1_3_CURR_X_COUNT 0xFFC01CF0 /* DMA1 Channel 3 Current Inner Loop Count */
+#define DMA1_3_CURR_Y_COUNT 0xFFC01CF8 /* DMA1 Channel 3 Current Outer Loop Count */
+#define DMA1_3_IRQ_STATUS 0xFFC01CE8 /* DMA1 Channel 3 Interrupt/Status Register */
+#define DMA1_3_PERIPHERAL_MAP 0xFFC01CEC /* DMA1 Channel 3 Peripheral Map Register */
+
+#define DMA1_4_CONFIG 0xFFC01D08 /* DMA1 Channel 4 Configuration register */
+#define DMA1_4_NEXT_DESC_PTR 0xFFC01D00 /* DMA1 Channel 4 Next Descripter Ptr Reg */
+#define DMA1_4_START_ADDR 0xFFC01D04 /* DMA1 Channel 4 Start Address */
+#define DMA1_4_X_COUNT 0xFFC01D10 /* DMA1 Channel 4 Inner Loop Count */
+#define DMA1_4_Y_COUNT 0xFFC01D18 /* DMA1 Channel 4 Outer Loop Count */
+#define DMA1_4_X_MODIFY 0xFFC01D14 /* DMA1 Channel 4 Inner Loop Addr Increment */
+#define DMA1_4_Y_MODIFY 0xFFC01D1C /* DMA1 Channel 4 Outer Loop Addr Increment */
+#define DMA1_4_CURR_DESC_PTR 0xFFC01D20 /* DMA1 Channel 4 Current Descriptor Pointer */
+#define DMA1_4_CURR_ADDR 0xFFC01D24 /* DMA1 Channel 4 Current Address Pointer */
+#define DMA1_4_CURR_X_COUNT 0xFFC01D30 /* DMA1 Channel 4 Current Inner Loop Count */
+#define DMA1_4_CURR_Y_COUNT 0xFFC01D38 /* DMA1 Channel 4 Current Outer Loop Count */
+#define DMA1_4_IRQ_STATUS 0xFFC01D28 /* DMA1 Channel 4 Interrupt/Status Register */
+#define DMA1_4_PERIPHERAL_MAP 0xFFC01D2C /* DMA1 Channel 4 Peripheral Map Register */
+
+#define DMA1_5_CONFIG 0xFFC01D48 /* DMA1 Channel 5 Configuration register */
+#define DMA1_5_NEXT_DESC_PTR 0xFFC01D40 /* DMA1 Channel 5 Next Descripter Ptr Reg */
+#define DMA1_5_START_ADDR 0xFFC01D44 /* DMA1 Channel 5 Start Address */
+#define DMA1_5_X_COUNT 0xFFC01D50 /* DMA1 Channel 5 Inner Loop Count */
+#define DMA1_5_Y_COUNT 0xFFC01D58 /* DMA1 Channel 5 Outer Loop Count */
+#define DMA1_5_X_MODIFY 0xFFC01D54 /* DMA1 Channel 5 Inner Loop Addr Increment */
+#define DMA1_5_Y_MODIFY 0xFFC01D5C /* DMA1 Channel 5 Outer Loop Addr Increment */
+#define DMA1_5_CURR_DESC_PTR 0xFFC01D60 /* DMA1 Channel 5 Current Descriptor Pointer */
+#define DMA1_5_CURR_ADDR 0xFFC01D64 /* DMA1 Channel 5 Current Address Pointer */
+#define DMA1_5_CURR_X_COUNT 0xFFC01D70 /* DMA1 Channel 5 Current Inner Loop Count */
+#define DMA1_5_CURR_Y_COUNT 0xFFC01D78 /* DMA1 Channel 5 Current Outer Loop Count */
+#define DMA1_5_IRQ_STATUS 0xFFC01D68 /* DMA1 Channel 5 Interrupt/Status Register */
+#define DMA1_5_PERIPHERAL_MAP 0xFFC01D6C /* DMA1 Channel 5 Peripheral Map Register */
+
+#define DMA1_6_CONFIG 0xFFC01D88 /* DMA1 Channel 6 Configuration register */
+#define DMA1_6_NEXT_DESC_PTR 0xFFC01D80 /* DMA1 Channel 6 Next Descripter Ptr Reg */
+#define DMA1_6_START_ADDR 0xFFC01D84 /* DMA1 Channel 6 Start Address */
+#define DMA1_6_X_COUNT 0xFFC01D90 /* DMA1 Channel 6 Inner Loop Count */
+#define DMA1_6_Y_COUNT 0xFFC01D98 /* DMA1 Channel 6 Outer Loop Count */
+#define DMA1_6_X_MODIFY 0xFFC01D94 /* DMA1 Channel 6 Inner Loop Addr Increment */
+#define DMA1_6_Y_MODIFY 0xFFC01D9C /* DMA1 Channel 6 Outer Loop Addr Increment */
+#define DMA1_6_CURR_DESC_PTR 0xFFC01DA0 /* DMA1 Channel 6 Current Descriptor Pointer */
+#define DMA1_6_CURR_ADDR 0xFFC01DA4 /* DMA1 Channel 6 Current Address Pointer */
+#define DMA1_6_CURR_X_COUNT 0xFFC01DB0 /* DMA1 Channel 6 Current Inner Loop Count */
+#define DMA1_6_CURR_Y_COUNT 0xFFC01DB8 /* DMA1 Channel 6 Current Outer Loop Count */
+#define DMA1_6_IRQ_STATUS 0xFFC01DA8 /* DMA1 Channel 6 Interrupt/Status Register */
+#define DMA1_6_PERIPHERAL_MAP 0xFFC01DAC /* DMA1 Channel 6 Peripheral Map Register */
+
+#define DMA1_7_CONFIG 0xFFC01DC8 /* DMA1 Channel 7 Configuration register */
+#define DMA1_7_NEXT_DESC_PTR 0xFFC01DC0 /* DMA1 Channel 7 Next Descripter Ptr Reg */
+#define DMA1_7_START_ADDR 0xFFC01DC4 /* DMA1 Channel 7 Start Address */
+#define DMA1_7_X_COUNT 0xFFC01DD0 /* DMA1 Channel 7 Inner Loop Count */
+#define DMA1_7_Y_COUNT 0xFFC01DD8 /* DMA1 Channel 7 Outer Loop Count */
+#define DMA1_7_X_MODIFY 0xFFC01DD4 /* DMA1 Channel 7 Inner Loop Addr Increment */
+#define DMA1_7_Y_MODIFY 0xFFC01DDC /* DMA1 Channel 7 Outer Loop Addr Increment */
+#define DMA1_7_CURR_DESC_PTR 0xFFC01DE0 /* DMA1 Channel 7 Current Descriptor Pointer */
+#define DMA1_7_CURR_ADDR 0xFFC01DE4 /* DMA1 Channel 7 Current Address Pointer */
+#define DMA1_7_CURR_X_COUNT 0xFFC01DF0 /* DMA1 Channel 7 Current Inner Loop Count */
+#define DMA1_7_CURR_Y_COUNT 0xFFC01DF8 /* DMA1 Channel 7 Current Outer Loop Count */
+#define DMA1_7_IRQ_STATUS 0xFFC01DE8 /* DMA1 Channel 7 Interrupt/Status Register */
+#define DMA1_7_PERIPHERAL_MAP 0xFFC01DEC /* DMA1 Channel 7 Peripheral Map Register */
+
+#define DMA1_8_CONFIG 0xFFC01E08 /* DMA1 Channel 8 Configuration register */
+#define DMA1_8_NEXT_DESC_PTR 0xFFC01E00 /* DMA1 Channel 8 Next Descripter Ptr Reg */
+#define DMA1_8_START_ADDR 0xFFC01E04 /* DMA1 Channel 8 Start Address */
+#define DMA1_8_X_COUNT 0xFFC01E10 /* DMA1 Channel 8 Inner Loop Count */
+#define DMA1_8_Y_COUNT 0xFFC01E18 /* DMA1 Channel 8 Outer Loop Count */
+#define DMA1_8_X_MODIFY 0xFFC01E14 /* DMA1 Channel 8 Inner Loop Addr Increment */
+#define DMA1_8_Y_MODIFY 0xFFC01E1C /* DMA1 Channel 8 Outer Loop Addr Increment */
+#define DMA1_8_CURR_DESC_PTR 0xFFC01E20 /* DMA1 Channel 8 Current Descriptor Pointer */
+#define DMA1_8_CURR_ADDR 0xFFC01E24 /* DMA1 Channel 8 Current Address Pointer */
+#define DMA1_8_CURR_X_COUNT 0xFFC01E30 /* DMA1 Channel 8 Current Inner Loop Count */
+#define DMA1_8_CURR_Y_COUNT 0xFFC01E38 /* DMA1 Channel 8 Current Outer Loop Count */
+#define DMA1_8_IRQ_STATUS 0xFFC01E28 /* DMA1 Channel 8 Interrupt/Status Register */
+#define DMA1_8_PERIPHERAL_MAP 0xFFC01E2C /* DMA1 Channel 8 Peripheral Map Register */
+
+#define DMA1_9_CONFIG 0xFFC01E48 /* DMA1 Channel 9 Configuration register */
+#define DMA1_9_NEXT_DESC_PTR 0xFFC01E40 /* DMA1 Channel 9 Next Descripter Ptr Reg */
+#define DMA1_9_START_ADDR 0xFFC01E44 /* DMA1 Channel 9 Start Address */
+#define DMA1_9_X_COUNT 0xFFC01E50 /* DMA1 Channel 9 Inner Loop Count */
+#define DMA1_9_Y_COUNT 0xFFC01E58 /* DMA1 Channel 9 Outer Loop Count */
+#define DMA1_9_X_MODIFY 0xFFC01E54 /* DMA1 Channel 9 Inner Loop Addr Increment */
+#define DMA1_9_Y_MODIFY 0xFFC01E5C /* DMA1 Channel 9 Outer Loop Addr Increment */
+#define DMA1_9_CURR_DESC_PTR 0xFFC01E60 /* DMA1 Channel 9 Current Descriptor Pointer */
+#define DMA1_9_CURR_ADDR 0xFFC01E64 /* DMA1 Channel 9 Current Address Pointer */
+#define DMA1_9_CURR_X_COUNT 0xFFC01E70 /* DMA1 Channel 9 Current Inner Loop Count */
+#define DMA1_9_CURR_Y_COUNT 0xFFC01E78 /* DMA1 Channel 9 Current Outer Loop Count */
+#define DMA1_9_IRQ_STATUS 0xFFC01E68 /* DMA1 Channel 9 Interrupt/Status Register */
+#define DMA1_9_PERIPHERAL_MAP 0xFFC01E6C /* DMA1 Channel 9 Peripheral Map Register */
+
+#define DMA1_10_CONFIG 0xFFC01E88 /* DMA1 Channel 10 Configuration register */
+#define DMA1_10_NEXT_DESC_PTR 0xFFC01E80 /* DMA1 Channel 10 Next Descripter Ptr Reg */
+#define DMA1_10_START_ADDR 0xFFC01E84 /* DMA1 Channel 10 Start Address */
+#define DMA1_10_X_COUNT 0xFFC01E90 /* DMA1 Channel 10 Inner Loop Count */
+#define DMA1_10_Y_COUNT 0xFFC01E98 /* DMA1 Channel 10 Outer Loop Count */
+#define DMA1_10_X_MODIFY 0xFFC01E94 /* DMA1 Channel 10 Inner Loop Addr Increment */
+#define DMA1_10_Y_MODIFY 0xFFC01E9C /* DMA1 Channel 10 Outer Loop Addr Increment */
+#define DMA1_10_CURR_DESC_PTR 0xFFC01EA0 /* DMA1 Channel 10 Current Descriptor Pointer */
+#define DMA1_10_CURR_ADDR 0xFFC01EA4 /* DMA1 Channel 10 Current Address Pointer */
+#define DMA1_10_CURR_X_COUNT 0xFFC01EB0 /* DMA1 Channel 10 Current Inner Loop Count */
+#define DMA1_10_CURR_Y_COUNT 0xFFC01EB8 /* DMA1 Channel 10 Current Outer Loop Count */
+#define DMA1_10_IRQ_STATUS 0xFFC01EA8 /* DMA1 Channel 10 Interrupt/Status Register */
+#define DMA1_10_PERIPHERAL_MAP 0xFFC01EAC /* DMA1 Channel 10 Peripheral Map Register */
+
+#define DMA1_11_CONFIG 0xFFC01EC8 /* DMA1 Channel 11 Configuration register */
+#define DMA1_11_NEXT_DESC_PTR 0xFFC01EC0 /* DMA1 Channel 11 Next Descripter Ptr Reg */
+#define DMA1_11_START_ADDR 0xFFC01EC4 /* DMA1 Channel 11 Start Address */
+#define DMA1_11_X_COUNT 0xFFC01ED0 /* DMA1 Channel 11 Inner Loop Count */
+#define DMA1_11_Y_COUNT 0xFFC01ED8 /* DMA1 Channel 11 Outer Loop Count */
+#define DMA1_11_X_MODIFY 0xFFC01ED4 /* DMA1 Channel 11 Inner Loop Addr Increment */
+#define DMA1_11_Y_MODIFY 0xFFC01EDC /* DMA1 Channel 11 Outer Loop Addr Increment */
+#define DMA1_11_CURR_DESC_PTR 0xFFC01EE0 /* DMA1 Channel 11 Current Descriptor Pointer */
+#define DMA1_11_CURR_ADDR 0xFFC01EE4 /* DMA1 Channel 11 Current Address Pointer */
+#define DMA1_11_CURR_X_COUNT 0xFFC01EF0 /* DMA1 Channel 11 Current Inner Loop Count */
+#define DMA1_11_CURR_Y_COUNT 0xFFC01EF8 /* DMA1 Channel 11 Current Outer Loop Count */
+#define DMA1_11_IRQ_STATUS 0xFFC01EE8 /* DMA1 Channel 11 Interrupt/Status Register */
+#define DMA1_11_PERIPHERAL_MAP 0xFFC01EEC /* DMA1 Channel 11 Peripheral Map Register */
+
+/* Memory DMA1 Controller registers (0xFFC0 1E80-0xFFC0 1FFF) */
+#define MDMA1_D0_CONFIG 0xFFC01F08 /*MemDMA1 Stream 0 Destination Configuration */
+#define MDMA1_D0_NEXT_DESC_PTR 0xFFC01F00 /*MemDMA1 Stream 0 Destination Next Descriptor Ptr Reg */
+#define MDMA1_D0_START_ADDR 0xFFC01F04 /*MemDMA1 Stream 0 Destination Start Address */
+#define MDMA1_D0_X_COUNT 0xFFC01F10 /*MemDMA1 Stream 0 Destination Inner-Loop Count */
+#define MDMA1_D0_Y_COUNT 0xFFC01F18 /*MemDMA1 Stream 0 Destination Outer-Loop Count */
+#define MDMA1_D0_X_MODIFY 0xFFC01F14 /*MemDMA1 Stream 0 Dest Inner-Loop Address-Increment */
+#define MDMA1_D0_Y_MODIFY 0xFFC01F1C /*MemDMA1 Stream 0 Dest Outer-Loop Address-Increment */
+#define MDMA1_D0_CURR_DESC_PTR 0xFFC01F20 /*MemDMA1 Stream 0 Dest Current Descriptor Ptr reg */
+#define MDMA1_D0_CURR_ADDR 0xFFC01F24 /*MemDMA1 Stream 0 Destination Current Address */
+#define MDMA1_D0_CURR_X_COUNT 0xFFC01F30 /*MemDMA1 Stream 0 Dest Current Inner-Loop Count */
+#define MDMA1_D0_CURR_Y_COUNT 0xFFC01F38 /*MemDMA1 Stream 0 Dest Current Outer-Loop Count */
+#define MDMA1_D0_IRQ_STATUS 0xFFC01F28 /*MemDMA1 Stream 0 Destination Interrupt/Status */
+#define MDMA1_D0_PERIPHERAL_MAP 0xFFC01F2C /*MemDMA1 Stream 0 Destination Peripheral Map */
+
+#define MDMA1_S0_CONFIG 0xFFC01F48 /*MemDMA1 Stream 0 Source Configuration */
+#define MDMA1_S0_NEXT_DESC_PTR 0xFFC01F40 /*MemDMA1 Stream 0 Source Next Descriptor Ptr Reg */
+#define MDMA1_S0_START_ADDR 0xFFC01F44 /*MemDMA1 Stream 0 Source Start Address */
+#define MDMA1_S0_X_COUNT 0xFFC01F50 /*MemDMA1 Stream 0 Source Inner-Loop Count */
+#define MDMA1_S0_Y_COUNT 0xFFC01F58 /*MemDMA1 Stream 0 Source Outer-Loop Count */
+#define MDMA1_S0_X_MODIFY 0xFFC01F54 /*MemDMA1 Stream 0 Source Inner-Loop Address-Increment */
+#define MDMA1_S0_Y_MODIFY 0xFFC01F5C /*MemDMA1 Stream 0 Source Outer-Loop Address-Increment */
+#define MDMA1_S0_CURR_DESC_PTR 0xFFC01F60 /*MemDMA1 Stream 0 Source Current Descriptor Ptr reg */
+#define MDMA1_S0_CURR_ADDR 0xFFC01F64 /*MemDMA1 Stream 0 Source Current Address */
+#define MDMA1_S0_CURR_X_COUNT 0xFFC01F70 /*MemDMA1 Stream 0 Source Current Inner-Loop Count */
+#define MDMA1_S0_CURR_Y_COUNT 0xFFC01F78 /*MemDMA1 Stream 0 Source Current Outer-Loop Count */
+#define MDMA1_S0_IRQ_STATUS 0xFFC01F68 /*MemDMA1 Stream 0 Source Interrupt/Status */
+#define MDMA1_S0_PERIPHERAL_MAP 0xFFC01F6C /*MemDMA1 Stream 0 Source Peripheral Map */
+
+#define MDMA1_D1_CONFIG 0xFFC01F88 /*MemDMA1 Stream 1 Destination Configuration */
+#define MDMA1_D1_NEXT_DESC_PTR 0xFFC01F80 /*MemDMA1 Stream 1 Destination Next Descriptor Ptr Reg */
+#define MDMA1_D1_START_ADDR 0xFFC01F84 /*MemDMA1 Stream 1 Destination Start Address */
+#define MDMA1_D1_X_COUNT 0xFFC01F90 /*MemDMA1 Stream 1 Destination Inner-Loop Count */
+#define MDMA1_D1_Y_COUNT 0xFFC01F98 /*MemDMA1 Stream 1 Destination Outer-Loop Count */
+#define MDMA1_D1_X_MODIFY 0xFFC01F94 /*MemDMA1 Stream 1 Dest Inner-Loop Address-Increment */
+#define MDMA1_D1_Y_MODIFY 0xFFC01F9C /*MemDMA1 Stream 1 Dest Outer-Loop Address-Increment */
+#define MDMA1_D1_CURR_DESC_PTR 0xFFC01FA0 /*MemDMA1 Stream 1 Dest Current Descriptor Ptr reg */
+#define MDMA1_D1_CURR_ADDR 0xFFC01FA4 /*MemDMA1 Stream 1 Dest Current Address */
+#define MDMA1_D1_CURR_X_COUNT 0xFFC01FB0 /*MemDMA1 Stream 1 Dest Current Inner-Loop Count */
+#define MDMA1_D1_CURR_Y_COUNT 0xFFC01FB8 /*MemDMA1 Stream 1 Dest Current Outer-Loop Count */
+#define MDMA1_D1_IRQ_STATUS 0xFFC01FA8 /*MemDMA1 Stream 1 Dest Interrupt/Status */
+#define MDMA1_D1_PERIPHERAL_MAP 0xFFC01FAC /*MemDMA1 Stream 1 Dest Peripheral Map */
+
+#define MDMA1_S1_CONFIG 0xFFC01FC8 /*MemDMA1 Stream 1 Source Configuration */
+#define MDMA1_S1_NEXT_DESC_PTR 0xFFC01FC0 /*MemDMA1 Stream 1 Source Next Descriptor Ptr Reg */
+#define MDMA1_S1_START_ADDR 0xFFC01FC4 /*MemDMA1 Stream 1 Source Start Address */
+#define MDMA1_S1_X_COUNT 0xFFC01FD0 /*MemDMA1 Stream 1 Source Inner-Loop Count */
+#define MDMA1_S1_Y_COUNT 0xFFC01FD8 /*MemDMA1 Stream 1 Source Outer-Loop Count */
+#define MDMA1_S1_X_MODIFY 0xFFC01FD4 /*MemDMA1 Stream 1 Source Inner-Loop Address-Increment */
+#define MDMA1_S1_Y_MODIFY 0xFFC01FDC /*MemDMA1 Stream 1 Source Outer-Loop Address-Increment */
+#define MDMA1_S1_CURR_DESC_PTR 0xFFC01FE0 /*MemDMA1 Stream 1 Source Current Descriptor Ptr reg */
+#define MDMA1_S1_CURR_ADDR 0xFFC01FE4 /*MemDMA1 Stream 1 Source Current Address */
+#define MDMA1_S1_CURR_X_COUNT 0xFFC01FF0 /*MemDMA1 Stream 1 Source Current Inner-Loop Count */
+#define MDMA1_S1_CURR_Y_COUNT 0xFFC01FF8 /*MemDMA1 Stream 1 Source Current Outer-Loop Count */
+#define MDMA1_S1_IRQ_STATUS 0xFFC01FE8 /*MemDMA1 Stream 1 Source Interrupt/Status */
+#define MDMA1_S1_PERIPHERAL_MAP 0xFFC01FEC /*MemDMA1 Stream 1 Source Peripheral Map */
+
+/* DMA2 Controller registers (0xFFC0 0C00-0xFFC0 0DFF) */
+#define DMA2_0_CONFIG 0xFFC00C08 /* DMA2 Channel 0 Configuration register */
+#define DMA2_0_NEXT_DESC_PTR 0xFFC00C00 /* DMA2 Channel 0 Next Descripter Ptr Reg */
+#define DMA2_0_START_ADDR 0xFFC00C04 /* DMA2 Channel 0 Start Address */
+#define DMA2_0_X_COUNT 0xFFC00C10 /* DMA2 Channel 0 Inner Loop Count */
+#define DMA2_0_Y_COUNT 0xFFC00C18 /* DMA2 Channel 0 Outer Loop Count */
+#define DMA2_0_X_MODIFY 0xFFC00C14 /* DMA2 Channel 0 Inner Loop Addr Increment */
+#define DMA2_0_Y_MODIFY 0xFFC00C1C /* DMA2 Channel 0 Outer Loop Addr Increment */
+#define DMA2_0_CURR_DESC_PTR 0xFFC00C20 /* DMA2 Channel 0 Current Descriptor Pointer */
+#define DMA2_0_CURR_ADDR 0xFFC00C24 /* DMA2 Channel 0 Current Address Pointer */
+#define DMA2_0_CURR_X_COUNT 0xFFC00C30 /* DMA2 Channel 0 Current Inner Loop Count */
+#define DMA2_0_CURR_Y_COUNT 0xFFC00C38 /* DMA2 Channel 0 Current Outer Loop Count */
+#define DMA2_0_IRQ_STATUS 0xFFC00C28 /* DMA2 Channel 0 Interrupt/Status Register */
+#define DMA2_0_PERIPHERAL_MAP 0xFFC00C2C /* DMA2 Channel 0 Peripheral Map Register */
+
+#define DMA2_1_CONFIG 0xFFC00C48 /* DMA2 Channel 1 Configuration register */
+#define DMA2_1_NEXT_DESC_PTR 0xFFC00C40 /* DMA2 Channel 1 Next Descripter Ptr Reg */
+#define DMA2_1_START_ADDR 0xFFC00C44 /* DMA2 Channel 1 Start Address */
+#define DMA2_1_X_COUNT 0xFFC00C50 /* DMA2 Channel 1 Inner Loop Count */
+#define DMA2_1_Y_COUNT 0xFFC00C58 /* DMA2 Channel 1 Outer Loop Count */
+#define DMA2_1_X_MODIFY 0xFFC00C54 /* DMA2 Channel 1 Inner Loop Addr Increment */
+#define DMA2_1_Y_MODIFY 0xFFC00C5C /* DMA2 Channel 1 Outer Loop Addr Increment */
+#define DMA2_1_CURR_DESC_PTR 0xFFC00C60 /* DMA2 Channel 1 Current Descriptor Pointer */
+#define DMA2_1_CURR_ADDR 0xFFC00C64 /* DMA2 Channel 1 Current Address Pointer */
+#define DMA2_1_CURR_X_COUNT 0xFFC00C70 /* DMA2 Channel 1 Current Inner Loop Count */
+#define DMA2_1_CURR_Y_COUNT 0xFFC00C78 /* DMA2 Channel 1 Current Outer Loop Count */
+#define DMA2_1_IRQ_STATUS 0xFFC00C68 /* DMA2 Channel 1 Interrupt/Status Register */
+#define DMA2_1_PERIPHERAL_MAP 0xFFC00C6C /* DMA2 Channel 1 Peripheral Map Register */
+
+#define DMA2_2_CONFIG 0xFFC00C88 /* DMA2 Channel 2 Configuration register */
+#define DMA2_2_NEXT_DESC_PTR 0xFFC00C80 /* DMA2 Channel 2 Next Descripter Ptr Reg */
+#define DMA2_2_START_ADDR 0xFFC00C84 /* DMA2 Channel 2 Start Address */
+#define DMA2_2_X_COUNT 0xFFC00C90 /* DMA2 Channel 2 Inner Loop Count */
+#define DMA2_2_Y_COUNT 0xFFC00C98 /* DMA2 Channel 2 Outer Loop Count */
+#define DMA2_2_X_MODIFY 0xFFC00C94 /* DMA2 Channel 2 Inner Loop Addr Increment */
+#define DMA2_2_Y_MODIFY 0xFFC00C9C /* DMA2 Channel 2 Outer Loop Addr Increment */
+#define DMA2_2_CURR_DESC_PTR 0xFFC00CA0 /* DMA2 Channel 2 Current Descriptor Pointer */
+#define DMA2_2_CURR_ADDR 0xFFC00CA4 /* DMA2 Channel 2 Current Address Pointer */
+#define DMA2_2_CURR_X_COUNT 0xFFC00CB0 /* DMA2 Channel 2 Current Inner Loop Count */
+#define DMA2_2_CURR_Y_COUNT 0xFFC00CB8 /* DMA2 Channel 2 Current Outer Loop Count */
+#define DMA2_2_IRQ_STATUS 0xFFC00CA8 /* DMA2 Channel 2 Interrupt/Status Register */
+#define DMA2_2_PERIPHERAL_MAP 0xFFC00CAC /* DMA2 Channel 2 Peripheral Map Register */
+
+#define DMA2_3_CONFIG 0xFFC00CC8 /* DMA2 Channel 3 Configuration register */
+#define DMA2_3_NEXT_DESC_PTR 0xFFC00CC0 /* DMA2 Channel 3 Next Descripter Ptr Reg */
+#define DMA2_3_START_ADDR 0xFFC00CC4 /* DMA2 Channel 3 Start Address */
+#define DMA2_3_X_COUNT 0xFFC00CD0 /* DMA2 Channel 3 Inner Loop Count */
+#define DMA2_3_Y_COUNT 0xFFC00CD8 /* DMA2 Channel 3 Outer Loop Count */
+#define DMA2_3_X_MODIFY 0xFFC00CD4 /* DMA2 Channel 3 Inner Loop Addr Increment */
+#define DMA2_3_Y_MODIFY 0xFFC00CDC /* DMA2 Channel 3 Outer Loop Addr Increment */
+#define DMA2_3_CURR_DESC_PTR 0xFFC00CE0 /* DMA2 Channel 3 Current Descriptor Pointer */
+#define DMA2_3_CURR_ADDR 0xFFC00CE4 /* DMA2 Channel 3 Current Address Pointer */
+#define DMA2_3_CURR_X_COUNT 0xFFC00CF0 /* DMA2 Channel 3 Current Inner Loop Count */
+#define DMA2_3_CURR_Y_COUNT 0xFFC00CF8 /* DMA2 Channel 3 Current Outer Loop Count */
+#define DMA2_3_IRQ_STATUS 0xFFC00CE8 /* DMA2 Channel 3 Interrupt/Status Register */
+#define DMA2_3_PERIPHERAL_MAP 0xFFC00CEC /* DMA2 Channel 3 Peripheral Map Register */
+
+#define DMA2_4_CONFIG 0xFFC00D08 /* DMA2 Channel 4 Configuration register */
+#define DMA2_4_NEXT_DESC_PTR 0xFFC00D00 /* DMA2 Channel 4 Next Descripter Ptr Reg */
+#define DMA2_4_START_ADDR 0xFFC00D04 /* DMA2 Channel 4 Start Address */
+#define DMA2_4_X_COUNT 0xFFC00D10 /* DMA2 Channel 4 Inner Loop Count */
+#define DMA2_4_Y_COUNT 0xFFC00D18 /* DMA2 Channel 4 Outer Loop Count */
+#define DMA2_4_X_MODIFY 0xFFC00D14 /* DMA2 Channel 4 Inner Loop Addr Increment */
+#define DMA2_4_Y_MODIFY 0xFFC00D1C /* DMA2 Channel 4 Outer Loop Addr Increment */
+#define DMA2_4_CURR_DESC_PTR 0xFFC00D20 /* DMA2 Channel 4 Current Descriptor Pointer */
+#define DMA2_4_CURR_ADDR 0xFFC00D24 /* DMA2 Channel 4 Current Address Pointer */
+#define DMA2_4_CURR_X_COUNT 0xFFC00D30 /* DMA2 Channel 4 Current Inner Loop Count */
+#define DMA2_4_CURR_Y_COUNT 0xFFC00D38 /* DMA2 Channel 4 Current Outer Loop Count */
+#define DMA2_4_IRQ_STATUS 0xFFC00D28 /* DMA2 Channel 4 Interrupt/Status Register */
+#define DMA2_4_PERIPHERAL_MAP 0xFFC00D2C /* DMA2 Channel 4 Peripheral Map Register */
+
+#define DMA2_5_CONFIG 0xFFC00D48 /* DMA2 Channel 5 Configuration register */
+#define DMA2_5_NEXT_DESC_PTR 0xFFC00D40 /* DMA2 Channel 5 Next Descripter Ptr Reg */
+#define DMA2_5_START_ADDR 0xFFC00D44 /* DMA2 Channel 5 Start Address */
+#define DMA2_5_X_COUNT 0xFFC00D50 /* DMA2 Channel 5 Inner Loop Count */
+#define DMA2_5_Y_COUNT 0xFFC00D58 /* DMA2 Channel 5 Outer Loop Count */
+#define DMA2_5_X_MODIFY 0xFFC00D54 /* DMA2 Channel 5 Inner Loop Addr Increment */
+#define DMA2_5_Y_MODIFY 0xFFC00D5C /* DMA2 Channel 5 Outer Loop Addr Increment */
+#define DMA2_5_CURR_DESC_PTR 0xFFC00D60 /* DMA2 Channel 5 Current Descriptor Pointer */
+#define DMA2_5_CURR_ADDR 0xFFC00D64 /* DMA2 Channel 5 Current Address Pointer */
+#define DMA2_5_CURR_X_COUNT 0xFFC00D70 /* DMA2 Channel 5 Current Inner Loop Count */
+#define DMA2_5_CURR_Y_COUNT 0xFFC00D78 /* DMA2 Channel 5 Current Outer Loop Count */
+#define DMA2_5_IRQ_STATUS 0xFFC00D68 /* DMA2 Channel 5 Interrupt/Status Register */
+#define DMA2_5_PERIPHERAL_MAP 0xFFC00D6C /* DMA2 Channel 5 Peripheral Map Register */
+
+#define DMA2_6_CONFIG 0xFFC00D88 /* DMA2 Channel 6 Configuration register */
+#define DMA2_6_NEXT_DESC_PTR 0xFFC00D80 /* DMA2 Channel 6 Next Descripter Ptr Reg */
+#define DMA2_6_START_ADDR 0xFFC00D84 /* DMA2 Channel 6 Start Address */
+#define DMA2_6_X_COUNT 0xFFC00D90 /* DMA2 Channel 6 Inner Loop Count */
+#define DMA2_6_Y_COUNT 0xFFC00D98 /* DMA2 Channel 6 Outer Loop Count */
+#define DMA2_6_X_MODIFY 0xFFC00D94 /* DMA2 Channel 6 Inner Loop Addr Increment */
+#define DMA2_6_Y_MODIFY 0xFFC00D9C /* DMA2 Channel 6 Outer Loop Addr Increment */
+#define DMA2_6_CURR_DESC_PTR 0xFFC00DA0 /* DMA2 Channel 6 Current Descriptor Pointer */
+#define DMA2_6_CURR_ADDR 0xFFC00DA4 /* DMA2 Channel 6 Current Address Pointer */
+#define DMA2_6_CURR_X_COUNT 0xFFC00DB0 /* DMA2 Channel 6 Current Inner Loop Count */
+#define DMA2_6_CURR_Y_COUNT 0xFFC00DB8 /* DMA2 Channel 6 Current Outer Loop Count */
+#define DMA2_6_IRQ_STATUS 0xFFC00DA8 /* DMA2 Channel 6 Interrupt/Status Register */
+#define DMA2_6_PERIPHERAL_MAP 0xFFC00DAC /* DMA2 Channel 6 Peripheral Map Register */
+
+#define DMA2_7_CONFIG 0xFFC00DC8 /* DMA2 Channel 7 Configuration register */
+#define DMA2_7_NEXT_DESC_PTR 0xFFC00DC0 /* DMA2 Channel 7 Next Descripter Ptr Reg */
+#define DMA2_7_START_ADDR 0xFFC00DC4 /* DMA2 Channel 7 Start Address */
+#define DMA2_7_X_COUNT 0xFFC00DD0 /* DMA2 Channel 7 Inner Loop Count */
+#define DMA2_7_Y_COUNT 0xFFC00DD8 /* DMA2 Channel 7 Outer Loop Count */
+#define DMA2_7_X_MODIFY 0xFFC00DD4 /* DMA2 Channel 7 Inner Loop Addr Increment */
+#define DMA2_7_Y_MODIFY 0xFFC00DDC /* DMA2 Channel 7 Outer Loop Addr Increment */
+#define DMA2_7_CURR_DESC_PTR 0xFFC00DE0 /* DMA2 Channel 7 Current Descriptor Pointer */
+#define DMA2_7_CURR_ADDR 0xFFC00DE4 /* DMA2 Channel 7 Current Address Pointer */
+#define DMA2_7_CURR_X_COUNT 0xFFC00DF0 /* DMA2 Channel 7 Current Inner Loop Count */
+#define DMA2_7_CURR_Y_COUNT 0xFFC00DF8 /* DMA2 Channel 7 Current Outer Loop Count */
+#define DMA2_7_IRQ_STATUS 0xFFC00DE8 /* DMA2 Channel 7 Interrupt/Status Register */
+#define DMA2_7_PERIPHERAL_MAP 0xFFC00DEC /* DMA2 Channel 7 Peripheral Map Register */
+
+#define DMA2_8_CONFIG 0xFFC00E08 /* DMA2 Channel 8 Configuration register */
+#define DMA2_8_NEXT_DESC_PTR 0xFFC00E00 /* DMA2 Channel 8 Next Descripter Ptr Reg */
+#define DMA2_8_START_ADDR 0xFFC00E04 /* DMA2 Channel 8 Start Address */
+#define DMA2_8_X_COUNT 0xFFC00E10 /* DMA2 Channel 8 Inner Loop Count */
+#define DMA2_8_Y_COUNT 0xFFC00E18 /* DMA2 Channel 8 Outer Loop Count */
+#define DMA2_8_X_MODIFY 0xFFC00E14 /* DMA2 Channel 8 Inner Loop Addr Increment */
+#define DMA2_8_Y_MODIFY 0xFFC00E1C /* DMA2 Channel 8 Outer Loop Addr Increment */
+#define DMA2_8_CURR_DESC_PTR 0xFFC00E20 /* DMA2 Channel 8 Current Descriptor Pointer */
+#define DMA2_8_CURR_ADDR 0xFFC00E24 /* DMA2 Channel 8 Current Address Pointer */
+#define DMA2_8_CURR_X_COUNT 0xFFC00E30 /* DMA2 Channel 8 Current Inner Loop Count */
+#define DMA2_8_CURR_Y_COUNT 0xFFC00E38 /* DMA2 Channel 8 Current Outer Loop Count */
+#define DMA2_8_IRQ_STATUS 0xFFC00E28 /* DMA2 Channel 8 Interrupt/Status Register */
+#define DMA2_8_PERIPHERAL_MAP 0xFFC00E2C /* DMA2 Channel 8 Peripheral Map Register */
+
+#define DMA2_9_CONFIG 0xFFC00E48 /* DMA2 Channel 9 Configuration register */
+#define DMA2_9_NEXT_DESC_PTR 0xFFC00E40 /* DMA2 Channel 9 Next Descripter Ptr Reg */
+#define DMA2_9_START_ADDR 0xFFC00E44 /* DMA2 Channel 9 Start Address */
+#define DMA2_9_X_COUNT 0xFFC00E50 /* DMA2 Channel 9 Inner Loop Count */
+#define DMA2_9_Y_COUNT 0xFFC00E58 /* DMA2 Channel 9 Outer Loop Count */
+#define DMA2_9_X_MODIFY 0xFFC00E54 /* DMA2 Channel 9 Inner Loop Addr Increment */
+#define DMA2_9_Y_MODIFY 0xFFC00E5C /* DMA2 Channel 9 Outer Loop Addr Increment */
+#define DMA2_9_CURR_DESC_PTR 0xFFC00E60 /* DMA2 Channel 9 Current Descriptor Pointer */
+#define DMA2_9_CURR_ADDR 0xFFC00E64 /* DMA2 Channel 9 Current Address Pointer */
+#define DMA2_9_CURR_X_COUNT 0xFFC00E70 /* DMA2 Channel 9 Current Inner Loop Count */
+#define DMA2_9_CURR_Y_COUNT 0xFFC00E78 /* DMA2 Channel 9 Current Outer Loop Count */
+#define DMA2_9_IRQ_STATUS 0xFFC00E68 /* DMA2 Channel 9 Interrupt/Status Register */
+#define DMA2_9_PERIPHERAL_MAP 0xFFC00E6C /* DMA2 Channel 9 Peripheral Map Register */
+
+#define DMA2_10_CONFIG 0xFFC00E88 /* DMA2 Channel 10 Configuration register */
+#define DMA2_10_NEXT_DESC_PTR 0xFFC00E80 /* DMA2 Channel 10 Next Descripter Ptr Reg */
+#define DMA2_10_START_ADDR 0xFFC00E84 /* DMA2 Channel 10 Start Address */
+#define DMA2_10_X_COUNT 0xFFC00E90 /* DMA2 Channel 10 Inner Loop Count */
+#define DMA2_10_Y_COUNT 0xFFC00E98 /* DMA2 Channel 10 Outer Loop Count */
+#define DMA2_10_X_MODIFY 0xFFC00E94 /* DMA2 Channel 10 Inner Loop Addr Increment */
+#define DMA2_10_Y_MODIFY 0xFFC00E9C /* DMA2 Channel 10 Outer Loop Addr Increment */
+#define DMA2_10_CURR_DESC_PTR 0xFFC00EA0 /* DMA2 Channel 10 Current Descriptor Pointer */
+#define DMA2_10_CURR_ADDR 0xFFC00EA4 /* DMA2 Channel 10 Current Address Pointer */
+#define DMA2_10_CURR_X_COUNT 0xFFC00EB0 /* DMA2 Channel 10 Current Inner Loop Count */
+#define DMA2_10_CURR_Y_COUNT 0xFFC00EB8 /* DMA2 Channel 10 Current Outer Loop Count */
+#define DMA2_10_IRQ_STATUS 0xFFC00EA8 /* DMA2 Channel 10 Interrupt/Status Register */
+#define DMA2_10_PERIPHERAL_MAP 0xFFC00EAC /* DMA2 Channel 10 Peripheral Map Register */
+
+#define DMA2_11_CONFIG 0xFFC00EC8 /* DMA2 Channel 11 Configuration register */
+#define DMA2_11_NEXT_DESC_PTR 0xFFC00EC0 /* DMA2 Channel 11 Next Descripter Ptr Reg */
+#define DMA2_11_START_ADDR 0xFFC00EC4 /* DMA2 Channel 11 Start Address */
+#define DMA2_11_X_COUNT 0xFFC00ED0 /* DMA2 Channel 11 Inner Loop Count */
+#define DMA2_11_Y_COUNT 0xFFC00ED8 /* DMA2 Channel 11 Outer Loop Count */
+#define DMA2_11_X_MODIFY 0xFFC00ED4 /* DMA2 Channel 11 Inner Loop Addr Increment */
+#define DMA2_11_Y_MODIFY 0xFFC00EDC /* DMA2 Channel 11 Outer Loop Addr Increment */
+#define DMA2_11_CURR_DESC_PTR 0xFFC00EE0 /* DMA2 Channel 11 Current Descriptor Pointer */
+#define DMA2_11_CURR_ADDR 0xFFC00EE4 /* DMA2 Channel 11 Current Address Pointer */
+#define DMA2_11_CURR_X_COUNT 0xFFC00EF0 /* DMA2 Channel 11 Current Inner Loop Count */
+#define DMA2_11_CURR_Y_COUNT 0xFFC00EF8 /* DMA2 Channel 11 Current Outer Loop Count */
+#define DMA2_11_IRQ_STATUS 0xFFC00EE8 /* DMA2 Channel 11 Interrupt/Status Register */
+#define DMA2_11_PERIPHERAL_MAP 0xFFC00EEC /* DMA2 Channel 11 Peripheral Map Register */
+
+/* Memory DMA2 Controller registers (0xFFC0 0E80-0xFFC0 0FFF) */
+#define MDMA2_D0_CONFIG 0xFFC00F08 /*MemDMA2 Stream 0 Destination Configuration register */
+#define MDMA2_D0_NEXT_DESC_PTR 0xFFC00F00 /*MemDMA2 Stream 0 Destination Next Descriptor Ptr Reg */
+#define MDMA2_D0_START_ADDR 0xFFC00F04 /*MemDMA2 Stream 0 Destination Start Address */
+#define MDMA2_D0_X_COUNT 0xFFC00F10 /*MemDMA2 Stream 0 Dest Inner-Loop Count register */
+#define MDMA2_D0_Y_COUNT 0xFFC00F18 /*MemDMA2 Stream 0 Dest Outer-Loop Count register */
+#define MDMA2_D0_X_MODIFY 0xFFC00F14 /*MemDMA2 Stream 0 Dest Inner-Loop Address-Increment */
+#define MDMA2_D0_Y_MODIFY 0xFFC00F1C /*MemDMA2 Stream 0 Dest Outer-Loop Address-Increment */
+#define MDMA2_D0_CURR_DESC_PTR 0xFFC00F20 /*MemDMA2 Stream 0 Dest Current Descriptor Ptr reg */
+#define MDMA2_D0_CURR_ADDR 0xFFC00F24 /*MemDMA2 Stream 0 Destination Current Address */
+#define MDMA2_D0_CURR_X_COUNT 0xFFC00F30 /*MemDMA2 Stream 0 Dest Current Inner-Loop Count reg */
+#define MDMA2_D0_CURR_Y_COUNT 0xFFC00F38 /*MemDMA2 Stream 0 Dest Current Outer-Loop Count reg */
+#define MDMA2_D0_IRQ_STATUS 0xFFC00F28 /*MemDMA2 Stream 0 Dest Interrupt/Status Register */
+#define MDMA2_D0_PERIPHERAL_MAP 0xFFC00F2C /*MemDMA2 Stream 0 Destination Peripheral Map register */
+
+#define MDMA2_S0_CONFIG 0xFFC00F48 /*MemDMA2 Stream 0 Source Configuration register */
+#define MDMA2_S0_NEXT_DESC_PTR 0xFFC00F40 /*MemDMA2 Stream 0 Source Next Descriptor Ptr Reg */
+#define MDMA2_S0_START_ADDR 0xFFC00F44 /*MemDMA2 Stream 0 Source Start Address */
+#define MDMA2_S0_X_COUNT 0xFFC00F50 /*MemDMA2 Stream 0 Source Inner-Loop Count register */
+#define MDMA2_S0_Y_COUNT 0xFFC00F58 /*MemDMA2 Stream 0 Source Outer-Loop Count register */
+#define MDMA2_S0_X_MODIFY 0xFFC00F54 /*MemDMA2 Stream 0 Src Inner-Loop Addr-Increment reg */
+#define MDMA2_S0_Y_MODIFY 0xFFC00F5C /*MemDMA2 Stream 0 Src Outer-Loop Addr-Increment reg */
+#define MDMA2_S0_CURR_DESC_PTR 0xFFC00F60 /*MemDMA2 Stream 0 Source Current Descriptor Ptr reg */
+#define MDMA2_S0_CURR_ADDR 0xFFC00F64 /*MemDMA2 Stream 0 Source Current Address */
+#define MDMA2_S0_CURR_X_COUNT 0xFFC00F70 /*MemDMA2 Stream 0 Src Current Inner-Loop Count reg */
+#define MDMA2_S0_CURR_Y_COUNT 0xFFC00F78 /*MemDMA2 Stream 0 Src Current Outer-Loop Count reg */
+#define MDMA2_S0_IRQ_STATUS 0xFFC00F68 /*MemDMA2 Stream 0 Source Interrupt/Status Register */
+#define MDMA2_S0_PERIPHERAL_MAP 0xFFC00F6C /*MemDMA2 Stream 0 Source Peripheral Map register */
+
+#define MDMA2_D1_CONFIG 0xFFC00F88 /*MemDMA2 Stream 1 Destination Configuration register */
+#define MDMA2_D1_NEXT_DESC_PTR 0xFFC00F80 /*MemDMA2 Stream 1 Destination Next Descriptor Ptr Reg */
+#define MDMA2_D1_START_ADDR 0xFFC00F84 /*MemDMA2 Stream 1 Destination Start Address */
+#define MDMA2_D1_X_COUNT 0xFFC00F90 /*MemDMA2 Stream 1 Dest Inner-Loop Count register */
+#define MDMA2_D1_Y_COUNT 0xFFC00F98 /*MemDMA2 Stream 1 Dest Outer-Loop Count register */
+#define MDMA2_D1_X_MODIFY 0xFFC00F94 /*MemDMA2 Stream 1 Dest Inner-Loop Address-Increment */
+#define MDMA2_D1_Y_MODIFY 0xFFC00F9C /*MemDMA2 Stream 1 Dest Outer-Loop Address-Increment */
+#define MDMA2_D1_CURR_DESC_PTR 0xFFC00FA0 /*MemDMA2 Stream 1 Destination Current Descriptor Ptr */
+#define MDMA2_D1_CURR_ADDR 0xFFC00FA4 /*MemDMA2 Stream 1 Destination Current Address reg */
+#define MDMA2_D1_CURR_X_COUNT 0xFFC00FB0 /*MemDMA2 Stream 1 Dest Current Inner-Loop Count reg */
+#define MDMA2_D1_CURR_Y_COUNT 0xFFC00FB8 /*MemDMA2 Stream 1 Dest Current Outer-Loop Count reg */
+#define MDMA2_D1_IRQ_STATUS 0xFFC00FA8 /*MemDMA2 Stream 1 Destination Interrupt/Status Reg */
+#define MDMA2_D1_PERIPHERAL_MAP 0xFFC00FAC /*MemDMA2 Stream 1 Destination Peripheral Map register */
+
+#define MDMA2_S1_CONFIG 0xFFC00FC8 /*MemDMA2 Stream 1 Source Configuration register */
+#define MDMA2_S1_NEXT_DESC_PTR 0xFFC00FC0 /*MemDMA2 Stream 1 Source Next Descriptor Ptr Reg */
+#define MDMA2_S1_START_ADDR 0xFFC00FC4 /*MemDMA2 Stream 1 Source Start Address */
+#define MDMA2_S1_X_COUNT 0xFFC00FD0 /*MemDMA2 Stream 1 Source Inner-Loop Count register */
+#define MDMA2_S1_Y_COUNT 0xFFC00FD8 /*MemDMA2 Stream 1 Source Outer-Loop Count register */
+#define MDMA2_S1_X_MODIFY 0xFFC00FD4 /*MemDMA2 Stream 1 Src Inner-Loop Address-Increment */
+#define MDMA2_S1_Y_MODIFY 0xFFC00FDC /*MemDMA2 Stream 1 Source Outer-Loop Address-Increment */
+#define MDMA2_S1_CURR_DESC_PTR 0xFFC00FE0 /*MemDMA2 Stream 1 Source Current Descriptor Ptr reg */
+#define MDMA2_S1_CURR_ADDR 0xFFC00FE4 /*MemDMA2 Stream 1 Source Current Address */
+#define MDMA2_S1_CURR_X_COUNT 0xFFC00FF0 /*MemDMA2 Stream 1 Source Current Inner-Loop Count */
+#define MDMA2_S1_CURR_Y_COUNT 0xFFC00FF8 /*MemDMA2 Stream 1 Source Current Outer-Loop Count */
+#define MDMA2_S1_IRQ_STATUS 0xFFC00FE8 /*MemDMA2 Stream 1 Source Interrupt/Status Register */
+#define MDMA2_S1_PERIPHERAL_MAP 0xFFC00FEC /*MemDMA2 Stream 1 Source Peripheral Map register */
+
+/* Internal Memory DMA Registers (0xFFC0_1800 - 0xFFC0_19FF) */
+#define IMDMA_D0_CONFIG 0xFFC01808 /*IMDMA Stream 0 Destination Configuration */
+#define IMDMA_D0_NEXT_DESC_PTR 0xFFC01800 /*IMDMA Stream 0 Destination Next Descriptor Ptr Reg */
+#define IMDMA_D0_START_ADDR 0xFFC01804 /*IMDMA Stream 0 Destination Start Address */
+#define IMDMA_D0_X_COUNT 0xFFC01810 /*IMDMA Stream 0 Destination Inner-Loop Count */
+#define IMDMA_D0_Y_COUNT 0xFFC01818 /*IMDMA Stream 0 Destination Outer-Loop Count */
+#define IMDMA_D0_X_MODIFY 0xFFC01814 /*IMDMA Stream 0 Dest Inner-Loop Address-Increment */
+#define IMDMA_D0_Y_MODIFY 0xFFC0181C /*IMDMA Stream 0 Dest Outer-Loop Address-Increment */
+#define IMDMA_D0_CURR_DESC_PTR 0xFFC01820 /*IMDMA Stream 0 Destination Current Descriptor Ptr */
+#define IMDMA_D0_CURR_ADDR 0xFFC01824 /*IMDMA Stream 0 Destination Current Address */
+#define IMDMA_D0_CURR_X_COUNT 0xFFC01830 /*IMDMA Stream 0 Destination Current Inner-Loop Count */
+#define IMDMA_D0_CURR_Y_COUNT 0xFFC01838 /*IMDMA Stream 0 Destination Current Outer-Loop Count */
+#define IMDMA_D0_IRQ_STATUS 0xFFC01828 /*IMDMA Stream 0 Destination Interrupt/Status */
+
+#define IMDMA_S0_CONFIG 0xFFC01848 /*IMDMA Stream 0 Source Configuration */
+#define IMDMA_S0_NEXT_DESC_PTR 0xFFC01840 /*IMDMA Stream 0 Source Next Descriptor Ptr Reg */
+#define IMDMA_S0_START_ADDR 0xFFC01844 /*IMDMA Stream 0 Source Start Address */
+#define IMDMA_S0_X_COUNT 0xFFC01850 /*IMDMA Stream 0 Source Inner-Loop Count */
+#define IMDMA_S0_Y_COUNT 0xFFC01858 /*IMDMA Stream 0 Source Outer-Loop Count */
+#define IMDMA_S0_X_MODIFY 0xFFC01854 /*IMDMA Stream 0 Source Inner-Loop Address-Increment */
+#define IMDMA_S0_Y_MODIFY 0xFFC0185C /*IMDMA Stream 0 Source Outer-Loop Address-Increment */
+#define IMDMA_S0_CURR_DESC_PTR 0xFFC01860 /*IMDMA Stream 0 Source Current Descriptor Ptr reg */
+#define IMDMA_S0_CURR_ADDR 0xFFC01864 /*IMDMA Stream 0 Source Current Address */
+#define IMDMA_S0_CURR_X_COUNT 0xFFC01870 /*IMDMA Stream 0 Source Current Inner-Loop Count */
+#define IMDMA_S0_CURR_Y_COUNT 0xFFC01878 /*IMDMA Stream 0 Source Current Outer-Loop Count */
+#define IMDMA_S0_IRQ_STATUS 0xFFC01868 /*IMDMA Stream 0 Source Interrupt/Status */
+
+#define IMDMA_D1_CONFIG 0xFFC01888 /*IMDMA Stream 1 Destination Configuration */
+#define IMDMA_D1_NEXT_DESC_PTR 0xFFC01880 /*IMDMA Stream 1 Destination Next Descriptor Ptr Reg */
+#define IMDMA_D1_START_ADDR 0xFFC01884 /*IMDMA Stream 1 Destination Start Address */
+#define IMDMA_D1_X_COUNT 0xFFC01890 /*IMDMA Stream 1 Destination Inner-Loop Count */
+#define IMDMA_D1_Y_COUNT 0xFFC01898 /*IMDMA Stream 1 Destination Outer-Loop Count */
+#define IMDMA_D1_X_MODIFY 0xFFC01894 /*IMDMA Stream 1 Dest Inner-Loop Address-Increment */
+#define IMDMA_D1_Y_MODIFY 0xFFC0189C /*IMDMA Stream 1 Dest Outer-Loop Address-Increment */
+#define IMDMA_D1_CURR_DESC_PTR 0xFFC018A0 /*IMDMA Stream 1 Destination Current Descriptor Ptr */
+#define IMDMA_D1_CURR_ADDR 0xFFC018A4 /*IMDMA Stream 1 Destination Current Address */
+#define IMDMA_D1_CURR_X_COUNT 0xFFC018B0 /*IMDMA Stream 1 Destination Current Inner-Loop Count */
+#define IMDMA_D1_CURR_Y_COUNT 0xFFC018B8 /*IMDMA Stream 1 Destination Current Outer-Loop Count */
+#define IMDMA_D1_IRQ_STATUS 0xFFC018A8 /*IMDMA Stream 1 Destination Interrupt/Status */
+
+#define IMDMA_S1_CONFIG 0xFFC018C8 /*IMDMA Stream 1 Source Configuration */
+#define IMDMA_S1_NEXT_DESC_PTR 0xFFC018C0 /*IMDMA Stream 1 Source Next Descriptor Ptr Reg */
+#define IMDMA_S1_START_ADDR 0xFFC018C4 /*IMDMA Stream 1 Source Start Address */
+#define IMDMA_S1_X_COUNT 0xFFC018D0 /*IMDMA Stream 1 Source Inner-Loop Count */
+#define IMDMA_S1_Y_COUNT 0xFFC018D8 /*IMDMA Stream 1 Source Outer-Loop Count */
+#define IMDMA_S1_X_MODIFY 0xFFC018D4 /*IMDMA Stream 1 Source Inner-Loop Address-Increment */
+#define IMDMA_S1_Y_MODIFY 0xFFC018DC /*IMDMA Stream 1 Source Outer-Loop Address-Increment */
+#define IMDMA_S1_CURR_DESC_PTR 0xFFC018E0 /*IMDMA Stream 1 Source Current Descriptor Ptr reg */
+#define IMDMA_S1_CURR_ADDR 0xFFC018E4 /*IMDMA Stream 1 Source Current Address */
+#define IMDMA_S1_CURR_X_COUNT 0xFFC018F0 /*IMDMA Stream 1 Source Current Inner-Loop Count */
+#define IMDMA_S1_CURR_Y_COUNT 0xFFC018F8 /*IMDMA Stream 1 Source Current Outer-Loop Count */
+#define IMDMA_S1_IRQ_STATUS 0xFFC018E8 /*IMDMA Stream 1 Source Interrupt/Status */
+
+/*********************************************************************************** */
+/* System MMR Register Bits */
+/******************************************************************************* */
+
+/* ********************* PLL AND RESET MASKS ************************ */
+
+/* PLL_CTL Masks */
+#define PLL_CLKIN 0x00000000 /* Pass CLKIN to PLL */
+#define PLL_CLKIN_DIV2 0x00000001 /* Pass CLKIN/2 to PLL */
+#define PLL_OFF 0x00000002 /* Shut off PLL clocks */
+#define STOPCK_OFF 0x00000008 /* Core clock off */
+#define PDWN 0x00000020 /* Put the PLL in a Deep Sleep state */
+#define BYPASS 0x00000100 /* Bypass the PLL */
+
+/* CHIPID Masks */
+#define CHIPID_VERSION 0xF0000000
+#define CHIPID_FAMILY 0x0FFFF000
+#define CHIPID_MANUFACTURE 0x00000FFE
+
+/* PLL_DIV Masks */
+#define SCLK_DIV(x) (x) /* SCLK = VCO / x */
+
+#define CCLK_DIV1 0x00000000 /* CCLK = VCO / 1 */
+#define CCLK_DIV2 0x00000010 /* CCLK = VCO / 2 */
+#define CCLK_DIV4 0x00000020 /* CCLK = VCO / 4 */
+#define CCLK_DIV8 0x00000030 /* CCLK = VCO / 8 */
+
+/* PLL_STAT Masks */
+#define ACTIVE_PLLENABLED 0x0001 /* Processor In Active Mode With PLL Enabled */
+#define FULL_ON 0x0002 /* Processor In Full On Mode */
+#define ACTIVE_PLLDISABLED 0x0004 /* Processor In Active Mode With PLL Disabled */
+#define PLL_LOCKED 0x0020 /* PLL_LOCKCNT Has Been Reached */
+
+/* SWRST Mask */
+#define SYSTEM_RESET 0x00000007 /* Initiates a system software reset */
+#define SWRST_DBL_FAULT_B 0x00000800 /* SWRST Core B Double Fault */
+#define SWRST_DBL_FAULT_A 0x00001000 /* SWRST Core A Double Fault */
+#define SWRST_WDT_B 0x00002000 /* SWRST Watchdog B */
+#define SWRST_WDT_A 0x00004000 /* SWRST Watchdog A */
+#define SWRST_OCCURRED 0x00008000 /* SWRST Status */
+
+/* ************* SYSTEM INTERRUPT CONTROLLER MASKS ***************** */
+
+/* SICu_IARv Masks */
+/* u = A or B */
+/* v = 0 to 7 */
+/* w = 0 or 1 */
+
+/* Per_number = 0 to 63 */
+/* IVG_number = 7 to 15 */
+#define Peripheral_IVG(Per_number, IVG_number) \
+ ((IVG_number) - 7) << (((Per_number) % 8) * 4) /* Peripheral #Per_number assigned IVG #IVG_number */
+ /* Usage: r0.l = lo(Peripheral_IVG(62, 10)); */
+ /* r0.h = hi(Peripheral_IVG(62, 10)); */
+
+/* SICx_IMASKw Masks */
+/* masks are 32 bit wide, so two writes reguired for "64 bit" wide registers */
+#define SIC_UNMASK_ALL 0x00000000 /* Unmask all peripheral interrupts */
+#define SIC_MASK_ALL 0xFFFFFFFF /* Mask all peripheral interrupts */
+#define SIC_MASK(x) (1 << (x)) /* Mask Peripheral #x interrupt */
+#define SIC_UNMASK(x) (0xFFFFFFFF ^ (1 << (x))) /* Unmask Peripheral #x interrupt */
+
+/* SIC_IWR Masks */
+#define IWR_DISABLE_ALL 0x00000000 /* Wakeup Disable all peripherals */
+#define IWR_ENABLE_ALL 0xFFFFFFFF /* Wakeup Enable all peripherals */
+/* x = pos 0 to 31, for 32-63 use value-32 */
+#define IWR_ENABLE(x) (1 << (x)) /* Wakeup Enable Peripheral #x */
+#define IWR_DISABLE(x) (0xFFFFFFFF ^ (1 << (x))) /* Wakeup Disable Peripheral #x */
+
+/* ********* WATCHDOG TIMER MASKS ********************8 */
+
+/* Watchdog Timer WDOG_CTL Register */
+#define ICTL(x) ((x<<1) & 0x0006)
+#define ENABLE_RESET 0x00000000 /* Set Watchdog Timer to generate reset */
+#define ENABLE_NMI 0x00000002 /* Set Watchdog Timer to generate non-maskable interrupt */
+#define ENABLE_GPI 0x00000004 /* Set Watchdog Timer to generate general-purpose interrupt */
+#define DISABLE_EVT 0x00000006 /* Disable Watchdog Timer interrupts */
+
+#define TMR_EN 0x0000
+#define TMR_DIS 0x0AD0
+#define TRO 0x8000
+
+#define ICTL_P0 0x01
+#define ICTL_P1 0x02
+#define TRO_P 0x0F
+
+/* ***************************** UART CONTROLLER MASKS ********************** */
+
+/* UART_LCR Register */
+
+#define DLAB 0x80
+#define SB 0x40
+#define STP 0x20
+#define EPS 0x10
+#define PEN 0x08
+#define STB 0x04
+#define WLS(x) ((x-5) & 0x03)
+
+#define DLAB_P 0x07
+#define SB_P 0x06
+#define STP_P 0x05
+#define EPS_P 0x04
+#define PEN_P 0x03
+#define STB_P 0x02
+#define WLS_P1 0x01
+#define WLS_P0 0x00
+
+/* UART_MCR Register */
+#define LOOP_ENA 0x10
+#define LOOP_ENA_P 0x04
+
+/* UART_LSR Register */
+#define TEMT 0x40
+#define THRE 0x20
+#define BI 0x10
+#define FE 0x08
+#define PE 0x04
+#define OE 0x02
+#define DR 0x01
+
+#define TEMP_P 0x06
+#define THRE_P 0x05
+#define BI_P 0x04
+#define FE_P 0x03
+#define PE_P 0x02
+#define OE_P 0x01
+#define DR_P 0x00
+
+/* UART_IER Register */
+#define ELSI 0x04
+#define ETBEI 0x02
+#define ERBFI 0x01
+
+#define ELSI_P 0x02
+#define ETBEI_P 0x01
+#define ERBFI_P 0x00
+
+/* UART_IIR Register */
+#define STATUS(x) ((x << 1) & 0x06)
+#define NINT 0x01
+#define STATUS_P1 0x02
+#define STATUS_P0 0x01
+#define NINT_P 0x00
+#define IIR_TX_READY 0x02 /* UART_THR empty */
+#define IIR_RX_READY 0x04 /* Receive data ready */
+#define IIR_LINE_CHANGE 0x06 /* Receive line status */
+#define IIR_STATUS 0x06
+
+/* UART_GCTL Register */
+#define FFE 0x20
+#define FPE 0x10
+#define RPOLC 0x08
+#define TPOLC 0x04
+#define IREN 0x02
+#define UCEN 0x01
+
+#define FFE_P 0x05
+#define FPE_P 0x04
+#define RPOLC_P 0x03
+#define TPOLC_P 0x02
+#define IREN_P 0x01
+#define UCEN_P 0x00
+
+/* ********** SERIAL PORT MASKS ********************** */
+
+/* SPORTx_TCR1 Masks */
+#define TSPEN 0x0001 /* TX enable */
+#define ITCLK 0x0002 /* Internal TX Clock Select */
+#define TDTYPE 0x000C /* TX Data Formatting Select */
+#define TLSBIT 0x0010 /* TX Bit Order */
+#define ITFS 0x0200 /* Internal TX Frame Sync Select */
+#define TFSR 0x0400 /* TX Frame Sync Required Select */
+#define DITFS 0x0800 /* Data Independent TX Frame Sync Select */
+#define LTFS 0x1000 /* Low TX Frame Sync Select */
+#define LATFS 0x2000 /* Late TX Frame Sync Select */
+#define TCKFE 0x4000 /* TX Clock Falling Edge Select */
+
+/* SPORTx_TCR2 Masks */
+#define SLEN 0x001F /*TX Word Length */
+#define TXSE 0x0100 /*TX Secondary Enable */
+#define TSFSE 0x0200 /*TX Stereo Frame Sync Enable */
+#define TRFST 0x0400 /*TX Right-First Data Order */
+
+/* SPORTx_RCR1 Masks */
+#define RSPEN 0x0001 /* RX enable */
+#define IRCLK 0x0002 /* Internal RX Clock Select */
+#define RDTYPE 0x000C /* RX Data Formatting Select */
+#define RULAW 0x0008 /* u-Law enable */
+#define RALAW 0x000C /* A-Law enable */
+#define RLSBIT 0x0010 /* RX Bit Order */
+#define IRFS 0x0200 /* Internal RX Frame Sync Select */
+#define RFSR 0x0400 /* RX Frame Sync Required Select */
+#define LRFS 0x1000 /* Low RX Frame Sync Select */
+#define LARFS 0x2000 /* Late RX Frame Sync Select */
+#define RCKFE 0x4000 /* RX Clock Falling Edge Select */
+
+/* SPORTx_RCR2 Masks */
+#define SLEN 0x001F /*RX Word Length */
+#define RXSE 0x0100 /*RX Secondary Enable */
+#define RSFSE 0x0200 /*RX Stereo Frame Sync Enable */
+#define RRFST 0x0400 /*Right-First Data Order */
+
+/*SPORTx_STAT Masks */
+#define RXNE 0x0001 /*RX FIFO Not Empty Status */
+#define RUVF 0x0002 /*RX Underflow Status */
+#define ROVF 0x0004 /*RX Overflow Status */
+#define TXF 0x0008 /*TX FIFO Full Status */
+#define TUVF 0x0010 /*TX Underflow Status */
+#define TOVF 0x0020 /*TX Overflow Status */
+#define TXHRE 0x0040 /*TX Hold Register Empty */
+
+/*SPORTx_MCMC1 Masks */
+#define SP_WSIZE 0x0000F000 /*Multichannel Window Size Field */
+#define SP_WOFF 0x000003FF /*Multichannel Window Offset Field */
+
+/*SPORTx_MCMC2 Masks */
+#define MCCRM 0x00000003 /*Multichannel Clock Recovery Mode */
+#define MCDTXPE 0x00000004 /*Multichannel DMA Transmit Packing */
+#define MCDRXPE 0x00000008 /*Multichannel DMA Receive Packing */
+#define MCMEN 0x00000010 /*Multichannel Frame Mode Enable */
+#define FSDR 0x00000080 /*Multichannel Frame Sync to Data Relationship */
+#define MFD 0x0000F000 /*Multichannel Frame Delay */
+
+/* ********* PARALLEL PERIPHERAL INTERFACE (PPI) MASKS **************** */
+
+/* PPI_CONTROL Masks */
+#define PORT_EN 0x00000001 /* PPI Port Enable */
+#define PORT_DIR 0x00000002 /* PPI Port Direction */
+#define XFR_TYPE 0x0000000C /* PPI Transfer Type */
+#define PORT_CFG 0x00000030 /* PPI Port Configuration */
+#define FLD_SEL 0x00000040 /* PPI Active Field Select */
+#define PACK_EN 0x00000080 /* PPI Packing Mode */
+#define DMA32 0x00000100 /* PPI 32-bit DMA Enable */
+#define SKIP_EN 0x00000200 /* PPI Skip Element Enable */
+#define SKIP_EO 0x00000400 /* PPI Skip Even/Odd Elements */
+#define DLENGTH 0x00003800 /* PPI Data Length */
+#define DLEN_8 0x0 /* PPI Data Length mask for DLEN=8 */
+#define DLEN(x) (((x-9) & 0x07) << 11) /* PPI Data Length (only works for x=10-->x=16) */
+#define POL 0x0000C000 /* PPI Signal Polarities */
+
+/* PPI_STATUS Masks */
+#define FLD 0x00000400 /* Field Indicator */
+#define FT_ERR 0x00000800 /* Frame Track Error */
+#define OVR 0x00001000 /* FIFO Overflow Error */
+#define UNDR 0x00002000 /* FIFO Underrun Error */
+#define ERR_DET 0x00004000 /* Error Detected Indicator */
+#define ERR_NCOR 0x00008000 /* Error Not Corrected Indicator */
+
+/* ********** DMA CONTROLLER MASKS *********************8 */
+
+/* DMAx_CONFIG, MDMA_yy_CONFIG, IMDMA_yy_CONFIG Masks */
+#define DMAEN 0x00000001 /* Channel Enable */
+#define WNR 0x00000002 /* Channel Direction (W/R*) */
+#define WDSIZE_8 0x00000000 /* Word Size 8 bits */
+#define WDSIZE_16 0x00000004 /* Word Size 16 bits */
+#define WDSIZE_32 0x00000008 /* Word Size 32 bits */
+#define DMA2D 0x00000010 /* 2D/1D* Mode */
+#define RESTART 0x00000020 /* Restart */
+#define DI_SEL 0x00000040 /* Data Interrupt Select */
+#define DI_EN 0x00000080 /* Data Interrupt Enable */
+#define NDSIZE_0 0x0000 /* Next Descriptor Size = 0 (Stop/Autobuffer) */
+#define NDSIZE_1 0x0100 /* Next Descriptor Size = 1 */
+#define NDSIZE_2 0x0200 /* Next Descriptor Size = 2 */
+#define NDSIZE_3 0x0300 /* Next Descriptor Size = 3 */
+#define NDSIZE_4 0x0400 /* Next Descriptor Size = 4 */
+#define NDSIZE_5 0x0500 /* Next Descriptor Size = 5 */
+#define NDSIZE_6 0x0600 /* Next Descriptor Size = 6 */
+#define NDSIZE_7 0x0700 /* Next Descriptor Size = 7 */
+#define NDSIZE_8 0x0800 /* Next Descriptor Size = 8 */
+#define NDSIZE_9 0x0900 /* Next Descriptor Size = 9 */
+#define NDSIZE 0x00000900 /* Next Descriptor Size */
+#define DMAFLOW 0x00007000 /* Flow Control */
+#define DMAFLOW_STOP 0x0000 /* Stop Mode */
+#define DMAFLOW_AUTO 0x1000 /* Autobuffer Mode */
+#define DMAFLOW_ARRAY 0x4000 /* Descriptor Array Mode */
+#define DMAFLOW_SMALL 0x6000 /* Small Model Descriptor List Mode */
+#define DMAFLOW_LARGE 0x7000 /* Large Model Descriptor List Mode */
+
+#define DMAEN_P 0 /* Channel Enable */
+#define WNR_P 1 /* Channel Direction (W/R*) */
+#define DMA2D_P 4 /* 2D/1D* Mode */
+#define RESTART_P 5 /* Restart */
+#define DI_SEL_P 6 /* Data Interrupt Select */
+#define DI_EN_P 7 /* Data Interrupt Enable */
+
+/* DMAx_IRQ_STATUS, MDMA_yy_IRQ_STATUS, IMDMA_yy_IRQ_STATUS Masks */
+
+#define DMA_DONE 0x00000001 /* DMA Done Indicator */
+#define DMA_ERR 0x00000002 /* DMA Error Indicator */
+#define DFETCH 0x00000004 /* Descriptor Fetch Indicator */
+#define DMA_RUN 0x00000008 /* DMA Running Indicator */
+
+#define DMA_DONE_P 0 /* DMA Done Indicator */
+#define DMA_ERR_P 1 /* DMA Error Indicator */
+#define DFETCH_P 2 /* Descriptor Fetch Indicator */
+#define DMA_RUN_P 3 /* DMA Running Indicator */
+
+/* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP, IMDMA_yy_PERIPHERAL_MAP Masks */
+
+#define CTYPE 0x00000040 /* DMA Channel Type Indicator */
+#define CTYPE_P 6 /* DMA Channel Type Indicator BIT POSITION */
+#define PCAP8 0x00000080 /* DMA 8-bit Operation Indicator */
+#define PCAP16 0x00000100 /* DMA 16-bit Operation Indicator */
+#define PCAP32 0x00000200 /* DMA 32-bit Operation Indicator */
+#define PCAPWR 0x00000400 /* DMA Write Operation Indicator */
+#define PCAPRD 0x00000800 /* DMA Read Operation Indicator */
+#define PMAP 0x00007000 /* DMA Peripheral Map Field */
+
+/* ************* GENERAL PURPOSE TIMER MASKS ******************** */
+
+/* PWM Timer bit definitions */
+
+/* TIMER_ENABLE Register */
+#define TIMEN0 0x0001
+#define TIMEN1 0x0002
+#define TIMEN2 0x0004
+#define TIMEN3 0x0008
+#define TIMEN4 0x0010
+#define TIMEN5 0x0020
+#define TIMEN6 0x0040
+#define TIMEN7 0x0080
+#define TIMEN8 0x0001
+#define TIMEN9 0x0002
+#define TIMEN10 0x0004
+#define TIMEN11 0x0008
+
+#define TIMEN0_P 0x00
+#define TIMEN1_P 0x01
+#define TIMEN2_P 0x02
+#define TIMEN3_P 0x03
+#define TIMEN4_P 0x04
+#define TIMEN5_P 0x05
+#define TIMEN6_P 0x06
+#define TIMEN7_P 0x07
+#define TIMEN8_P 0x00
+#define TIMEN9_P 0x01
+#define TIMEN10_P 0x02
+#define TIMEN11_P 0x03
+
+/* TIMER_DISABLE Register */
+#define TIMDIS0 0x0001
+#define TIMDIS1 0x0002
+#define TIMDIS2 0x0004
+#define TIMDIS3 0x0008
+#define TIMDIS4 0x0010
+#define TIMDIS5 0x0020
+#define TIMDIS6 0x0040
+#define TIMDIS7 0x0080
+#define TIMDIS8 0x0001
+#define TIMDIS9 0x0002
+#define TIMDIS10 0x0004
+#define TIMDIS11 0x0008
+
+#define TIMDIS0_P 0x00
+#define TIMDIS1_P 0x01
+#define TIMDIS2_P 0x02
+#define TIMDIS3_P 0x03
+#define TIMDIS4_P 0x04
+#define TIMDIS5_P 0x05
+#define TIMDIS6_P 0x06
+#define TIMDIS7_P 0x07
+#define TIMDIS8_P 0x00
+#define TIMDIS9_P 0x01
+#define TIMDIS10_P 0x02
+#define TIMDIS11_P 0x03
+
+/* TIMER_STATUS Register */
+#define TIMIL0 0x00000001
+#define TIMIL1 0x00000002
+#define TIMIL2 0x00000004
+#define TIMIL3 0x00000008
+#define TIMIL4 0x00010000
+#define TIMIL5 0x00020000
+#define TIMIL6 0x00040000
+#define TIMIL7 0x00080000
+#define TIMIL8 0x0001
+#define TIMIL9 0x0002
+#define TIMIL10 0x0004
+#define TIMIL11 0x0008
+#define TOVL_ERR0 0x00000010
+#define TOVL_ERR1 0x00000020
+#define TOVL_ERR2 0x00000040
+#define TOVL_ERR3 0x00000080
+#define TOVL_ERR4 0x00100000
+#define TOVL_ERR5 0x00200000
+#define TOVL_ERR6 0x00400000
+#define TOVL_ERR7 0x00800000
+#define TOVL_ERR8 0x0010
+#define TOVL_ERR9 0x0020
+#define TOVL_ERR10 0x0040
+#define TOVL_ERR11 0x0080
+#define TRUN0 0x00001000
+#define TRUN1 0x00002000
+#define TRUN2 0x00004000
+#define TRUN3 0x00008000
+#define TRUN4 0x10000000
+#define TRUN5 0x20000000
+#define TRUN6 0x40000000
+#define TRUN7 0x80000000
+#define TRUN8 0x1000
+#define TRUN9 0x2000
+#define TRUN10 0x4000
+#define TRUN11 0x8000
+
+#define TIMIL0_P 0x00
+#define TIMIL1_P 0x01
+#define TIMIL2_P 0x02
+#define TIMIL3_P 0x03
+#define TIMIL4_P 0x10
+#define TIMIL5_P 0x11
+#define TIMIL6_P 0x12
+#define TIMIL7_P 0x13
+#define TIMIL8_P 0x00
+#define TIMIL9_P 0x01
+#define TIMIL10_P 0x02
+#define TIMIL11_P 0x03
+#define TOVL_ERR0_P 0x04
+#define TOVL_ERR1_P 0x05
+#define TOVL_ERR2_P 0x06
+#define TOVL_ERR3_P 0x07
+#define TOVL_ERR4_P 0x14
+#define TOVL_ERR5_P 0x15
+#define TOVL_ERR6_P 0x16
+#define TOVL_ERR7_P 0x17
+#define TOVL_ERR8_P 0x04
+#define TOVL_ERR9_P 0x05
+#define TOVL_ERR10_P 0x06
+#define TOVL_ERR11_P 0x07
+#define TRUN0_P 0x0C
+#define TRUN1_P 0x0D
+#define TRUN2_P 0x0E
+#define TRUN3_P 0x0F
+#define TRUN4_P 0x1C
+#define TRUN5_P 0x1D
+#define TRUN6_P 0x1E
+#define TRUN7_P 0x1F
+#define TRUN8_P 0x0C
+#define TRUN9_P 0x0D
+#define TRUN10_P 0x0E
+#define TRUN11_P 0x0F
+
+/* TIMERx_CONFIG Registers */
+#define PWM_OUT 0x0001
+#define WDTH_CAP 0x0002
+#define EXT_CLK 0x0003
+#define PULSE_HI 0x0004
+#define PERIOD_CNT 0x0008
+#define IRQ_ENA 0x0010
+#define TIN_SEL 0x0020
+#define OUT_DIS 0x0040
+#define CLK_SEL 0x0080
+#define TOGGLE_HI 0x0100
+#define EMU_RUN 0x0200
+#define ERR_TYP(x) ((x & 0x03) << 14)
+
+#define TMODE_P0 0x00
+#define TMODE_P1 0x01
+#define PULSE_HI_P 0x02
+#define PERIOD_CNT_P 0x03
+#define IRQ_ENA_P 0x04
+#define TIN_SEL_P 0x05
+#define OUT_DIS_P 0x06
+#define CLK_SEL_P 0x07
+#define TOGGLE_HI_P 0x08
+#define EMU_RUN_P 0x09
+#define ERR_TYP_P0 0x0E
+#define ERR_TYP_P1 0x0F
+
+/*/ ****************** PROGRAMMABLE FLAG MASKS ********************* */
+
+/* General Purpose IO (0xFFC00700 - 0xFFC007FF) Masks */
+#define PF0 0x0001
+#define PF1 0x0002
+#define PF2 0x0004
+#define PF3 0x0008
+#define PF4 0x0010
+#define PF5 0x0020
+#define PF6 0x0040
+#define PF7 0x0080
+#define PF8 0x0100
+#define PF9 0x0200
+#define PF10 0x0400
+#define PF11 0x0800
+#define PF12 0x1000
+#define PF13 0x2000
+#define PF14 0x4000
+#define PF15 0x8000
+
+/* General Purpose IO (0xFFC00700 - 0xFFC007FF) BIT POSITIONS */
+#define PF0_P 0
+#define PF1_P 1
+#define PF2_P 2
+#define PF3_P 3
+#define PF4_P 4
+#define PF5_P 5
+#define PF6_P 6
+#define PF7_P 7
+#define PF8_P 8
+#define PF9_P 9
+#define PF10_P 10
+#define PF11_P 11
+#define PF12_P 12
+#define PF13_P 13
+#define PF14_P 14
+#define PF15_P 15
+
+/* *********** SERIAL PERIPHERAL INTERFACE (SPI) MASKS **************** */
+
+/* SPI_CTL Masks */
+#define TIMOD 0x00000003 /* Transfer initiation mode and interrupt generation */
+#define SZ 0x00000004 /* Send Zero (=0) or last (=1) word when TDBR empty. */
+#define GM 0x00000008 /* When RDBR full, get more (=1) data or discard (=0) incoming Data */
+#define PSSE 0x00000010 /* Enable (=1) Slave-Select input for Master. */
+#define EMISO 0x00000020 /* Enable (=1) MISO pin as an output. */
+#define SIZE 0x00000100 /* Word length (0 => 8 bits, 1 => 16 bits) */
+#define LSBF 0x00000200 /* Data format (0 => MSB sent/received first 1 => LSB sent/received first) */
+#define CPHA 0x00000400 /* Clock phase (0 => SPICLK starts toggling in middle of xfer, 1 => SPICLK toggles at the beginning of xfer. */
+#define CPOL 0x00000800 /* Clock polarity (0 => active-high, 1 => active-low) */
+#define MSTR 0x00001000 /* Configures SPI as master (=1) or slave (=0) */
+#define WOM 0x00002000 /* Open drain (=1) data output enable (for MOSI and MISO) */
+#define SPE 0x00004000 /* SPI module enable (=1), disable (=0) */
+
+/* SPI_FLG Masks */
+#define FLS1 0x00000002 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */
+#define FLS2 0x00000004 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */
+#define FLS3 0x00000008 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */
+#define FLS4 0x00000010 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */
+#define FLS5 0x00000020 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */
+#define FLS6 0x00000040 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */
+#define FLS7 0x00000080 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */
+#define FLG1 0x00000200 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */
+#define FLG2 0x00000400 /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */
+#define FLG3 0x00000800 /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */
+#define FLG4 0x00001000 /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */
+#define FLG5 0x00002000 /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */
+#define FLG6 0x00004000 /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */
+#define FLG7 0x00008000 /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */
+
+/* SPI_FLG Bit Positions */
+#define FLS1_P 0x00000001 /* Enables (=1) SPI_FLOUT1 as flag output for SPI Slave-select */
+#define FLS2_P 0x00000002 /* Enables (=1) SPI_FLOUT2 as flag output for SPI Slave-select */
+#define FLS3_P 0x00000003 /* Enables (=1) SPI_FLOUT3 as flag output for SPI Slave-select */
+#define FLS4_P 0x00000004 /* Enables (=1) SPI_FLOUT4 as flag output for SPI Slave-select */
+#define FLS5_P 0x00000005 /* Enables (=1) SPI_FLOUT5 as flag output for SPI Slave-select */
+#define FLS6_P 0x00000006 /* Enables (=1) SPI_FLOUT6 as flag output for SPI Slave-select */
+#define FLS7_P 0x00000007 /* Enables (=1) SPI_FLOUT7 as flag output for SPI Slave-select */
+#define FLG1_P 0x00000009 /* Activates (=0) SPI_FLOUT1 as flag output for SPI Slave-select */
+#define FLG2_P 0x0000000A /* Activates (=0) SPI_FLOUT2 as flag output for SPI Slave-select */
+#define FLG3_P 0x0000000B /* Activates (=0) SPI_FLOUT3 as flag output for SPI Slave-select */
+#define FLG4_P 0x0000000C /* Activates (=0) SPI_FLOUT4 as flag output for SPI Slave-select */
+#define FLG5_P 0x0000000D /* Activates (=0) SPI_FLOUT5 as flag output for SPI Slave-select */
+#define FLG6_P 0x0000000E /* Activates (=0) SPI_FLOUT6 as flag output for SPI Slave-select */
+#define FLG7_P 0x0000000F /* Activates (=0) SPI_FLOUT7 as flag output for SPI Slave-select */
+
+/* SPI_STAT Masks */
+#define SPIF 0x00000001 /* Set (=1) when SPI single-word transfer complete */
+#define MODF 0x00000002 /* Set (=1) in a master device when some other device tries to become master */
+#define TXE 0x00000004 /* Set (=1) when transmission occurs with no new data in SPI_TDBR */
+#define TXS 0x00000008 /* SPI_TDBR Data Buffer Status (0=Empty, 1=Full) */
+#define RBSY 0x00000010 /* Set (=1) when data is received with RDBR full */
+#define RXS 0x00000020 /* SPI_RDBR Data Buffer Status (0=Empty, 1=Full) */
+#define TXCOL 0x00000040 /* When set (=1), corrupt data may have been transmitted */
+
+/* ********************* ASYNCHRONOUS MEMORY CONTROLLER MASKS ************* */
+
+/* AMGCTL Masks */
+#define AMCKEN 0x0001 /* Enable CLKOUT */
+#define AMBEN_B0 0x0002 /* Enable Asynchronous Memory Bank 0 only */
+#define AMBEN_B0_B1 0x0004 /* Enable Asynchronous Memory Banks 0 & 1 only */
+#define AMBEN_B0_B1_B2 0x0006 /* Enable Asynchronous Memory Banks 0, 1, and 2 */
+#define AMBEN_ALL 0x0008 /* Enable Asynchronous Memory Banks (all) 0, 1, 2, and 3 */
+#define B0_PEN 0x0010 /* Enable 16-bit packing Bank 0 */
+#define B1_PEN 0x0020 /* Enable 16-bit packing Bank 1 */
+#define B2_PEN 0x0040 /* Enable 16-bit packing Bank 2 */
+#define B3_PEN 0x0080 /* Enable 16-bit packing Bank 3 */
+
+/* AMGCTL Bit Positions */
+#define AMCKEN_P 0x00000000 /* Enable CLKOUT */
+#define AMBEN_P0 0x00000001 /* Asynchronous Memory Enable, 000 - banks 0-3 disabled, 001 - Bank 0 enabled */
+#define AMBEN_P1 0x00000002 /* Asynchronous Memory Enable, 010 - banks 0&1 enabled, 011 - banks 0-3 enabled */
+#define AMBEN_P2 0x00000003 /* Asynchronous Memory Enable, 1xx - All banks (bank 0, 1, 2, and 3) enabled */
+#define B0_PEN_P 0x004 /* Enable 16-bit packing Bank 0 */
+#define B1_PEN_P 0x005 /* Enable 16-bit packing Bank 1 */
+#define B2_PEN_P 0x006 /* Enable 16-bit packing Bank 2 */
+#define B3_PEN_P 0x007 /* Enable 16-bit packing Bank 3 */
+
+/* AMBCTL0 Masks */
+#define B0RDYEN 0x00000001 /* Bank 0 RDY Enable, 0=disable, 1=enable */
+#define B0RDYPOL 0x00000002 /* Bank 0 RDY Active high, 0=active low, 1=active high */
+#define B0TT_1 0x00000004 /* Bank 0 Transition Time from Read to Write = 1 cycle */
+#define B0TT_2 0x00000008 /* Bank 0 Transition Time from Read to Write = 2 cycles */
+#define B0TT_3 0x0000000C /* Bank 0 Transition Time from Read to Write = 3 cycles */
+#define B0TT_4 0x00000000 /* Bank 0 Transition Time from Read to Write = 4 cycles */
+#define B0ST_1 0x00000010 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=1 cycle */
+#define B0ST_2 0x00000020 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=2 cycles */
+#define B0ST_3 0x00000030 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=3 cycles */
+#define B0ST_4 0x00000000 /* Bank 0 Setup Time from AOE asserted to Read/Write asserted=4 cycles */
+#define B0HT_1 0x00000040 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 1 cycle */
+#define B0HT_2 0x00000080 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 2 cycles */
+#define B0HT_3 0x000000C0 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 3 cycles */
+#define B0HT_0 0x00000000 /* Bank 0 Hold Time from Read/Write deasserted to AOE deasserted = 0 cycles */
+#define B0RAT_1 0x00000100 /* Bank 0 Read Access Time = 1 cycle */
+#define B0RAT_2 0x00000200 /* Bank 0 Read Access Time = 2 cycles */
+#define B0RAT_3 0x00000300 /* Bank 0 Read Access Time = 3 cycles */
+#define B0RAT_4 0x00000400 /* Bank 0 Read Access Time = 4 cycles */
+#define B0RAT_5 0x00000500 /* Bank 0 Read Access Time = 5 cycles */
+#define B0RAT_6 0x00000600 /* Bank 0 Read Access Time = 6 cycles */
+#define B0RAT_7 0x00000700 /* Bank 0 Read Access Time = 7 cycles */
+#define B0RAT_8 0x00000800 /* Bank 0 Read Access Time = 8 cycles */
+#define B0RAT_9 0x00000900 /* Bank 0 Read Access Time = 9 cycles */
+#define B0RAT_10 0x00000A00 /* Bank 0 Read Access Time = 10 cycles */
+#define B0RAT_11 0x00000B00 /* Bank 0 Read Access Time = 11 cycles */
+#define B0RAT_12 0x00000C00 /* Bank 0 Read Access Time = 12 cycles */
+#define B0RAT_13 0x00000D00 /* Bank 0 Read Access Time = 13 cycles */
+#define B0RAT_14 0x00000E00 /* Bank 0 Read Access Time = 14 cycles */
+#define B0RAT_15 0x00000F00 /* Bank 0 Read Access Time = 15 cycles */
+#define B0WAT_1 0x00001000 /* Bank 0 Write Access Time = 1 cycle */
+#define B0WAT_2 0x00002000 /* Bank 0 Write Access Time = 2 cycles */
+#define B0WAT_3 0x00003000 /* Bank 0 Write Access Time = 3 cycles */
+#define B0WAT_4 0x00004000 /* Bank 0 Write Access Time = 4 cycles */
+#define B0WAT_5 0x00005000 /* Bank 0 Write Access Time = 5 cycles */
+#define B0WAT_6 0x00006000 /* Bank 0 Write Access Time = 6 cycles */
+#define B0WAT_7 0x00007000 /* Bank 0 Write Access Time = 7 cycles */
+#define B0WAT_8 0x00008000 /* Bank 0 Write Access Time = 8 cycles */
+#define B0WAT_9 0x00009000 /* Bank 0 Write Access Time = 9 cycles */
+#define B0WAT_10 0x0000A000 /* Bank 0 Write Access Time = 10 cycles */
+#define B0WAT_11 0x0000B000 /* Bank 0 Write Access Time = 11 cycles */
+#define B0WAT_12 0x0000C000 /* Bank 0 Write Access Time = 12 cycles */
+#define B0WAT_13 0x0000D000 /* Bank 0 Write Access Time = 13 cycles */
+#define B0WAT_14 0x0000E000 /* Bank 0 Write Access Time = 14 cycles */
+#define B0WAT_15 0x0000F000 /* Bank 0 Write Access Time = 15 cycles */
+#define B1RDYEN 0x00010000 /* Bank 1 RDY enable, 0=disable, 1=enable */
+#define B1RDYPOL 0x00020000 /* Bank 1 RDY Active high, 0=active low, 1=active high */
+#define B1TT_1 0x00040000 /* Bank 1 Transition Time from Read to Write = 1 cycle */
+#define B1TT_2 0x00080000 /* Bank 1 Transition Time from Read to Write = 2 cycles */
+#define B1TT_3 0x000C0000 /* Bank 1 Transition Time from Read to Write = 3 cycles */
+#define B1TT_4 0x00000000 /* Bank 1 Transition Time from Read to Write = 4 cycles */
+#define B1ST_1 0x00100000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */
+#define B1ST_2 0x00200000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */
+#define B1ST_3 0x00300000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */
+#define B1ST_4 0x00000000 /* Bank 1 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */
+#define B1HT_1 0x00400000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */
+#define B1HT_2 0x00800000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */
+#define B1HT_3 0x00C00000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */
+#define B1HT_0 0x00000000 /* Bank 1 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */
+#define B1RAT_1 0x01000000 /* Bank 1 Read Access Time = 1 cycle */
+#define B1RAT_2 0x02000000 /* Bank 1 Read Access Time = 2 cycles */
+#define B1RAT_3 0x03000000 /* Bank 1 Read Access Time = 3 cycles */
+#define B1RAT_4 0x04000000 /* Bank 1 Read Access Time = 4 cycles */
+#define B1RAT_5 0x05000000 /* Bank 1 Read Access Time = 5 cycles */
+#define B1RAT_6 0x06000000 /* Bank 1 Read Access Time = 6 cycles */
+#define B1RAT_7 0x07000000 /* Bank 1 Read Access Time = 7 cycles */
+#define B1RAT_8 0x08000000 /* Bank 1 Read Access Time = 8 cycles */
+#define B1RAT_9 0x09000000 /* Bank 1 Read Access Time = 9 cycles */
+#define B1RAT_10 0x0A000000 /* Bank 1 Read Access Time = 10 cycles */
+#define B1RAT_11 0x0B000000 /* Bank 1 Read Access Time = 11 cycles */
+#define B1RAT_12 0x0C000000 /* Bank 1 Read Access Time = 12 cycles */
+#define B1RAT_13 0x0D000000 /* Bank 1 Read Access Time = 13 cycles */
+#define B1RAT_14 0x0E000000 /* Bank 1 Read Access Time = 14 cycles */
+#define B1RAT_15 0x0F000000 /* Bank 1 Read Access Time = 15 cycles */
+#define B1WAT_1 0x10000000 /* Bank 1 Write Access Time = 1 cycle */
+#define B1WAT_2 0x20000000 /* Bank 1 Write Access Time = 2 cycles */
+#define B1WAT_3 0x30000000 /* Bank 1 Write Access Time = 3 cycles */
+#define B1WAT_4 0x40000000 /* Bank 1 Write Access Time = 4 cycles */
+#define B1WAT_5 0x50000000 /* Bank 1 Write Access Time = 5 cycles */
+#define B1WAT_6 0x60000000 /* Bank 1 Write Access Time = 6 cycles */
+#define B1WAT_7 0x70000000 /* Bank 1 Write Access Time = 7 cycles */
+#define B1WAT_8 0x80000000 /* Bank 1 Write Access Time = 8 cycles */
+#define B1WAT_9 0x90000000 /* Bank 1 Write Access Time = 9 cycles */
+#define B1WAT_10 0xA0000000 /* Bank 1 Write Access Time = 10 cycles */
+#define B1WAT_11 0xB0000000 /* Bank 1 Write Access Time = 11 cycles */
+#define B1WAT_12 0xC0000000 /* Bank 1 Write Access Time = 12 cycles */
+#define B1WAT_13 0xD0000000 /* Bank 1 Write Access Time = 13 cycles */
+#define B1WAT_14 0xE0000000 /* Bank 1 Write Access Time = 14 cycles */
+#define B1WAT_15 0xF0000000 /* Bank 1 Write Access Time = 15 cycles */
+
+/* AMBCTL1 Masks */
+#define B2RDYEN 0x00000001 /* Bank 2 RDY Enable, 0=disable, 1=enable */
+#define B2RDYPOL 0x00000002 /* Bank 2 RDY Active high, 0=active low, 1=active high */
+#define B2TT_1 0x00000004 /* Bank 2 Transition Time from Read to Write = 1 cycle */
+#define B2TT_2 0x00000008 /* Bank 2 Transition Time from Read to Write = 2 cycles */
+#define B2TT_3 0x0000000C /* Bank 2 Transition Time from Read to Write = 3 cycles */
+#define B2TT_4 0x00000000 /* Bank 2 Transition Time from Read to Write = 4 cycles */
+#define B2ST_1 0x00000010 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */
+#define B2ST_2 0x00000020 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */
+#define B2ST_3 0x00000030 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */
+#define B2ST_4 0x00000000 /* Bank 2 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */
+#define B2HT_1 0x00000040 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */
+#define B2HT_2 0x00000080 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */
+#define B2HT_3 0x000000C0 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */
+#define B2HT_0 0x00000000 /* Bank 2 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */
+#define B2RAT_1 0x00000100 /* Bank 2 Read Access Time = 1 cycle */
+#define B2RAT_2 0x00000200 /* Bank 2 Read Access Time = 2 cycles */
+#define B2RAT_3 0x00000300 /* Bank 2 Read Access Time = 3 cycles */
+#define B2RAT_4 0x00000400 /* Bank 2 Read Access Time = 4 cycles */
+#define B2RAT_5 0x00000500 /* Bank 2 Read Access Time = 5 cycles */
+#define B2RAT_6 0x00000600 /* Bank 2 Read Access Time = 6 cycles */
+#define B2RAT_7 0x00000700 /* Bank 2 Read Access Time = 7 cycles */
+#define B2RAT_8 0x00000800 /* Bank 2 Read Access Time = 8 cycles */
+#define B2RAT_9 0x00000900 /* Bank 2 Read Access Time = 9 cycles */
+#define B2RAT_10 0x00000A00 /* Bank 2 Read Access Time = 10 cycles */
+#define B2RAT_11 0x00000B00 /* Bank 2 Read Access Time = 11 cycles */
+#define B2RAT_12 0x00000C00 /* Bank 2 Read Access Time = 12 cycles */
+#define B2RAT_13 0x00000D00 /* Bank 2 Read Access Time = 13 cycles */
+#define B2RAT_14 0x00000E00 /* Bank 2 Read Access Time = 14 cycles */
+#define B2RAT_15 0x00000F00 /* Bank 2 Read Access Time = 15 cycles */
+#define B2WAT_1 0x00001000 /* Bank 2 Write Access Time = 1 cycle */
+#define B2WAT_2 0x00002000 /* Bank 2 Write Access Time = 2 cycles */
+#define B2WAT_3 0x00003000 /* Bank 2 Write Access Time = 3 cycles */
+#define B2WAT_4 0x00004000 /* Bank 2 Write Access Time = 4 cycles */
+#define B2WAT_5 0x00005000 /* Bank 2 Write Access Time = 5 cycles */
+#define B2WAT_6 0x00006000 /* Bank 2 Write Access Time = 6 cycles */
+#define B2WAT_7 0x00007000 /* Bank 2 Write Access Time = 7 cycles */
+#define B2WAT_8 0x00008000 /* Bank 2 Write Access Time = 8 cycles */
+#define B2WAT_9 0x00009000 /* Bank 2 Write Access Time = 9 cycles */
+#define B2WAT_10 0x0000A000 /* Bank 2 Write Access Time = 10 cycles */
+#define B2WAT_11 0x0000B000 /* Bank 2 Write Access Time = 11 cycles */
+#define B2WAT_12 0x0000C000 /* Bank 2 Write Access Time = 12 cycles */
+#define B2WAT_13 0x0000D000 /* Bank 2 Write Access Time = 13 cycles */
+#define B2WAT_14 0x0000E000 /* Bank 2 Write Access Time = 14 cycles */
+#define B2WAT_15 0x0000F000 /* Bank 2 Write Access Time = 15 cycles */
+#define B3RDYEN 0x00010000 /* Bank 3 RDY enable, 0=disable, 1=enable */
+#define B3RDYPOL 0x00020000 /* Bank 3 RDY Active high, 0=active low, 1=active high */
+#define B3TT_1 0x00040000 /* Bank 3 Transition Time from Read to Write = 1 cycle */
+#define B3TT_2 0x00080000 /* Bank 3 Transition Time from Read to Write = 2 cycles */
+#define B3TT_3 0x000C0000 /* Bank 3 Transition Time from Read to Write = 3 cycles */
+#define B3TT_4 0x00000000 /* Bank 3 Transition Time from Read to Write = 4 cycles */
+#define B3ST_1 0x00100000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 1 cycle */
+#define B3ST_2 0x00200000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 2 cycles */
+#define B3ST_3 0x00300000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 3 cycles */
+#define B3ST_4 0x00000000 /* Bank 3 Setup Time from AOE asserted to Read or Write asserted = 4 cycles */
+#define B3HT_1 0x00400000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 1 cycle */
+#define B3HT_2 0x00800000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 2 cycles */
+#define B3HT_3 0x00C00000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 3 cycles */
+#define B3HT_0 0x00000000 /* Bank 3 Hold Time from Read or Write deasserted to AOE deasserted = 0 cycles */
+#define B3RAT_1 0x01000000 /* Bank 3 Read Access Time = 1 cycle */
+#define B3RAT_2 0x02000000 /* Bank 3 Read Access Time = 2 cycles */
+#define B3RAT_3 0x03000000 /* Bank 3 Read Access Time = 3 cycles */
+#define B3RAT_4 0x04000000 /* Bank 3 Read Access Time = 4 cycles */
+#define B3RAT_5 0x05000000 /* Bank 3 Read Access Time = 5 cycles */
+#define B3RAT_6 0x06000000 /* Bank 3 Read Access Time = 6 cycles */
+#define B3RAT_7 0x07000000 /* Bank 3 Read Access Time = 7 cycles */
+#define B3RAT_8 0x08000000 /* Bank 3 Read Access Time = 8 cycles */
+#define B3RAT_9 0x09000000 /* Bank 3 Read Access Time = 9 cycles */
+#define B3RAT_10 0x0A000000 /* Bank 3 Read Access Time = 10 cycles */
+#define B3RAT_11 0x0B000000 /* Bank 3 Read Access Time = 11 cycles */
+#define B3RAT_12 0x0C000000 /* Bank 3 Read Access Time = 12 cycles */
+#define B3RAT_13 0x0D000000 /* Bank 3 Read Access Time = 13 cycles */
+#define B3RAT_14 0x0E000000 /* Bank 3 Read Access Time = 14 cycles */
+#define B3RAT_15 0x0F000000 /* Bank 3 Read Access Time = 15 cycles */
+#define B3WAT_1 0x10000000 /* Bank 3 Write Access Time = 1 cycle */
+#define B3WAT_2 0x20000000 /* Bank 3 Write Access Time = 2 cycles */
+#define B3WAT_3 0x30000000 /* Bank 3 Write Access Time = 3 cycles */
+#define B3WAT_4 0x40000000 /* Bank 3 Write Access Time = 4 cycles */
+#define B3WAT_5 0x50000000 /* Bank 3 Write Access Time = 5 cycles */
+#define B3WAT_6 0x60000000 /* Bank 3 Write Access Time = 6 cycles */
+#define B3WAT_7 0x70000000 /* Bank 3 Write Access Time = 7 cycles */
+#define B3WAT_8 0x80000000 /* Bank 3 Write Access Time = 8 cycles */
+#define B3WAT_9 0x90000000 /* Bank 3 Write Access Time = 9 cycles */
+#define B3WAT_10 0xA0000000 /* Bank 3 Write Access Time = 10 cycles */
+#define B3WAT_11 0xB0000000 /* Bank 3 Write Access Time = 11 cycles */
+#define B3WAT_12 0xC0000000 /* Bank 3 Write Access Time = 12 cycles */
+#define B3WAT_13 0xD0000000 /* Bank 3 Write Access Time = 13 cycles */
+#define B3WAT_14 0xE0000000 /* Bank 3 Write Access Time = 14 cycles */
+#define B3WAT_15 0xF0000000 /* Bank 3 Write Access Time = 15 cycles */
+
+/* ********************** SDRAM CONTROLLER MASKS *************************** */
+
+/* EBIU_SDGCTL Masks */
+#define SCTLE 0x00000001 /* Enable SCLK[0], /SRAS, /SCAS, /SWE, SDQM[3:0] */
+#define CL_2 0x00000008 /* SDRAM CAS latency = 2 cycles */
+#define CL_3 0x0000000C /* SDRAM CAS latency = 3 cycles */
+#define PFE 0x00000010 /* Enable SDRAM prefetch */
+#define PFP 0x00000020 /* Prefetch has priority over AMC requests */
+#define TRAS_1 0x00000040 /* SDRAM tRAS = 1 cycle */
+#define TRAS_2 0x00000080 /* SDRAM tRAS = 2 cycles */
+#define TRAS_3 0x000000C0 /* SDRAM tRAS = 3 cycles */
+#define TRAS_4 0x00000100 /* SDRAM tRAS = 4 cycles */
+#define TRAS_5 0x00000140 /* SDRAM tRAS = 5 cycles */
+#define TRAS_6 0x00000180 /* SDRAM tRAS = 6 cycles */
+#define TRAS_7 0x000001C0 /* SDRAM tRAS = 7 cycles */
+#define TRAS_8 0x00000200 /* SDRAM tRAS = 8 cycles */
+#define TRAS_9 0x00000240 /* SDRAM tRAS = 9 cycles */
+#define TRAS_10 0x00000280 /* SDRAM tRAS = 10 cycles */
+#define TRAS_11 0x000002C0 /* SDRAM tRAS = 11 cycles */
+#define TRAS_12 0x00000300 /* SDRAM tRAS = 12 cycles */
+#define TRAS_13 0x00000340 /* SDRAM tRAS = 13 cycles */
+#define TRAS_14 0x00000380 /* SDRAM tRAS = 14 cycles */
+#define TRAS_15 0x000003C0 /* SDRAM tRAS = 15 cycles */
+#define TRP_1 0x00000800 /* SDRAM tRP = 1 cycle */
+#define TRP_2 0x00001000 /* SDRAM tRP = 2 cycles */
+#define TRP_3 0x00001800 /* SDRAM tRP = 3 cycles */
+#define TRP_4 0x00002000 /* SDRAM tRP = 4 cycles */
+#define TRP_5 0x00002800 /* SDRAM tRP = 5 cycles */
+#define TRP_6 0x00003000 /* SDRAM tRP = 6 cycles */
+#define TRP_7 0x00003800 /* SDRAM tRP = 7 cycles */
+#define TRCD_1 0x00008000 /* SDRAM tRCD = 1 cycle */
+#define TRCD_2 0x00010000 /* SDRAM tRCD = 2 cycles */
+#define TRCD_3 0x00018000 /* SDRAM tRCD = 3 cycles */
+#define TRCD_4 0x00020000 /* SDRAM tRCD = 4 cycles */
+#define TRCD_5 0x00028000 /* SDRAM tRCD = 5 cycles */
+#define TRCD_6 0x00030000 /* SDRAM tRCD = 6 cycles */
+#define TRCD_7 0x00038000 /* SDRAM tRCD = 7 cycles */
+#define TWR_1 0x00080000 /* SDRAM tWR = 1 cycle */
+#define TWR_2 0x00100000 /* SDRAM tWR = 2 cycles */
+#define TWR_3 0x00180000 /* SDRAM tWR = 3 cycles */
+#define PUPSD 0x00200000 /*Power-up start delay */
+#define PSM 0x00400000 /* SDRAM power-up sequence = Precharge, mode register set, 8 CBR refresh cycles */
+#define PSS 0x00800000 /* enable SDRAM power-up sequence on next SDRAM access */
+#define SRFS 0x01000000 /* Start SDRAM self-refresh mode */
+#define EBUFE 0x02000000 /* Enable external buffering timing */
+#define FBBRW 0x04000000 /* Fast back-to-back read write enable */
+#define EMREN 0x10000000 /* Extended mode register enable */
+#define TCSR 0x20000000 /* Temp compensated self refresh value 85 deg C */
+#define CDDBG 0x40000000 /* Tristate SDRAM controls during bus grant */
+
+/* EBIU_SDBCTL Masks */
+#define EB0_E 0x00000001 /* Enable SDRAM external bank 0 */
+#define EB0_SZ_16 0x00000000 /* SDRAM external bank size = 16MB */
+#define EB0_SZ_32 0x00000002 /* SDRAM external bank size = 32MB */
+#define EB0_SZ_64 0x00000004 /* SDRAM external bank size = 64MB */
+#define EB0_SZ_128 0x00000006 /* SDRAM external bank size = 128MB */
+#define EB0_CAW_8 0x00000000 /* SDRAM external bank column address width = 8 bits */
+#define EB0_CAW_9 0x00000010 /* SDRAM external bank column address width = 9 bits */
+#define EB0_CAW_10 0x00000020 /* SDRAM external bank column address width = 9 bits */
+#define EB0_CAW_11 0x00000030 /* SDRAM external bank column address width = 9 bits */
+
+#define EB1_E 0x00000100 /* Enable SDRAM external bank 1 */
+#define EB1__SZ_16 0x00000000 /* SDRAM external bank size = 16MB */
+#define EB1__SZ_32 0x00000200 /* SDRAM external bank size = 32MB */
+#define EB1__SZ_64 0x00000400 /* SDRAM external bank size = 64MB */
+#define EB1__SZ_128 0x00000600 /* SDRAM external bank size = 128MB */
+#define EB1__CAW_8 0x00000000 /* SDRAM external bank column address width = 8 bits */
+#define EB1__CAW_9 0x00001000 /* SDRAM external bank column address width = 9 bits */
+#define EB1__CAW_10 0x00002000 /* SDRAM external bank column address width = 9 bits */
+#define EB1__CAW_11 0x00003000 /* SDRAM external bank column address width = 9 bits */
+
+#define EB2__E 0x00010000 /* Enable SDRAM external bank 2 */
+#define EB2__SZ_16 0x00000000 /* SDRAM external bank size = 16MB */
+#define EB2__SZ_32 0x00020000 /* SDRAM external bank size = 32MB */
+#define EB2__SZ_64 0x00040000 /* SDRAM external bank size = 64MB */
+#define EB2__SZ_128 0x00060000 /* SDRAM external bank size = 128MB */
+#define EB2__CAW_8 0x00000000 /* SDRAM external bank column address width = 8 bits */
+#define EB2__CAW_9 0x00100000 /* SDRAM external bank column address width = 9 bits */
+#define EB2__CAW_10 0x00200000 /* SDRAM external bank column address width = 9 bits */
+#define EB2__CAW_11 0x00300000 /* SDRAM external bank column address width = 9 bits */
+
+#define EB3__E 0x01000000 /* Enable SDRAM external bank 3 */
+#define EB3__SZ_16 0x00000000 /* SDRAM external bank size = 16MB */
+#define EB3__SZ_32 0x02000000 /* SDRAM external bank size = 32MB */
+#define EB3__SZ_64 0x04000000 /* SDRAM external bank size = 64MB */
+#define EB3__SZ_128 0x06000000 /* SDRAM external bank size = 128MB */
+#define EB3__CAW_8 0x00000000 /* SDRAM external bank column address width = 8 bits */
+#define EB3__CAW_9 0x10000000 /* SDRAM external bank column address width = 9 bits */
+#define EB3__CAW_10 0x20000000 /* SDRAM external bank column address width = 9 bits */
+#define EB3__CAW_11 0x30000000 /* SDRAM external bank column address width = 9 bits */
+
+/* EBIU_SDSTAT Masks */
+#define SDCI 0x00000001 /* SDRAM controller is idle */
+#define SDSRA 0x00000002 /* SDRAM SDRAM self refresh is active */
+#define SDPUA 0x00000004 /* SDRAM power up active */
+#define SDRS 0x00000008 /* SDRAM is in reset state */
+#define SDEASE 0x00000010 /* SDRAM EAB sticky error status - W1C */
+#define BGSTAT 0x00000020 /* Bus granted */
+
+/*VR_CTL Masks*/
+#define WAKE 0x100
+#define VLEV_6 0x60
+#define VLEV_7 0x70
+#define VLEV_8 0x80
+#define VLEV_9 0x90
+#define VLEV_10 0xA0
+#define VLEV_11 0xB0
+#define VLEV_12 0xC0
+#define VLEV_13 0xD0
+#define VLEV_14 0xE0
+#define VLEV_15 0xF0
+#define FREQ_3 0x03
+
+#endif /* _DEF_BF561_H */
diff --git a/include/asm-blackfin/mach-bf561/dma.h b/include/asm-blackfin/mach-bf561/dma.h
new file mode 100644
index 0000000..21d9820
--- /dev/null
+++ b/include/asm-blackfin/mach-bf561/dma.h
@@ -0,0 +1,35 @@
+/*****************************************************************************
+*
+* BF-533/2/1 Specific Declarations
+*
+****************************************************************************/
+
+#ifndef _MACH_DMA_H_
+#define _MACH_DMA_H_
+
+#define MAX_BLACKFIN_DMA_CHANNEL 36
+
+#define CH_PPI0 0
+#define CH_PPI (CH_PPI0)
+#define CH_PPI1 1
+#define CH_SPORT0_RX 12
+#define CH_SPORT0_TX 13
+#define CH_SPORT1_RX 14
+#define CH_SPORT1_TX 15
+#define CH_SPI 16
+#define CH_UART_RX 17
+#define CH_UART_TX 18
+#define CH_MEM_STREAM0_DEST 24 /* TX */
+#define CH_MEM_STREAM0_SRC 25 /* RX */
+#define CH_MEM_STREAM1_DEST 26 /* TX */
+#define CH_MEM_STREAM1_SRC 27 /* RX */
+#define CH_MEM_STREAM2_DEST 28
+#define CH_MEM_STREAM2_SRC 29
+#define CH_MEM_STREAM3_SRC 30
+#define CH_MEM_STREAM3_DEST 31
+#define CH_IMEM_STREAM0_DEST 32
+#define CH_IMEM_STREAM0_SRC 33
+#define CH_IMEM_STREAM1_SRC 34
+#define CH_IMEM_STREAM1_DEST 35
+
+#endif
diff --git a/include/asm-blackfin/mach-bf561/irq.h b/include/asm-blackfin/mach-bf561/irq.h
new file mode 100644
index 0000000..a753ce7
--- /dev/null
+++ b/include/asm-blackfin/mach-bf561/irq.h
@@ -0,0 +1,450 @@
+
+/*
+ * File: include/asm-blackfin/mach-bf561/irq.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _BF561_IRQ_H_
+#define _BF561_IRQ_H_
+
+/***********************************************************************
+ * Interrupt source definitions:
+ Event Source Core Event Name IRQ No
+ (highest priority)
+ Emulation Events EMU 0
+ Reset RST 1
+ NMI NMI 2
+ Exception EVX 3
+ Reserved -- 4
+ Hardware Error IVHW 5
+ Core Timer IVTMR 6 *
+
+ PLL Wakeup Interrupt IVG7 7
+ DMA1 Error (generic) IVG7 8
+ DMA2 Error (generic) IVG7 9
+ IMDMA Error (generic) IVG7 10
+ PPI1 Error Interrupt IVG7 11
+ PPI2 Error Interrupt IVG7 12
+ SPORT0 Error Interrupt IVG7 13
+ SPORT1 Error Interrupt IVG7 14
+ SPI Error Interrupt IVG7 15
+ UART Error Interrupt IVG7 16
+ Reserved Interrupt IVG7 17
+
+ DMA1 0 Interrupt(PPI1) IVG8 18
+ DMA1 1 Interrupt(PPI2) IVG8 19
+ DMA1 2 Interrupt IVG8 20
+ DMA1 3 Interrupt IVG8 21
+ DMA1 4 Interrupt IVG8 22
+ DMA1 5 Interrupt IVG8 23
+ DMA1 6 Interrupt IVG8 24
+ DMA1 7 Interrupt IVG8 25
+ DMA1 8 Interrupt IVG8 26
+ DMA1 9 Interrupt IVG8 27
+ DMA1 10 Interrupt IVG8 28
+ DMA1 11 Interrupt IVG8 29
+
+ DMA2 0 (SPORT0 RX) IVG9 30
+ DMA2 1 (SPORT0 TX) IVG9 31
+ DMA2 2 (SPORT1 RX) IVG9 32
+ DMA2 3 (SPORT2 TX) IVG9 33
+ DMA2 4 (SPI) IVG9 34
+ DMA2 5 (UART RX) IVG9 35
+ DMA2 6 (UART TX) IVG9 36
+ DMA2 7 Interrupt IVG9 37
+ DMA2 8 Interrupt IVG9 38
+ DMA2 9 Interrupt IVG9 39
+ DMA2 10 Interrupt IVG9 40
+ DMA2 11 Interrupt IVG9 41
+
+ TIMER 0 Interrupt IVG10 42
+ TIMER 1 Interrupt IVG10 43
+ TIMER 2 Interrupt IVG10 44
+ TIMER 3 Interrupt IVG10 45
+ TIMER 4 Interrupt IVG10 46
+ TIMER 5 Interrupt IVG10 47
+ TIMER 6 Interrupt IVG10 48
+ TIMER 7 Interrupt IVG10 49
+ TIMER 8 Interrupt IVG10 50
+ TIMER 9 Interrupt IVG10 51
+ TIMER 10 Interrupt IVG10 52
+ TIMER 11 Interrupt IVG10 53
+
+ Programmable Flags0 A (8) IVG11 54
+ Programmable Flags0 B (8) IVG11 55
+ Programmable Flags1 A (8) IVG11 56
+ Programmable Flags1 B (8) IVG11 57
+ Programmable Flags2 A (8) IVG11 58
+ Programmable Flags2 B (8) IVG11 59
+
+ MDMA1 0 write/read INT IVG8 60
+ MDMA1 1 write/read INT IVG8 61
+
+ MDMA2 0 write/read INT IVG9 62
+ MDMA2 1 write/read INT IVG9 63
+
+ IMDMA 0 write/read INT IVG12 64
+ IMDMA 1 write/read INT IVG12 65
+
+ Watch Dog Timer IVG13 66
+
+ Reserved interrupt IVG7 67
+ Reserved interrupt IVG7 68
+ Supplemental interrupt 0 IVG7 69
+ supplemental interrupt 1 IVG7 70
+
+ Software Interrupt 1 IVG14 71
+ Software Interrupt 2 IVG15 72 *
+ (lowest priority)
+ **********************************************************************/
+
+#define SYS_IRQS 72
+#define NR_PERI_INTS 64
+
+/*
+ * The ABSTRACT IRQ definitions
+ * the first seven of the following are fixed,
+ * the rest you change if you need to.
+ */
+/* IVG 0-6*/
+#define IRQ_EMU 0 /* Emulation */
+#define IRQ_RST 1 /* Reset */
+#define IRQ_NMI 2 /* Non Maskable Interrupt */
+#define IRQ_EVX 3 /* Exception */
+#define IRQ_UNUSED 4 /* Reserved interrupt */
+#define IRQ_HWERR 5 /* Hardware Error */
+#define IRQ_CORETMR 6 /* Core timer */
+
+#define IVG_BASE 7
+/* IVG 7 */
+#define IRQ_PLL_WAKEUP (IVG_BASE + 0) /* PLL Wakeup Interrupt */
+#define IRQ_DMA1_ERROR (IVG_BASE + 1) /* DMA1 Error (general) */
+#define IRQ_DMA_ERROR IRQ_DMA1_ERROR /* DMA1 Error (general) */
+#define IRQ_DMA2_ERROR (IVG_BASE + 2) /* DMA2 Error (general) */
+#define IRQ_IMDMA_ERROR (IVG_BASE + 3) /* IMDMA Error Interrupt */
+#define IRQ_PPI1_ERROR (IVG_BASE + 4) /* PPI1 Error Interrupt */
+#define IRQ_PPI_ERROR IRQ_PPI1_ERROR /* PPI1 Error Interrupt */
+#define IRQ_PPI2_ERROR (IVG_BASE + 5) /* PPI2 Error Interrupt */
+#define IRQ_SPORT0_ERROR (IVG_BASE + 6) /* SPORT0 Error Interrupt */
+#define IRQ_SPORT1_ERROR (IVG_BASE + 7) /* SPORT1 Error Interrupt */
+#define IRQ_SPI_ERROR (IVG_BASE + 8) /* SPI Error Interrupt */
+#define IRQ_UART_ERROR (IVG_BASE + 9) /* UART Error Interrupt */
+#define IRQ_RESERVED_ERROR (IVG_BASE + 10) /* Reversed Interrupt */
+/* IVG 8 */
+#define IRQ_DMA1_0 (IVG_BASE + 11) /* DMA1 0 Interrupt(PPI1) */
+#define IRQ_PPI IRQ_DMA1_0 /* DMA1 0 Interrupt(PPI1) */
+#define IRQ_PPI0 IRQ_DMA1_0 /* DMA1 0 Interrupt(PPI1) */
+#define IRQ_DMA1_1 (IVG_BASE + 12) /* DMA1 1 Interrupt(PPI2) */
+#define IRQ_PPI1 IRQ_DMA1_1 /* DMA1 1 Interrupt(PPI2) */
+#define IRQ_DMA1_2 (IVG_BASE + 13) /* DMA1 2 Interrupt */
+#define IRQ_DMA1_3 (IVG_BASE + 14) /* DMA1 3 Interrupt */
+#define IRQ_DMA1_4 (IVG_BASE + 15) /* DMA1 4 Interrupt */
+#define IRQ_DMA1_5 (IVG_BASE + 16) /* DMA1 5 Interrupt */
+#define IRQ_DMA1_6 (IVG_BASE + 17) /* DMA1 6 Interrupt */
+#define IRQ_DMA1_7 (IVG_BASE + 18) /* DMA1 7 Interrupt */
+#define IRQ_DMA1_8 (IVG_BASE + 19) /* DMA1 8 Interrupt */
+#define IRQ_DMA1_9 (IVG_BASE + 20) /* DMA1 9 Interrupt */
+#define IRQ_DMA1_10 (IVG_BASE + 21) /* DMA1 10 Interrupt */
+#define IRQ_DMA1_11 (IVG_BASE + 22) /* DMA1 11 Interrupt */
+/* IVG 9 */
+#define IRQ_DMA2_0 (IVG_BASE + 23) /* DMA2 0 (SPORT0 RX) */
+#define IRQ_SPORT0_RX IRQ_DMA2_0 /* DMA2 0 (SPORT0 RX) */
+#define IRQ_DMA2_1 (IVG_BASE + 24) /* DMA2 1 (SPORT0 TX) */
+#define IRQ_SPORT0_TX IRQ_DMA2_1 /* DMA2 1 (SPORT0 TX) */
+#define IRQ_DMA2_2 (IVG_BASE + 25) /* DMA2 2 (SPORT1 RX) */
+#define IRQ_SPORT1_RX IRQ_DMA2_2 /* DMA2 2 (SPORT1 RX) */
+#define IRQ_DMA2_3 (IVG_BASE + 26) /* DMA2 3 (SPORT2 TX) */
+#define IRQ_SPORT1_TX IRQ_DMA2_3 /* DMA2 3 (SPORT2 TX) */
+#define IRQ_DMA2_4 (IVG_BASE + 27) /* DMA2 4 (SPI) */
+#define IRQ_SPI IRQ_DMA2_4 /* DMA2 4 (SPI) */
+#define IRQ_DMA2_5 (IVG_BASE + 28) /* DMA2 5 (UART RX) */
+#define IRQ_UART_RX IRQ_DMA2_5 /* DMA2 5 (UART RX) */
+#define IRQ_DMA2_6 (IVG_BASE + 29) /* DMA2 6 (UART TX) */
+#define IRQ_UART_TX IRQ_DMA2_6 /* DMA2 6 (UART TX) */
+#define IRQ_DMA2_7 (IVG_BASE + 30) /* DMA2 7 Interrupt */
+#define IRQ_DMA2_8 (IVG_BASE + 31) /* DMA2 8 Interrupt */
+#define IRQ_DMA2_9 (IVG_BASE + 32) /* DMA2 9 Interrupt */
+#define IRQ_DMA2_10 (IVG_BASE + 33) /* DMA2 10 Interrupt */
+#define IRQ_DMA2_11 (IVG_BASE + 34) /* DMA2 11 Interrupt */
+/* IVG 10 */
+#define IRQ_TIMER0 (IVG_BASE + 35) /* TIMER 0 Interrupt */
+#define IRQ_TIMER1 (IVG_BASE + 36) /* TIMER 1 Interrupt */
+#define IRQ_TIMER2 (IVG_BASE + 37) /* TIMER 2 Interrupt */
+#define IRQ_TIMER3 (IVG_BASE + 38) /* TIMER 3 Interrupt */
+#define IRQ_TIMER4 (IVG_BASE + 39) /* TIMER 4 Interrupt */
+#define IRQ_TIMER5 (IVG_BASE + 40) /* TIMER 5 Interrupt */
+#define IRQ_TIMER6 (IVG_BASE + 41) /* TIMER 6 Interrupt */
+#define IRQ_TIMER7 (IVG_BASE + 42) /* TIMER 7 Interrupt */
+#define IRQ_TIMER8 (IVG_BASE + 43) /* TIMER 8 Interrupt */
+#define IRQ_TIMER9 (IVG_BASE + 44) /* TIMER 9 Interrupt */
+#define IRQ_TIMER10 (IVG_BASE + 45) /* TIMER 10 Interrupt */
+#define IRQ_TIMER11 (IVG_BASE + 46) /* TIMER 11 Interrupt */
+/* IVG 11 */
+#define IRQ_PROG0_INTA (IVG_BASE + 47) /* Programmable Flags0 A (8) */
+#define IRQ_PROG_INTA IRQ_PROG0_INTA /* Programmable Flags0 A (8) */
+#define IRQ_PROG0_INTB (IVG_BASE + 48) /* Programmable Flags0 B (8) */
+#define IRQ_PROG_INTB IRQ_PROG0_INTB /* Programmable Flags0 B (8) */
+#define IRQ_PROG1_INTA (IVG_BASE + 49) /* Programmable Flags1 A (8) */
+#define IRQ_PROG1_INTB (IVG_BASE + 50) /* Programmable Flags1 B (8) */
+#define IRQ_PROG2_INTA (IVG_BASE + 51) /* Programmable Flags2 A (8) */
+#define IRQ_PROG2_INTB (IVG_BASE + 52) /* Programmable Flags2 B (8) */
+/* IVG 8 */
+#define IRQ_DMA1_WRRD0 (IVG_BASE + 53) /* MDMA1 0 write/read INT */
+#define IRQ_DMA_WRRD0 IRQ_DMA1_WRRD0 /* MDMA1 0 write/read INT */
+#define IRQ_MEM_DMA0 IRQ_DMA1_WRRD0
+#define IRQ_DMA1_WRRD1 (IVG_BASE + 54) /* MDMA1 1 write/read INT */
+#define IRQ_DMA_WRRD1 IRQ_DMA1_WRRD1 /* MDMA1 1 write/read INT */
+#define IRQ_MEM_DMA1 IRQ_DMA1_WRRD1
+/* IVG 9 */
+#define IRQ_DMA2_WRRD0 (IVG_BASE + 55) /* MDMA2 0 write/read INT */
+#define IRQ_MEM_DMA2 IRQ_DMA2_WRRD0
+#define IRQ_DMA2_WRRD1 (IVG_BASE + 56) /* MDMA2 1 write/read INT */
+#define IRQ_MEM_DMA3 IRQ_DMA2_WRRD1
+/* IVG 12 */
+#define IRQ_IMDMA_WRRD0 (IVG_BASE + 57) /* IMDMA 0 write/read INT */
+#define IRQ_IMEM_DMA0 IRQ_IMDMA_WRRD0
+#define IRQ_IMDMA_WRRD1 (IVG_BASE + 58) /* IMDMA 1 write/read INT */
+#define IRQ_IMEM_DMA1 IRQ_IMDMA_WRRD1
+/* IVG 13 */
+#define IRQ_WATCH (IVG_BASE + 59) /* Watch Dog Timer */
+/* IVG 7 */
+#define IRQ_RESERVED_1 (IVG_BASE + 60) /* Reserved interrupt */
+#define IRQ_RESERVED_2 (IVG_BASE + 61) /* Reserved interrupt */
+#define IRQ_SUPPLE_0 (IVG_BASE + 62) /* Supplemental interrupt 0 */
+#define IRQ_SUPPLE_1 (IVG_BASE + 63) /* supplemental interrupt 1 */
+#define IRQ_SW_INT1 71 /* Software Interrupt 1 */
+#define IRQ_SW_INT2 72 /* Software Interrupt 2 */
+ /* reserved for SYSCALL */
+#define IRQ_PF0 73
+#define IRQ_PF1 74
+#define IRQ_PF2 75
+#define IRQ_PF3 76
+#define IRQ_PF4 77
+#define IRQ_PF5 78
+#define IRQ_PF6 79
+#define IRQ_PF7 80
+#define IRQ_PF8 81
+#define IRQ_PF9 82
+#define IRQ_PF10 83
+#define IRQ_PF11 84
+#define IRQ_PF12 85
+#define IRQ_PF13 86
+#define IRQ_PF14 87
+#define IRQ_PF15 88
+#define IRQ_PF16 89
+#define IRQ_PF17 90
+#define IRQ_PF18 91
+#define IRQ_PF19 92
+#define IRQ_PF20 93
+#define IRQ_PF21 94
+#define IRQ_PF22 95
+#define IRQ_PF23 96
+#define IRQ_PF24 97
+#define IRQ_PF25 98
+#define IRQ_PF26 99
+#define IRQ_PF27 100
+#define IRQ_PF28 101
+#define IRQ_PF29 102
+#define IRQ_PF30 103
+#define IRQ_PF31 104
+#define IRQ_PF32 105
+#define IRQ_PF33 106
+#define IRQ_PF34 107
+#define IRQ_PF35 108
+#define IRQ_PF36 109
+#define IRQ_PF37 110
+#define IRQ_PF38 111
+#define IRQ_PF39 112
+#define IRQ_PF40 113
+#define IRQ_PF41 114
+#define IRQ_PF42 115
+#define IRQ_PF43 116
+#define IRQ_PF44 117
+#define IRQ_PF45 118
+#define IRQ_PF46 119
+#define IRQ_PF47 120
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+#define NR_IRQS (IRQ_PF47 + 1)
+#else
+#define NR_IRQS SYS_IRQS
+#endif
+
+#define IVG7 7
+#define IVG8 8
+#define IVG9 9
+#define IVG10 10
+#define IVG11 11
+#define IVG12 12
+#define IVG13 13
+#define IVG14 14
+#define IVG15 15
+
+/*
+ * DEFAULT PRIORITIES:
+ */
+
+#define CONFIG_DEF_PLL_WAKEUP 7
+#define CONFIG_DEF_DMA1_ERROR 7
+#define CONFIG_DEF_DMA2_ERROR 7
+#define CONFIG_DEF_IMDMA_ERROR 7
+#define CONFIG_DEF_PPI1_ERROR 7
+#define CONFIG_DEF_PPI2_ERROR 7
+#define CONFIG_DEF_SPORT0_ERROR 7
+#define CONFIG_DEF_SPORT1_ERROR 7
+#define CONFIG_DEF_SPI_ERROR 7
+#define CONFIG_DEF_UART_ERROR 7
+#define CONFIG_DEF_RESERVED_ERROR 7
+#define CONFIG_DEF_DMA1_0 8
+#define CONFIG_DEF_DMA1_1 8
+#define CONFIG_DEF_DMA1_2 8
+#define CONFIG_DEF_DMA1_3 8
+#define CONFIG_DEF_DMA1_4 8
+#define CONFIG_DEF_DMA1_5 8
+#define CONFIG_DEF_DMA1_6 8
+#define CONFIG_DEF_DMA1_7 8
+#define CONFIG_DEF_DMA1_8 8
+#define CONFIG_DEF_DMA1_9 8
+#define CONFIG_DEF_DMA1_10 8
+#define CONFIG_DEF_DMA1_11 8
+#define CONFIG_DEF_DMA2_0 9
+#define CONFIG_DEF_DMA2_1 9
+#define CONFIG_DEF_DMA2_2 9
+#define CONFIG_DEF_DMA2_3 9
+#define CONFIG_DEF_DMA2_4 9
+#define CONFIG_DEF_DMA2_5 9
+#define CONFIG_DEF_DMA2_6 9
+#define CONFIG_DEF_DMA2_7 9
+#define CONFIG_DEF_DMA2_8 9
+#define CONFIG_DEF_DMA2_9 9
+#define CONFIG_DEF_DMA2_10 9
+#define CONFIG_DEF_DMA2_11 9
+#define CONFIG_DEF_TIMER0 10
+#define CONFIG_DEF_TIMER1 10
+#define CONFIG_DEF_TIMER2 10
+#define CONFIG_DEF_TIMER3 10
+#define CONFIG_DEF_TIMER4 10
+#define CONFIG_DEF_TIMER5 10
+#define CONFIG_DEF_TIMER6 10
+#define CONFIG_DEF_TIMER7 10
+#define CONFIG_DEF_TIMER8 10
+#define CONFIG_DEF_TIMER9 10
+#define CONFIG_DEF_TIMER10 10
+#define CONFIG_DEF_TIMER11 10
+#define CONFIG_DEF_PROG0_INTA 11
+#define CONFIG_DEF_PROG0_INTB 11
+#define CONFIG_DEF_PROG1_INTA 11
+#define CONFIG_DEF_PROG1_INTB 11
+#define CONFIG_DEF_PROG2_INTA 11
+#define CONFIG_DEF_PROG2_INTB 11
+#define CONFIG_DEF_DMA1_WRRD0 8
+#define CONFIG_DEF_DMA1_WRRD1 8
+#define CONFIG_DEF_DMA2_WRRD0 9
+#define CONFIG_DEF_DMA2_WRRD1 9
+#define CONFIG_DEF_IMDMA_WRRD0 12
+#define CONFIG_DEF_IMDMA_WRRD1 12
+#define CONFIG_DEF_WATCH 13
+#define CONFIG_DEF_RESERVED_1 7
+#define CONFIG_DEF_RESERVED_2 7
+#define CONFIG_DEF_SUPPLE_0 7
+#define CONFIG_DEF_SUPPLE_1 7
+
+/* IAR0 BIT FIELDS */
+#define IRQ_PLL_WAKEUP_POS 0
+#define IRQ_DMA1_ERROR_POS 4
+#define IRQ_DMA2_ERROR_POS 8
+#define IRQ_IMDMA_ERROR_POS 12
+#define IRQ_PPI0_ERROR_POS 16
+#define IRQ_PPI1_ERROR_POS 20
+#define IRQ_SPORT0_ERROR_POS 24
+#define IRQ_SPORT1_ERROR_POS 28
+/* IAR1 BIT FIELDS */
+#define IRQ_SPI_ERROR_POS 0
+#define IRQ_UART_ERROR_POS 4
+#define IRQ_RESERVED_ERROR_POS 8
+#define IRQ_DMA1_0_POS 12
+#define IRQ_DMA1_1_POS 16
+#define IRQ_DMA1_2_POS 20
+#define IRQ_DMA1_3_POS 24
+#define IRQ_DMA1_4_POS 28
+/* IAR2 BIT FIELDS */
+#define IRQ_DMA1_5_POS 0
+#define IRQ_DMA1_6_POS 4
+#define IRQ_DMA1_7_POS 8
+#define IRQ_DMA1_8_POS 12
+#define IRQ_DMA1_9_POS 16
+#define IRQ_DMA1_10_POS 20
+#define IRQ_DMA1_11_POS 24
+#define IRQ_DMA2_0_POS 28
+/* IAR3 BIT FIELDS */
+#define IRQ_DMA2_1_POS 0
+#define IRQ_DMA2_2_POS 4
+#define IRQ_DMA2_3_POS 8
+#define IRQ_DMA2_4_POS 12
+#define IRQ_DMA2_5_POS 16
+#define IRQ_DMA2_6_POS 20
+#define IRQ_DMA2_7_POS 24
+#define IRQ_DMA2_8_POS 28
+/* IAR4 BIT FIELDS */
+#define IRQ_DMA2_9_POS 0
+#define IRQ_DMA2_10_POS 4
+#define IRQ_DMA2_11_POS 8
+#define IRQ_TIMER0_POS 12
+#define IRQ_TIMER1_POS 16
+#define IRQ_TIMER2_POS 20
+#define IRQ_TIMER3_POS 24
+#define IRQ_TIMER4_POS 28
+/* IAR5 BIT FIELDS */
+#define IRQ_TIMER5_POS 0
+#define IRQ_TIMER6_POS 4
+#define IRQ_TIMER7_POS 8
+#define IRQ_TIMER8_POS 12
+#define IRQ_TIMER9_POS 16
+#define IRQ_TIMER10_POS 20
+#define IRQ_TIMER11_POS 24
+#define IRQ_PROG0_INTA_POS 28
+/* IAR6 BIT FIELDS */
+#define IRQ_PROG0_INTB_POS 0
+#define IRQ_PROG1_INTA_POS 4
+#define IRQ_PROG1_INTB_POS 8
+#define IRQ_PROG2_INTA_POS 12
+#define IRQ_PROG2_INTB_POS 16
+#define IRQ_DMA1_WRRD0_POS 20
+#define IRQ_DMA1_WRRD1_POS 24
+#define IRQ_DMA2_WRRD0_POS 28
+/* IAR7 BIT FIELDS */
+#define IRQ_DMA2_WRRD1_POS 0
+#define IRQ_IMDMA_WRRD0_POS 4
+#define IRQ_IMDMA_WRRD1_POS 8
+#define IRQ_WDTIMER_POS 12
+#define IRQ_RESERVED_1_POS 16
+#define IRQ_RESERVED_2_POS 20
+#define IRQ_SUPPLE_0_POS 24
+#define IRQ_SUPPLE_1_POS 28
+
+#endif /* _BF561_IRQ_H_ */
diff --git a/include/asm-blackfin/mach-bf561/mem_init.h b/include/asm-blackfin/mach-bf561/mem_init.h
new file mode 100644
index 0000000..439a589
--- /dev/null
+++ b/include/asm-blackfin/mach-bf561/mem_init.h
@@ -0,0 +1,322 @@
+/*
+ * File: include/asm-blackfin/mach-bf561/mem_init.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#if (CONFIG_MEM_MT48LC16M16A2TG_75 || CONFIG_MEM_MT48LC64M4A2FB_7E || CONFIG_MEM_GENERIC_BOARD || CONFIG_MEM_MT48LC8M32B2B5_7)
+#if (CONFIG_SCLK_HZ > 119402985)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_7
+#define SDRAM_tRAS_num 7
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 104477612) && (CONFIG_SCLK_HZ <= 119402985)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_6
+#define SDRAM_tRAS_num 6
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 89552239) && (CONFIG_SCLK_HZ <= 104477612)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_5
+#define SDRAM_tRAS_num 5
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 74626866) && (CONFIG_SCLK_HZ <= 89552239)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_4
+#define SDRAM_tRAS_num 4
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 66666667) && (CONFIG_SCLK_HZ <= 74626866)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_3
+#define SDRAM_tRAS_num 3
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 59701493) && (CONFIG_SCLK_HZ <= 66666667)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_4
+#define SDRAM_tRAS_num 3
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 44776119) && (CONFIG_SCLK_HZ <= 59701493)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_3
+#define SDRAM_tRAS_num 3
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 29850746) && (CONFIG_SCLK_HZ <= 44776119)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_2
+#define SDRAM_tRAS_num 2
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ <= 29850746)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_1
+#define SDRAM_tRAS_num 1
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#endif
+
+#if (CONFIG_MEM_MT48LC16M16A2TG_75)
+ /*SDRAM INFORMATION: */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC64M4A2FB_7E)
+ /*SDRAM INFORMATION: */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC8M32B2B5_7)
+ /*SDRAM INFORMATION: */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 4096 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_GENERIC_BOARD)
+ /*SDRAM INFORMATION: Modify this for your board */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_SIZE == 128)
+#define SDRAM_SIZE EB0_SZ_128
+#endif
+#if (CONFIG_MEM_SIZE == 64)
+#define SDRAM_SIZE EB0_SZ_64
+#endif
+#if ( CONFIG_MEM_SIZE == 32)
+#define SDRAM_SIZE EB0_SZ_32
+#endif
+#if (CONFIG_MEM_SIZE == 16)
+#define SDRAM_SIZE EB0_SZ_16
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 11)
+#define SDRAM_WIDTH EB0_CAW_11
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 10)
+#define SDRAM_WIDTH EB0_CAW_10
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 9)
+#define SDRAM_WIDTH EB0_CAW_9
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 8)
+#define SDRAM_WIDTH EB0_CAW_8
+#endif
+
+#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EB0_E)
+
+/* Equation from section 17 (p17-46) of BF533 HRM */
+#define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num)
+
+/* Enable SCLK Out */
+#define mem_SDGCTL (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS)
+
+#if defined CONFIG_CLKIN_HALF
+#define CLKIN_HALF 1
+#else
+#define CLKIN_HALF 0
+#endif
+
+#if defined CONFIG_PLL_BYPASS
+#define PLL_BYPASS 1
+#else
+#define PLL_BYPASS 0
+#endif
+
+/***************************************Currently Not Being Used *********************************/
+#define flash_EBIU_AMBCTL_WAT ((CONFIG_FLASH_SPEED_BWAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_RAT ((CONFIG_FLASH_SPEED_BRAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_HT ((CONFIG_FLASH_SPEED_BHT * 4) / (4000000000 / CONFIG_SCLK_HZ))
+#define flash_EBIU_AMBCTL_ST ((CONFIG_FLASH_SPEED_BST * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_TT ((CONFIG_FLASH_SPEED_BTT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+
+#if (flash_EBIU_AMBCTL_TT > 3)
+#define flash_EBIU_AMBCTL0_TT B0TT_4
+#endif
+#if (flash_EBIU_AMBCTL_TT == 3)
+#define flash_EBIU_AMBCTL0_TT B0TT_3
+#endif
+#if (flash_EBIU_AMBCTL_TT == 2)
+#define flash_EBIU_AMBCTL0_TT B0TT_2
+#endif
+#if (flash_EBIU_AMBCTL_TT < 2)
+#define flash_EBIU_AMBCTL0_TT B0TT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_ST > 3)
+#define flash_EBIU_AMBCTL0_ST B0ST_4
+#endif
+#if (flash_EBIU_AMBCTL_ST == 3)
+#define flash_EBIU_AMBCTL0_ST B0ST_3
+#endif
+#if (flash_EBIU_AMBCTL_ST == 2)
+#define flash_EBIU_AMBCTL0_ST B0ST_2
+#endif
+#if (flash_EBIU_AMBCTL_ST < 2)
+#define flash_EBIU_AMBCTL0_ST B0ST_1
+#endif
+
+#if (flash_EBIU_AMBCTL_HT > 2)
+#define flash_EBIU_AMBCTL0_HT B0HT_3
+#endif
+#if (flash_EBIU_AMBCTL_HT == 2)
+#define flash_EBIU_AMBCTL0_HT B0HT_2
+#endif
+#if (flash_EBIU_AMBCTL_HT == 1)
+#define flash_EBIU_AMBCTL0_HT B0HT_1
+#endif
+#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT == 0)
+#define flash_EBIU_AMBCTL0_HT B0HT_0
+#endif
+#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT != 0)
+#define flash_EBIU_AMBCTL0_HT B0HT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_WAT > 14)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_15
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 14)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_14
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 13)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_13
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 12)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_12
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 11)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_11
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 10)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_10
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 9)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_9
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 8)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_8
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 7)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_7
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 6)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_6
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 5)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_5
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 4)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_4
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 3)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_3
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 2)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_2
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 1)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_RAT > 14)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_15
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 14)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_14
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 13)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_13
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 12)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_12
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 11)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_11
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 10)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_10
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 9)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_9
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 8)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_8
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 7)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_7
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 6)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_6
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 5)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_5
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 4)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_4
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 3)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_3
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 2)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_2
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 1)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_1
+#endif
+
+#define flash_EBIU_AMBCTL0 \
+ (flash_EBIU_AMBCTL0_WAT | flash_EBIU_AMBCTL0_RAT | flash_EBIU_AMBCTL0_HT | \
+ flash_EBIU_AMBCTL0_ST | flash_EBIU_AMBCTL0_TT | CONFIG_FLASH_SPEED_RDYEN)
diff --git a/include/asm-blackfin/mach-bf561/mem_map.h b/include/asm-blackfin/mach-bf561/mem_map.h
new file mode 100644
index 0000000..ebac9a8
--- /dev/null
+++ b/include/asm-blackfin/mach-bf561/mem_map.h
@@ -0,0 +1,75 @@
+/*
+ * Memory MAP
+ * Common header file for blackfin BF561 of processors.
+ */
+
+#ifndef _MEM_MAP_561_H_
+#define _MEM_MAP_561_H_
+
+#define COREMMR_BASE 0xFFE00000 /* Core MMRs */
+#define SYSMMR_BASE 0xFFC00000 /* System MMRs */
+
+/* Async Memory Banks */
+#define ASYNC_BANK3_BASE 0x2C000000 /* Async Bank 3 */
+#define ASYNC_BANK3_SIZE 0x04000000 /* 64M */
+#define ASYNC_BANK2_BASE 0x28000000 /* Async Bank 2 */
+#define ASYNC_BANK2_SIZE 0x04000000 /* 64M */
+#define ASYNC_BANK1_BASE 0x24000000 /* Async Bank 1 */
+#define ASYNC_BANK1_SIZE 0x04000000 /* 64M */
+#define ASYNC_BANK0_BASE 0x20000000 /* Async Bank 0 */
+#define ASYNC_BANK0_SIZE 0x04000000 /* 64M */
+
+/* Level 1 Memory */
+
+#ifdef CONFIG_BLKFIN_CACHE
+#define BLKFIN_ICACHESIZE (16*1024)
+#else
+#define BLKFIN_ICACHESIZE (0*1024)
+#endif
+
+/* Memory Map for ADSP-BF561 processors */
+
+#ifdef CONFIG_BF561
+#define L1_CODE_START 0xFFA00000
+#define L1_DATA_A_START 0xFF800000
+#define L1_DATA_B_START 0xFF900000
+
+#define L1_CODE_LENGTH 0x4000
+
+#ifdef CONFIG_BLKFIN_DCACHE
+
+#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH 0x8000
+#define BLKFIN_DCACHESIZE (16*1024)
+#define BLKFIN_DSUPBANKS 1
+#else
+#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH (0x8000 - 0x4000)
+#define BLKFIN_DCACHESIZE (32*1024)
+#define BLKFIN_DSUPBANKS 2
+#endif
+
+#else
+#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH 0x8000
+#define L1_DATA_B_LENGTH 0x8000
+#define BLKFIN_DCACHESIZE (0*1024)
+#define BLKFIN_DSUPBANKS 0
+#endif /*CONFIG_BLKFIN_DCACHE*/
+#endif
+
+/* Level 2 Memory */
+#define L2_START 0xFEB00000
+#define L2_LENGTH 0x20000
+
+/* Scratch Pad Memory */
+
+#if defined(CONFIG_BF561)
+#define L1_SCRATCH_START 0xFFB00000
+#define L1_SCRATCH_LENGTH 0x1000
+#endif
+
+#endif /* _MEM_MAP_533_H_ */
diff --git a/include/asm-blackfin/mach-common/cdef_LPBlackfin.h b/include/asm-blackfin/mach-common/cdef_LPBlackfin.h
new file mode 100644
index 0000000..22aa5e6
--- /dev/null
+++ b/include/asm-blackfin/mach-common/cdef_LPBlackfin.h
@@ -0,0 +1,471 @@
+ /*
+ * File: include/asm-blackfin/mach-common/cdef_LPBlackfin.h
+ * Based on:
+ * Author: unknown
+ * COPYRIGHT 2005 Analog Devices
+ * Created: ?
+ * Description:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _CDEF_LPBLACKFIN_H
+#define _CDEF_LPBLACKFIN_H
+
+/*#if !defined(__ADSPLPBLACKFIN__)
+#warning cdef_LPBlackfin.h should only be included for 532 compatible chips.
+#endif
+*/
+#include <asm/mach-common/def_LPBlackfin.h>
+
+/*Cache & SRAM Memory*/
+#define pSRAM_BASE_ADDRESS ((volatile void **)SRAM_BASE_ADDRESS)
+#define bfin_read_SRAM_BASE_ADDRESS() bfin_read32(SRAM_BASE_ADDRESS)
+#define bfin_write_SRAM_BASE_ADDRESS(val) bfin_write32(SRAM_BASE_ADDRESS,val)
+#define pDMEM_CONTROL ((volatile unsigned long *)DMEM_CONTROL)
+#define bfin_read_DMEM_CONTROL() bfin_read32(DMEM_CONTROL)
+#define bfin_write_DMEM_CONTROL(val) bfin_write32(DMEM_CONTROL,val)
+#define pDCPLB_STATUS ((volatile unsigned long *)DCPLB_STATUS)
+#define bfin_read_DCPLB_STATUS() bfin_read32(DCPLB_STATUS)
+#define bfin_write_DCPLB_STATUS(val) bfin_write32(DCPLB_STATUS,val)
+#define pDCPLB_FAULT_ADDR ((volatile void **)DCPLB_FAULT_ADDR)
+#define bfin_read_DCPLB_FAULT_ADDR() bfin_read32(DCPLB_FAULT_ADDR)
+#define bfin_write_DCPLB_FAULT_ADDR(val) bfin_write32(DCPLB_FAULT_ADDR,val)
+/*
+#define MMR_TIMEOUT 0xFFE00010
+*/
+#define pDCPLB_ADDR0 ((volatile void **)DCPLB_ADDR0)
+#define bfin_read_DCPLB_ADDR0() bfin_read32(DCPLB_ADDR0)
+#define bfin_write_DCPLB_ADDR0(val) bfin_write32(DCPLB_ADDR0,val)
+#define pDCPLB_ADDR1 ((volatile void **)DCPLB_ADDR1)
+#define bfin_read_DCPLB_ADDR1() bfin_read32(DCPLB_ADDR1)
+#define bfin_write_DCPLB_ADDR1(val) bfin_write32(DCPLB_ADDR1,val)
+#define pDCPLB_ADDR2 ((volatile void **)DCPLB_ADDR2)
+#define bfin_read_DCPLB_ADDR2() bfin_read32(DCPLB_ADDR2)
+#define bfin_write_DCPLB_ADDR2(val) bfin_write32(DCPLB_ADDR2,val)
+#define pDCPLB_ADDR3 ((volatile void **)DCPLB_ADDR3)
+#define bfin_read_DCPLB_ADDR3() bfin_read32(DCPLB_ADDR3)
+#define bfin_write_DCPLB_ADDR3(val) bfin_write32(DCPLB_ADDR3,val)
+#define pDCPLB_ADDR4 ((volatile void **)DCPLB_ADDR4)
+#define bfin_read_DCPLB_ADDR4() bfin_read32(DCPLB_ADDR4)
+#define bfin_write_DCPLB_ADDR4(val) bfin_write32(DCPLB_ADDR4,val)
+#define pDCPLB_ADDR5 ((volatile void **)DCPLB_ADDR5)
+#define bfin_read_DCPLB_ADDR5() bfin_read32(DCPLB_ADDR5)
+#define bfin_write_DCPLB_ADDR5(val) bfin_write32(DCPLB_ADDR5,val)
+#define pDCPLB_ADDR6 ((volatile void **)DCPLB_ADDR6)
+#define bfin_read_DCPLB_ADDR6() bfin_read32(DCPLB_ADDR6)
+#define bfin_write_DCPLB_ADDR6(val) bfin_write32(DCPLB_ADDR6,val)
+#define pDCPLB_ADDR7 ((volatile void **)DCPLB_ADDR7)
+#define bfin_read_DCPLB_ADDR7() bfin_read32(DCPLB_ADDR7)
+#define bfin_write_DCPLB_ADDR7(val) bfin_write32(DCPLB_ADDR7,val)
+#define pDCPLB_ADDR8 ((volatile void **)DCPLB_ADDR8)
+#define bfin_read_DCPLB_ADDR8() bfin_read32(DCPLB_ADDR8)
+#define bfin_write_DCPLB_ADDR8(val) bfin_write32(DCPLB_ADDR8,val)
+#define pDCPLB_ADDR9 ((volatile void **)DCPLB_ADDR9)
+#define bfin_read_DCPLB_ADDR9() bfin_read32(DCPLB_ADDR9)
+#define bfin_write_DCPLB_ADDR9(val) bfin_write32(DCPLB_ADDR9,val)
+#define pDCPLB_ADDR10 ((volatile void **)DCPLB_ADDR10)
+#define bfin_read_DCPLB_ADDR10() bfin_read32(DCPLB_ADDR10)
+#define bfin_write_DCPLB_ADDR10(val) bfin_write32(DCPLB_ADDR10,val)
+#define pDCPLB_ADDR11 ((volatile void **)DCPLB_ADDR11)
+#define bfin_read_DCPLB_ADDR11() bfin_read32(DCPLB_ADDR11)
+#define bfin_write_DCPLB_ADDR11(val) bfin_write32(DCPLB_ADDR11,val)
+#define pDCPLB_ADDR12 ((volatile void **)DCPLB_ADDR12)
+#define bfin_read_DCPLB_ADDR12() bfin_read32(DCPLB_ADDR12)
+#define bfin_write_DCPLB_ADDR12(val) bfin_write32(DCPLB_ADDR12,val)
+#define pDCPLB_ADDR13 ((volatile void **)DCPLB_ADDR13)
+#define bfin_read_DCPLB_ADDR13() bfin_read32(DCPLB_ADDR13)
+#define bfin_write_DCPLB_ADDR13(val) bfin_write32(DCPLB_ADDR13,val)
+#define pDCPLB_ADDR14 ((volatile void **)DCPLB_ADDR14)
+#define bfin_read_DCPLB_ADDR14() bfin_read32(DCPLB_ADDR14)
+#define bfin_write_DCPLB_ADDR14(val) bfin_write32(DCPLB_ADDR14,val)
+#define pDCPLB_ADDR15 ((volatile void **)DCPLB_ADDR15)
+#define bfin_read_DCPLB_ADDR15() bfin_read32(DCPLB_ADDR15)
+#define bfin_write_DCPLB_ADDR15(val) bfin_write32(DCPLB_ADDR15,val)
+#define pDCPLB_DATA0 ((volatile unsigned long *)DCPLB_DATA0)
+#define bfin_read_DCPLB_DATA0() bfin_read32(DCPLB_DATA0)
+#define bfin_write_DCPLB_DATA0(val) bfin_write32(DCPLB_DATA0,val)
+#define pDCPLB_DATA1 ((volatile unsigned long *)DCPLB_DATA1)
+#define bfin_read_DCPLB_DATA1() bfin_read32(DCPLB_DATA1)
+#define bfin_write_DCPLB_DATA1(val) bfin_write32(DCPLB_DATA1,val)
+#define pDCPLB_DATA2 ((volatile unsigned long *)DCPLB_DATA2)
+#define bfin_read_DCPLB_DATA2() bfin_read32(DCPLB_DATA2)
+#define bfin_write_DCPLB_DATA2(val) bfin_write32(DCPLB_DATA2,val)
+#define pDCPLB_DATA3 ((volatile unsigned long *)DCPLB_DATA3)
+#define bfin_read_DCPLB_DATA3() bfin_read32(DCPLB_DATA3)
+#define bfin_write_DCPLB_DATA3(val) bfin_write32(DCPLB_DATA3,val)
+#define pDCPLB_DATA4 ((volatile unsigned long *)DCPLB_DATA4)
+#define bfin_read_DCPLB_DATA4() bfin_read32(DCPLB_DATA4)
+#define bfin_write_DCPLB_DATA4(val) bfin_write32(DCPLB_DATA4,val)
+#define pDCPLB_DATA5 ((volatile unsigned long *)DCPLB_DATA5)
+#define bfin_read_DCPLB_DATA5() bfin_read32(DCPLB_DATA5)
+#define bfin_write_DCPLB_DATA5(val) bfin_write32(DCPLB_DATA5,val)
+#define pDCPLB_DATA6 ((volatile unsigned long *)DCPLB_DATA6)
+#define bfin_read_DCPLB_DATA6() bfin_read32(DCPLB_DATA6)
+#define bfin_write_DCPLB_DATA6(val) bfin_write32(DCPLB_DATA6,val)
+#define pDCPLB_DATA7 ((volatile unsigned long *)DCPLB_DATA7)
+#define bfin_read_DCPLB_DATA7() bfin_read32(DCPLB_DATA7)
+#define bfin_write_DCPLB_DATA7(val) bfin_write32(DCPLB_DATA7,val)
+#define pDCPLB_DATA8 ((volatile unsigned long *)DCPLB_DATA8)
+#define bfin_read_DCPLB_DATA8() bfin_read32(DCPLB_DATA8)
+#define bfin_write_DCPLB_DATA8(val) bfin_write32(DCPLB_DATA8,val)
+#define pDCPLB_DATA9 ((volatile unsigned long *)DCPLB_DATA9)
+#define bfin_read_DCPLB_DATA9() bfin_read32(DCPLB_DATA9)
+#define bfin_write_DCPLB_DATA9(val) bfin_write32(DCPLB_DATA9,val)
+#define pDCPLB_DATA10 ((volatile unsigned long *)DCPLB_DATA10)
+#define bfin_read_DCPLB_DATA10() bfin_read32(DCPLB_DATA10)
+#define bfin_write_DCPLB_DATA10(val) bfin_write32(DCPLB_DATA10,val)
+#define pDCPLB_DATA11 ((volatile unsigned long *)DCPLB_DATA11)
+#define bfin_read_DCPLB_DATA11() bfin_read32(DCPLB_DATA11)
+#define bfin_write_DCPLB_DATA11(val) bfin_write32(DCPLB_DATA11,val)
+#define pDCPLB_DATA12 ((volatile unsigned long *)DCPLB_DATA12)
+#define bfin_read_DCPLB_DATA12() bfin_read32(DCPLB_DATA12)
+#define bfin_write_DCPLB_DATA12(val) bfin_write32(DCPLB_DATA12,val)
+#define pDCPLB_DATA13 ((volatile unsigned long *)DCPLB_DATA13)
+#define bfin_read_DCPLB_DATA13() bfin_read32(DCPLB_DATA13)
+#define bfin_write_DCPLB_DATA13(val) bfin_write32(DCPLB_DATA13,val)
+#define pDCPLB_DATA14 ((volatile unsigned long *)DCPLB_DATA14)
+#define bfin_read_DCPLB_DATA14() bfin_read32(DCPLB_DATA14)
+#define bfin_write_DCPLB_DATA14(val) bfin_write32(DCPLB_DATA14,val)
+#define pDCPLB_DATA15 ((volatile unsigned long *)DCPLB_DATA15)
+#define bfin_read_DCPLB_DATA15() bfin_read32(DCPLB_DATA15)
+#define bfin_write_DCPLB_DATA15(val) bfin_write32(DCPLB_DATA15,val)
+#define pDTEST_COMMAND ((volatile unsigned long *)DTEST_COMMAND)
+#define bfin_read_DTEST_COMMAND() bfin_read32(DTEST_COMMAND)
+#define bfin_write_DTEST_COMMAND(val) bfin_write32(DTEST_COMMAND,val)
+/*
+#define DTEST_INDEX 0xFFE00304
+*/
+#define pDTEST_DATA0 ((volatile unsigned long *)DTEST_DATA0)
+#define bfin_read_DTEST_DATA0() bfin_read32(DTEST_DATA0)
+#define bfin_write_DTEST_DATA0(val) bfin_write32(DTEST_DATA0,val)
+#define pDTEST_DATA1 ((volatile unsigned long *)DTEST_DATA1)
+#define bfin_read_DTEST_DATA1() bfin_read32(DTEST_DATA1)
+#define bfin_write_DTEST_DATA1(val) bfin_write32(DTEST_DATA1,val)
+/*
+#define DTEST_DATA2 0xFFE00408
+#define DTEST_DATA3 0xFFE0040C
+*/
+#define pIMEM_CONTROL ((volatile unsigned long *)IMEM_CONTROL)
+#define bfin_read_IMEM_CONTROL() bfin_read32(IMEM_CONTROL)
+#define bfin_write_IMEM_CONTROL(val) bfin_write32(IMEM_CONTROL,val)
+#define pICPLB_STATUS ((volatile unsigned long *)ICPLB_STATUS)
+#define bfin_read_ICPLB_STATUS() bfin_read32(ICPLB_STATUS)
+#define bfin_write_ICPLB_STATUS(val) bfin_write32(ICPLB_STATUS,val)
+#define pICPLB_FAULT_ADDR ((volatile void **)ICPLB_FAULT_ADDR)
+#define bfin_read_ICPLB_FAULT_ADDR() bfin_read32(ICPLB_FAULT_ADDR)
+#define bfin_write_ICPLB_FAULT_ADDR(val) bfin_write32(ICPLB_FAULT_ADDR,val)
+#define pICPLB_ADDR0 ((volatile void **)ICPLB_ADDR0)
+#define bfin_read_ICPLB_ADDR0() bfin_read32(ICPLB_ADDR0)
+#define bfin_write_ICPLB_ADDR0(val) bfin_write32(ICPLB_ADDR0,val)
+#define pICPLB_ADDR1 ((volatile void **)ICPLB_ADDR1)
+#define bfin_read_ICPLB_ADDR1() bfin_read32(ICPLB_ADDR1)
+#define bfin_write_ICPLB_ADDR1(val) bfin_write32(ICPLB_ADDR1,val)
+#define pICPLB_ADDR2 ((volatile void **)ICPLB_ADDR2)
+#define bfin_read_ICPLB_ADDR2() bfin_read32(ICPLB_ADDR2)
+#define bfin_write_ICPLB_ADDR2(val) bfin_write32(ICPLB_ADDR2,val)
+#define pICPLB_ADDR3 ((volatile void **)ICPLB_ADDR3)
+#define bfin_read_ICPLB_ADDR3() bfin_read32(ICPLB_ADDR3)
+#define bfin_write_ICPLB_ADDR3(val) bfin_write32(ICPLB_ADDR3,val)
+#define pICPLB_ADDR4 ((volatile void **)ICPLB_ADDR4)
+#define bfin_read_ICPLB_ADDR4() bfin_read32(ICPLB_ADDR4)
+#define bfin_write_ICPLB_ADDR4(val) bfin_write32(ICPLB_ADDR4,val)
+#define pICPLB_ADDR5 ((volatile void **)ICPLB_ADDR5)
+#define bfin_read_ICPLB_ADDR5() bfin_read32(ICPLB_ADDR5)
+#define bfin_write_ICPLB_ADDR5(val) bfin_write32(ICPLB_ADDR5,val)
+#define pICPLB_ADDR6 ((volatile void **)ICPLB_ADDR6)
+#define bfin_read_ICPLB_ADDR6() bfin_read32(ICPLB_ADDR6)
+#define bfin_write_ICPLB_ADDR6(val) bfin_write32(ICPLB_ADDR6,val)
+#define pICPLB_ADDR7 ((volatile void **)ICPLB_ADDR7)
+#define bfin_read_ICPLB_ADDR7() bfin_read32(ICPLB_ADDR7)
+#define bfin_write_ICPLB_ADDR7(val) bfin_write32(ICPLB_ADDR7,val)
+#define pICPLB_ADDR8 ((volatile void **)ICPLB_ADDR8)
+#define bfin_read_ICPLB_ADDR8() bfin_read32(ICPLB_ADDR8)
+#define bfin_write_ICPLB_ADDR8(val) bfin_write32(ICPLB_ADDR8,val)
+#define pICPLB_ADDR9 ((volatile void **)ICPLB_ADDR9)
+#define bfin_read_ICPLB_ADDR9() bfin_read32(ICPLB_ADDR9)
+#define bfin_write_ICPLB_ADDR9(val) bfin_write32(ICPLB_ADDR9,val)
+#define pICPLB_ADDR10 ((volatile void **)ICPLB_ADDR10)
+#define bfin_read_ICPLB_ADDR10() bfin_read32(ICPLB_ADDR10)
+#define bfin_write_ICPLB_ADDR10(val) bfin_write32(ICPLB_ADDR10,val)
+#define pICPLB_ADDR11 ((volatile void **)ICPLB_ADDR11)
+#define bfin_read_ICPLB_ADDR11() bfin_read32(ICPLB_ADDR11)
+#define bfin_write_ICPLB_ADDR11(val) bfin_write32(ICPLB_ADDR11,val)
+#define pICPLB_ADDR12 ((volatile void **)ICPLB_ADDR12)
+#define bfin_read_ICPLB_ADDR12() bfin_read32(ICPLB_ADDR12)
+#define bfin_write_ICPLB_ADDR12(val) bfin_write32(ICPLB_ADDR12,val)
+#define pICPLB_ADDR13 ((volatile void **)ICPLB_ADDR13)
+#define bfin_read_ICPLB_ADDR13() bfin_read32(ICPLB_ADDR13)
+#define bfin_write_ICPLB_ADDR13(val) bfin_write32(ICPLB_ADDR13,val)
+#define pICPLB_ADDR14 ((volatile void **)ICPLB_ADDR14)
+#define bfin_read_ICPLB_ADDR14() bfin_read32(ICPLB_ADDR14)
+#define bfin_write_ICPLB_ADDR14(val) bfin_write32(ICPLB_ADDR14,val)
+#define pICPLB_ADDR15 ((volatile void **)ICPLB_ADDR15)
+#define bfin_read_ICPLB_ADDR15() bfin_read32(ICPLB_ADDR15)
+#define bfin_write_ICPLB_ADDR15(val) bfin_write32(ICPLB_ADDR15,val)
+#define pICPLB_DATA0 ((volatile unsigned long *)ICPLB_DATA0)
+#define bfin_read_ICPLB_DATA0() bfin_read32(ICPLB_DATA0)
+#define bfin_write_ICPLB_DATA0(val) bfin_write32(ICPLB_DATA0,val)
+#define pICPLB_DATA1 ((volatile unsigned long *)ICPLB_DATA1)
+#define bfin_read_ICPLB_DATA1() bfin_read32(ICPLB_DATA1)
+#define bfin_write_ICPLB_DATA1(val) bfin_write32(ICPLB_DATA1,val)
+#define pICPLB_DATA2 ((volatile unsigned long *)ICPLB_DATA2)
+#define bfin_read_ICPLB_DATA2() bfin_read32(ICPLB_DATA2)
+#define bfin_write_ICPLB_DATA2(val) bfin_write32(ICPLB_DATA2,val)
+#define pICPLB_DATA3 ((volatile unsigned long *)ICPLB_DATA3)
+#define bfin_read_ICPLB_DATA3() bfin_read32(ICPLB_DATA3)
+#define bfin_write_ICPLB_DATA3(val) bfin_write32(ICPLB_DATA3,val)
+#define pICPLB_DATA4 ((volatile unsigned long *)ICPLB_DATA4)
+#define bfin_read_ICPLB_DATA4() bfin_read32(ICPLB_DATA4)
+#define bfin_write_ICPLB_DATA4(val) bfin_write32(ICPLB_DATA4,val)
+#define pICPLB_DATA5 ((volatile unsigned long *)ICPLB_DATA5)
+#define bfin_read_ICPLB_DATA5() bfin_read32(ICPLB_DATA5)
+#define bfin_write_ICPLB_DATA5(val) bfin_write32(ICPLB_DATA5,val)
+#define pICPLB_DATA6 ((volatile unsigned long *)ICPLB_DATA6)
+#define bfin_read_ICPLB_DATA6() bfin_read32(ICPLB_DATA6)
+#define bfin_write_ICPLB_DATA6(val) bfin_write32(ICPLB_DATA6,val)
+#define pICPLB_DATA7 ((volatile unsigned long *)ICPLB_DATA7)
+#define bfin_read_ICPLB_DATA7() bfin_read32(ICPLB_DATA7)
+#define bfin_write_ICPLB_DATA7(val) bfin_write32(ICPLB_DATA7,val)
+#define pICPLB_DATA8 ((volatile unsigned long *)ICPLB_DATA8)
+#define bfin_read_ICPLB_DATA8() bfin_read32(ICPLB_DATA8)
+#define bfin_write_ICPLB_DATA8(val) bfin_write32(ICPLB_DATA8,val)
+#define pICPLB_DATA9 ((volatile unsigned long *)ICPLB_DATA9)
+#define bfin_read_ICPLB_DATA9() bfin_read32(ICPLB_DATA9)
+#define bfin_write_ICPLB_DATA9(val) bfin_write32(ICPLB_DATA9,val)
+#define pICPLB_DATA10 ((volatile unsigned long *)ICPLB_DATA10)
+#define bfin_read_ICPLB_DATA10() bfin_read32(ICPLB_DATA10)
+#define bfin_write_ICPLB_DATA10(val) bfin_write32(ICPLB_DATA10,val)
+#define pICPLB_DATA11 ((volatile unsigned long *)ICPLB_DATA11)
+#define bfin_read_ICPLB_DATA11() bfin_read32(ICPLB_DATA11)
+#define bfin_write_ICPLB_DATA11(val) bfin_write32(ICPLB_DATA11,val)
+#define pICPLB_DATA12 ((volatile unsigned long *)ICPLB_DATA12)
+#define bfin_read_ICPLB_DATA12() bfin_read32(ICPLB_DATA12)
+#define bfin_write_ICPLB_DATA12(val) bfin_write32(ICPLB_DATA12,val)
+#define pICPLB_DATA13 ((volatile unsigned long *)ICPLB_DATA13)
+#define bfin_read_ICPLB_DATA13() bfin_read32(ICPLB_DATA13)
+#define bfin_write_ICPLB_DATA13(val) bfin_write32(ICPLB_DATA13,val)
+#define pICPLB_DATA14 ((volatile unsigned long *)ICPLB_DATA14)
+#define bfin_read_ICPLB_DATA14() bfin_read32(ICPLB_DATA14)
+#define bfin_write_ICPLB_DATA14(val) bfin_write32(ICPLB_DATA14,val)
+#define pICPLB_DATA15 ((volatile unsigned long *)ICPLB_DATA15)
+#define bfin_read_ICPLB_DATA15() bfin_read32(ICPLB_DATA15)
+#define bfin_write_ICPLB_DATA15(val) bfin_write32(ICPLB_DATA15,val)
+#define pITEST_COMMAND ((volatile unsigned long *)ITEST_COMMAND)
+#define bfin_read_ITEST_COMMAND() bfin_read32(ITEST_COMMAND)
+#define bfin_write_ITEST_COMMAND(val) bfin_write32(ITEST_COMMAND,val)
+#if 0
+#define ITEST_INDEX 0xFFE01304 /* Instruction Test Index Register */
+#endif
+#define pITEST_DATA0 ((volatile unsigned long *)ITEST_DATA0)
+#define bfin_read_ITEST_DATA0() bfin_read32(ITEST_DATA0)
+#define bfin_write_ITEST_DATA0(val) bfin_write32(ITEST_DATA0,val)
+#define pITEST_DATA1 ((volatile unsigned long *)ITEST_DATA1)
+#define bfin_read_ITEST_DATA1() bfin_read32(ITEST_DATA1)
+#define bfin_write_ITEST_DATA1(val) bfin_write32(ITEST_DATA1,val)
+
+/* Event/Interrupt Registers*/
+
+#define pEVT0 ((volatile void **)EVT0)
+#define bfin_read_EVT0() bfin_read32(EVT0)
+#define bfin_write_EVT0(val) bfin_write32(EVT0,val)
+#define pEVT1 ((volatile void **)EVT1)
+#define bfin_read_EVT1() bfin_read32(EVT1)
+#define bfin_write_EVT1(val) bfin_write32(EVT1,val)
+#define pEVT2 ((volatile void **)EVT2)
+#define bfin_read_EVT2() bfin_read32(EVT2)
+#define bfin_write_EVT2(val) bfin_write32(EVT2,val)
+#define pEVT3 ((volatile void **)EVT3)
+#define bfin_read_EVT3() bfin_read32(EVT3)
+#define bfin_write_EVT3(val) bfin_write32(EVT3,val)
+#define pEVT4 ((volatile void **)EVT4)
+#define bfin_read_EVT4() bfin_read32(EVT4)
+#define bfin_write_EVT4(val) bfin_write32(EVT4,val)
+#define pEVT5 ((volatile void **)EVT5)
+#define bfin_read_EVT5() bfin_read32(EVT5)
+#define bfin_write_EVT5(val) bfin_write32(EVT5,val)
+#define pEVT6 ((volatile void **)EVT6)
+#define bfin_read_EVT6() bfin_read32(EVT6)
+#define bfin_write_EVT6(val) bfin_write32(EVT6,val)
+#define pEVT7 ((volatile void **)EVT7)
+#define bfin_read_EVT7() bfin_read32(EVT7)
+#define bfin_write_EVT7(val) bfin_write32(EVT7,val)
+#define pEVT8 ((volatile void **)EVT8)
+#define bfin_read_EVT8() bfin_read32(EVT8)
+#define bfin_write_EVT8(val) bfin_write32(EVT8,val)
+#define pEVT9 ((volatile void **)EVT9)
+#define bfin_read_EVT9() bfin_read32(EVT9)
+#define bfin_write_EVT9(val) bfin_write32(EVT9,val)
+#define pEVT10 ((volatile void **)EVT10)
+#define bfin_read_EVT10() bfin_read32(EVT10)
+#define bfin_write_EVT10(val) bfin_write32(EVT10,val)
+#define pEVT11 ((volatile void **)EVT11)
+#define bfin_read_EVT11() bfin_read32(EVT11)
+#define bfin_write_EVT11(val) bfin_write32(EVT11,val)
+#define pEVT12 ((volatile void **)EVT12)
+#define bfin_read_EVT12() bfin_read32(EVT12)
+#define bfin_write_EVT12(val) bfin_write32(EVT12,val)
+#define pEVT13 ((volatile void **)EVT13)
+#define bfin_read_EVT13() bfin_read32(EVT13)
+#define bfin_write_EVT13(val) bfin_write32(EVT13,val)
+#define pEVT14 ((volatile void **)EVT14)
+#define bfin_read_EVT14() bfin_read32(EVT14)
+#define bfin_write_EVT14(val) bfin_write32(EVT14,val)
+#define pEVT15 ((volatile void **)EVT15)
+#define bfin_read_EVT15() bfin_read32(EVT15)
+#define bfin_write_EVT15(val) bfin_write32(EVT15,val)
+#define pIMASK ((volatile unsigned long *)IMASK)
+#define bfin_read_IMASK() bfin_read32(IMASK)
+#define bfin_write_IMASK(val) bfin_write32(IMASK,val)
+#define pIPEND ((volatile unsigned long *)IPEND)
+#define bfin_read_IPEND() bfin_read32(IPEND)
+#define bfin_write_IPEND(val) bfin_write32(IPEND,val)
+#define pILAT ((volatile unsigned long *)ILAT)
+#define bfin_read_ILAT() bfin_read32(ILAT)
+#define bfin_write_ILAT(val) bfin_write32(ILAT,val)
+
+/*Core Timer Registers*/
+#define pTCNTL ((volatile unsigned long *)TCNTL)
+#define bfin_read_TCNTL() bfin_read32(TCNTL)
+#define bfin_write_TCNTL(val) bfin_write32(TCNTL,val)
+#define pTPERIOD ((volatile unsigned long *)TPERIOD)
+#define bfin_read_TPERIOD() bfin_read32(TPERIOD)
+#define bfin_write_TPERIOD(val) bfin_write32(TPERIOD,val)
+#define pTSCALE ((volatile unsigned long *)TSCALE)
+#define bfin_read_TSCALE() bfin_read32(TSCALE)
+#define bfin_write_TSCALE(val) bfin_write32(TSCALE,val)
+#define pTCOUNT ((volatile unsigned long *)TCOUNT)
+#define bfin_read_TCOUNT() bfin_read32(TCOUNT)
+#define bfin_write_TCOUNT(val) bfin_write32(TCOUNT,val)
+
+/*Debug/MP/Emulation Registers*/
+#define pDSPID ((volatile unsigned long *)DSPID)
+#define bfin_read_DSPID() bfin_read32(DSPID)
+#define bfin_write_DSPID(val) bfin_write32(DSPID,val)
+#define pDBGCTL ((volatile unsigned long *)DBGCTL)
+#define bfin_read_DBGCTL() bfin_read32(DBGCTL)
+#define bfin_write_DBGCTL(val) bfin_write32(DBGCTL,val)
+#define pDBGSTAT ((volatile unsigned long *)DBGSTAT)
+#define bfin_read_DBGSTAT() bfin_read32(DBGSTAT)
+#define bfin_write_DBGSTAT(val) bfin_write32(DBGSTAT,val)
+#define pEMUDAT ((volatile unsigned long *)EMUDAT)
+#define bfin_read_EMUDAT() bfin_read32(EMUDAT)
+#define bfin_write_EMUDAT(val) bfin_write32(EMUDAT,val)
+
+/*Trace Buffer Registers*/
+#define pTBUFCTL ((volatile unsigned long *)TBUFCTL)
+#define bfin_read_TBUFCTL() bfin_read32(TBUFCTL)
+#define bfin_write_TBUFCTL(val) bfin_write32(TBUFCTL,val)
+#define pTBUFSTAT ((volatile unsigned long *)TBUFSTAT)
+#define bfin_read_TBUFSTAT() bfin_read32(TBUFSTAT)
+#define bfin_write_TBUFSTAT(val) bfin_write32(TBUFSTAT,val)
+#define pTBUF ((volatile void **)TBUF)
+#define bfin_read_TBUF() bfin_read32(TBUF)
+#define bfin_write_TBUF(val) bfin_write32(TBUF,val)
+
+/*Watch Point Control Registers*/
+#define pWPIACTL ((volatile unsigned long *)WPIACTL)
+#define bfin_read_WPIACTL() bfin_read32(WPIACTL)
+#define bfin_write_WPIACTL(val) bfin_write32(WPIACTL,val)
+#define pWPIA0 ((volatile void **)WPIA0)
+#define bfin_read_WPIA0() bfin_read32(WPIA0)
+#define bfin_write_WPIA0(val) bfin_write32(WPIA0,val)
+#define pWPIA1 ((volatile void **)WPIA1)
+#define bfin_read_WPIA1() bfin_read32(WPIA1)
+#define bfin_write_WPIA1(val) bfin_write32(WPIA1,val)
+#define pWPIA2 ((volatile void **)WPIA2)
+#define bfin_read_WPIA2() bfin_read32(WPIA2)
+#define bfin_write_WPIA2(val) bfin_write32(WPIA2,val)
+#define pWPIA3 ((volatile void **)WPIA3)
+#define bfin_read_WPIA3() bfin_read32(WPIA3)
+#define bfin_write_WPIA3(val) bfin_write32(WPIA3,val)
+#define pWPIA4 ((volatile void **)WPIA4)
+#define bfin_read_WPIA4() bfin_read32(WPIA4)
+#define bfin_write_WPIA4(val) bfin_write32(WPIA4,val)
+#define pWPIA5 ((volatile void **)WPIA5)
+#define bfin_read_WPIA5() bfin_read32(WPIA5)
+#define bfin_write_WPIA5(val) bfin_write32(WPIA5,val)
+#define pWPIACNT0 ((volatile unsigned long *)WPIACNT0)
+#define bfin_read_WPIACNT0() bfin_read32(WPIACNT0)
+#define bfin_write_WPIACNT0(val) bfin_write32(WPIACNT0,val)
+#define pWPIACNT1 ((volatile unsigned long *)WPIACNT1)
+#define bfin_read_WPIACNT1() bfin_read32(WPIACNT1)
+#define bfin_write_WPIACNT1(val) bfin_write32(WPIACNT1,val)
+#define pWPIACNT2 ((volatile unsigned long *)WPIACNT2)
+#define bfin_read_WPIACNT2() bfin_read32(WPIACNT2)
+#define bfin_write_WPIACNT2(val) bfin_write32(WPIACNT2,val)
+#define pWPIACNT3 ((volatile unsigned long *)WPIACNT3)
+#define bfin_read_WPIACNT3() bfin_read32(WPIACNT3)
+#define bfin_write_WPIACNT3(val) bfin_write32(WPIACNT3,val)
+#define pWPIACNT4 ((volatile unsigned long *)WPIACNT4)
+#define bfin_read_WPIACNT4() bfin_read32(WPIACNT4)
+#define bfin_write_WPIACNT4(val) bfin_write32(WPIACNT4,val)
+#define pWPIACNT5 ((volatile unsigned long *)WPIACNT5)
+#define bfin_read_WPIACNT5() bfin_read32(WPIACNT5)
+#define bfin_write_WPIACNT5(val) bfin_write32(WPIACNT5,val)
+#define pWPDACTL ((volatile unsigned long *)WPDACTL)
+#define bfin_read_WPDACTL() bfin_read32(WPDACTL)
+#define bfin_write_WPDACTL(val) bfin_write32(WPDACTL,val)
+#define pWPDA0 ((volatile void **)WPDA0)
+#define bfin_read_WPDA0() bfin_read32(WPDA0)
+#define bfin_write_WPDA0(val) bfin_write32(WPDA0,val)
+#define pWPDA1 ((volatile void **)WPDA1)
+#define bfin_read_WPDA1() bfin_read32(WPDA1)
+#define bfin_write_WPDA1(val) bfin_write32(WPDA1,val)
+#define pWPDACNT0 ((volatile unsigned long *)WPDACNT0)
+#define bfin_read_WPDACNT0() bfin_read32(WPDACNT0)
+#define bfin_write_WPDACNT0(val) bfin_write32(WPDACNT0,val)
+#define pWPDACNT1 ((volatile unsigned long *)WPDACNT1)
+#define bfin_read_WPDACNT1() bfin_read32(WPDACNT1)
+#define bfin_write_WPDACNT1(val) bfin_write32(WPDACNT1,val)
+#define pWPSTAT ((volatile unsigned long *)WPSTAT)
+#define bfin_read_WPSTAT() bfin_read32(WPSTAT)
+#define bfin_write_WPSTAT(val) bfin_write32(WPSTAT,val)
+
+/*Performance Monitor Registers*/
+#define pPFCTL ((volatile unsigned long *)PFCTL)
+#define bfin_read_PFCTL() bfin_read32(PFCTL)
+#define bfin_write_PFCTL(val) bfin_write32(PFCTL,val)
+#define pPFCNTR0 ((volatile unsigned long *)PFCNTR0)
+#define bfin_read_PFCNTR0() bfin_read32(PFCNTR0)
+#define bfin_write_PFCNTR0(val) bfin_write32(PFCNTR0,val)
+#define pPFCNTR1 ((volatile unsigned long *)PFCNTR1)
+#define bfin_read_PFCNTR1() bfin_read32(PFCNTR1)
+#define bfin_write_PFCNTR1(val) bfin_write32(PFCNTR1,val)
+
+/*
+#define IPRIO 0xFFE02110
+*/
+
+#if defined(CONFIG_BFIN_ALIVE_LED)
+#define pCONFIG_BFIN_ALIVE_LED_DPORT \
+ (volatile unsigned short *)CONFIG_BFIN_ALIVE_LED_DPORT
+#define pCONFIG_BFIN_ALIVE_LED_PORT \
+ (volatile unsigned short *)CONFIG_BFIN_ALIVE_LED_PORT
+#endif
+
+#if defined(CONFIG_BFIN_IDLE_LED)
+#define pCONFIG_BFIN_IDLE_LED_DPORT \
+ (volatile unsigned short *)CONFIG_BFIN_IDLE_LED_DPORT
+#define pCONFIG_BFIN_IDLE_LED_PORT \
+ (volatile unsigned short *)CONFIG_BFIN_IDLE_LED_PORT
+#endif
+
+#endif /* _CDEF_LPBLACKFIN_H */
diff --git a/include/asm-blackfin/mach-common/context.S b/include/asm-blackfin/mach-common/context.S
new file mode 100644
index 0000000..fd0ebe1
--- /dev/null
+++ b/include/asm-blackfin/mach-common/context.S
@@ -0,0 +1,350 @@
+/*
+ * File: arch/blackfin/kernel/context.S
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Code to save processor context.
+ * We even save the register which are preserved by a function call
+ * - r4, r5, r6, r7, p3, p4, p5
+ */
+.macro save_context_with_interrupts
+ [--sp] = SYSCFG;
+
+ [--sp] = P0; /*orig_p0*/
+ [--sp] = R0; /*orig_r0*/
+
+ [--sp] = ( R7:0, P5:0 );
+ [--sp] = fp;
+ [--sp] = usp;
+
+ [--sp] = i0;
+ [--sp] = i1;
+ [--sp] = i2;
+ [--sp] = i3;
+
+ [--sp] = m0;
+ [--sp] = m1;
+ [--sp] = m2;
+ [--sp] = m3;
+
+ [--sp] = l0;
+ [--sp] = l1;
+ [--sp] = l2;
+ [--sp] = l3;
+
+ [--sp] = b0;
+ [--sp] = b1;
+ [--sp] = b2;
+ [--sp] = b3;
+ [--sp] = a0.x;
+ [--sp] = a0.w;
+ [--sp] = a1.x;
+ [--sp] = a1.w;
+
+ [--sp] = LC0;
+ [--sp] = LC1;
+ [--sp] = LT0;
+ [--sp] = LT1;
+ [--sp] = LB0;
+ [--sp] = LB1;
+
+ [--sp] = ASTAT;
+
+ [--sp] = r0; /* Skip reserved */
+ [--sp] = RETS;
+ r0 = RETI;
+ [--sp] = r0;
+ [--sp] = RETX;
+ [--sp] = RETN;
+ [--sp] = RETE;
+ [--sp] = SEQSTAT;
+ [--sp] = r0; /* Skip IPEND as well. */
+ /* Switch to other method of keeping interrupts disabled. */
+#ifdef CONFIG_DEBUG_HWERR
+ r0 = 0x3f;
+ sti r0;
+#else
+ cli r0;
+#endif
+ [--sp] = RETI; /*orig_pc*/
+ /* Clear all L registers. */
+ r0 = 0 (x);
+ l0 = r0;
+ l1 = r0;
+ l2 = r0;
+ l3 = r0;
+.endm
+
+.macro save_context_syscall
+ [--sp] = SYSCFG;
+
+ [--sp] = P0; /*orig_p0*/
+ [--sp] = R0; /*orig_r0*/
+ [--sp] = ( R7:0, P5:0 );
+ [--sp] = fp;
+ [--sp] = usp;
+
+ [--sp] = i0;
+ [--sp] = i1;
+ [--sp] = i2;
+ [--sp] = i3;
+
+ [--sp] = m0;
+ [--sp] = m1;
+ [--sp] = m2;
+ [--sp] = m3;
+
+ [--sp] = l0;
+ [--sp] = l1;
+ [--sp] = l2;
+ [--sp] = l3;
+
+ [--sp] = b0;
+ [--sp] = b1;
+ [--sp] = b2;
+ [--sp] = b3;
+ [--sp] = a0.x;
+ [--sp] = a0.w;
+ [--sp] = a1.x;
+ [--sp] = a1.w;
+
+ [--sp] = LC0;
+ [--sp] = LC1;
+ [--sp] = LT0;
+ [--sp] = LT1;
+ [--sp] = LB0;
+ [--sp] = LB1;
+
+ [--sp] = ASTAT;
+
+ [--sp] = r0; /* Skip reserved */
+ [--sp] = RETS;
+ r0 = RETI;
+ [--sp] = r0;
+ [--sp] = RETX;
+ [--sp] = RETN;
+ [--sp] = RETE;
+ [--sp] = SEQSTAT;
+ [--sp] = r0; /* Skip IPEND as well. */
+ [--sp] = RETI; /*orig_pc*/
+ /* Clear all L registers. */
+ r0 = 0 (x);
+ l0 = r0;
+ l1 = r0;
+ l2 = r0;
+ l3 = r0;
+.endm
+
+.macro save_context_no_interrupts
+ [--sp] = SYSCFG;
+ [--sp] = P0; /* orig_p0 */
+ [--sp] = R0; /* orig_r0 */
+ [--sp] = ( R7:0, P5:0 );
+ [--sp] = fp;
+ [--sp] = usp;
+
+ [--sp] = i0;
+ [--sp] = i1;
+ [--sp] = i2;
+ [--sp] = i3;
+
+ [--sp] = m0;
+ [--sp] = m1;
+ [--sp] = m2;
+ [--sp] = m3;
+
+ [--sp] = l0;
+ [--sp] = l1;
+ [--sp] = l2;
+ [--sp] = l3;
+
+ [--sp] = b0;
+ [--sp] = b1;
+ [--sp] = b2;
+ [--sp] = b3;
+ [--sp] = a0.x;
+ [--sp] = a0.w;
+ [--sp] = a1.x;
+ [--sp] = a1.w;
+
+ [--sp] = LC0;
+ [--sp] = LC1;
+ [--sp] = LT0;
+ [--sp] = LT1;
+ [--sp] = LB0;
+ [--sp] = LB1;
+
+ [--sp] = ASTAT;
+
+#ifdef CONFIG_KGDB
+ fp = 0(Z);
+ r1 = sp;
+ r1 += 60;
+ r1 += 60;
+ r1 += 60;
+ [--sp] = r1;
+#else
+ [--sp] = r0; /* Skip reserved */
+#endif
+ [--sp] = RETS;
+ r0 = RETI;
+ [--sp] = r0;
+ [--sp] = RETX;
+ [--sp] = RETN;
+ [--sp] = RETE;
+ [--sp] = SEQSTAT;
+#ifdef CONFIG_KGDB
+ r1.l = lo(IPEND);
+ r1.h = hi(IPEND);
+ [--sp] = r1;
+#else
+ [--sp] = r0; /* Skip IPEND as well. */
+#endif
+ [--sp] = r0; /*orig_pc*/
+ /* Clear all L registers. */
+ r0 = 0 (x);
+ l0 = r0;
+ l1 = r0;
+ l2 = r0;
+ l3 = r0;
+.endm
+
+.macro restore_context_no_interrupts
+ sp += 4; /* Skip orig_pc */
+ sp += 4; /* Skip IPEND */
+ SEQSTAT = [sp++];
+ RETE = [sp++];
+ RETN = [sp++];
+ RETX = [sp++];
+ r0 = [sp++];
+ RETI = r0; /* Restore RETI indirectly when in exception */
+ RETS = [sp++];
+
+ sp += 4; /* Skip Reserved */
+
+ ASTAT = [sp++];
+
+ LB1 = [sp++];
+ LB0 = [sp++];
+ LT1 = [sp++];
+ LT0 = [sp++];
+ LC1 = [sp++];
+ LC0 = [sp++];
+
+ a1.w = [sp++];
+ a1.x = [sp++];
+ a0.w = [sp++];
+ a0.x = [sp++];
+ b3 = [sp++];
+ b2 = [sp++];
+ b1 = [sp++];
+ b0 = [sp++];
+
+ l3 = [sp++];
+ l2 = [sp++];
+ l1 = [sp++];
+ l0 = [sp++];
+
+ m3 = [sp++];
+ m2 = [sp++];
+ m1 = [sp++];
+ m0 = [sp++];
+
+ i3 = [sp++];
+ i2 = [sp++];
+ i1 = [sp++];
+ i0 = [sp++];
+
+ sp += 4;
+ fp = [sp++];
+
+ ( R7 : 0, P5 : 0) = [ SP ++ ];
+ sp += 8; /* Skip orig_r0/orig_p0 */
+ SYSCFG = [sp++];
+.endm
+
+.macro restore_context_with_interrupts
+ sp += 4; /* Skip orig_pc */
+ sp += 4; /* Skip IPEND */
+ SEQSTAT = [sp++];
+ RETE = [sp++];
+ RETN = [sp++];
+ RETX = [sp++];
+ RETI = [sp++];
+ RETS = [sp++];
+
+ p0.h = _irq_flags;
+ p0.l = _irq_flags;
+ r0 = [p0];
+ sti r0;
+
+ sp += 4; /* Skip Reserved */
+
+ ASTAT = [sp++];
+
+ LB1 = [sp++];
+ LB0 = [sp++];
+ LT1 = [sp++];
+ LT0 = [sp++];
+ LC1 = [sp++];
+ LC0 = [sp++];
+
+ a1.w = [sp++];
+ a1.x = [sp++];
+ a0.w = [sp++];
+ a0.x = [sp++];
+ b3 = [sp++];
+ b2 = [sp++];
+ b1 = [sp++];
+ b0 = [sp++];
+
+ l3 = [sp++];
+ l2 = [sp++];
+ l1 = [sp++];
+ l0 = [sp++];
+
+ m3 = [sp++];
+ m2 = [sp++];
+ m1 = [sp++];
+ m0 = [sp++];
+
+ i3 = [sp++];
+ i2 = [sp++];
+ i1 = [sp++];
+ i0 = [sp++];
+
+ sp += 4;
+ fp = [sp++];
+
+ ( R7 : 0, P5 : 0) = [ SP ++ ];
+ sp += 8; /* Skip orig_r0/orig_p0 */
+ csync;
+ SYSCFG = [sp++];
+ csync;
+.endm
+
diff --git a/include/asm-blackfin/mach-common/def_LPBlackfin.h b/include/asm-blackfin/mach-common/def_LPBlackfin.h
new file mode 100644
index 0000000..7610352
--- /dev/null
+++ b/include/asm-blackfin/mach-common/def_LPBlackfin.h
@@ -0,0 +1,691 @@
+ /*
+ * File: include/asm-blackfin/mach-common/def_LPBlackfin.h
+ * Based on:
+ * Author: unknown
+ * COPYRIGHT 2005 Analog Devices
+ * Created: ?
+ * Description:
+ *
+ * Modified:
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* LP Blackfin CORE REGISTER BIT & ADDRESS DEFINITIONS FOR ADSP-BF532/33 */
+
+#ifndef _DEF_LPBLACKFIN_H
+#define _DEF_LPBLACKFIN_H
+
+#include <asm/mach/anomaly.h>
+
+/*#if !defined(__ADSPLPBLACKFIN__)
+#warning def_LPBlackfin.h should only be included for 532 compatible chips.
+#endif
+*/
+
+#define MK_BMSK_(x) (1<<x)
+
+#if defined(ANOMALY_05000198)
+
+#define bfin_read16(addr) ({ unsigned __v; \
+ __asm__ __volatile__ ("NOP;\n\t"\
+ "%0 = w[%1] (z);\n\t"\
+ : "=d"(__v) : "a"(addr)); (unsigned short)__v; })
+
+#define bfin_read32(addr) ({ unsigned __v; \
+ __asm__ __volatile__ ("NOP;\n\t"\
+ "%0 = [%1];\n\t"\
+ : "=d"(__v) : "a"(addr)); __v; })
+
+#define bfin_write16(addr,val) ({\
+ __asm__ __volatile__ ("NOP;\n\t"\
+ "w[%0] = %1;\n\t"\
+ : : "a"(addr) , "d"(val) : "memory");})
+
+#define bfin_write32(addr,val) ({\
+ __asm__ __volatile__ ("NOP;\n\t"\
+ "[%0] = %1;\n\t"\
+ : : "a"(addr) , "d"(val) : "memory");})
+
+#else
+
+#define bfin_read16(addr) ({ unsigned __v; \
+ __asm__ __volatile__ (\
+ "%0 = w[%1] (z);\n\t"\
+ : "=d"(__v) : "a"(addr)); (unsigned short)__v; })
+
+#define bfin_read32(addr) ({ unsigned __v; \
+ __asm__ __volatile__ (\
+ "%0 = [%1];\n\t"\
+ : "=d"(__v) : "a"(addr)); __v; })
+
+#define bfin_write16(addr,val) ({\
+ __asm__ __volatile__ (\
+ "w[%0] = %1;\n\t"\
+ : : "a"(addr) , "d"(val) : "memory");})
+
+#define bfin_write32(addr,val) ({\
+ __asm__ __volatile__ (\
+ "[%0] = %1;\n\t"\
+ : : "a"(addr) , "d"(val) : "memory");})
+
+#endif
+
+/**************************************************
+ * System Register Bits
+ **************************************************/
+
+/**************************************************
+ * ASTAT register
+ **************************************************/
+
+/* definitions of ASTAT bit positions*/
+
+/*Result of last ALU0 or shifter operation is zero*/
+#define ASTAT_AZ_P 0x00000000
+/*Result of last ALU0 or shifter operation is negative*/
+#define ASTAT_AN_P 0x00000001
+/*Condition Code, used for holding comparison results*/
+#define ASTAT_CC_P 0x00000005
+/*Quotient Bit*/
+#define ASTAT_AQ_P 0x00000006
+/*Rounding mode, set for biased, clear for unbiased*/
+#define ASTAT_RND_MOD_P 0x00000008
+/*Result of last ALU0 operation generated a carry*/
+#define ASTAT_AC0_P 0x0000000C
+/*Result of last ALU0 operation generated a carry*/
+#define ASTAT_AC0_COPY_P 0x00000002
+/*Result of last ALU1 operation generated a carry*/
+#define ASTAT_AC1_P 0x0000000D
+/*Result of last ALU0 or MAC0 operation overflowed, sticky for MAC*/
+#define ASTAT_AV0_P 0x00000010
+/*Sticky version of ASTAT_AV0 */
+#define ASTAT_AV0S_P 0x00000011
+/*Result of last MAC1 operation overflowed, sticky for MAC*/
+#define ASTAT_AV1_P 0x00000012
+/*Sticky version of ASTAT_AV1 */
+#define ASTAT_AV1S_P 0x00000013
+/*Result of last ALU0 or MAC0 operation overflowed*/
+#define ASTAT_V_P 0x00000018
+/*Result of last ALU0 or MAC0 operation overflowed*/
+#define ASTAT_V_COPY_P 0x00000003
+/*Sticky version of ASTAT_V*/
+#define ASTAT_VS_P 0x00000019
+
+/* Masks */
+
+/*Result of last ALU0 or shifter operation is zero*/
+#define ASTAT_AZ MK_BMSK_(ASTAT_AZ_P)
+/*Result of last ALU0 or shifter operation is negative*/
+#define ASTAT_AN MK_BMSK_(ASTAT_AN_P)
+/*Result of last ALU0 operation generated a carry*/
+#define ASTAT_AC0 MK_BMSK_(ASTAT_AC0_P)
+/*Result of last ALU0 operation generated a carry*/
+#define ASTAT_AC0_COPY MK_BMSK_(ASTAT_AC0_COPY_P)
+/*Result of last ALU0 operation generated a carry*/
+#define ASTAT_AC1 MK_BMSK_(ASTAT_AC1_P)
+/*Result of last ALU0 or MAC0 operation overflowed, sticky for MAC*/
+#define ASTAT_AV0 MK_BMSK_(ASTAT_AV0_P)
+/*Result of last MAC1 operation overflowed, sticky for MAC*/
+#define ASTAT_AV1 MK_BMSK_(ASTAT_AV1_P)
+/*Condition Code, used for holding comparison results*/
+#define ASTAT_CC MK_BMSK_(ASTAT_CC_P)
+/*Quotient Bit*/
+#define ASTAT_AQ MK_BMSK_(ASTAT_AQ_P)
+/*Rounding mode, set for biased, clear for unbiased*/
+#define ASTAT_RND_MOD MK_BMSK_(ASTAT_RND_MOD_P)
+/*Overflow Bit*/
+#define ASTAT_V MK_BMSK_(ASTAT_V_P)
+/*Overflow Bit*/
+#define ASTAT_V_COPY MK_BMSK_(ASTAT_V_COPY_P)
+
+/**************************************************
+ * SEQSTAT register
+ **************************************************/
+
+/* Bit Positions */
+#define SEQSTAT_EXCAUSE0_P 0x00000000 /* Last exception cause bit 0 */
+#define SEQSTAT_EXCAUSE1_P 0x00000001 /* Last exception cause bit 1 */
+#define SEQSTAT_EXCAUSE2_P 0x00000002 /* Last exception cause bit 2 */
+#define SEQSTAT_EXCAUSE3_P 0x00000003 /* Last exception cause bit 3 */
+#define SEQSTAT_EXCAUSE4_P 0x00000004 /* Last exception cause bit 4 */
+#define SEQSTAT_EXCAUSE5_P 0x00000005 /* Last exception cause bit 5 */
+#define SEQSTAT_IDLE_REQ_P 0x0000000C /* Pending idle mode request,
+ * set by IDLE instruction.
+ */
+#define SEQSTAT_SFTRESET_P 0x0000000D /* Indicates whether the last
+ * reset was a software reset
+ * (=1)
+ */
+#define SEQSTAT_HWERRCAUSE0_P 0x0000000E /* Last hw error cause bit 0 */
+#define SEQSTAT_HWERRCAUSE1_P 0x0000000F /* Last hw error cause bit 1 */
+#define SEQSTAT_HWERRCAUSE2_P 0x00000010 /* Last hw error cause bit 2 */
+#define SEQSTAT_HWERRCAUSE3_P 0x00000011 /* Last hw error cause bit 3 */
+#define SEQSTAT_HWERRCAUSE4_P 0x00000012 /* Last hw error cause bit 4 */
+/* Masks */
+/* Exception cause */
+#define SEQSTAT_EXCAUSE (MK_BMSK_(SEQSTAT_EXCAUSE0_P) | \
+ MK_BMSK_(SEQSTAT_EXCAUSE1_P) | \
+ MK_BMSK_(SEQSTAT_EXCAUSE2_P) | \
+ MK_BMSK_(SEQSTAT_EXCAUSE3_P) | \
+ MK_BMSK_(SEQSTAT_EXCAUSE4_P) | \
+ MK_BMSK_(SEQSTAT_EXCAUSE5_P) | \
+ 0)
+
+/* Indicates whether the last reset was a software reset (=1) */
+#define SEQSTAT_SFTRESET (MK_BMSK_(SEQSTAT_SFTRESET_P))
+
+/* Last hw error cause */
+#define SEQSTAT_HWERRCAUSE (MK_BMSK_(SEQSTAT_HWERRCAUSE0_P) | \
+ MK_BMSK_(SEQSTAT_HWERRCAUSE1_P) | \
+ MK_BMSK_(SEQSTAT_HWERRCAUSE2_P) | \
+ MK_BMSK_(SEQSTAT_HWERRCAUSE3_P) | \
+ MK_BMSK_(SEQSTAT_HWERRCAUSE4_P) | \
+ 0)
+
+/* Translate bits to something useful */
+
+/* Last hw error cause */
+#define SEQSTAT_HWERRCAUSE_SHIFT (14)
+#define SEQSTAT_HWERRCAUSE_SYSTEM_MMR (0x02 << SEQSTAT_HWERRCAUSE_SHIFT)
+#define SEQSTAT_HWERRCAUSE_EXTERN_ADDR (0x03 << SEQSTAT_HWERRCAUSE_SHIFT)
+#define SEQSTAT_HWERRCAUSE_PERF_FLOW (0x12 << SEQSTAT_HWERRCAUSE_SHIFT)
+#define SEQSTAT_HWERRCAUSE_RAISE_5 (0x18 << SEQSTAT_HWERRCAUSE_SHIFT)
+
+/**************************************************
+ * SYSCFG register
+ **************************************************/
+
+/* Bit Positions */
+#define SYSCFG_SSSTEP_P 0x00000000 /* Supervisor single step, when
+ * set it forces an exception
+ * for each instruction executed
+ */
+#define SYSCFG_CCEN_P 0x00000001 /* Enable cycle counter (=1) */
+#define SYSCFG_SNEN_P 0x00000002 /* Self nesting Interrupt Enable */
+
+/* Masks */
+
+/* Supervisor single step, when set it forces an exception for each
+ *instruction executed
+ */
+#define SYSCFG_SSSTEP MK_BMSK_(SYSCFG_SSSTEP_P )
+/* Enable cycle counter (=1) */
+#define SYSCFG_CCEN MK_BMSK_(SYSCFG_CCEN_P )
+/* Self Nesting Interrupt Enable */
+#define SYSCFG_SNEN MK_BMSK_(SYSCFG_SNEN_P)
+/* Backward-compatibility for typos in prior releases */
+#define SYSCFG_SSSSTEP SYSCFG_SSSTEP
+#define SYSCFG_CCCEN SYSCFG_CCEN
+
+/****************************************************
+ * Core MMR Register Map
+ ****************************************************/
+
+/* Data Cache & SRAM Memory (0xFFE00000 - 0xFFE00404) */
+
+#define SRAM_BASE_ADDRESS 0xFFE00000 /* SRAM Base Address Register */
+#define DMEM_CONTROL 0xFFE00004 /* Data memory control */
+#define DCPLB_STATUS 0xFFE00008 /* Data Cache Programmable Look-Aside
+ * Buffer Status
+ */
+#define DCPLB_FAULT_STATUS 0xFFE00008 /* "" (older define) */
+#define DCPLB_FAULT_ADDR 0xFFE0000C /* Data Cache Programmable Look-Aside
+ * Buffer Fault Address
+ */
+#define DCPLB_ADDR0 0xFFE00100 /* Data Cache Protection Lookaside
+ * Buffer 0
+ */
+#define DCPLB_ADDR1 0xFFE00104 /* Data Cache Protection Lookaside
+ * Buffer 1
+ */
+#define DCPLB_ADDR2 0xFFE00108 /* Data Cache Protection Lookaside
+ * Buffer 2
+ */
+#define DCPLB_ADDR3 0xFFE0010C /* Data Cacheability Protection
+ * Lookaside Buffer 3
+ */
+#define DCPLB_ADDR4 0xFFE00110 /* Data Cacheability Protection
+ * Lookaside Buffer 4
+ */
+#define DCPLB_ADDR5 0xFFE00114 /* Data Cacheability Protection
+ * Lookaside Buffer 5
+ */
+#define DCPLB_ADDR6 0xFFE00118 /* Data Cacheability Protection
+ * Lookaside Buffer 6
+ */
+#define DCPLB_ADDR7 0xFFE0011C /* Data Cacheability Protection
+ * Lookaside Buffer 7
+ */
+#define DCPLB_ADDR8 0xFFE00120 /* Data Cacheability Protection
+ * Lookaside Buffer 8
+ */
+#define DCPLB_ADDR9 0xFFE00124 /* Data Cacheability Protection
+ * Lookaside Buffer 9
+ */
+#define DCPLB_ADDR10 0xFFE00128 /* Data Cacheability Protection
+ * Lookaside Buffer 10
+ */
+#define DCPLB_ADDR11 0xFFE0012C /* Data Cacheability Protection
+ * Lookaside Buffer 11
+ */
+#define DCPLB_ADDR12 0xFFE00130 /* Data Cacheability Protection
+ * Lookaside Buffer 12
+ */
+#define DCPLB_ADDR13 0xFFE00134 /* Data Cacheability Protection
+ * Lookaside Buffer 13
+ */
+#define DCPLB_ADDR14 0xFFE00138 /* Data Cacheability Protection
+ * Lookaside Buffer 14
+ */
+#define DCPLB_ADDR15 0xFFE0013C /* Data Cacheability Protection
+ * Lookaside Buffer 15
+ */
+#define DCPLB_DATA0 0xFFE00200 /* Data Cache 0 Status */
+#define DCPLB_DATA1 0xFFE00204 /* Data Cache 1 Status */
+#define DCPLB_DATA2 0xFFE00208 /* Data Cache 2 Status */
+#define DCPLB_DATA3 0xFFE0020C /* Data Cache 3 Status */
+#define DCPLB_DATA4 0xFFE00210 /* Data Cache 4 Status */
+#define DCPLB_DATA5 0xFFE00214 /* Data Cache 5 Status */
+#define DCPLB_DATA6 0xFFE00218 /* Data Cache 6 Status */
+#define DCPLB_DATA7 0xFFE0021C /* Data Cache 7 Status */
+#define DCPLB_DATA8 0xFFE00220 /* Data Cache 8 Status */
+#define DCPLB_DATA9 0xFFE00224 /* Data Cache 9 Status */
+#define DCPLB_DATA10 0xFFE00228 /* Data Cache 10 Status */
+#define DCPLB_DATA11 0xFFE0022C /* Data Cache 11 Status */
+#define DCPLB_DATA12 0xFFE00230 /* Data Cache 12 Status */
+#define DCPLB_DATA13 0xFFE00234 /* Data Cache 13 Status */
+#define DCPLB_DATA14 0xFFE00238 /* Data Cache 14 Status */
+#define DCPLB_DATA15 0xFFE0023C /* Data Cache 15 Status */
+#define DCPLB_DATA16 0xFFE00240 /* Extra Dummy entry */
+
+#define DTEST_COMMAND 0xFFE00300 /* Data Test Command Register */
+#define DTEST_DATA0 0xFFE00400 /* Data Test Data Register */
+#define DTEST_DATA1 0xFFE00404 /* Data Test Data Register */
+
+/* Instruction Cache & SRAM Memory (0xFFE01004 - 0xFFE01404) */
+
+#define IMEM_CONTROL 0xFFE01004 /* Instruction Memory Control */
+#define ICPLB_STATUS 0xFFE01008 /* Instruction Cache miss status */
+#define CODE_FAULT_STATUS 0xFFE01008 /* "" (older define) */
+#define ICPLB_FAULT_ADDR 0xFFE0100C /* Instruction Cache miss address */
+#define CODE_FAULT_ADDR 0xFFE0100C /* "" (older define) */
+#define ICPLB_ADDR0 0xFFE01100 /* Instruction Cacheability
+ * Protection Lookaside Buffer 0
+ */
+#define ICPLB_ADDR1 0xFFE01104 /* Instruction Cacheability
+ * Protection Lookaside Buffer 1
+ */
+#define ICPLB_ADDR2 0xFFE01108 /* Instruction Cacheability
+ * Protection Lookaside Buffer 2
+ */
+#define ICPLB_ADDR3 0xFFE0110C /* Instruction Cacheability
+ * Protection Lookaside Buffer 3
+ */
+#define ICPLB_ADDR4 0xFFE01110 /* Instruction Cacheability
+ * Protection Lookaside Buffer 4
+ */
+#define ICPLB_ADDR5 0xFFE01114 /* Instruction Cacheability
+ * Protection Lookaside Buffer 5
+ */
+#define ICPLB_ADDR6 0xFFE01118 /* Instruction Cacheability
+ * Protection Lookaside Buffer 6
+ */
+#define ICPLB_ADDR7 0xFFE0111C /* Instruction Cacheability
+ * Protection Lookaside Buffer 7
+ */
+#define ICPLB_ADDR8 0xFFE01120 /* Instruction Cacheability
+ * Protection Lookaside Buffer 8
+ */
+#define ICPLB_ADDR9 0xFFE01124 /* Instruction Cacheability
+ * Protection Lookaside Buffer 9
+ */
+#define ICPLB_ADDR10 0xFFE01128 /* Instruction Cacheability
+ * Protection Lookaside Buffer 10
+ */
+#define ICPLB_ADDR11 0xFFE0112C /* Instruction Cacheability
+ * Protection Lookaside Buffer 11
+ */
+#define ICPLB_ADDR12 0xFFE01130 /* Instruction Cacheability
+ * Protection Lookaside Buffer 12
+ */
+#define ICPLB_ADDR13 0xFFE01134 /* Instruction Cacheability
+ * Protection Lookaside Buffer 13
+ */
+#define ICPLB_ADDR14 0xFFE01138 /* Instruction Cacheability
+ * Protection Lookaside Buffer 14
+ */
+#define ICPLB_ADDR15 0xFFE0113C /* Instruction Cacheability
+ * Protection Lookaside Buffer 15
+ */
+#define ICPLB_DATA0 0xFFE01200 /* Instruction Cache 0 Status */
+#define ICPLB_DATA1 0xFFE01204 /* Instruction Cache 1 Status */
+#define ICPLB_DATA2 0xFFE01208 /* Instruction Cache 2 Status */
+#define ICPLB_DATA3 0xFFE0120C /* Instruction Cache 3 Status */
+#define ICPLB_DATA4 0xFFE01210 /* Instruction Cache 4 Status */
+#define ICPLB_DATA5 0xFFE01214 /* Instruction Cache 5 Status */
+#define ICPLB_DATA6 0xFFE01218 /* Instruction Cache 6 Status */
+#define ICPLB_DATA7 0xFFE0121C /* Instruction Cache 7 Status */
+#define ICPLB_DATA8 0xFFE01220 /* Instruction Cache 8 Status */
+#define ICPLB_DATA9 0xFFE01224 /* Instruction Cache 9 Status */
+#define ICPLB_DATA10 0xFFE01228 /* Instruction Cache 10 Status */
+#define ICPLB_DATA11 0xFFE0122C /* Instruction Cache 11 Status */
+#define ICPLB_DATA12 0xFFE01230 /* Instruction Cache 12 Status */
+#define ICPLB_DATA13 0xFFE01234 /* Instruction Cache 13 Status */
+#define ICPLB_DATA14 0xFFE01238 /* Instruction Cache 14 Status */
+#define ICPLB_DATA15 0xFFE0123C /* Instruction Cache 15 Status */
+#define ITEST_COMMAND 0xFFE01300 /* Instruction Test Command Register */
+#define ITEST_DATA0 0xFFE01400 /* Instruction Test Data Register */
+#define ITEST_DATA1 0xFFE01404 /* Instruction Test Data Register */
+
+/* Event/Interrupt Controller Registers (0xFFE02000 - 0xFFE02110) */
+
+#define EVT0 0xFFE02000 /* Event Vector 0 ESR Address */
+#define EVT1 0xFFE02004 /* Event Vector 1 ESR Address */
+#define EVT2 0xFFE02008 /* Event Vector 2 ESR Address */
+#define EVT3 0xFFE0200C /* Event Vector 3 ESR Address */
+#define EVT4 0xFFE02010 /* Event Vector 4 ESR Address */
+#define EVT5 0xFFE02014 /* Event Vector 5 ESR Address */
+#define EVT6 0xFFE02018 /* Event Vector 6 ESR Address */
+#define EVT7 0xFFE0201C /* Event Vector 7 ESR Address */
+#define EVT8 0xFFE02020 /* Event Vector 8 ESR Address */
+#define EVT9 0xFFE02024 /* Event Vector 9 ESR Address */
+#define EVT10 0xFFE02028 /* Event Vector 10 ESR Address */
+#define EVT11 0xFFE0202C /* Event Vector 11 ESR Address */
+#define EVT12 0xFFE02030 /* Event Vector 12 ESR Address */
+#define EVT13 0xFFE02034 /* Event Vector 13 ESR Address */
+#define EVT14 0xFFE02038 /* Event Vector 14 ESR Address */
+#define EVT15 0xFFE0203C /* Event Vector 15 ESR Address */
+#define IMASK 0xFFE02104 /* Interrupt Mask Register */
+#define IPEND 0xFFE02108 /* Interrupt Pending Register */
+#define ILAT 0xFFE0210C /* Interrupt Latch Register */
+#define IPRIO 0xFFE02110 /* Core Interrupt Priority Register */
+
+/* Core Timer Registers (0xFFE03000 - 0xFFE0300C) */
+
+#define TCNTL 0xFFE03000 /* Core Timer Control Register */
+#define TPERIOD 0xFFE03004 /* Core Timer Period Register */
+#define TSCALE 0xFFE03008 /* Core Timer Scale Register */
+#define TCOUNT 0xFFE0300C /* Core Timer Count Register */
+
+/* Debug/MP/Emulation Registers (0xFFE05000 - 0xFFE05008) */
+#define DSPID 0xFFE05000 /* DSP Processor ID Register for
+ * MP implementations
+ */
+
+#define DBGSTAT 0xFFE05008 /* Debug Status Register */
+
+/* Trace Buffer Registers (0xFFE06000 - 0xFFE06100) */
+
+#define TBUFCTL 0xFFE06000 /* Trace Buffer Control Register */
+#define TBUFSTAT 0xFFE06004 /* Trace Buffer Status Register */
+#define TBUF 0xFFE06100 /* Trace Buffer */
+
+/* Watchpoint Control Registers (0xFFE07000 - 0xFFE07200) */
+
+/* Watchpoint Instruction Address Control Register */
+#define WPIACTL 0xFFE07000
+/* Watchpoint Instruction Address Register 0 */
+#define WPIA0 0xFFE07040
+/* Watchpoint Instruction Address Register 1 */
+#define WPIA1 0xFFE07044
+/* Watchpoint Instruction Address Register 2 */
+#define WPIA2 0xFFE07048
+/* Watchpoint Instruction Address Register 3 */
+#define WPIA3 0xFFE0704C
+/* Watchpoint Instruction Address Register 4 */
+#define WPIA4 0xFFE07050
+/* Watchpoint Instruction Address Register 5 */
+#define WPIA5 0xFFE07054
+/* Watchpoint Instruction Address Count Register 0 */
+#define WPIACNT0 0xFFE07080
+/* Watchpoint Instruction Address Count Register 1 */
+#define WPIACNT1 0xFFE07084
+/* Watchpoint Instruction Address Count Register 2 */
+#define WPIACNT2 0xFFE07088
+/* Watchpoint Instruction Address Count Register 3 */
+#define WPIACNT3 0xFFE0708C
+/* Watchpoint Instruction Address Count Register 4 */
+#define WPIACNT4 0xFFE07090
+/* Watchpoint Instruction Address Count Register 5 */
+#define WPIACNT5 0xFFE07094
+/* Watchpoint Data Address Control Register */
+#define WPDACTL 0xFFE07100
+/* Watchpoint Data Address Register 0 */
+#define WPDA0 0xFFE07140
+/* Watchpoint Data Address Register 1 */
+#define WPDA1 0xFFE07144
+/* Watchpoint Data Address Count Value Register 0 */
+#define WPDACNT0 0xFFE07180
+/* Watchpoint Data Address Count Value Register 1 */
+#define WPDACNT1 0xFFE07184
+/* Watchpoint Status Register */
+#define WPSTAT 0xFFE07200
+
+/* Performance Monitor Registers (0xFFE08000 - 0xFFE08104) */
+
+/* Performance Monitor Control Register */
+#define PFCTL 0xFFE08000
+/* Performance Monitor Counter Register 0 */
+#define PFCNTR0 0xFFE08100
+/* Performance Monitor Counter Register 1 */
+#define PFCNTR1 0xFFE08104
+
+/****************************************************
+ * Core MMR Register Bits
+ ****************************************************/
+
+/**************************************************
+ * EVT registers (ILAT, IMASK, and IPEND).
+ **************************************************/
+
+/* Bit Positions */
+#define EVT_EMU_P 0x00000000 /* Emulator interrupt bit position */
+#define EVT_RST_P 0x00000001 /* Reset interrupt bit position */
+#define EVT_NMI_P 0x00000002 /* Non Maskable interrupt bit position */
+#define EVT_EVX_P 0x00000003 /* Exception bit position */
+#define EVT_IRPTEN_P 0x00000004 /* Global interrupt enable bit position */
+#define EVT_IVHW_P 0x00000005 /* Hardware Error interrupt bit position */
+#define EVT_IVTMR_P 0x00000006 /* Timer interrupt bit position */
+#define EVT_IVG7_P 0x00000007 /* IVG7 interrupt bit position */
+#define EVT_IVG8_P 0x00000008 /* IVG8 interrupt bit position */
+#define EVT_IVG9_P 0x00000009 /* IVG9 interrupt bit position */
+#define EVT_IVG10_P 0x0000000a /* IVG10 interrupt bit position */
+#define EVT_IVG11_P 0x0000000b /* IVG11 interrupt bit position */
+#define EVT_IVG12_P 0x0000000c /* IVG12 interrupt bit position */
+#define EVT_IVG13_P 0x0000000d /* IVG13 interrupt bit position */
+#define EVT_IVG14_P 0x0000000e /* IVG14 interrupt bit position */
+#define EVT_IVG15_P 0x0000000f /* IVG15 interrupt bit position */
+
+/* Masks */
+#define EVT_EMU MK_BMSK_(EVT_EMU_P ) /* Emulator interrupt mask */
+#define EVT_RST MK_BMSK_(EVT_RST_P ) /* Reset interrupt mask */
+#define EVT_NMI MK_BMSK_(EVT_NMI_P ) /* Non Maskable interrupt mask */
+#define EVT_EVX MK_BMSK_(EVT_EVX_P ) /* Exception mask */
+#define EVT_IRPTEN MK_BMSK_(EVT_IRPTEN_P) /* Global interrupt enable mask */
+#define EVT_IVHW MK_BMSK_(EVT_IVHW_P ) /* Hardware Error interrupt mask */
+#define EVT_IVTMR MK_BMSK_(EVT_IVTMR_P ) /* Timer interrupt mask */
+#define EVT_IVG7 MK_BMSK_(EVT_IVG7_P ) /* IVG7 interrupt mask */
+#define EVT_IVG8 MK_BMSK_(EVT_IVG8_P ) /* IVG8 interrupt mask */
+#define EVT_IVG9 MK_BMSK_(EVT_IVG9_P ) /* IVG9 interrupt mask */
+#define EVT_IVG10 MK_BMSK_(EVT_IVG10_P ) /* IVG10 interrupt mask */
+#define EVT_IVG11 MK_BMSK_(EVT_IVG11_P ) /* IVG11 interrupt mask */
+#define EVT_IVG12 MK_BMSK_(EVT_IVG12_P ) /* IVG12 interrupt mask */
+#define EVT_IVG13 MK_BMSK_(EVT_IVG13_P ) /* IVG13 interrupt mask */
+#define EVT_IVG14 MK_BMSK_(EVT_IVG14_P ) /* IVG14 interrupt mask */
+#define EVT_IVG15 MK_BMSK_(EVT_IVG15_P ) /* IVG15 interrupt mask */
+
+/**************************************************
+ * DMEM_CONTROL Register
+ **************************************************/
+/* Bit Positions */
+#define ENDM_P 0x00 /* (doesn't really exist) Enable
+ *Data Memory L1
+ */
+#define DMCTL_ENDM_P ENDM_P /* "" (older define) */
+
+#define ENDCPLB_P 0x01 /* Enable DCPLBS */
+#define DMCTL_ENDCPLB_P ENDCPLB_P /* "" (older define) */
+#define DMC0_P 0x02 /* L1 Data Memory Configure bit 0 */
+#define DMCTL_DMC0_P DMC0_P /* "" (older define) */
+#define DMC1_P 0x03 /* L1 Data Memory Configure bit 1 */
+#define DMCTL_DMC1_P DMC1_P /* "" (older define) */
+#define DCBS_P 0x04 /* L1 Data Cache Bank Select */
+#define PORT_PREF0_P 0x12 /* DAG0 Port Preference */
+#define PORT_PREF1_P 0x13 /* DAG1 Port Preference */
+
+/* Masks */
+#define ENDM 0x00000001 /* (doesn't really exist) Enable
+ * Data Memory L1
+ */
+#define ENDCPLB 0x00000002 /* Enable DCPLB */
+#define ASRAM_BSRAM 0x00000000
+#define ACACHE_BSRAM 0x00000008
+#define ACACHE_BCACHE 0x0000000C
+#define DCBS 0x00000010 /* L1 Data Cache Bank Select */
+#define PORT_PREF0 0x00001000 /* DAG0 Port Preference */
+#define PORT_PREF1 0x00002000 /* DAG1 Port Preference */
+
+/* IMEM_CONTROL Register */
+/* Bit Positions */
+#define ENIM_P 0x00 /* Enable L1 Code Memory */
+#define IMCTL_ENIM_P 0x00 /* "" (older define) */
+#define ENICPLB_P 0x01 /* Enable ICPLB */
+#define IMCTL_ENICPLB_P 0x01 /* "" (older define) */
+#define IMC_P 0x02 /* Enable */
+#define IMCTL_IMC_P 0x02 /* Configure L1 code memory as
+ * cache (0=SRAM)
+ */
+#define ILOC0_P 0x03 /* Lock Way 0 */
+#define ILOC1_P 0x04 /* Lock Way 1 */
+#define ILOC2_P 0x05 /* Lock Way 2 */
+#define ILOC3_P 0x06 /* Lock Way 3 */
+#define LRUPRIORST_P 0x0D /* Least Recently Used Replacement
+ * Priority
+ */
+/* Masks */
+#define ENIM 0x00000001 /* Enable L1 Code Memory */
+#define ENICPLB 0x00000002 /* Enable ICPLB */
+#define IMC 0x00000004 /* Configure L1 code memory as
+ * cache (0=SRAM)
+ */
+#define ILOC0 0x00000008 /* Lock Way 0 */
+#define ILOC1 0x00000010 /* Lock Way 1 */
+#define ILOC2 0x00000020 /* Lock Way 2 */
+#define ILOC3 0x00000040 /* Lock Way 3 */
+#define LRUPRIORST 0x00002000 /* Least Recently Used Replacement
+ * Priority
+ */
+
+/* TCNTL Masks */
+#define TMPWR 0x00000001 /* Timer Low Power Control,
+ * 0=low power mode, 1=active state
+ */
+#define TMREN 0x00000002 /* Timer enable, 0=disable, 1=enable */
+#define TAUTORLD 0x00000004 /* Timer auto reload */
+#define TINT 0x00000008 /* Timer generated interrupt 0=no
+ * interrupt has been generated,
+ * 1=interrupt has been generated
+ * (sticky)
+ */
+
+/* DCPLB_DATA and ICPLB_DATA Registers */
+/* Bit Positions */
+#define CPLB_VALID_P 0x00000000 /* 0=invalid entry, 1=valid entry */
+#define CPLB_LOCK_P 0x00000001 /* 0=entry may be replaced, 1=entry
+ * locked
+ */
+#define CPLB_USER_RD_P 0x00000002 /* 0=no read access, 1=read access
+ * allowed (user mode)
+ */
+/* Masks */
+#define CPLB_VALID 0x00000001 /* 0=invalid entry, 1=valid entry */
+#define CPLB_LOCK 0x00000002 /* 0=entry may be replaced, 1=entry
+ * locked
+ */
+#define CPLB_USER_RD 0x00000004 /* 0=no read access, 1=read access
+ * allowed (user mode)
+ */
+#define PAGE_SIZE_1KB 0x00000000 /* 1 KB page size */
+#define PAGE_SIZE_4KB 0x00010000 /* 4 KB page size */
+#define PAGE_SIZE_1MB 0x00020000 /* 1 MB page size */
+#define PAGE_SIZE_4MB 0x00030000 /* 4 MB page size */
+#define CPLB_L1SRAM 0x00000020 /* 0=SRAM mapped in L1, 0=SRAM not
+ * mapped to L1
+ */
+#define CPLB_PORTPRIO 0x00000200 /* 0=low priority port, 1= high
+ * priority port
+ */
+#define CPLB_L1_CHBL 0x00001000 /* 0=non-cacheable in L1, 1=cacheable
+ * in L1
+ */
+/* ICPLB_DATA only */
+#define CPLB_LRUPRIO 0x00000100 /* 0=can be replaced by any line,
+ * 1=priority for non-replacement
+ */
+/* DCPLB_DATA only */
+#define CPLB_USER_WR 0x00000008 /* 0=no write access, 0=write
+ * access allowed (user mode)
+ */
+#define CPLB_SUPV_WR 0x00000010 /* 0=no write access, 0=write
+ * access allowed (supervisor mode)
+ */
+#define CPLB_DIRTY 0x00000080 /* 1=dirty, 0=clean */
+#define CPLB_L1_AOW 0x00008000 /* 0=do not allocate cache lines on
+ * write-through writes,
+ * 1= allocate cache lines on
+ * write-through writes.
+ */
+#define CPLB_WT 0x00004000 /* 0=write-back, 1=write-through */
+
+/* TBUFCTL Masks */
+#define TBUFPWR 0x0001
+#define TBUFEN 0x0002
+#define TBUFOVF 0x0004
+#define TBUFCMPLP_SINGLE 0x0008
+#define TBUFCMPLP_DOUBLE 0x0010
+#define TBUFCMPLP (TBUFCMPLP_SINGLE | TBUFCMPLP_DOUBLE)
+
+/* TBUFSTAT Masks */
+#define TBUFCNT 0x001F
+
+/* ITEST_COMMAND and DTEST_COMMAND Registers */
+/* Masks */
+#define TEST_READ 0x00000000 /* Read Access */
+#define TEST_WRITE 0x00000002 /* Write Access */
+#define TEST_TAG 0x00000000 /* Access TAG */
+#define TEST_DATA 0x00000004 /* Access DATA */
+#define TEST_DW0 0x00000000 /* Select Double Word 0 */
+#define TEST_DW1 0x00000008 /* Select Double Word 1 */
+#define TEST_DW2 0x00000010 /* Select Double Word 2 */
+#define TEST_DW3 0x00000018 /* Select Double Word 3 */
+#define TEST_MB0 0x00000000 /* Select Mini-Bank 0 */
+#define TEST_MB1 0x00010000 /* Select Mini-Bank 1 */
+#define TEST_MB2 0x00020000 /* Select Mini-Bank 2 */
+#define TEST_MB3 0x00030000 /* Select Mini-Bank 3 */
+#define TEST_SET(x) ((x << 5) & 0x03E0) /* Set Index 0->31 */
+#define TEST_WAY0 0x00000000 /* Access Way0 */
+#define TEST_WAY1 0x04000000 /* Access Way1 */
+/* ITEST_COMMAND only */
+#define TEST_WAY2 0x08000000 /* Access Way2 */
+#define TEST_WAY3 0x0C000000 /* Access Way3 */
+/* DTEST_COMMAND only */
+#define TEST_BNKSELA 0x00000000 /* Access SuperBank A */
+#define TEST_BNKSELB 0x00800000 /* Access SuperBank B */
+
+#endif /* _DEF_LPBLACKFIN_H */
diff --git a/include/asm-blackfin/macros.h b/include/asm-blackfin/macros.h
new file mode 100644
index 0000000..c0c04a2
--- /dev/null
+++ b/include/asm-blackfin/macros.h
@@ -0,0 +1,95 @@
+/************************************************************************
+ *
+ * macros.h
+ *
+ * (c) Copyright 2001-2003 Analog Devices, Inc. All rights reserved.
+ *
+ ************************************************************************/
+
+/* Defines various assembly macros. */
+
+#ifndef _MACROS_H
+#define _MACROS_H
+
+#define LO(con32) ((con32) & 0xFFFF)
+#define lo(con32) ((con32) & 0xFFFF)
+#define HI(con32) (((con32) >> 16) & 0xFFFF)
+#define hi(con32) (((con32) >> 16) & 0xFFFF)
+
+/*
+ * Set the corresponding bits in a System Register (SR);
+ * All bits set in "mask" will be set in the system register
+ * specified by "sys_reg" bitset_SR(sys_reg, mask), where
+ * sys_reg is the system register and mask are the bits to be set.
+ */
+#define bitset_SR(sys_reg, mask)\
+ [--SP] = (R7:6);\
+ r7 = sys_reg;\
+ r6.l = (mask) & 0xffff;\
+ r6.h = (mask) >> 16;\
+ r7 = r7 | r6;\
+ sys_reg = r7;\
+ csync;\
+ (R7:6) = [SP++]
+
+/*
+ * Clear the corresponding bits in a System Register (SR);
+ * All bits set in "mask" will be cleared in the SR
+ * specified by "sys_reg" bitclr_SR(sys_reg, mask), where
+ * sys_reg is the SR and mask are the bits to be cleared.
+ */
+#define bitclr_SR(sys_reg, mask)\
+ [--SP] = (R7:6);\
+ r7 = sys_reg;\
+ r7 =~ r7;\
+ r6.l = (mask) & 0xffff;\
+ r6.h = (mask) >> 16;\
+ r7 = r7 | r6;\
+ r7 =~ r7;\
+ sys_reg = r7;\
+ csync;\
+ (R7:6) = [SP++]
+
+/*
+ * Set the corresponding bits in a Memory Mapped Register (MMR);
+ * All bits set in "mask" will be set in the MMR specified by "mmr_reg"
+ * bitset_MMR(mmr_reg, mask), where mmr_reg is the MMR and mask are
+ * the bits to be set.
+ */
+#define bitset_MMR(mmr_reg, mask)\
+ [--SP] = (R7:6);\
+ [--SP] = P5;\
+ p5.l = mmr_reg & 0xffff;\
+ p5.h = mmr_reg >> 16;\
+ r7 = [p5];\
+ r6.l = (mask) & 0xffff;\
+ r6.h = (mask) >> 16;\
+ r7 = r7 | r6;\
+ [p5] = r7;\
+ csync;\
+ p5 = [SP++];\
+ (R7:6) = [SP++]
+
+/*
+ * Clear the corresponding bits in a Memory Mapped Register (MMR);
+ * All bits set in "mask" will be cleared in the MMR specified by "mmr_reg"
+ * bitclr_MMRreg(mmr_reg, mask), where sys_reg is the MMR and mask are
+ * the bits to be cleared.
+ */
+#define bitclr_MMR(mmr_reg, mask)\
+ [--SP] = (R7:6);\
+ [--SP] = P5;\
+ p5.l = mmr_reg & 0xffff;\
+ p5.h = mmr_reg >> 16;\
+ r7 = [p5];\
+ r7 =~ r7;\
+ r6.l = (mask) & 0xffff;\
+ r6.h = (mask) >> 16;\
+ r7 = r7 | r6;\
+ r7 =~ r7;\
+ [p5] = r7;\
+ csync;\
+ p5 = [SP++];\
+ (R7:6) = [SP++]
+
+#endif /* _MACROS_H */
diff --git a/include/asm-blackfin/mem_map.h b/include/asm-blackfin/mem_map.h
new file mode 100644
index 0000000..42d1f37
--- /dev/null
+++ b/include/asm-blackfin/mem_map.h
@@ -0,0 +1,12 @@
+/*
+ * mem_map.h
+ * Common header file for blackfin family of processors.
+ *
+ */
+
+#ifndef _MEM_MAP_H_
+#define _MEM_MAP_H_
+
+#include <asm/mach/mem_map.h>
+
+#endif /* _MEM_MAP_H_ */
diff --git a/include/asm-blackfin/mman.h b/include/asm-blackfin/mman.h
new file mode 100644
index 0000000..4d504f9
--- /dev/null
+++ b/include/asm-blackfin/mman.h
@@ -0,0 +1,45 @@
+#ifndef __BFIN_MMAN_H__
+#define __BFIN_MMAN_H__
+
+#define PROT_READ 0x1 /* page can be read */
+#define PROT_WRITE 0x2 /* page can be written */
+#define PROT_EXEC 0x4 /* page can be executed */
+#define PROT_SEM 0x8 /* page may be used for atomic ops */
+#define PROT_NONE 0x0 /* page can not be accessed */
+#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */
+#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */
+
+#define MAP_SHARED 0x01 /* Share changes */
+#define MAP_PRIVATE 0x02 /* Changes are private */
+#define MAP_TYPE 0x0f /* Mask for type of mapping */
+#define MAP_FIXED 0x10 /* Interpret addr exactly */
+#define MAP_ANONYMOUS 0x20 /* don't use a file */
+
+#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
+#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
+#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
+#define MAP_LOCKED 0x2000 /* pages are locked */
+#define MAP_NORESERVE 0x4000 /* don't check for reservations */
+#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
+#define MAP_NONBLOCK 0x10000 /* do not block on IO */
+#define MAP_UNINITIALIZE 0x4000000 /* For anonymous mmap, memory could
+ be uninitialized. */
+
+#define MS_ASYNC 1 /* sync memory asynchronously */
+#define MS_INVALIDATE 2 /* invalidate the caches */
+#define MS_SYNC 4 /* synchronous memory sync */
+
+#define MCL_CURRENT 1 /* lock all current mappings */
+#define MCL_FUTURE 2 /* lock all future mappings */
+
+#define MADV_NORMAL 0x0 /* default page-in behavior */
+#define MADV_RANDOM 0x1 /* page-in minimum required */
+#define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */
+#define MADV_WILLNEED 0x3 /* pre-fault pages */
+#define MADV_DONTNEED 0x4 /* discard these pages */
+
+/* compatibility flags */
+#define MAP_ANON MAP_ANONYMOUS
+#define MAP_FILE 0
+
+#endif /* __BFIN_MMAN_H__ */
diff --git a/include/asm-blackfin/mmu.h b/include/asm-blackfin/mmu.h
new file mode 100644
index 0000000..11d52f1
--- /dev/null
+++ b/include/asm-blackfin/mmu.h
@@ -0,0 +1,30 @@
+#ifndef __MMU_H
+#define __MMU_H
+
+/* Copyright (C) 2002, David McCullough <davidm@snapgear.com> */
+
+struct sram_list_struct {
+ struct sram_list_struct *next;
+ void *addr;
+ size_t length;
+};
+
+typedef struct {
+ struct vm_list_struct *vmlist;
+ unsigned long end_brk;
+ unsigned long stack_start;
+
+ /* Points to the location in SDRAM where the L1 stack is normally
+ saved, or NULL if the stack is always in SDRAM. */
+ void *l1_stack_save;
+
+ struct sram_list_struct *sram_list;
+
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+ unsigned long exec_fdpic_loadmap;
+ unsigned long interp_fdpic_loadmap;
+#endif
+
+} mm_context_t;
+
+#endif
diff --git a/include/asm-blackfin/mmu_context.h b/include/asm-blackfin/mmu_context.h
new file mode 100644
index 0000000..c5c71a6
--- /dev/null
+++ b/include/asm-blackfin/mmu_context.h
@@ -0,0 +1,129 @@
+/*
+ * File: include/asm-blackfin/mmu_context.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __BLACKFIN_MMU_CONTEXT_H__
+#define __BLACKFIN_MMU_CONTEXT_H__
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+extern void *current_l1_stack_save;
+extern int nr_l1stack_tasks;
+extern void *l1_stack_base;
+extern unsigned long l1_stack_len;
+
+extern int l1sram_free(const void*);
+extern void *l1sram_alloc_max(void*);
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+/* Called when creating a new context during fork() or execve(). */
+static inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+ return 0;
+}
+
+static inline void free_l1stack(void)
+{
+ nr_l1stack_tasks--;
+ if (nr_l1stack_tasks == 0)
+ l1sram_free(l1_stack_base);
+}
+static inline void destroy_context(struct mm_struct *mm)
+{
+ struct sram_list_struct *tmp;
+
+ if (current_l1_stack_save == mm->context.l1_stack_save)
+ current_l1_stack_save = 0;
+ if (mm->context.l1_stack_save)
+ free_l1stack();
+
+ while ((tmp = mm->context.sram_list)) {
+ mm->context.sram_list = tmp->next;
+ sram_free(tmp->addr);
+ kfree(tmp);
+ }
+}
+
+static inline unsigned long
+alloc_l1stack(unsigned long length, unsigned long *stack_base)
+{
+ if (nr_l1stack_tasks == 0) {
+ l1_stack_base = l1sram_alloc_max(&l1_stack_len);
+ if (!l1_stack_base)
+ return 0;
+ }
+
+ if (l1_stack_len < length) {
+ if (nr_l1stack_tasks == 0)
+ l1sram_free(l1_stack_base);
+ return 0;
+ }
+ *stack_base = (unsigned long)l1_stack_base;
+ nr_l1stack_tasks++;
+ return l1_stack_len;
+}
+
+static inline int
+activate_l1stack(struct mm_struct *mm, unsigned long sp_base)
+{
+ if (current_l1_stack_save)
+ memcpy(current_l1_stack_save, l1_stack_base, l1_stack_len);
+ mm->context.l1_stack_save = current_l1_stack_save = (void*)sp_base;
+ memcpy(l1_stack_base, current_l1_stack_save, l1_stack_len);
+ return 1;
+}
+
+#define deactivate_mm(tsk,mm) do { } while (0)
+
+static inline void activate_mm(struct mm_struct *prev_mm,
+ struct mm_struct *next_mm)
+{
+ if (!next_mm->context.l1_stack_save)
+ return;
+ if (next_mm->context.l1_stack_save == current_l1_stack_save)
+ return;
+ if (current_l1_stack_save) {
+ memcpy(current_l1_stack_save, l1_stack_base, l1_stack_len);
+ }
+ current_l1_stack_save = next_mm->context.l1_stack_save;
+ memcpy(l1_stack_base, current_l1_stack_save, l1_stack_len);
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+ struct task_struct *tsk)
+{
+ activate_mm(prev, next);
+}
+
+#endif
diff --git a/include/asm-blackfin/module.h b/include/asm-blackfin/module.h
new file mode 100644
index 0000000..3c7ce16
--- /dev/null
+++ b/include/asm-blackfin/module.h
@@ -0,0 +1,19 @@
+#ifndef _ASM_BFIN_MODULE_H
+#define _ASM_BFIN_MODULE_H
+
+#define MODULE_SYMBOL_PREFIX "_"
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+#define FLG_CODE_IN_L1 0x10
+#define FLG_DATA_IN_L1 0x20
+
+struct mod_arch_specific {
+ Elf_Shdr *text_l1;
+ Elf_Shdr *data_a_l1;
+ Elf_Shdr *bss_a_l1;
+ Elf_Shdr *data_b_l1;
+ Elf_Shdr *bss_b_l1;
+};
+#endif /* _ASM_BFIN_MODULE_H */
diff --git a/include/asm-blackfin/msgbuf.h b/include/asm-blackfin/msgbuf.h
new file mode 100644
index 0000000..6fcbe8c
--- /dev/null
+++ b/include/asm-blackfin/msgbuf.h
@@ -0,0 +1,31 @@
+#ifndef _BFIN_MSGBUF_H
+#define _BFIN_MSGBUF_H
+
+/*
+ * The msqid64_ds structure for bfin architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+ struct ipc64_perm msg_perm;
+ __kernel_time_t msg_stime; /* last msgsnd time */
+ unsigned long __unused1;
+ __kernel_time_t msg_rtime; /* last msgrcv time */
+ unsigned long __unused2;
+ __kernel_time_t msg_ctime; /* last change time */
+ unsigned long __unused3;
+ unsigned long msg_cbytes; /* current number of bytes on queue */
+ unsigned long msg_qnum; /* number of messages in queue */
+ unsigned long msg_qbytes; /* max number of bytes on queue */
+ __kernel_pid_t msg_lspid; /* pid of last msgsnd */
+ __kernel_pid_t msg_lrpid; /* last receive pid */
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+#endif /* _BFIN_MSGBUF_H */
diff --git a/include/asm-blackfin/mutex.h b/include/asm-blackfin/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-blackfin/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-blackfin/namei.h b/include/asm-blackfin/namei.h
new file mode 100644
index 0000000..8b89a2d
--- /dev/null
+++ b/include/asm-blackfin/namei.h
@@ -0,0 +1,19 @@
+/*
+ * linux/include/asm/namei.h
+ *
+ * Included from linux/fs/namei.c
+ *
+ * Changes made by Lineo Inc. May 2001
+ */
+
+#ifndef __BFIN_NAMEI_H
+#define __BFIN_NAMEI_H
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __emul_prefix() NULL
+
+#endif
diff --git a/include/asm-blackfin/page.h b/include/asm-blackfin/page.h
new file mode 100644
index 0000000..ffad947
--- /dev/null
+++ b/include/asm-blackfin/page.h
@@ -0,0 +1,89 @@
+#ifndef _BLACKFIN_PAGE_H
+#define _BLACKFIN_PAGE_H
+
+/* PAGE_SHIFT determines the page size */
+
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+
+#include <asm/setup.h>
+
+#ifndef __ASSEMBLY__
+
+#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr) free_page(addr)
+
+#define clear_page(page) memset((page), 0, PAGE_SIZE)
+#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(page, vaddr,pg) clear_page(page)
+#define copy_user_page(to, from, vaddr,pg) copy_page(to, from)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct {
+ unsigned long pte;
+} pte_t;
+typedef struct {
+ unsigned long pmd[16];
+} pmd_t;
+typedef struct {
+ unsigned long pgd;
+} pgd_t;
+typedef struct {
+ unsigned long pgprot;
+} pgprot_t;
+
+#define pte_val(x) ((x).pte)
+#define pmd_val(x) ((&x)->pmd[0])
+#define pgd_val(x) ((x).pgd)
+#define pgprot_val(x) ((x).pgprot)
+
+#define __pte(x) ((pte_t) { (x) } )
+#define __pmd(x) ((pmd_t) { (x) } )
+#define __pgd(x) ((pgd_t) { (x) } )
+#define __pgprot(x) ((pgprot_t) { (x) } )
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+extern unsigned long memory_start;
+extern unsigned long memory_end;
+
+#endif /* !__ASSEMBLY__ */
+
+#include <asm/page_offset.h>
+#include <asm/io.h>
+
+#define PAGE_OFFSET (PAGE_OFFSET_RAW)
+
+#ifndef __ASSEMBLY__
+
+#define __pa(vaddr) virt_to_phys((void *)(vaddr))
+#define __va(paddr) phys_to_virt((unsigned long)(paddr))
+
+#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
+
+#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT)
+#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT)
+#define virt_to_page(addr) (mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
+#define page_to_virt(page) ((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)
+#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
+
+#define pfn_to_page(pfn) virt_to_page(pfn_to_virt(pfn))
+#define page_to_pfn(page) virt_to_pfn(page_to_virt(page))
+#define pfn_valid(pfn) ((pfn) < max_mapnr)
+
+#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \
+ ((void *)(kaddr) < (void *)memory_end))
+
+#include <asm-generic/page.h>
+
+#endif /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+
+#endif /* _BLACKFIN_PAGE_H */
diff --git a/include/asm-blackfin/page_offset.h b/include/asm-blackfin/page_offset.h
new file mode 100644
index 0000000..3b671d5
--- /dev/null
+++ b/include/asm-blackfin/page_offset.h
@@ -0,0 +1,6 @@
+
+/* This handles the memory map.. */
+
+#ifdef CONFIG_BFIN
+#define PAGE_OFFSET_RAW 0x00000000
+#endif
diff --git a/include/asm-blackfin/param.h b/include/asm-blackfin/param.h
new file mode 100644
index 0000000..41564a6
--- /dev/null
+++ b/include/asm-blackfin/param.h
@@ -0,0 +1,22 @@
+#ifndef _BLACKFIN_PARAM_H
+#define _BLACKFIN_PARAM_H
+
+#ifdef __KERNEL__
+#define HZ CONFIG_HZ
+#define USER_HZ 100
+#define CLOCKS_PER_SEC (USER_HZ)
+#endif
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#define EXEC_PAGESIZE 4096
+
+#ifndef NOGROUP
+#define NOGROUP (-1)
+#endif
+
+#define MAXHOSTNAMELEN 64 /* max length of hostname */
+
+#endif /* _BLACKFIN_PARAM_H */
diff --git a/include/asm-blackfin/pci.h b/include/asm-blackfin/pci.h
new file mode 100644
index 0000000..6127735
--- /dev/null
+++ b/include/asm-blackfin/pci.h
@@ -0,0 +1,148 @@
+/* Changed from asm-m68k version, Lineo Inc. May 2001 */
+
+#ifndef _ASM_BFIN_PCI_H
+#define _ASM_BFIN_PCI_H
+
+#include <asm/scatterlist.h>
+
+/*
+ *
+ * Written by Wout Klaren.
+ */
+
+/* Added by Chang Junxiao */
+#define PCIBIOS_MIN_IO 0x00001000
+#define PCIBIOS_MIN_MEM 0x10000000
+
+#define PCI_DMA_BUS_IS_PHYS (1)
+struct pci_ops;
+
+/*
+ * Structure with hardware dependent information and functions of the
+ * PCI bus.
+ */
+struct pci_bus_info {
+
+ /*
+ * Resources of the PCI bus.
+ */
+ struct resource mem_space;
+ struct resource io_space;
+
+ /*
+ * System dependent functions.
+ */
+ struct pci_ops *bfin_pci_ops;
+ void (*fixup) (int pci_modify);
+ void (*conf_device) (unsigned char bus, unsigned char device_fn);
+};
+
+#define pcibios_assign_all_busses() 0
+static inline void pcibios_set_master(struct pci_dev *dev)
+{
+
+ /* No special bus mastering setup handling */
+}
+static inline void pcibios_penalize_isa_irq(int irq)
+{
+
+ /* We don't do dynamic PCI IRQ allocation */
+}
+static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+ size_t size, int direction)
+{
+ if (direction == PCI_DMA_NONE)
+ BUG();
+
+ /* return virt_to_bus(ptr); */
+ return (dma_addr_t) ptr;
+}
+
+/* Unmap a single streaming mode DMA translation. The dma_addr and size
+ * must match what was provided for in a previous pci_map_single call. All
+ * other usages are undefined.
+ *
+ * After this call, reads by the cpu to the buffer are guarenteed to see
+ * whatever the device wrote there.
+ */
+static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+ size_t size, int direction)
+{
+ if (direction == PCI_DMA_NONE)
+ BUG();
+
+ /* Nothing to do */
+}
+
+/* Map a set of buffers described by scatterlist in streaming
+ * mode for DMA. This is the scather-gather version of the
+ * above pci_map_single interface. Here the scatter gather list
+ * elements are each tagged with the appropriate dma address
+ * and length. They are obtained via sg_dma_{address,length}(SG).
+ *
+ * NOTE: An implementation may be able to use a smaller number of
+ * DMA address/length pairs than there are SG table elements.
+ * (for example via virtual mapping capabilities)
+ * The routine returns the number of addr/length pairs actually
+ * used, at most nents.
+ *
+ * Device ownership issues as mentioned above for pci_map_single are
+ * the same here.
+ */
+static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+ int nents, int direction)
+{
+ if (direction == PCI_DMA_NONE)
+ BUG();
+ return nents;
+}
+
+/* Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+ int nents, int direction)
+{
+ if (direction == PCI_DMA_NONE)
+ BUG();
+
+ /* Nothing to do */
+}
+
+/* Make physical memory consistent for a single
+ * streaming mode DMA translation after a transfer.
+ *
+ * If you perform a pci_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so. At the
+ * next point you give the PCI dma address back to the card, the
+ * device again owns the buffer.
+ */
+static inline void pci_dma_sync_single(struct pci_dev *hwdev,
+ dma_addr_t dma_handle, size_t size,
+ int direction)
+{
+ if (direction == PCI_DMA_NONE)
+ BUG();
+
+ /* Nothing to do */
+}
+
+/* Make physical memory consistent for a set of streaming
+ * mode DMA translations after a transfer.
+ *
+ * The same as pci_dma_sync_single but for a scatter-gather list,
+ * same rules and usage.
+ */
+static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+ struct scatterlist *sg, int nelems,
+ int direction)
+{
+ if (direction == PCI_DMA_NONE)
+ BUG();
+
+ /* Nothing to do */
+}
+
+#endif /* _ASM_BFIN_PCI_H */
diff --git a/include/asm-blackfin/percpu.h b/include/asm-blackfin/percpu.h
new file mode 100644
index 0000000..78dd61f
--- /dev/null
+++ b/include/asm-blackfin/percpu.h
@@ -0,0 +1,6 @@
+#ifndef __ARCH_BLACKFIN_PERCPU__
+#define __ARCH_BLACKFIN_PERCPU__
+
+#include <asm-generic/percpu.h>
+
+#endif /* __ARCH_BLACKFIN_PERCPU__ */
diff --git a/include/asm-blackfin/pgalloc.h b/include/asm-blackfin/pgalloc.h
new file mode 100644
index 0000000..c686e05
--- /dev/null
+++ b/include/asm-blackfin/pgalloc.h
@@ -0,0 +1,8 @@
+#ifndef _BLACKFIN_PGALLOC_H
+#define _BLACKFIN_PGALLOC_H
+
+#include <asm/setup.h>
+
+#define check_pgt_cache() do { } while (0)
+
+#endif /* _BLACKFIN_PGALLOC_H */
diff --git a/include/asm-blackfin/pgtable.h b/include/asm-blackfin/pgtable.h
new file mode 100644
index 0000000..5a8f9e4
--- /dev/null
+++ b/include/asm-blackfin/pgtable.h
@@ -0,0 +1,96 @@
+#ifndef _BLACKFIN_PGTABLE_H
+#define _BLACKFIN_PGTABLE_H
+
+#include <asm-generic/4level-fixup.h>
+
+#include <asm/page.h>
+#include <asm/cplb.h>
+
+typedef pte_t *pte_addr_t;
+/*
+* Trivial page table functions.
+*/
+#define pgd_present(pgd) (1)
+#define pgd_none(pgd) (0)
+#define pgd_bad(pgd) (0)
+#define pgd_clear(pgdp)
+#define kern_addr_valid(addr) (1)
+
+#define pmd_offset(a, b) ((void *)0)
+#define pmd_none(x) (!pmd_val(x))
+#define pmd_present(x) (pmd_val(x))
+#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
+#define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK)
+
+#define kern_addr_valid(addr) (1)
+
+#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_COPY __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_READONLY __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_KERNEL __pgprot(0) /* these mean nothing to NO_MM */
+
+extern void paging_init(void);
+
+#define __swp_type(x) (0)
+#define __swp_offset(x) (0)
+#define __swp_entry(typ,off) ((swp_entry_t) { ((typ) | ((off) << 7)) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
+
+static inline int pte_file(pte_t pte)
+{
+ return 0;
+}
+
+#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
+#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
+
+/*
+ * Page assess control based on Blackfin CPLB management
+ */
+#define _PAGE_RD (CPLB_USER_RD)
+#define _PAGE_WR (CPLB_USER_WR)
+#define _PAGE_USER (CPLB_USER_RD | CPLB_USER_WR)
+#define _PAGE_ACCESSED CPLB_ALL_ACCESS
+#define _PAGE_DIRTY (CPLB_DIRTY)
+
+#define PTE_BIT_FUNC(fn, op) \
+ static inline pte_t pte_##fn(pte_t _pte) { _pte.pte op; return _pte; }
+
+PTE_BIT_FUNC(rdprotect, &= ~_PAGE_RD);
+PTE_BIT_FUNC(mkread, |= _PAGE_RD);
+PTE_BIT_FUNC(wrprotect, &= ~_PAGE_WR);
+PTE_BIT_FUNC(mkwrite, |= _PAGE_WR);
+PTE_BIT_FUNC(exprotect, &= ~_PAGE_USER);
+PTE_BIT_FUNC(mkexec, |= _PAGE_USER);
+PTE_BIT_FUNC(mkclean, &= ~_PAGE_DIRTY);
+PTE_BIT_FUNC(mkdirty, |= _PAGE_DIRTY);
+PTE_BIT_FUNC(mkold, &= ~_PAGE_ACCESSED);
+PTE_BIT_FUNC(mkyoung, |= _PAGE_ACCESSED);
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+#define ZERO_PAGE(vaddr) (virt_to_page(0))
+
+extern unsigned int kobjsize(const void *objp);
+
+#define swapper_pg_dir ((pgd_t *) 0)
+/*
+ * No page table caches to initialise.
+ */
+#define pgtable_cache_init() do { } while (0)
+#define io_remap_pfn_range remap_pfn_range
+
+/*
+ * All 32bit addresses are effectively valid for vmalloc...
+ * Sort of meaningless for non-VM targets.
+ */
+#define VMALLOC_START 0
+#define VMALLOC_END 0xffffffff
+
+#include <asm-generic/pgtable.h>
+
+#endif /* _BLACKFIN_PGTABLE_H */
diff --git a/include/asm-blackfin/poll.h b/include/asm-blackfin/poll.h
new file mode 100644
index 0000000..94cc263
--- /dev/null
+++ b/include/asm-blackfin/poll.h
@@ -0,0 +1,24 @@
+#ifndef __BFIN_POLL_H
+#define __BFIN_POLL_H
+
+#define POLLIN 1
+#define POLLPRI 2
+#define POLLOUT 4
+#define POLLERR 8
+#define POLLHUP 16
+#define POLLNVAL 32
+#define POLLRDNORM 64
+#define POLLWRNORM POLLOUT
+#define POLLRDBAND 128
+#define POLLWRBAND 256
+#define POLLMSG 0x0400
+#define POLLREMOVE 0x1000
+#define POLLRDHUP 0x2000
+
+struct pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+
+#endif /* __BFIN_POLL_H */
diff --git a/include/asm-blackfin/posix_types.h b/include/asm-blackfin/posix_types.h
new file mode 100644
index 0000000..c3fa50f
--- /dev/null
+++ b/include/asm-blackfin/posix_types.h
@@ -0,0 +1,65 @@
+#ifndef __ARCH_BFIN_POSIX_TYPES_H
+#define __ARCH_BFIN_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc. Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long __kernel_ino_t;
+typedef unsigned short __kernel_mode_t;
+typedef unsigned short __kernel_nlink_t;
+typedef long __kernel_off_t;
+typedef int __kernel_pid_t;
+typedef unsigned int __kernel_ipc_pid_t;
+typedef unsigned int __kernel_uid_t;
+typedef unsigned int __kernel_gid_t;
+typedef unsigned long __kernel_size_t;
+typedef long __kernel_ssize_t;
+typedef int __kernel_ptrdiff_t;
+typedef long __kernel_time_t;
+typedef long __kernel_suseconds_t;
+typedef long __kernel_clock_t;
+typedef int __kernel_timer_t;
+typedef int __kernel_clockid_t;
+typedef int __kernel_daddr_t;
+typedef char *__kernel_caddr_t;
+typedef unsigned short __kernel_uid16_t;
+typedef unsigned short __kernel_gid16_t;
+typedef unsigned int __kernel_uid32_t;
+typedef unsigned int __kernel_gid32_t;
+
+typedef unsigned short __kernel_old_uid_t;
+typedef unsigned short __kernel_old_gid_t;
+typedef unsigned short __kernel_old_dev_t;
+
+#ifdef __GNUC__
+typedef long long __kernel_loff_t;
+#endif
+
+typedef struct {
+#if defined(__KERNEL__) || defined(__USE_ALL)
+ int val[2];
+#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+ int __val[2];
+#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
+#undef __FD_SET
+#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+
+#undef __FD_CLR
+#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+
+#undef __FD_ISSET
+#define __FD_ISSET(d, set) ((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+
+#undef __FD_ZERO
+#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+
+#endif
diff --git a/include/asm-blackfin/processor.h b/include/asm-blackfin/processor.h
new file mode 100644
index 0000000..997465c
--- /dev/null
+++ b/include/asm-blackfin/processor.h
@@ -0,0 +1,130 @@
+#ifndef __ASM_BFIN_PROCESSOR_H
+#define __ASM_BFIN_PROCESSOR_H
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <asm/blackfin.h>
+#include <asm/segment.h>
+#include <linux/compiler.h>
+
+static inline unsigned long rdusp(void)
+{
+ unsigned long usp;
+
+ __asm__ __volatile__("%0 = usp;\n\t":"=da"(usp));
+ return usp;
+}
+
+static inline void wrusp(unsigned long usp)
+{
+ __asm__ __volatile__("usp = %0;\n\t"::"da"(usp));
+}
+
+/*
+ * User space process size: 1st byte beyond user address space.
+ */
+extern unsigned long memory_end;
+#define TASK_SIZE (memory_end)
+
+#define TASK_UNMAPPED_BASE 0
+
+struct thread_struct {
+ unsigned long ksp; /* kernel stack pointer */
+ unsigned long usp; /* user stack pointer */
+ unsigned short seqstat; /* saved status register */
+ unsigned long esp0; /* points to SR of stack frame pt_regs */
+ unsigned long pc; /* instruction pointer */
+ void * debuggerinfo;
+};
+
+#define INIT_THREAD { \
+ sizeof(init_stack) + (unsigned long) init_stack, 0, \
+ PS_S, 0, 0 \
+}
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ *
+ * pass the data segment into user programs if it exists,
+ * it can't hurt anything as far as I can tell
+ */
+#define start_thread(_regs, _pc, _usp) \
+do { \
+ set_fs(USER_DS); \
+ (_regs)->pc = (_pc); \
+ if (current->mm) \
+ (_regs)->p5 = current->mm->start_data; \
+ current->thread_info->l1_task_info.stack_start \
+ = (void *)current->mm->context.stack_start; \
+ current->thread_info->l1_task_info.lowest_sp = (void *)(_usp); \
+ memcpy(L1_SCRATCH_TASK_INFO, &current->thread_info->l1_task_info, \
+ sizeof(*L1_SCRATCH_TASK_INFO)); \
+ wrusp(_usp); \
+} while(0)
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+#define prepare_to_copy(tsk) do { } while (0)
+
+extern int kernel_thread(int (*fn) (void *), void *arg, unsigned long flags);
+
+/*
+ * Free current thread data structures etc..
+ */
+static inline void exit_thread(void)
+{
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+#define thread_saved_pc(tsk) (tsk->thread.pc)
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define KSTK_EIP(tsk) \
+ ({ \
+ unsigned long eip = 0; \
+ if ((tsk)->thread.esp0 > PAGE_SIZE && \
+ MAP_NR((tsk)->thread.esp0) < max_mapnr) \
+ eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
+ eip; })
+#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp)
+
+#define cpu_relax() barrier()
+
+/* Get the Silicon Revision of the chip */
+static inline uint32_t bfin_revid(void)
+{
+ /* stored in the upper 4 bits */
+ return bfin_read_CHIPID() >> 28;
+}
+
+static inline uint32_t bfin_compiled_revid(void)
+{
+#if defined(CONFIG_BF_REV_0_0)
+ return 0;
+#elif defined(CONFIG_BF_REV_0_1)
+ return 1;
+#elif defined(CONFIG_BF_REV_0_2)
+ return 2;
+#elif defined(CONFIG_BF_REV_0_3)
+ return 3;
+#elif defined(CONFIG_BF_REV_0_4)
+ return 4;
+#elif defined(CONFIG_BF_REV_0_5)
+ return 5;
+#endif
+}
+
+#endif
diff --git a/include/asm-blackfin/ptrace.h b/include/asm-blackfin/ptrace.h
new file mode 100644
index 0000000..b8346cd
--- /dev/null
+++ b/include/asm-blackfin/ptrace.h
@@ -0,0 +1,166 @@
+#ifndef _BFIN_PTRACE_H
+#define _BFIN_PTRACE_H
+
+/*
+ * GCC defines register number like this:
+ * -----------------------------
+ * 0 - 7 are data registers R0-R7
+ * 8 - 15 are address registers P0-P7
+ * 16 - 31 dsp registers I/B/L0 -- I/B/L3 & M0--M3
+ * 32 - 33 A registers A0 & A1
+ * 34 - status register
+ * -----------------------------
+ *
+ * We follows above, except:
+ * 32-33 --- Low 32-bit of A0&1
+ * 34-35 --- High 8-bit of A0&1
+ */
+
+#ifndef __ASSEMBLY__
+
+/* this struct defines the way the registers are stored on the
+ stack during a system call. */
+
+struct pt_regs {
+ long orig_pc;
+ long ipend;
+ long seqstat;
+ long rete;
+ long retn;
+ long retx;
+ long pc; /* PC == RETI */
+ long rets;
+ long reserved; /* Used as scratch during system calls */
+ long astat;
+ long lb1;
+ long lb0;
+ long lt1;
+ long lt0;
+ long lc1;
+ long lc0;
+ long a1w;
+ long a1x;
+ long a0w;
+ long a0x;
+ long b3;
+ long b2;
+ long b1;
+ long b0;
+ long l3;
+ long l2;
+ long l1;
+ long l0;
+ long m3;
+ long m2;
+ long m1;
+ long m0;
+ long i3;
+ long i2;
+ long i1;
+ long i0;
+ long usp;
+ long fp;
+ long p5;
+ long p4;
+ long p3;
+ long p2;
+ long p1;
+ long p0;
+ long r7;
+ long r6;
+ long r5;
+ long r4;
+ long r3;
+ long r2;
+ long r1;
+ long r0;
+ long orig_r0;
+ long orig_p0;
+ long syscfg;
+};
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13 /* ptrace signal */
+
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+#define PTRACE_GETFDPIC 31
+#define PTRACE_GETFDPIC_EXEC 0
+#define PTRACE_GETFDPIC_INTERP 1
+#endif
+
+#define PS_S (0x0002)
+
+/* user_mode returns true if only one bit is set in IPEND, other than the
+ master interrupt enable. */
+#define user_mode(regs) (!(((regs)->ipend & ~0x10) & (((regs)->ipend & ~0x10) - 1)))
+#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
+extern void show_regs(struct pt_regs *);
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Offsets used by 'ptrace' system call interface.
+ */
+
+#define PT_R0 204
+#define PT_R1 200
+#define PT_R2 196
+#define PT_R3 192
+#define PT_R4 188
+#define PT_R5 184
+#define PT_R6 180
+#define PT_R7 176
+#define PT_P0 172
+#define PT_P1 168
+#define PT_P2 164
+#define PT_P3 160
+#define PT_P4 156
+#define PT_P5 152
+#define PT_FP 148
+#define PT_USP 144
+#define PT_I0 140
+#define PT_I1 136
+#define PT_I2 132
+#define PT_I3 128
+#define PT_M0 124
+#define PT_M1 120
+#define PT_M2 116
+#define PT_M3 112
+#define PT_L0 108
+#define PT_L1 104
+#define PT_L2 100
+#define PT_L3 96
+#define PT_B0 92
+#define PT_B1 88
+#define PT_B2 84
+#define PT_B3 80
+#define PT_A0X 76
+#define PT_A0W 72
+#define PT_A1X 68
+#define PT_A1W 64
+#define PT_LC0 60
+#define PT_LC1 56
+#define PT_LT0 52
+#define PT_LT1 48
+#define PT_LB0 44
+#define PT_LB1 40
+#define PT_ASTAT 36
+#define PT_RESERVED 32
+#define PT_RETS 28
+#define PT_PC 24
+#define PT_RETX 20
+#define PT_RETN 16
+#define PT_RETE 12
+#define PT_SEQSTAT 8
+#define PT_IPEND 4
+
+#define PT_SYSCFG 216
+#define PT_TEXT_ADDR 220
+#define PT_TEXT_END_ADDR 224
+#define PT_DATA_ADDR 228
+#define PT_FDPIC_EXEC 232
+#define PT_FDPIC_INTERP 236
+
+#endif /* _BFIN_PTRACE_H */
diff --git a/include/asm-blackfin/resource.h b/include/asm-blackfin/resource.h
new file mode 100644
index 0000000..091355a
--- /dev/null
+++ b/include/asm-blackfin/resource.h
@@ -0,0 +1,6 @@
+#ifndef _BFIN_RESOURCE_H
+#define _BFIN_RESOURCE_H
+
+#include <asm-generic/resource.h>
+
+#endif /* _BFIN_RESOURCE_H */
diff --git a/include/asm-blackfin/scatterlist.h b/include/asm-blackfin/scatterlist.h
new file mode 100644
index 0000000..60e07b9
--- /dev/null
+++ b/include/asm-blackfin/scatterlist.h
@@ -0,0 +1,26 @@
+#ifndef _BLACKFIN_SCATTERLIST_H
+#define _BLACKFIN_SCATTERLIST_H
+
+#include <linux/mm.h>
+
+struct scatterlist {
+ struct page *page;
+ unsigned int offset;
+ dma_addr_t dma_address;
+ unsigned int length;
+};
+
+/*
+ * These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_address(sg) (page_address((sg)->page) + (sg)->offset)
+#define sg_dma_address(sg) ((sg)->dma_address)
+#define sg_dma_len(sg) ((sg)->length)
+
+#define ISA_DMA_THRESHOLD (0xffffffff)
+
+#endif /* !(_BLACKFIN_SCATTERLIST_H) */
diff --git a/include/asm-blackfin/sections.h b/include/asm-blackfin/sections.h
new file mode 100644
index 0000000..1443c33
--- /dev/null
+++ b/include/asm-blackfin/sections.h
@@ -0,0 +1,7 @@
+#ifndef _BLACKFIN_SECTIONS_H
+#define _BLACKFIN_SECTIONS_H
+
+/* nothing to see, move along */
+#include <asm-generic/sections.h>
+
+#endif
diff --git a/include/asm-blackfin/segment.h b/include/asm-blackfin/segment.h
new file mode 100644
index 0000000..02cfd09
--- /dev/null
+++ b/include/asm-blackfin/segment.h
@@ -0,0 +1,7 @@
+#ifndef _BFIN_SEGMENT_H
+#define _BFIN_SEGMENT_H
+
+#define KERNEL_DS (0x5)
+#define USER_DS (0x1)
+
+#endif /* _BFIN_SEGMENT_H */
diff --git a/include/asm-blackfin/semaphore-helper.h b/include/asm-blackfin/semaphore-helper.h
new file mode 100644
index 0000000..9082b0d
--- /dev/null
+++ b/include/asm-blackfin/semaphore-helper.h
@@ -0,0 +1,82 @@
+/* Based on M68K version, Lineo Inc. May 2001 */
+
+#ifndef _BFIN_SEMAPHORE_HELPER_H
+#define _BFIN_SEMAPHORE_HELPER_H
+
+/*
+ * SMP- and interrupt-safe semaphores helper functions.
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ *
+ */
+
+#include <asm/errno.h>
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ */
+static inline void wake_one_more(struct semaphore *sem)
+{
+ atomic_inc(&sem->waking);
+}
+
+static inline int waking_non_zero(struct semaphore *sem)
+{
+ int ret;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&semaphore_wake_lock, flags);
+ ret = 0;
+ if (atomic_read(&sem->waking) > 0) {
+ atomic_dec(&sem->waking);
+ ret = 1;
+ }
+ spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+ return ret;
+}
+
+/*
+ * waking_non_zero_interruptible:
+ * 1 got the lock
+ * 0 go to sleep
+ * -EINTR interrupted
+ */
+static inline int waking_non_zero_interruptible(struct semaphore *sem,
+ struct task_struct *tsk)
+{
+ int ret = 0;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&semaphore_wake_lock, flags);
+ if (atomic_read(&sem->waking) > 0) {
+ atomic_dec(&sem->waking);
+ ret = 1;
+ } else if (signal_pending(tsk)) {
+ atomic_inc(&sem->count);
+ ret = -EINTR;
+ }
+ spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+ return ret;
+}
+
+/*
+ * waking_non_zero_trylock:
+ * 1 failed to lock
+ * 0 got the lock
+ */
+static inline int waking_non_zero_trylock(struct semaphore *sem)
+{
+ int ret = 1;
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&semaphore_wake_lock, flags);
+ if (atomic_read(&sem->waking) > 0) {
+ atomic_dec(&sem->waking);
+ ret = 0;
+ } else
+ atomic_inc(&sem->count);
+ spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+ return ret;
+}
+
+#endif /* _BFIN_SEMAPHORE_HELPER_H */
diff --git a/include/asm-blackfin/semaphore.h b/include/asm-blackfin/semaphore.h
new file mode 100644
index 0000000..94c04d7
--- /dev/null
+++ b/include/asm-blackfin/semaphore.h
@@ -0,0 +1,106 @@
+#ifndef _BFIN_SEMAPHORE_H
+#define _BFIN_SEMAPHORE_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/linkage.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/rwsem.h>
+#include <asm/atomic.h>
+
+/*
+ * Interrupt-safe semaphores..
+ *
+ * (C) Copyright 1996 Linus Torvalds
+ *
+ * BFIN version by akbar hussain Lineo Inc April 2001
+ *
+ */
+
+struct semaphore {
+ atomic_t count;
+ int sleepers;
+ wait_queue_head_t wait;
+};
+
+#define __SEMAPHORE_INITIALIZER(name, n) \
+{ \
+ .count = ATOMIC_INIT(n), \
+ .sleepers = 0, \
+ .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+}
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+ struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+static inline void sema_init(struct semaphore *sem, int val)
+{
+ *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
+}
+
+static inline void init_MUTEX(struct semaphore *sem)
+{
+ sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED(struct semaphore *sem)
+{
+ sema_init(sem, 0);
+}
+
+asmlinkage void __down(struct semaphore *sem);
+asmlinkage int __down_interruptible(struct semaphore *sem);
+asmlinkage int __down_trylock(struct semaphore *sem);
+asmlinkage void __up(struct semaphore *sem);
+
+extern spinlock_t semaphore_wake_lock;
+
+/*
+ * This is ugly, but we want the default case to fall through.
+ * "down_failed" is a special asm handler that calls the C
+ * routine that actually waits.
+ */
+static inline void down(struct semaphore *sem)
+{
+ might_sleep();
+ if (atomic_dec_return(&sem->count) < 0)
+ __down(sem);
+}
+
+static inline int down_interruptible(struct semaphore *sem)
+{
+ int ret = 0;
+
+ might_sleep();
+ if (atomic_dec_return(&sem->count) < 0)
+ ret = __down_interruptible(sem);
+ return (ret);
+}
+
+static inline int down_trylock(struct semaphore *sem)
+{
+ int ret = 0;
+
+ if (atomic_dec_return(&sem->count) < 0)
+ ret = __down_trylock(sem);
+ return ret;
+}
+
+/*
+ * Note! This is subtle. We jump to wake people up only if
+ * the semaphore was negative (== somebody was waiting on it).
+ * The default case (no contention) will result in NO
+ * jumps for both down() and up().
+ */
+static inline void up(struct semaphore *sem)
+{
+ if (atomic_inc_return(&sem->count) <= 0)
+ __up(sem);
+}
+
+#endif /* __ASSEMBLY__ */
+#endif /* _BFIN_SEMAPHORE_H */
diff --git a/include/asm-blackfin/sembuf.h b/include/asm-blackfin/sembuf.h
new file mode 100644
index 0000000..18deb5c
--- /dev/null
+++ b/include/asm-blackfin/sembuf.h
@@ -0,0 +1,25 @@
+#ifndef _BFIN_SEMBUF_H
+#define _BFIN_SEMBUF_H
+
+/*
+ * The semid64_ds structure for bfin architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+ struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
+ __kernel_time_t sem_otime; /* last semop time */
+ unsigned long __unused1;
+ __kernel_time_t sem_ctime; /* last change time */
+ unsigned long __unused2;
+ unsigned long sem_nsems; /* no. of semaphores in array */
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+#endif /* _BFIN_SEMBUF_H */
diff --git a/include/asm-blackfin/setup.h b/include/asm-blackfin/setup.h
new file mode 100644
index 0000000..01c8c6c
--- /dev/null
+++ b/include/asm-blackfin/setup.h
@@ -0,0 +1,17 @@
+/*
+** asm/setup.h -- Definition of the Linux/bfin setup information
+**
+** This file is subject to the terms and conditions of the GNU General Public
+** License. See the file COPYING in the main directory of this archive
+** for more details.
+**
+** Copyright Lineo, Inc 2001 Tony Kou
+**
+*/
+
+#ifndef _BFIN_SETUP_H
+#define _BFIN_SETUP_H
+
+#define COMMAND_LINE_SIZE 512
+
+#endif /* _BFIN_SETUP_H */
diff --git a/include/asm-blackfin/shmbuf.h b/include/asm-blackfin/shmbuf.h
new file mode 100644
index 0000000..6124363
--- /dev/null
+++ b/include/asm-blackfin/shmbuf.h
@@ -0,0 +1,42 @@
+#ifndef _BFIN_SHMBUF_H
+#define _BFIN_SHMBUF_H
+
+/*
+ * The shmid64_ds structure for bfin architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+ struct ipc64_perm shm_perm; /* operation perms */
+ size_t shm_segsz; /* size of segment (bytes) */
+ __kernel_time_t shm_atime; /* last attach time */
+ unsigned long __unused1;
+ __kernel_time_t shm_dtime; /* last detach time */
+ unsigned long __unused2;
+ __kernel_time_t shm_ctime; /* last change time */
+ unsigned long __unused3;
+ __kernel_pid_t shm_cpid; /* pid of creator */
+ __kernel_pid_t shm_lpid; /* pid of last operator */
+ unsigned long shm_nattch; /* no. of current attaches */
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+struct shminfo64 {
+ unsigned long shmmax;
+ unsigned long shmmin;
+ unsigned long shmmni;
+ unsigned long shmseg;
+ unsigned long shmall;
+ unsigned long __unused1;
+ unsigned long __unused2;
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+#endif /* _BFIN_SHMBUF_H */
diff --git a/include/asm-blackfin/shmparam.h b/include/asm-blackfin/shmparam.h
new file mode 100644
index 0000000..3c03906
--- /dev/null
+++ b/include/asm-blackfin/shmparam.h
@@ -0,0 +1,6 @@
+#ifndef _BFIN_SHMPARAM_H
+#define _BFIN_SHMPARAM_H
+
+#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
+
+#endif /* _BFIN_SHMPARAM_H */
diff --git a/include/asm-blackfin/sigcontext.h b/include/asm-blackfin/sigcontext.h
new file mode 100644
index 0000000..ce00b03
--- /dev/null
+++ b/include/asm-blackfin/sigcontext.h
@@ -0,0 +1,55 @@
+#ifndef _ASM_BLACKFIN_SIGCONTEXT_H
+#define _ASM_BLACKFIN_SIGCONTEXT_H
+
+/* Add new entries at the end of the structure only. */
+struct sigcontext {
+ unsigned long sc_r0;
+ unsigned long sc_r1;
+ unsigned long sc_r2;
+ unsigned long sc_r3;
+ unsigned long sc_r4;
+ unsigned long sc_r5;
+ unsigned long sc_r6;
+ unsigned long sc_r7;
+ unsigned long sc_p0;
+ unsigned long sc_p1;
+ unsigned long sc_p2;
+ unsigned long sc_p3;
+ unsigned long sc_p4;
+ unsigned long sc_p5;
+ unsigned long sc_usp;
+ unsigned long sc_a0w;
+ unsigned long sc_a1w;
+ unsigned long sc_a0x;
+ unsigned long sc_a1x;
+ unsigned long sc_astat;
+ unsigned long sc_rets;
+ unsigned long sc_pc;
+ unsigned long sc_retx;
+ unsigned long sc_fp;
+ unsigned long sc_i0;
+ unsigned long sc_i1;
+ unsigned long sc_i2;
+ unsigned long sc_i3;
+ unsigned long sc_m0;
+ unsigned long sc_m1;
+ unsigned long sc_m2;
+ unsigned long sc_m3;
+ unsigned long sc_l0;
+ unsigned long sc_l1;
+ unsigned long sc_l2;
+ unsigned long sc_l3;
+ unsigned long sc_b0;
+ unsigned long sc_b1;
+ unsigned long sc_b2;
+ unsigned long sc_b3;
+ unsigned long sc_lc0;
+ unsigned long sc_lc1;
+ unsigned long sc_lt0;
+ unsigned long sc_lt1;
+ unsigned long sc_lb0;
+ unsigned long sc_lb1;
+ unsigned long sc_seqstat;
+};
+
+#endif
diff --git a/include/asm-blackfin/siginfo.h b/include/asm-blackfin/siginfo.h
new file mode 100644
index 0000000..eca4565
--- /dev/null
+++ b/include/asm-blackfin/siginfo.h
@@ -0,0 +1,35 @@
+#ifndef _BFIN_SIGINFO_H
+#define _BFIN_SIGINFO_H
+
+#include <linux/types.h>
+#include <asm-generic/siginfo.h>
+
+#define UID16_SIGINFO_COMPAT_NEEDED
+
+#define si_uid16 _sifields._kill._uid
+
+#define ILL_ILLPARAOP (__SI_FAULT|2) /* illegal opcode combine ********** */
+#define ILL_ILLEXCPT (__SI_FAULT|4) /* unrecoverable exception ********** */
+#define ILL_CPLB_VI (__SI_FAULT|9) /* D/I CPLB protect violation ******** */
+#define ILL_CPLB_MISS (__SI_FAULT|10) /* D/I CPLB miss ******** */
+#define ILL_CPLB_MULHIT (__SI_FAULT|11) /* D/I CPLB multiple hit ******** */
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_OPFETCH (__SI_FAULT|4) /* error from instruction fetch ******** */
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_STEP (__SI_FAULT|1) /* single-step breakpoint************* */
+#define TRAP_TRACEFLOW (__SI_FAULT|2) /* trace buffer overflow ************* */
+#define TRAP_WATCHPT (__SI_FAULT|3) /* watchpoint match ************* */
+#define TRAP_ILLTRAP (__SI_FAULT|4) /* illegal trap ************* */
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_STACKFLOW (__SI_FAULT|3) /* stack overflow */
+
+#endif
diff --git a/include/asm-blackfin/signal.h b/include/asm-blackfin/signal.h
new file mode 100644
index 0000000..0250429
--- /dev/null
+++ b/include/asm-blackfin/signal.h
@@ -0,0 +1,160 @@
+#ifndef _BLACKFIN_SIGNAL_H
+#define _BLACKFIN_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems. */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+ is taken to make libc match. */
+
+#define _NSIG 64
+#define _NSIG_BPW 32
+#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t; /* at least 32 bits */
+
+typedef struct {
+ unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+#define NSIG 32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+/*
+#define SIGLOST 29
+*/
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED 31
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP 0x00000001
+#define SA_NOCLDWAIT 0x00000002 /* not supported yet */
+#define SA_SIGINFO 0x00000004
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+#include <asm-generic/signal.h>
+
+#ifdef __KERNEL__
+struct old_sigaction {
+ __sighandler_t sa_handler;
+ old_sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer) (void);
+};
+
+struct sigaction {
+ __sighandler_t sa_handler;
+ unsigned long sa_flags;
+ void (*sa_restorer) (void);
+ sigset_t sa_mask; /* mask last for extensibility */
+};
+
+struct k_sigaction {
+ struct sigaction sa;
+};
+#else
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+struct sigaction {
+ union {
+ __sighandler_t _sa_handler;
+ void (*_sa_sigaction) (int, struct siginfo *, void *);
+ } _u;
+ sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer) (void);
+};
+
+#define sa_handler _u._sa_handler
+#define sa_sigaction _u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+ void *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#undef __HAVE_ARCH_SIG_BITOPS
+
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _BLACKFIN_SIGNAL_H */
diff --git a/include/asm-blackfin/socket.h b/include/asm-blackfin/socket.h
new file mode 100644
index 0000000..5213c96
--- /dev/null
+++ b/include/asm-blackfin/socket.h
@@ -0,0 +1,53 @@
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET 1
+
+#define SO_DEBUG 1
+#define SO_REUSEADDR 2
+#define SO_TYPE 3
+#define SO_ERROR 4
+#define SO_DONTROUTE 5
+#define SO_BROADCAST 6
+#define SO_SNDBUF 7
+#define SO_RCVBUF 8
+#define SO_SNDBUFFORCE 32
+#define SO_RCVBUFFORCE 33
+#define SO_KEEPALIVE 9
+#define SO_OOBINLINE 10
+#define SO_NO_CHECK 11
+#define SO_PRIORITY 12
+#define SO_LINGER 13
+#define SO_BSDCOMPAT 14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED 16
+#define SO_PEERCRED 17
+#define SO_RCVLOWAT 18
+#define SO_SNDLOWAT 19
+#define SO_RCVTIMEO 20
+#define SO_SNDTIMEO 21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION 22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
+#define SO_SECURITY_ENCRYPTION_NETWORK 24
+
+#define SO_BINDTODEVICE 25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER 26
+#define SO_DETACH_FILTER 27
+
+#define SO_PEERNAME 28
+#define SO_TIMESTAMP 29
+#define SCM_TIMESTAMP SO_TIMESTAMP
+
+#define SO_ACCEPTCONN 30
+#define SO_PEERSEC 31
+#define SO_PASSSEC 34
+#define SO_TIMESTAMPNS 35
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-blackfin/sockios.h b/include/asm-blackfin/sockios.h
new file mode 100644
index 0000000..426b89b
--- /dev/null
+++ b/include/asm-blackfin/sockios.h
@@ -0,0 +1,13 @@
+#ifndef __ARCH_BFIN_SOCKIOS__
+#define __ARCH_BFIN_SOCKIOS__
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
+#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
+
+#endif /* __ARCH_BFIN_SOCKIOS__ */
diff --git a/include/asm-blackfin/spinlock.h b/include/asm-blackfin/spinlock.h
new file mode 100644
index 0000000..64e908a
--- /dev/null
+++ b/include/asm-blackfin/spinlock.h
@@ -0,0 +1,6 @@
+#ifndef __BFIN_SPINLOCK_H
+#define __BFIN_SPINLOCK_H
+
+#error blackfin architecture does not support SMP spin lock yet
+
+#endif
diff --git a/include/asm-blackfin/stat.h b/include/asm-blackfin/stat.h
new file mode 100644
index 0000000..d2b6f11
--- /dev/null
+++ b/include/asm-blackfin/stat.h
@@ -0,0 +1,63 @@
+#ifndef _BFIN_STAT_H
+#define _BFIN_STAT_H
+
+struct stat {
+ unsigned short st_dev;
+ unsigned short __pad1;
+ unsigned long st_ino;
+ unsigned short st_mode;
+ unsigned short st_nlink;
+ unsigned short st_uid;
+ unsigned short st_gid;
+ unsigned short st_rdev;
+ unsigned short __pad2;
+ unsigned long st_size;
+ unsigned long st_blksize;
+ unsigned long st_blocks;
+ unsigned long st_atime;
+ unsigned long __unused1;
+ unsigned long st_mtime;
+ unsigned long __unused2;
+ unsigned long st_ctime;
+ unsigned long __unused3;
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+ unsigned long long st_dev;
+ unsigned char __pad1[4];
+
+#define STAT64_HAS_BROKEN_ST_INO 1
+ unsigned long __st_ino;
+
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ unsigned long st_uid;
+ unsigned long st_gid;
+
+ unsigned long long st_rdev;
+ unsigned char __pad2[4];
+
+ long long st_size;
+ unsigned long st_blksize;
+
+ long long st_blocks; /* Number 512-byte blocks allocated. */
+
+ unsigned long st_atime;
+ unsigned long st_atime_nsec;
+
+ unsigned long st_mtime;
+ unsigned long st_mtime_nsec;
+
+ unsigned long st_ctime;
+ unsigned long st_ctime_nsec;
+
+ unsigned long long st_ino;
+};
+
+#endif /* _BFIN_STAT_H */
diff --git a/include/asm-blackfin/statfs.h b/include/asm-blackfin/statfs.h
new file mode 100644
index 0000000..3506720
--- /dev/null
+++ b/include/asm-blackfin/statfs.h
@@ -0,0 +1,6 @@
+#ifndef _BFIN_STATFS_H
+#define _BFIN_STATFS_H
+
+#include <asm-generic/statfs.h>
+
+#endif /* _BFIN_STATFS_H */
diff --git a/include/asm-blackfin/string.h b/include/asm-blackfin/string.h
new file mode 100644
index 0000000..6f1eb7d
--- /dev/null
+++ b/include/asm-blackfin/string.h
@@ -0,0 +1,104 @@
+#ifndef _BLACKFIN_STRING_H_
+#define _BLACKFIN_STRING_H_
+
+#ifdef __KERNEL__ /* only set these up for kernel code */
+
+#define __HAVE_ARCH_STRCPY
+extern inline char *strcpy(char *dest, const char *src)
+{
+ char *xdest = dest;
+ char temp = 0;
+
+ __asm__ __volatile__
+ ("1:\t%2 = B [%1++] (Z);\n\t"
+ "B [%0++] = %2;\n\t"
+ "CC = %2;\n\t"
+ "if cc jump 1b (bp);\n"
+ : "+&a" (dest), "+&a" (src), "=&d" (temp)
+ ::"memory", "CC");
+ return xdest;
+}
+
+#define __HAVE_ARCH_STRNCPY
+extern inline char *strncpy(char *dest, const char *src, size_t n)
+{
+ char *xdest = dest;
+ char temp = 0;
+
+ if (n == 0)
+ return xdest;
+
+ __asm__ __volatile__
+ ("1:\t%3 = B [%1++] (Z);\n\t"
+ "B [%0++] = %3;\n\t"
+ "CC = %3;\n\t"
+ "if ! cc jump 2f;\n\t"
+ "%2 += -1;\n\t"
+ "CC = %2 == 0;\n\t"
+ "if ! cc jump 1b (bp);\n"
+ "2:\n"
+ : "+&a" (dest), "+&a" (src), "+&da" (n), "=&d" (temp)
+ ::"memory", "CC");
+ return xdest;
+}
+
+#define __HAVE_ARCH_STRCMP
+extern inline int strcmp(const char *cs, const char *ct)
+{
+ char __res1, __res2;
+
+ __asm__
+ ("1:\t%2 = B[%0++] (Z);\n\t" /* get *cs */
+ "%3 = B[%1++] (Z);\n\t" /* get *ct */
+ "CC = %2 == %3;\n\t" /* compare a byte */
+ "if ! cc jump 2f;\n\t" /* not equal, break out */
+ "CC = %2;\n\t" /* at end of cs? */
+ "if cc jump 1b (bp);\n\t" /* no, keep going */
+ "jump.s 3f;\n" /* strings are equal */
+ "2:\t%2 = %2 - %3;\n" /* *cs - *ct */
+ "3:\n"
+ : "+&a" (cs), "+&a" (ct), "=&d" (__res1), "=&d" (__res2)
+ : : "CC");
+
+ return __res1;
+}
+
+#define __HAVE_ARCH_STRNCMP
+extern inline int strncmp(const char *cs, const char *ct, size_t count)
+{
+ char __res1, __res2;
+
+ if (!count)
+ return 0;
+ __asm__
+ ("1:\t%3 = B[%0++] (Z);\n\t" /* get *cs */
+ "%4 = B[%1++] (Z);\n\t" /* get *ct */
+ "CC = %3 == %4;\n\t" /* compare a byte */
+ "if ! cc jump 3f;\n\t" /* not equal, break out */
+ "CC = %3;\n\t" /* at end of cs? */
+ "if ! cc jump 4f;\n\t" /* yes, all done */
+ "%2 += -1;\n\t" /* no, adjust count */
+ "CC = %2 == 0;\n\t"
+ "if ! cc jump 1b;\n" /* more to do, keep going */
+ "2:\t%3 = 0;\n\t" /* strings are equal */
+ "jump.s 4f;\n"
+ "3:\t%3 = %3 - %4;\n" /* *cs - *ct */
+ "4:"
+ : "+&a" (cs), "+&a" (ct), "+&da" (count), "=&d" (__res1), "=&d" (__res2)
+ : : "CC");
+ return __res1;
+}
+
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *s, int c, size_t count);
+#define __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *d, const void *s, size_t count);
+#define __HAVE_ARCH_MEMCMP
+extern int memcmp(const void *, const void *, __kernel_size_t);
+#define __HAVE_ARCH_MEMCHR
+extern void *memchr(const void *s, int c, size_t n);
+#define __HAVE_ARCH_MEMMOVE
+extern void *memmove(void *dest, const void *src, size_t count);
+
+#endif /*__KERNEL__*/
+#endif /* _BLACKFIN_STRING_H_ */
diff --git a/include/asm-blackfin/system.h b/include/asm-blackfin/system.h
new file mode 100644
index 0000000..b5bf6e7
--- /dev/null
+++ b/include/asm-blackfin/system.h
@@ -0,0 +1,249 @@
+/*
+ * File: include/asm/system.h
+ * Based on:
+ * Author: Tony Kou (tonyko@lineo.ca)
+ * Copyright (c) 2002 Arcturus Networks Inc.
+ * (www.arcturusnetworks.com)
+ * Copyright (c) 2003 Metrowerks (www.metrowerks.com)
+ * Copyright (c) 2004 Analog Device Inc.
+ * Created: 25Jan2001 - Tony Kou
+ * Description: system.h include file
+ *
+ * Modified: 22Sep2006 - Robin Getz
+ * - move include blackfin.h down, so I can get access to
+ * irq functions in other include files.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _BLACKFIN_SYSTEM_H
+#define _BLACKFIN_SYSTEM_H
+
+#include <linux/linkage.h>
+#include <linux/compiler.h>
+
+/*
+ * Interrupt configuring macros.
+ */
+
+extern unsigned long irq_flags;
+
+#define local_irq_enable() do { \
+ __asm__ __volatile__ ( \
+ "sti %0;" \
+ ::"d"(irq_flags)); \
+} while (0)
+
+#define local_irq_disable() do { \
+ int _tmp_dummy; \
+ __asm__ __volatile__ ( \
+ "cli %0;" \
+ :"=d" (_tmp_dummy):); \
+} while (0)
+
+#if defined(ANOMALY_05000244) && defined (CONFIG_BLKFIN_CACHE)
+#define idle_with_irq_disabled() do { \
+ __asm__ __volatile__ ( \
+ "nop; nop;\n" \
+ ".align 8;\n" \
+ "sti %0; idle;\n" \
+ ::"d" (irq_flags)); \
+} while (0)
+#else
+#define idle_with_irq_disabled() do { \
+ __asm__ __volatile__ ( \
+ ".align 8;\n" \
+ "sti %0; idle;\n" \
+ ::"d" (irq_flags)); \
+} while (0)
+#endif
+
+#ifdef CONFIG_DEBUG_HWERR
+#define __save_and_cli(x) do { \
+ __asm__ __volatile__ ( \
+ "cli %0;\n\tsti %1;" \
+ :"=&d"(x): "d" (0x3F)); \
+} while (0)
+#else
+#define __save_and_cli(x) do { \
+ __asm__ __volatile__ ( \
+ "cli %0;" \
+ :"=&d"(x):); \
+} while (0)
+#endif
+
+#define local_save_flags(x) asm volatile ("cli %0;" \
+ "sti %0;" \
+ :"=d"(x):);
+
+#ifdef CONFIG_DEBUG_HWERR
+#define irqs_enabled_from_flags(x) (((x) & ~0x3f) != 0)
+#else
+#define irqs_enabled_from_flags(x) ((x) != 0x1f)
+#endif
+
+#define local_irq_restore(x) do { \
+ if (irqs_enabled_from_flags(x)) \
+ local_irq_enable (); \
+} while (0)
+
+/* For spinlocks etc */
+#define local_irq_save(x) __save_and_cli(x)
+
+#define irqs_disabled() \
+({ \
+ unsigned long flags; \
+ local_save_flags(flags); \
+ !irqs_enabled_from_flags(flags); \
+})
+
+/*
+ * Force strict CPU ordering.
+ */
+#define nop() asm volatile ("nop;\n\t"::)
+#define mb() asm volatile ("" : : :"memory")
+#define rmb() asm volatile ("" : : :"memory")
+#define wmb() asm volatile ("" : : :"memory")
+#define set_rmb(var, value) do { (void) xchg(&var, value); } while (0)
+#define set_mb(var, value) set_rmb(var, value)
+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+
+#define read_barrier_depends() do { } while(0)
+
+#ifdef CONFIG_SMP
+#define smp_mb() mb()
+#define smp_rmb() rmb()
+#define smp_wmb() wmb()
+#define smp_read_barrier_depends() read_barrier_depends()
+#else
+#define smp_mb() barrier()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+#define smp_read_barrier_depends() do { } while(0)
+#endif
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+
+struct __xchg_dummy {
+ unsigned long a[100];
+};
+#define __xg(x) ((volatile struct __xchg_dummy *)(x))
+
+static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
+ int size)
+{
+ unsigned long tmp = 0;
+ unsigned long flags = 0;
+
+ local_irq_save(flags);
+
+ switch (size) {
+ case 1:
+ __asm__ __volatile__
+ ("%0 = b%2 (z);\n\t"
+ "b%2 = %1;\n\t"
+ : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
+ break;
+ case 2:
+ __asm__ __volatile__
+ ("%0 = w%2 (z);\n\t"
+ "w%2 = %1;\n\t"
+ : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
+ break;
+ case 4:
+ __asm__ __volatile__
+ ("%0 = %2;\n\t"
+ "%2 = %1;\n\t"
+ : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
+ break;
+ }
+ local_irq_restore(flags);
+ return tmp;
+}
+
+/*
+ * Atomic compare and exchange. Compare OLD with MEM, if identical,
+ * store NEW in MEM. Return the initial value in MEM. Success is
+ * indicated by comparing RETURN with OLD.
+ */
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+ unsigned long new, int size)
+{
+ unsigned long tmp = 0;
+ unsigned long flags = 0;
+
+ local_irq_save(flags);
+
+ switch (size) {
+ case 1:
+ __asm__ __volatile__
+ ("%0 = b%3 (z);\n\t"
+ "CC = %1 == %0;\n\t"
+ "IF !CC JUMP 1f;\n\t"
+ "b%3 = %2;\n\t"
+ "1:\n\t"
+ : "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
+ break;
+ case 2:
+ __asm__ __volatile__
+ ("%0 = w%3 (z);\n\t"
+ "CC = %1 == %0;\n\t"
+ "IF !CC JUMP 1f;\n\t"
+ "w%3 = %2;\n\t"
+ "1:\n\t"
+ : "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
+ break;
+ case 4:
+ __asm__ __volatile__
+ ("%0 = %3;\n\t"
+ "CC = %1 == %0;\n\t"
+ "IF !CC JUMP 1f;\n\t"
+ "%3 = %2;\n\t"
+ "1:\n\t"
+ : "=&d" (tmp) : "d" (old), "d" (new), "m" (*__xg(ptr)) : "memory");
+ break;
+ }
+ local_irq_restore(flags);
+ return tmp;
+}
+
+#define cmpxchg(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
+ (unsigned long)(n),sizeof(*(ptr))))
+
+#define prepare_to_switch() do { } while(0)
+
+/*
+ * switch_to(n) should switch tasks to task ptr, first checking that
+ * ptr isn't the current task, in which case it does nothing.
+ */
+
+#include <asm/blackfin.h>
+
+asmlinkage struct task_struct *resume(struct task_struct *prev, struct task_struct *next);
+
+#define switch_to(prev,next,last) \
+do { \
+ memcpy (&prev->thread_info->l1_task_info, L1_SCRATCH_TASK_INFO, \
+ sizeof *L1_SCRATCH_TASK_INFO); \
+ memcpy (L1_SCRATCH_TASK_INFO, &next->thread_info->l1_task_info, \
+ sizeof *L1_SCRATCH_TASK_INFO); \
+ (last) = resume (prev, next); \
+} while (0)
+
+#endif /* _BLACKFIN_SYSTEM_H */
diff --git a/include/asm-blackfin/termbits.h b/include/asm-blackfin/termbits.h
new file mode 100644
index 0000000..2fd9dab
--- /dev/null
+++ b/include/asm-blackfin/termbits.h
@@ -0,0 +1,184 @@
+#ifndef __ARCH_BFIN_TERMBITS_H__
+#define __ARCH_BFIN_TERMBITS_H__
+
+#include <linux/posix_types.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 19
+struct termios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+};
+
+struct ktermios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IUCLC 0001000
+#define IXON 0002000
+#define IXANY 0004000
+#define IXOFF 0010000
+#define IMAXBEL 0020000
+#define IUTF8 0040000
+
+/* c_oflag bits */
+#define OPOST 0000001
+#define OLCUC 0000002
+#define ONLCR 0000004
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define XTABS 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+
+/* c_cflag bit meaning */
+#define CBAUD 0010017
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0000060
+#define CS5 0000000
+#define CS6 0000020
+#define CS7 0000040
+#define CS8 0000060
+#define CSTOPB 0000100
+#define CREAD 0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL 0002000
+#define CLOCAL 0004000
+#define CBAUDEX 0010000
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define B500000 0010005
+#define B576000 0010006
+#define B921600 0010007
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+#define CIBAUD 002003600000 /* input baud rate (not used) */
+#define CMSPAR 010000000000 /* mark or space (stick) parity */
+#define CRTSCTS 020000000000 /* flow control */
+
+/* c_lflag bits */
+#define ISIG 0000001
+#define ICANON 0000002
+#define XCASE 0000004
+#define ECHO 0000010
+#define ECHOE 0000020
+#define ECHOK 0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+#define IEXTEN 0100000
+
+/* tcflow() and TCXONC use these */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* tcflush() and TCFLSH use these */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* tcsetattr uses these */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#endif /* __ARCH_BFIN_TERMBITS_H__ */
diff --git a/include/asm-blackfin/termios.h b/include/asm-blackfin/termios.h
new file mode 100644
index 0000000..5c41478
--- /dev/null
+++ b/include/asm-blackfin/termios.h
@@ -0,0 +1,106 @@
+#ifndef __BFIN_TERMIOS_H__
+#define __BFIN_TERMIOS_H__
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* line disciplines */
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+#define N_STRIP 4
+#define N_AX25 5
+#define N_X25 6 /* X.25 async */
+#define N_6PACK 7
+#define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964 9 /* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL 10 /* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA 11 /* Linux IR - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC 13 /* synchronous HDLC */
+#define N_SYNC_PPP 14 /* synchronous PPP */
+#define N_HCI 15 /* Bluetooth HCI UART */
+
+#ifdef __KERNEL__
+
+/* intr=^C quit=^\ erase=del kill=^U
+ eof=^D vtime=\0 vmin=\1 sxtc=\0
+ start=^Q stop=^S susp=^Z eol=\0
+ reprint=^R discard=^U werase=^W lnext=^V
+ eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+ unsigned short __tmp; \
+ get_user(__tmp,&(termio)->x); \
+ *(unsigned short *) &(termios)->x = __tmp; \
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+ SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+ SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+ SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+ SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+ copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+ put_user((termios)->c_iflag, &(termio)->c_iflag); \
+ put_user((termios)->c_oflag, &(termio)->c_oflag); \
+ put_user((termios)->c_cflag, &(termio)->c_cflag); \
+ put_user((termios)->c_lflag, &(termio)->c_lflag); \
+ put_user((termios)->c_line, &(termio)->c_line); \
+ copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif /* __KERNEL__ */
+
+#endif /* __BFIN_TERMIOS_H__ */
diff --git a/include/asm-blackfin/thread_info.h b/include/asm-blackfin/thread_info.h
new file mode 100644
index 0000000..fa8f08c
--- /dev/null
+++ b/include/asm-blackfin/thread_info.h
@@ -0,0 +1,143 @@
+/*
+ * File: include/asm-blackfin/thread_info.h
+ * Based on: include/asm-m68knommu/thread_info.h
+ * Author: LG Soft India
+ * Copyright (C) 2004-2005 Analog Devices Inc.
+ * Created: Tue Sep 21 2004
+ * Description: Blackfin low-level thread information
+ * Modified:
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _ASM_THREAD_INFO_H
+#define _ASM_THREAD_INFO_H
+
+#include <asm/page.h>
+#include <asm/entry.h>
+#include <asm/l1layout.h>
+#include <linux/compiler.h>
+
+#ifdef __KERNEL__
+
+/* Thread Align Mask to reach to the top of the stack
+ * for any process
+ */
+#define ALIGN_PAGE_MASK 0xffffe000
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long mm_segment_t;
+
+/*
+ * low level task data.
+ * If you change this, change the TI_* offsets below to match.
+ */
+
+struct thread_info {
+ struct task_struct *task; /* main task structure */
+ struct exec_domain *exec_domain; /* execution domain */
+ unsigned long flags; /* low level flags */
+ int cpu; /* cpu we're on */
+ int preempt_count; /* 0 => preemptable, <0 => BUG */
+ mm_segment_t addr_limit; /* address limit */
+ struct restart_block restart_block;
+ struct l1_scratch_task_info l1_task_info;
+};
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ */
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .task = &tsk, \
+ .exec_domain = &default_exec_domain, \
+ .flags = 0, \
+ .cpu = 0, \
+ .preempt_count = 1, \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
+}
+#define init_thread_info (init_thread_union.thread_info)
+#define init_stack (init_thread_union.stack)
+
+/*
+ * Size of kernel stack for each process. This must be a power of 2...
+ */
+#define THREAD_SIZE 8192 /* 2 pages */
+
+/* How to get the thread information struct from C */
+
+static inline struct thread_info *current_thread_info(void)
+ __attribute__ ((__const__));
+
+/* Given a task stack pointer, you can find it's task structure
+ * just by masking it to the 8K boundary.
+ */
+static inline struct thread_info *current_thread_info(void)
+{
+ struct thread_info *ti;
+ __asm__("%0 = sp;": "=&d"(ti):
+ );
+ return (struct thread_info *)((long)ti & ~8191UL);
+}
+
+/* thread information allocation */
+#define alloc_thread_info(tsk) ((struct thread_info *) \
+ __get_free_pages(GFP_KERNEL, 1))
+#define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Offsets in thread_info structure, used in assembly code
+ */
+#define TI_TASK 0
+#define TI_EXECDOMAIN 4
+#define TI_FLAGS 8
+#define TI_CPU 12
+#define TI_PREEMPT 16
+
+#define PREEMPT_ACTIVE 0x4000000
+
+/*
+ * thread information flag bit numbers
+ */
+#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
+#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
+#define TIF_SIGPENDING 2 /* signal pending */
+#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
+#define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling
+ TIF_NEED_RESCHED */
+#define TIF_MEMDIE 5
+#define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */
+#define TIF_FREEZE 7 /* is freezing for suspend */
+
+/* as above, but as bit values */
+#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
+#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
+#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
+
+#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_THREAD_INFO_H */
diff --git a/include/asm-blackfin/timex.h b/include/asm-blackfin/timex.h
new file mode 100644
index 0000000..8285901
--- /dev/null
+++ b/include/asm-blackfin/timex.h
@@ -0,0 +1,18 @@
+/* blackfin architecture timex specifications: Lineo Inc. 2001
+ *
+ * Based on: include/asm-m68knommu/timex.h
+ */
+
+#ifndef _ASMBLACKFIN_TIMEX_H
+#define _ASMBLACKFIN_TIMEX_H
+
+#define CLOCK_TICK_RATE 1000000 /* Underlying HZ */
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+ return 0;
+}
+
+#endif
diff --git a/include/asm-blackfin/tlb.h b/include/asm-blackfin/tlb.h
new file mode 100644
index 0000000..89a12ee
--- /dev/null
+++ b/include/asm-blackfin/tlb.h
@@ -0,0 +1,16 @@
+#ifndef _BLACKFIN_TLB_H
+#define _BLACKFIN_TLB_H
+
+#define tlb_start_vma(tlb, vma) do { } while (0)
+#define tlb_end_vma(tlb, vma) do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
+
+/*
+ * .. because we flush the whole mm when it
+ * fills up.
+ */
+#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+
+#include <asm-generic/tlb.h>
+
+#endif /* _BLACKFIN_TLB_H */
diff --git a/include/asm-blackfin/tlbflush.h b/include/asm-blackfin/tlbflush.h
new file mode 100644
index 0000000..10a07ba
--- /dev/null
+++ b/include/asm-blackfin/tlbflush.h
@@ -0,0 +1,62 @@
+#ifndef _BLACKFIN_TLBFLUSH_H
+#define _BLACKFIN_TLBFLUSH_H
+
+/*
+ * Copyright (C) 2000 Lineo, David McCullough <davidm@uclinux.org>
+ * Copyright (C) 2000-2002, Greg Ungerer <gerg@snapgear.com>
+ */
+
+#include <asm/setup.h>
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+ BUG();
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+ BUG();
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+ BUG();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+ BUG();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma,
+ unsigned long addr)
+{
+ BUG();
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+ unsigned long start, unsigned long end)
+{
+ BUG();
+}
+
+static inline void flush_tlb_kernel_page(unsigned long addr)
+{
+ BUG();
+}
+
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
+ unsigned long start, unsigned long end)
+{
+ BUG();
+}
+
+#endif
diff --git a/include/asm-blackfin/topology.h b/include/asm-blackfin/topology.h
new file mode 100644
index 0000000..acee239
--- /dev/null
+++ b/include/asm-blackfin/topology.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_BLACKFIN_TOPOLOGY_H
+#define _ASM_BLACKFIN_TOPOLOGY_H
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_BLACKFIN_TOPOLOGY_H */
diff --git a/include/asm-blackfin/traps.h b/include/asm-blackfin/traps.h
new file mode 100644
index 0000000..fe365b1
--- /dev/null
+++ b/include/asm-blackfin/traps.h
@@ -0,0 +1,75 @@
+/*
+ * linux/include/asm/traps.h
+ *
+ * Copyright (C) 1993 Hamish Macdonald
+ *
+ * Lineo, Inc Jul 2001 Tony Kou
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _BFIN_TRAPS_H
+#define _BFIN_TRAPS_H
+
+#define VEC_SYS (0)
+#define VEC_EXCPT01 (1)
+#define VEC_EXCPT02 (2)
+#define VEC_EXCPT03 (3)
+#define VEC_EXCPT04 (4)
+#define VEC_EXCPT05 (5)
+#define VEC_EXCPT06 (6)
+#define VEC_EXCPT07 (7)
+#define VEC_EXCPT08 (8)
+#define VEC_EXCPT09 (9)
+#define VEC_EXCPT10 (10)
+#define VEC_EXCPT11 (11)
+#define VEC_EXCPT12 (12)
+#define VEC_EXCPT13 (13)
+#define VEC_EXCPT14 (14)
+#define VEC_EXCPT15 (15)
+#define VEC_STEP (16)
+#define VEC_OVFLOW (17)
+#define VEC_UNDEF_I (33)
+#define VEC_ILGAL_I (34)
+#define VEC_CPLB_VL (35)
+#define VEC_MISALI_D (36)
+#define VEC_UNCOV (37)
+#define VEC_CPLB_M (38)
+#define VEC_CPLB_MHIT (39)
+#define VEC_WATCH (40)
+#define VEC_ISTRU_VL (41) /*ADSP-BF535 only (MH) */
+#define VEC_MISALI_I (42)
+#define VEC_CPLB_I_VL (43)
+#define VEC_CPLB_I_M (44)
+#define VEC_CPLB_I_MHIT (45)
+#define VEC_ILL_RES (46) /* including unvalid supervisor mode insn */
+
+#ifndef __ASSEMBLY__
+
+#define HWC_x2 "System MMR Error\nAn error occurred due to an invalid access to an System MMR location\nPossible reason: a 32-bit register is accessed with a 16-bit instruction,\nor a 16-bit register is accessed with a 32-bit instruction.\n"
+#define HWC_x3 "External Memory Addressing Error\n"
+#define HWC_x12 "Performance Monitor Overflow\n"
+#define HWC_x18 "RAISE 5 instruction\n Software issued a RAISE 5 instruction to invoke the Hardware\n"
+#define HWC_default "Reserved\n"
+
+#define EXC_0x03 "Application stack overflow\n - Please increase the stack size of the application using elf2flt -s option,\n and/or reduce the stack use of the application.\n"
+#define EXC_0x10 "Single step\n - When the processor is in single step mode, every instruction\n generates an exception. Primarily used for debugging.\n"
+#define EXC_0x11 "Exception caused by a trace buffer full condition\n - The processor takes this exception when the trace\n buffer overflows (only when enabled by the Trace Unit Control register).\n"
+#define EXC_0x21 "Undefined instruction\n - May be used to emulate instructions that are not defined for\n a particular processor implementation.\n"
+#define EXC_0x22 "Illegal instruction combination\n - See section for multi-issue rules in the ADSP-BF53x Blackfin\n Processor Instruction Set Reference.\n"
+#define EXC_0x23 "Data access CPLB protection violation\n - Attempted read or write to Supervisor resource,\n or illegal data memory access. \n"
+#define EXC_0x24 "Data access misaligned address violation\n - Attempted misaligned data memory or data cache access.\n"
+#define EXC_0x25 "Unrecoverable event\n - For example, an exception generated while processing a previous exception.\n"
+#define EXC_0x26 "Data access CPLB miss\n - Used by the MMU to signal a CPLB miss on a data access.\n"
+#define EXC_0x27 "Data access multiple CPLB hits\n - More than one CPLB entry matches data fetch address.\n"
+#define EXC_0x28 "Program Sequencer Exception caused by an emulation watchpoint match\n - There is a watchpoint match, and one of the EMUSW\n bits in the Watchpoint Instruction Address Control register (WPIACTL) is set.\n"
+#define EXC_0x2A "Instruction fetch misaligned address violation\n - Attempted misaligned instruction cache fetch. On a misaligned instruction fetch exception,\n the return address provided in RETX is the destination address which is misaligned, rather than the address of the offending instruction.\n"
+#define EXC_0x2B "CPLB protection violation\n - Illegal instruction fetch access (memory protection violation).\n"
+#define EXC_0x2C "Instruction fetch CPLB miss\n - CPLB miss on an instruction fetch.\n"
+#define EXC_0x2D "Instruction fetch multiple CPLB hits\n - More than one CPLB entry matches instruction fetch address.\n"
+#define EXC_0x2E "Illegal use of supervisor resource\n - Attempted to use a Supervisor register or instruction from User mode.\n Supervisor resources are registers and instructions that are reserved\n for Supervisor use: Supervisor only registers, all MMRs, and Supervisor\n only instructions.\n"
+
+#endif /* __ASSEMBLY__ */
+#endif /* _BFIN_TRAPS_H */
diff --git a/include/asm-blackfin/types.h b/include/asm-blackfin/types.h
new file mode 100644
index 0000000..36f8dc8
--- /dev/null
+++ b/include/asm-blackfin/types.h
@@ -0,0 +1,66 @@
+#ifndef _BFIN_TYPES_H
+#define _BFIN_TYPES_H
+
+/*
+ * This file is never included by application software unless
+ * explicitly requested (e.g., via linux/types.h) in which case the
+ * application is Linux specific so (user-) name space pollution is
+ * not a major issue. However, for interoperability, libraries still
+ * need to be careful to avoid a name clashes.
+ */
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+/* HK0617 -- Changes to unsigned long temporarily */
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+#endif /* __ASSEMBLY__ */
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+#define BITS_PER_LONG 32
+
+#ifndef __ASSEMBLY__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+/* Dma addresses are 32-bits wide. */
+
+typedef u32 dma_addr_t;
+typedef u64 dma64_addr_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _BFIN_TYPES_H */
diff --git a/include/asm-blackfin/uaccess.h b/include/asm-blackfin/uaccess.h
new file mode 100644
index 0000000..bfcb679
--- /dev/null
+++ b/include/asm-blackfin/uaccess.h
@@ -0,0 +1,271 @@
+/* Changes made by Lineo Inc. May 2001
+ *
+ * Based on: include/asm-m68knommu/uaccess.h
+ */
+
+#ifndef __BLACKFIN_UACCESS_H
+#define __BLACKFIN_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+
+#include <asm/segment.h>
+#ifndef CONFIG_NO_ACCESS_CHECK
+# include <asm/bfin-global.h>
+#endif
+
+#define get_ds() (KERNEL_DS)
+#define get_fs() (current_thread_info()->addr_limit)
+
+static inline void set_fs(mm_segment_t fs)
+{
+ current_thread_info()->addr_limit = fs;
+}
+
+#define segment_eq(a,b) ((a) == (b))
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+#define access_ok(type,addr,size) _access_ok((unsigned long)(addr),(size))
+
+static inline int is_in_rom(unsigned long addr)
+{
+ /*
+ * What we are really trying to do is determine if addr is
+ * in an allocated kernel memory region. If not then assume
+ * we cannot free it or otherwise de-allocate it. Ideally
+ * we could restrict this to really being in a ROM or flash,
+ * but that would need to be done on a board by board basis,
+ * not globally.
+ */
+ if ((addr < _ramstart) || (addr >= _ramend))
+ return (1);
+
+ /* Default case, not in ROM */
+ return (0);
+}
+
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not. If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ */
+
+#ifdef CONFIG_NO_ACCESS_CHECK
+static inline int _access_ok(unsigned long addr, unsigned long size) { return 1; }
+#else
+#ifdef CONFIG_ACCESS_OK_L1
+extern int _access_ok(unsigned long addr, unsigned long size)__attribute__((l1_text));
+#else
+extern int _access_ok(unsigned long addr, unsigned long size);
+#endif
+#endif
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue. No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path. This means when everything is well,
+ * we don't even have to jump over them. Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry {
+ unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise. */
+extern unsigned long search_exception_table(unsigned long);
+
+/*
+ * These are the main single-value transfer routines. They automatically
+ * use the right size if we just have the right pointer type.
+ */
+
+#define put_user(x,p) \
+ ({ \
+ int _err = 0; \
+ typeof(*(p)) _x = (x); \
+ typeof(*(p)) *_p = (p); \
+ if (!access_ok(VERIFY_WRITE, _p, sizeof(*(_p)))) {\
+ _err = -EFAULT; \
+ } \
+ else { \
+ switch (sizeof (*(_p))) { \
+ case 1: \
+ __put_user_asm(_x, _p, B); \
+ break; \
+ case 2: \
+ __put_user_asm(_x, _p, W); \
+ break; \
+ case 4: \
+ __put_user_asm(_x, _p, ); \
+ break; \
+ case 8: { \
+ long _xl, _xh; \
+ _xl = ((long *)&_x)[0]; \
+ _xh = ((long *)&_x)[1]; \
+ __put_user_asm(_xl, ((long *)_p)+0, ); \
+ __put_user_asm(_xh, ((long *)_p)+1, ); \
+ } break; \
+ default: \
+ _err = __put_user_bad(); \
+ break; \
+ } \
+ } \
+ _err; \
+ })
+
+#define __put_user(x,p) put_user(x,p)
+static inline int bad_user_access_length(void)
+{
+ panic("bad_user_access_length");
+ return -1;
+}
+
+#define __put_user_bad() (printk(KERN_INFO "put_user_bad %s:%d %s\n",\
+ __FILE__, __LINE__, __FUNCTION__),\
+ bad_user_access_length(), (-EFAULT))
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+
+#define __ptr(x) ((unsigned long *)(x))
+
+#define __put_user_asm(x,p,bhw) \
+ __asm__ (#bhw"[%1] = %0;\n\t" \
+ : /* no outputs */ \
+ :"d" (x),"a" (__ptr(p)) : "memory")
+
+#define get_user(x,p) \
+ ({ \
+ int _err = 0; \
+ typeof(*(p)) *_p = (p); \
+ if (!access_ok(VERIFY_READ, _p, sizeof(*(_p)))) { \
+ _err = -EFAULT; \
+ } \
+ else { \
+ switch (sizeof(*(_p))) { \
+ case 1: \
+ __get_user_asm(x, _p, B,(Z)); \
+ break; \
+ case 2: \
+ __get_user_asm(x, _p, W,(Z)); \
+ break; \
+ case 4: \
+ __get_user_asm(x, _p, , ); \
+ break; \
+ case 8: { \
+ unsigned long _xl, _xh; \
+ __get_user_asm(_xl, ((unsigned long *)_p)+0, , ); \
+ __get_user_asm(_xh, ((unsigned long *)_p)+1, , ); \
+ ((unsigned long *)&x)[0] = _xl; \
+ ((unsigned long *)&x)[1] = _xh; \
+ } break; \
+ default: \
+ x = 0; \
+ printk(KERN_INFO "get_user_bad: %s:%d %s\n", \
+ __FILE__, __LINE__, __FUNCTION__); \
+ _err = __get_user_bad(); \
+ break; \
+ } \
+ } \
+ _err; \
+ })
+
+#define __get_user(x,p) get_user(x,p)
+
+#define __get_user_bad() (bad_user_access_length(), (-EFAULT))
+
+#define __get_user_asm(x,p,bhw,option) \
+ { \
+ unsigned long _tmp; \
+ __asm__ ("%0 =" #bhw "[%1]"#option";\n\t" \
+ : "=d" (_tmp) \
+ : "a" (__ptr(p))); \
+ (x) = (__typeof__(*(p))) _tmp; \
+ }
+
+#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
+#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
+
+#define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n))\
+ return retval; })
+
+#define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n))\
+ return retval; })
+
+static inline long copy_from_user(void *to,
+ const void __user * from, unsigned long n)
+{
+ if (access_ok(VERIFY_READ, from, n))
+ memcpy(to, from, n);
+ else
+ return n;
+ return 0;
+}
+
+static inline long copy_to_user(void *to,
+ const void __user * from, unsigned long n)
+{
+ if (access_ok(VERIFY_WRITE, to, n))
+ memcpy(to, from, n);
+ else
+ return n;
+ return 0;
+}
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+
+static inline long strncpy_from_user(char *dst,
+ const char *src, long count)
+{
+ char *tmp;
+ if (!access_ok(VERIFY_READ, src, 1))
+ return -EFAULT;
+ strncpy(dst, src, count);
+ for (tmp = dst; *tmp && count > 0; tmp++, count--) ;
+ return (tmp - dst);
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 on exception, a value greater than N if too long
+ */
+static inline long strnlen_user(const char *src, long n)
+{
+ return (strlen(src) + 1);
+}
+
+#define strlen_user(str) strnlen_user(str, 32767)
+
+/*
+ * Zero Userspace
+ */
+
+static inline unsigned long __clear_user(void *to, unsigned long n)
+{
+ memset(to, 0, n);
+ return 0;
+}
+
+#define clear_user(to, n) __clear_user(to, n)
+
+#endif /* _BLACKFIN_UACCESS_H */
diff --git a/include/asm-blackfin/ucontext.h b/include/asm-blackfin/ucontext.h
new file mode 100644
index 0000000..4a4e385
--- /dev/null
+++ b/include/asm-blackfin/ucontext.h
@@ -0,0 +1,17 @@
+/** Changes made by Tony Kou Lineo Inc. May 2001
+ *
+ * Based on: include/m68knommu/ucontext.h
+ */
+
+#ifndef _BLACKFIN_UCONTEXT_H
+#define _BLACKFIN_UCONTEXT_H
+
+struct ucontext {
+ unsigned long uc_flags; /* the others are necessary */
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ struct sigcontext uc_mcontext;
+ sigset_t uc_sigmask; /* mask last for extensibility */
+};
+
+#endif /* _BLACKFIN_UCONTEXT_H */
diff --git a/include/asm-blackfin/unaligned.h b/include/asm-blackfin/unaligned.h
new file mode 100644
index 0000000..10081dc
--- /dev/null
+++ b/include/asm-blackfin/unaligned.h
@@ -0,0 +1,6 @@
+#ifndef __BFIN_UNALIGNED_H
+#define __BFIN_UNALIGNED_H
+
+#include <asm-generic/unaligned.h>
+
+#endif /* __BFIN_UNALIGNED_H */
diff --git a/include/asm-blackfin/unistd.h b/include/asm-blackfin/unistd.h
new file mode 100644
index 0000000..4df8790
--- /dev/null
+++ b/include/asm-blackfin/unistd.h
@@ -0,0 +1,382 @@
+#ifndef __ASM_BFIN_UNISTD_H
+#define __ASM_BFIN_UNISTD_H
+/*
+ * This file contains the system call numbers.
+ */
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+ /* 7 __NR_waitpid obsolete */
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_chown 16
+ /* 17 __NR_break obsolete */
+ /* 18 __NR_oldstat obsolete */
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+ /* 22 __NR_umount obsolete */
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+ /* 28 __NR_oldfstat obsolete */
+#define __NR_pause 29
+ /* 30 __NR_utime obsolete */
+ /* 31 __NR_stty obsolete */
+ /* 32 __NR_gtty obsolete */
+#define __NR_access 33
+#define __NR_nice 34
+ /* 35 __NR_ftime obsolete */
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+ /* 44 __NR_prof obsolete */
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+ /* 48 __NR_signal obsolete */
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_umount2 52
+ /* 53 __NR_lock obsolete */
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+ /* 56 __NR_mpx obsolete */
+#define __NR_setpgid 57
+ /* 58 __NR_ulimit obsolete */
+ /* 59 __NR_oldolduname obsolete */
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+ /* 67 __NR_sigaction obsolete */
+#define __NR_sgetmask 68
+#define __NR_ssetmask 69
+#define __NR_setreuid 70
+#define __NR_setregid 71
+ /* 72 __NR_sigsuspend obsolete */
+ /* 73 __NR_sigpending obsolete */
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+ /* 76 __NR_old_getrlimit obsolete */
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+ /* 82 __NR_select obsolete */
+#define __NR_symlink 83
+ /* 84 __NR_oldlstat obsolete */
+#define __NR_readlink 85
+ /* 86 __NR_uselib obsolete */
+ /* 87 __NR_swapon obsolete */
+#define __NR_reboot 88
+ /* 89 __NR_readdir obsolete */
+ /* 90 __NR_mmap obsolete */
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+ /* 98 __NR_profil obsolete */
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+ /* 101 __NR_ioperm */
+ /* 102 __NR_socketcall obsolete */
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+ /* 109 __NR_olduname obsolete */
+ /* 110 __NR_iopl obsolete */
+#define __NR_vhangup 111
+ /* 112 __NR_idle obsolete */
+ /* 113 __NR_vm86old */
+#define __NR_wait4 114
+ /* 115 __NR_swapoff obsolete */
+#define __NR_sysinfo 116
+ /* 117 __NR_ipc oboslete */
+#define __NR_fsync 118
+ /* 119 __NR_sigreturn obsolete */
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+ /* 123 __NR_modify_ldt obsolete */
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+ /* 126 __NR_sigprocmask obsolete */
+ /* 127 __NR_create_module obsolete */
+#define __NR_init_module 128
+#define __NR_delete_module 129
+ /* 130 __NR_get_kernel_syms obsolete */
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+ /* 135 was sysfs */
+#define __NR_personality 136
+ /* 137 __NR_afs_syscall */
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR_getdents 141
+ /* 142 __NR__newselect obsolete */
+#define __NR_flock 143
+ /* 144 __NR_msync obsolete */
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+ /* 150 __NR_mlock */
+ /* 151 __NR_munlock */
+ /* 152 __NR_mlockall */
+ /* 153 __NR_munlockall */
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+ /* 163 __NR_mremap */
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+ /* 166 __NR_vm86 */
+ /* 167 __NR_query_module */
+ /* 168 __NR_poll */
+ /* 169 __NR_nfsservctl */
+#define __NR_setresgid 170
+#define __NR_getresgid 171
+#define __NR_prctl 172
+#define __NR_rt_sigreturn 173
+#define __NR_rt_sigaction 174
+#define __NR_rt_sigprocmask 175
+#define __NR_rt_sigpending 176
+#define __NR_rt_sigtimedwait 177
+#define __NR_rt_sigqueueinfo 178
+#define __NR_rt_sigsuspend 179
+#define __NR_pread 180
+#define __NR_pwrite 181
+#define __NR_lchown 182
+#define __NR_getcwd 183
+#define __NR_capget 184
+#define __NR_capset 185
+#define __NR_sigaltstack 186
+#define __NR_sendfile 187
+ /* 188 __NR_getpmsg */
+ /* 189 __NR_putpmsg */
+#define __NR_vfork 190
+#define __NR_getrlimit 191
+#define __NR_mmap2 192
+#define __NR_truncate64 193
+#define __NR_ftruncate64 194
+#define __NR_stat64 195
+#define __NR_lstat64 196
+#define __NR_fstat64 197
+#define __NR_chown32 198
+#define __NR_getuid32 199
+#define __NR_getgid32 200
+#define __NR_geteuid32 201
+#define __NR_getegid32 202
+#define __NR_setreuid32 203
+#define __NR_setregid32 204
+#define __NR_getgroups32 205
+#define __NR_setgroups32 206
+#define __NR_fchown32 207
+#define __NR_setresuid32 208
+#define __NR_getresuid32 209
+#define __NR_setresgid32 210
+#define __NR_getresgid32 211
+#define __NR_lchown32 212
+#define __NR_setuid32 213
+#define __NR_setgid32 214
+#define __NR_setfsuid32 215
+#define __NR_setfsgid32 216
+#define __NR_pivot_root 217
+ /* 218 __NR_mincore */
+ /* 219 __NR_madvise */
+#define __NR_getdents64 220
+#define __NR_fcntl64 221
+ /* 222 reserved for TUX */
+ /* 223 reserved for TUX */
+#define __NR_gettid 224
+ /* 225 __NR_readahead */
+#define __NR_setxattr 226
+#define __NR_lsetxattr 227
+#define __NR_fsetxattr 228
+#define __NR_getxattr 229
+#define __NR_lgetxattr 230
+#define __NR_fgetxattr 231
+#define __NR_listxattr 232
+#define __NR_llistxattr 233
+#define __NR_flistxattr 234
+#define __NR_removexattr 235
+#define __NR_lremovexattr 236
+#define __NR_fremovexattr 237
+#define __NR_tkill 238
+#define __NR_sendfile64 239
+#define __NR_futex 240
+#define __NR_sched_setaffinity 241
+#define __NR_sched_getaffinity 242
+ /* 243 __NR_set_thread_area */
+ /* 244 __NR_get_thread_area */
+#define __NR_io_setup 245
+#define __NR_io_destroy 246
+#define __NR_io_getevents 247
+#define __NR_io_submit 248
+#define __NR_io_cancel 249
+ /* 250 __NR_alloc_hugepages */
+ /* 251 __NR_free_hugepages */
+#define __NR_exit_group 252
+#define __NR_lookup_dcookie 253
+#define __NR_bfin_spinlock 254
+
+#define __NR_epoll_create 255
+#define __NR_epoll_ctl 256
+#define __NR_epoll_wait 257
+ /* 258 __NR_remap_file_pages */
+#define __NR_set_tid_address 259
+#define __NR_timer_create 260
+#define __NR_timer_settime (__NR_timer_create+1)
+#define __NR_timer_gettime (__NR_timer_create+2)
+#define __NR_timer_getoverrun (__NR_timer_create+3)
+#define __NR_timer_delete (__NR_timer_create+4)
+#define __NR_clock_settime (__NR_timer_create+5)
+#define __NR_clock_gettime (__NR_timer_create+6)
+#define __NR_clock_getres (__NR_timer_create+7)
+#define __NR_clock_nanosleep (__NR_timer_create+8)
+#define __NR_statfs64 269
+#define __NR_fstatfs64 270
+#define __NR_tgkill 271
+#define __NR_utimes 272
+#define __NR_fadvise64_64 273
+ /* 274 __NR_vserver */
+ /* 275 __NR_mbind */
+ /* 276 __NR_get_mempolicy */
+ /* 277 __NR_set_mempolicy */
+#define __NR_mq_open 278
+#define __NR_mq_unlink (__NR_mq_open+1)
+#define __NR_mq_timedsend (__NR_mq_open+2)
+#define __NR_mq_timedreceive (__NR_mq_open+3)
+#define __NR_mq_notify (__NR_mq_open+4)
+#define __NR_mq_getsetattr (__NR_mq_open+5)
+ /* 284 __NR_sys_kexec_load */
+#define __NR_waitid 285
+#define __NR_add_key 286
+#define __NR_request_key 287
+#define __NR_keyctl 288
+#define __NR_ioprio_set 289
+#define __NR_ioprio_get 290
+#define __NR_inotify_init 291
+#define __NR_inotify_add_watch 292
+#define __NR_inotify_rm_watch 293
+ /* 294 __NR_migrate_pages */
+#define __NR_openat 295
+#define __NR_mkdirat 296
+#define __NR_mknodat 297
+#define __NR_fchownat 298
+#define __NR_futimesat 299
+#define __NR_fstatat64 300
+#define __NR_unlinkat 301
+#define __NR_renameat 302
+#define __NR_linkat 303
+#define __NR_symlinkat 304
+#define __NR_readlinkat 305
+#define __NR_fchmodat 306
+#define __NR_faccessat 307
+#define __NR_pselect6 308
+#define __NR_ppoll 309
+#define __NR_unshare 310
+
+/* Blackfin private syscalls */
+#define __NR_sram_alloc 311
+#define __NR_sram_free 312
+#define __NR_dma_memcpy 313
+
+/* socket syscalls */
+#define __NR_accept 314
+#define __NR_bind 315
+#define __NR_connect 316
+#define __NR_getpeername 317
+#define __NR_getsockname 318
+#define __NR_getsockopt 319
+#define __NR_listen 320
+#define __NR_recv 321
+#define __NR_recvfrom 322
+#define __NR_recvmsg 323
+#define __NR_send 324
+#define __NR_sendmsg 325
+#define __NR_sendto 326
+#define __NR_setsockopt 327
+#define __NR_shutdown 328
+#define __NR_socket 329
+#define __NR_socketpair 330
+
+/* sysv ipc syscalls */
+#define __NR_semctl 331
+#define __NR_semget 332
+#define __NR_semop 333
+#define __NR_msgctl 334
+#define __NR_msgget 335
+#define __NR_msgrcv 336
+#define __NR_msgsnd 337
+#define __NR_shmat 338
+#define __NR_shmctl 339
+#define __NR_shmdt 340
+#define __NR_shmget 341
+
+#define __NR_syscall 342
+#define NR_syscalls __NR_syscall
+
+#ifdef __KERNEL__
+#define __ARCH_WANT_IPC_PARSE_VERSION
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_SGETMASK
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_FADVISE64
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+#define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#endif
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#define cond_syscall(x) asm(".weak\t_" #x "\n\t.set\t_" #x ",_sys_ni_syscall");
+
+#endif /* __ASM_BFIN_UNISTD_H */
diff --git a/include/asm-blackfin/user.h b/include/asm-blackfin/user.h
new file mode 100644
index 0000000..abc3462
--- /dev/null
+++ b/include/asm-blackfin/user.h
@@ -0,0 +1,89 @@
+#ifndef _BFIN_USER_H
+#define _BFIN_USER_H
+
+/* Changes by Tony Kou Lineo, Inc. July, 2001
+ *
+ * Based include/asm-m68knommu/user.h
+ *
+ */
+
+/* Core file format: The core file is written in such a way that gdb
+ can understand it and provide useful information to the user (under
+ linux we use the 'trad-core' bfd). There are quite a number of
+ obstacles to being able to view the contents of the floating point
+ registers, and until these are solved you will not be able to view the
+ contents of them. Actually, you can read in the core file and look at
+ the contents of the user struct to find out what the floating point
+ registers contain.
+ The actual file contents are as follows:
+ UPAGE: 1 page consisting of a user struct that tells gdb what is present
+ in the file. Directly after this is a copy of the task_struct, which
+ is currently not used by gdb, but it may come in useful at some point.
+ All of the registers are stored as part of the upage. The upage should
+ always be only one page.
+ DATA: The data area is stored. We use current->end_text to
+ current->brk to pick up all of the user variables, plus any memory
+ that may have been malloced. No attempt is made to determine if a page
+ is demand-zero or if a page is totally unused, we just cover the entire
+ range. All of the addresses are rounded in such a way that an integral
+ number of pages is written.
+ STACK: We need the stack information in order to get a meaningful
+ backtrace. We need to write the data from (esp) to
+ current->start_stack, so we round each of these off in order to be able
+ to write an integer number of pages.
+ The minimum core file size is 3 pages, or 12288 bytes.
+*/
+struct user_bfinfp_struct {
+};
+
+/* This is the old layout of "struct pt_regs" as of Linux 1.x, and
+ is still the layout used by user (the new pt_regs doesn't have
+ all registers). */
+struct user_regs_struct {
+ long r0, r1, r2, r3, r4, r5, r6, r7;
+ long p0, p1, p2, p3, p4, p5, usp, fp;
+ long i0, i1, i2, i3;
+ long l0, l1, l2, l3;
+ long b0, b1, b2, b3;
+ long m0, m1, m2, m3;
+ long a0w, a1w;
+ long a0x, a1x;
+ unsigned long rets;
+ unsigned long astat;
+ unsigned long pc;
+ unsigned long orig_p0;
+};
+
+/* When the kernel dumps core, it starts by dumping the user struct -
+ this will be used by gdb to figure out where the data and stack segments
+ are within the file, and what virtual addresses to use. */
+
+struct user {
+/* We start with the registers, to mimic the way that "memory" is returned
+ from the ptrace(3,...) function. */
+
+ struct user_regs_struct regs; /* Where the registers are actually stored */
+
+/* The rest of this junk is to help gdb figure out what goes where */
+ unsigned long int u_tsize; /* Text segment size (pages). */
+ unsigned long int u_dsize; /* Data segment size (pages). */
+ unsigned long int u_ssize; /* Stack segment size (pages). */
+ unsigned long start_code; /* Starting virtual address of text. */
+ unsigned long start_stack; /* Starting virtual address of stack area.
+ This is actually the bottom of the stack,
+ the top of the stack is always found in the
+ esp register. */
+ long int signal; /* Signal that caused the core dump. */
+ int reserved; /* No longer used */
+ struct user_regs_struct *u_ar0;
+ /* Used by gdb to help find the values for */
+ /* the registers. */
+ unsigned long magic; /* To uniquely identify a core file */
+ char u_comm[32]; /* User command that was responsible */
+};
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif
diff --git a/include/asm-cris/kdebug.h b/include/asm-cris/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-cris/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-frv/atomic.h b/include/asm-frv/atomic.h
index 066386a..d425d8d 100644
--- a/include/asm-frv/atomic.h
+++ b/include/asm-frv/atomic.h
@@ -16,6 +16,7 @@
#include <linux/types.h>
#include <asm/spr-regs.h>
+#include <asm/system.h>
#ifdef CONFIG_SMP
#error not SMP safe
@@ -258,85 +259,23 @@ extern uint32_t __xchg_32(uint32_t i, volatile void *v);
#define tas(ptr) (xchg((ptr), 1))
-/*****************************************************************************/
-/*
- * compare and conditionally exchange value with memory
- * - if (*ptr == test) then orig = *ptr; *ptr = test;
- * - if (*ptr != test) then orig = *ptr;
- */
-#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
-
-#define cmpxchg(ptr, test, new) \
-({ \
- __typeof__(ptr) __xg_ptr = (ptr); \
- __typeof__(*(ptr)) __xg_orig, __xg_tmp; \
- __typeof__(*(ptr)) __xg_test = (test); \
- __typeof__(*(ptr)) __xg_new = (new); \
- \
- switch (sizeof(__xg_orig)) { \
- case 4: \
- asm volatile( \
- "0: \n" \
- " orcc gr0,gr0,gr0,icc3 \n" \
- " ckeq icc3,cc7 \n" \
- " ld.p %M0,%1 \n" \
- " orcr cc7,cc7,cc3 \n" \
- " sub%I4cc %1,%4,%2,icc0 \n" \
- " bne icc0,#0,1f \n" \
- " cst.p %3,%M0 ,cc3,#1 \n" \
- " corcc gr29,gr29,gr0 ,cc3,#1 \n" \
- " beq icc3,#0,0b \n" \
- "1: \n" \
- : "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp) \
- : "r"(__xg_new), "NPr"(__xg_test) \
- : "memory", "cc7", "cc3", "icc3", "icc0" \
- ); \
- break; \
- \
- default: \
- __xg_orig = 0; \
- asm volatile("break"); \
- break; \
- } \
- \
- __xg_orig; \
-})
-
-#else
-
-extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
-
-#define cmpxchg(ptr, test, new) \
-({ \
- __typeof__(ptr) __xg_ptr = (ptr); \
- __typeof__(*(ptr)) __xg_orig; \
- __typeof__(*(ptr)) __xg_test = (test); \
- __typeof__(*(ptr)) __xg_new = (new); \
- \
- switch (sizeof(__xg_orig)) { \
- case 4: __xg_orig = __cmpxchg_32(__xg_ptr, __xg_test, __xg_new); break; \
- default: \
- __xg_orig = 0; \
- asm volatile("break"); \
- break; \
- } \
- \
- __xg_orig; \
-})
-
-#endif
-
#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
- c = old; \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
diff --git a/include/asm-frv/kdebug.h b/include/asm-frv/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-frv/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h
index 8a05aa1..2687c77 100644
--- a/include/asm-frv/pgtable.h
+++ b/include/asm-frv/pgtable.h
@@ -509,10 +509,6 @@ static inline int pte_file(pte_t pte)
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
diff --git a/include/asm-frv/semaphore.h b/include/asm-frv/semaphore.h
index 907c5c3..0958652 100644
--- a/include/asm-frv/semaphore.h
+++ b/include/asm-frv/semaphore.h
@@ -20,8 +20,6 @@
#include <linux/spinlock.h>
#include <linux/rwsem.h>
-#define SEMAPHORE_DEBUG 0
-
/*
* the semaphore definition
* - if counter is >0 then there are tokens available on the semaphore for down to collect
@@ -32,12 +30,12 @@ struct semaphore {
unsigned counter;
spinlock_t wait_lock;
struct list_head wait_list;
-#if SEMAPHORE_DEBUG
+#ifdef CONFIG_DEBUG_SEMAPHORE
unsigned __magic;
#endif
};
-#if SEMAPHORE_DEBUG
+#ifdef CONFIG_DEBUG_SEMAPHORE
# define __SEM_DEBUG_INIT(name) , (long)&(name).__magic
#else
# define __SEM_DEBUG_INIT(name)
@@ -76,7 +74,7 @@ static inline void down(struct semaphore *sem)
{
unsigned long flags;
-#if SEMAPHORE_DEBUG
+#ifdef CONFIG_DEBUG_SEMAPHORE
CHECK_MAGIC(sem->__magic);
#endif
@@ -95,7 +93,7 @@ static inline int down_interruptible(struct semaphore *sem)
unsigned long flags;
int ret = 0;
-#if SEMAPHORE_DEBUG
+#ifdef CONFIG_DEBUG_SEMAPHORE
CHECK_MAGIC(sem->__magic);
#endif
@@ -119,7 +117,7 @@ static inline int down_trylock(struct semaphore *sem)
unsigned long flags;
int success = 0;
-#if SEMAPHORE_DEBUG
+#ifdef CONFIG_DEBUG_SEMAPHORE
CHECK_MAGIC(sem->__magic);
#endif
@@ -136,7 +134,7 @@ static inline void up(struct semaphore *sem)
{
unsigned long flags;
-#if SEMAPHORE_DEBUG
+#ifdef CONFIG_DEBUG_SEMAPHORE
CHECK_MAGIC(sem->__magic);
#endif
diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h
index 1166899..be303b3 100644
--- a/include/asm-frv/system.h
+++ b/include/asm-frv/system.h
@@ -13,7 +13,6 @@
#define _ASM_SYSTEM_H
#include <linux/linkage.h>
-#include <asm/atomic.h>
struct thread_struct;
@@ -197,4 +196,73 @@ extern void free_initmem(void);
#define arch_align_stack(x) (x)
+/*****************************************************************************/
+/*
+ * compare and conditionally exchange value with memory
+ * - if (*ptr == test) then orig = *ptr; *ptr = test;
+ * - if (*ptr != test) then orig = *ptr;
+ */
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+
+#define cmpxchg(ptr, test, new) \
+({ \
+ __typeof__(ptr) __xg_ptr = (ptr); \
+ __typeof__(*(ptr)) __xg_orig, __xg_tmp; \
+ __typeof__(*(ptr)) __xg_test = (test); \
+ __typeof__(*(ptr)) __xg_new = (new); \
+ \
+ switch (sizeof(__xg_orig)) { \
+ case 4: \
+ asm volatile( \
+ "0: \n" \
+ " orcc gr0,gr0,gr0,icc3 \n" \
+ " ckeq icc3,cc7 \n" \
+ " ld.p %M0,%1 \n" \
+ " orcr cc7,cc7,cc3 \n" \
+ " sub%I4cc %1,%4,%2,icc0 \n" \
+ " bne icc0,#0,1f \n" \
+ " cst.p %3,%M0 ,cc3,#1 \n" \
+ " corcc gr29,gr29,gr0 ,cc3,#1 \n" \
+ " beq icc3,#0,0b \n" \
+ "1: \n" \
+ : "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp) \
+ : "r"(__xg_new), "NPr"(__xg_test) \
+ : "memory", "cc7", "cc3", "icc3", "icc0" \
+ ); \
+ break; \
+ \
+ default: \
+ __xg_orig = 0; \
+ asm volatile("break"); \
+ break; \
+ } \
+ \
+ __xg_orig; \
+})
+
+#else
+
+extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
+
+#define cmpxchg(ptr, test, new) \
+({ \
+ __typeof__(ptr) __xg_ptr = (ptr); \
+ __typeof__(*(ptr)) __xg_orig; \
+ __typeof__(*(ptr)) __xg_test = (test); \
+ __typeof__(*(ptr)) __xg_new = (new); \
+ \
+ switch (sizeof(__xg_orig)) { \
+ case 4: __xg_orig = __cmpxchg_32(__xg_ptr, __xg_test, __xg_new); break; \
+ default: \
+ __xg_orig = 0; \
+ asm volatile("break"); \
+ break; \
+ } \
+ \
+ __xg_orig; \
+})
+
+#endif
+
+
#endif /* _ASM_SYSTEM_H */
diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h
index b7e4a04..85fd0aa 100644
--- a/include/asm-generic/atomic.h
+++ b/include/asm-generic/atomic.h
@@ -66,6 +66,76 @@ static inline void atomic_long_sub(long i, atomic_long_t *l)
atomic64_sub(i, v);
}
+static inline int atomic_long_sub_and_test(long i, atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return atomic64_sub_and_test(i, v);
+}
+
+static inline int atomic_long_dec_and_test(atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return atomic64_dec_and_test(v);
+}
+
+static inline int atomic_long_inc_and_test(atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return atomic64_inc_and_test(v);
+}
+
+static inline int atomic_long_add_negative(long i, atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return atomic64_add_negative(i, v);
+}
+
+static inline long atomic_long_add_return(long i, atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_add_return(i, v);
+}
+
+static inline long atomic_long_sub_return(long i, atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_sub_return(i, v);
+}
+
+static inline long atomic_long_inc_return(atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_inc_return(v);
+}
+
+static inline long atomic_long_dec_return(atomic_long_t *l)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_dec_return(v);
+}
+
+static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u)
+{
+ atomic64_t *v = (atomic64_t *)l;
+
+ return (long)atomic64_add_unless(v, a, u);
+}
+
+#define atomic_long_inc_not_zero(l) atomic64_inc_not_zero((atomic64_t *)(l))
+
+#define atomic_long_cmpxchg(l, old, new) \
+ (atomic_cmpxchg((atomic64_t *)(l), (old), (new)))
+#define atomic_long_xchg(v, new) \
+ (atomic_xchg((atomic64_t *)(l), (new)))
+
#else /* BITS_PER_LONG == 64 */
typedef atomic_t atomic_long_t;
@@ -113,6 +183,76 @@ static inline void atomic_long_sub(long i, atomic_long_t *l)
atomic_sub(i, v);
}
+static inline int atomic_long_sub_and_test(long i, atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return atomic_sub_and_test(i, v);
+}
+
+static inline int atomic_long_dec_and_test(atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return atomic_dec_and_test(v);
+}
+
+static inline int atomic_long_inc_and_test(atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return atomic_inc_and_test(v);
+}
+
+static inline int atomic_long_add_negative(long i, atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return atomic_add_negative(i, v);
+}
+
+static inline long atomic_long_add_return(long i, atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_add_return(i, v);
+}
+
+static inline long atomic_long_sub_return(long i, atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_sub_return(i, v);
+}
+
+static inline long atomic_long_inc_return(atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_inc_return(v);
+}
+
+static inline long atomic_long_dec_return(atomic_long_t *l)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_dec_return(v);
+}
+
+static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u)
+{
+ atomic_t *v = (atomic_t *)l;
+
+ return (long)atomic_add_unless(v, a, u);
+}
+
+#define atomic_long_inc_not_zero(l) atomic_inc_not_zero((atomic_t *)(l))
+
+#define atomic_long_cmpxchg(l, old, new) \
+ (atomic_cmpxchg((atomic_t *)(l), (old), (new)))
+#define atomic_long_xchg(v, new) \
+ (atomic_xchg((atomic_t *)(l), (new)))
+
#endif /* BITS_PER_LONG == 64 */
#endif /* _ASM_GENERIC_ATOMIC_H */
diff --git a/include/asm-generic/kdebug.h b/include/asm-generic/kdebug.h
new file mode 100644
index 0000000..2b799c9
--- /dev/null
+++ b/include/asm-generic/kdebug.h
@@ -0,0 +1,8 @@
+#ifndef _ASM_GENERIC_KDEBUG_H
+#define _ASM_GENERIC_KDEBUG_H
+
+enum die_val {
+ DIE_UNUSED,
+};
+
+#endif /* _ASM_GENERIC_KDEBUG_H */
diff --git a/include/asm-generic/local.h b/include/asm-generic/local.h
index ab46929..33d7d04 100644
--- a/include/asm-generic/local.h
+++ b/include/asm-generic/local.h
@@ -33,6 +33,19 @@ typedef struct
#define local_add(i,l) atomic_long_add((i),(&(l)->a))
#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
+#define local_sub_and_test(i, l) atomic_long_sub_and_test((i), (&(l)->a))
+#define local_dec_and_test(l) atomic_long_dec_and_test(&(l)->a)
+#define local_inc_and_test(l) atomic_long_inc_and_test(&(l)->a)
+#define local_add_negative(i, l) atomic_long_add_negative((i), (&(l)->a))
+#define local_add_return(i, l) atomic_long_add_return((i), (&(l)->a))
+#define local_sub_return(i, l) atomic_long_sub_return((i), (&(l)->a))
+#define local_inc_return(l) atomic_long_inc_return(&(l)->a)
+
+#define local_cmpxchg(l, o, n) atomic_long_cmpxchg((&(l)->a), (o), (n))
+#define local_xchg(l, n) atomic_long_xchg((&(l)->a), (n))
+#define local_add_unless(l, a, u) atomic_long_add_unless((&(l)->a), (a), (u))
+#define local_inc_not_zero(l) atomic_long_inc_not_zero(&(l)->a)
+
/* Non-atomic variants, ie. preemption disabled and won't be touched
* in interrupt, etc. Some archs can optimize this case well. */
#define __local_inc(l) local_set((l), local_read(l) + 1)
@@ -44,19 +57,19 @@ typedef struct
* much more efficient than these naive implementations. Note they take
* a variable (eg. mystruct.foo), not an address.
*/
-#define cpu_local_read(v) local_read(&__get_cpu_var(v))
-#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i))
-#define cpu_local_inc(v) local_inc(&__get_cpu_var(v))
-#define cpu_local_dec(v) local_dec(&__get_cpu_var(v))
-#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v))
-#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v))
+#define cpu_local_read(l) local_read(&__get_cpu_var(l))
+#define cpu_local_set(l, i) local_set(&__get_cpu_var(l), (i))
+#define cpu_local_inc(l) local_inc(&__get_cpu_var(l))
+#define cpu_local_dec(l) local_dec(&__get_cpu_var(l))
+#define cpu_local_add(i, l) local_add((i), &__get_cpu_var(l))
+#define cpu_local_sub(i, l) local_sub((i), &__get_cpu_var(l))
/* Non-atomic increments, ie. preemption disabled and won't be touched
* in interrupt, etc. Some archs can optimize this case well.
*/
-#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v))
-#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v))
-#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v))
-#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v))
+#define __cpu_local_inc(l) __local_inc(&__get_cpu_var(l))
+#define __cpu_local_dec(l) __local_dec(&__get_cpu_var(l))
+#define __cpu_local_add(i, l) __local_add((i), &__get_cpu_var(l))
+#define __cpu_local_sub(i, l) __local_sub((i), &__get_cpu_var(l))
#endif /* _ASM_GENERIC_LOCAL_H */
diff --git a/include/asm-h8300/irq.h b/include/asm-h8300/irq.h
index 42a3ac4..41be646 100644
--- a/include/asm-h8300/irq.h
+++ b/include/asm-h8300/irq.h
@@ -61,6 +61,5 @@ static __inline__ int irq_canonicalize(int irq)
extern void enable_irq(unsigned int);
extern void disable_irq(unsigned int);
-#define disable_irq_nosync(x) disable_irq(x)
#endif /* _H8300_IRQ_H_ */
diff --git a/include/asm-h8300/irq_regs.h b/include/asm-h8300/irq_regs.h
new file mode 100644
index 0000000..3dd9c0b
--- /dev/null
+++ b/include/asm-h8300/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/include/asm-h8300/kdebug.h b/include/asm-h8300/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-h8300/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-h8300/pgtable.h b/include/asm-h8300/pgtable.h
index 8b7c685..a09230a 100644
--- a/include/asm-h8300/pgtable.h
+++ b/include/asm-h8300/pgtable.h
@@ -55,10 +55,6 @@ extern int is_in_rom(unsigned long);
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/*
* All 32bit addresses are effectively valid for vmalloc...
* Sort of meaningless for non-VM targets.
@@ -73,4 +69,5 @@ extern int is_in_rom(unsigned long);
#define VMALLOC_START 0
#define VMALLOC_END 0xffffffff
+#define arch_enter_lazy_cpu_mode() do {} while (0)
#endif /* _H8300_PGTABLE_H */
diff --git a/include/asm-h8300/system.h b/include/asm-h8300/system.h
index 5084a9d..7807018 100644
--- a/include/asm-h8300/system.h
+++ b/include/asm-h8300/system.h
@@ -98,7 +98,6 @@ asmlinkage void resume(void);
#endif
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((volatile struct __xchg_dummy *)(x))
diff --git a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h
index 4dd2723..0baa2f8 100644
--- a/include/asm-i386/atomic.h
+++ b/include/asm-i386/atomic.h
@@ -3,6 +3,7 @@
#include <linux/compiler.h>
#include <asm/processor.h>
+#include <asm/cmpxchg.h>
/*
* Atomic operations that C can't guarantee us. Useful for
@@ -51,7 +52,7 @@ static __inline__ void atomic_add(int i, atomic_t *v)
}
/**
- * atomic_sub - subtract the atomic variable
+ * atomic_sub - subtract integer from atomic variable
* @i: integer value to subtract
* @v: pointer of type atomic_t
*
@@ -170,7 +171,7 @@ static __inline__ int atomic_add_negative(int i, atomic_t *v)
}
/**
- * atomic_add_return - add and return
+ * atomic_add_return - add integer and return
* @v: pointer of type atomic_t
* @i: integer value to add
*
@@ -202,13 +203,20 @@ no_xadd: /* Legacy 386 processor */
#endif
}
+/**
+ * atomic_sub_return - subtract integer and return
+ * @v: pointer of type atomic_t
+ * @i: integer value to subtract
+ *
+ * Atomically subtracts @i from @v and returns @v - @i
+ */
static __inline__ int atomic_sub_return(int i, atomic_t *v)
{
return atomic_add_return(-i,v);
}
-#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
/**
* atomic_add_unless - add unless the number is already a given value
@@ -219,20 +227,21 @@ static __inline__ int atomic_sub_return(int i, atomic_t *v)
* Atomically adds @a to @v, so long as @v was not already @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- for (;;) { \
- if (unlikely(c == (u))) \
- break; \
- old = atomic_cmpxchg((v), c, c + (a)); \
- if (likely(old == c)) \
- break; \
- c = old; \
- } \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
#define atomic_inc_return(v) (atomic_add_return(1,v))
diff --git a/include/asm-i386/cmpxchg.h b/include/asm-i386/cmpxchg.h
new file mode 100644
index 0000000..7adcef0
--- /dev/null
+++ b/include/asm-i386/cmpxchg.h
@@ -0,0 +1,293 @@
+#ifndef __ASM_CMPXCHG_H
+#define __ASM_CMPXCHG_H
+
+#include <linux/bitops.h> /* for LOCK_PREFIX */
+
+#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((struct __xchg_dummy *)(x))
+
+
+#ifdef CONFIG_X86_CMPXCHG64
+
+/*
+ * The semantics of XCHGCMP8B are a bit strange, this is why
+ * there is a loop and the loading of %%eax and %%edx has to
+ * be inside. This inlines well in most cases, the cached
+ * cost is around ~38 cycles. (in the future we might want
+ * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that
+ * might have an implicit FPU-save as a cost, so it's not
+ * clear which path to go.)
+ *
+ * cmpxchg8b must be used with the lock prefix here to allow
+ * the instruction to be executed atomically, see page 3-102
+ * of the instruction set reference 24319102.pdf. We need
+ * the reader side to see the coherent 64bit value.
+ */
+static inline void __set_64bit (unsigned long long * ptr,
+ unsigned int low, unsigned int high)
+{
+ __asm__ __volatile__ (
+ "\n1:\t"
+ "movl (%0), %%eax\n\t"
+ "movl 4(%0), %%edx\n\t"
+ "lock cmpxchg8b (%0)\n\t"
+ "jnz 1b"
+ : /* no outputs */
+ : "D"(ptr),
+ "b"(low),
+ "c"(high)
+ : "ax","dx","memory");
+}
+
+static inline void __set_64bit_constant (unsigned long long *ptr,
+ unsigned long long value)
+{
+ __set_64bit(ptr,(unsigned int)(value), (unsigned int)((value)>>32ULL));
+}
+#define ll_low(x) *(((unsigned int*)&(x))+0)
+#define ll_high(x) *(((unsigned int*)&(x))+1)
+
+static inline void __set_64bit_var (unsigned long long *ptr,
+ unsigned long long value)
+{
+ __set_64bit(ptr,ll_low(value), ll_high(value));
+}
+
+#define set_64bit(ptr,value) \
+(__builtin_constant_p(value) ? \
+ __set_64bit_constant(ptr, value) : \
+ __set_64bit_var(ptr, value) )
+
+#define _set_64bit(ptr,value) \
+(__builtin_constant_p(value) ? \
+ __set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \
+ __set_64bit(ptr, ll_low(value), ll_high(value)) )
+
+#endif
+
+/*
+ * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
+ * Note 2: xchg has side effect, so that attribute volatile is necessary,
+ * but generally the primitive is invalid, *ptr is output argument. --ANK
+ */
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+ switch (size) {
+ case 1:
+ __asm__ __volatile__("xchgb %b0,%1"
+ :"=q" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
+ break;
+ case 2:
+ __asm__ __volatile__("xchgw %w0,%1"
+ :"=r" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
+ break;
+ case 4:
+ __asm__ __volatile__("xchgl %0,%1"
+ :"=r" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
+ break;
+ }
+ return x;
+}
+
+/*
+ * Atomic compare and exchange. Compare OLD with MEM, if identical,
+ * store NEW in MEM. Return the initial value in MEM. Success is
+ * indicated by comparing RETURN with OLD.
+ */
+
+#ifdef CONFIG_X86_CMPXCHG
+#define __HAVE_ARCH_CMPXCHG 1
+#define cmpxchg(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
+ (unsigned long)(n),sizeof(*(ptr))))
+#define sync_cmpxchg(ptr,o,n)\
+ ((__typeof__(*(ptr)))__sync_cmpxchg((ptr),(unsigned long)(o),\
+ (unsigned long)(n),sizeof(*(ptr))))
+#define cmpxchg_local(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg_local((ptr),(unsigned long)(o),\
+ (unsigned long)(n),sizeof(*(ptr))))
+#endif
+
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+ unsigned long new, int size)
+{
+ unsigned long prev;
+ switch (size) {
+ case 1:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
+ : "=a"(prev)
+ : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 2:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 4:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ }
+ return old;
+}
+
+/*
+ * Always use locked operations when touching memory shared with a
+ * hypervisor, since the system may be SMP even if the guest kernel
+ * isn't.
+ */
+static inline unsigned long __sync_cmpxchg(volatile void *ptr,
+ unsigned long old,
+ unsigned long new, int size)
+{
+ unsigned long prev;
+ switch (size) {
+ case 1:
+ __asm__ __volatile__("lock; cmpxchgb %b1,%2"
+ : "=a"(prev)
+ : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 2:
+ __asm__ __volatile__("lock; cmpxchgw %w1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 4:
+ __asm__ __volatile__("lock; cmpxchgl %1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ }
+ return old;
+}
+
+static inline unsigned long __cmpxchg_local(volatile void *ptr,
+ unsigned long old, unsigned long new, int size)
+{
+ unsigned long prev;
+ switch (size) {
+ case 1:
+ __asm__ __volatile__("cmpxchgb %b1,%2"
+ : "=a"(prev)
+ : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 2:
+ __asm__ __volatile__("cmpxchgw %w1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 4:
+ __asm__ __volatile__("cmpxchgl %1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ }
+ return old;
+}
+
+#ifndef CONFIG_X86_CMPXCHG
+/*
+ * Building a kernel capable running on 80386. It may be necessary to
+ * simulate the cmpxchg on the 80386 CPU. For that purpose we define
+ * a function for each of the sizes we support.
+ */
+
+extern unsigned long cmpxchg_386_u8(volatile void *, u8, u8);
+extern unsigned long cmpxchg_386_u16(volatile void *, u16, u16);
+extern unsigned long cmpxchg_386_u32(volatile void *, u32, u32);
+
+static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
+ unsigned long new, int size)
+{
+ switch (size) {
+ case 1:
+ return cmpxchg_386_u8(ptr, old, new);
+ case 2:
+ return cmpxchg_386_u16(ptr, old, new);
+ case 4:
+ return cmpxchg_386_u32(ptr, old, new);
+ }
+ return old;
+}
+
+#define cmpxchg(ptr,o,n) \
+({ \
+ __typeof__(*(ptr)) __ret; \
+ if (likely(boot_cpu_data.x86 > 3)) \
+ __ret = __cmpxchg((ptr), (unsigned long)(o), \
+ (unsigned long)(n), sizeof(*(ptr))); \
+ else \
+ __ret = cmpxchg_386((ptr), (unsigned long)(o), \
+ (unsigned long)(n), sizeof(*(ptr))); \
+ __ret; \
+})
+#define cmpxchg_local(ptr,o,n) \
+({ \
+ __typeof__(*(ptr)) __ret; \
+ if (likely(boot_cpu_data.x86 > 3)) \
+ __ret = __cmpxchg_local((ptr), (unsigned long)(o), \
+ (unsigned long)(n), sizeof(*(ptr))); \
+ else \
+ __ret = cmpxchg_386((ptr), (unsigned long)(o), \
+ (unsigned long)(n), sizeof(*(ptr))); \
+ __ret; \
+})
+#endif
+
+#ifdef CONFIG_X86_CMPXCHG64
+
+static inline unsigned long long __cmpxchg64(volatile void *ptr, unsigned long long old,
+ unsigned long long new)
+{
+ unsigned long long prev;
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
+ : "=A"(prev)
+ : "b"((unsigned long)new),
+ "c"((unsigned long)(new >> 32)),
+ "m"(*__xg(ptr)),
+ "0"(old)
+ : "memory");
+ return prev;
+}
+
+static inline unsigned long long __cmpxchg64_local(volatile void *ptr,
+ unsigned long long old, unsigned long long new)
+{
+ unsigned long long prev;
+ __asm__ __volatile__("cmpxchg8b %3"
+ : "=A"(prev)
+ : "b"((unsigned long)new),
+ "c"((unsigned long)(new >> 32)),
+ "m"(*__xg(ptr)),
+ "0"(old)
+ : "memory");
+ return prev;
+}
+
+#define cmpxchg64(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg64((ptr),(unsigned long long)(o),\
+ (unsigned long long)(n)))
+#define cmpxchg64_local(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg64_local((ptr),(unsigned long long)(o),\
+ (unsigned long long)(n)))
+#endif
+
+#endif
diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h
index d304ab4..b32df3a 100644
--- a/include/asm-i386/elf.h
+++ b/include/asm-i386/elf.h
@@ -9,8 +9,6 @@
#include <asm/user.h>
#include <asm/auxvec.h>
-#include <linux/utsname.h>
-
#define R_386_NONE 0
#define R_386_32 1
#define R_386_PC32 2
diff --git a/include/asm-i386/ioctls.h b/include/asm-i386/ioctls.h
index f962fad..ef58787 100644
--- a/include/asm-i386/ioctls.h
+++ b/include/asm-i386/ioctls.h
@@ -47,6 +47,10 @@
#define TIOCSBRK 0x5427 /* BSD compatibility */
#define TIOCCBRK 0x5428 /* BSD compatibility */
#define TIOCGSID 0x5429 /* Return the session ID of FD */
+#define TCGETS2 _IOR('T',0x2A, struct termios2)
+#define TCSETS2 _IOW('T',0x2B, struct termios2)
+#define TCSETSW2 _IOW('T',0x2C, struct termios2)
+#define TCSETSF2 _IOW('T',0x2D, struct termios2)
#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
diff --git a/include/asm-i386/kdebug.h b/include/asm-i386/kdebug.h
index d18cdb9..05c3117 100644
--- a/include/asm-i386/kdebug.h
+++ b/include/asm-i386/kdebug.h
@@ -9,19 +9,8 @@
struct pt_regs;
-struct die_args {
- struct pt_regs *regs;
- const char *str;
- long err;
- int trapnr;
- int signr;
-};
-
-extern int register_die_notifier(struct notifier_block *);
-extern int unregister_die_notifier(struct notifier_block *);
extern int register_page_fault_notifier(struct notifier_block *);
extern int unregister_page_fault_notifier(struct notifier_block *);
-extern struct atomic_notifier_head i386die_chain;
/* Grossly misnamed. */
@@ -38,20 +27,8 @@ enum die_val {
DIE_GPF,
DIE_CALL,
DIE_NMI_IPI,
+ DIE_NMI_POST,
DIE_PAGE_FAULT,
};
-static inline int notify_die(enum die_val val, const char *str,
- struct pt_regs *regs, long err, int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .str = str,
- .err = err,
- .trapnr = trap,
- .signr = sig
- };
- return atomic_notifier_call_chain(&i386die_chain, val, &args);
-}
-
#endif
diff --git a/include/asm-i386/kexec.h b/include/asm-i386/kexec.h
index bcb5b21..4b9dc9e 100644
--- a/include/asm-i386/kexec.h
+++ b/include/asm-i386/kexec.h
@@ -45,8 +45,6 @@
/* We can also handle crash dumps from 64 bit kernel. */
#define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64)
-#define MAX_NOTE_BYTES 1024
-
/* CPU does not save ss and esp on stack if execution is already
* running in kernel mode at the time of NMI occurrence. This code
* fixes it.
diff --git a/include/asm-i386/local.h b/include/asm-i386/local.h
index 12060e2..e13d3e9 100644
--- a/include/asm-i386/local.h
+++ b/include/asm-i386/local.h
@@ -2,47 +2,198 @@
#define _ARCH_I386_LOCAL_H
#include <linux/percpu.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
typedef struct
{
- volatile long counter;
+ atomic_long_t a;
} local_t;
-#define LOCAL_INIT(i) { (i) }
+#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
-#define local_read(v) ((v)->counter)
-#define local_set(v,i) (((v)->counter) = (i))
+#define local_read(l) atomic_long_read(&(l)->a)
+#define local_set(l,i) atomic_long_set(&(l)->a, (i))
-static __inline__ void local_inc(local_t *v)
+static __inline__ void local_inc(local_t *l)
{
__asm__ __volatile__(
"incl %0"
- :"+m" (v->counter));
+ :"+m" (l->a.counter));
}
-static __inline__ void local_dec(local_t *v)
+static __inline__ void local_dec(local_t *l)
{
__asm__ __volatile__(
"decl %0"
- :"+m" (v->counter));
+ :"+m" (l->a.counter));
}
-static __inline__ void local_add(long i, local_t *v)
+static __inline__ void local_add(long i, local_t *l)
{
__asm__ __volatile__(
"addl %1,%0"
- :"+m" (v->counter)
+ :"+m" (l->a.counter)
:"ir" (i));
}
-static __inline__ void local_sub(long i, local_t *v)
+static __inline__ void local_sub(long i, local_t *l)
{
__asm__ __volatile__(
"subl %1,%0"
- :"+m" (v->counter)
+ :"+m" (l->a.counter)
:"ir" (i));
}
+/**
+ * local_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @l: pointer of type local_t
+ *
+ * Atomically subtracts @i from @l and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+static __inline__ int local_sub_and_test(long i, local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "subl %2,%0; sete %1"
+ :"+m" (l->a.counter), "=qm" (c)
+ :"ir" (i) : "memory");
+ return c;
+}
+
+/**
+ * local_dec_and_test - decrement and test
+ * @l: pointer of type local_t
+ *
+ * Atomically decrements @l by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+static __inline__ int local_dec_and_test(local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "decl %0; sete %1"
+ :"+m" (l->a.counter), "=qm" (c)
+ : : "memory");
+ return c != 0;
+}
+
+/**
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+static __inline__ int local_inc_and_test(local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "incl %0; sete %1"
+ :"+m" (l->a.counter), "=qm" (c)
+ : : "memory");
+ return c != 0;
+}
+
+/**
+ * local_add_negative - add and test if negative
+ * @l: pointer of type local_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @l and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+static __inline__ int local_add_negative(long i, local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "addl %2,%0; sets %1"
+ :"+m" (l->a.counter), "=qm" (c)
+ :"ir" (i) : "memory");
+ return c;
+}
+
+/**
+ * local_add_return - add and return
+ * @l: pointer of type local_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @l and returns @i + @l
+ */
+static __inline__ long local_add_return(long i, local_t *l)
+{
+ long __i;
+#ifdef CONFIG_M386
+ unsigned long flags;
+ if(unlikely(boot_cpu_data.x86==3))
+ goto no_xadd;
+#endif
+ /* Modern 486+ processor */
+ __i = i;
+ __asm__ __volatile__(
+ "xaddl %0, %1;"
+ :"+r" (i), "+m" (l->a.counter)
+ : : "memory");
+ return i + __i;
+
+#ifdef CONFIG_M386
+no_xadd: /* Legacy 386 processor */
+ local_irq_save(flags);
+ __i = local_read(l);
+ local_set(l, i + __i);
+ local_irq_restore(flags);
+ return i + __i;
+#endif
+}
+
+static __inline__ long local_sub_return(long i, local_t *l)
+{
+ return local_add_return(-i,l);
+}
+
+#define local_inc_return(l) (local_add_return(1,l))
+#define local_dec_return(l) (local_sub_return(1,l))
+
+#define local_cmpxchg(l, o, n) \
+ (cmpxchg_local(&((l)->a.counter), (o), (n)))
+/* Always has a lock prefix */
+#define local_xchg(l, n) (xchg(&((l)->a.counter), (n)))
+
+/**
+ * local_add_unless - add unless the number is a given value
+ * @l: pointer of type local_t
+ * @a: the amount to add to l...
+ * @u: ...unless l is equal to u.
+ *
+ * Atomically adds @a to @l, so long as it was not @u.
+ * Returns non-zero if @l was not @u, and zero otherwise.
+ */
+#define local_add_unless(l, a, u) \
+({ \
+ long c, old; \
+ c = local_read(l); \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = local_cmpxchg((l), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
+ c = old; \
+ } \
+ c != (u); \
+})
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
/* On x86, these are no better than the atomic variants. */
#define __local_inc(l) local_inc(l)
#define __local_dec(l) local_dec(l)
@@ -56,27 +207,27 @@ static __inline__ void local_sub(long i, local_t *v)
/* Need to disable preemption for the cpu local counters otherwise we could
still access a variable of a previous CPU in a non atomic way. */
-#define cpu_local_wrap_v(v) \
+#define cpu_local_wrap_v(l) \
({ local_t res__; \
preempt_disable(); \
- res__ = (v); \
+ res__ = (l); \
preempt_enable(); \
res__; })
-#define cpu_local_wrap(v) \
+#define cpu_local_wrap(l) \
({ preempt_disable(); \
- v; \
+ l; \
preempt_enable(); }) \
-#define cpu_local_read(v) cpu_local_wrap_v(local_read(&__get_cpu_var(v)))
-#define cpu_local_set(v, i) cpu_local_wrap(local_set(&__get_cpu_var(v), (i)))
-#define cpu_local_inc(v) cpu_local_wrap(local_inc(&__get_cpu_var(v)))
-#define cpu_local_dec(v) cpu_local_wrap(local_dec(&__get_cpu_var(v)))
-#define cpu_local_add(i, v) cpu_local_wrap(local_add((i), &__get_cpu_var(v)))
-#define cpu_local_sub(i, v) cpu_local_wrap(local_sub((i), &__get_cpu_var(v)))
-
-#define __cpu_local_inc(v) cpu_local_inc(v)
-#define __cpu_local_dec(v) cpu_local_dec(v)
-#define __cpu_local_add(i, v) cpu_local_add((i), (v))
-#define __cpu_local_sub(i, v) cpu_local_sub((i), (v))
+#define cpu_local_read(l) cpu_local_wrap_v(local_read(&__get_cpu_var(l)))
+#define cpu_local_set(l, i) cpu_local_wrap(local_set(&__get_cpu_var(l), (i)))
+#define cpu_local_inc(l) cpu_local_wrap(local_inc(&__get_cpu_var(l)))
+#define cpu_local_dec(l) cpu_local_wrap(local_dec(&__get_cpu_var(l)))
+#define cpu_local_add(i, l) cpu_local_wrap(local_add((i), &__get_cpu_var(l)))
+#define cpu_local_sub(i, l) cpu_local_wrap(local_sub((i), &__get_cpu_var(l)))
+
+#define __cpu_local_inc(l) cpu_local_inc(l)
+#define __cpu_local_dec(l) cpu_local_dec(l)
+#define __cpu_local_add(i, l) cpu_local_add((i), (l))
+#define __cpu_local_sub(i, l) cpu_local_sub((i), (l))
#endif /* _ARCH_I386_LOCAL_H */
diff --git a/include/asm-i386/msr.h b/include/asm-i386/msr.h
index 9559894..26861df 100644
--- a/include/asm-i386/msr.h
+++ b/include/asm-i386/msr.h
@@ -77,7 +77,7 @@ static inline unsigned long long native_read_pmc(void)
#ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h>
#else
-
+#include <linux/errno.h>
/*
* Access to machine-specific registers (available on 586 and better only)
* Note: the rd* operations modify the parameters directly (without using
@@ -148,6 +148,8 @@ static inline void wrmsrl (unsigned long msr, unsigned long long val)
#ifdef CONFIG_SMP
void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
+int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
+int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
#else /* CONFIG_SMP */
static inline void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
{
@@ -157,6 +159,14 @@ static inline void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
{
wrmsr(msr_no, l, h);
}
+static inline int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
+{
+ return rdmsr_safe(msr_no, l, h);
+}
+static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+{
+ return wrmsr_safe(msr_no, l, h);
+}
#endif /* CONFIG_SMP */
#endif
#endif
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
index c6b8b94..edce9d5 100644
--- a/include/asm-i386/pgtable.h
+++ b/include/asm-i386/pgtable.h
@@ -243,8 +243,6 @@ static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; re
static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; }
static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return pte; }
-extern void vmalloc_sync_all(void);
-
#ifdef CONFIG_X86_PAE
# include <asm/pgtable-3level.h>
#else
@@ -296,12 +294,25 @@ do { \
} \
} while (0)
-/*
- * We don't actually have these, but we want to advertise them so that
- * we can encompass the flush here.
- */
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
+#define ptep_test_and_clear_dirty(vma, addr, ptep) ({ \
+ int ret = 0; \
+ if (pte_dirty(*ptep)) \
+ ret = test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low); \
+ if (ret) \
+ pte_update_defer(vma->vm_mm, addr, ptep); \
+ ret; \
+})
+
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define ptep_test_and_clear_young(vma, addr, ptep) ({ \
+ int ret = 0; \
+ if (pte_young(*ptep)) \
+ ret = test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low); \
+ if (ret) \
+ pte_update_defer(vma->vm_mm, addr, ptep); \
+ ret; \
+})
/*
* Rules for using ptep_establish: the pte MUST be a user pte, and
@@ -318,12 +329,9 @@ do { \
#define ptep_clear_flush_dirty(vma, address, ptep) \
({ \
int __dirty; \
- __dirty = pte_dirty(*(ptep)); \
- if (__dirty) { \
- clear_bit(_PAGE_BIT_DIRTY, &(ptep)->pte_low); \
- pte_update_defer((vma)->vm_mm, (address), (ptep)); \
+ __dirty = ptep_test_and_clear_dirty((vma), (address), (ptep)); \
+ if (__dirty) \
flush_tlb_page(vma, address); \
- } \
__dirty; \
})
@@ -331,12 +339,9 @@ do { \
#define ptep_clear_flush_young(vma, address, ptep) \
({ \
int __young; \
- __young = pte_young(*(ptep)); \
- if (__young) { \
- clear_bit(_PAGE_BIT_ACCESSED, &(ptep)->pte_low); \
- pte_update_defer((vma)->vm_mm, (address), (ptep)); \
+ __young = ptep_test_and_clear_young((vma), (address), (ptep)); \
+ if (__young) \
flush_tlb_page(vma, address); \
- } \
__young; \
})
@@ -537,10 +542,6 @@ static inline void paravirt_pagetable_setup_done(pgd_t *base)
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#include <asm-generic/pgtable.h>
#endif /* _I386_PGTABLE_H */
diff --git a/include/asm-i386/serial.h b/include/asm-i386/serial.h
index bd67480..57a4306 100644
--- a/include/asm-i386/serial.h
+++ b/include/asm-i386/serial.h
@@ -11,19 +11,3 @@
* megabits/second; but this requires the faster clock.
*/
#define BASE_BAUD ( 1843200 / 16 )
-
-/* Standard COM flags (except for COM4, because of the 8514 problem) */
-#ifdef CONFIG_SERIAL_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
-#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
-#endif
-
-#define SERIAL_PORT_DFNS \
- /* UART CLK PORT IRQ FLAGS */ \
- { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
- { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
- { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
- { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
index c3a58c0..94ed368 100644
--- a/include/asm-i386/system.h
+++ b/include/asm-i386/system.h
@@ -4,7 +4,7 @@
#include <linux/kernel.h>
#include <asm/segment.h>
#include <asm/cpufeature.h>
-#include <linux/bitops.h> /* for LOCK_PREFIX */
+#include <asm/cmpxchg.h>
#ifdef __KERNEL__
@@ -195,238 +195,6 @@ static inline unsigned long get_limit(unsigned long segment)
#define nop() __asm__ __volatile__ ("nop")
-#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
-
-#define tas(ptr) (xchg((ptr),1))
-
-struct __xchg_dummy { unsigned long a[100]; };
-#define __xg(x) ((struct __xchg_dummy *)(x))
-
-
-#ifdef CONFIG_X86_CMPXCHG64
-
-/*
- * The semantics of XCHGCMP8B are a bit strange, this is why
- * there is a loop and the loading of %%eax and %%edx has to
- * be inside. This inlines well in most cases, the cached
- * cost is around ~38 cycles. (in the future we might want
- * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that
- * might have an implicit FPU-save as a cost, so it's not
- * clear which path to go.)
- *
- * cmpxchg8b must be used with the lock prefix here to allow
- * the instruction to be executed atomically, see page 3-102
- * of the instruction set reference 24319102.pdf. We need
- * the reader side to see the coherent 64bit value.
- */
-static inline void __set_64bit (unsigned long long * ptr,
- unsigned int low, unsigned int high)
-{
- __asm__ __volatile__ (
- "\n1:\t"
- "movl (%0), %%eax\n\t"
- "movl 4(%0), %%edx\n\t"
- "lock cmpxchg8b (%0)\n\t"
- "jnz 1b"
- : /* no outputs */
- : "D"(ptr),
- "b"(low),
- "c"(high)
- : "ax","dx","memory");
-}
-
-static inline void __set_64bit_constant (unsigned long long *ptr,
- unsigned long long value)
-{
- __set_64bit(ptr,(unsigned int)(value), (unsigned int)((value)>>32ULL));
-}
-#define ll_low(x) *(((unsigned int*)&(x))+0)
-#define ll_high(x) *(((unsigned int*)&(x))+1)
-
-static inline void __set_64bit_var (unsigned long long *ptr,
- unsigned long long value)
-{
- __set_64bit(ptr,ll_low(value), ll_high(value));
-}
-
-#define set_64bit(ptr,value) \
-(__builtin_constant_p(value) ? \
- __set_64bit_constant(ptr, value) : \
- __set_64bit_var(ptr, value) )
-
-#define _set_64bit(ptr,value) \
-(__builtin_constant_p(value) ? \
- __set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \
- __set_64bit(ptr, ll_low(value), ll_high(value)) )
-
-#endif
-
-/*
- * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
- * Note 2: xchg has side effect, so that attribute volatile is necessary,
- * but generally the primitive is invalid, *ptr is output argument. --ANK
- */
-static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
-{
- switch (size) {
- case 1:
- __asm__ __volatile__("xchgb %b0,%1"
- :"=q" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 2:
- __asm__ __volatile__("xchgw %w0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 4:
- __asm__ __volatile__("xchgl %0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- }
- return x;
-}
-
-/*
- * Atomic compare and exchange. Compare OLD with MEM, if identical,
- * store NEW in MEM. Return the initial value in MEM. Success is
- * indicated by comparing RETURN with OLD.
- */
-
-#ifdef CONFIG_X86_CMPXCHG
-#define __HAVE_ARCH_CMPXCHG 1
-#define cmpxchg(ptr,o,n)\
- ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
- (unsigned long)(n),sizeof(*(ptr))))
-#define sync_cmpxchg(ptr,o,n)\
- ((__typeof__(*(ptr)))__sync_cmpxchg((ptr),(unsigned long)(o),\
- (unsigned long)(n),sizeof(*(ptr))))
-#endif
-
-static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
- unsigned long new, int size)
-{
- unsigned long prev;
- switch (size) {
- case 1:
- __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
- : "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 2:
- __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 4:
- __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- }
- return old;
-}
-
-/*
- * Always use locked operations when touching memory shared with a
- * hypervisor, since the system may be SMP even if the guest kernel
- * isn't.
- */
-static inline unsigned long __sync_cmpxchg(volatile void *ptr,
- unsigned long old,
- unsigned long new, int size)
-{
- unsigned long prev;
- switch (size) {
- case 1:
- __asm__ __volatile__("lock; cmpxchgb %b1,%2"
- : "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 2:
- __asm__ __volatile__("lock; cmpxchgw %w1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 4:
- __asm__ __volatile__("lock; cmpxchgl %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- }
- return old;
-}
-
-#ifndef CONFIG_X86_CMPXCHG
-/*
- * Building a kernel capable running on 80386. It may be necessary to
- * simulate the cmpxchg on the 80386 CPU. For that purpose we define
- * a function for each of the sizes we support.
- */
-
-extern unsigned long cmpxchg_386_u8(volatile void *, u8, u8);
-extern unsigned long cmpxchg_386_u16(volatile void *, u16, u16);
-extern unsigned long cmpxchg_386_u32(volatile void *, u32, u32);
-
-static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
- unsigned long new, int size)
-{
- switch (size) {
- case 1:
- return cmpxchg_386_u8(ptr, old, new);
- case 2:
- return cmpxchg_386_u16(ptr, old, new);
- case 4:
- return cmpxchg_386_u32(ptr, old, new);
- }
- return old;
-}
-
-#define cmpxchg(ptr,o,n) \
-({ \
- __typeof__(*(ptr)) __ret; \
- if (likely(boot_cpu_data.x86 > 3)) \
- __ret = __cmpxchg((ptr), (unsigned long)(o), \
- (unsigned long)(n), sizeof(*(ptr))); \
- else \
- __ret = cmpxchg_386((ptr), (unsigned long)(o), \
- (unsigned long)(n), sizeof(*(ptr))); \
- __ret; \
-})
-#endif
-
-#ifdef CONFIG_X86_CMPXCHG64
-
-static inline unsigned long long __cmpxchg64(volatile void *ptr, unsigned long long old,
- unsigned long long new)
-{
- unsigned long long prev;
- __asm__ __volatile__(LOCK_PREFIX "cmpxchg8b %3"
- : "=A"(prev)
- : "b"((unsigned long)new),
- "c"((unsigned long)(new >> 32)),
- "m"(*__xg(ptr)),
- "0"(old)
- : "memory");
- return prev;
-}
-
-#define cmpxchg64(ptr,o,n)\
- ((__typeof__(*(ptr)))__cmpxchg64((ptr),(unsigned long long)(o),\
- (unsigned long long)(n)))
-
-#endif
-
/*
* Force strict CPU ordering.
* And yes, this is required on UP too when we're talking
diff --git a/include/asm-i386/termbits.h b/include/asm-i386/termbits.h
index 2e623769..a217003 100644
--- a/include/asm-i386/termbits.h
+++ b/include/asm-i386/termbits.h
@@ -17,6 +17,17 @@ struct termios {
cc_t c_cc[NCCS]; /* control characters */
};
+struct termios2 {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
struct ktermios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
@@ -129,6 +140,7 @@ struct ktermios {
#define HUPCL 0002000
#define CLOCAL 0004000
#define CBAUDEX 0010000
+#define BOTHER 0010000
#define B57600 0010001
#define B115200 0010002
#define B230400 0010003
@@ -148,6 +160,8 @@ struct ktermios {
#define CMSPAR 010000000000 /* mark or space (stick) parity */
#define CRTSCTS 020000000000 /* flow control */
+#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
+
/* c_lflag bits */
#define ISIG 0000001
#define ICANON 0000002
diff --git a/include/asm-i386/termios.h b/include/asm-i386/termios.h
index 7c99678..f520b7c 100644
--- a/include/asm-i386/termios.h
+++ b/include/asm-i386/termios.h
@@ -81,8 +81,10 @@ struct termio {
copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
})
-#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
-#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
+#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
#endif /* __KERNEL__ */
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
index 4b187bb..bf01d4b 100644
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -95,12 +95,14 @@ static inline struct thread_info *current_thread_info(void)
/* thread information allocation */
#ifdef CONFIG_DEBUG_STACK_USAGE
-#define alloc_thread_info(tsk) kzalloc(THREAD_SIZE, GFP_KERNEL)
+#define alloc_thread_info(tsk) ((struct thread_info *) \
+ __get_free_pages(GFP_KERNEL| __GFP_ZERO, get_order(THREAD_SIZE)))
#else
-#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
+#define alloc_thread_info(tsk) ((struct thread_info *) \
+ __get_free_pages(GFP_KERNEL, get_order(THREAD_SIZE)))
#endif
-#define free_thread_info(info) kfree(info)
+#define free_thread_info(info) free_pages((unsigned long)(info), get_order(THREAD_SIZE))
#else /* !__ASSEMBLY__ */
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index 833fa17..bd21e79 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -325,10 +325,11 @@
#define __NR_move_pages 317
#define __NR_getcpu 318
#define __NR_epoll_pwait 319
+#define __NR_utimensat 320
#ifdef __KERNEL__
-#define NR_syscalls 320
+#define NR_syscalls 321
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
diff --git a/include/asm-ia64/asmmacro.h b/include/asm-ia64/asmmacro.h
index c22b465..c1642fd 100644
--- a/include/asm-ia64/asmmacro.h
+++ b/include/asm-ia64/asmmacro.h
@@ -104,6 +104,16 @@ name:
#endif
/*
+ * If physical stack register size is different from DEF_NUM_STACK_REG,
+ * dynamically patch the kernel for correct size.
+ */
+ .section ".data.patch.phys_stack_reg", "a"
+ .previous
+#define LOAD_PHYS_STACK_REG_SIZE(reg) \
+[1:] adds reg=IA64_NUM_PHYS_STACK_REG*8+8,r0; \
+ .xdata4 ".data.patch.phys_stack_reg", 1b-.
+
+/*
* Up until early 2004, use of .align within a function caused bad unwind info.
* TEXT_ALIGN(n) expands into ".align n" if a fixed GAS is available or into nothing
* otherwise.
diff --git a/include/asm-ia64/atomic.h b/include/asm-ia64/atomic.h
index 569ec75..1fc3b83 100644
--- a/include/asm-ia64/atomic.h
+++ b/include/asm-ia64/atomic.h
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <asm/intrinsics.h>
+#include <asm/system.h>
/*
* On IA-64, counter must always be volatile to ensure that that the
@@ -88,25 +89,47 @@ ia64_atomic64_sub (__s64 i, atomic64_t *v)
return new;
}
-#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- for (;;) { \
- if (unlikely(c == (u))) \
- break; \
- old = atomic_cmpxchg((v), c, c + (a)); \
- if (likely(old == c)) \
- break; \
- c = old; \
- } \
- c != (u); \
-})
+#define atomic64_cmpxchg(v, old, new) \
+ (cmpxchg(&((v)->counter), old, new))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+ long c, old;
+ c = atomic64_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic64_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
#define atomic_add_return(i,v) \
({ \
int __ia64_aar_i = (i); \
diff --git a/include/asm-ia64/io.h b/include/asm-ia64/io.h
index 6311e16..eb17a86 100644
--- a/include/asm-ia64/io.h
+++ b/include/asm-ia64/io.h
@@ -421,11 +421,7 @@ __writeq (unsigned long val, volatile void __iomem *addr)
extern void __iomem * ioremap(unsigned long offset, unsigned long size);
extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
-
-static inline void
-iounmap (volatile void __iomem *addr)
-{
-}
+extern void iounmap (volatile void __iomem *addr);
/* Use normal IO mappings for DMI */
#define dmi_ioremap ioremap
diff --git a/include/asm-ia64/kdebug.h b/include/asm-ia64/kdebug.h
index aed7142..ba211e0 100644
--- a/include/asm-ia64/kdebug.h
+++ b/include/asm-ia64/kdebug.h
@@ -28,21 +28,8 @@
*/
#include <linux/notifier.h>
-struct pt_regs;
-
-struct die_args {
- struct pt_regs *regs;
- const char *str;
- long err;
- int trapnr;
- int signr;
-};
-
-extern int register_die_notifier(struct notifier_block *);
-extern int unregister_die_notifier(struct notifier_block *);
extern int register_page_fault_notifier(struct notifier_block *);
extern int unregister_page_fault_notifier(struct notifier_block *);
-extern struct atomic_notifier_head ia64die_chain;
enum die_val {
DIE_BREAK = 1,
@@ -74,18 +61,4 @@ enum die_val {
DIE_KDUMP_LEAVE,
};
-static inline int notify_die(enum die_val val, char *str, struct pt_regs *regs,
- long err, int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .str = str,
- .err = err,
- .trapnr = trap,
- .signr = sig
- };
-
- return atomic_notifier_call_chain(&ia64die_chain, val, &args);
-}
-
#endif
diff --git a/include/asm-ia64/kexec.h b/include/asm-ia64/kexec.h
index 41299dd..541be83 100644
--- a/include/asm-ia64/kexec.h
+++ b/include/asm-ia64/kexec.h
@@ -14,8 +14,6 @@
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_IA_64
-#define MAX_NOTE_BYTES 1024
-
#define kexec_flush_icache_page(page) do { \
unsigned long page_addr = (unsigned long)page_address(page); \
flush_icache_range(page_addr, page_addr + PAGE_SIZE); \
diff --git a/include/asm-ia64/kregs.h b/include/asm-ia64/kregs.h
index 221b5cb..7e55a58 100644
--- a/include/asm-ia64/kregs.h
+++ b/include/asm-ia64/kregs.h
@@ -29,8 +29,7 @@
*/
#define IA64_TR_KERNEL 0 /* itr0, dtr0: maps kernel image (code & data) */
#define IA64_TR_PALCODE 1 /* itr1: maps PALcode as required by EFI */
-#define IA64_TR_PERCPU_DATA 1 /* dtr1: percpu data */
-#define IA64_TR_CURRENT_STACK 2 /* dtr2: maps kernel's memory- & register-stacks */
+#define IA64_TR_CURRENT_STACK 1 /* dtr1: maps kernel's memory- & register-stacks */
/* Processor status register bits: */
#define IA64_PSR_BE_BIT 1
diff --git a/include/asm-ia64/local.h b/include/asm-ia64/local.h
index dc51909..c11c530 100644
--- a/include/asm-ia64/local.h
+++ b/include/asm-ia64/local.h
@@ -1,50 +1 @@
-#ifndef _ASM_IA64_LOCAL_H
-#define _ASM_IA64_LOCAL_H
-
-/*
- * Copyright (C) 2003 Hewlett-Packard Co
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/percpu.h>
-
-typedef struct {
- atomic64_t val;
-} local_t;
-
-#define LOCAL_INIT(i) ((local_t) { { (i) } })
-#define local_read(l) atomic64_read(&(l)->val)
-#define local_set(l, i) atomic64_set(&(l)->val, i)
-#define local_inc(l) atomic64_inc(&(l)->val)
-#define local_dec(l) atomic64_dec(&(l)->val)
-#define local_add(i, l) atomic64_add((i), &(l)->val)
-#define local_sub(i, l) atomic64_sub((i), &(l)->val)
-
-/* Non-atomic variants, i.e., preemption disabled and won't be touched in interrupt, etc. */
-
-#define __local_inc(l) (++(l)->val.counter)
-#define __local_dec(l) (--(l)->val.counter)
-#define __local_add(i,l) ((l)->val.counter += (i))
-#define __local_sub(i,l) ((l)->val.counter -= (i))
-
-/*
- * Use these for per-cpu local_t variables. Note they take a variable (eg. mystruct.foo),
- * not an address.
- */
-#define cpu_local_read(v) local_read(&__ia64_per_cpu_var(v))
-#define cpu_local_set(v, i) local_set(&__ia64_per_cpu_var(v), (i))
-#define cpu_local_inc(v) local_inc(&__ia64_per_cpu_var(v))
-#define cpu_local_dec(v) local_dec(&__ia64_per_cpu_var(v))
-#define cpu_local_add(i, v) local_add((i), &__ia64_per_cpu_var(v))
-#define cpu_local_sub(i, v) local_sub((i), &__ia64_per_cpu_var(v))
-
-/*
- * Non-atomic increments, i.e., preemption disabled and won't be touched in interrupt,
- * etc.
- */
-#define __cpu_local_inc(v) __local_inc(&__ia64_per_cpu_var(v))
-#define __cpu_local_dec(v) __local_dec(&__ia64_per_cpu_var(v))
-#define __cpu_local_add(i, v) __local_add((i), &__ia64_per_cpu_var(v))
-#define __cpu_local_sub(i, v) __local_sub((i), &__ia64_per_cpu_var(v))
-
-#endif /* _ASM_IA64_LOCAL_H */
+#include <asm-generic/local.h>
diff --git a/include/asm-ia64/pal.h b/include/asm-ia64/pal.h
index 67656ce..abfcb3a 100644
--- a/include/asm-ia64/pal.h
+++ b/include/asm-ia64/pal.h
@@ -89,6 +89,8 @@
#define PAL_GET_PSTATE_TYPE_AVGNORESET 2
#define PAL_GET_PSTATE_TYPE_INSTANT 3
+#define PAL_MC_ERROR_INJECT 276 /* Injects processor error or returns injection capabilities */
+
#ifndef __ASSEMBLY__
#include <linux/types.h>
@@ -1235,6 +1237,37 @@ ia64_pal_mc_error_info (u64 info_index, u64 type_index, u64 *size, u64 *error_in
return iprv.status;
}
+/* Injects the requested processor error or returns info on
+ * supported injection capabilities for current processor implementation
+ */
+static inline s64
+ia64_pal_mc_error_inject_phys (u64 err_type_info, u64 err_struct_info,
+ u64 err_data_buffer, u64 *capabilities, u64 *resources)
+{
+ struct ia64_pal_retval iprv;
+ PAL_CALL_PHYS_STK(iprv, PAL_MC_ERROR_INJECT, err_type_info,
+ err_struct_info, err_data_buffer);
+ if (capabilities)
+ *capabilities= iprv.v0;
+ if (resources)
+ *resources= iprv.v1;
+ return iprv.status;
+}
+
+static inline s64
+ia64_pal_mc_error_inject_virt (u64 err_type_info, u64 err_struct_info,
+ u64 err_data_buffer, u64 *capabilities, u64 *resources)
+{
+ struct ia64_pal_retval iprv;
+ PAL_CALL_STK(iprv, PAL_MC_ERROR_INJECT, err_type_info,
+ err_struct_info, err_data_buffer);
+ if (capabilities)
+ *capabilities= iprv.v0;
+ if (resources)
+ *resources= iprv.v1;
+ return iprv.status;
+}
+
/* Inform PALE_CHECK whether a machine check is expected so that PALE_CHECK willnot
* attempt to correct any expected machine checks.
*/
diff --git a/include/asm-ia64/patch.h b/include/asm-ia64/patch.h
index 4797f35..a715430 100644
--- a/include/asm-ia64/patch.h
+++ b/include/asm-ia64/patch.h
@@ -20,6 +20,7 @@ extern void ia64_patch_imm60 (u64 insn_addr, u64 val); /* patch "brl" w/ip-rel
extern void ia64_patch_mckinley_e9 (unsigned long start, unsigned long end);
extern void ia64_patch_vtop (unsigned long start, unsigned long end);
+extern void ia64_patch_phys_stack_reg(unsigned long val);
extern void ia64_patch_gate (void);
#endif /* _ASM_IA64_PATCH_H */
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index 5531827..670b706 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -485,10 +485,6 @@ extern void paging_init (void);
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/*
* ZERO_PAGE is a global shared page that is always zero: used
* for zero-mapped memory areas etc..
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
index 4f4ee1c..db81ba4 100644
--- a/include/asm-ia64/processor.h
+++ b/include/asm-ia64/processor.h
@@ -19,6 +19,7 @@
#include <asm/ptrace.h>
#include <asm/ustack.h>
+#define IA64_NUM_PHYS_STACK_REG 96
#define IA64_NUM_DBG_REGS 8
#define DEFAULT_MAP_BASE __IA64_UL_CONST(0x2000000000000000)
diff --git a/include/asm-ia64/sections.h b/include/asm-ia64/sections.h
index e9eb7f6..dc42a35 100644
--- a/include/asm-ia64/sections.h
+++ b/include/asm-ia64/sections.h
@@ -11,6 +11,7 @@
extern char __per_cpu_start[], __per_cpu_end[], __phys_per_cpu_start[];
extern char __start___vtop_patchlist[], __end___vtop_patchlist[];
extern char __start___mckinley_e9_bundles[], __end___mckinley_e9_bundles[];
+extern char __start___phys_stack_reg_patchlist[], __end___phys_stack_reg_patchlist[];
extern char __start_gate_section[];
extern char __start_gate_mckinley_e9_patchlist[], __end_gate_mckinley_e9_patchlist[];
extern char __start_gate_vtop_patchlist[], __end_gate_vtop_patchlist[];
diff --git a/include/asm-m32r/atomic.h b/include/asm-m32r/atomic.h
index f5a7d73..3a38ffe 100644
--- a/include/asm-m32r/atomic.h
+++ b/include/asm-m32r/atomic.h
@@ -253,14 +253,21 @@ static __inline__ int atomic_dec_return(atomic_t *v)
* Atomically adds @a to @v, so long as it was not @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
- c = old; \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t *addr)
diff --git a/include/asm-m32r/kdebug.h b/include/asm-m32r/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-m32r/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-m32r/pgtable.h b/include/asm-m32r/pgtable.h
index 1c15ba7..8b2a2f1 100644
--- a/include/asm-m32r/pgtable.h
+++ b/include/asm-m32r/pgtable.h
@@ -381,10 +381,6 @@ static inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
diff --git a/include/asm-m32r/system.h b/include/asm-m32r/system.h
index 99ee098..06cdece 100644
--- a/include/asm-m32r/system.h
+++ b/include/asm-m32r/system.h
@@ -122,8 +122,6 @@ static inline void local_irq_disable(void)
#define xchg(ptr,x) \
((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
-
#ifdef CONFIG_SMP
extern void __xchg_called_with_bad_pointer(void);
#endif
diff --git a/include/asm-m68k/atomic.h b/include/asm-m68k/atomic.h
index d5eed64..4915294 100644
--- a/include/asm-m68k/atomic.h
+++ b/include/asm-m68k/atomic.h
@@ -2,7 +2,7 @@
#define __ARCH_M68K_ATOMIC__
-#include <asm/system.h> /* local_irq_XXX() */
+#include <asm/system.h>
/*
* Atomic operations that C can't guarantee us. Useful for
@@ -170,20 +170,21 @@ static inline void atomic_set_mask(unsigned long mask, unsigned long *v)
__asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask));
}
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- for (;;) { \
- if (unlikely(c == (u))) \
- break; \
- old = atomic_cmpxchg((v), c, c + (a)); \
- if (likely(old == c)) \
- break; \
- c = old; \
- } \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
/* Atomic operations are already serializing */
diff --git a/include/asm-m68k/kdebug.h b/include/asm-m68k/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-m68k/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h
index f3aa053..555b87a 100644
--- a/include/asm-m68k/pgtable.h
+++ b/include/asm-m68k/pgtable.h
@@ -143,10 +143,6 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/* MMU-specific headers */
#ifdef CONFIG_SUN3
diff --git a/include/asm-m68k/system.h b/include/asm-m68k/system.h
index 243dd13..198878b 100644
--- a/include/asm-m68k/system.h
+++ b/include/asm-m68k/system.h
@@ -88,7 +88,6 @@ static inline int irqs_disabled(void)
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((volatile struct __xchg_dummy *)(x))
diff --git a/include/asm-m68knommu/atomic.h b/include/asm-m68knommu/atomic.h
index 6c4e4b6..d5632a3 100644
--- a/include/asm-m68knommu/atomic.h
+++ b/include/asm-m68knommu/atomic.h
@@ -1,7 +1,7 @@
#ifndef __ARCH_M68KNOMMU_ATOMIC__
#define __ARCH_M68KNOMMU_ATOMIC__
-#include <asm/system.h> /* local_irq_XXX() */
+#include <asm/system.h>
/*
* Atomic operations that C can't guarantee us. Useful for
@@ -131,14 +131,21 @@ static inline int atomic_sub_return(int i, atomic_t * v)
#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
- c = old; \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
#define atomic_dec_return(v) atomic_sub_return(1,(v))
diff --git a/include/asm-m68knommu/kdebug.h b/include/asm-m68knommu/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-m68knommu/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-m68knommu/pgtable.h b/include/asm-m68knommu/pgtable.h
index 549ad23..9dfbbc2 100644
--- a/include/asm-m68knommu/pgtable.h
+++ b/include/asm-m68knommu/pgtable.h
@@ -59,10 +59,6 @@ extern int is_in_rom(unsigned long);
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/*
* All 32bit addresses are effectively valid for vmalloc...
* Sort of meaningless for non-VM targets.
diff --git a/include/asm-m68knommu/system.h b/include/asm-m68knommu/system.h
index 2a81449..5e5ed18 100644
--- a/include/asm-m68knommu/system.h
+++ b/include/asm-m68knommu/system.h
@@ -120,7 +120,6 @@ asmlinkage void resume(void);
#endif
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((volatile struct __xchg_dummy *)(x))
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index 1ac50b6..62daa74 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -18,6 +18,7 @@
#include <asm/barrier.h>
#include <asm/cpu-features.h>
#include <asm/war.h>
+#include <asm/system.h>
typedef struct { volatile int counter; } atomic_t;
@@ -306,8 +307,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
return result;
}
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
/**
* atomic_add_unless - add unless the number is a given value
@@ -318,14 +319,20 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
* Atomically adds @a to @v, so long as it was not @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
- c = old; \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
#define atomic_dec_return(v) atomic_sub_return(1,(v))
@@ -681,6 +688,36 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
return result;
}
+#define atomic64_cmpxchg(v, o, n) \
+ (((__typeof__((v)->counter)))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), (new)))
+
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+ long c, old;
+ c = atomic64_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic64_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
#define atomic64_dec_return(v) atomic64_sub_return(1,(v))
#define atomic64_inc_return(v) atomic64_add_return(1,(v))
diff --git a/include/asm-mips/kdebug.h b/include/asm-mips/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-mips/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-mips/kexec.h b/include/asm-mips/kexec.h
index b25267e..cdbab43 100644
--- a/include/asm-mips/kexec.h
+++ b/include/asm-mips/kexec.h
@@ -21,8 +21,6 @@
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_MIPS
-#define MAX_NOTE_BYTES 1024
-
static inline void crash_setup_regs(struct pt_regs *newregs,
struct pt_regs *oldregs)
{
diff --git a/include/asm-mips/local.h b/include/asm-mips/local.h
index 9e2d43b..ed882c8 100644
--- a/include/asm-mips/local.h
+++ b/include/asm-mips/local.h
@@ -1,60 +1,288 @@
-#ifndef _ASM_LOCAL_H
-#define _ASM_LOCAL_H
+#ifndef _ARCH_MIPS_LOCAL_H
+#define _ARCH_MIPS_LOCAL_H
#include <linux/percpu.h>
+#include <linux/bitops.h>
#include <asm/atomic.h>
+#include <asm/war.h>
-#ifdef CONFIG_32BIT
+typedef struct
+{
+ atomic_long_t a;
+} local_t;
-typedef atomic_t local_t;
+#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
-#define LOCAL_INIT(i) ATOMIC_INIT(i)
-#define local_read(v) atomic_read(v)
-#define local_set(v,i) atomic_set(v,i)
+#define local_read(l) atomic_long_read(&(l)->a)
+#define local_set(l,i) atomic_long_set(&(l)->a, (i))
-#define local_inc(v) atomic_inc(v)
-#define local_dec(v) atomic_dec(v)
-#define local_add(i, v) atomic_add(i, v)
-#define local_sub(i, v) atomic_sub(i, v)
+#define local_add(i,l) atomic_long_add((i),(&(l)->a))
+#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
+#define local_inc(l) atomic_long_inc(&(l)->a)
+#define local_dec(l) atomic_long_dec(&(l)->a)
-#endif
+/*
+ * Same as above, but return the result value
+ */
+static __inline__ long local_add_return(long i, local_t * l)
+{
+ unsigned long result;
+
+ if (cpu_has_llsc && R10000_LLSC_WAR) {
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_add_return \n"
+ " addu %0, %1, %3 \n"
+ __SC "%0, %2 \n"
+ " beqzl %0, 1b \n"
+ " addu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else if (cpu_has_llsc) {
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_add_return \n"
+ " addu %0, %1, %3 \n"
+ __SC "%0, %2 \n"
+ " beqz %0, 1b \n"
+ " addu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else {
+ unsigned long flags;
-#ifdef CONFIG_64BIT
+ local_irq_save(flags);
+ result = l->a.counter;
+ result += i;
+ l->a.counter = result;
+ local_irq_restore(flags);
+ }
-typedef atomic64_t local_t;
+ return result;
+}
-#define LOCAL_INIT(i) ATOMIC64_INIT(i)
-#define local_read(v) atomic64_read(v)
-#define local_set(v,i) atomic64_set(v,i)
+static __inline__ long local_sub_return(long i, local_t * l)
+{
+ unsigned long result;
-#define local_inc(v) atomic64_inc(v)
-#define local_dec(v) atomic64_dec(v)
-#define local_add(i, v) atomic64_add(i, v)
-#define local_sub(i, v) atomic64_sub(i, v)
+ if (cpu_has_llsc && R10000_LLSC_WAR) {
+ unsigned long temp;
-#endif
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_sub_return \n"
+ " subu %0, %1, %3 \n"
+ __SC "%0, %2 \n"
+ " beqzl %0, 1b \n"
+ " subu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else if (cpu_has_llsc) {
+ unsigned long temp;
-#define __local_inc(v) ((v)->counter++)
-#define __local_dec(v) ((v)->counter--)
-#define __local_add(i,v) ((v)->counter+=(i))
-#define __local_sub(i,v) ((v)->counter-=(i))
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_sub_return \n"
+ " subu %0, %1, %3 \n"
+ __SC "%0, %2 \n"
+ " beqz %0, 1b \n"
+ " subu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ result = l->a.counter;
+ result -= i;
+ l->a.counter = result;
+ local_irq_restore(flags);
+ }
+
+ return result;
+}
/*
- * Use these for per-cpu local_t variables: on some archs they are
+ * local_sub_if_positive - conditionally subtract integer from atomic variable
+ * @i: integer value to subtract
+ * @l: pointer of type local_t
+ *
+ * Atomically test @l and subtract @i if @l is greater or equal than @i.
+ * The function returns the old value of @l minus @i.
+ */
+static __inline__ long local_sub_if_positive(long i, local_t * l)
+{
+ unsigned long result;
+
+ if (cpu_has_llsc && R10000_LLSC_WAR) {
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_sub_if_positive\n"
+ " dsubu %0, %1, %3 \n"
+ " bltz %0, 1f \n"
+ __SC "%0, %2 \n"
+ " .set noreorder \n"
+ " beqzl %0, 1b \n"
+ " dsubu %0, %1, %3 \n"
+ " .set reorder \n"
+ "1: \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else if (cpu_has_llsc) {
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_sub_if_positive\n"
+ " dsubu %0, %1, %3 \n"
+ " bltz %0, 1f \n"
+ __SC "%0, %2 \n"
+ " .set noreorder \n"
+ " beqz %0, 1b \n"
+ " dsubu %0, %1, %3 \n"
+ " .set reorder \n"
+ "1: \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ result = l->a.counter;
+ result -= i;
+ if (result >= 0)
+ l->a.counter = result;
+ local_irq_restore(flags);
+ }
+
+ return result;
+}
+
+#define local_cmpxchg(l, o, n) \
+ ((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
+#define local_xchg(l, n) (xchg_local(&((l)->a.counter),(n)))
+
+/**
+ * local_add_unless - add unless the number is a given value
+ * @l: pointer of type local_t
+ * @a: the amount to add to l...
+ * @u: ...unless l is equal to u.
+ *
+ * Atomically adds @a to @l, so long as it was not @u.
+ * Returns non-zero if @l was not @u, and zero otherwise.
+ */
+#define local_add_unless(l, a, u) \
+({ \
+ long c, old; \
+ c = local_read(l); \
+ while (c != (u) && (old = local_cmpxchg((l), c, c + (a))) != c) \
+ c = old; \
+ c != (u); \
+})
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_dec_return(l) local_sub_return(1,(l))
+#define local_inc_return(l) local_add_return(1,(l))
+
+/*
+ * local_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @l: pointer of type local_t
+ *
+ * Atomically subtracts @i from @l and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_sub_and_test(i,l) (local_sub_return((i), (l)) == 0)
+
+/*
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+/*
+ * local_dec_and_test - decrement by 1 and test
+ * @l: pointer of type local_t
+ *
+ * Atomically decrements @l by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+#define local_dec_and_test(l) (local_sub_return(1, (l)) == 0)
+
+/*
+ * local_dec_if_positive - decrement by 1 if old value positive
+ * @l: pointer of type local_t
+ */
+#define local_dec_if_positive(l) local_sub_if_positive(1, l)
+
+/*
+ * local_add_negative - add and test if negative
+ * @l: pointer of type local_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @l and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+#define local_add_negative(i,l) (local_add_return(i, (l)) < 0)
+
+/* Use these for per-cpu local_t variables: on some archs they are
* much more efficient than these naive implementations. Note they take
* a variable, not an address.
*/
-#define cpu_local_read(v) local_read(&__get_cpu_var(v))
-#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i))
-#define cpu_local_inc(v) local_inc(&__get_cpu_var(v))
-#define cpu_local_dec(v) local_dec(&__get_cpu_var(v))
-#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v))
-#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v))
+#define __local_inc(l) ((l)->a.counter++)
+#define __local_dec(l) ((l)->a.counter++)
+#define __local_add(i,l) ((l)->a.counter+=(i))
+#define __local_sub(i,l) ((l)->a.counter-=(i))
+
+/* Need to disable preemption for the cpu local counters otherwise we could
+ still access a variable of a previous CPU in a non atomic way. */
+#define cpu_local_wrap_v(l) \
+ ({ local_t res__; \
+ preempt_disable(); \
+ res__ = (l); \
+ preempt_enable(); \
+ res__; })
+#define cpu_local_wrap(l) \
+ ({ preempt_disable(); \
+ l; \
+ preempt_enable(); }) \
+
+#define cpu_local_read(l) cpu_local_wrap_v(local_read(&__get_cpu_var(l)))
+#define cpu_local_set(l, i) cpu_local_wrap(local_set(&__get_cpu_var(l), (i)))
+#define cpu_local_inc(l) cpu_local_wrap(local_inc(&__get_cpu_var(l)))
+#define cpu_local_dec(l) cpu_local_wrap(local_dec(&__get_cpu_var(l)))
+#define cpu_local_add(i, l) cpu_local_wrap(local_add((i), &__get_cpu_var(l)))
+#define cpu_local_sub(i, l) cpu_local_wrap(local_sub((i), &__get_cpu_var(l)))
-#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v))
-#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v))
-#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v))
-#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v))
+#define __cpu_local_inc(l) cpu_local_inc(l)
+#define __cpu_local_dec(l) cpu_local_dec(l)
+#define __cpu_local_add(i, l) cpu_local_add((i), (l))
+#define __cpu_local_sub(i, l) cpu_local_sub((i), (l))
-#endif /* _ASM_LOCAL_H */
+#endif /* _ARCH_MIPS_LOCAL_H */
diff --git a/include/asm-mips/mach-au1x00/au1550_spi.h b/include/asm-mips/mach-au1x00/au1550_spi.h
new file mode 100644
index 0000000..c2f0466
--- /dev/null
+++ b/include/asm-mips/mach-au1x00/au1550_spi.h
@@ -0,0 +1,16 @@
+/*
+ * au1550_spi.h - au1550 psc spi controller driver - platform data struct
+ */
+
+#ifndef _AU1550_SPI_H_
+#define _AU1550_SPI_H_
+
+struct au1550_spi_info {
+ s16 bus_num; /* defines which PSC and IRQ to use */
+ u32 mainclk_hz; /* main input clock frequency of PSC */
+ u16 num_chipselect; /* number of chipselects supported */
+ void (*activate_cs)(struct au1550_spi_info *spi, int cs, int polarity);
+ void (*deactivate_cs)(struct au1550_spi_info *spi, int cs, int polarity);
+};
+
+#endif
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
index 0d3295f..27d77d9 100644
--- a/include/asm-mips/pgtable.h
+++ b/include/asm-mips/pgtable.h
@@ -387,10 +387,6 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
remap_pfn_range(vma, vaddr, pfn, size, prot)
#endif
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#include <asm-generic/pgtable.h>
/*
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 2908870..30f23a2 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -201,7 +201,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
}
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
#define __HAVE_ARCH_CMPXCHG 1
@@ -262,6 +261,58 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
return retval;
}
+static inline unsigned long __cmpxchg_u32_local(volatile int * m,
+ unsigned long old, unsigned long new)
+{
+ __u32 retval;
+
+ if (cpu_has_llsc && R10000_LLSC_WAR) {
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noat \n"
+ " .set mips3 \n"
+ "1: ll %0, %2 # __cmpxchg_u32 \n"
+ " bne %0, %z3, 2f \n"
+ " .set mips0 \n"
+ " move $1, %z4 \n"
+ " .set mips3 \n"
+ " sc $1, %1 \n"
+ " beqzl $1, 1b \n"
+ "2: \n"
+ " .set pop \n"
+ : "=&r" (retval), "=R" (*m)
+ : "R" (*m), "Jr" (old), "Jr" (new)
+ : "memory");
+ } else if (cpu_has_llsc) {
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noat \n"
+ " .set mips3 \n"
+ "1: ll %0, %2 # __cmpxchg_u32 \n"
+ " bne %0, %z3, 2f \n"
+ " .set mips0 \n"
+ " move $1, %z4 \n"
+ " .set mips3 \n"
+ " sc $1, %1 \n"
+ " beqz $1, 1b \n"
+ "2: \n"
+ " .set pop \n"
+ : "=&r" (retval), "=R" (*m)
+ : "R" (*m), "Jr" (old), "Jr" (new)
+ : "memory");
+ } else {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ retval = *m;
+ if (retval == old)
+ *m = new;
+ local_irq_restore(flags); /* implies memory barrier */
+ }
+
+ return retval;
+}
+
#ifdef CONFIG_64BIT
static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
unsigned long new)
@@ -315,10 +366,62 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
return retval;
}
+
+static inline unsigned long __cmpxchg_u64_local(volatile int * m,
+ unsigned long old, unsigned long new)
+{
+ __u64 retval;
+
+ if (cpu_has_llsc && R10000_LLSC_WAR) {
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noat \n"
+ " .set mips3 \n"
+ "1: lld %0, %2 # __cmpxchg_u64 \n"
+ " bne %0, %z3, 2f \n"
+ " move $1, %z4 \n"
+ " scd $1, %1 \n"
+ " beqzl $1, 1b \n"
+ "2: \n"
+ " .set pop \n"
+ : "=&r" (retval), "=R" (*m)
+ : "R" (*m), "Jr" (old), "Jr" (new)
+ : "memory");
+ } else if (cpu_has_llsc) {
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noat \n"
+ " .set mips3 \n"
+ "1: lld %0, %2 # __cmpxchg_u64 \n"
+ " bne %0, %z3, 2f \n"
+ " move $1, %z4 \n"
+ " scd $1, %1 \n"
+ " beqz $1, 1b \n"
+ "2: \n"
+ " .set pop \n"
+ : "=&r" (retval), "=R" (*m)
+ : "R" (*m), "Jr" (old), "Jr" (new)
+ : "memory");
+ } else {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ retval = *m;
+ if (retval == old)
+ *m = new;
+ local_irq_restore(flags); /* implies memory barrier */
+ }
+
+ return retval;
+}
+
#else
extern unsigned long __cmpxchg_u64_unsupported_on_32bit_kernels(
volatile int * m, unsigned long old, unsigned long new);
#define __cmpxchg_u64 __cmpxchg_u64_unsupported_on_32bit_kernels
+extern unsigned long __cmpxchg_u64_local_unsupported_on_32bit_kernels(
+ volatile int * m, unsigned long old, unsigned long new);
+#define __cmpxchg_u64_local __cmpxchg_u64_local_unsupported_on_32bit_kernels
#endif
/* This function doesn't exist, so you'll get a linker error
@@ -338,7 +441,26 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
return old;
}
-#define cmpxchg(ptr,old,new) ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr))))
+static inline unsigned long __cmpxchg_local(volatile void * ptr,
+ unsigned long old, unsigned long new, int size)
+{
+ switch (size) {
+ case 4:
+ return __cmpxchg_u32_local(ptr, old, new);
+ case 8:
+ return __cmpxchg_u64_local(ptr, old, new);
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
+
+#define cmpxchg(ptr,old,new) \
+ ((__typeof__(*(ptr)))__cmpxchg((ptr), \
+ (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr))))
+
+#define cmpxchg_local(ptr,old,new) \
+ ((__typeof__(*(ptr)))__cmpxchg_local((ptr), \
+ (unsigned long)(old), (unsigned long)(new),sizeof(*(ptr))))
extern void set_handler (unsigned long offset, void *addr, unsigned long len);
extern void set_uncached_handler (unsigned long offset, void *addr, unsigned long len);
diff --git a/include/asm-parisc/atomic.h b/include/asm-parisc/atomic.h
index 7d57d34..e894ee3 100644
--- a/include/asm-parisc/atomic.h
+++ b/include/asm-parisc/atomic.h
@@ -163,7 +163,7 @@ static __inline__ int atomic_read(const atomic_t *v)
}
/* exported interface */
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
/**
@@ -175,14 +175,21 @@ static __inline__ int atomic_read(const atomic_t *v)
* Atomically adds @a to @v, so long as it was not @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
- c = old; \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
#define atomic_add(i,v) ((void)(__atomic_add_return( ((int)i),(v))))
@@ -270,6 +277,37 @@ atomic64_read(const atomic64_t *v)
#define atomic64_dec_and_test(v) (atomic64_dec_return(v) == 0)
#define atomic64_sub_and_test(i,v) (atomic64_sub_return((i),(v)) == 0)
+/* exported interface */
+#define atomic64_cmpxchg(v, o, n) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+ long c, old;
+ c = atomic64_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic64_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
#endif /* CONFIG_64BIT */
#include <asm-generic/atomic.h>
diff --git a/include/asm-parisc/kdebug.h b/include/asm-parisc/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-parisc/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-parisc/local.h b/include/asm-parisc/local.h
index d0f5509..c11c530 100644
--- a/include/asm-parisc/local.h
+++ b/include/asm-parisc/local.h
@@ -1,40 +1 @@
-#ifndef _ARCH_PARISC_LOCAL_H
-#define _ARCH_PARISC_LOCAL_H
-
-#include <linux/percpu.h>
-#include <asm/atomic.h>
-
-typedef atomic_long_t local_t;
-
-#define LOCAL_INIT(i) ATOMIC_LONG_INIT(i)
-#define local_read(v) atomic_long_read(v)
-#define local_set(v,i) atomic_long_set(v,i)
-
-#define local_inc(v) atomic_long_inc(v)
-#define local_dec(v) atomic_long_dec(v)
-#define local_add(i, v) atomic_long_add(i, v)
-#define local_sub(i, v) atomic_long_sub(i, v)
-
-#define __local_inc(v) ((v)->counter++)
-#define __local_dec(v) ((v)->counter--)
-#define __local_add(i,v) ((v)->counter+=(i))
-#define __local_sub(i,v) ((v)->counter-=(i))
-
-/* Use these for per-cpu local_t variables: on some archs they are
- * much more efficient than these naive implementations. Note they take
- * a variable, not an address.
- */
-#define cpu_local_read(v) local_read(&__get_cpu_var(v))
-#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i))
-
-#define cpu_local_inc(v) local_inc(&__get_cpu_var(v))
-#define cpu_local_dec(v) local_dec(&__get_cpu_var(v))
-#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v))
-#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v))
-
-#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v))
-#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v))
-#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v))
-#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v))
-
-#endif /* _ARCH_PARISC_LOCAL_H */
+#include <asm-generic/local.h>
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h
index d7e1b10..beb2adb 100644
--- a/include/asm-parisc/pgtable.h
+++ b/include/asm-parisc/pgtable.h
@@ -528,10 +528,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) | _PAGE_NO_CACHE)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/* We provide our own get_unmapped_area to provide cache coherency */
#define HAVE_ARCH_UNMAPPED_AREA
diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h
index 2ce4b6b..c44810b 100644
--- a/include/asm-powerpc/atomic.h
+++ b/include/asm-powerpc/atomic.h
@@ -11,6 +11,7 @@ typedef struct { volatile int counter; } atomic_t;
#include <linux/compiler.h>
#include <asm/synch.h>
#include <asm/asm-compat.h>
+#include <asm/system.h>
#define ATOMIC_INIT(i) { (i) }
@@ -165,8 +166,7 @@ static __inline__ int atomic_dec_return(atomic_t *v)
return t;
}
-#define atomic_cmpxchg(v, o, n) \
- ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
/**
@@ -414,8 +414,7 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
return t;
}
-#define atomic64_cmpxchg(v, o, n) \
- ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
/**
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h
index 8f757f6..8144a27 100644
--- a/include/asm-powerpc/bitops.h
+++ b/include/asm-powerpc/bitops.h
@@ -39,7 +39,6 @@
#ifdef __KERNEL__
#include <linux/compiler.h>
-#include <asm/atomic.h>
#include <asm/asm-compat.h>
#include <asm/synch.h>
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index b2e56b3..870967e 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -26,6 +26,7 @@
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
+#include <asm/machdep.h>
#include <asm/types.h>
#include <asm/bitops.h>
@@ -109,6 +110,19 @@ static inline void pci_iommu_init(void) { }
#endif
extern void alloc_dart_table(void);
+#if defined(CONFIG_PPC64) && defined(CONFIG_PM)
+static inline void iommu_save(void)
+{
+ if (ppc_md.iommu_save)
+ ppc_md.iommu_save();
+}
+
+static inline void iommu_restore(void)
+{
+ if (ppc_md.iommu_restore)
+ ppc_md.iommu_restore();
+}
+#endif
#endif /* __KERNEL__ */
#endif /* _ASM_IOMMU_H */
diff --git a/include/asm-powerpc/kdebug.h b/include/asm-powerpc/kdebug.h
index 532bfee..295f016 100644
--- a/include/asm-powerpc/kdebug.h
+++ b/include/asm-powerpc/kdebug.h
@@ -6,20 +6,19 @@
#include <linux/notifier.h>
-struct pt_regs;
-
-struct die_args {
- struct pt_regs *regs;
- const char *str;
- long err;
- int trapnr;
- int signr;
-};
-
-extern int register_die_notifier(struct notifier_block *);
-extern int unregister_die_notifier(struct notifier_block *);
-extern int register_page_fault_notifier(struct notifier_block *);
-extern int unregister_page_fault_notifier(struct notifier_block *);
+/*
+ * These are only here because kprobes.c wants them to implement a
+ * blatant layering violation. Will hopefully go away soon once all
+ * architectures are updated.
+ */
+static inline int register_page_fault_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
+static inline int unregister_page_fault_notifier(struct notifier_block *nb)
+{
+ return 0;
+}
extern struct atomic_notifier_head powerpc_die_chain;
/* Grossly misnamed. */
@@ -29,14 +28,7 @@ enum die_val {
DIE_DABR_MATCH,
DIE_BPT,
DIE_SSTEP,
- DIE_PAGE_FAULT,
};
-static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig)
-{
- struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig };
- return atomic_notifier_call_chain(&powerpc_die_chain, val, &args);
-}
-
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_KDEBUG_H */
diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h
index 11cbdf8..b6f817b 100644
--- a/include/asm-powerpc/kexec.h
+++ b/include/asm-powerpc/kexec.h
@@ -108,8 +108,6 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
struct pt_regs *oldregs) { }
#endif /* !__powerpc64 __ */
-#define MAX_NOTE_BYTES 1024
-
extern void kexec_smp_wait(void); /* get and clear naca physid, wait for
master to copy new code to 0 */
extern int crashing_cpu;
diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h
index f850ca7..b0e40ff 100644
--- a/include/asm-powerpc/kprobes.h
+++ b/include/asm-powerpc/kprobes.h
@@ -64,6 +64,12 @@ typedef unsigned int kprobe_opcode_t;
addr = *(kprobe_opcode_t **)addr; \
} else if (name[0] != '.') \
addr = *(kprobe_opcode_t **)addr; \
+ } else { \
+ char dot_name[KSYM_NAME_LEN+1]; \
+ dot_name[0] = '.'; \
+ dot_name[1] = '\0'; \
+ strncat(dot_name, name, KSYM_NAME_LEN); \
+ addr = (kprobe_opcode_t *)kallsyms_lookup_name(dot_name); \
} \
}
@@ -110,5 +116,6 @@ struct kprobe_ctlblk {
extern int kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data);
+extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_KPROBES_H */
diff --git a/include/asm-powerpc/local.h b/include/asm-powerpc/local.h
index c11c530..612d832 100644
--- a/include/asm-powerpc/local.h
+++ b/include/asm-powerpc/local.h
@@ -1 +1,200 @@
-#include <asm-generic/local.h>
+#ifndef _ARCH_POWERPC_LOCAL_H
+#define _ARCH_POWERPC_LOCAL_H
+
+#include <linux/percpu.h>
+#include <asm/atomic.h>
+
+typedef struct
+{
+ atomic_long_t a;
+} local_t;
+
+#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
+
+#define local_read(l) atomic_long_read(&(l)->a)
+#define local_set(l,i) atomic_long_set(&(l)->a, (i))
+
+#define local_add(i,l) atomic_long_add((i),(&(l)->a))
+#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
+#define local_inc(l) atomic_long_inc(&(l)->a)
+#define local_dec(l) atomic_long_dec(&(l)->a)
+
+static __inline__ long local_add_return(long a, local_t *l)
+{
+ long t;
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%2 # local_add_return\n\
+ add %0,%1,%0\n"
+ PPC405_ERR77(0,%2)
+ PPC_STLCX "%0,0,%2 \n\
+ bne- 1b"
+ : "=&r" (t)
+ : "r" (a), "r" (&(l->a.counter))
+ : "cc", "memory");
+
+ return t;
+}
+
+#define local_add_negative(a, l) (local_add_return((a), (l)) < 0)
+
+static __inline__ long local_sub_return(long a, local_t *l)
+{
+ long t;
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%2 # local_sub_return\n\
+ subf %0,%1,%0\n"
+ PPC405_ERR77(0,%2)
+ PPC_STLCX "%0,0,%2 \n\
+ bne- 1b"
+ : "=&r" (t)
+ : "r" (a), "r" (&(l->a.counter))
+ : "cc", "memory");
+
+ return t;
+}
+
+static __inline__ long local_inc_return(local_t *l)
+{
+ long t;
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%1 # local_inc_return\n\
+ addic %0,%0,1\n"
+ PPC405_ERR77(0,%1)
+ PPC_STLCX "%0,0,%1 \n\
+ bne- 1b"
+ : "=&r" (t)
+ : "r" (&(l->a.counter))
+ : "cc", "memory");
+
+ return t;
+}
+
+/*
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+static __inline__ long local_dec_return(local_t *l)
+{
+ long t;
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%1 # local_dec_return\n\
+ addic %0,%0,-1\n"
+ PPC405_ERR77(0,%1)
+ PPC_STLCX "%0,0,%1\n\
+ bne- 1b"
+ : "=&r" (t)
+ : "r" (&(l->a.counter))
+ : "cc", "memory");
+
+ return t;
+}
+
+#define local_cmpxchg(l, o, n) \
+ (cmpxchg_local(&((l)->a.counter), (o), (n)))
+#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
+
+/**
+ * local_add_unless - add unless the number is a given value
+ * @l: pointer of type local_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @l, so long as it was not @u.
+ * Returns non-zero if @l was not @u, and zero otherwise.
+ */
+static __inline__ int local_add_unless(local_t *l, long a, long u)
+{
+ long t;
+
+ __asm__ __volatile__ (
+"1:" PPC_LLARX "%0,0,%1 # local_add_unless\n\
+ cmpw 0,%0,%3 \n\
+ beq- 2f \n\
+ add %0,%2,%0 \n"
+ PPC405_ERR77(0,%2)
+ PPC_STLCX "%0,0,%1 \n\
+ bne- 1b \n"
+" subf %0,%2,%0 \n\
+2:"
+ : "=&r" (t)
+ : "r" (&(l->a.counter)), "r" (a), "r" (u)
+ : "cc", "memory");
+
+ return t != u;
+}
+
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_sub_and_test(a, l) (local_sub_return((a), (l)) == 0)
+#define local_dec_and_test(l) (local_dec_return((l)) == 0)
+
+/*
+ * Atomically test *l and decrement if it is greater than 0.
+ * The function returns the old value of *l minus 1.
+ */
+static __inline__ long local_dec_if_positive(local_t *l)
+{
+ long t;
+
+ __asm__ __volatile__(
+"1:" PPC_LLARX "%0,0,%1 # local_dec_if_positive\n\
+ cmpwi %0,1\n\
+ addi %0,%0,-1\n\
+ blt- 2f\n"
+ PPC405_ERR77(0,%1)
+ PPC_STLCX "%0,0,%1\n\
+ bne- 1b"
+ "\n\
+2:" : "=&b" (t)
+ : "r" (&(l->a.counter))
+ : "cc", "memory");
+
+ return t;
+}
+
+/* Use these for per-cpu local_t variables: on some archs they are
+ * much more efficient than these naive implementations. Note they take
+ * a variable, not an address.
+ */
+
+#define __local_inc(l) ((l)->a.counter++)
+#define __local_dec(l) ((l)->a.counter++)
+#define __local_add(i,l) ((l)->a.counter+=(i))
+#define __local_sub(i,l) ((l)->a.counter-=(i))
+
+/* Need to disable preemption for the cpu local counters otherwise we could
+ still access a variable of a previous CPU in a non atomic way. */
+#define cpu_local_wrap_v(l) \
+ ({ local_t res__; \
+ preempt_disable(); \
+ res__ = (l); \
+ preempt_enable(); \
+ res__; })
+#define cpu_local_wrap(l) \
+ ({ preempt_disable(); \
+ l; \
+ preempt_enable(); }) \
+
+#define cpu_local_read(l) cpu_local_wrap_v(local_read(&__get_cpu_var(l)))
+#define cpu_local_set(l, i) cpu_local_wrap(local_set(&__get_cpu_var(l), (i)))
+#define cpu_local_inc(l) cpu_local_wrap(local_inc(&__get_cpu_var(l)))
+#define cpu_local_dec(l) cpu_local_wrap(local_dec(&__get_cpu_var(l)))
+#define cpu_local_add(i, l) cpu_local_wrap(local_add((i), &__get_cpu_var(l)))
+#define cpu_local_sub(i, l) cpu_local_wrap(local_sub((i), &__get_cpu_var(l)))
+
+#define __cpu_local_inc(l) cpu_local_inc(l)
+#define __cpu_local_dec(l) cpu_local_dec(l)
+#define __cpu_local_add(i, l) cpu_local_add((i), (l))
+#define __cpu_local_sub(i, l) cpu_local_sub((i), (l))
+
+#endif /* _ARCH_POWERPC_LOCAL_H */
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index b204926..6cf1a83 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -91,6 +91,11 @@ struct machdep_calls {
void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size,
unsigned long flags);
void (*iounmap)(volatile void __iomem *token);
+
+#ifdef CONFIG_PM
+ void (*iommu_save)(void);
+ void (*iommu_restore)(void);
+#endif
#endif /* CONFIG_PPC64 */
int (*probe)(void);
@@ -115,6 +120,14 @@ struct machdep_calls {
/* To setup PHBs when using automatic OF platform driver for PCI */
int (*pci_setup_phb)(struct pci_controller *host);
+#ifdef CONFIG_PCI_MSI
+ int (*msi_check_device)(struct pci_dev* dev,
+ int nvec, int type);
+ int (*setup_msi_irqs)(struct pci_dev *dev,
+ int nvec, int type);
+ void (*teardown_msi_irqs)(struct pci_dev *dev);
+#endif
+
void (*restart)(char *cmd);
void (*power_off)(void);
void (*halt)(void);
@@ -240,14 +253,10 @@ struct machdep_calls {
*/
void (*machine_kexec)(struct kimage *image);
#endif /* CONFIG_KEXEC */
-
-#ifdef CONFIG_PCI_MSI
- int (*enable_msi)(struct pci_dev *pdev);
- void (*disable_msi)(struct pci_dev *pdev);
-#endif /* CONFIG_PCI_MSI */
};
extern void power4_idle(void);
+extern void power4_cpu_offline_powersave(void);
extern void ppc6xx_idle(void);
/*
diff --git a/include/asm-powerpc/mmu-44x.h b/include/asm-powerpc/mmu-44x.h
new file mode 100644
index 0000000..d5ce7a8
--- /dev/null
+++ b/include/asm-powerpc/mmu-44x.h
@@ -0,0 +1,78 @@
+#ifndef _ASM_POWERPC_MMU_44X_H_
+#define _ASM_POWERPC_MMU_44X_H_
+/*
+ * PPC440 support
+ */
+
+#define PPC44x_MMUCR_TID 0x000000ff
+#define PPC44x_MMUCR_STS 0x00010000
+
+#define PPC44x_TLB_PAGEID 0
+#define PPC44x_TLB_XLAT 1
+#define PPC44x_TLB_ATTRIB 2
+
+/* Page identification fields */
+#define PPC44x_TLB_EPN_MASK 0xfffffc00 /* Effective Page Number */
+#define PPC44x_TLB_VALID 0x00000200 /* Valid flag */
+#define PPC44x_TLB_TS 0x00000100 /* Translation address space */
+#define PPC44x_TLB_1K 0x00000000 /* Page sizes */
+#define PPC44x_TLB_4K 0x00000010
+#define PPC44x_TLB_16K 0x00000020
+#define PPC44x_TLB_64K 0x00000030
+#define PPC44x_TLB_256K 0x00000040
+#define PPC44x_TLB_1M 0x00000050
+#define PPC44x_TLB_16M 0x00000070
+#define PPC44x_TLB_256M 0x00000090
+
+/* Translation fields */
+#define PPC44x_TLB_RPN_MASK 0xfffffc00 /* Real Page Number */
+#define PPC44x_TLB_ERPN_MASK 0x0000000f
+
+/* Storage attribute and access control fields */
+#define PPC44x_TLB_ATTR_MASK 0x0000ff80
+#define PPC44x_TLB_U0 0x00008000 /* User 0 */
+#define PPC44x_TLB_U1 0x00004000 /* User 1 */
+#define PPC44x_TLB_U2 0x00002000 /* User 2 */
+#define PPC44x_TLB_U3 0x00001000 /* User 3 */
+#define PPC44x_TLB_W 0x00000800 /* Caching is write-through */
+#define PPC44x_TLB_I 0x00000400 /* Caching is inhibited */
+#define PPC44x_TLB_M 0x00000200 /* Memory is coherent */
+#define PPC44x_TLB_G 0x00000100 /* Memory is guarded */
+#define PPC44x_TLB_E 0x00000080 /* Memory is guarded */
+
+#define PPC44x_TLB_PERM_MASK 0x0000003f
+#define PPC44x_TLB_UX 0x00000020 /* User execution */
+#define PPC44x_TLB_UW 0x00000010 /* User write */
+#define PPC44x_TLB_UR 0x00000008 /* User read */
+#define PPC44x_TLB_SX 0x00000004 /* Super execution */
+#define PPC44x_TLB_SW 0x00000002 /* Super write */
+#define PPC44x_TLB_SR 0x00000001 /* Super read */
+
+/* Number of TLB entries */
+#define PPC44x_TLB_SIZE 64
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long long phys_addr_t;
+
+extern phys_addr_t fixup_bigphys_addr(phys_addr_t, phys_addr_t);
+
+typedef struct {
+ unsigned long id;
+ unsigned long vdso_base;
+} mm_context_t;
+
+#endif /* !__ASSEMBLY__ */
+
+#ifndef CONFIG_PPC_EARLY_DEBUG_44x
+#define PPC44x_EARLY_TLBS 1
+#else
+#define PPC44x_EARLY_TLBS 2
+#define PPC44x_EARLY_DEBUG_VIRTADDR (ASM_CONST(0xf0000000) \
+ | (ASM_CONST(CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW) & 0xffff))
+#endif
+
+/* Size of the TLBs used for pinning in lowmem */
+#define PPC_PIN_SIZE (1 << 28) /* 256M */
+
+#endif /* _ASM_POWERPC_MMU_44X_H_ */
diff --git a/include/asm-powerpc/mmu.h b/include/asm-powerpc/mmu.h
index 06b3e6d..fe510ff 100644
--- a/include/asm-powerpc/mmu.h
+++ b/include/asm-powerpc/mmu.h
@@ -5,9 +5,12 @@
#ifdef CONFIG_PPC64
/* 64-bit classic hash table MMU */
# include <asm/mmu-hash64.h>
+#elif defined(CONFIG_44x)
+/* 44x-style software loaded TLB */
+# include <asm/mmu-44x.h>
#else
-/* 32-bit. FIXME: split up the 32-bit MMU types, and revise for
- * arch/powerpc */
+/* Other 32-bit. FIXME: split up the other 32-bit MMU types, and
+ * revise for arch/powerpc */
# include <asm-ppc/mmu.h>
#endif
diff --git a/include/asm-powerpc/mpc52xx.h b/include/asm-powerpc/mpc52xx.h
index 7afd5bf..c4631f6 100644
--- a/include/asm-powerpc/mpc52xx.h
+++ b/include/asm-powerpc/mpc52xx.h
@@ -253,5 +253,16 @@ extern int __init mpc52xx_add_bridge(struct device_node *node);
#endif /* __ASSEMBLY__ */
+#ifdef CONFIG_PM
+struct mpc52xx_suspend {
+ void (*board_suspend_prepare)(void __iomem *mbar);
+ void (*board_resume_finish)(void __iomem *mbar);
+};
+
+extern struct mpc52xx_suspend mpc52xx_suspend;
+extern int __init mpc52xx_pm_init(void);
+extern int mpc52xx_set_wakeup_gpio(u8 pin, u8 level);
+#endif /* CONFIG_PM */
+
#endif /* __ASM_POWERPC_MPC52xx_H__ */
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
index e4d5fc5..2ffb06a 100644
--- a/include/asm-powerpc/mpic.h
+++ b/include/asm-powerpc/mpic.h
@@ -3,6 +3,7 @@
#ifdef __KERNEL__
#include <linux/irq.h>
+#include <linux/sysdev.h>
#include <asm/dcr.h>
/*
@@ -228,6 +229,14 @@ struct mpic_reg_bank {
#endif /* CONFIG_PPC_DCR */
};
+struct mpic_irq_save {
+ u32 vecprio,
+ dest;
+#ifdef CONFIG_MPIC_U3_HT_IRQS
+ u32 fixup_data;
+#endif
+};
+
/* The instance data of a given MPIC */
struct mpic
{
@@ -292,8 +301,19 @@ struct mpic
u32 *hw_set;
#endif
+#ifdef CONFIG_PCI_MSI
+ spinlock_t bitmap_lock;
+ unsigned long *hwirq_bitmap;
+#endif
+
/* link */
struct mpic *next;
+
+ struct sys_device sysdev;
+
+#ifdef CONFIG_PM
+ struct mpic_irq_save *save_data;
+#endif
};
/*
diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h
index 4f1aabe..e9af49e 100644
--- a/include/asm-powerpc/of_device.h
+++ b/include/asm-powerpc/of_device.h
@@ -32,6 +32,8 @@ extern int of_device_register(struct of_device *ofdev);
extern void of_device_unregister(struct of_device *ofdev);
extern void of_release_dev(struct device *dev);
+extern ssize_t of_device_get_modalias(struct of_device *ofdev,
+ char *str, ssize_t len);
extern int of_device_uevent(struct device *dev,
char **envp, int num_envp, char *buffer, int buffer_size);
diff --git a/include/asm-powerpc/page.h b/include/asm-powerpc/page.h
index b4d38b0..10c51f4 100644
--- a/include/asm-powerpc/page.h
+++ b/include/asm-powerpc/page.h
@@ -121,6 +121,7 @@ typedef struct { pte_t pte; } real_pte_t;
#endif
/* PMD level */
+#ifdef CONFIG_PPC64
typedef struct { unsigned long pmd; } pmd_t;
#define pmd_val(x) ((x).pmd)
#define __pmd(x) ((pmd_t) { (x) })
@@ -130,7 +131,8 @@ typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pud; } pud_t;
#define pud_val(x) ((x).pud)
#define __pud(x) ((pud_t) { (x) })
-#endif
+#endif /* !CONFIG_PPC_64K_PAGES */
+#endif /* CONFIG_PPC64 */
/* PGD level */
typedef struct { unsigned long pgd; } pgd_t;
@@ -159,15 +161,17 @@ typedef unsigned long real_pte_t;
#endif
+#ifdef CONFIG_PPC64
typedef unsigned long pmd_t;
#define pmd_val(x) (x)
#define __pmd(x) (x)
-#if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_64K_PAGES)
+#ifndef CONFIG_PPC_64K_PAGES
typedef unsigned long pud_t;
#define pud_val(x) (x)
#define __pud(x) (x)
-#endif
+#endif /* !CONFIG_PPC_64K_PAGES */
+#endif /* CONFIG_PPC64 */
typedef unsigned long pgd_t;
#define pgd_val(x) (x)
diff --git a/include/asm-powerpc/page_32.h b/include/asm-powerpc/page_32.h
index 07f6d3c..374d0db 100644
--- a/include/asm-powerpc/page_32.h
+++ b/include/asm-powerpc/page_32.h
@@ -14,11 +14,9 @@
#ifdef CONFIG_PTE_64BIT
typedef unsigned long long pte_basic_t;
#define PTE_SHIFT (PAGE_SHIFT - 3) /* 512 ptes per page */
-#define PTE_FMT "%16Lx"
#else
typedef unsigned long pte_basic_t;
#define PTE_SHIFT (PAGE_SHIFT - 2) /* 1024 ptes per page */
-#define PTE_FMT "%.8lx"
#endif
struct page;
diff --git a/include/asm-powerpc/parport.h b/include/asm-powerpc/parport.h
index b37b81e..414c50e 100644
--- a/include/asm-powerpc/parport.h
+++ b/include/asm-powerpc/parport.h
@@ -12,11 +12,6 @@
#include <asm/prom.h>
-extern struct parport *parport_pc_probe_port (unsigned long int base,
- unsigned long int base_hi,
- int irq, int dma,
- struct pci_dev *dev);
-
static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
{
struct device_node *np;
diff --git a/include/asm-powerpc/pgalloc-32.h b/include/asm-powerpc/pgalloc-32.h
new file mode 100644
index 0000000..e130743
--- /dev/null
+++ b/include/asm-powerpc/pgalloc-32.h
@@ -0,0 +1,41 @@
+#ifndef _ASM_POWERPC_PGALLOC_32_H
+#define _ASM_POWERPC_PGALLOC_32_H
+
+#include <linux/threads.h>
+
+extern void __bad_pte(pmd_t *pmd);
+
+extern pgd_t *pgd_alloc(struct mm_struct *mm);
+extern void pgd_free(pgd_t *pgd);
+
+/*
+ * We don't have any real pmd's, and this code never triggers because
+ * the pgd will always be present..
+ */
+/* #define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) */
+#define pmd_free(x) do { } while (0)
+#define __pmd_free_tlb(tlb,x) do { } while (0)
+/* #define pgd_populate(mm, pmd, pte) BUG() */
+
+#ifndef CONFIG_BOOKE
+#define pmd_populate_kernel(mm, pmd, pte) \
+ (pmd_val(*(pmd)) = __pa(pte) | _PMD_PRESENT)
+#define pmd_populate(mm, pmd, pte) \
+ (pmd_val(*(pmd)) = (page_to_pfn(pte) << PAGE_SHIFT) | _PMD_PRESENT)
+#else
+#define pmd_populate_kernel(mm, pmd, pte) \
+ (pmd_val(*(pmd)) = (unsigned long)pte | _PMD_PRESENT)
+#define pmd_populate(mm, pmd, pte) \
+ (pmd_val(*(pmd)) = (unsigned long)lowmem_page_address(pte) | _PMD_PRESENT)
+#endif
+
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
+extern struct page *pte_alloc_one(struct mm_struct *mm, unsigned long addr);
+extern void pte_free_kernel(pte_t *pte);
+extern void pte_free(struct page *pte);
+
+#define __pte_free_tlb(tlb, pte) pte_free((pte))
+
+#define check_pgt_cache() do { } while (0)
+
+#endif /* _ASM_POWERPC_PGALLOC_32_H */
diff --git a/include/asm-powerpc/pgalloc-64.h b/include/asm-powerpc/pgalloc-64.h
new file mode 100644
index 0000000..30b50cf
--- /dev/null
+++ b/include/asm-powerpc/pgalloc-64.h
@@ -0,0 +1,152 @@
+#ifndef _ASM_POWERPC_PGALLOC_64_H
+#define _ASM_POWERPC_PGALLOC_64_H
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/cpumask.h>
+#include <linux/percpu.h>
+
+extern struct kmem_cache *pgtable_cache[];
+
+#ifdef CONFIG_PPC_64K_PAGES
+#define PTE_CACHE_NUM 0
+#define PMD_CACHE_NUM 1
+#define PGD_CACHE_NUM 2
+#define HUGEPTE_CACHE_NUM 3
+#else
+#define PTE_CACHE_NUM 0
+#define PMD_CACHE_NUM 1
+#define PUD_CACHE_NUM 1
+#define PGD_CACHE_NUM 0
+#define HUGEPTE_CACHE_NUM 2
+#endif
+
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+ return kmem_cache_alloc(pgtable_cache[PGD_CACHE_NUM], GFP_KERNEL);
+}
+
+static inline void pgd_free(pgd_t *pgd)
+{
+ kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd);
+}
+
+#ifndef CONFIG_PPC_64K_PAGES
+
+#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, PUD)
+
+static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+ return kmem_cache_alloc(pgtable_cache[PUD_CACHE_NUM],
+ GFP_KERNEL|__GFP_REPEAT);
+}
+
+static inline void pud_free(pud_t *pud)
+{
+ kmem_cache_free(pgtable_cache[PUD_CACHE_NUM], pud);
+}
+
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+{
+ pud_set(pud, (unsigned long)pmd);
+}
+
+#define pmd_populate(mm, pmd, pte_page) \
+ pmd_populate_kernel(mm, pmd, page_address(pte_page))
+#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte))
+
+
+#else /* CONFIG_PPC_64K_PAGES */
+
+#define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd)
+
+static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
+ pte_t *pte)
+{
+ pmd_set(pmd, (unsigned long)pte);
+}
+
+#define pmd_populate(mm, pmd, pte_page) \
+ pmd_populate_kernel(mm, pmd, page_address(pte_page))
+
+#endif /* CONFIG_PPC_64K_PAGES */
+
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+ return kmem_cache_alloc(pgtable_cache[PMD_CACHE_NUM],
+ GFP_KERNEL|__GFP_REPEAT);
+}
+
+static inline void pmd_free(pmd_t *pmd)
+{
+ kmem_cache_free(pgtable_cache[PMD_CACHE_NUM], pmd);
+}
+
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+ unsigned long address)
+{
+ return kmem_cache_alloc(pgtable_cache[PTE_CACHE_NUM],
+ GFP_KERNEL|__GFP_REPEAT);
+}
+
+static inline struct page *pte_alloc_one(struct mm_struct *mm,
+ unsigned long address)
+{
+ return virt_to_page(pte_alloc_one_kernel(mm, address));
+}
+
+static inline void pte_free_kernel(pte_t *pte)
+{
+ kmem_cache_free(pgtable_cache[PTE_CACHE_NUM], pte);
+}
+
+static inline void pte_free(struct page *ptepage)
+{
+ pte_free_kernel(page_address(ptepage));
+}
+
+#define PGF_CACHENUM_MASK 0x3
+
+typedef struct pgtable_free {
+ unsigned long val;
+} pgtable_free_t;
+
+static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
+ unsigned long mask)
+{
+ BUG_ON(cachenum > PGF_CACHENUM_MASK);
+
+ return (pgtable_free_t){.val = ((unsigned long) p & ~mask) | cachenum};
+}
+
+static inline void pgtable_free(pgtable_free_t pgf)
+{
+ void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);
+ int cachenum = pgf.val & PGF_CACHENUM_MASK;
+
+ kmem_cache_free(pgtable_cache[cachenum], p);
+}
+
+extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
+
+#define __pte_free_tlb(tlb, ptepage) \
+ pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \
+ PTE_CACHE_NUM, PTE_TABLE_SIZE-1))
+#define __pmd_free_tlb(tlb, pmd) \
+ pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \
+ PMD_CACHE_NUM, PMD_TABLE_SIZE-1))
+#ifndef CONFIG_PPC_64K_PAGES
+#define __pud_free_tlb(tlb, pud) \
+ pgtable_free_tlb(tlb, pgtable_free_cache(pud, \
+ PUD_CACHE_NUM, PUD_TABLE_SIZE-1))
+#endif /* CONFIG_PPC_64K_PAGES */
+
+#define check_pgt_cache() do { } while (0)
+
+#endif /* _ASM_POWERPC_PGALLOC_64_H */
diff --git a/include/asm-powerpc/pgalloc.h b/include/asm-powerpc/pgalloc.h
index b0830db..b4505ed 100644
--- a/include/asm-powerpc/pgalloc.h
+++ b/include/asm-powerpc/pgalloc.h
@@ -2,159 +2,11 @@
#define _ASM_POWERPC_PGALLOC_H
#ifdef __KERNEL__
-#ifndef CONFIG_PPC64
-#include <asm-ppc/pgalloc.h>
+#ifdef CONFIG_PPC64
+#include <asm/pgalloc-64.h>
#else
-
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/cpumask.h>
-#include <linux/percpu.h>
-
-extern struct kmem_cache *pgtable_cache[];
-
-#ifdef CONFIG_PPC_64K_PAGES
-#define PTE_CACHE_NUM 0
-#define PMD_CACHE_NUM 1
-#define PGD_CACHE_NUM 2
-#define HUGEPTE_CACHE_NUM 3
-#else
-#define PTE_CACHE_NUM 0
-#define PMD_CACHE_NUM 1
-#define PUD_CACHE_NUM 1
-#define PGD_CACHE_NUM 0
-#define HUGEPTE_CACHE_NUM 2
+#include <asm/pgalloc-32.h>
#endif
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-static inline pgd_t *pgd_alloc(struct mm_struct *mm)
-{
- return kmem_cache_alloc(pgtable_cache[PGD_CACHE_NUM], GFP_KERNEL);
-}
-
-static inline void pgd_free(pgd_t *pgd)
-{
- kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd);
-}
-
-#ifndef CONFIG_PPC_64K_PAGES
-
-#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, PUD)
-
-static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
-{
- return kmem_cache_alloc(pgtable_cache[PUD_CACHE_NUM],
- GFP_KERNEL|__GFP_REPEAT);
-}
-
-static inline void pud_free(pud_t *pud)
-{
- kmem_cache_free(pgtable_cache[PUD_CACHE_NUM], pud);
-}
-
-static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
-{
- pud_set(pud, (unsigned long)pmd);
-}
-
-#define pmd_populate(mm, pmd, pte_page) \
- pmd_populate_kernel(mm, pmd, page_address(pte_page))
-#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte))
-
-
-#else /* CONFIG_PPC_64K_PAGES */
-
-#define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd)
-
-static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
- pte_t *pte)
-{
- pmd_set(pmd, (unsigned long)pte);
-}
-
-#define pmd_populate(mm, pmd, pte_page) \
- pmd_populate_kernel(mm, pmd, page_address(pte_page))
-
-#endif /* CONFIG_PPC_64K_PAGES */
-
-static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
-{
- return kmem_cache_alloc(pgtable_cache[PMD_CACHE_NUM],
- GFP_KERNEL|__GFP_REPEAT);
-}
-
-static inline void pmd_free(pmd_t *pmd)
-{
- kmem_cache_free(pgtable_cache[PMD_CACHE_NUM], pmd);
-}
-
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
- unsigned long address)
-{
- return kmem_cache_alloc(pgtable_cache[PTE_CACHE_NUM],
- GFP_KERNEL|__GFP_REPEAT);
-}
-
-static inline struct page *pte_alloc_one(struct mm_struct *mm,
- unsigned long address)
-{
- return virt_to_page(pte_alloc_one_kernel(mm, address));
-}
-
-static inline void pte_free_kernel(pte_t *pte)
-{
- kmem_cache_free(pgtable_cache[PTE_CACHE_NUM], pte);
-}
-
-static inline void pte_free(struct page *ptepage)
-{
- pte_free_kernel(page_address(ptepage));
-}
-
-#define PGF_CACHENUM_MASK 0x3
-
-typedef struct pgtable_free {
- unsigned long val;
-} pgtable_free_t;
-
-static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
- unsigned long mask)
-{
- BUG_ON(cachenum > PGF_CACHENUM_MASK);
-
- return (pgtable_free_t){.val = ((unsigned long) p & ~mask) | cachenum};
-}
-
-static inline void pgtable_free(pgtable_free_t pgf)
-{
- void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);
- int cachenum = pgf.val & PGF_CACHENUM_MASK;
-
- kmem_cache_free(pgtable_cache[cachenum], p);
-}
-
-extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
-
-#define __pte_free_tlb(tlb, ptepage) \
- pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \
- PTE_CACHE_NUM, PTE_TABLE_SIZE-1))
-#define __pmd_free_tlb(tlb, pmd) \
- pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \
- PMD_CACHE_NUM, PMD_TABLE_SIZE-1))
-#ifndef CONFIG_PPC_64K_PAGES
-#define __pud_free_tlb(tlb, pud) \
- pgtable_free_tlb(tlb, pgtable_free_cache(pud, \
- PUD_CACHE_NUM, PUD_TABLE_SIZE-1))
-#endif /* CONFIG_PPC_64K_PAGES */
-
-#define check_pgt_cache() do { } while (0)
-
-#endif /* CONFIG_PPC64 */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_PGALLOC_H */
diff --git a/include/asm-powerpc/pgtable-4k.h b/include/asm-powerpc/pgtable-4k.h
index a28fa8b..1744d6a 100644
--- a/include/asm-powerpc/pgtable-4k.h
+++ b/include/asm-powerpc/pgtable-4k.h
@@ -1,3 +1,5 @@
+#ifndef _ASM_POWERPC_PGTABLE_4K_H
+#define _ASM_POWERPC_PGTABLE_4K_H
/*
* Entries per page directory level. The PTE level must use a 64b record
* for each page table entry. The PMD and PGD level use a 32b record for
@@ -100,3 +102,4 @@
#define remap_4k_pfn(vma, addr, pfn, prot) \
remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot))
+#endif /* _ASM_POWERPC_PGTABLE_4K_H */
diff --git a/include/asm-powerpc/pgtable-64k.h b/include/asm-powerpc/pgtable-64k.h
index 5e84f07..16ef497 100644
--- a/include/asm-powerpc/pgtable-64k.h
+++ b/include/asm-powerpc/pgtable-64k.h
@@ -1,6 +1,5 @@
#ifndef _ASM_POWERPC_PGTABLE_64K_H
#define _ASM_POWERPC_PGTABLE_64K_H
-#ifdef __KERNEL__
#include <asm-generic/pgtable-nopud.h>
@@ -65,8 +64,6 @@
/* Bits to mask out from a PGD/PUD to get to the PMD page */
#define PUD_MASKED_BITS 0x1ff
-#ifndef __ASSEMBLY__
-
/* Manipulate "rpte" values */
#define __real_pte(e,p) ((real_pte_t) { \
(e), pte_val(*((p) + PTRS_PER_PTE)) })
@@ -98,6 +95,4 @@
remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \
__pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))
-#endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_PGTABLE_64K_H */
diff --git a/include/asm-powerpc/pgtable-ppc32.h b/include/asm-powerpc/pgtable-ppc32.h
new file mode 100644
index 0000000..09662a2
--- /dev/null
+++ b/include/asm-powerpc/pgtable-ppc32.h
@@ -0,0 +1,813 @@
+#ifndef _ASM_POWERPC_PGTABLE_PPC32_H
+#define _ASM_POWERPC_PGTABLE_PPC32_H
+
+#include <asm-generic/pgtable-nopmd.h>
+
+#ifndef __ASSEMBLY__
+#include <linux/sched.h>
+#include <linux/threads.h>
+#include <asm/processor.h> /* For TASK_SIZE */
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/io.h> /* For sub-arch specific PPC_PIN_SIZE */
+struct mm_struct;
+
+extern unsigned long va_to_phys(unsigned long address);
+extern pte_t *va_to_pte(unsigned long address);
+extern unsigned long ioremap_bot, ioremap_base;
+#endif /* __ASSEMBLY__ */
+
+/*
+ * The PowerPC MMU uses a hash table containing PTEs, together with
+ * a set of 16 segment registers (on 32-bit implementations), to define
+ * the virtual to physical address mapping.
+ *
+ * We use the hash table as an extended TLB, i.e. a cache of currently
+ * active mappings. We maintain a two-level page table tree, much
+ * like that used by the i386, for the sake of the Linux memory
+ * management code. Low-level assembler code in hashtable.S
+ * (procedure hash_page) is responsible for extracting ptes from the
+ * tree and putting them into the hash table when necessary, and
+ * updating the accessed and modified bits in the page table tree.
+ */
+
+/*
+ * The PowerPC MPC8xx uses a TLB with hardware assisted, software tablewalk.
+ * We also use the two level tables, but we can put the real bits in them
+ * needed for the TLB and tablewalk. These definitions require Mx_CTR.PPM = 0,
+ * Mx_CTR.PPCS = 0, and MD_CTR.TWAM = 1. The level 2 descriptor has
+ * additional page protection (when Mx_CTR.PPCS = 1) that allows TLB hit
+ * based upon user/super access. The TLB does not have accessed nor write
+ * protect. We assume that if the TLB get loaded with an entry it is
+ * accessed, and overload the changed bit for write protect. We use
+ * two bits in the software pte that are supposed to be set to zero in
+ * the TLB entry (24 and 25) for these indicators. Although the level 1
+ * descriptor contains the guarded and writethrough/copyback bits, we can
+ * set these at the page level since they get copied from the Mx_TWC
+ * register when the TLB entry is loaded. We will use bit 27 for guard, since
+ * that is where it exists in the MD_TWC, and bit 26 for writethrough.
+ * These will get masked from the level 2 descriptor at TLB load time, and
+ * copied to the MD_TWC before it gets loaded.
+ * Large page sizes added. We currently support two sizes, 4K and 8M.
+ * This also allows a TLB hander optimization because we can directly
+ * load the PMD into MD_TWC. The 8M pages are only used for kernel
+ * mapping of well known areas. The PMD (PGD) entries contain control
+ * flags in addition to the address, so care must be taken that the
+ * software no longer assumes these are only pointers.
+ */
+
+/*
+ * At present, all PowerPC 400-class processors share a similar TLB
+ * architecture. The instruction and data sides share a unified,
+ * 64-entry, fully-associative TLB which is maintained totally under
+ * software control. In addition, the instruction side has a
+ * hardware-managed, 4-entry, fully-associative TLB which serves as a
+ * first level to the shared TLB. These two TLBs are known as the UTLB
+ * and ITLB, respectively (see "mmu.h" for definitions).
+ */
+
+/*
+ * The normal case is that PTEs are 32-bits and we have a 1-page
+ * 1024-entry pgdir pointing to 1-page 1024-entry PTE pages. -- paulus
+ *
+ * For any >32-bit physical address platform, we can use the following
+ * two level page table layout where the pgdir is 8KB and the MS 13 bits
+ * are an index to the second level table. The combined pgdir/pmd first
+ * level has 2048 entries and the second level has 512 64-bit PTE entries.
+ * -Matt
+ */
+/* PGDIR_SHIFT determines what a top-level page table entry can map */
+#define PGDIR_SHIFT (PAGE_SHIFT + PTE_SHIFT)
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/*
+ * entries per page directory level: our page-table tree is two-level, so
+ * we don't really have any PMD directory.
+ */
+#define PTRS_PER_PTE (1 << PTE_SHIFT)
+#define PTRS_PER_PMD 1
+#define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT))
+
+#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
+#define FIRST_USER_ADDRESS 0
+
+#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
+#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
+
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %llx.\n", __FILE__, __LINE__, \
+ (unsigned long long)pte_val(e))
+#define pgd_ERROR(e) \
+ printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 64MB value just means that there will be a 64MB "hole" after the
+ * physical memory until the kernel virtual memory starts. That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ *
+ * We no longer map larger than phys RAM with the BATs so we don't have
+ * to worry about the VMALLOC_OFFSET causing problems. We do have to worry
+ * about clashes between our early calls to ioremap() that start growing down
+ * from ioremap_base being run into the VM area allocations (growing upwards
+ * from VMALLOC_START). For this reason we have ioremap_bot to check when
+ * we actually run into our mappings setup in the early boot with the VM
+ * system. This really does become a problem for machines with good amounts
+ * of RAM. -- Cort
+ */
+#define VMALLOC_OFFSET (0x1000000) /* 16M */
+#ifdef PPC_PIN_SIZE
+#define VMALLOC_START (((_ALIGN((long)high_memory, PPC_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+#else
+#define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+#endif
+#define VMALLOC_END ioremap_bot
+
+/*
+ * Bits in a linux-style PTE. These match the bits in the
+ * (hardware-defined) PowerPC PTE as closely as possible.
+ */
+
+#if defined(CONFIG_40x)
+
+/* There are several potential gotchas here. The 40x hardware TLBLO
+ field looks like this:
+
+ 0 1 2 3 4 ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ RPN..................... 0 0 EX WR ZSEL....... W I M G
+
+ Where possible we make the Linux PTE bits match up with this
+
+ - bits 20 and 21 must be cleared, because we use 4k pages (40x can
+ support down to 1k pages), this is done in the TLBMiss exception
+ handler.
+ - We use only zones 0 (for kernel pages) and 1 (for user pages)
+ of the 16 available. Bit 24-26 of the TLB are cleared in the TLB
+ miss handler. Bit 27 is PAGE_USER, thus selecting the correct
+ zone.
+ - PRESENT *must* be in the bottom two bits because swap cache
+ entries use the top 30 bits. Because 40x doesn't support SMP
+ anyway, M is irrelevant so we borrow it for PAGE_PRESENT. Bit 30
+ is cleared in the TLB miss handler before the TLB entry is loaded.
+ - All other bits of the PTE are loaded into TLBLO without
+ modification, leaving us only the bits 20, 21, 24, 25, 26, 30 for
+ software PTE bits. We actually use use bits 21, 24, 25, and
+ 30 respectively for the software bits: ACCESSED, DIRTY, RW, and
+ PRESENT.
+*/
+
+/* Definitions for 40x embedded chips. */
+#define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */
+#define _PAGE_FILE 0x001 /* when !present: nonlinear file mapping */
+#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */
+#define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */
+#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */
+#define _PAGE_USER 0x010 /* matches one of the zone permission bits */
+#define _PAGE_RW 0x040 /* software: Writes permitted */
+#define _PAGE_DIRTY 0x080 /* software: dirty page */
+#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */
+#define _PAGE_HWEXEC 0x200 /* hardware: EX permission */
+#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */
+
+#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */
+#define _PMD_BAD 0x802
+#define _PMD_SIZE 0x0e0 /* size field, != 0 for large-page PMD entry */
+#define _PMD_SIZE_4M 0x0c0
+#define _PMD_SIZE_16M 0x0e0
+#define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4))
+
+#elif defined(CONFIG_44x)
+/*
+ * Definitions for PPC440
+ *
+ * Because of the 3 word TLB entries to support 36-bit addressing,
+ * the attribute are difficult to map in such a fashion that they
+ * are easily loaded during exception processing. I decided to
+ * organize the entry so the ERPN is the only portion in the
+ * upper word of the PTE and the attribute bits below are packed
+ * in as sensibly as they can be in the area below a 4KB page size
+ * oriented RPN. This at least makes it easy to load the RPN and
+ * ERPN fields in the TLB. -Matt
+ *
+ * Note that these bits preclude future use of a page size
+ * less than 4KB.
+ *
+ *
+ * PPC 440 core has following TLB attribute fields;
+ *
+ * TLB1:
+ * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ * RPN................................. - - - - - - ERPN.......
+ *
+ * TLB2:
+ * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ * - - - - - - U0 U1 U2 U3 W I M G E - UX UW UR SX SW SR
+ *
+ * There are some constrains and options, to decide mapping software bits
+ * into TLB entry.
+ *
+ * - PRESENT *must* be in the bottom three bits because swap cache
+ * entries use the top 29 bits for TLB2.
+ *
+ * - FILE *must* be in the bottom three bits because swap cache
+ * entries use the top 29 bits for TLB2.
+ *
+ * - CACHE COHERENT bit (M) has no effect on PPC440 core, because it
+ * doesn't support SMP. So we can use this as software bit, like
+ * DIRTY.
+ *
+ * With the PPC 44x Linux implementation, the 0-11th LSBs of the PTE are used
+ * for memory protection related functions (see PTE structure in
+ * include/asm-ppc/mmu.h). The _PAGE_XXX definitions in this file map to the
+ * above bits. Note that the bit values are CPU specific, not architecture
+ * specific.
+ *
+ * The kernel PTE entry holds an arch-dependent swp_entry structure under
+ * certain situations. In other words, in such situations some portion of
+ * the PTE bits are used as a swp_entry. In the PPC implementation, the
+ * 3-24th LSB are shared with swp_entry, however the 0-2nd three LSB still
+ * hold protection values. That means the three protection bits are
+ * reserved for both PTE and SWAP entry at the most significant three
+ * LSBs.
+ *
+ * There are three protection bits available for SWAP entry:
+ * _PAGE_PRESENT
+ * _PAGE_FILE
+ * _PAGE_HASHPTE (if HW has)
+ *
+ * So those three bits have to be inside of 0-2nd LSB of PTE.
+ *
+ */
+
+#define _PAGE_PRESENT 0x00000001 /* S: PTE valid */
+#define _PAGE_RW 0x00000002 /* S: Write permission */
+#define _PAGE_FILE 0x00000004 /* S: nonlinear file mapping */
+#define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */
+#define _PAGE_HWWRITE 0x00000010 /* H: Dirty & RW */
+#define _PAGE_HWEXEC 0x00000020 /* H: Execute permission */
+#define _PAGE_USER 0x00000040 /* S: User page */
+#define _PAGE_ENDIAN 0x00000080 /* H: E bit */
+#define _PAGE_GUARDED 0x00000100 /* H: G bit */
+#define _PAGE_DIRTY 0x00000200 /* S: Page dirty */
+#define _PAGE_NO_CACHE 0x00000400 /* H: I bit */
+#define _PAGE_WRITETHRU 0x00000800 /* H: W bit */
+
+/* TODO: Add large page lowmem mapping support */
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+
+/* ERPN in a PTE never gets cleared, ignore it */
+#define _PTE_NONE_MASK 0xffffffff00000000ULL
+
+#elif defined(CONFIG_FSL_BOOKE)
+/*
+ MMU Assist Register 3:
+
+ 32 33 34 35 36 ... 50 51 52 53 54 55 56 57 58 59 60 61 62 63
+ RPN...................... 0 0 U0 U1 U2 U3 UX SX UW SW UR SR
+
+ - PRESENT *must* be in the bottom three bits because swap cache
+ entries use the top 29 bits.
+
+ - FILE *must* be in the bottom three bits because swap cache
+ entries use the top 29 bits.
+*/
+
+/* Definitions for FSL Book-E Cores */
+#define _PAGE_PRESENT 0x00001 /* S: PTE contains a translation */
+#define _PAGE_USER 0x00002 /* S: User page (maps to UR) */
+#define _PAGE_FILE 0x00002 /* S: when !present: nonlinear file mapping */
+#define _PAGE_ACCESSED 0x00004 /* S: Page referenced */
+#define _PAGE_HWWRITE 0x00008 /* H: Dirty & RW, set in exception */
+#define _PAGE_RW 0x00010 /* S: Write permission */
+#define _PAGE_HWEXEC 0x00020 /* H: UX permission */
+
+#define _PAGE_ENDIAN 0x00040 /* H: E bit */
+#define _PAGE_GUARDED 0x00080 /* H: G bit */
+#define _PAGE_COHERENT 0x00100 /* H: M bit */
+#define _PAGE_NO_CACHE 0x00200 /* H: I bit */
+#define _PAGE_WRITETHRU 0x00400 /* H: W bit */
+
+#ifdef CONFIG_PTE_64BIT
+#define _PAGE_DIRTY 0x08000 /* S: Page dirty */
+
+/* ERPN in a PTE never gets cleared, ignore it */
+#define _PTE_NONE_MASK 0xffffffffffff0000ULL
+#else
+#define _PAGE_DIRTY 0x00800 /* S: Page dirty */
+#endif
+
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+
+#elif defined(CONFIG_8xx)
+/* Definitions for 8xx embedded chips. */
+#define _PAGE_PRESENT 0x0001 /* Page is valid */
+#define _PAGE_FILE 0x0002 /* when !present: nonlinear file mapping */
+#define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */
+#define _PAGE_SHARED 0x0004 /* No ASID (context) compare */
+
+/* These five software bits must be masked out when the entry is loaded
+ * into the TLB.
+ */
+#define _PAGE_EXEC 0x0008 /* software: i-cache coherency required */
+#define _PAGE_GUARDED 0x0010 /* software: guarded access */
+#define _PAGE_DIRTY 0x0020 /* software: page changed */
+#define _PAGE_RW 0x0040 /* software: user write access allowed */
+#define _PAGE_ACCESSED 0x0080 /* software: page referenced */
+
+/* Setting any bits in the nibble with the follow two controls will
+ * require a TLB exception handler change. It is assumed unused bits
+ * are always zero.
+ */
+#define _PAGE_HWWRITE 0x0100 /* h/w write enable: never set in Linux PTE */
+#define _PAGE_USER 0x0800 /* One of the PP bits, the other is USER&~RW */
+
+#define _PMD_PRESENT 0x0001
+#define _PMD_BAD 0x0ff0
+#define _PMD_PAGE_MASK 0x000c
+#define _PMD_PAGE_8M 0x000c
+
+/*
+ * The 8xx TLB miss handler allegedly sets _PAGE_ACCESSED in the PTE
+ * for an address even if _PAGE_PRESENT is not set, as a performance
+ * optimization. This is a bug if you ever want to use swap unless
+ * _PAGE_ACCESSED is 2, which it isn't, or unless you have 8xx-specific
+ * definitions for __swp_entry etc. below, which would be gross.
+ * -- paulus
+ */
+#define _PTE_NONE_MASK _PAGE_ACCESSED
+
+#else /* CONFIG_6xx */
+/* Definitions for 60x, 740/750, etc. */
+#define _PAGE_PRESENT 0x001 /* software: pte contains a translation */
+#define _PAGE_HASHPTE 0x002 /* hash_page has made an HPTE for this pte */
+#define _PAGE_FILE 0x004 /* when !present: nonlinear file mapping */
+#define _PAGE_USER 0x004 /* usermode access allowed */
+#define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */
+#define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */
+#define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */
+#define _PAGE_WRITETHRU 0x040 /* W: cache write-through */
+#define _PAGE_DIRTY 0x080 /* C: page changed */
+#define _PAGE_ACCESSED 0x100 /* R: page referenced */
+#define _PAGE_EXEC 0x200 /* software: i-cache coherency required */
+#define _PAGE_RW 0x400 /* software: user write access allowed */
+
+#define _PTE_NONE_MASK _PAGE_HASHPTE
+
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+#endif
+
+/*
+ * Some bits are only used on some cpu families...
+ */
+#ifndef _PAGE_HASHPTE
+#define _PAGE_HASHPTE 0
+#endif
+#ifndef _PTE_NONE_MASK
+#define _PTE_NONE_MASK 0
+#endif
+#ifndef _PAGE_SHARED
+#define _PAGE_SHARED 0
+#endif
+#ifndef _PAGE_HWWRITE
+#define _PAGE_HWWRITE 0
+#endif
+#ifndef _PAGE_HWEXEC
+#define _PAGE_HWEXEC 0
+#endif
+#ifndef _PAGE_EXEC
+#define _PAGE_EXEC 0
+#endif
+#ifndef _PMD_PRESENT_MASK
+#define _PMD_PRESENT_MASK _PMD_PRESENT
+#endif
+#ifndef _PMD_SIZE
+#define _PMD_SIZE 0
+#define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE()
+#endif
+
+#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+
+/*
+ * Note: the _PAGE_COHERENT bit automatically gets set in the hardware
+ * PTE if CONFIG_SMP is defined (hash_page does this); there is no need
+ * to have it in the Linux PTE, and in fact the bit could be reused for
+ * another purpose. -- paulus.
+ */
+
+#ifdef CONFIG_44x
+#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_GUARDED)
+#else
+#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED)
+#endif
+#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE)
+#define _PAGE_KERNEL (_PAGE_BASE | _PAGE_SHARED | _PAGE_WRENABLE)
+
+#ifdef CONFIG_PPC_STD_MMU
+/* On standard PPC MMU, no user access implies kernel read/write access,
+ * so to write-protect kernel memory we must turn on user access */
+#define _PAGE_KERNEL_RO (_PAGE_BASE | _PAGE_SHARED | _PAGE_USER)
+#else
+#define _PAGE_KERNEL_RO (_PAGE_BASE | _PAGE_SHARED)
+#endif
+
+#define _PAGE_IO (_PAGE_KERNEL | _PAGE_NO_CACHE | _PAGE_GUARDED)
+#define _PAGE_RAM (_PAGE_KERNEL | _PAGE_HWEXEC)
+
+#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH)
+/* We want the debuggers to be able to set breakpoints anywhere, so
+ * don't write protect the kernel text */
+#define _PAGE_RAM_TEXT _PAGE_RAM
+#else
+#define _PAGE_RAM_TEXT (_PAGE_KERNEL_RO | _PAGE_HWEXEC)
+#endif
+
+#define PAGE_NONE __pgprot(_PAGE_BASE)
+#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
+#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
+#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+
+#define PAGE_KERNEL __pgprot(_PAGE_RAM)
+#define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
+
+/*
+ * The PowerPC can only do execute protection on a segment (256MB) basis,
+ * not on a page basis. So we consider execute permission the same as read.
+ * Also, write permissions imply read permissions.
+ * This is the closest we can get..
+ */
+#define __P000 PAGE_NONE
+#define __P001 PAGE_READONLY_X
+#define __P010 PAGE_COPY
+#define __P011 PAGE_COPY_X
+#define __P100 PAGE_READONLY
+#define __P101 PAGE_READONLY_X
+#define __P110 PAGE_COPY
+#define __P111 PAGE_COPY_X
+
+#define __S000 PAGE_NONE
+#define __S001 PAGE_READONLY_X
+#define __S010 PAGE_SHARED
+#define __S011 PAGE_SHARED_X
+#define __S100 PAGE_READONLY
+#define __S101 PAGE_READONLY_X
+#define __S110 PAGE_SHARED
+#define __S111 PAGE_SHARED_X
+
+#ifndef __ASSEMBLY__
+/* Make sure we get a link error if PMD_PAGE_SIZE is ever called on a
+ * kernel without large page PMD support */
+extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
+
+/*
+ * Conversions between PTE values and page frame numbers.
+ */
+
+/* in some case we want to additionaly adjust where the pfn is in the pte to
+ * allow room for more flags */
+#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT)
+#define PFN_SHIFT_OFFSET (PAGE_SHIFT + 8)
+#else
+#define PFN_SHIFT_OFFSET (PAGE_SHIFT)
+#endif
+
+#define pte_pfn(x) (pte_val(x) >> PFN_SHIFT_OFFSET)
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+
+#define pfn_pte(pfn, prot) __pte(((pte_basic_t)(pfn) << PFN_SHIFT_OFFSET) |\
+ pgprot_val(prot))
+#define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot)
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern unsigned long empty_zero_page[1024];
+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+
+#endif /* __ASSEMBLY__ */
+
+#define pte_none(pte) ((pte_val(pte) & ~_PTE_NONE_MASK) == 0)
+#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
+#define pte_clear(mm,addr,ptep) do { set_pte_at((mm), (addr), (ptep), __pte(0)); } while (0)
+
+#define pmd_none(pmd) (!pmd_val(pmd))
+#define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD)
+#define pmd_present(pmd) (pmd_val(pmd) & _PMD_PRESENT_MASK)
+#define pmd_clear(pmdp) do { pmd_val(*(pmdp)) = 0; } while (0)
+
+#ifndef __ASSEMBLY__
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
+static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
+static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_EXEC; }
+static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
+
+static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; }
+static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; }
+
+static inline pte_t pte_rdprotect(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_USER; return pte; }
+static inline pte_t pte_wrprotect(pte_t pte) {
+ pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); return pte; }
+static inline pte_t pte_exprotect(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_EXEC; return pte; }
+static inline pte_t pte_mkclean(pte_t pte) {
+ pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; }
+static inline pte_t pte_mkold(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+
+static inline pte_t pte_mkread(pte_t pte) {
+ pte_val(pte) |= _PAGE_USER; return pte; }
+static inline pte_t pte_mkexec(pte_t pte) {
+ pte_val(pte) |= _PAGE_USER | _PAGE_EXEC; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte) {
+ pte_val(pte) |= _PAGE_RW; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte) {
+ pte_val(pte) |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte) {
+ pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
+ return pte;
+}
+
+/*
+ * When flushing the tlb entry for a page, we also need to flush the hash
+ * table entry. flush_hash_pages is assembler (for speed) in hashtable.S.
+ */
+extern int flush_hash_pages(unsigned context, unsigned long va,
+ unsigned long pmdval, int count);
+
+/* Add an HPTE to the hash table */
+extern void add_hash_page(unsigned context, unsigned long va,
+ unsigned long pmdval);
+
+/*
+ * Atomic PTE updates.
+ *
+ * pte_update clears and sets bit atomically, and returns
+ * the old pte value. In the 64-bit PTE case we lock around the
+ * low PTE word since we expect ALL flag bits to be there
+ */
+#ifndef CONFIG_PTE_64BIT
+static inline unsigned long pte_update(pte_t *p, unsigned long clr,
+ unsigned long set)
+{
+ unsigned long old, tmp;
+
+ __asm__ __volatile__("\
+1: lwarx %0,0,%3\n\
+ andc %1,%0,%4\n\
+ or %1,%1,%5\n"
+ PPC405_ERR77(0,%3)
+" stwcx. %1,0,%3\n\
+ bne- 1b"
+ : "=&r" (old), "=&r" (tmp), "=m" (*p)
+ : "r" (p), "r" (clr), "r" (set), "m" (*p)
+ : "cc" );
+ return old;
+}
+#else
+static inline unsigned long long pte_update(pte_t *p, unsigned long clr,
+ unsigned long set)
+{
+ unsigned long long old;
+ unsigned long tmp;
+
+ __asm__ __volatile__("\
+1: lwarx %L0,0,%4\n\
+ lwzx %0,0,%3\n\
+ andc %1,%L0,%5\n\
+ or %1,%1,%6\n"
+ PPC405_ERR77(0,%3)
+" stwcx. %1,0,%4\n\
+ bne- 1b"
+ : "=&r" (old), "=&r" (tmp), "=m" (*p)
+ : "r" (p), "r" ((unsigned long)(p) + 4), "r" (clr), "r" (set), "m" (*p)
+ : "cc" );
+ return old;
+}
+#endif
+
+/*
+ * set_pte stores a linux PTE into the linux page table.
+ * On machines which use an MMU hash table we avoid changing the
+ * _PAGE_HASHPTE bit.
+ */
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte)
+{
+#if _PAGE_HASHPTE != 0
+ pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE);
+#else
+ *ptep = pte;
+#endif
+}
+
+/*
+ * 2.6 calles this without flushing the TLB entry, this is wrong
+ * for our hash-based implementation, we fix that up here
+ */
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+static inline int __ptep_test_and_clear_young(unsigned int context, unsigned long addr, pte_t *ptep)
+{
+ unsigned long old;
+ old = pte_update(ptep, _PAGE_ACCESSED, 0);
+#if _PAGE_HASHPTE != 0
+ if (old & _PAGE_HASHPTE) {
+ unsigned long ptephys = __pa(ptep) & PAGE_MASK;
+ flush_hash_pages(context, addr, ptephys, 1);
+ }
+#endif
+ return (old & _PAGE_ACCESSED) != 0;
+}
+#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
+ __ptep_test_and_clear_young((__vma)->vm_mm->context.id, __addr, __ptep)
+
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
+static inline int ptep_test_and_clear_dirty(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+ return (pte_update(ptep, (_PAGE_DIRTY | _PAGE_HWWRITE), 0) & _PAGE_DIRTY) != 0;
+}
+
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+ return __pte(pte_update(ptep, ~_PAGE_HASHPTE, 0));
+}
+
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+ pte_update(ptep, (_PAGE_RW | _PAGE_HWWRITE), 0);
+}
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
+{
+ unsigned long bits = pte_val(entry) &
+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW);
+ pte_update(ptep, 0, bits);
+}
+
+#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
+ do { \
+ __ptep_set_access_flags(__ptep, __entry, __dirty); \
+ flush_tlb_page_nohash(__vma, __address); \
+ } while(0)
+
+/*
+ * Macro to mark a page protection value as "uncacheable".
+ */
+#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
+
+struct file;
+extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot);
+#define __HAVE_PHYS_MEM_ACCESS_PROT
+
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)
+
+/*
+ * Note that on Book E processors, the pmd contains the kernel virtual
+ * (lowmem) address of the pte page. The physical address is less useful
+ * because everything runs with translation enabled (even the TLB miss
+ * handler). On everything else the pmd contains the physical address
+ * of the pte page. -- paulus
+ */
+#ifndef CONFIG_BOOKE
+#define pmd_page_vaddr(pmd) \
+ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+#define pmd_page(pmd) \
+ (mem_map + (pmd_val(pmd) >> PAGE_SHIFT))
+#else
+#define pmd_page_vaddr(pmd) \
+ ((unsigned long) (pmd_val(pmd) & PAGE_MASK))
+#define pmd_page(pmd) \
+ (mem_map + (__pa(pmd_val(pmd)) >> PAGE_SHIFT))
+#endif
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/* to find an entry in a page-table-directory */
+#define pgd_index(address) ((address) >> PGDIR_SHIFT)
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+
+/* Find an entry in the third-level page table.. */
+#define pte_index(address) \
+ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset_kernel(dir, addr) \
+ ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(addr))
+#define pte_offset_map(dir, addr) \
+ ((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE0) + pte_index(addr))
+#define pte_offset_map_nested(dir, addr) \
+ ((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE1) + pte_index(addr))
+
+#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
+#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1)
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+extern void paging_init(void);
+
+/*
+ * Encode and decode a swap entry.
+ * Note that the bits we use in a PTE for representing a swap entry
+ * must not include the _PAGE_PRESENT bit, the _PAGE_FILE bit, or the
+ *_PAGE_HASHPTE bit (if used). -- paulus
+ */
+#define __swp_type(entry) ((entry).val & 0x1f)
+#define __swp_offset(entry) ((entry).val >> 5)
+#define __swp_entry(type, offset) ((swp_entry_t) { (type) | ((offset) << 5) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 3 })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val << 3 })
+
+/* Encode and decode a nonlinear file mapping entry */
+#define PTE_FILE_MAX_BITS 29
+#define pte_to_pgoff(pte) (pte_val(pte) >> 3)
+#define pgoff_to_pte(off) ((pte_t) { ((off) << 3) | _PAGE_FILE })
+
+/* CONFIG_APUS */
+/* For virtual address to physical address conversion */
+extern void cache_clear(__u32 addr, int length);
+extern void cache_push(__u32 addr, int length);
+extern int mm_end_of_chunk (unsigned long addr, int len);
+extern unsigned long iopa(unsigned long addr);
+extern unsigned long mm_ptov(unsigned long addr) __attribute_const__;
+
+/* Values for nocacheflag and cmode */
+/* These are not used by the APUS kernel_map, but prevents
+ compilation errors. */
+#define KERNELMAP_FULL_CACHING 0
+#define KERNELMAP_NOCACHE_SER 1
+#define KERNELMAP_NOCACHE_NONSER 2
+#define KERNELMAP_NO_COPYBACK 3
+
+/*
+ * Map some physical address range into the kernel address space.
+ */
+extern unsigned long kernel_map(unsigned long paddr, unsigned long size,
+ int nocacheflag, unsigned long *memavailp );
+
+/*
+ * Set cache mode of (kernel space) address range.
+ */
+extern void kernel_set_cachemode (unsigned long address, unsigned long size,
+ unsigned int cmode);
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define kern_addr_valid(addr) (1)
+
+#ifdef CONFIG_PHYS_64BIT
+extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
+ unsigned long paddr, unsigned long size, pgprot_t prot);
+
+static inline int io_remap_pfn_range(struct vm_area_struct *vma,
+ unsigned long vaddr,
+ unsigned long pfn,
+ unsigned long size,
+ pgprot_t prot)
+{
+ phys_addr_t paddr64 = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
+ return remap_pfn_range(vma, vaddr, paddr64 >> PAGE_SHIFT, size, prot);
+}
+#else
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+#endif
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init() do { } while (0)
+
+extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep,
+ pmd_t **pmdp);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_POWERPC_PGTABLE_PPC32_H */
diff --git a/include/asm-powerpc/pgtable-ppc64.h b/include/asm-powerpc/pgtable-ppc64.h
new file mode 100644
index 0000000..704c4e6
--- /dev/null
+++ b/include/asm-powerpc/pgtable-ppc64.h
@@ -0,0 +1,492 @@
+#ifndef _ASM_POWERPC_PGTABLE_PPC64_H_
+#define _ASM_POWERPC_PGTABLE_PPC64_H_
+/*
+ * This file contains the functions and defines necessary to modify and use
+ * the ppc64 hashed page table.
+ */
+
+#ifndef __ASSEMBLY__
+#include <linux/stddef.h>
+#include <asm/processor.h> /* For TASK_SIZE */
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/tlbflush.h>
+struct mm_struct;
+#endif /* __ASSEMBLY__ */
+
+#ifdef CONFIG_PPC_64K_PAGES
+#include <asm/pgtable-64k.h>
+#else
+#include <asm/pgtable-4k.h>
+#endif
+
+#define FIRST_USER_ADDRESS 0
+
+/*
+ * Size of EA range mapped by our pagetables.
+ */
+#define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \
+ PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT)
+#define PGTABLE_RANGE (1UL << PGTABLE_EADDR_SIZE)
+
+#if TASK_SIZE_USER64 > PGTABLE_RANGE
+#error TASK_SIZE_USER64 exceeds pagetable range
+#endif
+
+#if TASK_SIZE_USER64 > (1UL << (USER_ESID_BITS + SID_SHIFT))
+#error TASK_SIZE_USER64 exceeds user VSID range
+#endif
+
+/*
+ * Define the address range of the vmalloc VM area.
+ */
+#define VMALLOC_START ASM_CONST(0xD000000000000000)
+#define VMALLOC_SIZE ASM_CONST(0x80000000000)
+#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE)
+
+/*
+ * Define the address range of the imalloc VM area.
+ */
+#define PHBS_IO_BASE VMALLOC_END
+#define IMALLOC_BASE (PHBS_IO_BASE + 0x80000000ul) /* Reserve 2 gigs for PHBs */
+#define IMALLOC_END (VMALLOC_START + PGTABLE_RANGE)
+
+/*
+ * Region IDs
+ */
+#define REGION_SHIFT 60UL
+#define REGION_MASK (0xfUL << REGION_SHIFT)
+#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT)
+
+#define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START))
+#define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET))
+#define USER_REGION_ID (0UL)
+
+/*
+ * Common bits in a linux-style PTE. These match the bits in the
+ * (hardware-defined) PowerPC PTE as closely as possible. Additional
+ * bits may be defined in pgtable-*.h
+ */
+#define _PAGE_PRESENT 0x0001 /* software: pte contains a translation */
+#define _PAGE_USER 0x0002 /* matches one of the PP bits */
+#define _PAGE_FILE 0x0002 /* (!present only) software: pte holds file offset */
+#define _PAGE_EXEC 0x0004 /* No execute on POWER4 and newer (we invert) */
+#define _PAGE_GUARDED 0x0008
+#define _PAGE_COHERENT 0x0010 /* M: enforce memory coherence (SMP systems) */
+#define _PAGE_NO_CACHE 0x0020 /* I: cache inhibit */
+#define _PAGE_WRITETHRU 0x0040 /* W: cache write-through */
+#define _PAGE_DIRTY 0x0080 /* C: page changed */
+#define _PAGE_ACCESSED 0x0100 /* R: page referenced */
+#define _PAGE_RW 0x0200 /* software: user write access allowed */
+#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */
+#define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */
+
+#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT)
+
+#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY)
+
+/* __pgprot defined in asm-powerpc/page.h */
+#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
+
+#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER)
+#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_WRENABLE)
+#define PAGE_KERNEL_CI __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
+ _PAGE_WRENABLE | _PAGE_NO_CACHE | _PAGE_GUARDED)
+#define PAGE_KERNEL_EXEC __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_EXEC)
+
+#define PAGE_AGP __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_NO_CACHE)
+#define HAVE_PAGE_AGP
+
+/* PTEIDX nibble */
+#define _PTEIDX_SECONDARY 0x8
+#define _PTEIDX_GROUP_IX 0x7
+
+
+/*
+ * POWER4 and newer have per page execute protection, older chips can only
+ * do this on a segment (256MB) basis.
+ *
+ * Also, write permissions imply read permissions.
+ * This is the closest we can get..
+ *
+ * Note due to the way vm flags are laid out, the bits are XWR
+ */
+#define __P000 PAGE_NONE
+#define __P001 PAGE_READONLY
+#define __P010 PAGE_COPY
+#define __P011 PAGE_COPY
+#define __P100 PAGE_READONLY_X
+#define __P101 PAGE_READONLY_X
+#define __P110 PAGE_COPY_X
+#define __P111 PAGE_COPY_X
+
+#define __S000 PAGE_NONE
+#define __S001 PAGE_READONLY
+#define __S010 PAGE_SHARED
+#define __S011 PAGE_SHARED
+#define __S100 PAGE_READONLY_X
+#define __S101 PAGE_READONLY_X
+#define __S110 PAGE_SHARED_X
+#define __S111 PAGE_SHARED_X
+
+#ifndef __ASSEMBLY__
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+#endif /* __ASSEMBLY__ */
+
+#ifdef CONFIG_HUGETLB_PAGE
+
+#define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+
+#endif
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ *
+ * mk_pte takes a (struct page *) as input
+ */
+#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
+
+static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
+{
+ pte_t pte;
+
+
+ pte_val(pte) = (pfn << PTE_RPN_SHIFT) | pgprot_val(pgprot);
+ return pte;
+}
+
+#define pte_modify(_pte, newprot) \
+ (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)))
+
+#define pte_none(pte) ((pte_val(pte) & ~_PAGE_HPTEFLAGS) == 0)
+#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
+
+/* pte_clear moved to later in this file */
+
+#define pte_pfn(x) ((unsigned long)((pte_val(x)>>PTE_RPN_SHIFT)))
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+
+#define PMD_BAD_BITS (PTE_TABLE_SIZE-1)
+#define PUD_BAD_BITS (PMD_TABLE_SIZE-1)
+
+#define pmd_set(pmdp, pmdval) (pmd_val(*(pmdp)) = (pmdval))
+#define pmd_none(pmd) (!pmd_val(pmd))
+#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \
+ || (pmd_val(pmd) & PMD_BAD_BITS))
+#define pmd_present(pmd) (pmd_val(pmd) != 0)
+#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0)
+#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS)
+#define pmd_page(pmd) virt_to_page(pmd_page_vaddr(pmd))
+
+#define pud_set(pudp, pudval) (pud_val(*(pudp)) = (pudval))
+#define pud_none(pud) (!pud_val(pud))
+#define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \
+ || (pud_val(pud) & PUD_BAD_BITS))
+#define pud_present(pud) (pud_val(pud) != 0)
+#define pud_clear(pudp) (pud_val(*(pudp)) = 0)
+#define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS)
+#define pud_page(pud) virt_to_page(pud_page_vaddr(pud))
+
+#define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);})
+
+/*
+ * Find an entry in a page-table-directory. We combine the address region
+ * (the high order N bits) and the pgd portion of the address.
+ */
+/* to avoid overflow in free_pgtables we don't use PTRS_PER_PGD here */
+#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & 0x1ff)
+
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+
+#define pmd_offset(pudp,addr) \
+ (((pmd_t *) pud_page_vaddr(*(pudp))) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
+
+#define pte_offset_kernel(dir,addr) \
+ (((pte_t *) pmd_page_vaddr(*(dir))) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
+
+#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr))
+#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr))
+#define pte_unmap(pte) do { } while(0)
+#define pte_unmap_nested(pte) do { } while(0)
+
+/* to find an entry in a kernel page-table-directory */
+/* This now only contains the vmalloc pages */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER;}
+static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW;}
+static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_EXEC;}
+static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY;}
+static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;}
+static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE;}
+
+static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; }
+static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; }
+
+static inline pte_t pte_rdprotect(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_USER; return pte; }
+static inline pte_t pte_exprotect(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_EXEC; return pte; }
+static inline pte_t pte_wrprotect(pte_t pte) {
+ pte_val(pte) &= ~(_PAGE_RW); return pte; }
+static inline pte_t pte_mkclean(pte_t pte) {
+ pte_val(pte) &= ~(_PAGE_DIRTY); return pte; }
+static inline pte_t pte_mkold(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkread(pte_t pte) {
+ pte_val(pte) |= _PAGE_USER; return pte; }
+static inline pte_t pte_mkexec(pte_t pte) {
+ pte_val(pte) |= _PAGE_USER | _PAGE_EXEC; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte) {
+ pte_val(pte) |= _PAGE_RW; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte) {
+ pte_val(pte) |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte) {
+ pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkhuge(pte_t pte) {
+ return pte; }
+
+/* Atomic PTE updates */
+static inline unsigned long pte_update(struct mm_struct *mm,
+ unsigned long addr,
+ pte_t *ptep, unsigned long clr,
+ int huge)
+{
+ unsigned long old, tmp;
+
+ __asm__ __volatile__(
+ "1: ldarx %0,0,%3 # pte_update\n\
+ andi. %1,%0,%6\n\
+ bne- 1b \n\
+ andc %1,%0,%4 \n\
+ stdcx. %1,0,%3 \n\
+ bne- 1b"
+ : "=&r" (old), "=&r" (tmp), "=m" (*ptep)
+ : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY)
+ : "cc" );
+
+ if (old & _PAGE_HASHPTE)
+ hpte_need_flush(mm, addr, ptep, old, huge);
+ return old;
+}
+
+static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ unsigned long old;
+
+ if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
+ return 0;
+ old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0);
+ return (old & _PAGE_ACCESSED) != 0;
+}
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
+({ \
+ int __r; \
+ __r = __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \
+ __r; \
+})
+
+/*
+ * On RW/DIRTY bit transitions we can avoid flushing the hpte. For the
+ * moment we always flush but we need to fix hpte_update and test if the
+ * optimisation is worth it.
+ */
+static inline int __ptep_test_and_clear_dirty(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ unsigned long old;
+
+ if ((pte_val(*ptep) & _PAGE_DIRTY) == 0)
+ return 0;
+ old = pte_update(mm, addr, ptep, _PAGE_DIRTY, 0);
+ return (old & _PAGE_DIRTY) != 0;
+}
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
+#define ptep_test_and_clear_dirty(__vma, __addr, __ptep) \
+({ \
+ int __r; \
+ __r = __ptep_test_and_clear_dirty((__vma)->vm_mm, __addr, __ptep); \
+ __r; \
+})
+
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+ unsigned long old;
+
+ if ((pte_val(*ptep) & _PAGE_RW) == 0)
+ return;
+ old = pte_update(mm, addr, ptep, _PAGE_RW, 0);
+}
+
+/*
+ * We currently remove entries from the hashtable regardless of whether
+ * the entry was young or dirty. The generic routines only flush if the
+ * entry was young or dirty which is not good enough.
+ *
+ * We should be more intelligent about this but for the moment we override
+ * these functions and force a tlb flush unconditionally
+ */
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+#define ptep_clear_flush_young(__vma, __address, __ptep) \
+({ \
+ int __young = __ptep_test_and_clear_young((__vma)->vm_mm, __address, \
+ __ptep); \
+ __young; \
+})
+
+#define __HAVE_ARCH_PTEP_CLEAR_DIRTY_FLUSH
+#define ptep_clear_flush_dirty(__vma, __address, __ptep) \
+({ \
+ int __dirty = __ptep_test_and_clear_dirty((__vma)->vm_mm, __address, \
+ __ptep); \
+ __dirty; \
+})
+
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0);
+ return __pte(old);
+}
+
+static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
+ pte_t * ptep)
+{
+ pte_update(mm, addr, ptep, ~0UL, 0);
+}
+
+/*
+ * set_pte stores a linux PTE into the linux page table.
+ */
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte)
+{
+ if (pte_present(*ptep))
+ pte_clear(mm, addr, ptep);
+ pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
+ *ptep = pte;
+}
+
+/* Set the dirty and/or accessed bits atomically in a linux PTE, this
+ * function doesn't need to flush the hash entry
+ */
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
+{
+ unsigned long bits = pte_val(entry) &
+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
+ unsigned long old, tmp;
+
+ __asm__ __volatile__(
+ "1: ldarx %0,0,%4\n\
+ andi. %1,%0,%6\n\
+ bne- 1b \n\
+ or %0,%3,%0\n\
+ stdcx. %0,0,%4\n\
+ bne- 1b"
+ :"=&r" (old), "=&r" (tmp), "=m" (*ptep)
+ :"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY)
+ :"cc");
+}
+#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
+ do { \
+ __ptep_set_access_flags(__ptep, __entry, __dirty); \
+ flush_tlb_page_nohash(__vma, __address); \
+ } while(0)
+
+/*
+ * Macro to mark a page protection value as "uncacheable".
+ */
+#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
+
+struct file;
+extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot);
+#define __HAVE_PHYS_MEM_ACCESS_PROT
+
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
+
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+#define pmd_ERROR(e) \
+ printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pgd_ERROR(e) \
+ printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+extern pgd_t swapper_pg_dir[];
+
+extern void paging_init(void);
+
+/* Encode and de-code a swap entry */
+#define __swp_type(entry) (((entry).val >> 1) & 0x3f)
+#define __swp_offset(entry) ((entry).val >> 8)
+#define __swp_entry(type, offset) ((swp_entry_t){((type)<< 1)|((offset)<<8)})
+#define __pte_to_swp_entry(pte) ((swp_entry_t){pte_val(pte) >> PTE_RPN_SHIFT})
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val << PTE_RPN_SHIFT })
+#define pte_to_pgoff(pte) (pte_val(pte) >> PTE_RPN_SHIFT)
+#define pgoff_to_pte(off) ((pte_t) {((off) << PTE_RPN_SHIFT)|_PAGE_FILE})
+#define PTE_FILE_MAX_BITS (BITS_PER_LONG - PTE_RPN_SHIFT)
+
+/*
+ * kern_addr_valid is intended to indicate whether an address is a valid
+ * kernel address. Most 32-bit archs define it as always true (like this)
+ * but most 64-bit archs actually perform a test. What should we do here?
+ * The only use is in fs/ncpfs/dir.c
+ */
+#define kern_addr_valid(addr) (1)
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+void pgtable_cache_init(void);
+
+/*
+ * find_linux_pte returns the address of a linux pte for a given
+ * effective address and directory. If not found, it returns zero.
+ */static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea)
+{
+ pgd_t *pg;
+ pud_t *pu;
+ pmd_t *pm;
+ pte_t *pt = NULL;
+
+ pg = pgdir + pgd_index(ea);
+ if (!pgd_none(*pg)) {
+ pu = pud_offset(pg, ea);
+ if (!pud_none(*pu)) {
+ pm = pmd_offset(pu, ea);
+ if (pmd_present(*pm))
+ pt = pte_offset_kernel(pm, ea);
+ }
+ }
+ return pt;
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_POWERPC_PGTABLE_PPC64_H_ */
diff --git a/include/asm-powerpc/pgtable.h b/include/asm-powerpc/pgtable.h
index 19edb69..78bf4ae 100644
--- a/include/asm-powerpc/pgtable.h
+++ b/include/asm-powerpc/pgtable.h
@@ -2,502 +2,15 @@
#define _ASM_POWERPC_PGTABLE_H
#ifdef __KERNEL__
-#ifndef CONFIG_PPC64
-#include <asm-ppc/pgtable.h>
+#if defined(CONFIG_PPC64)
+# include <asm/pgtable-ppc64.h>
#else
-
-/*
- * This file contains the functions and defines necessary to modify and use
- * the ppc64 hashed page table.
- */
-
-#ifndef __ASSEMBLY__
-#include <linux/stddef.h>
-#include <asm/processor.h> /* For TASK_SIZE */
-#include <asm/mmu.h>
-#include <asm/page.h>
-#include <asm/tlbflush.h>
-struct mm_struct;
-#endif /* __ASSEMBLY__ */
-
-#ifdef CONFIG_PPC_64K_PAGES
-#include <asm/pgtable-64k.h>
-#else
-#include <asm/pgtable-4k.h>
-#endif
-
-#define FIRST_USER_ADDRESS 0
-
-/*
- * Size of EA range mapped by our pagetables.
- */
-#define PGTABLE_EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \
- PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT)
-#define PGTABLE_RANGE (1UL << PGTABLE_EADDR_SIZE)
-
-#if TASK_SIZE_USER64 > PGTABLE_RANGE
-#error TASK_SIZE_USER64 exceeds pagetable range
-#endif
-
-#if TASK_SIZE_USER64 > (1UL << (USER_ESID_BITS + SID_SHIFT))
-#error TASK_SIZE_USER64 exceeds user VSID range
+# include <asm/pgtable-ppc32.h>
#endif
-/*
- * Define the address range of the vmalloc VM area.
- */
-#define VMALLOC_START ASM_CONST(0xD000000000000000)
-#define VMALLOC_SIZE ASM_CONST(0x80000000000)
-#define VMALLOC_END (VMALLOC_START + VMALLOC_SIZE)
-
-/*
- * Define the address range of the imalloc VM area.
- */
-#define PHBS_IO_BASE VMALLOC_END
-#define IMALLOC_BASE (PHBS_IO_BASE + 0x80000000ul) /* Reserve 2 gigs for PHBs */
-#define IMALLOC_END (VMALLOC_START + PGTABLE_RANGE)
-
-/*
- * Region IDs
- */
-#define REGION_SHIFT 60UL
-#define REGION_MASK (0xfUL << REGION_SHIFT)
-#define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT)
-
-#define VMALLOC_REGION_ID (REGION_ID(VMALLOC_START))
-#define KERNEL_REGION_ID (REGION_ID(PAGE_OFFSET))
-#define USER_REGION_ID (0UL)
-
-/*
- * Common bits in a linux-style PTE. These match the bits in the
- * (hardware-defined) PowerPC PTE as closely as possible. Additional
- * bits may be defined in pgtable-*.h
- */
-#define _PAGE_PRESENT 0x0001 /* software: pte contains a translation */
-#define _PAGE_USER 0x0002 /* matches one of the PP bits */
-#define _PAGE_FILE 0x0002 /* (!present only) software: pte holds file offset */
-#define _PAGE_EXEC 0x0004 /* No execute on POWER4 and newer (we invert) */
-#define _PAGE_GUARDED 0x0008
-#define _PAGE_COHERENT 0x0010 /* M: enforce memory coherence (SMP systems) */
-#define _PAGE_NO_CACHE 0x0020 /* I: cache inhibit */
-#define _PAGE_WRITETHRU 0x0040 /* W: cache write-through */
-#define _PAGE_DIRTY 0x0080 /* C: page changed */
-#define _PAGE_ACCESSED 0x0100 /* R: page referenced */
-#define _PAGE_RW 0x0200 /* software: user write access allowed */
-#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */
-#define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */
-
-#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT)
-
-#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY)
-
-/* __pgprot defined in asm-powerpc/page.h */
-#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
-
-#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER)
-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER | _PAGE_EXEC)
-#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-#define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_WRENABLE)
-#define PAGE_KERNEL_CI __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
- _PAGE_WRENABLE | _PAGE_NO_CACHE | _PAGE_GUARDED)
-#define PAGE_KERNEL_EXEC __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_EXEC)
-
-#define PAGE_AGP __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_NO_CACHE)
-#define HAVE_PAGE_AGP
-
-/* PTEIDX nibble */
-#define _PTEIDX_SECONDARY 0x8
-#define _PTEIDX_GROUP_IX 0x7
-
-
-/*
- * POWER4 and newer have per page execute protection, older chips can only
- * do this on a segment (256MB) basis.
- *
- * Also, write permissions imply read permissions.
- * This is the closest we can get..
- *
- * Note due to the way vm flags are laid out, the bits are XWR
- */
-#define __P000 PAGE_NONE
-#define __P001 PAGE_READONLY
-#define __P010 PAGE_COPY
-#define __P011 PAGE_COPY
-#define __P100 PAGE_READONLY_X
-#define __P101 PAGE_READONLY_X
-#define __P110 PAGE_COPY_X
-#define __P111 PAGE_COPY_X
-
-#define __S000 PAGE_NONE
-#define __S001 PAGE_READONLY
-#define __S010 PAGE_SHARED
-#define __S011 PAGE_SHARED
-#define __S100 PAGE_READONLY_X
-#define __S101 PAGE_READONLY_X
-#define __S110 PAGE_SHARED_X
-#define __S111 PAGE_SHARED_X
-
#ifndef __ASSEMBLY__
-
-/*
- * ZERO_PAGE is a global shared page that is always zero: used
- * for zero-mapped memory areas etc..
- */
-extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
-#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
-#endif /* __ASSEMBLY__ */
-
-#ifdef CONFIG_HUGETLB_PAGE
-
-#define HAVE_ARCH_UNMAPPED_AREA
-#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
-
-#endif
-
-#ifndef __ASSEMBLY__
-
-/*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- *
- * mk_pte takes a (struct page *) as input
- */
-#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
-
-static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
-{
- pte_t pte;
-
-
- pte_val(pte) = (pfn << PTE_RPN_SHIFT) | pgprot_val(pgprot);
- return pte;
-}
-
-#define pte_modify(_pte, newprot) \
- (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)))
-
-#define pte_none(pte) ((pte_val(pte) & ~_PAGE_HPTEFLAGS) == 0)
-#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
-
-/* pte_clear moved to later in this file */
-
-#define pte_pfn(x) ((unsigned long)((pte_val(x)>>PTE_RPN_SHIFT)))
-#define pte_page(x) pfn_to_page(pte_pfn(x))
-
-#define PMD_BAD_BITS (PTE_TABLE_SIZE-1)
-#define PUD_BAD_BITS (PMD_TABLE_SIZE-1)
-
-#define pmd_set(pmdp, pmdval) (pmd_val(*(pmdp)) = (pmdval))
-#define pmd_none(pmd) (!pmd_val(pmd))
-#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \
- || (pmd_val(pmd) & PMD_BAD_BITS))
-#define pmd_present(pmd) (pmd_val(pmd) != 0)
-#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0)
-#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS)
-#define pmd_page(pmd) virt_to_page(pmd_page_vaddr(pmd))
-
-#define pud_set(pudp, pudval) (pud_val(*(pudp)) = (pudval))
-#define pud_none(pud) (!pud_val(pud))
-#define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \
- || (pud_val(pud) & PUD_BAD_BITS))
-#define pud_present(pud) (pud_val(pud) != 0)
-#define pud_clear(pudp) (pud_val(*(pudp)) = 0)
-#define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS)
-#define pud_page(pud) virt_to_page(pud_page_vaddr(pud))
-
-#define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);})
-
-/*
- * Find an entry in a page-table-directory. We combine the address region
- * (the high order N bits) and the pgd portion of the address.
- */
-/* to avoid overflow in free_pgtables we don't use PTRS_PER_PGD here */
-#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & 0x1ff)
-
-#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
-
-#define pmd_offset(pudp,addr) \
- (((pmd_t *) pud_page_vaddr(*(pudp))) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
-
-#define pte_offset_kernel(dir,addr) \
- (((pte_t *) pmd_page_vaddr(*(dir))) + (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
-
-#define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr))
-#define pte_offset_map_nested(dir,addr) pte_offset_kernel((dir), (addr))
-#define pte_unmap(pte) do { } while(0)
-#define pte_unmap_nested(pte) do { } while(0)
-
-/* to find an entry in a kernel page-table-directory */
-/* This now only contains the vmalloc pages */
-#define pgd_offset_k(address) pgd_offset(&init_mm, address)
-
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER;}
-static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW;}
-static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_EXEC;}
-static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY;}
-static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;}
-static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE;}
-
-static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; }
-static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; }
-
-static inline pte_t pte_rdprotect(pte_t pte) {
- pte_val(pte) &= ~_PAGE_USER; return pte; }
-static inline pte_t pte_exprotect(pte_t pte) {
- pte_val(pte) &= ~_PAGE_EXEC; return pte; }
-static inline pte_t pte_wrprotect(pte_t pte) {
- pte_val(pte) &= ~(_PAGE_RW); return pte; }
-static inline pte_t pte_mkclean(pte_t pte) {
- pte_val(pte) &= ~(_PAGE_DIRTY); return pte; }
-static inline pte_t pte_mkold(pte_t pte) {
- pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-static inline pte_t pte_mkread(pte_t pte) {
- pte_val(pte) |= _PAGE_USER; return pte; }
-static inline pte_t pte_mkexec(pte_t pte) {
- pte_val(pte) |= _PAGE_USER | _PAGE_EXEC; return pte; }
-static inline pte_t pte_mkwrite(pte_t pte) {
- pte_val(pte) |= _PAGE_RW; return pte; }
-static inline pte_t pte_mkdirty(pte_t pte) {
- pte_val(pte) |= _PAGE_DIRTY; return pte; }
-static inline pte_t pte_mkyoung(pte_t pte) {
- pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-static inline pte_t pte_mkhuge(pte_t pte) {
- return pte; }
-
-/* Atomic PTE updates */
-static inline unsigned long pte_update(struct mm_struct *mm,
- unsigned long addr,
- pte_t *ptep, unsigned long clr,
- int huge)
-{
- unsigned long old, tmp;
-
- __asm__ __volatile__(
- "1: ldarx %0,0,%3 # pte_update\n\
- andi. %1,%0,%6\n\
- bne- 1b \n\
- andc %1,%0,%4 \n\
- stdcx. %1,0,%3 \n\
- bne- 1b"
- : "=&r" (old), "=&r" (tmp), "=m" (*ptep)
- : "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY)
- : "cc" );
-
- if (old & _PAGE_HASHPTE)
- hpte_need_flush(mm, addr, ptep, old, huge);
- return old;
-}
-
-static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
- unsigned long addr, pte_t *ptep)
-{
- unsigned long old;
-
- if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0)
- return 0;
- old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0);
- return (old & _PAGE_ACCESSED) != 0;
-}
-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-#define ptep_test_and_clear_young(__vma, __addr, __ptep) \
-({ \
- int __r; \
- __r = __ptep_test_and_clear_young((__vma)->vm_mm, __addr, __ptep); \
- __r; \
-})
-
-/*
- * On RW/DIRTY bit transitions we can avoid flushing the hpte. For the
- * moment we always flush but we need to fix hpte_update and test if the
- * optimisation is worth it.
- */
-static inline int __ptep_test_and_clear_dirty(struct mm_struct *mm,
- unsigned long addr, pte_t *ptep)
-{
- unsigned long old;
-
- if ((pte_val(*ptep) & _PAGE_DIRTY) == 0)
- return 0;
- old = pte_update(mm, addr, ptep, _PAGE_DIRTY, 0);
- return (old & _PAGE_DIRTY) != 0;
-}
-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
-#define ptep_test_and_clear_dirty(__vma, __addr, __ptep) \
-({ \
- int __r; \
- __r = __ptep_test_and_clear_dirty((__vma)->vm_mm, __addr, __ptep); \
- __r; \
-})
-
-#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep)
-{
- unsigned long old;
-
- if ((pte_val(*ptep) & _PAGE_RW) == 0)
- return;
- old = pte_update(mm, addr, ptep, _PAGE_RW, 0);
-}
-
-/*
- * We currently remove entries from the hashtable regardless of whether
- * the entry was young or dirty. The generic routines only flush if the
- * entry was young or dirty which is not good enough.
- *
- * We should be more intelligent about this but for the moment we override
- * these functions and force a tlb flush unconditionally
- */
-#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
-#define ptep_clear_flush_young(__vma, __address, __ptep) \
-({ \
- int __young = __ptep_test_and_clear_young((__vma)->vm_mm, __address, \
- __ptep); \
- __young; \
-})
-
-#define __HAVE_ARCH_PTEP_CLEAR_DIRTY_FLUSH
-#define ptep_clear_flush_dirty(__vma, __address, __ptep) \
-({ \
- int __dirty = __ptep_test_and_clear_dirty((__vma)->vm_mm, __address, \
- __ptep); \
- __dirty; \
-})
-
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
- unsigned long addr, pte_t *ptep)
-{
- unsigned long old = pte_update(mm, addr, ptep, ~0UL, 0);
- return __pte(old);
-}
-
-static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
- pte_t * ptep)
-{
- pte_update(mm, addr, ptep, ~0UL, 0);
-}
-
-/*
- * set_pte stores a linux PTE into the linux page table.
- */
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte)
-{
- if (pte_present(*ptep))
- pte_clear(mm, addr, ptep);
- pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
- *ptep = pte;
-}
-
-/* Set the dirty and/or accessed bits atomically in a linux PTE, this
- * function doesn't need to flush the hash entry
- */
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
-{
- unsigned long bits = pte_val(entry) &
- (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
- unsigned long old, tmp;
-
- __asm__ __volatile__(
- "1: ldarx %0,0,%4\n\
- andi. %1,%0,%6\n\
- bne- 1b \n\
- or %0,%3,%0\n\
- stdcx. %0,0,%4\n\
- bne- 1b"
- :"=&r" (old), "=&r" (tmp), "=m" (*ptep)
- :"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY)
- :"cc");
-}
-#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
- do { \
- __ptep_set_access_flags(__ptep, __entry, __dirty); \
- flush_tlb_page_nohash(__vma, __address); \
- } while(0)
-
-/*
- * Macro to mark a page protection value as "uncacheable".
- */
-#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
-
-struct file;
-extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
- unsigned long size, pgprot_t vma_prot);
-#define __HAVE_PHYS_MEM_ACCESS_PROT
-
-#define __HAVE_ARCH_PTE_SAME
-#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
-
-#define pte_ERROR(e) \
- printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
-#define pmd_ERROR(e) \
- printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
-#define pgd_ERROR(e) \
- printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
-
-extern pgd_t swapper_pg_dir[];
-
-extern void paging_init(void);
-
-/* Encode and de-code a swap entry */
-#define __swp_type(entry) (((entry).val >> 1) & 0x3f)
-#define __swp_offset(entry) ((entry).val >> 8)
-#define __swp_entry(type, offset) ((swp_entry_t){((type)<< 1)|((offset)<<8)})
-#define __pte_to_swp_entry(pte) ((swp_entry_t){pte_val(pte) >> PTE_RPN_SHIFT})
-#define __swp_entry_to_pte(x) ((pte_t) { (x).val << PTE_RPN_SHIFT })
-#define pte_to_pgoff(pte) (pte_val(pte) >> PTE_RPN_SHIFT)
-#define pgoff_to_pte(off) ((pte_t) {((off) << PTE_RPN_SHIFT)|_PAGE_FILE})
-#define PTE_FILE_MAX_BITS (BITS_PER_LONG - PTE_RPN_SHIFT)
-
-/*
- * kern_addr_valid is intended to indicate whether an address is a valid
- * kernel address. Most 32-bit archs define it as always true (like this)
- * but most 64-bit archs actually perform a test. What should we do here?
- * The only use is in fs/ncpfs/dir.c
- */
-#define kern_addr_valid(addr) (1)
-
-#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
- remap_pfn_range(vma, vaddr, pfn, size, prot)
-
-void pgtable_cache_init(void);
-
-/*
- * find_linux_pte returns the address of a linux pte for a given
- * effective address and directory. If not found, it returns zero.
- */static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea)
-{
- pgd_t *pg;
- pud_t *pu;
- pmd_t *pm;
- pte_t *pt = NULL;
-
- pg = pgdir + pgd_index(ea);
- if (!pgd_none(*pg)) {
- pu = pud_offset(pg, ea);
- if (!pud_none(*pu)) {
- pm = pmd_offset(pu, ea);
- if (pmd_present(*pm))
- pt = pte_offset_kernel(pm, ea);
- }
- }
- return pt;
-}
-
-
#include <asm-generic/pgtable.h>
-
#endif /* __ASSEMBLY__ */
-#endif /* CONFIG_PPC64 */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_PGTABLE_H */
diff --git a/include/asm-powerpc/pmac_feature.h b/include/asm-powerpc/pmac_feature.h
index d3599cc..d43d91b 100644
--- a/include/asm-powerpc/pmac_feature.h
+++ b/include/asm-powerpc/pmac_feature.h
@@ -146,7 +146,7 @@ struct device_node;
static inline long pmac_call_feature(int selector, struct device_node* node,
long param, long value)
{
- if (!ppc_md.feature_call)
+ if (!ppc_md.feature_call || !machine_is(powermac))
return -ENODEV;
return ppc_md.feature_call(selector, node, param, value);
}
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index ec400f6..6845af9 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -20,7 +20,6 @@
#include <linux/platform_device.h>
#include <asm/irq.h>
#include <asm/atomic.h>
-#include <asm/io.h>
/* Definitions used by the flattened device tree */
#define OF_DT_HEADER 0xd00dfeed /* marker */
@@ -334,30 +333,17 @@ extern int of_irq_map_one(struct device_node *device, int index,
struct pci_dev;
extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-static inline int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
-{
- int irq = irq_of_parse_and_map(dev, index);
-
- /* Only dereference the resource if both the
- * resource and the irq are valid. */
- if (r && irq != NO_IRQ) {
- r->start = r->end = irq;
- r->flags = IORESOURCE_IRQ;
- }
-
- return irq;
-}
-
-static inline void __iomem *of_iomap(struct device_node *np, int index)
-{
- struct resource res;
-
- if (of_address_to_resource(np, index, &res))
- return NULL;
-
- return ioremap(res.start, 1 + res.end - res.start);
-}
+extern int of_irq_to_resource(struct device_node *dev, int index,
+ struct resource *r);
+/**
+ * of_iomap - Maps the memory mapped IO for a given device_node
+ * @device: the device whose io range will be mapped
+ * @index: index of the io range
+ *
+ * Returns a pointer to the mapped memory
+ */
+extern void __iomem *of_iomap(struct device_node *device, int index);
#endif /* __KERNEL__ */
#endif /* _POWERPC_PROM_H */
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h
index 821581a..13c372d 100644
--- a/include/asm-powerpc/ps3.h
+++ b/include/asm-powerpc/ps3.h
@@ -167,26 +167,31 @@ enum ps3_cpu_binding {
PS3_BINDING_CPU_1 = 1,
};
-int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
+int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
unsigned int *virq);
-int ps3_free_io_irq(unsigned int virq);
-int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq);
-int ps3_free_event_irq(unsigned int virq);
+int ps3_virq_destroy(unsigned int virq);
+int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
+ unsigned int *virq);
+int ps3_irq_plug_destroy(unsigned int virq);
+int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq);
+int ps3_event_receive_port_destroy(unsigned int virq);
int ps3_send_event_locally(unsigned int virq);
-int ps3_connect_event_irq(enum ps3_cpu_binding cpu,
- const struct ps3_device_id *did, unsigned int interrupt_id,
+
+int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
unsigned int *virq);
-int ps3_disconnect_event_irq(const struct ps3_device_id *did,
- unsigned int interrupt_id, unsigned int virq);
-int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
+int ps3_io_irq_destroy(unsigned int virq);
+int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
unsigned int *virq);
-int ps3_free_vuart_irq(unsigned int virq);
-int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id,
+int ps3_vuart_irq_destroy(unsigned int virq);
+int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
unsigned int class, unsigned int *virq);
-int ps3_free_spe_irq(unsigned int virq);
-int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
+int ps3_spe_irq_destroy(unsigned int virq);
+
+int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
+ const struct ps3_device_id *did, unsigned int interrupt_id,
unsigned int *virq);
-int ps3_free_irq(unsigned int virq);
+int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did,
+ unsigned int interrupt_id, unsigned int virq);
/* lv1 result codes */
diff --git a/include/asm-powerpc/suspend.h b/include/asm-powerpc/suspend.h
new file mode 100644
index 0000000..cbf2c94
--- /dev/null
+++ b/include/asm-powerpc/suspend.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_POWERPC_SUSPEND_H
+#define __ASM_POWERPC_SUSPEND_H
+
+static inline int arch_prepare_suspend(void) { return 0; }
+
+void save_processor_state(void);
+void restore_processor_state(void);
+
+#endif /* __ASM_POWERPC_SUSPEND_H */
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index d3e0906..09621f6 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -7,7 +7,6 @@
#include <linux/kernel.h>
#include <asm/hw_irq.h>
-#include <asm/atomic.h>
/*
* Memory barrier.
@@ -227,6 +226,29 @@ __xchg_u32(volatile void *p, unsigned long val)
return prev;
}
+/*
+ * Atomic exchange
+ *
+ * Changes the memory location '*ptr' to be val and returns
+ * the previous value stored there.
+ */
+static __inline__ unsigned long
+__xchg_u32_local(volatile void *p, unsigned long val)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%2 \n"
+ PPC405_ERR77(0,%2)
+" stwcx. %3,0,%2 \n\
+ bne- 1b"
+ : "=&r" (prev), "+m" (*(volatile unsigned int *)p)
+ : "r" (p), "r" (val)
+ : "cc", "memory");
+
+ return prev;
+}
+
#ifdef CONFIG_PPC64
static __inline__ unsigned long
__xchg_u64(volatile void *p, unsigned long val)
@@ -246,6 +268,23 @@ __xchg_u64(volatile void *p, unsigned long val)
return prev;
}
+
+static __inline__ unsigned long
+__xchg_u64_local(volatile void *p, unsigned long val)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__(
+"1: ldarx %0,0,%2 \n"
+ PPC405_ERR77(0,%2)
+" stdcx. %3,0,%2 \n\
+ bne- 1b"
+ : "=&r" (prev), "+m" (*(volatile unsigned long *)p)
+ : "r" (p), "r" (val)
+ : "cc", "memory");
+
+ return prev;
+}
#endif
/*
@@ -269,13 +308,32 @@ __xchg(volatile void *ptr, unsigned long x, unsigned int size)
return x;
}
+static __inline__ unsigned long
+__xchg_local(volatile void *ptr, unsigned long x, unsigned int size)
+{
+ switch (size) {
+ case 4:
+ return __xchg_u32_local(ptr, x);
+#ifdef CONFIG_PPC64
+ case 8:
+ return __xchg_u64_local(ptr, x);
+#endif
+ }
+ __xchg_called_with_bad_pointer();
+ return x;
+}
#define xchg(ptr,x) \
({ \
__typeof__(*(ptr)) _x_ = (x); \
(__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
})
-#define tas(ptr) (xchg((ptr),1))
+#define xchg_local(ptr,x) \
+ ({ \
+ __typeof__(*(ptr)) _x_ = (x); \
+ (__typeof__(*(ptr))) __xchg_local((ptr), \
+ (unsigned long)_x_, sizeof(*(ptr))); \
+ })
/*
* Compare and exchange - if *p == old, set it to new,
@@ -306,6 +364,28 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
return prev;
}
+static __inline__ unsigned long
+__cmpxchg_u32_local(volatile unsigned int *p, unsigned long old,
+ unsigned long new)
+{
+ unsigned int prev;
+
+ __asm__ __volatile__ (
+"1: lwarx %0,0,%2 # __cmpxchg_u32\n\
+ cmpw 0,%0,%3\n\
+ bne- 2f\n"
+ PPC405_ERR77(0,%2)
+" stwcx. %4,0,%2\n\
+ bne- 1b"
+ "\n\
+2:"
+ : "=&r" (prev), "+m" (*p)
+ : "r" (p), "r" (old), "r" (new)
+ : "cc", "memory");
+
+ return prev;
+}
+
#ifdef CONFIG_PPC64
static __inline__ unsigned long
__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
@@ -328,6 +408,27 @@ __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
return prev;
}
+
+static __inline__ unsigned long
+__cmpxchg_u64_local(volatile unsigned long *p, unsigned long old,
+ unsigned long new)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__ (
+"1: ldarx %0,0,%2 # __cmpxchg_u64\n\
+ cmpd 0,%0,%3\n\
+ bne- 2f\n\
+ stdcx. %4,0,%2\n\
+ bne- 1b"
+ "\n\
+2:"
+ : "=&r" (prev), "+m" (*p)
+ : "r" (p), "r" (old), "r" (new)
+ : "cc", "memory");
+
+ return prev;
+}
#endif
/* This function doesn't exist, so you'll get a linker error
@@ -350,6 +451,22 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
return old;
}
+static __inline__ unsigned long
+__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
+ unsigned int size)
+{
+ switch (size) {
+ case 4:
+ return __cmpxchg_u32_local(ptr, old, new);
+#ifdef CONFIG_PPC64
+ case 8:
+ return __cmpxchg_u64_local(ptr, old, new);
+#endif
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
+
#define cmpxchg(ptr,o,n) \
({ \
__typeof__(*(ptr)) _o_ = (o); \
@@ -358,6 +475,15 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
(unsigned long)_n_, sizeof(*(ptr))); \
})
+
+#define cmpxchg_local(ptr,o,n) \
+ ({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \
+ (unsigned long)_n_, sizeof(*(ptr))); \
+ })
+
#ifdef CONFIG_PPC64
/*
* We handle most unaligned accesses in hardware. On the other hand
diff --git a/include/asm-powerpc/tsi108.h b/include/asm-powerpc/tsi108.h
index 4e95d15..f8b6079 100644
--- a/include/asm-powerpc/tsi108.h
+++ b/include/asm-powerpc/tsi108.h
@@ -68,8 +68,17 @@
#define TSI108_PB_ERRCS_ES (1 << 1)
#define TSI108_PB_ISR_PBS_RD_ERR (1 << 8)
-#define TSI108_PCI_CFG_BASE_PHYS (0xfb000000)
#define TSI108_PCI_CFG_SIZE (0x01000000)
+
+/*
+ * PHY Configuration Options
+ *
+ * Specify "bcm54xx" in the compatible property of your device tree phy
+ * nodes if your board uses the Broadcom PHYs
+ */
+#define TSI108_PHY_MV88E 0 /* Marvel 88Exxxx PHY */
+#define TSI108_PHY_BCM54XX 1 /* Broardcom BCM54xx PHY */
+
/* Global variables */
extern u32 tsi108_pci_cfg_base;
@@ -93,6 +102,7 @@ typedef struct {
u16 phy; /* phy address */
u16 irq_num; /* irq number */
u8 mac_addr[6]; /* phy mac address */
+ u16 phy_type; /* type of phy on board */
} hw_info;
extern u32 get_vir_csrbase(void);
diff --git a/include/asm-powerpc/tsi108_pci.h b/include/asm-powerpc/tsi108_pci.h
new file mode 100644
index 0000000..a9f92f7
--- /dev/null
+++ b/include/asm-powerpc/tsi108_pci.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 IBM Corp
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _ASM_PPC_TSI108_PCI_H
+#define _ASM_PPC_TSI108_PCI_H
+
+#include <asm/tsi108.h>
+
+/* Register definitions */
+#define TSI108_PCI_P2O_BAR0 (TSI108_PCI_OFFSET + 0x10)
+#define TSI108_PCI_P2O_BAR0_UPPER (TSI108_PCI_OFFSET + 0x14)
+#define TSI108_PCI_P2O_BAR2 (TSI108_PCI_OFFSET + 0x18)
+#define TSI108_PCI_P2O_BAR2_UPPER (TSI108_PCI_OFFSET + 0x1c)
+#define TSI108_PCI_P2O_PAGE_SIZES (TSI108_PCI_OFFSET + 0x4c)
+#define TSI108_PCI_PFAB_BAR0 (TSI108_PCI_OFFSET + 0x204)
+#define TSI108_PCI_PFAB_BAR0_UPPER (TSI108_PCI_OFFSET + 0x208)
+#define TSI108_PCI_PFAB_IO (TSI108_PCI_OFFSET + 0x20c)
+#define TSI108_PCI_PFAB_IO_UPPER (TSI108_PCI_OFFSET + 0x210)
+#define TSI108_PCI_PFAB_MEM32 (TSI108_PCI_OFFSET + 0x214)
+#define TSI108_PCI_PFAB_PFM3 (TSI108_PCI_OFFSET + 0x220)
+#define TSI108_PCI_PFAB_PFM4 (TSI108_PCI_OFFSET + 0x230)
+
+extern int tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary);
+extern void tsi108_pci_int_init(struct device_node *node);
+extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc);
+extern void tsi108_clear_pci_cfg_error(void);
+
+#endif /* _ASM_PPC_TSI108_PCI_H */
diff --git a/include/asm-powerpc/udbg.h b/include/asm-powerpc/udbg.h
index d03d855..ce9d82f 100644
--- a/include/asm-powerpc/udbg.h
+++ b/include/asm-powerpc/udbg.h
@@ -47,6 +47,7 @@ extern void __init udbg_init_rtas_panel(void);
extern void __init udbg_init_rtas_console(void);
extern void __init udbg_init_debug_beat(void);
extern void __init udbg_init_btext(void);
+extern void __init udbg_init_44x_as1(void);
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_UDBG_H */
diff --git a/include/asm-ppc/kdebug.h b/include/asm-ppc/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-ppc/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
index b1fdbf4..bed452d 100644
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -827,10 +827,6 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
remap_pfn_range(vma, vaddr, pfn, size, prot)
#endif
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
/*
* No page table caches to initialise
*/
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index 7389435..d84a3cf 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -6,7 +6,6 @@
#include <linux/kernel.h>
-#include <asm/atomic.h>
#include <asm/hw_irq.h>
/*
@@ -170,7 +169,6 @@ xchg_u32(volatile void *p, unsigned long val)
extern void __xchg_called_with_bad_pointer(void);
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
{
diff --git a/include/asm-s390/dma-mapping.h b/include/asm-s390/dma-mapping.h
index 09bb7b0..3f8c12f 100644
--- a/include/asm-s390/dma-mapping.h
+++ b/include/asm-s390/dma-mapping.h
@@ -9,6 +9,4 @@
#ifndef _ASM_DMA_MAPPING_H
#define _ASM_DMA_MAPPING_H
-#include <asm-generic/dma-mapping-broken.h>
-
#endif /* _ASM_DMA_MAPPING_H */
diff --git a/include/asm-s390/kdebug.h b/include/asm-s390/kdebug.h
index d2d7ad2..04418af 100644
--- a/include/asm-s390/kdebug.h
+++ b/include/asm-s390/kdebug.h
@@ -8,21 +8,6 @@
struct pt_regs;
-struct die_args {
- struct pt_regs *regs;
- const char *str;
- long err;
- int trapnr;
- int signr;
-};
-
-/* Note - you should never unregister because that can race with NMIs.
- * If you really want to do it first unregister - then synchronize_sched
- * - then free.
- */
-extern int register_die_notifier(struct notifier_block *);
-extern int unregister_die_notifier(struct notifier_block *);
-
/*
* These are only here because kprobes.c wants them to implement a
* blatant layering violation. Will hopefully go away soon once all
@@ -37,8 +22,6 @@ static inline int unregister_page_fault_notifier(struct notifier_block *nb)
return 0;
}
-extern struct atomic_notifier_head s390die_chain;
-
enum die_val {
DIE_OOPS = 1,
DIE_BPT,
@@ -54,19 +37,6 @@ enum die_val {
DIE_NMI_IPI,
};
-static inline int notify_die(enum die_val val, const char *str,
- struct pt_regs *regs, long err, int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .str = str,
- .err = err,
- .trapnr = trap,
- .signr = sig
- };
- return atomic_notifier_call_chain(&s390die_chain, val, &args);
-}
-
extern void die(const char *, struct pt_regs *, long);
#endif
diff --git a/include/asm-s390/kexec.h b/include/asm-s390/kexec.h
index 9c35c8a..7592af7 100644
--- a/include/asm-s390/kexec.h
+++ b/include/asm-s390/kexec.h
@@ -34,8 +34,6 @@
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_S390
-#define MAX_NOTE_BYTES 1024
-
/* Provide a dummy definition to avoid build failures. */
static inline void crash_setup_regs(struct pt_regs *newregs,
struct pt_regs *oldregs) { }
diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h
index 127f72e..74db1dc 100644
--- a/include/asm-s390/qdio.h
+++ b/include/asm-s390/qdio.h
@@ -120,6 +120,7 @@ extern unsigned long qdio_get_status(int irq);
#define QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT 0x08 /* no effect on
adapter interrupts */
#define QDIO_FLAG_DONT_SIGA 0x10
+#define QDIO_FLAG_PCI_OUT 0x20
extern int do_QDIO(struct ccw_device*, unsigned int flags,
unsigned int queue_number,
diff --git a/include/asm-sh/bug.h b/include/asm-sh/bug.h
index 2f89dd0..794c36d 100644
--- a/include/asm-sh/bug.h
+++ b/include/asm-sh/bug.h
@@ -2,50 +2,80 @@
#define __ASM_SH_BUG_H
#ifdef CONFIG_BUG
-
-struct bug_frame {
- unsigned short opcode;
- unsigned short line;
- const char *file;
- const char *func;
-};
-
-struct pt_regs;
-
-extern void handle_BUG(struct pt_regs *);
+#define HAVE_ARCH_BUG
+#define HAVE_ARCH_WARN_ON
#define TRAPA_BUG_OPCODE 0xc33e /* trapa #0x3e */
+/**
+ * _EMIT_BUG_ENTRY
+ * %1 - __FILE__
+ * %2 - __LINE__
+ * %3 - trap type
+ * %4 - sizeof(struct bug_entry)
+ *
+ * The trapa opcode itself sits in %0.
+ * The %O notation is used to avoid # generation.
+ *
+ * The offending file and line are encoded in the __bug_table section.
+ */
#ifdef CONFIG_DEBUG_BUGVERBOSE
+#define _EMIT_BUG_ENTRY \
+ "\t.pushsection __bug_table,\"a\"\n" \
+ "2:\t.long 1b, %O1\n" \
+ "\t.short %O2, %O3\n" \
+ "\t.org 2b+%O4\n" \
+ "\t.popsection\n"
+#else
+#define _EMIT_BUG_ENTRY \
+ "\t.pushsection __bug_table,\"a\"\n" \
+ "2:\t.long 1b\n" \
+ "\t.short %O3\n" \
+ "\t.org 2b+%O4\n" \
+ "\t.popsection\n"
+#endif
#define BUG() \
do { \
__asm__ __volatile__ ( \
- ".align 2\n\t" \
- ".short %O0\n\t" \
- ".short %O1\n\t" \
- ".long %O2\n\t" \
- ".long %O3\n\t" \
- : \
- : "n" (TRAPA_BUG_OPCODE), \
- "i" (__LINE__), "X" (__FILE__), \
- "X" (__FUNCTION__)); \
+ "1:\t.short %O0\n" \
+ _EMIT_BUG_ENTRY \
+ : \
+ : "n" (TRAPA_BUG_OPCODE), \
+ "i" (__FILE__), \
+ "i" (__LINE__), "i" (0), \
+ "i" (sizeof(struct bug_entry))); \
} while (0)
-#else
-
-#define BUG() \
-do { \
- __asm__ __volatile__ ( \
- ".align 2\n\t" \
- ".short %O0\n\t" \
- : \
- : "n" (TRAPA_BUG_OPCODE)); \
+#define __WARN() \
+do { \
+ __asm__ __volatile__ ( \
+ "1:\t.short %O0\n" \
+ _EMIT_BUG_ENTRY \
+ : \
+ : "n" (TRAPA_BUG_OPCODE), \
+ "i" (__FILE__), \
+ "i" (__LINE__), \
+ "i" (BUGFLAG_WARNING), \
+ "i" (sizeof(struct bug_entry))); \
} while (0)
-#endif /* CONFIG_DEBUG_BUGVERBOSE */
+#define WARN_ON(x) ({ \
+ typeof(x) __ret_warn_on = (x); \
+ if (__builtin_constant_p(__ret_warn_on)) { \
+ if (__ret_warn_on) \
+ __WARN(); \
+ } else { \
+ if (unlikely(__ret_warn_on)) \
+ __WARN(); \
+ } \
+ unlikely(__ret_warn_on); \
+})
-#define HAVE_ARCH_BUG
+struct pt_regs;
+
+/* arch/sh/kernel/traps.c */
+void handle_BUG(struct pt_regs *);
#endif /* CONFIG_BUG */
diff --git a/include/asm-sh/clock.h b/include/asm-sh/clock.h
index 1df9280..386d797 100644
--- a/include/asm-sh/clock.h
+++ b/include/asm-sh/clock.h
@@ -13,7 +13,7 @@ struct clk_ops {
void (*enable)(struct clk *clk);
void (*disable)(struct clk *clk);
void (*recalc)(struct clk *clk);
- int (*set_rate)(struct clk *clk, unsigned long rate);
+ int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id);
};
struct clk {
@@ -48,6 +48,34 @@ void clk_recalc_rate(struct clk *);
int clk_register(struct clk *);
void clk_unregister(struct clk *);
-int show_clocks(struct seq_file *m);
+/* the exported API, in addition to clk_set_rate */
+/**
+ * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter
+ * @clk: clock source
+ * @rate: desired clock rate in Hz
+ * @algo_id: algorithm id to be passed down to ops->set_rate
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id);
+enum clk_sh_algo_id {
+ NO_CHANGE = 0,
+
+ IUS_N1_N1,
+ IUS_322,
+ IUS_522,
+ IUS_N11,
+
+ SB_N1,
+
+ SB3_N1,
+ SB3_32,
+ SB3_43,
+ SB3_54,
+
+ BP_N1,
+
+ IP_N1,
+};
#endif /* __ASM_SH_CLOCK_H */
diff --git a/include/asm-sh/cpu-sh3/mmu_context.h b/include/asm-sh/cpu-sh3/mmu_context.h
index bccb7dd..4704e86 100644
--- a/include/asm-sh/cpu-sh3/mmu_context.h
+++ b/include/asm-sh/cpu-sh3/mmu_context.h
@@ -32,6 +32,7 @@
defined(CONFIG_CPU_SUBTYPE_SH7706) || \
defined(CONFIG_CPU_SUBTYPE_SH7300) || \
defined(CONFIG_CPU_SUBTYPE_SH7705) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7712) || \
defined(CONFIG_CPU_SUBTYPE_SH7710)
#define INTEVT 0xa4000000 /* INTEVTE2(0xa4000000) */
#else
diff --git a/include/asm-sh/cpu-sh4/freq.h b/include/asm-sh/cpu-sh4/freq.h
index 602d061..86564e7 100644
--- a/include/asm-sh/cpu-sh4/freq.h
+++ b/include/asm-sh/cpu-sh4/freq.h
@@ -12,8 +12,16 @@
#if defined(CONFIG_CPU_SUBTYPE_SH73180) || defined(CONFIG_CPU_SUBTYPE_SH7722)
#define FRQCR 0xa4150000
+#define VCLKCR 0xa4150004
+#define SCLKACR 0xa4150008
+#define SCLKBCR 0xa415000c
+#define IrDACLKCR 0xa4150010
#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
#define FRQCR 0xffc80000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7785)
+#define FRQCR0 0xffc80000
+#define FRQCR1 0xffc80004
+#define FRQMR1 0xffc80014
#else
#define FRQCR 0xffc00000
#endif
diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h
index afe188f..e81bf21 100644
--- a/include/asm-sh/irq.h
+++ b/include/asm-sh/irq.h
@@ -2,94 +2,13 @@
#define __ASM_SH_IRQ_H
#include <asm/machvec.h>
-#include <asm/ptrace.h> /* for pt_regs */
-/* NR_IRQS is made from three components:
- * 1. ONCHIP_NR_IRQS - number of IRLS + on-chip peripherial modules
- * 2. PINT_NR_IRQS - number of PINT interrupts
- * 3. OFFCHIP_NR_IRQS - numbe of IRQs from off-chip peripherial modules
+/*
+ * A sane default based on a reasonable vector table size, platforms are
+ * advised to cap this at the hard limit that they're interested in
+ * through the machvec.
*/
-
-/* 1. ONCHIP_NR_IRQS */
-#if defined(CONFIG_CPU_SUBTYPE_SH7604)
-# define ONCHIP_NR_IRQS 24 // Actually 21
-#elif defined(CONFIG_CPU_SUBTYPE_SH7707)
-# define ONCHIP_NR_IRQS 64
-# define PINT_NR_IRQS 16
-#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
-# define ONCHIP_NR_IRQS 32
-#elif defined(CONFIG_CPU_SUBTYPE_SH7709) || \
- defined(CONFIG_CPU_SUBTYPE_SH7706) || \
- defined(CONFIG_CPU_SUBTYPE_SH7705)
-# define ONCHIP_NR_IRQS 64 // Actually 61
-# define PINT_NR_IRQS 16
-#elif defined(CONFIG_CPU_SUBTYPE_SH7710)
-# define ONCHIP_NR_IRQS 104
-#elif defined(CONFIG_CPU_SUBTYPE_SH7750)
-# define ONCHIP_NR_IRQS 48 // Actually 44
-#elif defined(CONFIG_CPU_SUBTYPE_SH7751)
-# define ONCHIP_NR_IRQS 72
-#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
-# define ONCHIP_NR_IRQS 112 /* XXX */
-#elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
-# define ONCHIP_NR_IRQS 72
-#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
-# define ONCHIP_NR_IRQS 144
-#elif defined(CONFIG_CPU_SUBTYPE_SH7300) || \
- defined(CONFIG_CPU_SUBTYPE_SH73180) || \
- defined(CONFIG_CPU_SUBTYPE_SH7343) || \
- defined(CONFIG_CPU_SUBTYPE_SH7722)
-# define ONCHIP_NR_IRQS 109
-#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
-# define ONCHIP_NR_IRQS 111
-#elif defined(CONFIG_CPU_SUBTYPE_SH7206)
-# define ONCHIP_NR_IRQS 256
-#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
-# define ONCHIP_NR_IRQS 128
-#elif defined(CONFIG_SH_UNKNOWN) /* Most be last */
-# define ONCHIP_NR_IRQS 144
-#endif
-
-/* 2. PINT_NR_IRQS */
-#ifdef CONFIG_SH_UNKNOWN
-# define PINT_NR_IRQS 16
-#else
-# ifndef PINT_NR_IRQS
-# define PINT_NR_IRQS 0
-# endif
-#endif
-
-#if PINT_NR_IRQS > 0
-# define PINT_IRQ_BASE ONCHIP_NR_IRQS
-#endif
-
-/* 3. OFFCHIP_NR_IRQS */
-#if defined(CONFIG_HD64461)
-# define OFFCHIP_NR_IRQS 18
-#elif defined(CONFIG_HD64465)
-# define OFFCHIP_NR_IRQS 16
-#elif defined (CONFIG_SH_DREAMCAST)
-# define OFFCHIP_NR_IRQS 96
-#elif defined (CONFIG_SH_TITAN)
-# define OFFCHIP_NR_IRQS 4
-#elif defined(CONFIG_SH_R7780RP)
-# define OFFCHIP_NR_IRQS 16
-#elif defined(CONFIG_SH_7343_SOLUTION_ENGINE)
-# define OFFCHIP_NR_IRQS 12
-#elif defined(CONFIG_SH_7722_SOLUTION_ENGINE)
-# define OFFCHIP_NR_IRQS 14
-#elif defined(CONFIG_SH_UNKNOWN)
-# define OFFCHIP_NR_IRQS 16 /* Must also be last */
-#else
-# define OFFCHIP_NR_IRQS 0
-#endif
-
-#if OFFCHIP_NR_IRQS > 0
-# define OFFCHIP_IRQ_BASE (ONCHIP_NR_IRQS + PINT_NR_IRQS)
-#endif
-
-/* NR_IRQS. 1+2+3 */
-#define NR_IRQS (ONCHIP_NR_IRQS + PINT_NR_IRQS + OFFCHIP_NR_IRQS)
+#define NR_IRQS 256
/*
* Convert back and forth between INTEVT and IRQ values.
diff --git a/include/asm-sh/kdebug.h b/include/asm-sh/kdebug.h
new file mode 100644
index 0000000..493c206
--- /dev/null
+++ b/include/asm-sh/kdebug.h
@@ -0,0 +1,36 @@
+#ifndef __ASM_SH_KDEBUG_H
+#define __ASM_SH_KDEBUG_H
+
+#include <linux/notifier.h>
+#include <asm-generic/kdebug.h>
+
+struct pt_regs;
+
+struct die_args {
+ struct pt_regs *regs;
+ int trapnr;
+};
+
+int register_die_notifier(struct notifier_block *nb);
+int unregister_die_notifier(struct notifier_block *nb);
+int register_page_fault_notifier(struct notifier_block *nb);
+int unregister_page_fault_notifier(struct notifier_block *nb);
+extern struct atomic_notifier_head shdie_chain;
+
+/* Grossly misnamed. */
+enum die_val {
+ DIE_TRAP,
+ DIE_PAGE_FAULT,
+};
+
+static inline int notify_die(enum die_val val, struct pt_regs *regs,
+ int trap, int sig)
+{
+ struct die_args args = {
+ .regs = regs,
+ .trapnr = trap,
+ };
+
+ return atomic_notifier_call_chain(&shdie_chain, val, &args);
+}
+#endif /* __ASM_SH_KDEBUG_H */
diff --git a/include/asm-sh/kexec.h b/include/asm-sh/kexec.h
index 9d235af..00f4260 100644
--- a/include/asm-sh/kexec.h
+++ b/include/asm-sh/kexec.h
@@ -1,5 +1,8 @@
-#ifndef _SH_KEXEC_H
-#define _SH_KEXEC_H
+#ifndef __ASM_SH_KEXEC_H
+#define __ASM_SH_KEXEC_H
+
+#include <asm/ptrace.h>
+#include <asm/string.h>
/*
* KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
@@ -23,10 +26,37 @@
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_SH
-#define MAX_NOTE_BYTES 1024
-
-/* Provide a dummy definition to avoid build failures. */
static inline void crash_setup_regs(struct pt_regs *newregs,
- struct pt_regs *oldregs) { }
+ struct pt_regs *oldregs)
+{
+ if (oldregs)
+ memcpy(newregs, oldregs, sizeof(*newregs));
+ else {
+ __asm__ __volatile__ ("mov r0, %0" : "=r" (newregs->regs[0]));
+ __asm__ __volatile__ ("mov r1, %0" : "=r" (newregs->regs[1]));
+ __asm__ __volatile__ ("mov r2, %0" : "=r" (newregs->regs[2]));
+ __asm__ __volatile__ ("mov r3, %0" : "=r" (newregs->regs[3]));
+ __asm__ __volatile__ ("mov r4, %0" : "=r" (newregs->regs[4]));
+ __asm__ __volatile__ ("mov r5, %0" : "=r" (newregs->regs[5]));
+ __asm__ __volatile__ ("mov r6, %0" : "=r" (newregs->regs[6]));
+ __asm__ __volatile__ ("mov r7, %0" : "=r" (newregs->regs[7]));
+ __asm__ __volatile__ ("mov r8, %0" : "=r" (newregs->regs[8]));
+ __asm__ __volatile__ ("mov r9, %0" : "=r" (newregs->regs[9]));
+ __asm__ __volatile__ ("mov r10, %0" : "=r" (newregs->regs[10]));
+ __asm__ __volatile__ ("mov r11, %0" : "=r" (newregs->regs[11]));
+ __asm__ __volatile__ ("mov r12, %0" : "=r" (newregs->regs[12]));
+ __asm__ __volatile__ ("mov r13, %0" : "=r" (newregs->regs[13]));
+ __asm__ __volatile__ ("mov r14, %0" : "=r" (newregs->regs[14]));
+ __asm__ __volatile__ ("mov r15, %0" : "=r" (newregs->regs[15]));
+
+ __asm__ __volatile__ ("sts pr, %0" : "=r" (newregs->pr));
+ __asm__ __volatile__ ("sts macl, %0" : "=r" (newregs->macl));
+ __asm__ __volatile__ ("sts mach, %0" : "=r" (newregs->mach));
+
+ __asm__ __volatile__ ("stc gbr, %0" : "=r" (newregs->gbr));
+ __asm__ __volatile__ ("stc sr, %0" : "=r" (newregs->sr));
-#endif /* _SH_KEXEC_H */
+ newregs->pc = (unsigned long)current_text_addr();
+ }
+}
+#endif /* __ASM_SH_KEXEC_H */
diff --git a/include/asm-sh/kgdb.h b/include/asm-sh/kgdb.h
index 0095c66..74bd095 100644
--- a/include/asm-sh/kgdb.h
+++ b/include/asm-sh/kgdb.h
@@ -17,6 +17,7 @@
#define __KGDB_H
#include <asm/ptrace.h>
+#include <asm/cacheflush.h>
struct console;
@@ -45,35 +46,21 @@ extern int kgdb_portnum;
extern int kgdb_baud;
extern char kgdb_parity;
extern char kgdb_bits;
-extern int kgdb_console_setup(struct console *, char *);
/* Init and interface stuff */
extern int kgdb_init(void);
-extern int (*kgdb_serial_setup)(void);
extern int (*kgdb_getchar)(void);
extern void (*kgdb_putchar)(int);
-struct kgdb_sermap {
- char *name;
- int namelen;
- int (*setup_fn)(struct console *, char *);
- struct kgdb_sermap *next;
-};
-extern void kgdb_register_sermap(struct kgdb_sermap *map);
-extern struct kgdb_sermap *kgdb_porttype;
-
/* Trap functions */
-typedef void (kgdb_debug_hook_t)(struct pt_regs *regs);
+typedef void (kgdb_debug_hook_t)(struct pt_regs *regs);
typedef void (kgdb_bus_error_hook_t)(void);
extern kgdb_debug_hook_t *kgdb_debug_hook;
extern kgdb_bus_error_hook_t *kgdb_bus_err_hook;
-extern void breakpoint(void);
-
/* Console */
-struct console;
void kgdb_console_write(struct console *co, const char *s, unsigned count);
-void kgdb_console_init(void);
+extern int kgdb_console_setup(struct console *, char *);
/* Prototypes for jmp fns */
#define _JBLEN 9
@@ -81,11 +68,8 @@ typedef int jmp_buf[_JBLEN];
extern void longjmp(jmp_buf __jmpb, int __retval);
extern int setjmp(jmp_buf __jmpb);
-/* Variadic macro to print our own message to the console */
-#define KGDB_PRINTK(...) printk("KGDB: " __VA_ARGS__)
-
/* Forced breakpoint */
-#define BREAKPOINT() \
+#define breakpoint() \
do { \
if (kgdb_enabled) \
__asm__ __volatile__("trapa #0x3c"); \
@@ -95,7 +79,6 @@ do { \
#if defined(CONFIG_CPU_SH4)
#define kgdb_flush_icache_range(start, end) \
{ \
- extern void __flush_purge_region(void *, int); \
__flush_purge_region((void*)(start), (int)(end) - (int)(start));\
flush_icache_range((start), (end)); \
}
@@ -103,31 +86,6 @@ do { \
#define kgdb_flush_icache_range(start, end) do { } while (0)
#endif
-/* Kernel assert macros */
-#ifdef CONFIG_KGDB_KERNEL_ASSERTS
-
-/* Predefined conditions */
-#define KA_VALID_ERRNO(errno) ((errno) > 0 && (errno) <= EMEDIUMTYPE)
-#define KA_VALID_PTR_ERR(ptr) KA_VALID_ERRNO(-PTR_ERR(ptr))
-#define KA_VALID_KPTR(ptr) (!(ptr) || \
- ((void *)(ptr) >= (void *)PAGE_OFFSET && \
- (void *)(ptr) < ERR_PTR(-EMEDIUMTYPE)))
-#define KA_VALID_PTRORERR(errptr) \
- (KA_VALID_KPTR(errptr) || KA_VALID_PTR_ERR(errptr))
-#define KA_HELD_GKL() (current->lock_depth >= 0)
-
-/* The actual assert */
-#define KGDB_ASSERT(condition, message) do { \
- if (!(condition) && (kgdb_enabled)) { \
- KGDB_PRINTK("Assertion failed at %s:%d: %s\n", \
- __FILE__, __LINE__, message);\
- BREAKPOINT(); \
- } \
-} while (0)
-#else
-#define KGDB_ASSERT(condition, message)
-#endif
-
/* Taken from sh-stub.c of GDB 4.18 */
static const char hexchars[] = "0123456789abcdef";
@@ -142,5 +100,4 @@ static inline char lowhex(const int x)
{
return hexchars[x & 0xf];
}
-
#endif
diff --git a/include/asm-sh/lboxre2.h b/include/asm-sh/lboxre2.h
new file mode 100644
index 0000000..e6d1605
--- /dev/null
+++ b/include/asm-sh/lboxre2.h
@@ -0,0 +1,27 @@
+#ifndef __ASM_SH_LBOXRE2_H
+#define __ASM_SH_LBOXRE2_H
+
+/*
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * NTT COMWARE L-BOX RE2 support
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#define IRQ_CF1 9 /* CF1 */
+#define IRQ_CF0 10 /* CF0 */
+#define IRQ_INTD 11 /* INTD */
+#define IRQ_ETH1 12 /* Ether1 */
+#define IRQ_ETH0 13 /* Ether0 */
+#define IRQ_INTA 14 /* INTA */
+
+void init_lboxre2_IRQ(void);
+
+#define __IO_PREFIX lboxre2
+#include <asm/io_generic.h>
+
+#endif /* __ASM_SH_LBOXRE2_H */
diff --git a/include/asm-sh/mmu_context.h b/include/asm-sh/mmu_context.h
index 01acaaa..199662b 100644
--- a/include/asm-sh/mmu_context.h
+++ b/include/asm-sh/mmu_context.h
@@ -169,6 +169,8 @@ enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
#define destroy_context(mm) do { } while (0)
#define set_asid(asid) do { } while (0)
#define get_asid() (0)
+#define set_TTB(pgd) do { } while (0)
+#define get_TTB() (0)
#define activate_context(mm,cpu) do { } while (0)
#define switch_mm(prev,next,tsk) do { } while (0)
#define deactivate_mm(tsk,mm) do { } while (0)
@@ -211,8 +213,8 @@ static inline void disable_mmu(void)
* MMU control handlers for processors lacking memory
* management hardware.
*/
-#define enable_mmu() do { BUG(); } while (0)
-#define disable_mmu() do { BUG(); } while (0)
+#define enable_mmu() do { } while (0)
+#define disable_mmu() do { } while (0)
#endif
#endif /* __KERNEL__ */
diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h
index ac4b467..7464de4 100644
--- a/include/asm-sh/page.h
+++ b/include/asm-sh/page.h
@@ -59,6 +59,7 @@ extern void (*clear_page)(void *to);
extern void (*copy_page)(void *to, void *from);
extern unsigned long shm_align_mask;
+extern unsigned long max_low_pfn, min_low_pfn;
#ifdef CONFIG_MMU
extern void clear_page_slow(void *to);
@@ -124,17 +125,16 @@ typedef struct { unsigned long pgd; } pgd_t;
#define PAGE_OFFSET CONFIG_PAGE_OFFSET
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
+#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
-#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
-
-#define phys_to_page(phys) (mem_map + (((phys)-__MEMORY_START) >> PAGE_SHIFT))
-#define page_to_phys(page) (((page - mem_map) << PAGE_SHIFT) + __MEMORY_START)
+#define phys_to_page(phys) (pfn_to_page(phys >> PAGE_SHIFT))
+#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
/* PFN start number, because of __MEMORY_START */
#define PFN_START (__MEMORY_START >> PAGE_SHIFT)
#define ARCH_PFN_OFFSET (PFN_START)
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-#define pfn_valid(pfn) (((pfn) - PFN_START) < max_mapnr)
+#define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_low_pfn)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
diff --git a/include/asm-sh/param.h b/include/asm-sh/param.h
index ce13064..1012296 100644
--- a/include/asm-sh/param.h
+++ b/include/asm-sh/param.h
@@ -5,7 +5,7 @@
# ifdef CONFIG_SH_WDT
# define HZ 1000 /* Needed for high-res WOVF */
# else
-# define HZ 100
+# define HZ CONFIG_HZ
# endif
# define USER_HZ 100 /* User interfaces are in "ticks" */
# define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */
diff --git a/include/asm-sh/pci.h b/include/asm-sh/pci.h
index 6ccc948..b1f9a9e 100644
--- a/include/asm-sh/pci.h
+++ b/include/asm-sh/pci.h
@@ -35,7 +35,7 @@ extern struct pci_channel board_pci_channels[];
/*
* I/O routine helpers
*/
-#ifdef CONFIG_CPU_SUBTYPE_SH7780
+#if defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785)
#define PCI_IO_AREA 0xFE400000
#define PCI_IO_SIZE 0x00400000
#else
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
index 184d7fc..5b523c7 100644
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -568,10 +568,6 @@ typedef pte_t *pte_addr_t;
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
struct mm_struct;
/*
diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h
index 3e46a7a..d42f68e 100644
--- a/include/asm-sh/processor.h
+++ b/include/asm-sh/processor.h
@@ -44,7 +44,7 @@ enum cpu_type {
/* SH-3 types */
CPU_SH7705, CPU_SH7706, CPU_SH7707,
CPU_SH7708, CPU_SH7708S, CPU_SH7708R,
- CPU_SH7709, CPU_SH7709A, CPU_SH7710,
+ CPU_SH7709, CPU_SH7709A, CPU_SH7710, CPU_SH7712,
CPU_SH7729, CPU_SH7300,
/* SH-4 types */
diff --git a/include/asm-sh/r7780rp.h b/include/asm-sh/r7780rp.h
index c18f648..4083b59 100644
--- a/include/asm-sh/r7780rp.h
+++ b/include/asm-sh/r7780rp.h
@@ -1,17 +1,11 @@
#ifndef __ASM_SH_RENESAS_R7780RP_H
#define __ASM_SH_RENESAS_R7780RP_H
-/*
- * linux/include/asm-sh/r7780rp.h
- *
- * Copyright (C) 2000 Atom Create Engineering Co., Ltd.
- *
- * Renesas Solutions Highlander R7780RP support
- */
-
/* Box specific addresses. */
#if defined(CONFIG_SH_R7780MP)
#define PA_BCR 0xa4000000 /* FPGA */
+#define PA_SDPOW (-1)
+
#define PA_IRLMSK (PA_BCR+0x0000) /* Interrupt Mask control */
#define PA_IRLMON (PA_BCR+0x0002) /* Interrupt Status control */
#define PA_IRLPRI1 (PA_BCR+0x0004) /* Interrupt Priorty 1 */
@@ -70,18 +64,12 @@
#define PA_POFF (PA_BCR+0x0800) /* System Power Off control */
#define PA_PMR (PA_BCR+0x0900) /* */
-#define PA_AX88796L 0xa4100400 /* AX88796L Area */
-#define PA_SC1602BSLB 0xa6000000 /* SC1602BSLB Area */
-#define PA_IDE_OFFSET 0x1f0 /* CF IDE Offset */
-#define AX88796L_IO_BASE 0x1000 /* AX88796L IO Base Address */
-
#define IRLCNTR1 (PA_BCR + 0) /* Interrupt Control Register1 */
#define IRQ_PCISLOT1 65 /* PCI Slot #1 IRQ */
#define IRQ_PCISLOT2 66 /* PCI Slot #2 IRQ */
#define IRQ_PCISLOT3 67 /* PCI Slot #3 IRQ */
#define IRQ_PCISLOT4 68 /* PCI Slot #4 IRQ */
-// #define IRQ_CFINST 0 /* CF Card Insert IRQ */
#define IRQ_TP 2 /* Touch Panel IRQ */
#define IRQ_SCI1 3 /* SCI1 IRQ */
#define IRQ_SCI0 4 /* SCI0 IRQ */
@@ -95,7 +83,10 @@
#define IRQ_ONETH 13 /* On board Ethernet IRQ */
#define IRQ_PSW 14 /* Push Switch IRQ */
-#else /* R7780RP */
+#define IVDR_CK_ON 8 /* iVDR Clock ON */
+
+#elif defined(CONFIG_SH_R7780RP)
+#define PA_POFF (-1)
#define PA_BCR 0xa5000000 /* FPGA */
#define PA_IRLMSK (PA_BCR+0x0000) /* Interrupt Mask control */
@@ -163,7 +154,60 @@
#define IRQ_PSW 13 /* Push Switch IRQ */
#define IRQ_ZIGBEE 14 /* Ziggbee IO IRQ */
-#endif /* CONFIG_SH_R7780MP */
+#define IVDR_CK_ON 8 /* iVDR Clock ON */
+
+#elif defined(CONFIG_SH_R7785RP)
+#define PA_BCR 0xa4000000 /* FPGA */
+#define PA_SDPOW (-1)
+
+#define PA_PCISCR (PA_BCR+0x0000)
+#define PA_IRLPRA (PA_BCR+0x0002)
+#define PA_IRLPRB (PA_BCR+0x0004)
+#define PA_IRLPRC (PA_BCR+0x0006)
+#define PA_IRLPRD (PA_BCR+0x0008)
+#define IRLCNTR1 (PA_BCR+0x0010)
+#define PA_IRLPRE (PA_BCR+0x000a)
+#define PA_IRLPRF (PA_BCR+0x000c)
+#define PA_EXIRLCR (PA_BCR+0x000e)
+#define PA_IRLMCR1 (PA_BCR+0x0010)
+#define PA_IRLMCR2 (PA_BCR+0x0012)
+#define PA_IRLSSR1 (PA_BCR+0x0014)
+#define PA_IRLSSR2 (PA_BCR+0x0016)
+#define PA_CFTCR (PA_BCR+0x0100)
+#define PA_CFPCR (PA_BCR+0x0102)
+#define PA_PCICR (PA_BCR+0x0110)
+#define PA_IVDRCTL (PA_BCR+0x0112)
+#define PA_IVDRSR (PA_BCR+0x0114)
+#define PA_PDRSTCR (PA_BCR+0x0116)
+#define PA_POFF (PA_BCR+0x0120)
+#define PA_LCDCR (PA_BCR+0x0130)
+#define PA_TPCR (PA_BCR+0x0140)
+#define PA_TPCKCR (PA_BCR+0x0142)
+#define PA_TPRSTR (PA_BCR+0x0144)
+#define PA_TPXPDR (PA_BCR+0x0146)
+#define PA_TPYPDR (PA_BCR+0x0148)
+#define PA_GPIOPFR (PA_BCR+0x0150)
+#define PA_GPIODR (PA_BCR+0x0152)
+#define PA_OBLED (PA_BCR+0x0154)
+#define PA_SWSR (PA_BCR+0x0156)
+#define PA_VERREG (PA_BCR+0x0158)
+#define PA_SMCR (PA_BCR+0x0200)
+#define PA_SMSMADR (PA_BCR+0x0202)
+#define PA_SMMR (PA_BCR+0x0204)
+#define PA_SMSADR1 (PA_BCR+0x0206)
+#define PA_SMSADR32 (PA_BCR+0x0244)
+#define PA_SMTRDR1 (PA_BCR+0x0246)
+#define PA_SMTRDR16 (PA_BCR+0x0264)
+#define PA_CU3MDR (PA_BCR+0x0300)
+#define PA_CU5MDR (PA_BCR+0x0302)
+#define PA_MMSR (PA_BCR+0x0400)
+
+#define IVDR_CK_ON 4 /* iVDR Clock ON */
+
+#endif
+
+void make_r7780rp_irq(unsigned int irq);
+void highlander_init_irq(void);
#define __IO_PREFIX r7780rp
#include <asm/io_generic.h>
diff --git a/include/asm-sh/se.h b/include/asm-sh/se.h
index a183215..bd2596c 100644
--- a/include/asm-sh/se.h
+++ b/include/asm-sh/se.h
@@ -69,9 +69,11 @@
#define BCR_ILCRG (PA_BCR + 12)
#if defined(CONFIG_CPU_SUBTYPE_SH7705)
-#define IRQ_STNIC 12
+#define IRQ_STNIC 12
+#define IRQ_CFCARD 14
#else
#define IRQ_STNIC 10
+#define IRQ_CFCARD 7
#endif
#define __IO_PREFIX se
diff --git a/include/asm-sh/se7722.h b/include/asm-sh/se7722.h
new file mode 100644
index 0000000..b3b31e4
--- /dev/null
+++ b/include/asm-sh/se7722.h
@@ -0,0 +1,118 @@
+#ifndef __ASM_SH_SE7722_H
+#define __ASM_SH_SE7722_H
+
+/*
+ * linux/include/asm-sh/se7722.h
+ *
+ * Copyright (C) 2007 Nobuhiro Iwamatsu
+ *
+ * Hitachi UL SolutionEngine 7722 Support.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#include <asm/addrspace.h>
+
+/* Box specific addresses. */
+#define SE_AREA0_WIDTH 4 /* Area0: 32bit */
+#define PA_ROM 0xa0000000 /* EPROM */
+#define PA_ROM_SIZE 0x00200000 /* EPROM size 2M byte */
+#define PA_FROM 0xa1000000 /* Flash-ROM */
+#define PA_FROM_SIZE 0x01000000 /* Flash-ROM size 16M byte */
+#define PA_EXT1 0xa4000000
+#define PA_EXT1_SIZE 0x04000000
+#define PA_SDRAM 0xaC000000 /* DDR-SDRAM(Area3) 64MB */
+#define PA_SDRAM_SIZE 0x04000000
+
+#define PA_EXT4 0xb0000000
+#define PA_EXT4_SIZE 0x04000000
+
+#define PA_PERIPHERAL 0xB0000000
+
+#define PA_PCIC PA_PERIPHERAL /* MR-SHPC-01 PCMCIA */
+#define PA_MRSHPC (PA_PERIPHERAL + 0x003fffe0) /* MR-SHPC-01 PCMCIA controller */
+#define PA_MRSHPC_MW1 (PA_PERIPHERAL + 0x00400000) /* MR-SHPC-01 memory window base */
+#define PA_MRSHPC_MW2 (PA_PERIPHERAL + 0x00500000) /* MR-SHPC-01 attribute window base */
+#define PA_MRSHPC_IO (PA_PERIPHERAL + 0x00600000) /* MR-SHPC-01 I/O window base */
+#define MRSHPC_OPTION (PA_MRSHPC + 6)
+#define MRSHPC_CSR (PA_MRSHPC + 8)
+#define MRSHPC_ISR (PA_MRSHPC + 10)
+#define MRSHPC_ICR (PA_MRSHPC + 12)
+#define MRSHPC_CPWCR (PA_MRSHPC + 14)
+#define MRSHPC_MW0CR1 (PA_MRSHPC + 16)
+#define MRSHPC_MW1CR1 (PA_MRSHPC + 18)
+#define MRSHPC_IOWCR1 (PA_MRSHPC + 20)
+#define MRSHPC_MW0CR2 (PA_MRSHPC + 22)
+#define MRSHPC_MW1CR2 (PA_MRSHPC + 24)
+#define MRSHPC_IOWCR2 (PA_MRSHPC + 26)
+#define MRSHPC_CDCR (PA_MRSHPC + 28)
+#define MRSHPC_PCIC_INFO (PA_MRSHPC + 30)
+
+#define PA_LED (PA_PERIPHERAL + 0x00800000) /* 8bit LED */
+#define PA_FPGA (PA_PERIPHERAL + 0x01800000) /* FPGA base address */
+
+#define PA_LAN (PA_AREA6_IO + 0) /* SMC LAN91C111 */
+/* GPIO */
+#define MSTPCR0 0xA4150030UL
+#define MSTPCR1 0xA4150034UL
+#define MSTPCR2 0xA4150038UL
+
+#define FPGA_IN 0xb1840000UL
+#define FPGA_OUT 0xb1840004UL
+
+#define PORT_PECR 0xA4050108UL
+#define PORT_PJCR 0xA4050110UL
+#define PORT_PSELD 0xA4050154UL
+#define PORT_PSELB 0xA4050150UL
+
+#define PORT_PSELC 0xA4050152UL
+#define PORT_PKCR 0xA4050112UL
+#define PORT_PHCR 0xA405010EUL
+#define PORT_PLCR 0xA4050114UL
+#define PORT_PMCR 0xA4050116UL
+#define PORT_PRCR 0xA405011CUL
+#define PORT_PXCR 0xA4050148UL
+#define PORT_PSELA 0xA405014EUL
+#define PORT_PYCR 0xA405014AUL
+#define PORT_PZCR 0xA405014CUL
+
+/* IRQ */
+#define IRQ0_IRQ 32
+#define IRQ1_IRQ 33
+#define INTC_ICR0 0xA4140000UL
+#define INTC_ICR1 0xA414001CUL
+
+#define INTMSK0 0xa4140044
+#define INTMSKCLR0 0xa4140064
+#define INTC_INTPRI0 0xa4140010
+
+#define IRQ01_MODE 0xb1800000
+#define IRQ01_STS 0xb1800004
+#define IRQ01_MASK 0xb1800008
+#define EXT_BIT (0x3fc0) /* SH IRQ1 */
+#define MRSHPC_BIT0 (0x0004) /* SH IRQ1 */
+#define MRSHPC_BIT1 (0x0008) /* SH IRQ1 */
+#define MRSHPC_BIT2 (0x0010) /* SH IRQ1 */
+#define MRSHPC_BIT3 (0x0020) /* SH IRQ1 */
+#define SMC_BIT (0x0002) /* SH IRQ0 */
+#define USB_BIT (0x0001) /* SH IRQ0 */
+
+#define MRSHPC_IRQ3 11
+#define MRSHPC_IRQ2 12
+#define MRSHPC_IRQ1 13
+#define MRSHPC_IRQ0 14
+#define SMC_IRQ 10
+#define EXT_IRQ 5
+#define USB_IRQ 6
+
+
+/* arch/sh/boards/se/7722/irq.c */
+void init_se7722_IRQ(void);
+int se7722_irq_demux(int);
+
+#define __IO_PREFIX se7722
+#include <asm/io_generic.h>
+
+#endif /* __ASM_SH_SE7722_H */
diff --git a/include/asm-sh/se7751.h b/include/asm-sh/se7751.h
index 88cd379..02ca934 100644
--- a/include/asm-sh/se7751.h
+++ b/include/asm-sh/se7751.h
@@ -65,6 +65,8 @@
#define IRQ_79C973 13
+void init_7751se_IRQ(void);
+
#define __IO_PREFIX sh7751se
#include <asm/io_generic.h>
diff --git a/include/asm-sh/se7780.h b/include/asm-sh/se7780.h
new file mode 100644
index 0000000..40e9b41
--- /dev/null
+++ b/include/asm-sh/se7780.h
@@ -0,0 +1,108 @@
+#ifndef __ASM_SH_SE7780_H
+#define __ASM_SH_SE7780_H
+
+/*
+ * linux/include/asm-sh/se7780.h
+ *
+ * Copyright (C) 2006,2007 Nobuhiro Iwamatsu
+ *
+ * Hitachi UL SolutionEngine 7780 Support.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <asm/addrspace.h>
+
+/* Box specific addresses. */
+#define SE_AREA0_WIDTH 4 /* Area0: 32bit */
+#define PA_ROM 0xa0000000 /* EPROM */
+#define PA_ROM_SIZE 0x00400000 /* EPROM size 4M byte */
+#define PA_FROM 0xa1000000 /* Flash-ROM */
+#define PA_FROM_SIZE 0x01000000 /* Flash-ROM size 16M byte */
+#define PA_EXT1 0xa4000000
+#define PA_EXT1_SIZE 0x04000000
+#define PA_SM501 PA_EXT1 /* Graphic IC (SM501) */
+#define PA_SM501_SIZE PA_EXT1_SIZE /* Graphic IC (SM501) */
+#define PA_SDRAM 0xa8000000 /* DDR-SDRAM(Area2/3) 128MB */
+#define PA_SDRAM_SIZE 0x08000000
+
+#define PA_EXT4 0xb0000000
+#define PA_EXT4_SIZE 0x04000000
+#define PA_EXT_FLASH PA_EXT4 /* Expansion Flash-ROM */
+
+#define PA_PERIPHERAL PA_AREA6_IO /* SW6-6=ON */
+
+#define PA_LAN (PA_PERIPHERAL + 0) /* SMC LAN91C111 */
+#define PA_LED_DISP (PA_PERIPHERAL + 0x02000000) /* 8words LED Display */
+#define DISP_CHAR_RAM (7 << 3)
+#define DISP_SEL0_ADDR (DISP_CHAR_RAM + 0)
+#define DISP_SEL1_ADDR (DISP_CHAR_RAM + 1)
+#define DISP_SEL2_ADDR (DISP_CHAR_RAM + 2)
+#define DISP_SEL3_ADDR (DISP_CHAR_RAM + 3)
+#define DISP_SEL4_ADDR (DISP_CHAR_RAM + 4)
+#define DISP_SEL5_ADDR (DISP_CHAR_RAM + 5)
+#define DISP_SEL6_ADDR (DISP_CHAR_RAM + 6)
+#define DISP_SEL7_ADDR (DISP_CHAR_RAM + 7)
+
+#define DISP_UDC_RAM (5 << 3)
+#define PA_FPGA (PA_PERIPHERAL + 0x03000000) /* FPGA base address */
+
+/* FPGA register address and bit */
+#define FPGA_SFTRST (PA_FPGA + 0) /* Soft reset register */
+#define FPGA_INTMSK1 (PA_FPGA + 2) /* Interrupt Mask register 1 */
+#define FPGA_INTMSK2 (PA_FPGA + 4) /* Interrupt Mask register 2 */
+#define FPGA_INTSEL1 (PA_FPGA + 6) /* Interrupt select register 1 */
+#define FPGA_INTSEL2 (PA_FPGA + 8) /* Interrupt select register 2 */
+#define FPGA_INTSEL3 (PA_FPGA + 10) /* Interrupt select register 3 */
+#define FPGA_PCI_INTSEL1 (PA_FPGA + 12) /* PCI Interrupt select register 1 */
+#define FPGA_PCI_INTSEL2 (PA_FPGA + 14) /* PCI Interrupt select register 2 */
+#define FPGA_INTSET (PA_FPGA + 16) /* IRQ/IRL select register */
+#define FPGA_INTSTS1 (PA_FPGA + 18) /* Interrupt status register 1 */
+#define FPGA_INTSTS2 (PA_FPGA + 20) /* Interrupt status register 2 */
+#define FPGA_REQSEL (PA_FPGA + 22) /* REQ/GNT select register */
+#define FPGA_DBG_LED (PA_FPGA + 32) /* Debug LED(D-LED[8:1] */
+#define PA_LED FPGA_DBG_LED
+#define FPGA_IVDRID (PA_FPGA + 36) /* iVDR ID Register */
+#define FPGA_IVDRPW (PA_FPGA + 38) /* iVDR Power ON Register */
+#define FPGA_MMCID (PA_FPGA + 40) /* MMC ID Register */
+
+/* FPGA INTSEL position */
+/* INTSEL1 */
+#define IRQPOS_SMC91CX (0 * 4)
+#define IRQPOS_SM501 (1 * 4)
+/* INTSEL2 */
+#define IRQPOS_EXTINT1 (0 * 4)
+#define IRQPOS_EXTINT2 (1 * 4)
+#define IRQPOS_EXTINT3 (2 * 4)
+#define IRQPOS_EXTINT4 (3 * 4)
+/* INTSEL3 */
+#define IRQPOS_PCCPW (0 * 4)
+
+/* IDE interrupt */
+#define IRQ_IDE0 67 /* iVDR */
+
+/* SMC interrupt */
+#define SMC_IRQ 8
+
+/* SM501 interrupt */
+#define SM501_IRQ 0
+
+/* interrupt pin */
+#define IRQPIN_EXTINT1 0 /* IRQ0 pin */
+#define IRQPIN_EXTINT2 1 /* IRQ1 pin */
+#define IRQPIN_EXTINT3 2 /* IRQ2 pin */
+#define IRQPIN_SMC91CX 3 /* IRQ3 pin */
+#define IRQPIN_EXTINT4 4 /* IRQ4 pin */
+#define IRQPIN_PCC0 5 /* IRQ5 pin */
+#define IRQPIN_PCC2 6 /* IRQ6 pin */
+#define IRQPIN_SM501 7 /* IRQ7 pin */
+#define IRQPIN_PCCPW 7 /* IRQ7 pin */
+
+/* arch/sh/boards/se/7780/irq.c */
+void init_se7780_IRQ(void);
+
+#define __IO_PREFIX se7780
+#include <asm/io_generic.h>
+
+#endif /* __ASM_SH_SE7780_H */
diff --git a/include/asm-sh/stat.h b/include/asm-sh/stat.h
index 6c41a60..6d6ad26 100644
--- a/include/asm-sh/stat.h
+++ b/include/asm-sh/stat.h
@@ -16,15 +16,13 @@ struct __old_kernel_stat {
};
struct stat {
- unsigned short st_dev;
- unsigned short __pad1;
- unsigned long st_ino;
+ unsigned long st_dev;
+ unsigned long st_ino;
unsigned short st_mode;
unsigned short st_nlink;
unsigned short st_uid;
unsigned short st_gid;
- unsigned short st_rdev;
- unsigned short __pad2;
+ unsigned long st_rdev;
unsigned long st_size;
unsigned long st_blksize;
unsigned long st_blocks;
@@ -38,8 +36,6 @@ struct stat {
unsigned long __unused5;
};
-#define STAT_HAVE_NSEC 1
-
/* This matches struct stat64 in glibc2.1, hence the absolutely
* insane amounts of padding around dev_t's.
*/
@@ -47,7 +43,9 @@ struct stat64 {
unsigned long long st_dev;
unsigned char __pad0[4];
- unsigned long st_ino;
+#define STAT64_HAS_BROKEN_ST_INO 1
+ unsigned long __st_ino;
+
unsigned int st_mode;
unsigned int st_nlink;
@@ -71,8 +69,9 @@ struct stat64 {
unsigned long st_ctime;
unsigned long st_ctime_nsec;
- unsigned long __unused1;
- unsigned long __unused2;
+ unsigned long long st_ino;
};
+#define STAT_HAVE_NSEC 1
+
#endif /* __ASM_SH_STAT_H */
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index 4a6a19f..e7e96ee 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -9,6 +9,7 @@
#include <linux/irqflags.h>
#include <linux/compiler.h>
#include <asm/types.h>
+#include <asm/ptrace.h>
/*
* switch_to() should switch tasks to task nr n, first
@@ -81,16 +82,6 @@ static inline void sched_cacheflush(void)
}
#endif
-static inline unsigned long tas(volatile int *m)
-{
- unsigned long retval;
-
- __asm__ __volatile__ ("tas.b @%1\n\t"
- "movt %0"
- : "=r" (retval): "r" (m): "t", "memory");
- return retval;
-}
-
/*
* A brief note on ctrl_barrier(), the control register write barrier.
*
@@ -255,6 +246,8 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
(unsigned long)_n_, sizeof(*(ptr))); \
})
+extern void die(const char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn));
+
extern void *set_exception_table_vec(unsigned int vec, void *handler);
static inline void *set_exception_table_evt(unsigned int evt, void *handler)
diff --git a/include/asm-sh64/kdebug.h b/include/asm-sh64/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-sh64/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-sh64/pgtable.h b/include/asm-sh64/pgtable.h
index 6b97c4c..b875482 100644
--- a/include/asm-sh64/pgtable.h
+++ b/include/asm-sh64/pgtable.h
@@ -485,10 +485,6 @@ extern void update_mmu_cache(struct vm_area_struct * vma,
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#endif /* !__ASSEMBLY__ */
/*
diff --git a/include/asm-sh64/system.h b/include/asm-sh64/system.h
index b1598c2..5ff9464 100644
--- a/include/asm-sh64/system.h
+++ b/include/asm-sh64/system.h
@@ -43,8 +43,6 @@ extern struct task_struct *sh64_switch_to(struct task_struct *prev,
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr), 1))
-
extern void __xchg_called_with_bad_pointer(void);
#define mb() __asm__ __volatile__ ("synco": : :"memory")
diff --git a/include/asm-sparc/kdebug.h b/include/asm-sparc/kdebug.h
index fba9248..404d807 100644
--- a/include/asm-sparc/kdebug.h
+++ b/include/asm-sparc/kdebug.h
@@ -66,4 +66,8 @@ static inline void sp_enter_debugger(void)
#define KDEBUG_DUNNO2_OFF 0x8
#define KDEBUG_TEACH_OFF 0xc
+enum die_val {
+ DIE_UNUSED,
+};
+
#endif /* !(_SPARC_KDEBUG_H) */
diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h
index 100c3ea..8b6d9c9 100644
--- a/include/asm-sparc/system.h
+++ b/include/asm-sparc/system.h
@@ -241,7 +241,6 @@ static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned lon
}
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
extern void __xchg_called_with_bad_pointer(void);
diff --git a/include/asm-sparc64/Kbuild b/include/asm-sparc64/Kbuild
index a7f4440..854fd3a 100644
--- a/include/asm-sparc64/Kbuild
+++ b/include/asm-sparc64/Kbuild
@@ -8,7 +8,6 @@ header-y += apb.h
header-y += asi.h
header-y += bbc.h
header-y += bpp.h
-header-y += const.h
header-y += display7seg.h
header-y += envctrl.h
header-y += ipc.h
diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h
index 2f0bec2..3fb4e1f 100644
--- a/include/asm-sparc64/atomic.h
+++ b/include/asm-sparc64/atomic.h
@@ -9,6 +9,7 @@
#define __ARCH_SPARC64_ATOMIC__
#include <linux/types.h>
+#include <asm/system.h>
typedef struct { volatile int counter; } atomic_t;
typedef struct { volatile __s64 counter; } atomic64_t;
@@ -70,25 +71,47 @@ extern int atomic64_sub_ret(int, atomic64_t *);
#define atomic_add_negative(i, v) (atomic_add_ret(i, v) < 0)
#define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0)
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- for (;;) { \
- if (unlikely(c == (u))) \
- break; \
- old = atomic_cmpxchg((v), c, c + (a)); \
- if (likely(old == c)) \
- break; \
- c = old; \
- } \
- likely(c != (u)); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+#define atomic64_cmpxchg(v, o, n) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+ long c, old;
+ c = atomic64_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic64_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
/* Atomic operations are already serializing */
#ifdef CONFIG_SMP
#define smp_mb__before_atomic_dec() membar_storeload_loadload();
diff --git a/include/asm-sparc64/const.h b/include/asm-sparc64/const.h
deleted file mode 100644
index 8ad902b..0000000
--- a/include/asm-sparc64/const.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* const.h: Macros for dealing with constants. */
-
-#ifndef _SPARC64_CONST_H
-#define _SPARC64_CONST_H
-
-/* Some constant macros are used in both assembler and
- * C code. Therefore we cannot annotate them always with
- * 'UL' and other type specificers unilaterally. We
- * use the following macros to deal with this.
- */
-
-#ifdef __ASSEMBLY__
-#define _AC(X,Y) X
-#else
-#define _AC(X,Y) (X##Y)
-#endif
-
-
-#endif /* !(_SPARC64_CONST_H) */
diff --git a/include/asm-sparc64/iommu.h b/include/asm-sparc64/iommu.h
index e199594..0b1813f 100644
--- a/include/asm-sparc64/iommu.h
+++ b/include/asm-sparc64/iommu.h
@@ -32,6 +32,7 @@ struct iommu {
unsigned long iommu_control;
unsigned long iommu_tsbbase;
unsigned long iommu_flush;
+ unsigned long iommu_flushinv;
unsigned long iommu_ctxflush;
unsigned long write_complete_reg;
unsigned long dummy_page;
diff --git a/include/asm-sparc64/kdebug.h b/include/asm-sparc64/kdebug.h
index 11251bd..f8032e7 100644
--- a/include/asm-sparc64/kdebug.h
+++ b/include/asm-sparc64/kdebug.h
@@ -7,19 +7,8 @@
struct pt_regs;
-struct die_args {
- struct pt_regs *regs;
- const char *str;
- long err;
- int trapnr;
- int signr;
-};
-
-extern int register_die_notifier(struct notifier_block *);
-extern int unregister_die_notifier(struct notifier_block *);
extern int register_page_fault_notifier(struct notifier_block *);
extern int unregister_page_fault_notifier(struct notifier_block *);
-extern struct atomic_notifier_head sparc64die_chain;
extern void bad_trap(struct pt_regs *, long);
@@ -36,16 +25,4 @@ enum die_val {
DIE_PAGE_FAULT,
};
-static inline int notify_die(enum die_val val,char *str, struct pt_regs *regs,
- long err, int trap, int sig)
-{
- struct die_args args = { .regs = regs,
- .str = str,
- .err = err,
- .trapnr = trap,
- .signr = sig };
-
- return atomic_notifier_call_chain(&sparc64die_chain, val, &args);
-}
-
#endif
diff --git a/include/asm-sparc64/local.h b/include/asm-sparc64/local.h
index dfde115a..c11c530 100644
--- a/include/asm-sparc64/local.h
+++ b/include/asm-sparc64/local.h
@@ -1,40 +1 @@
-#ifndef _ARCH_SPARC64_LOCAL_H
-#define _ARCH_SPARC64_LOCAL_H
-
-#include <linux/percpu.h>
-#include <asm/atomic.h>
-
-typedef atomic64_t local_t;
-
-#define LOCAL_INIT(i) ATOMIC64_INIT(i)
-#define local_read(v) atomic64_read(v)
-#define local_set(v,i) atomic64_set(v,i)
-
-#define local_inc(v) atomic64_inc(v)
-#define local_dec(v) atomic64_dec(v)
-#define local_add(i, v) atomic64_add(i, v)
-#define local_sub(i, v) atomic64_sub(i, v)
-
-#define __local_inc(v) ((v)->counter++)
-#define __local_dec(v) ((v)->counter--)
-#define __local_add(i,v) ((v)->counter+=(i))
-#define __local_sub(i,v) ((v)->counter-=(i))
-
-/* Use these for per-cpu local_t variables: on some archs they are
- * much more efficient than these naive implementations. Note they take
- * a variable, not an address.
- */
-#define cpu_local_read(v) local_read(&__get_cpu_var(v))
-#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i))
-
-#define cpu_local_inc(v) local_inc(&__get_cpu_var(v))
-#define cpu_local_dec(v) local_dec(&__get_cpu_var(v))
-#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v))
-#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v))
-
-#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v))
-#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v))
-#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v))
-#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v))
-
-#endif /* _ARCH_SPARC64_LOCAL_H */
+#include <asm-generic/local.h>
diff --git a/include/asm-sparc64/lsu.h b/include/asm-sparc64/lsu.h
index e5329c7..79f1098 100644
--- a/include/asm-sparc64/lsu.h
+++ b/include/asm-sparc64/lsu.h
@@ -2,7 +2,7 @@
#ifndef _SPARC64_LSU_H
#define _SPARC64_LSU_H
-#include <asm/const.h>
+#include <linux/const.h>
/* LSU Control Register */
#define LSU_CONTROL_PM _AC(0x000001fe00000000,UL) /* Phys-watchpoint byte mask*/
diff --git a/include/asm-sparc64/mmu.h b/include/asm-sparc64/mmu.h
index 70af4b6..8abc58f 100644
--- a/include/asm-sparc64/mmu.h
+++ b/include/asm-sparc64/mmu.h
@@ -1,8 +1,8 @@
#ifndef __MMU_H
#define __MMU_H
+#include <linux/const.h>
#include <asm/page.h>
-#include <asm/const.h>
#include <asm/hypervisor.h>
#define CTX_NR_BITS 13
diff --git a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h
index ff736ea..7af1077 100644
--- a/include/asm-sparc64/page.h
+++ b/include/asm-sparc64/page.h
@@ -5,7 +5,7 @@
#ifdef __KERNEL__
-#include <asm/const.h>
+#include <linux/const.h>
#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
#define PAGE_SHIFT 13
diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h
index 5891ff7..5d66b85 100644
--- a/include/asm-sparc64/pgalloc.h
+++ b/include/asm-sparc64/pgalloc.h
@@ -6,6 +6,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/slab.h>
+#include <linux/quicklist.h>
#include <asm/spitfire.h>
#include <asm/cpudata.h>
@@ -13,52 +14,50 @@
#include <asm/page.h>
/* Page table allocation/freeing. */
-extern struct kmem_cache *pgtable_cache;
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
{
- return kmem_cache_alloc(pgtable_cache, GFP_KERNEL);
+ return quicklist_alloc(0, GFP_KERNEL, NULL);
}
static inline void pgd_free(pgd_t *pgd)
{
- kmem_cache_free(pgtable_cache, pgd);
+ quicklist_free(0, NULL, pgd);
}
#define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD)
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{
- return kmem_cache_alloc(pgtable_cache,
- GFP_KERNEL|__GFP_REPEAT);
+ return quicklist_alloc(0, GFP_KERNEL, NULL);
}
static inline void pmd_free(pmd_t *pmd)
{
- kmem_cache_free(pgtable_cache, pmd);
+ quicklist_free(0, NULL, pmd);
}
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long address)
{
- return kmem_cache_alloc(pgtable_cache,
- GFP_KERNEL|__GFP_REPEAT);
+ return quicklist_alloc(0, GFP_KERNEL, NULL);
}
static inline struct page *pte_alloc_one(struct mm_struct *mm,
unsigned long address)
{
- return virt_to_page(pte_alloc_one_kernel(mm, address));
+ void *pg = quicklist_alloc(0, GFP_KERNEL, NULL);
+ return pg ? virt_to_page(pg) : NULL;
}
static inline void pte_free_kernel(pte_t *pte)
{
- kmem_cache_free(pgtable_cache, pte);
+ quicklist_free(0, NULL, pte);
}
static inline void pte_free(struct page *ptepage)
{
- pte_free_kernel(page_address(ptepage));
+ quicklist_free_page(0, NULL, ptepage);
}
@@ -66,6 +65,9 @@ static inline void pte_free(struct page *ptepage)
#define pmd_populate(MM,PMD,PTE_PAGE) \
pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE))
-#define check_pgt_cache() do { } while (0)
+static inline void check_pgt_cache(void)
+{
+ quicklist_trim(0, NULL, 25, 16);
+}
#endif /* _SPARC64_PGALLOC_H */
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index 46705ef..9e80ad4 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -15,13 +15,13 @@
#include <asm-generic/pgtable-nopud.h>
#include <linux/compiler.h>
+#include <linux/const.h>
#include <asm/types.h>
#include <asm/spitfire.h>
#include <asm/asi.h>
#include <asm/system.h>
#include <asm/page.h>
#include <asm/processor.h>
-#include <asm/const.h>
/* The kernel image occupies 0x4000000 to 0x1000000 (4MB --> 32MB).
* The page copy blockops can use 0x2000000 to 0x4000000.
diff --git a/include/asm-sparc64/pstate.h b/include/asm-sparc64/pstate.h
index 49a7924..f3c4548 100644
--- a/include/asm-sparc64/pstate.h
+++ b/include/asm-sparc64/pstate.h
@@ -2,7 +2,7 @@
#ifndef _SPARC64_PSTATE_H
#define _SPARC64_PSTATE_H
-#include <asm/const.h>
+#include <linux/const.h>
/* The V9 PSTATE Register (with SpitFire extensions).
*
diff --git a/include/asm-sparc64/sfafsr.h b/include/asm-sparc64/sfafsr.h
index 2f792c2..e96137b 100644
--- a/include/asm-sparc64/sfafsr.h
+++ b/include/asm-sparc64/sfafsr.h
@@ -1,7 +1,7 @@
#ifndef _SPARC64_SFAFSR_H
#define _SPARC64_SFAFSR_H
-#include <asm/const.h>
+#include <linux/const.h>
/* Spitfire Asynchronous Fault Status register, ASI=0x4C VA<63:0>=0x0 */
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index 32281ac..8ba380e 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -253,7 +253,6 @@ static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long
}
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
extern void __xchg_called_with_bad_pointer(void);
diff --git a/include/asm-um/cmpxchg.h b/include/asm-um/cmpxchg.h
new file mode 100644
index 0000000..529376a
--- /dev/null
+++ b/include/asm-um/cmpxchg.h
@@ -0,0 +1,6 @@
+#ifndef __UM_CMPXCHG_H
+#define __UM_CMPXCHG_H
+
+#include "asm/arch/cmpxchg.h"
+
+#endif
diff --git a/include/asm-um/kdebug.h b/include/asm-um/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-um/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-um/page.h b/include/asm-um/page.h
index 4296d31..8e310d8 100644
--- a/include/asm-um/page.h
+++ b/include/asm-um/page.h
@@ -114,9 +114,6 @@ extern unsigned long uml_physmem;
extern struct page *arch_validate(struct page *page, gfp_t mask, int order);
#define HAVE_ARCH_VALIDATE
-extern void arch_free_page(struct page *page, int order);
-#define HAVE_ARCH_FREE_PAGE
-
#include <asm-generic/memory_model.h>
#include <asm-generic/page.h>
diff --git a/include/asm-um/tlbflush.h b/include/asm-um/tlbflush.h
index 522aa30..e78c28c 100644
--- a/include/asm-um/tlbflush.h
+++ b/include/asm-um/tlbflush.h
@@ -7,6 +7,7 @@
#define __UM_TLBFLUSH_H
#include <linux/mm.h>
+#include "choose-mode.h"
/*
* TLB flushing:
@@ -24,6 +25,18 @@ extern void flush_tlb_all(void);
extern void flush_tlb_mm(struct mm_struct *mm);
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
+extern void flush_tlb_page_skas(struct vm_area_struct *vma,
+ unsigned long address);
+
+static inline void flush_tlb_page(struct vm_area_struct *vma,
+ unsigned long address)
+{
+ address &= PAGE_MASK;
+
+ CHOOSE_MODE(flush_tlb_range(vma, address, address + PAGE_SIZE),
+ flush_tlb_page_skas(vma, address));
+}
+
extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
extern void flush_tlb_kernel_vm(void);
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
@@ -35,14 +48,3 @@ static inline void flush_tlb_pgtables(struct mm_struct *mm,
}
#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/include/asm-v850/kdebug.h b/include/asm-v850/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-v850/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-v850/system.h b/include/asm-v850/system.h
index da39916..0de2481 100644
--- a/include/asm-v850/system.h
+++ b/include/asm-v850/system.h
@@ -76,7 +76,6 @@ static inline int irqs_disabled (void)
#define xchg(ptr, with) \
((__typeof__ (*(ptr)))__xchg ((unsigned long)(with), (ptr), sizeof (*(ptr))))
-#define tas(ptr) (xchg ((ptr), 1))
static inline unsigned long __xchg (unsigned long with,
__volatile__ void *ptr, int size)
diff --git a/include/asm-x86_64/Kbuild b/include/asm-x86_64/Kbuild
index 89ad1fc..75a2def 100644
--- a/include/asm-x86_64/Kbuild
+++ b/include/asm-x86_64/Kbuild
@@ -19,4 +19,3 @@ unifdef-y += mce.h
unifdef-y += msr.h
unifdef-y += mtrr.h
unifdef-y += vsyscall.h
-unifdef-y += const.h
diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86_64/atomic.h
index 706ca4b..f2e6463 100644
--- a/include/asm-x86_64/atomic.h
+++ b/include/asm-x86_64/atomic.h
@@ -2,6 +2,7 @@
#define __ARCH_X86_64_ATOMIC__
#include <asm/alternative.h>
+#include <asm/cmpxchg.h>
/* atomic_t should be 32 bit signed type */
@@ -375,8 +376,8 @@ static __inline__ long atomic64_add_return(long i, atomic64_t *v)
long __i = i;
__asm__ __volatile__(
LOCK_PREFIX "xaddq %0, %1;"
- :"=r"(i)
- :"m"(v->counter), "0"(i));
+ :"+r" (i), "+m" (v->counter)
+ : : "memory");
return i + __i;
}
@@ -388,7 +389,10 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t *v)
#define atomic64_inc_return(v) (atomic64_add_return(1,v))
#define atomic64_dec_return(v) (atomic64_sub_return(1,v))
-#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+#define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
/**
@@ -400,22 +404,49 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t *v)
* Atomically adds @a to @v, so long as it was not @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- for (;;) { \
- if (unlikely(c == (u))) \
- break; \
- old = atomic_cmpxchg((v), c, c + (a)); \
- if (likely(old == c)) \
- break; \
- c = old; \
- } \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+ long c, old;
+ c = atomic64_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic64_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
/* These are x86-specific, used by some header files */
#define atomic_clear_mask(mask, addr) \
__asm__ __volatile__(LOCK_PREFIX "andl %0,%1" \
diff --git a/include/asm-x86_64/cmpxchg.h b/include/asm-x86_64/cmpxchg.h
new file mode 100644
index 0000000..09a6b6b
--- /dev/null
+++ b/include/asm-x86_64/cmpxchg.h
@@ -0,0 +1,134 @@
+#ifndef __ASM_CMPXCHG_H
+#define __ASM_CMPXCHG_H
+
+#include <asm/alternative.h> /* Provides LOCK_PREFIX */
+
+#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
+
+#define __xg(x) ((volatile long *)(x))
+
+static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
+{
+ *ptr = val;
+}
+
+#define _set_64bit set_64bit
+
+/*
+ * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
+ * Note 2: xchg has side effect, so that attribute volatile is necessary,
+ * but generally the primitive is invalid, *ptr is output argument. --ANK
+ */
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+ switch (size) {
+ case 1:
+ __asm__ __volatile__("xchgb %b0,%1"
+ :"=q" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
+ break;
+ case 2:
+ __asm__ __volatile__("xchgw %w0,%1"
+ :"=r" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
+ break;
+ case 4:
+ __asm__ __volatile__("xchgl %k0,%1"
+ :"=r" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
+ break;
+ case 8:
+ __asm__ __volatile__("xchgq %0,%1"
+ :"=r" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
+ break;
+ }
+ return x;
+}
+
+/*
+ * Atomic compare and exchange. Compare OLD with MEM, if identical,
+ * store NEW in MEM. Return the initial value in MEM. Success is
+ * indicated by comparing RETURN with OLD.
+ */
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+ unsigned long new, int size)
+{
+ unsigned long prev;
+ switch (size) {
+ case 1:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
+ : "=a"(prev)
+ : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 2:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 4:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %k1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 8:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgq %1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ }
+ return old;
+}
+
+static inline unsigned long __cmpxchg_local(volatile void *ptr,
+ unsigned long old, unsigned long new, int size)
+{
+ unsigned long prev;
+ switch (size) {
+ case 1:
+ __asm__ __volatile__("cmpxchgb %b1,%2"
+ : "=a"(prev)
+ : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 2:
+ __asm__ __volatile__("cmpxchgw %w1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 4:
+ __asm__ __volatile__("cmpxchgl %k1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 8:
+ __asm__ __volatile__("cmpxchgq %1,%2"
+ : "=a"(prev)
+ : "r"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ }
+ return old;
+}
+
+#define cmpxchg(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
+ (unsigned long)(n),sizeof(*(ptr))))
+#define cmpxchg_local(ptr,o,n)\
+ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
+ (unsigned long)(n),sizeof(*(ptr))))
+
+#endif
diff --git a/include/asm-x86_64/kdebug.h b/include/asm-x86_64/kdebug.h
index 2b0c088..74feae9 100644
--- a/include/asm-x86_64/kdebug.h
+++ b/include/asm-x86_64/kdebug.h
@@ -5,19 +5,8 @@
struct pt_regs;
-struct die_args {
- struct pt_regs *regs;
- const char *str;
- long err;
- int trapnr;
- int signr;
-};
-
-extern int register_die_notifier(struct notifier_block *);
-extern int unregister_die_notifier(struct notifier_block *);
extern int register_page_fault_notifier(struct notifier_block *);
extern int unregister_page_fault_notifier(struct notifier_block *);
-extern struct atomic_notifier_head die_chain;
/* Grossly misnamed. */
enum die_val {
@@ -33,22 +22,10 @@ enum die_val {
DIE_GPF,
DIE_CALL,
DIE_NMI_IPI,
+ DIE_NMI_POST,
DIE_PAGE_FAULT,
};
-static inline int notify_die(enum die_val val, const char *str,
- struct pt_regs *regs, long err, int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .str = str,
- .err = err,
- .trapnr = trap,
- .signr = sig
- };
- return atomic_notifier_call_chain(&die_chain, val, &args);
-}
-
extern void printk_address(unsigned long address);
extern void die(const char *,struct pt_regs *,long);
extern void __die(const char *,struct pt_regs *,long);
diff --git a/include/asm-x86_64/kexec.h b/include/asm-x86_64/kexec.h
index 5fab957..738e581 100644
--- a/include/asm-x86_64/kexec.h
+++ b/include/asm-x86_64/kexec.h
@@ -48,8 +48,6 @@
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_X86_64
-#define MAX_NOTE_BYTES 1024
-
/*
* Saving the registers of the cpu on which panic occured in
* crash_kexec to save a valid sp. The registers of other cpus
diff --git a/include/asm-x86_64/local.h b/include/asm-x86_64/local.h
index e769e62..e87492b 100644
--- a/include/asm-x86_64/local.h
+++ b/include/asm-x86_64/local.h
@@ -2,49 +2,183 @@
#define _ARCH_X8664_LOCAL_H
#include <linux/percpu.h>
+#include <asm/atomic.h>
typedef struct
{
- volatile long counter;
+ atomic_long_t a;
} local_t;
-#define LOCAL_INIT(i) { (i) }
+#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
-#define local_read(v) ((v)->counter)
-#define local_set(v,i) (((v)->counter) = (i))
+#define local_read(l) atomic_long_read(&(l)->a)
+#define local_set(l,i) atomic_long_set(&(l)->a, (i))
-static inline void local_inc(local_t *v)
+static inline void local_inc(local_t *l)
{
__asm__ __volatile__(
"incq %0"
- :"=m" (v->counter)
- :"m" (v->counter));
+ :"=m" (l->a.counter)
+ :"m" (l->a.counter));
}
-static inline void local_dec(local_t *v)
+static inline void local_dec(local_t *l)
{
__asm__ __volatile__(
"decq %0"
- :"=m" (v->counter)
- :"m" (v->counter));
+ :"=m" (l->a.counter)
+ :"m" (l->a.counter));
}
-static inline void local_add(long i, local_t *v)
+static inline void local_add(long i, local_t *l)
{
__asm__ __volatile__(
"addq %1,%0"
- :"=m" (v->counter)
- :"ir" (i), "m" (v->counter));
+ :"=m" (l->a.counter)
+ :"ir" (i), "m" (l->a.counter));
}
-static inline void local_sub(long i, local_t *v)
+static inline void local_sub(long i, local_t *l)
{
__asm__ __volatile__(
"subq %1,%0"
- :"=m" (v->counter)
- :"ir" (i), "m" (v->counter));
+ :"=m" (l->a.counter)
+ :"ir" (i), "m" (l->a.counter));
}
+/**
+ * local_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @l: pointer to type local_t
+ *
+ * Atomically subtracts @i from @l and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+static __inline__ int local_sub_and_test(long i, local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "subq %2,%0; sete %1"
+ :"=m" (l->a.counter), "=qm" (c)
+ :"ir" (i), "m" (l->a.counter) : "memory");
+ return c;
+}
+
+/**
+ * local_dec_and_test - decrement and test
+ * @l: pointer to type local_t
+ *
+ * Atomically decrements @l by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+static __inline__ int local_dec_and_test(local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "decq %0; sete %1"
+ :"=m" (l->a.counter), "=qm" (c)
+ :"m" (l->a.counter) : "memory");
+ return c != 0;
+}
+
+/**
+ * local_inc_and_test - increment and test
+ * @l: pointer to type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+static __inline__ int local_inc_and_test(local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "incq %0; sete %1"
+ :"=m" (l->a.counter), "=qm" (c)
+ :"m" (l->a.counter) : "memory");
+ return c != 0;
+}
+
+/**
+ * local_add_negative - add and test if negative
+ * @i: integer value to add
+ * @l: pointer to type local_t
+ *
+ * Atomically adds @i to @l and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+static __inline__ int local_add_negative(long i, local_t *l)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ "addq %2,%0; sets %1"
+ :"=m" (l->a.counter), "=qm" (c)
+ :"ir" (i), "m" (l->a.counter) : "memory");
+ return c;
+}
+
+/**
+ * local_add_return - add and return
+ * @i: integer value to add
+ * @l: pointer to type local_t
+ *
+ * Atomically adds @i to @l and returns @i + @l
+ */
+static __inline__ long local_add_return(long i, local_t *l)
+{
+ long __i = i;
+ __asm__ __volatile__(
+ "xaddq %0, %1;"
+ :"+r" (i), "+m" (l->a.counter)
+ : : "memory");
+ return i + __i;
+}
+
+static __inline__ long local_sub_return(long i, local_t *l)
+{
+ return local_add_return(-i,l);
+}
+
+#define local_inc_return(l) (local_add_return(1,l))
+#define local_dec_return(l) (local_sub_return(1,l))
+
+#define local_cmpxchg(l, o, n) \
+ (cmpxchg_local(&((l)->a.counter), (o), (n)))
+/* Always has a lock prefix */
+#define local_xchg(l, n) (xchg(&((l)->a.counter), (n)))
+
+/**
+ * atomic_up_add_unless - add unless the number is a given value
+ * @l: pointer of type local_t
+ * @a: the amount to add to l...
+ * @u: ...unless l is equal to u.
+ *
+ * Atomically adds @a to @l, so long as it was not @u.
+ * Returns non-zero if @l was not @u, and zero otherwise.
+ */
+#define local_add_unless(l, a, u) \
+({ \
+ long c, old; \
+ c = local_read(l); \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = local_cmpxchg((l), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
+ c = old; \
+ } \
+ c != (u); \
+})
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
/* On x86-64 these are better than the atomic variants on SMP kernels
because they dont use a lock prefix. */
#define __local_inc(l) local_inc(l)
@@ -62,27 +196,27 @@ static inline void local_sub(long i, local_t *v)
/* Need to disable preemption for the cpu local counters otherwise we could
still access a variable of a previous CPU in a non atomic way. */
-#define cpu_local_wrap_v(v) \
+#define cpu_local_wrap_v(l) \
({ local_t res__; \
preempt_disable(); \
- res__ = (v); \
+ res__ = (l); \
preempt_enable(); \
res__; })
-#define cpu_local_wrap(v) \
+#define cpu_local_wrap(l) \
({ preempt_disable(); \
- v; \
+ l; \
preempt_enable(); }) \
-#define cpu_local_read(v) cpu_local_wrap_v(local_read(&__get_cpu_var(v)))
-#define cpu_local_set(v, i) cpu_local_wrap(local_set(&__get_cpu_var(v), (i)))
-#define cpu_local_inc(v) cpu_local_wrap(local_inc(&__get_cpu_var(v)))
-#define cpu_local_dec(v) cpu_local_wrap(local_dec(&__get_cpu_var(v)))
-#define cpu_local_add(i, v) cpu_local_wrap(local_add((i), &__get_cpu_var(v)))
-#define cpu_local_sub(i, v) cpu_local_wrap(local_sub((i), &__get_cpu_var(v)))
+#define cpu_local_read(l) cpu_local_wrap_v(local_read(&__get_cpu_var(l)))
+#define cpu_local_set(l, i) cpu_local_wrap(local_set(&__get_cpu_var(l), (i)))
+#define cpu_local_inc(l) cpu_local_wrap(local_inc(&__get_cpu_var(l)))
+#define cpu_local_dec(l) cpu_local_wrap(local_dec(&__get_cpu_var(l)))
+#define cpu_local_add(i, l) cpu_local_wrap(local_add((i), &__get_cpu_var(l)))
+#define cpu_local_sub(i, l) cpu_local_wrap(local_sub((i), &__get_cpu_var(l)))
-#define __cpu_local_inc(v) cpu_local_inc(v)
-#define __cpu_local_dec(v) cpu_local_dec(v)
-#define __cpu_local_add(i, v) cpu_local_add((i), (v))
-#define __cpu_local_sub(i, v) cpu_local_sub((i), (v))
+#define __cpu_local_inc(l) cpu_local_inc(l)
+#define __cpu_local_dec(l) cpu_local_dec(l)
+#define __cpu_local_add(i, l) cpu_local_add((i), (l))
+#define __cpu_local_sub(i, l) cpu_local_sub((i), (l))
-#endif /* _ARCH_I386_LOCAL_H */
+#endif /* _ARCH_X8664_LOCAL_H */
diff --git a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h
index a524f03..d5c55b8 100644
--- a/include/asm-x86_64/msr.h
+++ b/include/asm-x86_64/msr.h
@@ -4,6 +4,7 @@
#include <asm/msr-index.h>
#ifndef __ASSEMBLY__
+#include <linux/errno.h>
/*
* Access to machine-specific registers (available on 586 and better only)
* Note: the rd* operations modify the parameters directly (without using
@@ -162,6 +163,8 @@ static inline unsigned int cpuid_edx(unsigned int op)
#ifdef CONFIG_SMP
void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
+int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
+int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
#else /* CONFIG_SMP */
static inline void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
{
@@ -171,6 +174,14 @@ static inline void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
{
wrmsr(msr_no, l, h);
}
+static inline int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
+{
+ return rdmsr_safe(msr_no, l, h);
+}
+static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+{
+ return wrmsr_safe(msr_no, l, h);
+}
#endif /* CONFIG_SMP */
#endif /* __ASSEMBLY__ */
#endif /* X86_64_MSR_H */
diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
index b17fc16..dee632f 100644
--- a/include/asm-x86_64/page.h
+++ b/include/asm-x86_64/page.h
@@ -1,7 +1,7 @@
#ifndef _X86_64_PAGE_H
#define _X86_64_PAGE_H
-#include <asm/const.h>
+#include <linux/const.h>
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12
@@ -79,9 +79,10 @@ extern unsigned long phys_base;
#define __PHYSICAL_START CONFIG_PHYSICAL_START
#define __KERNEL_ALIGN 0x200000
+
#define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
-#define __START_KERNEL_map 0xffffffff80000000
-#define __PAGE_OFFSET 0xffff810000000000
+#define __START_KERNEL_map _AC(0xffffffff80000000, UL)
+#define __PAGE_OFFSET _AC(0xffff810000000000, UL)
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
@@ -93,27 +94,23 @@ extern unsigned long phys_base;
#define __VIRTUAL_MASK ((_AC(1,UL) << __VIRTUAL_MASK_SHIFT) - 1)
#define KERNEL_TEXT_SIZE (40*1024*1024)
-#define KERNEL_TEXT_START 0xffffffff80000000
+#define KERNEL_TEXT_START _AC(0xffffffff80000000, UL)
+#define PAGE_OFFSET __PAGE_OFFSET
#ifndef __ASSEMBLY__
#include <asm/bug.h>
-#endif /* __ASSEMBLY__ */
+extern unsigned long __phys_addr(unsigned long);
-#define PAGE_OFFSET __PAGE_OFFSET
+#endif /* __ASSEMBLY__ */
-/* Note: __pa(&symbol_visible_to_c) should be always replaced with __pa_symbol.
- Otherwise you risk miscompilation. */
-#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET)
-/* __pa_symbol should be used for C visible symbols.
- This seems to be the official gcc blessed way to do such arithmetic. */
-#define __pa_symbol(x) \
- ({unsigned long v; \
- asm("" : "=r" (v) : "0" (x)); \
- ((v - __START_KERNEL_map) + phys_base); })
+#define __pa(x) __phys_addr((unsigned long)(x))
+#define __pa_symbol(x) __phys_addr((unsigned long)(x))
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
+#define __boot_va(x) __va(x)
+#define __boot_pa(x) __pa(x)
#ifdef CONFIG_FLATMEM
#define pfn_valid(pfn) ((pfn) < end_pfn)
#endif
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
index 599993f..08b9831 100644
--- a/include/asm-x86_64/pgtable.h
+++ b/include/asm-x86_64/pgtable.h
@@ -1,7 +1,7 @@
#ifndef _X86_64_PGTABLE_H
#define _X86_64_PGTABLE_H
-#include <asm/const.h>
+#include <linux/const.h>
#ifndef __ASSEMBLY__
/*
@@ -19,7 +19,7 @@ extern pmd_t level2_kernel_pgt[512];
extern pgd_t init_level4_pgt[];
extern unsigned long __supported_pte_mask;
-#define swapper_pg_dir ((pgd_t *)NULL)
+#define swapper_pg_dir init_level4_pgt
extern void paging_init(void);
extern void clear_kernel_mapping(unsigned long addr, unsigned long size);
@@ -29,7 +29,7 @@ extern void clear_kernel_mapping(unsigned long addr, unsigned long size);
* for zero-mapped memory areas etc..
*/
extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
-#define ZERO_PAGE(vaddr) (pfn_to_page(__pa_symbol(&empty_zero_page) >> PAGE_SHIFT))
+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
#endif /* !__ASSEMBLY__ */
@@ -134,11 +134,11 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long
#define USER_PTRS_PER_PGD ((TASK_SIZE-1)/PGDIR_SIZE+1)
#define FIRST_USER_ADDRESS 0
-#define MAXMEM 0x3fffffffffff
-#define VMALLOC_START 0xffffc20000000000
-#define VMALLOC_END 0xffffe1ffffffffff
-#define MODULES_VADDR 0xffffffff88000000
-#define MODULES_END 0xfffffffffff00000
+#define MAXMEM _AC(0x3fffffffffff, UL)
+#define VMALLOC_START _AC(0xffffc20000000000, UL)
+#define VMALLOC_END _AC(0xffffe1ffffffffff, UL)
+#define MODULES_VADDR _AC(0xffffffff88000000, UL)
+#define MODULES_END _AC(0xfffffffffff00000, UL)
#define MODULES_LEN (MODULES_END - MODULES_VADDR)
#define _PAGE_BIT_PRESENT 0
@@ -411,17 +411,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
extern spinlock_t pgd_lock;
extern struct list_head pgd_list;
-void vmalloc_sync_all(void);
extern int kern_addr_valid(unsigned long addr);
#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
remap_pfn_range(vma, vaddr, pfn, size, prot)
-#define MK_IOSPACE_PFN(space, pfn) (pfn)
-#define GET_IOSPACE(pfn) 0
-#define GET_PFN(pfn) (pfn)
-
#define HAVE_ARCH_UNMAPPED_AREA
#define pgtable_cache_init() do { } while (0)
diff --git a/include/asm-x86_64/serial.h b/include/asm-x86_64/serial.h
index b0496e0..8ebd765 100644
--- a/include/asm-x86_64/serial.h
+++ b/include/asm-x86_64/serial.h
@@ -11,19 +11,3 @@
* megabits/second; but this requires the faster clock.
*/
#define BASE_BAUD ( 1843200 / 16 )
-
-/* Standard COM flags (except for COM4, because of the 8514 problem) */
-#ifdef CONFIG_SERIAL_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
-#else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
-#endif
-
-#define SERIAL_PORT_DFNS \
- /* UART CLK PORT IRQ FLAGS */ \
- { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
- { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
- { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
- { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h
index 213b7fe..b7b8021 100644
--- a/include/asm-x86_64/system.h
+++ b/include/asm-x86_64/system.h
@@ -3,7 +3,7 @@
#include <linux/kernel.h>
#include <asm/segment.h>
-#include <asm/alternative.h>
+#include <asm/cmpxchg.h>
#ifdef __KERNEL__
@@ -124,100 +124,6 @@ static inline void sched_cacheflush(void)
#define nop() __asm__ __volatile__ ("nop")
-#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
-
-#define tas(ptr) (xchg((ptr),1))
-
-#define __xg(x) ((volatile long *)(x))
-
-static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
-{
- *ptr = val;
-}
-
-#define _set_64bit set_64bit
-
-/*
- * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
- * Note 2: xchg has side effect, so that attribute volatile is necessary,
- * but generally the primitive is invalid, *ptr is output argument. --ANK
- */
-static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
-{
- switch (size) {
- case 1:
- __asm__ __volatile__("xchgb %b0,%1"
- :"=q" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 2:
- __asm__ __volatile__("xchgw %w0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 4:
- __asm__ __volatile__("xchgl %k0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- case 8:
- __asm__ __volatile__("xchgq %0,%1"
- :"=r" (x)
- :"m" (*__xg(ptr)), "0" (x)
- :"memory");
- break;
- }
- return x;
-}
-
-/*
- * Atomic compare and exchange. Compare OLD with MEM, if identical,
- * store NEW in MEM. Return the initial value in MEM. Success is
- * indicated by comparing RETURN with OLD.
- */
-
-#define __HAVE_ARCH_CMPXCHG 1
-
-static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
- unsigned long new, int size)
-{
- unsigned long prev;
- switch (size) {
- case 1:
- __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
- : "=a"(prev)
- : "q"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 2:
- __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 4:
- __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %k1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- case 8:
- __asm__ __volatile__(LOCK_PREFIX "cmpxchgq %1,%2"
- : "=a"(prev)
- : "r"(new), "m"(*__xg(ptr)), "0"(old)
- : "memory");
- return prev;
- }
- return old;
-}
-
-#define cmpxchg(ptr,o,n)\
- ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
- (unsigned long)(n),sizeof(*(ptr))))
-
#ifdef CONFIG_SMP
#define smp_mb() mb()
#define smp_rmb() rmb()
diff --git a/include/asm-x86_64/termbits.h b/include/asm-x86_64/termbits.h
index 6cfc3bb..7405756 100644
--- a/include/asm-x86_64/termbits.h
+++ b/include/asm-x86_64/termbits.h
@@ -160,7 +160,7 @@ struct ktermios {
#define CMSPAR 010000000000 /* mark or space (stick) parity */
#define CRTSCTS 020000000000 /* flow control */
-#define IBSHIFT 8 /* Shift from CBAUD to CIBAUD */
+#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
/* c_lflag bits */
#define ISIG 0000001
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index 26e23e0..5957039 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -619,6 +619,8 @@ __SYSCALL(__NR_sync_file_range, sys_sync_file_range)
__SYSCALL(__NR_vmsplice, sys_vmsplice)
#define __NR_move_pages 279
__SYSCALL(__NR_move_pages, sys_move_pages)
+#define __NR_utimensat 280
+__SYSCALL(__NR_utimensat, sys_utimensat)
#ifndef __NO_STUBS
#define __ARCH_WANT_OLD_READDIR
diff --git a/include/asm-xtensa/atomic.h b/include/asm-xtensa/atomic.h
index 5c26720..b3b2354 100644
--- a/include/asm-xtensa/atomic.h
+++ b/include/asm-xtensa/atomic.h
@@ -234,14 +234,21 @@ static inline int atomic_sub_return(int i, atomic_t * v)
* Atomically adds @a to @v, so long as it was not @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
- c = old; \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
diff --git a/include/asm-xtensa/kdebug.h b/include/asm-xtensa/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/include/asm-xtensa/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h
index 4aaed7f..ddc9708 100644
--- a/include/asm-xtensa/system.h
+++ b/include/asm-xtensa/system.h
@@ -183,8 +183,6 @@ static inline unsigned long xchg_u32(volatile int * m, unsigned long val)
return tmp;
}
-#define tas(ptr) (xchg((ptr),1))
-
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
/*
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 4ff0f57..94cc04a 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -4,6 +4,7 @@ header-y += hdlc/
header-y += isdn/
header-y += nfsd/
header-y += raid/
+header-y += spi/
header-y += sunrpc/
header-y += tc_act/
header-y += netfilter/
@@ -33,7 +34,6 @@ header-y += atmsvc.h
header-y += atm_zatm.h
header-y += auto_fs4.h
header-y += auxvec.h
-header-y += awe_voice.h
header-y += ax25.h
header-y += b1lli.h
header-y += baycom.h
@@ -46,6 +46,7 @@ header-y += coda_psdev.h
header-y += coff.h
header-y += comstats.h
header-y += consolemap.h
+header-y += const.h
header-y += cycx_cfm.h
header-y += dlm_device.h
header-y += dm-ioctl.h
@@ -91,11 +92,11 @@ header-y += ip_mp_alg.h
header-y += ipsec.h
header-y += ipx.h
header-y += irda.h
-header-y += isdn_divertif.h
header-y += iso_fs.h
header-y += ixjuser.h
header-y += jffs2.h
header-y += keyctl.h
+header-y += kvm.h
header-y += limits.h
header-y += lock_dlm_plock.h
header-y += magic.h
@@ -120,6 +121,7 @@ header-y += pci_regs.h
header-y += personality.h
header-y += pfkeyv2.h
header-y += pg.h
+header-y += phantom.h
header-y += pkt_cls.h
header-y += pkt_sched.h
header-y += posix_types.h
@@ -139,6 +141,7 @@ header-y += sockios.h
header-y += som.h
header-y += sound.h
header-y += synclink.h
+header-y += taskstats.h
header-y += telephony.h
header-y += termios.h
header-y += ticable.h
@@ -238,6 +241,7 @@ unifdef-y += ipv6.h
unifdef-y += ipv6_route.h
unifdef-y += isdn.h
unifdef-y += isdnif.h
+unifdef-y += isdn_divertif.h
unifdef-y += isdn_ppp.h
unifdef-y += isicom.h
unifdef-y += jbd.h
diff --git a/include/linux/awe_voice.h b/include/linux/awe_voice.h
deleted file mode 100644
index bf33f17..0000000
--- a/include/linux/awe_voice.h
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * include/linux/awe_voice.h
- *
- * Voice information definitions for the low level driver for the
- * AWE32/SB32/AWE64 wave table synth.
- * version 0.4.4; Jan. 4, 2000
- *
- * Copyright (C) 1996-2000 Takashi Iwai
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef AWE_VOICE_H
-#define AWE_VOICE_H
-
-#ifndef SAMPLE_TYPE_AWE32
-#define SAMPLE_TYPE_AWE32 0x20
-#endif
-
-#define _LINUX_PATCHKEY_H_INDIRECT
-#include <linux/patchkey.h>
-#undef _LINUX_PATCHKEY_H_INDIRECT
-
-/*----------------------------------------------------------------
- * patch information record
- *----------------------------------------------------------------*/
-
-/* patch interface header: 16 bytes */
-typedef struct awe_patch_info {
- short key; /* use AWE_PATCH here */
-#define AWE_PATCH _PATCHKEY(0x07)
-
- short device_no; /* synthesizer number */
- unsigned short sf_id; /* file id (should be zero) */
- short optarg; /* optional argument */
- int len; /* data length (without this header) */
-
- short type; /* patch operation type */
-#define AWE_LOAD_INFO 0 /* awe_voice_rec */
-#define AWE_LOAD_DATA 1 /* awe_sample_info */
-#define AWE_OPEN_PATCH 2 /* awe_open_parm */
-#define AWE_CLOSE_PATCH 3 /* none */
-#define AWE_UNLOAD_PATCH 4 /* none */
-#define AWE_REPLACE_DATA 5 /* awe_sample_info (optarg=#channels)*/
-#define AWE_MAP_PRESET 6 /* awe_voice_map */
-/*#define AWE_PROBE_INFO 7*/ /* awe_voice_map (pat only) */
-#define AWE_PROBE_DATA 8 /* optarg=sample */
-#define AWE_REMOVE_INFO 9 /* optarg=(bank<<8)|instr */
-#define AWE_LOAD_CHORUS_FX 0x10 /* awe_chorus_fx_rec (optarg=mode) */
-#define AWE_LOAD_REVERB_FX 0x11 /* awe_reverb_fx_rec (optarg=mode) */
-
- short reserved; /* word alignment data */
-
- /* the actual patch data begins after this */
-#if defined(AWE_COMPAT_030) && AWE_COMPAT_030
- char data[0];
-#endif
-} awe_patch_info;
-
-/*#define AWE_PATCH_INFO_SIZE 16*/
-#define AWE_PATCH_INFO_SIZE sizeof(awe_patch_info)
-
-
-/*----------------------------------------------------------------
- * open patch
- *----------------------------------------------------------------*/
-
-#define AWE_PATCH_NAME_LEN 32
-
-typedef struct _awe_open_parm {
- unsigned short type; /* sample type */
-#define AWE_PAT_TYPE_MISC 0
-#define AWE_PAT_TYPE_GM 1
-#define AWE_PAT_TYPE_GS 2
-#define AWE_PAT_TYPE_MT32 3
-#define AWE_PAT_TYPE_XG 4
-#define AWE_PAT_TYPE_SFX 5
-#define AWE_PAT_TYPE_GUS 6
-#define AWE_PAT_TYPE_MAP 7
-
-#define AWE_PAT_LOCKED 0x100 /* lock the samples */
-#define AWE_PAT_SHARED 0x200 /* sample is shared */
-
- short reserved;
- char name[AWE_PATCH_NAME_LEN];
-} awe_open_parm;
-
-/*#define AWE_OPEN_PARM_SIZE 28*/
-#define AWE_OPEN_PARM_SIZE sizeof(awe_open_parm)
-
-
-/*----------------------------------------------------------------
- * raw voice information record
- *----------------------------------------------------------------*/
-
-/* wave table envelope & effect parameters to control EMU8000 */
-typedef struct _awe_voice_parm {
- unsigned short moddelay; /* modulation delay (0x8000) */
- unsigned short modatkhld; /* modulation attack & hold time (0x7f7f) */
- unsigned short moddcysus; /* modulation decay & sustain (0x7f7f) */
- unsigned short modrelease; /* modulation release time (0x807f) */
- short modkeyhold, modkeydecay; /* envelope change per key (not used) */
- unsigned short voldelay; /* volume delay (0x8000) */
- unsigned short volatkhld; /* volume attack & hold time (0x7f7f) */
- unsigned short voldcysus; /* volume decay & sustain (0x7f7f) */
- unsigned short volrelease; /* volume release time (0x807f) */
- short volkeyhold, volkeydecay; /* envelope change per key (not used) */
- unsigned short lfo1delay; /* LFO1 delay (0x8000) */
- unsigned short lfo2delay; /* LFO2 delay (0x8000) */
- unsigned short pefe; /* modulation pitch & cutoff (0x0000) */
- unsigned short fmmod; /* LFO1 pitch & cutoff (0x0000) */
- unsigned short tremfrq; /* LFO1 volume & freq (0x0000) */
- unsigned short fm2frq2; /* LFO2 pitch & freq (0x0000) */
- unsigned char cutoff; /* initial cutoff (0xff) */
- unsigned char filterQ; /* initial filter Q [0-15] (0x0) */
- unsigned char chorus; /* chorus send (0x00) */
- unsigned char reverb; /* reverb send (0x00) */
- unsigned short reserved[4]; /* not used */
-} awe_voice_parm;
-
-typedef struct _awe_voice_parm_block {
- unsigned short moddelay; /* modulation delay (0x8000) */
- unsigned char modatk, modhld;
- unsigned char moddcy, modsus;
- unsigned char modrel, moddummy;
- short modkeyhold, modkeydecay; /* envelope change per key (not used) */
- unsigned short voldelay; /* volume delay (0x8000) */
- unsigned char volatk, volhld;
- unsigned char voldcy, volsus;
- unsigned char volrel, voldummy;
- short volkeyhold, volkeydecay; /* envelope change per key (not used) */
- unsigned short lfo1delay; /* LFO1 delay (0x8000) */
- unsigned short lfo2delay; /* LFO2 delay (0x8000) */
- unsigned char env1fc, env1pit;
- unsigned char lfo1fc, lfo1pit;
- unsigned char lfo1freq, lfo1vol;
- unsigned char lfo2freq, lfo2pit;
- unsigned char cutoff; /* initial cutoff (0xff) */
- unsigned char filterQ; /* initial filter Q [0-15] (0x0) */
- unsigned char chorus; /* chorus send (0x00) */
- unsigned char reverb; /* reverb send (0x00) */
- unsigned short reserved[4]; /* not used */
-} awe_voice_parm_block;
-
-#define AWE_VOICE_PARM_SIZE 48
-
-
-/* wave table parameters: 92 bytes */
-typedef struct _awe_voice_info {
- unsigned short sf_id; /* file id (should be zero) */
- unsigned short sample; /* sample id */
- int start, end; /* sample offset correction */
- int loopstart, loopend; /* loop offset correction */
- short rate_offset; /* sample rate pitch offset */
- unsigned short mode; /* sample mode */
-#define AWE_MODE_ROMSOUND 0x8000
-#define AWE_MODE_STEREO 1
-#define AWE_MODE_LOOPING 2
-#define AWE_MODE_NORELEASE 4 /* obsolete */
-#define AWE_MODE_INIT_PARM 8
-
- short root; /* midi root key */
- short tune; /* pitch tuning (in cents) */
- signed char low, high; /* key note range */
- signed char vellow, velhigh; /* velocity range */
- signed char fixkey, fixvel; /* fixed key, velocity */
- signed char pan, fixpan; /* panning, fixed panning */
- short exclusiveClass; /* exclusive class (0 = none) */
- unsigned char amplitude; /* sample volume (127 max) */
- unsigned char attenuation; /* attenuation (0.375dB) */
- short scaleTuning; /* pitch scale tuning(%), normally 100 */
- awe_voice_parm parm; /* voice envelope parameters */
- short index; /* internal index (set by driver) */
-} awe_voice_info;
-
-/*#define AWE_VOICE_INFO_SIZE 92*/
-#define AWE_VOICE_INFO_SIZE sizeof(awe_voice_info)
-
-/*----------------------------------------------------------------*/
-
-/* The info entry of awe_voice_rec is changed from 0 to 1
- * for some compilers refusing zero size array.
- * Due to this change, sizeof(awe_voice_rec) becomes different
- * from older versions.
- * Use AWE_VOICE_REC_SIZE instead.
- */
-
-/* instrument info header: 4 bytes */
-typedef struct _awe_voice_rec_hdr {
- unsigned char bank; /* midi bank number */
- unsigned char instr; /* midi preset number */
- char nvoices; /* number of voices */
- char write_mode; /* write mode; normally 0 */
-#define AWE_WR_APPEND 0 /* append anyway */
-#define AWE_WR_EXCLUSIVE 1 /* skip if already exists */
-#define AWE_WR_REPLACE 2 /* replace if already exists */
-} awe_voice_rec_hdr;
-
-/*#define AWE_VOICE_REC_SIZE 4*/
-#define AWE_VOICE_REC_SIZE sizeof(awe_voice_rec_hdr)
-
-/* the standard patch structure for one sample */
-typedef struct _awe_voice_rec_patch {
- awe_patch_info patch;
- awe_voice_rec_hdr hdr;
- awe_voice_info info;
-} awe_voice_rec_patch;
-
-
-/* obsolete data type */
-#if defined(AWE_COMPAT_030) && AWE_COMPAT_030
-#define AWE_INFOARRAY_SIZE 0
-#else
-#define AWE_INFOARRAY_SIZE 1
-#endif
-
-typedef struct _awe_voice_rec {
- unsigned char bank; /* midi bank number */
- unsigned char instr; /* midi preset number */
- short nvoices; /* number of voices */
- /* voice information follows here */
- awe_voice_info info[AWE_INFOARRAY_SIZE];
-} awe_voice_rec;
-
-
-/*----------------------------------------------------------------
- * sample wave information
- *----------------------------------------------------------------*/
-
-/* wave table sample header: 32 bytes */
-typedef struct awe_sample_info {
- unsigned short sf_id; /* file id (should be zero) */
- unsigned short sample; /* sample id */
- int start, end; /* start & end offset */
- int loopstart, loopend; /* loop start & end offset */
- int size; /* size (0 = ROM) */
- short checksum_flag; /* use check sum = 1 */
- unsigned short mode_flags; /* mode flags */
-#define AWE_SAMPLE_8BITS 1 /* wave data is 8bits */
-#define AWE_SAMPLE_UNSIGNED 2 /* wave data is unsigned */
-#define AWE_SAMPLE_NO_BLANK 4 /* no blank loop is attached */
-#define AWE_SAMPLE_SINGLESHOT 8 /* single-shot w/o loop */
-#define AWE_SAMPLE_BIDIR_LOOP 16 /* bidirectional looping */
-#define AWE_SAMPLE_STEREO_LEFT 32 /* stereo left sound */
-#define AWE_SAMPLE_STEREO_RIGHT 64 /* stereo right sound */
-#define AWE_SAMPLE_REVERSE_LOOP 128 /* reverse looping */
- unsigned int checksum; /* check sum */
-#if defined(AWE_COMPAT_030) && AWE_COMPAT_030
- unsigned short data[0]; /* sample data follows here */
-#endif
-} awe_sample_info;
-
-/*#define AWE_SAMPLE_INFO_SIZE 32*/
-#define AWE_SAMPLE_INFO_SIZE sizeof(awe_sample_info)
-
-
-/*----------------------------------------------------------------
- * voice preset mapping
- *----------------------------------------------------------------*/
-
-typedef struct awe_voice_map {
- int map_bank, map_instr, map_key; /* key = -1 means all keys */
- int src_bank, src_instr, src_key;
-} awe_voice_map;
-
-#define AWE_VOICE_MAP_SIZE sizeof(awe_voice_map)
-
-
-/*----------------------------------------------------------------
- * awe hardware controls
- *----------------------------------------------------------------*/
-
-#define _AWE_DEBUG_MODE 0x00
-#define _AWE_REVERB_MODE 0x01
-#define _AWE_CHORUS_MODE 0x02
-#define _AWE_REMOVE_LAST_SAMPLES 0x03
-#define _AWE_INITIALIZE_CHIP 0x04
-#define _AWE_SEND_EFFECT 0x05
-#define _AWE_TERMINATE_CHANNEL 0x06
-#define _AWE_TERMINATE_ALL 0x07
-#define _AWE_INITIAL_VOLUME 0x08
-#define _AWE_INITIAL_ATTEN _AWE_INITIAL_VOLUME
-#define _AWE_RESET_CHANNEL 0x09
-#define _AWE_CHANNEL_MODE 0x0a
-#define _AWE_DRUM_CHANNELS 0x0b
-#define _AWE_MISC_MODE 0x0c
-#define _AWE_RELEASE_ALL 0x0d
-#define _AWE_NOTEOFF_ALL 0x0e
-#define _AWE_CHN_PRESSURE 0x0f
-/*#define _AWE_GET_CURRENT_MODE 0x10*/
-#define _AWE_EQUALIZER 0x11
-/*#define _AWE_GET_MISC_MODE 0x12*/
-/*#define _AWE_GET_FONTINFO 0x13*/
-
-#define _AWE_MODE_FLAG 0x80
-#define _AWE_COOKED_FLAG 0x40 /* not supported */
-#define _AWE_MODE_VALUE_MASK 0x3F
-
-/*----------------------------------------------------------------*/
-
-#define _AWE_SET_CMD(p,dev,voice,cmd,p1,p2) \
-{((char*)(p))[0] = SEQ_PRIVATE;\
- ((char*)(p))[1] = dev;\
- ((char*)(p))[2] = _AWE_MODE_FLAG|(cmd);\
- ((char*)(p))[3] = voice;\
- ((unsigned short*)(p))[2] = p1;\
- ((unsigned short*)(p))[3] = p2;}
-
-/* buffered access */
-#define _AWE_CMD(dev, voice, cmd, p1, p2) \
-{_SEQ_NEEDBUF(8);\
- _AWE_SET_CMD(_seqbuf + _seqbufptr, dev, voice, cmd, p1, p2);\
- _SEQ_ADVBUF(8);}
-
-/* direct access */
-#define _AWE_CMD_NOW(seqfd,dev,voice,cmd,p1,p2) \
-{struct seq_event_rec tmp;\
- _AWE_SET_CMD(&tmp, dev, voice, cmd, p1, p2);\
- ioctl(seqfd, SNDCTL_SEQ_OUTOFBAND, &tmp);}
-
-/*----------------------------------------------------------------*/
-
-/* set debugging mode */
-#define AWE_DEBUG_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_DEBUG_MODE, p1, 0)
-/* set reverb mode; from 0 to 7 */
-#define AWE_REVERB_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_REVERB_MODE, p1, 0)
-/* set chorus mode; from 0 to 7 */
-#define AWE_CHORUS_MODE(dev,p1) _AWE_CMD(dev, 0, _AWE_CHORUS_MODE, p1, 0)
-
-/* reset channel */
-#define AWE_RESET_CHANNEL(dev,ch) _AWE_CMD(dev, ch, _AWE_RESET_CHANNEL, 0, 0)
-#define AWE_RESET_CONTROL(dev,ch) _AWE_CMD(dev, ch, _AWE_RESET_CHANNEL, 1, 0)
-
-/* send an effect to all layers */
-#define AWE_SEND_EFFECT(dev,voice,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,type,value)
-#define AWE_ADD_EFFECT(dev,voice,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((type)|0x80),value)
-#define AWE_UNSET_EFFECT(dev,voice,type) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((type)|0x40),0)
-/* send an effect to a layer */
-#define AWE_SEND_LAYER_EFFECT(dev,voice,layer,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)),value)
-#define AWE_ADD_LAYER_EFFECT(dev,voice,layer,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)|0x80),value)
-#define AWE_UNSET_LAYER_EFFECT(dev,voice,layer,type) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)|0x40),0)
-
-/* terminate sound on the channel/voice */
-#define AWE_TERMINATE_CHANNEL(dev,voice) _AWE_CMD(dev,voice,_AWE_TERMINATE_CHANNEL,0,0)
-/* terminate all sounds */
-#define AWE_TERMINATE_ALL(dev) _AWE_CMD(dev, 0, _AWE_TERMINATE_ALL, 0, 0)
-/* release all sounds (w/o sustain effect) */
-#define AWE_RELEASE_ALL(dev) _AWE_CMD(dev, 0, _AWE_RELEASE_ALL, 0, 0)
-/* note off all sounds (w sustain effect) */
-#define AWE_NOTEOFF_ALL(dev) _AWE_CMD(dev, 0, _AWE_NOTEOFF_ALL, 0, 0)
-
-/* set initial attenuation */
-#define AWE_INITIAL_VOLUME(dev,atten) _AWE_CMD(dev, 0, _AWE_INITIAL_VOLUME, atten, 0)
-#define AWE_INITIAL_ATTEN AWE_INITIAL_VOLUME
-/* relative attenuation */
-#define AWE_SET_ATTEN(dev,atten) _AWE_CMD(dev, 0, _AWE_INITIAL_VOLUME, atten, 1)
-
-/* set channel playing mode; mode=0/1/2 */
-#define AWE_SET_CHANNEL_MODE(dev,mode) _AWE_CMD(dev, 0, _AWE_CHANNEL_MODE, mode, 0)
-#define AWE_PLAY_INDIRECT 0 /* indirect voice mode (default) */
-#define AWE_PLAY_MULTI 1 /* multi note voice mode */
-#define AWE_PLAY_DIRECT 2 /* direct single voice mode */
-#define AWE_PLAY_MULTI2 3 /* sequencer2 mode; used internally */
-
-/* set drum channel mask; channels is 32bit long value */
-#define AWE_DRUM_CHANNELS(dev,channels) _AWE_CMD(dev, 0, _AWE_DRUM_CHANNELS, ((channels) & 0xffff), ((channels) >> 16))
-
-/* set bass and treble control; values are from 0 to 11 */
-#define AWE_EQUALIZER(dev,bass,treble) _AWE_CMD(dev, 0, _AWE_EQUALIZER, bass, treble)
-
-/* remove last loaded samples */
-#define AWE_REMOVE_LAST_SAMPLES(seqfd,dev) _AWE_CMD_NOW(seqfd, dev, 0, _AWE_REMOVE_LAST_SAMPLES, 0, 0)
-/* initialize emu8000 chip */
-#define AWE_INITIALIZE_CHIP(seqfd,dev) _AWE_CMD_NOW(seqfd, dev, 0, _AWE_INITIALIZE_CHIP, 0, 0)
-
-/* set miscellaneous modes; meta command */
-#define AWE_MISC_MODE(dev,mode,value) _AWE_CMD(dev, 0, _AWE_MISC_MODE, mode, value)
-/* exclusive sound off; 1=off */
-#define AWE_EXCLUSIVE_SOUND(dev,mode) AWE_MISC_MODE(dev,AWE_MD_EXCLUSIVE_SOUND,mode)
-/* default GUS bank number */
-#define AWE_SET_GUS_BANK(dev,bank) AWE_MISC_MODE(dev,AWE_MD_GUS_BANK,bank)
-/* change panning position in realtime; 0=don't 1=do */
-#define AWE_REALTIME_PAN(dev,mode) AWE_MISC_MODE(dev,AWE_MD_REALTIME_PAN,mode)
-
-/* extended pressure controls; not portable with other sound drivers */
-#define AWE_KEY_PRESSURE(dev,ch,note,vel) SEQ_START_NOTE(dev,ch,(note)+128,vel)
-#define AWE_CHN_PRESSURE(dev,ch,vel) _AWE_CMD(dev,ch,_AWE_CHN_PRESSURE,vel,0)
-
-/*----------------------------------------------------------------*/
-
-/* reverb mode parameters */
-#define AWE_REVERB_ROOM1 0
-#define AWE_REVERB_ROOM2 1
-#define AWE_REVERB_ROOM3 2
-#define AWE_REVERB_HALL1 3
-#define AWE_REVERB_HALL2 4
-#define AWE_REVERB_PLATE 5
-#define AWE_REVERB_DELAY 6
-#define AWE_REVERB_PANNINGDELAY 7
-#define AWE_REVERB_PREDEFINED 8
-/* user can define reverb modes up to 32 */
-#define AWE_REVERB_NUMBERS 32
-
-typedef struct awe_reverb_fx_rec {
- unsigned short parms[28];
-} awe_reverb_fx_rec;
-
-/*----------------------------------------------------------------*/
-
-/* chorus mode parameters */
-#define AWE_CHORUS_1 0
-#define AWE_CHORUS_2 1
-#define AWE_CHORUS_3 2
-#define AWE_CHORUS_4 3
-#define AWE_CHORUS_FEEDBACK 4
-#define AWE_CHORUS_FLANGER 5
-#define AWE_CHORUS_SHORTDELAY 6
-#define AWE_CHORUS_SHORTDELAY2 7
-#define AWE_CHORUS_PREDEFINED 8
-/* user can define chorus modes up to 32 */
-#define AWE_CHORUS_NUMBERS 32
-
-typedef struct awe_chorus_fx_rec {
- unsigned short feedback; /* feedback level (0xE600-0xE6FF) */
- unsigned short delay_offset; /* delay (0-0x0DA3) [1/44100 sec] */
- unsigned short lfo_depth; /* LFO depth (0xBC00-0xBCFF) */
- unsigned int delay; /* right delay (0-0xFFFFFFFF) [1/256/44100 sec] */
- unsigned int lfo_freq; /* LFO freq LFO freq (0-0xFFFFFFFF) */
-} awe_chorus_fx_rec;
-
-/*----------------------------------------------------------------*/
-
-/* misc mode types */
-enum {
-/* 0*/ AWE_MD_EXCLUSIVE_OFF, /* obsolete */
-/* 1*/ AWE_MD_EXCLUSIVE_ON, /* obsolete */
-/* 2*/ AWE_MD_VERSION, /* read only */
-/* 3*/ AWE_MD_EXCLUSIVE_SOUND, /* 0/1: exclusive note on (default=1) */
-/* 4*/ AWE_MD_REALTIME_PAN, /* 0/1: do realtime pan change (default=1) */
-/* 5*/ AWE_MD_GUS_BANK, /* bank number for GUS patches (default=0) */
-/* 6*/ AWE_MD_KEEP_EFFECT, /* 0/1: keep effect values, (default=0) */
-/* 7*/ AWE_MD_ZERO_ATTEN, /* attenuation of max volume (default=32) */
-/* 8*/ AWE_MD_CHN_PRIOR, /* 0/1: set MIDI channel priority mode (default=1) */
-/* 9*/ AWE_MD_MOD_SENSE, /* integer: modwheel sensitivity (def=18) */
-/*10*/ AWE_MD_DEF_PRESET, /* integer: default preset number (def=0) */
-/*11*/ AWE_MD_DEF_BANK, /* integer: default bank number (def=0) */
-/*12*/ AWE_MD_DEF_DRUM, /* integer: default drumset number (def=0) */
-/*13*/ AWE_MD_TOGGLE_DRUM_BANK, /* 0/1: toggle drum flag with bank# (def=0) */
-/*14*/ AWE_MD_NEW_VOLUME_CALC, /* 0/1: volume calculation mode (def=1) */
-/*15*/ AWE_MD_CHORUS_MODE, /* integer: chorus mode (def=2) */
-/*16*/ AWE_MD_REVERB_MODE, /* integer: chorus mode (def=4) */
-/*17*/ AWE_MD_BASS_LEVEL, /* integer: bass level (def=5) */
-/*18*/ AWE_MD_TREBLE_LEVEL, /* integer: treble level (def=9) */
-/*19*/ AWE_MD_DEBUG_MODE, /* integer: debug level (def=0) */
-/*20*/ AWE_MD_PAN_EXCHANGE, /* 0/1: exchange panning direction (def=0) */
- AWE_MD_END,
-};
-
-/*----------------------------------------------------------------*/
-
-/* effect parameters */
-enum {
-
-/* modulation envelope parameters */
-/* 0*/ AWE_FX_ENV1_DELAY, /* WORD: ENVVAL */
-/* 1*/ AWE_FX_ENV1_ATTACK, /* BYTE: up ATKHLD */
-/* 2*/ AWE_FX_ENV1_HOLD, /* BYTE: lw ATKHLD */
-/* 3*/ AWE_FX_ENV1_DECAY, /* BYTE: lw DCYSUS */
-/* 4*/ AWE_FX_ENV1_RELEASE, /* BYTE: lw DCYSUS */
-/* 5*/ AWE_FX_ENV1_SUSTAIN, /* BYTE: up DCYSUS */
-/* 6*/ AWE_FX_ENV1_PITCH, /* BYTE: up PEFE */
-/* 7*/ AWE_FX_ENV1_CUTOFF, /* BYTE: lw PEFE */
-
-/* volume envelope parameters */
-/* 8*/ AWE_FX_ENV2_DELAY, /* WORD: ENVVOL */
-/* 9*/ AWE_FX_ENV2_ATTACK, /* BYTE: up ATKHLDV */
-/*10*/ AWE_FX_ENV2_HOLD, /* BYTE: lw ATKHLDV */
-/*11*/ AWE_FX_ENV2_DECAY, /* BYTE: lw DCYSUSV */
-/*12*/ AWE_FX_ENV2_RELEASE, /* BYTE: lw DCYSUSV */
-/*13*/ AWE_FX_ENV2_SUSTAIN, /* BYTE: up DCYSUSV */
-
-/* LFO1 (tremolo & vibrato) parameters */
-/*14*/ AWE_FX_LFO1_DELAY, /* WORD: LFO1VAL */
-/*15*/ AWE_FX_LFO1_FREQ, /* BYTE: lo TREMFRQ */
-/*16*/ AWE_FX_LFO1_VOLUME, /* BYTE: up TREMFRQ */
-/*17*/ AWE_FX_LFO1_PITCH, /* BYTE: up FMMOD */
-/*18*/ AWE_FX_LFO1_CUTOFF, /* BYTE: lo FMMOD */
-
-/* LFO2 (vibrato) parameters */
-/*19*/ AWE_FX_LFO2_DELAY, /* WORD: LFO2VAL */
-/*20*/ AWE_FX_LFO2_FREQ, /* BYTE: lo FM2FRQ2 */
-/*21*/ AWE_FX_LFO2_PITCH, /* BYTE: up FM2FRQ2 */
-
-/* Other overall effect parameters */
-/*22*/ AWE_FX_INIT_PITCH, /* SHORT: pitch offset */
-/*23*/ AWE_FX_CHORUS, /* BYTE: chorus effects send (0-255) */
-/*24*/ AWE_FX_REVERB, /* BYTE: reverb effects send (0-255) */
-/*25*/ AWE_FX_CUTOFF, /* BYTE: up IFATN */
-/*26*/ AWE_FX_FILTERQ, /* BYTE: up CCCA */
-
-/* Sample / loop offset changes */
-/*27*/ AWE_FX_SAMPLE_START, /* SHORT: offset */
-/*28*/ AWE_FX_LOOP_START, /* SHORT: offset */
-/*29*/ AWE_FX_LOOP_END, /* SHORT: offset */
-/*30*/ AWE_FX_COARSE_SAMPLE_START, /* SHORT: upper word offset */
-/*31*/ AWE_FX_COARSE_LOOP_START, /* SHORT: upper word offset */
-/*32*/ AWE_FX_COARSE_LOOP_END, /* SHORT: upper word offset */
-/*33*/ AWE_FX_ATTEN, /* BYTE: lo IFATN */
-
- AWE_FX_END,
-};
-
-#endif /* AWE_VOICE_H */
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index dd27b1c..5c6e128 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -165,7 +165,7 @@ int sync_mapping_buffers(struct address_space *mapping);
void unmap_underlying_metadata(struct block_device *bdev, sector_t block);
void mark_buffer_async_write(struct buffer_head *bh);
-void invalidate_bdev(struct block_device *, int);
+void invalidate_bdev(struct block_device *);
int sync_blockdev(struct block_device *bdev);
void __wait_on_buffer(struct buffer_head *);
wait_queue_head_t *bh_waitq_head(struct buffer_head *bh);
@@ -182,6 +182,7 @@ void __brelse(struct buffer_head *);
void __bforget(struct buffer_head *);
void __breadahead(struct block_device *, sector_t block, unsigned int size);
struct buffer_head *__bread(struct block_device *, sector_t block, unsigned size);
+void invalidate_bh_lrus(void);
struct buffer_head *alloc_buffer_head(gfp_t gfp_flags);
void free_buffer_head(struct buffer_head * bh);
void FASTCALL(unlock_buffer(struct buffer_head *bh));
@@ -319,7 +320,7 @@ static inline int inode_has_buffers(struct inode *inode) { return 0; }
static inline void invalidate_inode_buffers(struct inode *inode) {}
static inline int remove_inode_buffers(struct inode *inode) { return 1; }
static inline int sync_mapping_buffers(struct address_space *mapping) { return 0; }
-static inline void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers) {}
+static inline void invalidate_bdev(struct block_device *bdev) {}
#endif /* CONFIG_BLOCK */
diff --git a/include/linux/byteorder/generic.h b/include/linux/byteorder/generic.h
index e86e4a9..3dc715b 100644
--- a/include/linux/byteorder/generic.h
+++ b/include/linux/byteorder/generic.h
@@ -124,19 +124,8 @@
#define be32_to_cpus __be32_to_cpus
#define cpu_to_be16s __cpu_to_be16s
#define be16_to_cpus __be16_to_cpus
-#endif
-
-#if defined(__KERNEL__)
/*
- * Handle ntohl and suches. These have various compatibility
- * issues - like we want to give the prototype even though we
- * also have a macro for them in case some strange program
- * wants to take the address of the thing or something..
- *
- * Note that these used to return a "long" in libc5, even though
- * long is often 64-bit these days.. Thus the casts.
- *
* They have to be macros in order to do the constant folding
* correctly - if the argument passed into a inline function
* it is no longer constant according to gcc..
@@ -147,17 +136,6 @@
#undef htonl
#undef htons
-/*
- * Do the prototypes. Somebody might want to take the
- * address or some such sick thing..
- */
-extern __u32 ntohl(__be32);
-extern __be32 htonl(__u32);
-extern __u16 ntohs(__be16);
-extern __be16 htons(__u16);
-
-#if defined(__GNUC__) && defined(__OPTIMIZE__)
-
#define ___htonl(x) __cpu_to_be32(x)
#define ___htons(x) __cpu_to_be16(x)
#define ___ntohl(x) __be32_to_cpu(x)
@@ -168,9 +146,6 @@ extern __be16 htons(__u16);
#define htons(x) ___htons(x)
#define ntohs(x) ___ntohs(x)
-#endif /* OPTIMIZE */
-
#endif /* KERNEL */
-
#endif /* _LINUX_BYTEORDER_GENERIC_H */
diff --git a/include/linux/byteorder/swab.h b/include/linux/byteorder/swab.h
index 25f7f32..142134f 100644
--- a/include/linux/byteorder/swab.h
+++ b/include/linux/byteorder/swab.h
@@ -10,6 +10,10 @@
* separated swab functions from cpu_to_XX,
* to clean up support for bizarre-endian architectures.
*
+ * Trent Piepho <xyzzy@speakeasy.org> 2007114
+ * make constant-folding work, provide C versions that
+ * gcc can optimize better, explain different versions
+ *
* See asm-i386/byteorder.h and suches for examples of how to provide
* architecture-dependent optimized versions
*
@@ -17,40 +21,66 @@
#include <linux/compiler.h>
+/* Functions/macros defined, there are a lot:
+ *
+ * ___swabXX
+ * Generic C versions of the swab functions.
+ *
+ * ___constant_swabXX
+ * C versions that gcc can fold into a compile-time constant when
+ * the argument is a compile-time constant.
+ *
+ * __arch__swabXX[sp]?
+ * Architecture optimized versions of all the swab functions
+ * (including the s and p versions). These can be defined in
+ * asm-arch/byteorder.h. Any which are not, are defined here.
+ * __arch__swabXXs() is defined in terms of __arch__swabXXp(), which
+ * is defined in terms of __arch__swabXX(), which is in turn defined
+ * in terms of ___swabXX(x).
+ * These must be macros. They may be unsafe for arguments with
+ * side-effects.
+ *
+ * __fswabXX
+ * Inline function versions of the __arch__ macros. These _are_ safe
+ * if the arguments have side-effects. Note there are no s and p
+ * versions of these.
+ *
+ * __swabXX[sb]
+ * There are the ones you should actually use. The __swabXX versions
+ * will be a constant given a constant argument and use the arch
+ * specific code (if any) for non-constant arguments. The s and p
+ * versions always use the arch specific code (constant folding
+ * doesn't apply). They are safe to use with arguments with
+ * side-effects.
+ *
+ * swabXX[sb]
+ * Nicknames for __swabXX[sb] to use in the kernel.
+ */
+
/* casts are necessary for constants, because we never know how for sure
* how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
*/
-#define ___swab16(x) \
-({ \
- __u16 __x = (x); \
- ((__u16)( \
- (((__u16)(__x) & (__u16)0x00ffU) << 8) | \
- (((__u16)(__x) & (__u16)0xff00U) >> 8) )); \
-})
-#define ___swab32(x) \
-({ \
- __u32 __x = (x); \
- ((__u32)( \
- (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
- (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \
- (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \
- (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
-})
-
-#define ___swab64(x) \
-({ \
- __u64 __x = (x); \
- ((__u64)( \
- (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \
- (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \
- (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \
- (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \
- (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \
- (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
- (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \
- (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \
-})
+static __inline__ __attribute_const__ __u16 ___swab16(__u16 x)
+{
+ return x<<8 | x>>8;
+}
+static __inline__ __attribute_const__ __u32 ___swab32(__u32 x)
+{
+ return x<<24 | x>>24 |
+ (x & (__u32)0x0000ff00UL)<<8 |
+ (x & (__u32)0x00ff0000UL)>>8;
+}
+static __inline__ __attribute_const__ __u64 ___swab64(__u64 x)
+{
+ return x<<56 | x>>56 |
+ (x & (__u64)0x000000000000ff00ULL)<<40 |
+ (x & (__u64)0x0000000000ff0000ULL)<<24 |
+ (x & (__u64)0x00000000ff000000ULL)<< 8 |
+ (x & (__u64)0x000000ff00000000ULL)>> 8 |
+ (x & (__u64)0x0000ff0000000000ULL)>>24 |
+ (x & (__u64)0x00ff000000000000ULL)>>40;
+}
#define ___constant_swab16(x) \
((__u16)( \
@@ -77,13 +107,13 @@
* provide defaults when no architecture-specific optimization is detected
*/
#ifndef __arch__swab16
-# define __arch__swab16(x) ({ __u16 __tmp = (x) ; ___swab16(__tmp); })
+# define __arch__swab16(x) ___swab16(x)
#endif
#ifndef __arch__swab32
-# define __arch__swab32(x) ({ __u32 __tmp = (x) ; ___swab32(__tmp); })
+# define __arch__swab32(x) ___swab32(x)
#endif
#ifndef __arch__swab64
-# define __arch__swab64(x) ({ __u64 __tmp = (x) ; ___swab64(__tmp); })
+# define __arch__swab64(x) ___swab64(x)
#endif
#ifndef __arch__swab16p
@@ -97,13 +127,13 @@
#endif
#ifndef __arch__swab16s
-# define __arch__swab16s(x) do { *(x) = __arch__swab16p((x)); } while (0)
+# define __arch__swab16s(x) ((void)(*(x) = __arch__swab16p(x)))
#endif
#ifndef __arch__swab32s
-# define __arch__swab32s(x) do { *(x) = __arch__swab32p((x)); } while (0)
+# define __arch__swab32s(x) ((void)(*(x) = __arch__swab32p(x)))
#endif
#ifndef __arch__swab64s
-# define __arch__swab64s(x) do { *(x) = __arch__swab64p((x)); } while (0)
+# define __arch__swab64s(x) ((void)(*(x) = __arch__swab64p(x)))
#endif
@@ -113,15 +143,15 @@
#if defined(__GNUC__) && defined(__OPTIMIZE__)
# define __swab16(x) \
(__builtin_constant_p((__u16)(x)) ? \
- ___swab16((x)) : \
+ ___constant_swab16((x)) : \
__fswab16((x)))
# define __swab32(x) \
(__builtin_constant_p((__u32)(x)) ? \
- ___swab32((x)) : \
+ ___constant_swab32((x)) : \
__fswab32((x)))
# define __swab64(x) \
(__builtin_constant_p((__u64)(x)) ? \
- ___swab64((x)) : \
+ ___constant_swab64((x)) : \
__fswab64((x)))
#else
# define __swab16(x) __fswab16(x)
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 4ea7e7b..8486e78 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -54,17 +54,17 @@ enum clock_event_nofitiers {
/**
* struct clock_event_device - clock event device descriptor
* @name: ptr to clock event name
- * @hints: usage hints
+ * @features: features
* @max_delta_ns: maximum delta value in ns
* @min_delta_ns: minimum delta value in ns
* @mult: nanosecond to cycles multiplier
* @shift: nanoseconds to cycles divisor (power of two)
* @rating: variable to rate clock event devices
- * @irq: irq number (only for non cpu local devices)
- * @cpumask: cpumask to indicate for which cpus this device works
- * @set_next_event: set next event
+ * @irq: IRQ number (only for non CPU local devices)
+ * @cpumask: cpumask to indicate for which CPUs this device works
+ * @set_next_event: set next event function
* @set_mode: set mode function
- * @evthandler: Assigned by the framework to be called by the low
+ * @event_handler: Assigned by the framework to be called by the low
* level handler of the event source
* @broadcast: function to broadcast events
* @list: list head for the management code
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index daa4940..2665ca0 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -12,6 +12,7 @@
#include <linux/timex.h>
#include <linux/time.h>
#include <linux/list.h>
+#include <linux/cache.h>
#include <linux/timer.h>
#include <asm/div64.h>
#include <asm/io.h>
@@ -52,6 +53,9 @@ struct clocksource;
* @xtime_interval: Used internally by timekeeping core, please ignore.
*/
struct clocksource {
+ /*
+ * First part of structure is read mostly
+ */
char *name;
struct list_head list;
int rating;
@@ -63,8 +67,15 @@ struct clocksource {
cycle_t (*vread)(void);
/* timekeeping specific data, ignore */
- cycle_t cycle_last, cycle_interval;
- u64 xtime_nsec, xtime_interval;
+ cycle_t cycle_interval;
+ u64 xtime_interval;
+ /*
+ * Second part is written at each timer interrupt
+ * Keep it in a different cache line to dirty no
+ * more than one cache line.
+ */
+ cycle_t cycle_last ____cacheline_aligned_in_smp;
+ u64 xtime_nsec;
s64 error;
#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
deleted file mode 100644
index c26c3ad..0000000
--- a/include/linux/compat_ioctl.h
+++ /dev/null
@@ -1,830 +0,0 @@
-/* List here explicitly which ioctl's are known to have
- * compatible types passed or none at all... Please include
- * only stuff that is compatible on *all architectures*.
- */
-
-COMPATIBLE_IOCTL(0x4B50) /* KDGHWCLK - not in the kernel, but don't complain */
-COMPATIBLE_IOCTL(0x4B51) /* KDSHWCLK - not in the kernel, but don't complain */
-
-/* Big T */
-COMPATIBLE_IOCTL(TCGETA)
-COMPATIBLE_IOCTL(TCSETA)
-COMPATIBLE_IOCTL(TCSETAW)
-COMPATIBLE_IOCTL(TCSETAF)
-COMPATIBLE_IOCTL(TCSBRK)
-ULONG_IOCTL(TCSBRKP)
-COMPATIBLE_IOCTL(TCXONC)
-COMPATIBLE_IOCTL(TCFLSH)
-COMPATIBLE_IOCTL(TCGETS)
-COMPATIBLE_IOCTL(TCSETS)
-COMPATIBLE_IOCTL(TCSETSW)
-COMPATIBLE_IOCTL(TCSETSF)
-COMPATIBLE_IOCTL(TIOCLINUX)
-COMPATIBLE_IOCTL(TIOCSBRK)
-COMPATIBLE_IOCTL(TIOCCBRK)
-ULONG_IOCTL(TIOCMIWAIT)
-COMPATIBLE_IOCTL(TIOCGICOUNT)
-/* Little t */
-COMPATIBLE_IOCTL(TIOCGETD)
-COMPATIBLE_IOCTL(TIOCSETD)
-COMPATIBLE_IOCTL(TIOCEXCL)
-COMPATIBLE_IOCTL(TIOCNXCL)
-COMPATIBLE_IOCTL(TIOCCONS)
-COMPATIBLE_IOCTL(TIOCGSOFTCAR)
-COMPATIBLE_IOCTL(TIOCSSOFTCAR)
-COMPATIBLE_IOCTL(TIOCSWINSZ)
-COMPATIBLE_IOCTL(TIOCGWINSZ)
-COMPATIBLE_IOCTL(TIOCMGET)
-COMPATIBLE_IOCTL(TIOCMBIC)
-COMPATIBLE_IOCTL(TIOCMBIS)
-COMPATIBLE_IOCTL(TIOCMSET)
-COMPATIBLE_IOCTL(TIOCPKT)
-COMPATIBLE_IOCTL(TIOCNOTTY)
-COMPATIBLE_IOCTL(TIOCSTI)
-COMPATIBLE_IOCTL(TIOCOUTQ)
-COMPATIBLE_IOCTL(TIOCSPGRP)
-COMPATIBLE_IOCTL(TIOCGPGRP)
-ULONG_IOCTL(TIOCSCTTY)
-COMPATIBLE_IOCTL(TIOCGPTN)
-COMPATIBLE_IOCTL(TIOCSPTLCK)
-COMPATIBLE_IOCTL(TIOCSERGETLSR)
-/* Little f */
-COMPATIBLE_IOCTL(FIOCLEX)
-COMPATIBLE_IOCTL(FIONCLEX)
-COMPATIBLE_IOCTL(FIOASYNC)
-COMPATIBLE_IOCTL(FIONBIO)
-COMPATIBLE_IOCTL(FIONREAD) /* This is also TIOCINQ */
-/* 0x00 */
-COMPATIBLE_IOCTL(FIBMAP)
-COMPATIBLE_IOCTL(FIGETBSZ)
-/* 0x03 -- HD/IDE ioctl's used by hdparm and friends.
- * Some need translations, these do not.
- */
-COMPATIBLE_IOCTL(HDIO_GET_IDENTITY)
-COMPATIBLE_IOCTL(HDIO_DRIVE_TASK)
-COMPATIBLE_IOCTL(HDIO_DRIVE_CMD)
-ULONG_IOCTL(HDIO_SET_MULTCOUNT)
-ULONG_IOCTL(HDIO_SET_UNMASKINTR)
-ULONG_IOCTL(HDIO_SET_KEEPSETTINGS)
-ULONG_IOCTL(HDIO_SET_32BIT)
-ULONG_IOCTL(HDIO_SET_NOWERR)
-ULONG_IOCTL(HDIO_SET_DMA)
-ULONG_IOCTL(HDIO_SET_PIO_MODE)
-ULONG_IOCTL(HDIO_SET_NICE)
-ULONG_IOCTL(HDIO_SET_WCACHE)
-ULONG_IOCTL(HDIO_SET_ACOUSTIC)
-ULONG_IOCTL(HDIO_SET_BUSSTATE)
-ULONG_IOCTL(HDIO_SET_ADDRESS)
-COMPATIBLE_IOCTL(HDIO_SCAN_HWIF)
-/* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */
-COMPATIBLE_IOCTL(0x330)
-/* 0x02 -- Floppy ioctls */
-COMPATIBLE_IOCTL(FDMSGON)
-COMPATIBLE_IOCTL(FDMSGOFF)
-COMPATIBLE_IOCTL(FDSETEMSGTRESH)
-COMPATIBLE_IOCTL(FDFLUSH)
-COMPATIBLE_IOCTL(FDWERRORCLR)
-COMPATIBLE_IOCTL(FDSETMAXERRS)
-COMPATIBLE_IOCTL(FDGETMAXERRS)
-COMPATIBLE_IOCTL(FDGETDRVTYP)
-COMPATIBLE_IOCTL(FDEJECT)
-COMPATIBLE_IOCTL(FDCLRPRM)
-COMPATIBLE_IOCTL(FDFMTBEG)
-COMPATIBLE_IOCTL(FDFMTEND)
-COMPATIBLE_IOCTL(FDRESET)
-COMPATIBLE_IOCTL(FDTWADDLE)
-COMPATIBLE_IOCTL(FDFMTTRK)
-COMPATIBLE_IOCTL(FDRAWCMD)
-/* 0x12 */
-#ifdef CONFIG_BLOCK
-COMPATIBLE_IOCTL(BLKRASET)
-COMPATIBLE_IOCTL(BLKROSET)
-COMPATIBLE_IOCTL(BLKROGET)
-COMPATIBLE_IOCTL(BLKRRPART)
-COMPATIBLE_IOCTL(BLKFLSBUF)
-COMPATIBLE_IOCTL(BLKSECTSET)
-COMPATIBLE_IOCTL(BLKSSZGET)
-COMPATIBLE_IOCTL(BLKTRACESTART)
-COMPATIBLE_IOCTL(BLKTRACESTOP)
-COMPATIBLE_IOCTL(BLKTRACESETUP)
-COMPATIBLE_IOCTL(BLKTRACETEARDOWN)
-ULONG_IOCTL(BLKRASET)
-ULONG_IOCTL(BLKFRASET)
-#endif
-/* RAID */
-COMPATIBLE_IOCTL(RAID_VERSION)
-COMPATIBLE_IOCTL(GET_ARRAY_INFO)
-COMPATIBLE_IOCTL(GET_DISK_INFO)
-COMPATIBLE_IOCTL(PRINT_RAID_DEBUG)
-COMPATIBLE_IOCTL(RAID_AUTORUN)
-COMPATIBLE_IOCTL(CLEAR_ARRAY)
-COMPATIBLE_IOCTL(ADD_NEW_DISK)
-ULONG_IOCTL(HOT_REMOVE_DISK)
-COMPATIBLE_IOCTL(SET_ARRAY_INFO)
-COMPATIBLE_IOCTL(SET_DISK_INFO)
-COMPATIBLE_IOCTL(WRITE_RAID_INFO)
-COMPATIBLE_IOCTL(UNPROTECT_ARRAY)
-COMPATIBLE_IOCTL(PROTECT_ARRAY)
-ULONG_IOCTL(HOT_ADD_DISK)
-ULONG_IOCTL(SET_DISK_FAULTY)
-COMPATIBLE_IOCTL(RUN_ARRAY)
-COMPATIBLE_IOCTL(STOP_ARRAY)
-COMPATIBLE_IOCTL(STOP_ARRAY_RO)
-COMPATIBLE_IOCTL(RESTART_ARRAY_RW)
-COMPATIBLE_IOCTL(GET_BITMAP_FILE)
-ULONG_IOCTL(SET_BITMAP_FILE)
-/* DM */
-COMPATIBLE_IOCTL(DM_VERSION_32)
-COMPATIBLE_IOCTL(DM_REMOVE_ALL_32)
-COMPATIBLE_IOCTL(DM_LIST_DEVICES_32)
-COMPATIBLE_IOCTL(DM_DEV_CREATE_32)
-COMPATIBLE_IOCTL(DM_DEV_REMOVE_32)
-COMPATIBLE_IOCTL(DM_DEV_RENAME_32)
-COMPATIBLE_IOCTL(DM_DEV_SUSPEND_32)
-COMPATIBLE_IOCTL(DM_DEV_STATUS_32)
-COMPATIBLE_IOCTL(DM_DEV_WAIT_32)
-COMPATIBLE_IOCTL(DM_TABLE_LOAD_32)
-COMPATIBLE_IOCTL(DM_TABLE_CLEAR_32)
-COMPATIBLE_IOCTL(DM_TABLE_DEPS_32)
-COMPATIBLE_IOCTL(DM_TABLE_STATUS_32)
-COMPATIBLE_IOCTL(DM_LIST_VERSIONS_32)
-COMPATIBLE_IOCTL(DM_TARGET_MSG_32)
-COMPATIBLE_IOCTL(DM_DEV_SET_GEOMETRY_32)
-COMPATIBLE_IOCTL(DM_VERSION)
-COMPATIBLE_IOCTL(DM_REMOVE_ALL)
-COMPATIBLE_IOCTL(DM_LIST_DEVICES)
-COMPATIBLE_IOCTL(DM_DEV_CREATE)
-COMPATIBLE_IOCTL(DM_DEV_REMOVE)
-COMPATIBLE_IOCTL(DM_DEV_RENAME)
-COMPATIBLE_IOCTL(DM_DEV_SUSPEND)
-COMPATIBLE_IOCTL(DM_DEV_STATUS)
-COMPATIBLE_IOCTL(DM_DEV_WAIT)
-COMPATIBLE_IOCTL(DM_TABLE_LOAD)
-COMPATIBLE_IOCTL(DM_TABLE_CLEAR)
-COMPATIBLE_IOCTL(DM_TABLE_DEPS)
-COMPATIBLE_IOCTL(DM_TABLE_STATUS)
-COMPATIBLE_IOCTL(DM_LIST_VERSIONS)
-COMPATIBLE_IOCTL(DM_TARGET_MSG)
-COMPATIBLE_IOCTL(DM_DEV_SET_GEOMETRY)
-/* Big K */
-COMPATIBLE_IOCTL(PIO_FONT)
-COMPATIBLE_IOCTL(GIO_FONT)
-ULONG_IOCTL(KDSIGACCEPT)
-COMPATIBLE_IOCTL(KDGETKEYCODE)
-COMPATIBLE_IOCTL(KDSETKEYCODE)
-ULONG_IOCTL(KIOCSOUND)
-ULONG_IOCTL(KDMKTONE)
-COMPATIBLE_IOCTL(KDGKBTYPE)
-ULONG_IOCTL(KDSETMODE)
-COMPATIBLE_IOCTL(KDGETMODE)
-ULONG_IOCTL(KDSKBMODE)
-COMPATIBLE_IOCTL(KDGKBMODE)
-ULONG_IOCTL(KDSKBMETA)
-COMPATIBLE_IOCTL(KDGKBMETA)
-COMPATIBLE_IOCTL(KDGKBENT)
-COMPATIBLE_IOCTL(KDSKBENT)
-COMPATIBLE_IOCTL(KDGKBSENT)
-COMPATIBLE_IOCTL(KDSKBSENT)
-COMPATIBLE_IOCTL(KDGKBDIACR)
-COMPATIBLE_IOCTL(KDSKBDIACR)
-COMPATIBLE_IOCTL(KDKBDREP)
-COMPATIBLE_IOCTL(KDGKBLED)
-ULONG_IOCTL(KDSKBLED)
-COMPATIBLE_IOCTL(KDGETLED)
-ULONG_IOCTL(KDSETLED)
-COMPATIBLE_IOCTL(GIO_SCRNMAP)
-COMPATIBLE_IOCTL(PIO_SCRNMAP)
-COMPATIBLE_IOCTL(GIO_UNISCRNMAP)
-COMPATIBLE_IOCTL(PIO_UNISCRNMAP)
-COMPATIBLE_IOCTL(PIO_FONTRESET)
-COMPATIBLE_IOCTL(PIO_UNIMAPCLR)
-/* Big S */
-COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN)
-COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK)
-COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK)
-COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY)
-COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER)
-COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
-COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
-COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
-/* Big T */
-COMPATIBLE_IOCTL(TUNSETNOCSUM)
-COMPATIBLE_IOCTL(TUNSETDEBUG)
-COMPATIBLE_IOCTL(TUNSETPERSIST)
-COMPATIBLE_IOCTL(TUNSETOWNER)
-/* Big V */
-COMPATIBLE_IOCTL(VT_SETMODE)
-COMPATIBLE_IOCTL(VT_GETMODE)
-COMPATIBLE_IOCTL(VT_GETSTATE)
-COMPATIBLE_IOCTL(VT_OPENQRY)
-ULONG_IOCTL(VT_ACTIVATE)
-ULONG_IOCTL(VT_WAITACTIVE)
-ULONG_IOCTL(VT_RELDISP)
-ULONG_IOCTL(VT_DISALLOCATE)
-COMPATIBLE_IOCTL(VT_RESIZE)
-COMPATIBLE_IOCTL(VT_RESIZEX)
-COMPATIBLE_IOCTL(VT_LOCKSWITCH)
-COMPATIBLE_IOCTL(VT_UNLOCKSWITCH)
-COMPATIBLE_IOCTL(VT_GETHIFONTMASK)
-/* Little p (/dev/rtc, /dev/envctrl, etc.) */
-COMPATIBLE_IOCTL(RTC_AIE_ON)
-COMPATIBLE_IOCTL(RTC_AIE_OFF)
-COMPATIBLE_IOCTL(RTC_UIE_ON)
-COMPATIBLE_IOCTL(RTC_UIE_OFF)
-COMPATIBLE_IOCTL(RTC_PIE_ON)
-COMPATIBLE_IOCTL(RTC_PIE_OFF)
-COMPATIBLE_IOCTL(RTC_WIE_ON)
-COMPATIBLE_IOCTL(RTC_WIE_OFF)
-COMPATIBLE_IOCTL(RTC_ALM_SET)
-COMPATIBLE_IOCTL(RTC_ALM_READ)
-COMPATIBLE_IOCTL(RTC_RD_TIME)
-COMPATIBLE_IOCTL(RTC_SET_TIME)
-COMPATIBLE_IOCTL(RTC_WKALM_SET)
-COMPATIBLE_IOCTL(RTC_WKALM_RD)
-/*
- * These two are only for the sbus rtc driver, but
- * hwclock tries them on every rtc device first when
- * running on sparc. On other architectures the entries
- * are useless but harmless.
- */
-COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
-COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
-/* Little m */
-COMPATIBLE_IOCTL(MTIOCTOP)
-/* Socket level stuff */
-COMPATIBLE_IOCTL(FIOQSIZE)
-COMPATIBLE_IOCTL(FIOSETOWN)
-COMPATIBLE_IOCTL(SIOCSPGRP)
-COMPATIBLE_IOCTL(FIOGETOWN)
-COMPATIBLE_IOCTL(SIOCGPGRP)
-COMPATIBLE_IOCTL(SIOCATMARK)
-COMPATIBLE_IOCTL(SIOCSIFLINK)
-COMPATIBLE_IOCTL(SIOCSIFENCAP)
-COMPATIBLE_IOCTL(SIOCGIFENCAP)
-COMPATIBLE_IOCTL(SIOCSIFNAME)
-COMPATIBLE_IOCTL(SIOCSARP)
-COMPATIBLE_IOCTL(SIOCGARP)
-COMPATIBLE_IOCTL(SIOCDARP)
-COMPATIBLE_IOCTL(SIOCSRARP)
-COMPATIBLE_IOCTL(SIOCGRARP)
-COMPATIBLE_IOCTL(SIOCDRARP)
-COMPATIBLE_IOCTL(SIOCADDDLCI)
-COMPATIBLE_IOCTL(SIOCDELDLCI)
-COMPATIBLE_IOCTL(SIOCGMIIPHY)
-COMPATIBLE_IOCTL(SIOCGMIIREG)
-COMPATIBLE_IOCTL(SIOCSMIIREG)
-COMPATIBLE_IOCTL(SIOCGIFVLAN)
-COMPATIBLE_IOCTL(SIOCSIFVLAN)
-COMPATIBLE_IOCTL(SIOCBRADDBR)
-COMPATIBLE_IOCTL(SIOCBRDELBR)
-/* SG stuff */
-COMPATIBLE_IOCTL(SG_SET_TIMEOUT)
-COMPATIBLE_IOCTL(SG_GET_TIMEOUT)
-COMPATIBLE_IOCTL(SG_EMULATED_HOST)
-ULONG_IOCTL(SG_SET_TRANSFORM)
-COMPATIBLE_IOCTL(SG_GET_TRANSFORM)
-COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE)
-COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE)
-COMPATIBLE_IOCTL(SG_GET_SCSI_ID)
-COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA)
-COMPATIBLE_IOCTL(SG_GET_LOW_DMA)
-COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID)
-COMPATIBLE_IOCTL(SG_GET_PACK_ID)
-COMPATIBLE_IOCTL(SG_GET_NUM_WAITING)
-COMPATIBLE_IOCTL(SG_SET_DEBUG)
-COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE)
-COMPATIBLE_IOCTL(SG_GET_COMMAND_Q)
-COMPATIBLE_IOCTL(SG_SET_COMMAND_Q)
-COMPATIBLE_IOCTL(SG_GET_VERSION_NUM)
-COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN)
-COMPATIBLE_IOCTL(SG_SCSI_RESET)
-COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE)
-COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN)
-COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN)
-/* PPP stuff */
-COMPATIBLE_IOCTL(PPPIOCGFLAGS)
-COMPATIBLE_IOCTL(PPPIOCSFLAGS)
-COMPATIBLE_IOCTL(PPPIOCGASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCGUNIT)
-COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCGMRU)
-COMPATIBLE_IOCTL(PPPIOCSMRU)
-COMPATIBLE_IOCTL(PPPIOCSMAXCID)
-COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
-COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
-/* PPPIOCSCOMPRESS is translated */
-COMPATIBLE_IOCTL(PPPIOCGNPMODE)
-COMPATIBLE_IOCTL(PPPIOCSNPMODE)
-COMPATIBLE_IOCTL(PPPIOCGDEBUG)
-COMPATIBLE_IOCTL(PPPIOCSDEBUG)
-/* PPPIOCSPASS is translated */
-/* PPPIOCSACTIVE is translated */
-/* PPPIOCGIDLE is translated */
-COMPATIBLE_IOCTL(PPPIOCNEWUNIT)
-COMPATIBLE_IOCTL(PPPIOCATTACH)
-COMPATIBLE_IOCTL(PPPIOCDETACH)
-COMPATIBLE_IOCTL(PPPIOCSMRRU)
-COMPATIBLE_IOCTL(PPPIOCCONNECT)
-COMPATIBLE_IOCTL(PPPIOCDISCONN)
-COMPATIBLE_IOCTL(PPPIOCATTCHAN)
-COMPATIBLE_IOCTL(PPPIOCGCHAN)
-/* PPPOX */
-COMPATIBLE_IOCTL(PPPOEIOCSFWD)
-COMPATIBLE_IOCTL(PPPOEIOCDFWD)
-/* LP */
-COMPATIBLE_IOCTL(LPGETSTATUS)
-/* ppdev */
-COMPATIBLE_IOCTL(PPSETMODE)
-COMPATIBLE_IOCTL(PPRSTATUS)
-COMPATIBLE_IOCTL(PPRCONTROL)
-COMPATIBLE_IOCTL(PPWCONTROL)
-COMPATIBLE_IOCTL(PPFCONTROL)
-COMPATIBLE_IOCTL(PPRDATA)
-COMPATIBLE_IOCTL(PPWDATA)
-COMPATIBLE_IOCTL(PPCLAIM)
-COMPATIBLE_IOCTL(PPRELEASE)
-COMPATIBLE_IOCTL(PPYIELD)
-COMPATIBLE_IOCTL(PPEXCL)
-COMPATIBLE_IOCTL(PPDATADIR)
-COMPATIBLE_IOCTL(PPNEGOT)
-COMPATIBLE_IOCTL(PPWCTLONIRQ)
-COMPATIBLE_IOCTL(PPCLRIRQ)
-COMPATIBLE_IOCTL(PPSETPHASE)
-COMPATIBLE_IOCTL(PPGETMODES)
-COMPATIBLE_IOCTL(PPGETMODE)
-COMPATIBLE_IOCTL(PPGETPHASE)
-COMPATIBLE_IOCTL(PPGETFLAGS)
-COMPATIBLE_IOCTL(PPSETFLAGS)
-/* CDROM stuff */
-COMPATIBLE_IOCTL(CDROMPAUSE)
-COMPATIBLE_IOCTL(CDROMRESUME)
-COMPATIBLE_IOCTL(CDROMPLAYMSF)
-COMPATIBLE_IOCTL(CDROMPLAYTRKIND)
-COMPATIBLE_IOCTL(CDROMREADTOCHDR)
-COMPATIBLE_IOCTL(CDROMREADTOCENTRY)
-COMPATIBLE_IOCTL(CDROMSTOP)
-COMPATIBLE_IOCTL(CDROMSTART)
-COMPATIBLE_IOCTL(CDROMEJECT)
-COMPATIBLE_IOCTL(CDROMVOLCTRL)
-COMPATIBLE_IOCTL(CDROMSUBCHNL)
-ULONG_IOCTL(CDROMEJECT_SW)
-COMPATIBLE_IOCTL(CDROMMULTISESSION)
-COMPATIBLE_IOCTL(CDROM_GET_MCN)
-COMPATIBLE_IOCTL(CDROMRESET)
-COMPATIBLE_IOCTL(CDROMVOLREAD)
-COMPATIBLE_IOCTL(CDROMSEEK)
-COMPATIBLE_IOCTL(CDROMPLAYBLK)
-COMPATIBLE_IOCTL(CDROMCLOSETRAY)
-ULONG_IOCTL(CDROM_SET_OPTIONS)
-ULONG_IOCTL(CDROM_CLEAR_OPTIONS)
-ULONG_IOCTL(CDROM_SELECT_SPEED)
-ULONG_IOCTL(CDROM_SELECT_DISC)
-ULONG_IOCTL(CDROM_MEDIA_CHANGED)
-ULONG_IOCTL(CDROM_DRIVE_STATUS)
-COMPATIBLE_IOCTL(CDROM_DISC_STATUS)
-COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS)
-ULONG_IOCTL(CDROM_LOCKDOOR)
-ULONG_IOCTL(CDROM_DEBUG)
-COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY)
-/* Ignore cdrom.h about these next 5 ioctls, they absolutely do
- * not take a struct cdrom_read, instead they take a struct cdrom_msf
- * which is compatible.
- */
-COMPATIBLE_IOCTL(CDROMREADMODE2)
-COMPATIBLE_IOCTL(CDROMREADMODE1)
-COMPATIBLE_IOCTL(CDROMREADRAW)
-COMPATIBLE_IOCTL(CDROMREADCOOKED)
-COMPATIBLE_IOCTL(CDROMREADALL)
-/* DVD ioctls */
-COMPATIBLE_IOCTL(DVD_READ_STRUCT)
-COMPATIBLE_IOCTL(DVD_WRITE_STRUCT)
-COMPATIBLE_IOCTL(DVD_AUTH)
-/* pktcdvd */
-COMPATIBLE_IOCTL(PACKET_CTRL_CMD)
-/* Big A */
-/* sparc only */
-/* Big Q for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_SEQ_RESET)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_SYNC)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_INFO)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_CTRLRATE)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_GETOUTCOUNT)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_GETINCOUNT)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_PERCMODE)
-COMPATIBLE_IOCTL(SNDCTL_FM_LOAD_INSTR)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_TESTMIDI)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_RESETSAMPLES)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_NRSYNTHS)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_NRMIDIS)
-COMPATIBLE_IOCTL(SNDCTL_MIDI_INFO)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_THRESHOLD)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_MEMAVL)
-COMPATIBLE_IOCTL(SNDCTL_FM_4OP_ENABLE)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_PANIC)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_OUTOFBAND)
-COMPATIBLE_IOCTL(SNDCTL_SEQ_GETTIME)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_ID)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_CONTROL)
-COMPATIBLE_IOCTL(SNDCTL_SYNTH_REMOVESAMPLE)
-/* Big T for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_TMR_TIMEBASE)
-COMPATIBLE_IOCTL(SNDCTL_TMR_START)
-COMPATIBLE_IOCTL(SNDCTL_TMR_STOP)
-COMPATIBLE_IOCTL(SNDCTL_TMR_CONTINUE)
-COMPATIBLE_IOCTL(SNDCTL_TMR_TEMPO)
-COMPATIBLE_IOCTL(SNDCTL_TMR_SOURCE)
-COMPATIBLE_IOCTL(SNDCTL_TMR_METRONOME)
-COMPATIBLE_IOCTL(SNDCTL_TMR_SELECT)
-/* Little m for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_MIDI_PRETIME)
-COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUMODE)
-COMPATIBLE_IOCTL(SNDCTL_MIDI_MPUCMD)
-/* Big P for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_DSP_RESET)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SYNC)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SPEED)
-COMPATIBLE_IOCTL(SNDCTL_DSP_STEREO)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETBLKSIZE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_CHANNELS)
-COMPATIBLE_IOCTL(SOUND_PCM_WRITE_FILTER)
-COMPATIBLE_IOCTL(SNDCTL_DSP_POST)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SUBDIVIDE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETFRAGMENT)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETFMTS)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETFMT)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETOSPACE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETISPACE)
-COMPATIBLE_IOCTL(SNDCTL_DSP_NONBLOCK)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETCAPS)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETTRIGGER)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETTRIGGER)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETIPTR)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETOPTR)
-/* SNDCTL_DSP_MAPINBUF, XXX needs translation */
-/* SNDCTL_DSP_MAPOUTBUF, XXX needs translation */
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETSYNCRO)
-COMPATIBLE_IOCTL(SNDCTL_DSP_SETDUPLEX)
-COMPATIBLE_IOCTL(SNDCTL_DSP_GETODELAY)
-COMPATIBLE_IOCTL(SNDCTL_DSP_PROFILE)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_RATE)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_CHANNELS)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_BITS)
-COMPATIBLE_IOCTL(SOUND_PCM_READ_FILTER)
-/* Big C for sound/OSS */
-COMPATIBLE_IOCTL(SNDCTL_COPR_RESET)
-COMPATIBLE_IOCTL(SNDCTL_COPR_LOAD)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RDATA)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RCODE)
-COMPATIBLE_IOCTL(SNDCTL_COPR_WDATA)
-COMPATIBLE_IOCTL(SNDCTL_COPR_WCODE)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RUN)
-COMPATIBLE_IOCTL(SNDCTL_COPR_HALT)
-COMPATIBLE_IOCTL(SNDCTL_COPR_SENDMSG)
-COMPATIBLE_IOCTL(SNDCTL_COPR_RCVMSG)
-/* Big M for sound/OSS */
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_VOLUME)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_BASS)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_TREBLE)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_SYNTH)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_PCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_SPEAKER)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_MIC)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_CD)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_IMIX)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_ALTPCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECLEV)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_IGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_OGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE1)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE2)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_LINE3)
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL1))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL2))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_DIGITAL3))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEIN))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_PHONEOUT))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_VIDEO))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_RADIO))
-COMPATIBLE_IOCTL(MIXER_READ(SOUND_MIXER_MONITOR))
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_MUTE)
-/* SOUND_MIXER_READ_ENHANCE, same value as READ_MUTE */
-/* SOUND_MIXER_READ_LOUD, same value as READ_MUTE */
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECSRC)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_DEVMASK)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_RECMASK)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_STEREODEVS)
-COMPATIBLE_IOCTL(SOUND_MIXER_READ_CAPS)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_VOLUME)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_BASS)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_TREBLE)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SYNTH)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_PCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_SPEAKER)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MIC)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_CD)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IMIX)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_ALTPCM)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECLEV)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_IGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_OGAIN)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE1)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE2)
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_LINE3)
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL1))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL2))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_DIGITAL3))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEIN))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_PHONEOUT))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_VIDEO))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_RADIO))
-COMPATIBLE_IOCTL(MIXER_WRITE(SOUND_MIXER_MONITOR))
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_MUTE)
-/* SOUND_MIXER_WRITE_ENHANCE, same value as WRITE_MUTE */
-/* SOUND_MIXER_WRITE_LOUD, same value as WRITE_MUTE */
-COMPATIBLE_IOCTL(SOUND_MIXER_WRITE_RECSRC)
-COMPATIBLE_IOCTL(SOUND_MIXER_INFO)
-COMPATIBLE_IOCTL(SOUND_OLD_MIXER_INFO)
-COMPATIBLE_IOCTL(SOUND_MIXER_ACCESS)
-COMPATIBLE_IOCTL(SOUND_MIXER_AGC)
-COMPATIBLE_IOCTL(SOUND_MIXER_3DSE)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE1)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE2)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE3)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE4)
-COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5)
-COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS)
-COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS)
-COMPATIBLE_IOCTL(OSS_GETVERSION)
-/* AUTOFS */
-ULONG_IOCTL(AUTOFS_IOC_READY)
-ULONG_IOCTL(AUTOFS_IOC_FAIL)
-COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC)
-COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER)
-COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE)
-COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI)
-COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER)
-COMPATIBLE_IOCTL(AUTOFS_IOC_ASKREGHOST)
-COMPATIBLE_IOCTL(AUTOFS_IOC_TOGGLEREGHOST)
-COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT)
-/* Raw devices */
-COMPATIBLE_IOCTL(RAW_SETBIND)
-COMPATIBLE_IOCTL(RAW_GETBIND)
-/* SMB ioctls which do not need any translations */
-COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
-/* Little a */
-COMPATIBLE_IOCTL(ATMSIGD_CTRL)
-COMPATIBLE_IOCTL(ATMARPD_CTRL)
-COMPATIBLE_IOCTL(ATMLEC_CTRL)
-COMPATIBLE_IOCTL(ATMLEC_MCAST)
-COMPATIBLE_IOCTL(ATMLEC_DATA)
-COMPATIBLE_IOCTL(ATM_SETSC)
-COMPATIBLE_IOCTL(SIOCSIFATMTCP)
-COMPATIBLE_IOCTL(SIOCMKCLIP)
-COMPATIBLE_IOCTL(ATMARP_MKIP)
-COMPATIBLE_IOCTL(ATMARP_SETENTRY)
-COMPATIBLE_IOCTL(ATMARP_ENCAP)
-COMPATIBLE_IOCTL(ATMTCP_CREATE)
-COMPATIBLE_IOCTL(ATMTCP_REMOVE)
-COMPATIBLE_IOCTL(ATMMPC_CTRL)
-COMPATIBLE_IOCTL(ATMMPC_DATA)
-/* Watchdog */
-COMPATIBLE_IOCTL(WDIOC_GETSUPPORT)
-COMPATIBLE_IOCTL(WDIOC_GETSTATUS)
-COMPATIBLE_IOCTL(WDIOC_GETBOOTSTATUS)
-COMPATIBLE_IOCTL(WDIOC_GETTEMP)
-COMPATIBLE_IOCTL(WDIOC_SETOPTIONS)
-COMPATIBLE_IOCTL(WDIOC_KEEPALIVE)
-COMPATIBLE_IOCTL(WDIOC_SETTIMEOUT)
-COMPATIBLE_IOCTL(WDIOC_GETTIMEOUT)
-/* Big R */
-COMPATIBLE_IOCTL(RNDGETENTCNT)
-COMPATIBLE_IOCTL(RNDADDTOENTCNT)
-COMPATIBLE_IOCTL(RNDGETPOOL)
-COMPATIBLE_IOCTL(RNDADDENTROPY)
-COMPATIBLE_IOCTL(RNDZAPENTCNT)
-COMPATIBLE_IOCTL(RNDCLEARPOOL)
-/* Bluetooth */
-COMPATIBLE_IOCTL(HCIDEVUP)
-COMPATIBLE_IOCTL(HCIDEVDOWN)
-COMPATIBLE_IOCTL(HCIDEVRESET)
-COMPATIBLE_IOCTL(HCIDEVRESTAT)
-COMPATIBLE_IOCTL(HCIGETDEVLIST)
-COMPATIBLE_IOCTL(HCIGETDEVINFO)
-COMPATIBLE_IOCTL(HCIGETCONNLIST)
-COMPATIBLE_IOCTL(HCIGETCONNINFO)
-COMPATIBLE_IOCTL(HCISETRAW)
-COMPATIBLE_IOCTL(HCISETSCAN)
-COMPATIBLE_IOCTL(HCISETAUTH)
-COMPATIBLE_IOCTL(HCISETENCRYPT)
-COMPATIBLE_IOCTL(HCISETPTYPE)
-COMPATIBLE_IOCTL(HCISETLINKPOL)
-COMPATIBLE_IOCTL(HCISETLINKMODE)
-COMPATIBLE_IOCTL(HCISETACLMTU)
-COMPATIBLE_IOCTL(HCISETSCOMTU)
-COMPATIBLE_IOCTL(HCIINQUIRY)
-COMPATIBLE_IOCTL(HCIUARTSETPROTO)
-COMPATIBLE_IOCTL(HCIUARTGETPROTO)
-COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
-COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
-COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
-COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
-COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
-COMPATIBLE_IOCTL(BNEPCONNADD)
-COMPATIBLE_IOCTL(BNEPCONNDEL)
-COMPATIBLE_IOCTL(BNEPGETCONNLIST)
-COMPATIBLE_IOCTL(BNEPGETCONNINFO)
-COMPATIBLE_IOCTL(CMTPCONNADD)
-COMPATIBLE_IOCTL(CMTPCONNDEL)
-COMPATIBLE_IOCTL(CMTPGETCONNLIST)
-COMPATIBLE_IOCTL(CMTPGETCONNINFO)
-COMPATIBLE_IOCTL(HIDPCONNADD)
-COMPATIBLE_IOCTL(HIDPCONNDEL)
-COMPATIBLE_IOCTL(HIDPGETCONNLIST)
-COMPATIBLE_IOCTL(HIDPGETCONNINFO)
-/* CAPI */
-COMPATIBLE_IOCTL(CAPI_REGISTER)
-COMPATIBLE_IOCTL(CAPI_GET_MANUFACTURER)
-COMPATIBLE_IOCTL(CAPI_GET_VERSION)
-COMPATIBLE_IOCTL(CAPI_GET_SERIAL)
-COMPATIBLE_IOCTL(CAPI_GET_PROFILE)
-COMPATIBLE_IOCTL(CAPI_MANUFACTURER_CMD)
-COMPATIBLE_IOCTL(CAPI_GET_ERRCODE)
-COMPATIBLE_IOCTL(CAPI_INSTALLED)
-COMPATIBLE_IOCTL(CAPI_GET_FLAGS)
-COMPATIBLE_IOCTL(CAPI_SET_FLAGS)
-COMPATIBLE_IOCTL(CAPI_CLR_FLAGS)
-COMPATIBLE_IOCTL(CAPI_NCCI_OPENCOUNT)
-COMPATIBLE_IOCTL(CAPI_NCCI_GETUNIT)
-/* Siemens Gigaset */
-COMPATIBLE_IOCTL(GIGASET_REDIR)
-COMPATIBLE_IOCTL(GIGASET_CONFIG)
-COMPATIBLE_IOCTL(GIGASET_BRKCHARS)
-COMPATIBLE_IOCTL(GIGASET_VERSION)
-/* Misc. */
-COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */
-COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */
-COMPATIBLE_IOCTL(PCIIOC_CONTROLLER)
-COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO)
-COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM)
-COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE)
-/* USB */
-COMPATIBLE_IOCTL(USBDEVFS_RESETEP)
-COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE)
-COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION)
-COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER)
-COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB)
-COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE)
-COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE)
-COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO)
-COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO)
-COMPATIBLE_IOCTL(USBDEVFS_RESET)
-COMPATIBLE_IOCTL(USBDEVFS_SUBMITURB32)
-COMPATIBLE_IOCTL(USBDEVFS_REAPURB32)
-COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32)
-COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT)
-/* MTD */
-COMPATIBLE_IOCTL(MEMGETINFO)
-COMPATIBLE_IOCTL(MEMERASE)
-COMPATIBLE_IOCTL(MEMLOCK)
-COMPATIBLE_IOCTL(MEMUNLOCK)
-COMPATIBLE_IOCTL(MEMGETREGIONCOUNT)
-COMPATIBLE_IOCTL(MEMGETREGIONINFO)
-COMPATIBLE_IOCTL(MEMGETBADBLOCK)
-COMPATIBLE_IOCTL(MEMSETBADBLOCK)
-/* NBD */
-ULONG_IOCTL(NBD_SET_SOCK)
-ULONG_IOCTL(NBD_SET_BLKSIZE)
-ULONG_IOCTL(NBD_SET_SIZE)
-COMPATIBLE_IOCTL(NBD_DO_IT)
-COMPATIBLE_IOCTL(NBD_CLEAR_SOCK)
-COMPATIBLE_IOCTL(NBD_CLEAR_QUE)
-COMPATIBLE_IOCTL(NBD_PRINT_DEBUG)
-ULONG_IOCTL(NBD_SET_SIZE_BLOCKS)
-COMPATIBLE_IOCTL(NBD_DISCONNECT)
-/* i2c */
-COMPATIBLE_IOCTL(I2C_SLAVE)
-COMPATIBLE_IOCTL(I2C_SLAVE_FORCE)
-COMPATIBLE_IOCTL(I2C_TENBIT)
-COMPATIBLE_IOCTL(I2C_PEC)
-COMPATIBLE_IOCTL(I2C_RETRIES)
-COMPATIBLE_IOCTL(I2C_TIMEOUT)
-/* wireless */
-COMPATIBLE_IOCTL(SIOCSIWCOMMIT)
-COMPATIBLE_IOCTL(SIOCGIWNAME)
-COMPATIBLE_IOCTL(SIOCSIWNWID)
-COMPATIBLE_IOCTL(SIOCGIWNWID)
-COMPATIBLE_IOCTL(SIOCSIWFREQ)
-COMPATIBLE_IOCTL(SIOCGIWFREQ)
-COMPATIBLE_IOCTL(SIOCSIWMODE)
-COMPATIBLE_IOCTL(SIOCGIWMODE)
-COMPATIBLE_IOCTL(SIOCSIWSENS)
-COMPATIBLE_IOCTL(SIOCGIWSENS)
-COMPATIBLE_IOCTL(SIOCSIWRANGE)
-COMPATIBLE_IOCTL(SIOCSIWPRIV)
-COMPATIBLE_IOCTL(SIOCGIWPRIV)
-COMPATIBLE_IOCTL(SIOCSIWSTATS)
-COMPATIBLE_IOCTL(SIOCGIWSTATS)
-COMPATIBLE_IOCTL(SIOCSIWAP)
-COMPATIBLE_IOCTL(SIOCGIWAP)
-COMPATIBLE_IOCTL(SIOCSIWSCAN)
-COMPATIBLE_IOCTL(SIOCSIWRATE)
-COMPATIBLE_IOCTL(SIOCGIWRATE)
-COMPATIBLE_IOCTL(SIOCSIWRTS)
-COMPATIBLE_IOCTL(SIOCGIWRTS)
-COMPATIBLE_IOCTL(SIOCSIWFRAG)
-COMPATIBLE_IOCTL(SIOCGIWFRAG)
-COMPATIBLE_IOCTL(SIOCSIWTXPOW)
-COMPATIBLE_IOCTL(SIOCGIWTXPOW)
-COMPATIBLE_IOCTL(SIOCSIWRETRY)
-COMPATIBLE_IOCTL(SIOCGIWRETRY)
-COMPATIBLE_IOCTL(SIOCSIWPOWER)
-COMPATIBLE_IOCTL(SIOCGIWPOWER)
-/* hiddev */
-COMPATIBLE_IOCTL(HIDIOCGVERSION)
-COMPATIBLE_IOCTL(HIDIOCAPPLICATION)
-COMPATIBLE_IOCTL(HIDIOCGDEVINFO)
-COMPATIBLE_IOCTL(HIDIOCGSTRING)
-COMPATIBLE_IOCTL(HIDIOCINITREPORT)
-COMPATIBLE_IOCTL(HIDIOCGREPORT)
-COMPATIBLE_IOCTL(HIDIOCSREPORT)
-COMPATIBLE_IOCTL(HIDIOCGREPORTINFO)
-COMPATIBLE_IOCTL(HIDIOCGFIELDINFO)
-COMPATIBLE_IOCTL(HIDIOCGUSAGE)
-COMPATIBLE_IOCTL(HIDIOCSUSAGE)
-COMPATIBLE_IOCTL(HIDIOCGUCODE)
-COMPATIBLE_IOCTL(HIDIOCGFLAG)
-COMPATIBLE_IOCTL(HIDIOCSFLAG)
-COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINDEX)
-COMPATIBLE_IOCTL(HIDIOCGCOLLECTIONINFO)
-/* dvb */
-COMPATIBLE_IOCTL(AUDIO_STOP)
-COMPATIBLE_IOCTL(AUDIO_PLAY)
-COMPATIBLE_IOCTL(AUDIO_PAUSE)
-COMPATIBLE_IOCTL(AUDIO_CONTINUE)
-COMPATIBLE_IOCTL(AUDIO_SELECT_SOURCE)
-COMPATIBLE_IOCTL(AUDIO_SET_MUTE)
-COMPATIBLE_IOCTL(AUDIO_SET_AV_SYNC)
-COMPATIBLE_IOCTL(AUDIO_SET_BYPASS_MODE)
-COMPATIBLE_IOCTL(AUDIO_CHANNEL_SELECT)
-COMPATIBLE_IOCTL(AUDIO_GET_STATUS)
-COMPATIBLE_IOCTL(AUDIO_GET_CAPABILITIES)
-COMPATIBLE_IOCTL(AUDIO_CLEAR_BUFFER)
-COMPATIBLE_IOCTL(AUDIO_SET_ID)
-COMPATIBLE_IOCTL(AUDIO_SET_MIXER)
-COMPATIBLE_IOCTL(AUDIO_SET_STREAMTYPE)
-COMPATIBLE_IOCTL(AUDIO_SET_EXT_ID)
-COMPATIBLE_IOCTL(AUDIO_SET_ATTRIBUTES)
-COMPATIBLE_IOCTL(AUDIO_SET_KARAOKE)
-COMPATIBLE_IOCTL(DMX_START)
-COMPATIBLE_IOCTL(DMX_STOP)
-COMPATIBLE_IOCTL(DMX_SET_FILTER)
-COMPATIBLE_IOCTL(DMX_SET_PES_FILTER)
-COMPATIBLE_IOCTL(DMX_SET_BUFFER_SIZE)
-COMPATIBLE_IOCTL(DMX_GET_PES_PIDS)
-COMPATIBLE_IOCTL(DMX_GET_CAPS)
-COMPATIBLE_IOCTL(DMX_SET_SOURCE)
-COMPATIBLE_IOCTL(DMX_GET_STC)
-COMPATIBLE_IOCTL(FE_GET_INFO)
-COMPATIBLE_IOCTL(FE_DISEQC_RESET_OVERLOAD)
-COMPATIBLE_IOCTL(FE_DISEQC_SEND_MASTER_CMD)
-COMPATIBLE_IOCTL(FE_DISEQC_RECV_SLAVE_REPLY)
-COMPATIBLE_IOCTL(FE_DISEQC_SEND_BURST)
-COMPATIBLE_IOCTL(FE_SET_TONE)
-COMPATIBLE_IOCTL(FE_SET_VOLTAGE)
-COMPATIBLE_IOCTL(FE_ENABLE_HIGH_LNB_VOLTAGE)
-COMPATIBLE_IOCTL(FE_READ_STATUS)
-COMPATIBLE_IOCTL(FE_READ_BER)
-COMPATIBLE_IOCTL(FE_READ_SIGNAL_STRENGTH)
-COMPATIBLE_IOCTL(FE_READ_SNR)
-COMPATIBLE_IOCTL(FE_READ_UNCORRECTED_BLOCKS)
-COMPATIBLE_IOCTL(FE_SET_FRONTEND)
-COMPATIBLE_IOCTL(FE_GET_FRONTEND)
-COMPATIBLE_IOCTL(FE_GET_EVENT)
-COMPATIBLE_IOCTL(FE_DISHNETWORK_SEND_LEGACY_CMD)
-COMPATIBLE_IOCTL(VIDEO_STOP)
-COMPATIBLE_IOCTL(VIDEO_PLAY)
-COMPATIBLE_IOCTL(VIDEO_FREEZE)
-COMPATIBLE_IOCTL(VIDEO_CONTINUE)
-COMPATIBLE_IOCTL(VIDEO_SELECT_SOURCE)
-COMPATIBLE_IOCTL(VIDEO_SET_BLANK)
-COMPATIBLE_IOCTL(VIDEO_GET_STATUS)
-COMPATIBLE_IOCTL(VIDEO_SET_DISPLAY_FORMAT)
-COMPATIBLE_IOCTL(VIDEO_FAST_FORWARD)
-COMPATIBLE_IOCTL(VIDEO_SLOWMOTION)
-COMPATIBLE_IOCTL(VIDEO_GET_CAPABILITIES)
-COMPATIBLE_IOCTL(VIDEO_CLEAR_BUFFER)
-COMPATIBLE_IOCTL(VIDEO_SET_ID)
-COMPATIBLE_IOCTL(VIDEO_SET_STREAMTYPE)
-COMPATIBLE_IOCTL(VIDEO_SET_FORMAT)
-COMPATIBLE_IOCTL(VIDEO_SET_SYSTEM)
-COMPATIBLE_IOCTL(VIDEO_SET_HIGHLIGHT)
-COMPATIBLE_IOCTL(VIDEO_SET_SPU)
-COMPATIBLE_IOCTL(VIDEO_GET_NAVI)
-COMPATIBLE_IOCTL(VIDEO_SET_ATTRIBUTES)
-COMPATIBLE_IOCTL(VIDEO_GET_SIZE)
-COMPATIBLE_IOCTL(VIDEO_GET_FRAME_RATE)
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 9008eab..a9f7947 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -22,6 +22,9 @@
__asm__ ("" : "=r"(__ptr) : "0"(ptr)); \
(typeof(ptr)) (__ptr + (off)); })
+/* &a[0] degrades to a pointer: a different type from an array */
+#define __must_be_array(a) \
+ BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0])))
#define inline inline __attribute__((always_inline))
#define __inline__ __inline__ __attribute__((always_inline))
diff --git a/include/linux/compiler-gcc3.h b/include/linux/compiler-gcc3.h
index 1698b84..ecd621f 100644
--- a/include/linux/compiler-gcc3.h
+++ b/include/linux/compiler-gcc3.h
@@ -13,4 +13,10 @@
#define __must_check __attribute__((warn_unused_result))
#endif
+/*
+ * A trick to suppress uninitialized variable warning without generating any
+ * code
+ */
+#define uninitialized_var(x) x = x
+
#define __always_inline inline __attribute__((always_inline))
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index 6f5cc6f..fd0cc7c 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -16,3 +16,9 @@
#define __must_check __attribute__((warn_unused_result))
#define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
#define __always_inline inline __attribute__((always_inline))
+
+/*
+ * A trick to suppress uninitialized variable warning without generating any
+ * code
+ */
+#define uninitialized_var(x) x = x
diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h
index 1d1c3ce..b769961 100644
--- a/include/linux/compiler-intel.h
+++ b/include/linux/compiler-intel.h
@@ -21,4 +21,9 @@
__ptr = (unsigned long) (ptr); \
(typeof(ptr)) (__ptr + (off)); })
+/* Intel ECC compiler doesn't support __builtin_types_compatible_p() */
+#define __must_be_array(a) 0
+
#endif
+
+#define uninitialized_var(x) x
diff --git a/include/linux/console.h b/include/linux/console.h
index de25ee3..62ef6e1 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -51,7 +51,7 @@ struct consw {
int (*con_scrolldelta)(struct vc_data *, int);
int (*con_set_origin)(struct vc_data *);
void (*con_save_screen)(struct vc_data *);
- u8 (*con_build_attr)(struct vc_data *, u8, u8, u8, u8, u8);
+ u8 (*con_build_attr)(struct vc_data *, u8, u8, u8, u8, u8, u8);
void (*con_invert_region)(struct vc_data *, u16 *, int);
u16 *(*con_screen_pos)(struct vc_data *, int);
unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);
@@ -92,9 +92,8 @@ void give_up_console(const struct consw *sw);
#define CON_BOOT (8)
#define CON_ANYTIME (16) /* Safe to call when cpu is offline */
-struct console
-{
- char name[8];
+struct console {
+ char name[16];
void (*write)(struct console *, const char *, unsigned);
int (*read)(struct console *, char *, unsigned);
struct tty_driver *(*device)(struct console *, int *);
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index a86162b..a461f76 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -37,6 +37,7 @@ struct vc_data {
unsigned char vc_color; /* Foreground & background */
unsigned char vc_s_color; /* Saved foreground & background */
unsigned char vc_ulcolor; /* Color for underline mode */
+ unsigned char vc_itcolor;
unsigned char vc_halfcolor; /* Color for half intensity mode */
/* cursor */
unsigned int vc_cursor_type;
@@ -71,10 +72,12 @@ struct vc_data {
unsigned int vc_deccolm : 1; /* 80/132 Column Mode */
/* attribute flags */
unsigned int vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */
+ unsigned int vc_italic:1;
unsigned int vc_underline : 1;
unsigned int vc_blink : 1;
unsigned int vc_reverse : 1;
unsigned int vc_s_intensity : 2; /* saved rendition */
+ unsigned int vc_s_italic:1;
unsigned int vc_s_underline : 1;
unsigned int vc_s_blink : 1;
unsigned int vc_s_reverse : 1;
diff --git a/include/asm-x86_64/const.h b/include/linux/const.h
index 54fb08f..07b300b 100644
--- a/include/asm-x86_64/const.h
+++ b/include/linux/const.h
@@ -1,11 +1,11 @@
/* const.h: Macros for dealing with constants. */
-#ifndef _X86_64_CONST_H
-#define _X86_64_CONST_H
+#ifndef _LINUX_CONST_H
+#define _LINUX_CONST_H
/* Some constant macros are used in both assembler and
* C code. Therefore we cannot annotate them always with
- * 'UL' and other type specificers unilaterally. We
+ * 'UL' and other type specifiers unilaterally. We
* use the following macros to deal with this.
*/
@@ -16,5 +16,4 @@
#define _AC(X,Y) __AC(X,Y)
#endif
-
-#endif /* !(_X86_64_CONST_H) */
+#endif /* !(_LINUX_CONST_H) */
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index c22b0df..3b2df25 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -41,6 +41,9 @@ extern void cpu_remove_sysdev_attr(struct sysdev_attribute *attr);
extern int cpu_add_sysdev_attr_group(struct attribute_group *attrs);
extern void cpu_remove_sysdev_attr_group(struct attribute_group *attrs);
+extern struct sysdev_attribute attr_sched_mc_power_savings;
+extern struct sysdev_attribute attr_sched_smt_power_savings;
+extern int sched_create_sysfs_power_savings_entries(struct sysdev_class *cls);
#ifdef CONFIG_HOTPLUG_CPU
extern void unregister_cpu(struct cpu *cpu);
diff --git a/include/linux/cyclades.h b/include/linux/cyclades.h
index 46d8254..72aa00c 100644
--- a/include/linux/cyclades.h
+++ b/include/linux/cyclades.h
@@ -67,6 +67,8 @@
#ifndef _LINUX_CYCLADES_H
#define _LINUX_CYCLADES_H
+#include <linux/types.h>
+
struct cyclades_monitor {
unsigned long int_count;
unsigned long char_count;
@@ -108,7 +110,6 @@ struct cyclades_idle_stats {
#define CYZSETPOLLCYCLE 0x43590e
#define CYZGETPOLLCYCLE 0x43590f
#define CYGETCD1400VER 0x435910
-#define CYGETCARDINFO 0x435911
#define CYSETWAIT 0x435912
#define CYGETWAIT 0x435913
@@ -149,14 +150,12 @@ struct CYZ_BOOT_CTRL {
* architectures and compilers.
*/
-#if defined(__alpha__)
-typedef unsigned long ucdouble; /* 64 bits, unsigned */
-typedef unsigned int uclong; /* 32 bits, unsigned */
-#else
-typedef unsigned long uclong; /* 32 bits, unsigned */
-#endif
-typedef unsigned short ucshort; /* 16 bits, unsigned */
-typedef unsigned char ucchar; /* 8 bits, unsigned */
+#include <asm/types.h>
+
+typedef __u64 ucdouble; /* 64 bits, unsigned */
+typedef __u32 uclong; /* 32 bits, unsigned */
+typedef __u16 ucshort; /* 16 bits, unsigned */
+typedef __u8 ucchar; /* 8 bits, unsigned */
/*
* Memory Window Sizes
@@ -174,24 +173,24 @@ typedef unsigned char ucchar; /* 8 bits, unsigned */
*/
struct CUSTOM_REG {
- uclong fpga_id; /* FPGA Identification Register */
- uclong fpga_version; /* FPGA Version Number Register */
- uclong cpu_start; /* CPU start Register (write) */
- uclong cpu_stop; /* CPU stop Register (write) */
- uclong misc_reg; /* Miscelaneous Register */
- uclong idt_mode; /* IDT mode Register */
- uclong uart_irq_status; /* UART IRQ status Register */
- uclong clear_timer0_irq; /* Clear timer interrupt Register */
- uclong clear_timer1_irq; /* Clear timer interrupt Register */
- uclong clear_timer2_irq; /* Clear timer interrupt Register */
- uclong test_register; /* Test Register */
- uclong test_count; /* Test Count Register */
- uclong timer_select; /* Timer select register */
- uclong pr_uart_irq_status; /* Prioritized UART IRQ stat Reg */
- uclong ram_wait_state; /* RAM wait-state Register */
- uclong uart_wait_state; /* UART wait-state Register */
- uclong timer_wait_state; /* timer wait-state Register */
- uclong ack_wait_state; /* ACK wait State Register */
+ __u32 fpga_id; /* FPGA Identification Register */
+ __u32 fpga_version; /* FPGA Version Number Register */
+ __u32 cpu_start; /* CPU start Register (write) */
+ __u32 cpu_stop; /* CPU stop Register (write) */
+ __u32 misc_reg; /* Miscelaneous Register */
+ __u32 idt_mode; /* IDT mode Register */
+ __u32 uart_irq_status; /* UART IRQ status Register */
+ __u32 clear_timer0_irq; /* Clear timer interrupt Register */
+ __u32 clear_timer1_irq; /* Clear timer interrupt Register */
+ __u32 clear_timer2_irq; /* Clear timer interrupt Register */
+ __u32 test_register; /* Test Register */
+ __u32 test_count; /* Test Count Register */
+ __u32 timer_select; /* Timer select register */
+ __u32 pr_uart_irq_status; /* Prioritized UART IRQ stat Reg */
+ __u32 ram_wait_state; /* RAM wait-state Register */
+ __u32 uart_wait_state; /* UART wait-state Register */
+ __u32 timer_wait_state; /* timer wait-state Register */
+ __u32 ack_wait_state; /* ACK wait State Register */
};
/*
@@ -201,34 +200,34 @@ struct CUSTOM_REG {
*/
struct RUNTIME_9060 {
- uclong loc_addr_range; /* 00h - Local Address Range */
- uclong loc_addr_base; /* 04h - Local Address Base */
- uclong loc_arbitr; /* 08h - Local Arbitration */
- uclong endian_descr; /* 0Ch - Big/Little Endian Descriptor */
- uclong loc_rom_range; /* 10h - Local ROM Range */
- uclong loc_rom_base; /* 14h - Local ROM Base */
- uclong loc_bus_descr; /* 18h - Local Bus descriptor */
- uclong loc_range_mst; /* 1Ch - Local Range for Master to PCI */
- uclong loc_base_mst; /* 20h - Local Base for Master PCI */
- uclong loc_range_io; /* 24h - Local Range for Master IO */
- uclong pci_base_mst; /* 28h - PCI Base for Master PCI */
- uclong pci_conf_io; /* 2Ch - PCI configuration for Master IO */
- uclong filler1; /* 30h */
- uclong filler2; /* 34h */
- uclong filler3; /* 38h */
- uclong filler4; /* 3Ch */
- uclong mail_box_0; /* 40h - Mail Box 0 */
- uclong mail_box_1; /* 44h - Mail Box 1 */
- uclong mail_box_2; /* 48h - Mail Box 2 */
- uclong mail_box_3; /* 4Ch - Mail Box 3 */
- uclong filler5; /* 50h */
- uclong filler6; /* 54h */
- uclong filler7; /* 58h */
- uclong filler8; /* 5Ch */
- uclong pci_doorbell; /* 60h - PCI to Local Doorbell */
- uclong loc_doorbell; /* 64h - Local to PCI Doorbell */
- uclong intr_ctrl_stat; /* 68h - Interrupt Control/Status */
- uclong init_ctrl; /* 6Ch - EEPROM control, Init Control, etc */
+ __u32 loc_addr_range; /* 00h - Local Address Range */
+ __u32 loc_addr_base; /* 04h - Local Address Base */
+ __u32 loc_arbitr; /* 08h - Local Arbitration */
+ __u32 endian_descr; /* 0Ch - Big/Little Endian Descriptor */
+ __u32 loc_rom_range; /* 10h - Local ROM Range */
+ __u32 loc_rom_base; /* 14h - Local ROM Base */
+ __u32 loc_bus_descr; /* 18h - Local Bus descriptor */
+ __u32 loc_range_mst; /* 1Ch - Local Range for Master to PCI */
+ __u32 loc_base_mst; /* 20h - Local Base for Master PCI */
+ __u32 loc_range_io; /* 24h - Local Range for Master IO */
+ __u32 pci_base_mst; /* 28h - PCI Base for Master PCI */
+ __u32 pci_conf_io; /* 2Ch - PCI configuration for Master IO */
+ __u32 filler1; /* 30h */
+ __u32 filler2; /* 34h */
+ __u32 filler3; /* 38h */
+ __u32 filler4; /* 3Ch */
+ __u32 mail_box_0; /* 40h - Mail Box 0 */
+ __u32 mail_box_1; /* 44h - Mail Box 1 */
+ __u32 mail_box_2; /* 48h - Mail Box 2 */
+ __u32 mail_box_3; /* 4Ch - Mail Box 3 */
+ __u32 filler5; /* 50h */
+ __u32 filler6; /* 54h */
+ __u32 filler7; /* 58h */
+ __u32 filler8; /* 5Ch */
+ __u32 pci_doorbell; /* 60h - PCI to Local Doorbell */
+ __u32 loc_doorbell; /* 64h - Local to PCI Doorbell */
+ __u32 intr_ctrl_stat; /* 68h - Interrupt Control/Status */
+ __u32 init_ctrl; /* 6Ch - EEPROM control, Init Control, etc */
};
/* Values for the Local Base Address re-map register */
@@ -270,8 +269,8 @@ struct RUNTIME_9060 {
#define ZF_TINACT ZF_TINACT_DEF
struct FIRM_ID {
- uclong signature; /* ZFIRM/U signature */
- uclong zfwctrl_addr; /* pointer to ZFW_CTRL structure */
+ __u32 signature; /* ZFIRM/U signature */
+ __u32 zfwctrl_addr; /* pointer to ZFW_CTRL structure */
};
/* Op. System id */
@@ -408,24 +407,24 @@ struct FIRM_ID {
*/
struct CH_CTRL {
- uclong op_mode; /* operation mode */
- uclong intr_enable; /* interrupt masking */
- uclong sw_flow; /* SW flow control */
- uclong flow_status; /* output flow status */
- uclong comm_baud; /* baud rate - numerically specified */
- uclong comm_parity; /* parity */
- uclong comm_data_l; /* data length/stop */
- uclong comm_flags; /* other flags */
- uclong hw_flow; /* HW flow control */
- uclong rs_control; /* RS-232 outputs */
- uclong rs_status; /* RS-232 inputs */
- uclong flow_xon; /* xon char */
- uclong flow_xoff; /* xoff char */
- uclong hw_overflow; /* hw overflow counter */
- uclong sw_overflow; /* sw overflow counter */
- uclong comm_error; /* frame/parity error counter */
- uclong ichar;
- uclong filler[7];
+ __u32 op_mode; /* operation mode */
+ __u32 intr_enable; /* interrupt masking */
+ __u32 sw_flow; /* SW flow control */
+ __u32 flow_status; /* output flow status */
+ __u32 comm_baud; /* baud rate - numerically specified */
+ __u32 comm_parity; /* parity */
+ __u32 comm_data_l; /* data length/stop */
+ __u32 comm_flags; /* other flags */
+ __u32 hw_flow; /* HW flow control */
+ __u32 rs_control; /* RS-232 outputs */
+ __u32 rs_status; /* RS-232 inputs */
+ __u32 flow_xon; /* xon char */
+ __u32 flow_xoff; /* xoff char */
+ __u32 hw_overflow; /* hw overflow counter */
+ __u32 sw_overflow; /* sw overflow counter */
+ __u32 comm_error; /* frame/parity error counter */
+ __u32 ichar;
+ __u32 filler[7];
};
@@ -435,18 +434,18 @@ struct CH_CTRL {
*/
struct BUF_CTRL {
- uclong flag_dma; /* buffers are in Host memory */
- uclong tx_bufaddr; /* address of the tx buffer */
- uclong tx_bufsize; /* tx buffer size */
- uclong tx_threshold; /* tx low water mark */
- uclong tx_get; /* tail index tx buf */
- uclong tx_put; /* head index tx buf */
- uclong rx_bufaddr; /* address of the rx buffer */
- uclong rx_bufsize; /* rx buffer size */
- uclong rx_threshold; /* rx high water mark */
- uclong rx_get; /* tail index rx buf */
- uclong rx_put; /* head index rx buf */
- uclong filler[5]; /* filler to align structures */
+ __u32 flag_dma; /* buffers are in Host memory */
+ __u32 tx_bufaddr; /* address of the tx buffer */
+ __u32 tx_bufsize; /* tx buffer size */
+ __u32 tx_threshold; /* tx low water mark */
+ __u32 tx_get; /* tail index tx buf */
+ __u32 tx_put; /* head index tx buf */
+ __u32 rx_bufaddr; /* address of the rx buffer */
+ __u32 rx_bufsize; /* rx buffer size */
+ __u32 rx_threshold; /* rx high water mark */
+ __u32 rx_get; /* tail index rx buf */
+ __u32 rx_put; /* head index rx buf */
+ __u32 filler[5]; /* filler to align structures */
};
/*
@@ -457,27 +456,27 @@ struct BUF_CTRL {
struct BOARD_CTRL {
/* static info provided by the on-board CPU */
- uclong n_channel; /* number of channels */
- uclong fw_version; /* firmware version */
+ __u32 n_channel; /* number of channels */
+ __u32 fw_version; /* firmware version */
/* static info provided by the driver */
- uclong op_system; /* op_system id */
- uclong dr_version; /* driver version */
+ __u32 op_system; /* op_system id */
+ __u32 dr_version; /* driver version */
/* board control area */
- uclong inactivity; /* inactivity control */
+ __u32 inactivity; /* inactivity control */
/* host to FW commands */
- uclong hcmd_channel; /* channel number */
- uclong hcmd_param; /* pointer to parameters */
+ __u32 hcmd_channel; /* channel number */
+ __u32 hcmd_param; /* pointer to parameters */
/* FW to Host commands */
- uclong fwcmd_channel; /* channel number */
- uclong fwcmd_param; /* pointer to parameters */
- uclong zf_int_queue_addr; /* offset for INT_QUEUE structure */
+ __u32 fwcmd_channel; /* channel number */
+ __u32 fwcmd_param; /* pointer to parameters */
+ __u32 zf_int_queue_addr; /* offset for INT_QUEUE structure */
/* filler so the structures are aligned */
- uclong filler[6];
+ __u32 filler[6];
};
/* Host Interrupt Queue */
@@ -506,11 +505,10 @@ struct ZFW_CTRL {
/****************** ****************** *******************/
#endif
+#ifdef __KERNEL__
+
/* Per card data structure */
-struct resource;
struct cyclades_card {
- unsigned long base_phys;
- unsigned long ctl_phys;
void __iomem *base_addr;
void __iomem *ctl_addr;
int irq;
@@ -519,33 +517,18 @@ struct cyclades_card {
int nports; /* Number of ports in the card */
int bus_index; /* address shift - 0 for ISA, 1 for PCI */
int intr_enabled; /* FW Interrupt flag - 0 disabled, 1 enabled */
- struct pci_dev *pdev;
-#ifdef __KERNEL__
spinlock_t card_lock;
-#else
- unsigned long filler;
-#endif
+ struct cyclades_port *ports;
};
-struct cyclades_chip {
- int filler;
-};
-
-
-#ifdef __KERNEL__
-
/***************************************
* Memory access functions/macros *
* (required to support Alpha systems) *
***************************************/
-#define cy_writeb(port,val) {writeb((val),(port)); mb();}
-#define cy_writew(port,val) {writew((val),(port)); mb();}
-#define cy_writel(port,val) {writel((val),(port)); mb();}
-
-#define cy_readb(port) readb(port)
-#define cy_readw(port) readw(port)
-#define cy_readl(port) readl(port)
+#define cy_writeb(port,val) do { writeb((val), (port)); mb(); } while (0)
+#define cy_writew(port,val) do { writew((val), (port)); mb(); } while (0)
+#define cy_writel(port,val) do { writel((val), (port)); mb(); } while (0)
/*
* Statistics counters
@@ -567,7 +550,7 @@ struct cyclades_icount {
struct cyclades_port {
int magic;
- int card;
+ struct cyclades_card *card;
int line;
int flags; /* defined in tty.h */
int type; /* UART type */
@@ -587,7 +570,6 @@ struct cyclades_port {
int close_delay;
unsigned short closing_wait;
unsigned long event;
- unsigned long last_active;
int count; /* # of fd on device */
int breakon;
int breakoff;
@@ -598,7 +580,6 @@ struct cyclades_port {
int xmit_cnt;
int default_threshold;
int default_timeout;
- unsigned long jiffies[3];
unsigned long rflush_count;
struct cyclades_monitor mon;
struct cyclades_idle_stats idle_stats;
@@ -606,7 +587,7 @@ struct cyclades_port {
struct work_struct tqueue;
wait_queue_head_t open_wait;
wait_queue_head_t close_wait;
- wait_queue_head_t shutdown_wait;
+ struct completion shutdown_wait;
wait_queue_head_t delta_msr_wait;
int throttle;
};
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 63f64a9..aab53df 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -133,6 +133,7 @@ struct dentry_operations {
int (*d_delete)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
+ char *(*d_dname)(struct dentry *, char *, int);
};
/* the dentry parameter passed to d_hash and d_compare is the parent
@@ -293,6 +294,11 @@ extern struct dentry * d_hash_and_lookup(struct dentry *, struct qstr *);
/* validate "insecure" dentry pointer */
extern int d_validate(struct dentry *, struct dentry *);
+/*
+ * helper function for dentry_operations.d_dname() members
+ */
+extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
+
extern char * d_path(struct dentry *, struct vfsmount *, char *, int);
/* Allocation counts.. */
diff --git a/include/linux/device.h b/include/linux/device.h
index 6579068..2e1a298 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -412,12 +412,13 @@ struct device {
struct klist_node knode_parent; /* node in sibling list */
struct klist_node knode_driver;
struct klist_node knode_bus;
- struct device * parent;
+ struct device *parent;
struct kobject kobj;
char bus_id[BUS_ID_SIZE]; /* position on parent bus */
struct device_type *type;
unsigned is_registered:1;
+ unsigned uevent_suppress:1;
struct device_attribute uevent_attr;
struct device_attribute *devt_attr;
@@ -458,7 +459,6 @@ struct device {
struct class *class;
dev_t devt; /* dev_t, creates the sysfs "dev" */
struct attribute_group **groups; /* optional groups */
- int uevent_suppress;
void (*release)(struct device * dev);
};
diff --git a/include/linux/display.h b/include/linux/display.h
new file mode 100644
index 0000000..3bf70d6
--- /dev/null
+++ b/include/linux/display.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2006 James Simmons <jsimmons@infradead.org>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#ifndef _LINUX_DISPLAY_H
+#define _LINUX_DISPLAY_H
+
+#include <linux/device.h>
+
+struct display_device;
+
+/* This structure defines all the properties of a Display. */
+struct display_driver {
+ int (*set_contrast)(struct display_device *, unsigned int);
+ int (*get_contrast)(struct display_device *);
+ void (*suspend)(struct display_device *, pm_message_t state);
+ void (*resume)(struct display_device *);
+ int (*probe)(struct display_device *, void *);
+ int (*remove)(struct display_device *);
+ int max_contrast;
+};
+
+struct display_device {
+ struct module *owner; /* Owner module */
+ struct display_driver *driver;
+ struct device *parent; /* This is the parent */
+ struct device *dev; /* This is this display device */
+ struct mutex lock;
+ void *priv_data;
+ char type[16];
+ char *name;
+ int idx;
+};
+
+extern struct display_device *display_device_register(struct display_driver *driver,
+ struct device *dev, void *devdata);
+extern void display_device_unregister(struct display_device *dev);
+
+extern int probe_edid(struct display_device *dev, void *devdata);
+
+#define to_display_device(obj) container_of(obj, struct display_device, class_dev)
+
+#endif
diff --git a/include/linux/dlm_device.h b/include/linux/dlm_device.h
index 2a2dd18..c2735ca 100644
--- a/include/linux/dlm_device.h
+++ b/include/linux/dlm_device.h
@@ -19,7 +19,7 @@
/* Version of the device interface */
#define DLM_DEVICE_VERSION_MAJOR 5
-#define DLM_DEVICE_VERSION_MINOR 0
+#define DLM_DEVICE_VERSION_MINOR 1
#define DLM_DEVICE_VERSION_PATCH 0
/* struct passed to the lock write */
@@ -44,6 +44,11 @@ struct dlm_lspace_params {
char name[0];
};
+struct dlm_purge_params {
+ __u32 nodeid;
+ __u32 pid;
+};
+
struct dlm_write_request {
__u32 version[3];
__u8 cmd;
@@ -53,6 +58,7 @@ struct dlm_write_request {
union {
struct dlm_lock_params lock;
struct dlm_lspace_params lspace;
+ struct dlm_purge_params purge;
} i;
};
@@ -76,6 +82,7 @@ struct dlm_lock_result {
#define DLM_USER_QUERY 3
#define DLM_USER_CREATE_LOCKSPACE 4
#define DLM_USER_REMOVE_LOCKSPACE 5
+#define DLM_USER_PURGE 6
/* Arbitrary length restriction */
#define MAX_LS_NAME_LEN 64
diff --git a/include/linux/ds1wm.h b/include/linux/ds1wm.h
new file mode 100644
index 0000000..31f6e3c
--- /dev/null
+++ b/include/linux/ds1wm.h
@@ -0,0 +1,11 @@
+/* platform data for the DS1WM driver */
+
+struct ds1wm_platform_data {
+ int bus_shift; /* number of shifts needed to calculate the
+ * offset between DS1WM registers;
+ * e.g. on h5xxx and h2200 this is 2
+ * (registers aligned to 4-byte boundaries),
+ * while on hx4700 this is 1 */
+ void (*enable)(struct platform_device *pdev);
+ void (*disable)(struct platform_device *pdev);
+};
diff --git a/include/linux/efi.h b/include/linux/efi.h
index f8ebd7c..0b9579a 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -213,7 +213,6 @@ typedef struct {
} efi_config_table_t;
#define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL)
-#define EFI_SYSTEM_TABLE_REVISION ((1 << 16) | 00)
typedef struct {
efi_table_hdr_t hdr;
diff --git a/include/linux/elf-em.h b/include/linux/elf-em.h
index 666e0a5..0311bad 100644
--- a/include/linux/elf-em.h
+++ b/include/linux/elf-em.h
@@ -30,6 +30,7 @@
#define EM_V850 87 /* NEC v850 */
#define EM_M32R 88 /* Renesas M32R */
#define EM_H8_300 46 /* Renesas H8/300,300H,H8S */
+#define EM_BLACKFIN 106 /* ADI Blackfin Processor */
#define EM_FRV 0x5441 /* Fujitsu FR-V */
#define EM_AVR32 0x18ad /* Atmel AVR32 */
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 745c988..071c67a 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -71,6 +71,18 @@ static inline int is_multicast_ether_addr(const u8 *addr)
}
/**
+ * is_local_ether_addr - Determine if the Ethernet address is locally-assigned
+ * one (IEEE 802).
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Return true if the address is a local address.
+ */
+static inline int is_local_ether_addr(const u8 *addr)
+{
+ return (0x02 & addr[0]);
+}
+
+/**
* is_broadcast_ether_addr - Determine if the Ethernet address is broadcast
* @addr: Pointer to a six-byte array containing the Ethernet address
*
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index 4eb18ac..ece49a8 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -824,6 +824,7 @@ extern int ext3_change_inode_journal_flag(struct inode *, int);
extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *);
extern void ext3_truncate (struct inode *);
extern void ext3_set_inode_flags(struct inode *);
+extern void ext3_get_inode_flags(struct ext3_inode_info *);
extern void ext3_set_aops(struct inode *inode);
/* ioctl.c */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index be913ec..dff7a728 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -4,6 +4,8 @@
#include <asm/types.h>
#include <linux/i2c.h>
+struct dentry;
+
/* Definitions of frame buffers */
#define FB_MAJOR 29
@@ -525,12 +527,20 @@ struct fb_cursor_user {
#define FB_EVENT_MODE_CHANGE_ALL 0x0B
/* A software display blank change occured */
#define FB_EVENT_CONBLANK 0x0C
+/* Get drawing requirements */
+#define FB_EVENT_GET_REQ 0x0D
struct fb_event {
struct fb_info *info;
void *data;
};
+struct fb_blit_caps {
+ u32 x;
+ u32 y;
+ u32 len;
+ u32 flags;
+};
extern int fb_register_client(struct notifier_block *nb);
extern int fb_unregister_client(struct notifier_block *nb);
@@ -556,11 +566,25 @@ struct fb_pixmap {
u32 scan_align; /* alignment per scanline */
u32 access_align; /* alignment per read/write (bits) */
u32 flags; /* see FB_PIXMAP_* */
+ u32 blit_x; /* supported bit block dimensions (1-32)*/
+ u32 blit_y; /* Format: blit_x = 1 << (width - 1) */
+ /* blit_y = 1 << (height - 1) */
+ /* if 0, will be set to 0xffffffff (all)*/
/* access methods */
void (*writeio)(struct fb_info *info, void __iomem *dst, void *src, unsigned int size);
void (*readio) (struct fb_info *info, void *dst, void __iomem *src, unsigned int size);
};
+#ifdef CONFIG_FB_DEFERRED_IO
+struct fb_deferred_io {
+ /* delay between mkwrite and deferred handler */
+ unsigned long delay;
+ struct mutex lock; /* mutex that protects the page list */
+ struct list_head pagelist; /* list of touched pages */
+ /* callback */
+ void (*deferred_io)(struct fb_info *info, struct list_head *pagelist);
+};
+#endif
/*
* Frame buffer operations
@@ -579,8 +603,10 @@ struct fb_ops {
/* For framebuffers with strange non linear layouts or that do not
* work with normal memory mapped access
*/
- ssize_t (*fb_read)(struct file *file, char __user *buf, size_t count, loff_t *ppos);
- ssize_t (*fb_write)(struct file *file, const char __user *buf, size_t count, loff_t *ppos);
+ ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
+ size_t count, loff_t *ppos);
+ ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos);
/* checks var and eventually tweaks it to something supported,
* DO NOT MODIFY PAR */
@@ -634,10 +660,13 @@ struct fb_ops {
/* restore saved state */
void (*fb_restore_state)(struct fb_info *info);
+
+ /* get capability given var */
+ void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
+ struct fb_var_screeninfo *var);
};
#ifdef CONFIG_FB_TILEBLITTING
-
#define FB_TILE_CURSOR_NONE 0
#define FB_TILE_CURSOR_UNDERLINE 1
#define FB_TILE_CURSOR_LOWER_THIRD 2
@@ -709,6 +738,8 @@ struct fb_tile_ops {
/* cursor */
void (*fb_tilecursor)(struct fb_info *info,
struct fb_tilecursor *cursor);
+ /* get maximum length of the tile map */
+ int (*fb_get_tilemax)(struct fb_info *info);
};
#endif /* CONFIG_FB_TILEBLITTING */
@@ -778,6 +809,10 @@ struct fb_info {
struct mutex bl_curve_mutex;
u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif
+#ifdef CONFIG_FB_DEFERRED_IO
+ struct delayed_work deferred_work;
+ struct fb_deferred_io *fbdefio;
+#endif
struct fb_ops *fbops;
struct device *device; /* This is the parent */
@@ -879,6 +914,16 @@ extern int fb_blank(struct fb_info *info, int blank);
extern void cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
extern void cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image);
+/*
+ * Drawing operations where framebuffer is in system RAM
+ */
+extern void sys_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
+extern void sys_copyarea(struct fb_info *info, const struct fb_copyarea *area);
+extern void sys_imageblit(struct fb_info *info, const struct fb_image *image);
+extern ssize_t fb_sys_read(struct fb_info *info, char __user *buf,
+ size_t count, loff_t *ppos);
+extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
+ size_t count, loff_t *ppos);
/* drivers/video/fbmem.c */
extern int register_framebuffer(struct fb_info *fb_info);
@@ -913,6 +958,12 @@ static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch,
}
}
+/* drivers/video/fb_defio.c */
+extern void fb_deferred_io_init(struct fb_info *info);
+extern void fb_deferred_io_cleanup(struct fb_info *info);
+extern int fb_deferred_io_fsync(struct file *file, struct dentry *dentry,
+ int datasync);
+
/* drivers/video/fbsysfs.c */
extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);
extern void framebuffer_release(struct fb_info *info);
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index 996f561..40b9326 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -3,6 +3,10 @@
#include <asm/fcntl.h>
+/* Cancel a blocking posix lock; internal use only until we expose an
+ * asynchronous lock api to userspace: */
+#define F_CANCELLK (F_LINUX_SPECIFIC_BASE+5)
+
#define F_SETLEASE (F_LINUX_SPECIFIC_BASE+0)
#define F_GETLEASE (F_LINUX_SPECIFIC_BASE+1)
diff --git a/include/linux/font.h b/include/linux/font.h
index 53b129f..40a24ab 100644
--- a/include/linux/font.h
+++ b/include/linux/font.h
@@ -49,7 +49,8 @@ extern const struct font_desc *find_font(const char *name);
/* Get the default font for a specific screen size */
-extern const struct font_desc *get_default_font(int xres, int yres);
+extern const struct font_desc *get_default_font(int xres, int yres,
+ u32 font_w, u32 font_h);
/* Max. length for the name of a predefined font */
#define MAX_FONT_NAME 32
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 7c0077f..7cf0c54 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -30,6 +30,7 @@
#define SEEK_SET 0 /* seek relative to beginning of file */
#define SEEK_CUR 1 /* seek relative to current file position */
#define SEEK_END 2 /* seek relative to end of file */
+#define SEEK_MAX SEEK_END
/* And dynamically-tunable limits and defaults: */
struct files_stat_struct {
@@ -91,6 +92,7 @@ extern int dir_notify_enable;
/* public flags for file_system_type */
#define FS_REQUIRES_DEV 1
#define FS_BINARY_MOUNTDATA 2
+#define FS_HAS_SUBTYPE 4
#define FS_REVAL_DOT 16384 /* Check the paths ".", ".." for staleness */
#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move()
* during rename() internally.
@@ -696,12 +698,13 @@ struct file_ra_state {
unsigned long size;
unsigned long flags; /* ra flags RA_FLAG_xxx*/
unsigned long cache_hit; /* cache hit count*/
- unsigned long prev_page; /* Cache last read() position */
+ unsigned long prev_index; /* Cache last read() position */
unsigned long ahead_start; /* Ahead window */
unsigned long ahead_size;
unsigned long ra_pages; /* Maximum readahead window */
unsigned long mmap_hit; /* Cache hit stat for mmap accesses */
unsigned long mmap_miss; /* Cache miss stat for mmap accesses */
+ unsigned int prev_offset; /* Offset where last read() ended in a page */
};
#define RA_FLAG_MISS 0x01 /* a cache miss occured against this file */
#define RA_FLAG_INCACHE 0x02 /* file is already in cache */
@@ -785,6 +788,7 @@ struct file_lock_operations {
struct lock_manager_operations {
int (*fl_compare_owner)(struct file_lock *, struct file_lock *);
void (*fl_notify)(struct file_lock *); /* unblock callback */
+ int (*fl_grant)(struct file_lock *, struct file_lock *, int);
void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
void (*fl_release_private)(struct file_lock *);
void (*fl_break)(struct file_lock *);
@@ -845,22 +849,19 @@ extern int fcntl_getlease(struct file *filp);
/* fs/sync.c */
extern int do_sync_mapping_range(struct address_space *mapping, loff_t offset,
loff_t endbyte, unsigned int flags);
-static inline int do_sync_file_range(struct file *file, loff_t offset,
- loff_t endbyte, unsigned int flags)
-{
- return do_sync_mapping_range(file->f_mapping, offset, endbyte, flags);
-}
/* fs/locks.c */
extern void locks_init_lock(struct file_lock *);
extern void locks_copy_lock(struct file_lock *, struct file_lock *);
extern void locks_remove_posix(struct file *, fl_owner_t);
extern void locks_remove_flock(struct file *);
-extern int posix_test_lock(struct file *, struct file_lock *, struct file_lock *);
-extern int posix_lock_file_conf(struct file *, struct file_lock *, struct file_lock *);
-extern int posix_lock_file(struct file *, struct file_lock *);
+extern int posix_test_lock(struct file *, struct file_lock *);
+extern int posix_lock_file(struct file *, struct file_lock *, struct file_lock *);
extern int posix_lock_file_wait(struct file *, struct file_lock *);
extern int posix_unblock_lock(struct file *, struct file_lock *);
+extern int vfs_test_lock(struct file *, struct file_lock *);
+extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *);
+extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl);
extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl);
extern int __break_lease(struct inode *inode, unsigned int flags);
extern void lease_get_mtime(struct inode *, struct timespec *time);
@@ -956,6 +957,12 @@ struct super_block {
/* Granularity of c/m/atime in ns.
Cannot be worse than a second */
u32 s_time_gran;
+
+ /*
+ * Filesystem subtype. If non-empty the filesystem type field
+ * in /proc/mounts will be "type.subtype"
+ */
+ char *s_subtype;
};
extern struct timespec current_fs_time(struct super_block *sb);
@@ -1731,6 +1738,8 @@ extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor
extern void do_generic_mapping_read(struct address_space *mapping,
struct file_ra_state *, struct file *,
loff_t *, read_descriptor_t *, read_actor_t);
+extern int generic_segment_checks(const struct iovec *iov,
+ unsigned long *nr_segs, size_t *count, int access_flags);
/* fs/splice.c */
extern ssize_t generic_file_splice_read(struct file *, loff_t *,
diff --git a/include/linux/futex.h b/include/linux/futex.h
index 3f153b4..820125c 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -100,6 +100,35 @@ long do_futex(u32 __user *uaddr, int op, u32 val, unsigned long timeout,
extern int
handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi);
+/*
+ * Futexes are matched on equal values of this key.
+ * The key type depends on whether it's a shared or private mapping.
+ * Don't rearrange members without looking at hash_futex().
+ *
+ * offset is aligned to a multiple of sizeof(u32) (== 4) by definition.
+ * We set bit 0 to indicate if it's an inode-based key.
+ */
+union futex_key {
+ struct {
+ unsigned long pgoff;
+ struct inode *inode;
+ int offset;
+ } shared;
+ struct {
+ unsigned long address;
+ struct mm_struct *mm;
+ int offset;
+ } private;
+ struct {
+ unsigned long word;
+ void *ptr;
+ int offset;
+ } both;
+};
+int get_futex_key(u32 __user *uaddr, union futex_key *key);
+void get_futex_key_refs(union futex_key *key);
+void drop_futex_key_refs(union futex_key *key);
+
#ifdef CONFIG_FUTEX
extern void exit_robust_list(struct task_struct *curr);
extern void exit_pi_state_list(struct task_struct *curr);
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 2a7d15b..97a36c3 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -40,7 +40,6 @@ struct vm_area_struct;
#define __GFP_REPEAT ((__force gfp_t)0x400u) /* Retry the allocation. Might fail */
#define __GFP_NOFAIL ((__force gfp_t)0x800u) /* Retry for ever. Cannot fail */
#define __GFP_NORETRY ((__force gfp_t)0x1000u)/* Do not retry. Might fail */
-#define __GFP_NO_GROW ((__force gfp_t)0x2000u)/* Slab internal usage */
#define __GFP_COMP ((__force gfp_t)0x4000u)/* Add compound page metadata */
#define __GFP_ZERO ((__force gfp_t)0x8000u)/* Return zeroed page on success */
#define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) /* Don't use emergency reserves */
@@ -53,7 +52,7 @@ struct vm_area_struct;
/* if you forget to add the bitmask here kernel will crash, period */
#define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \
__GFP_COLD|__GFP_NOWARN|__GFP_REPEAT| \
- __GFP_NOFAIL|__GFP_NORETRY|__GFP_NO_GROW|__GFP_COMP| \
+ __GFP_NOFAIL|__GFP_NORETRY|__GFP_COMP| \
__GFP_NOMEMALLOC|__GFP_HARDWALL|__GFP_THISNODE)
/* This equals 0, but use constants in case they ever change */
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 3f3e7a6..b4570b6 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -189,4 +189,10 @@ static inline void set_file_hugepages(struct file *file)
#endif /* !CONFIG_HUGETLBFS */
+#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long pgoff,
+ unsigned long flags);
+#endif /* HAVE_ARCH_HUGETLB_UNMAPPED_AREA */
+
#endif /* _LINUX_HUGETLB_H */
diff --git a/include/linux/init.h b/include/linux/init.h
index 9abf120..8bc32bb 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -77,7 +77,8 @@ extern char *saved_command_line;
extern unsigned int reset_devices;
/* used by init/main.c */
-extern void setup_arch(char **);
+void setup_arch(char **);
+void prepare_namespace(void);
#endif
@@ -233,7 +234,7 @@ void __init parse_early_param(void);
#define __obsolete_setup(str) /* nothing */
#endif
-/* Data marked not to be saved by software_suspend() */
+/* Data marked not to be saved by software suspend */
#define __nosavedata __attribute__ ((__section__ (".data.nosave")))
/* This means "can be init if no module support, otherwise module load
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index a2d95ff..7951023 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -138,7 +138,7 @@ extern struct group_info init_groups;
.journal_info = NULL, \
.cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \
.fs_excl = ATOMIC_INIT(0), \
- .pi_lock = SPIN_LOCK_UNLOCKED, \
+ .pi_lock = __SPIN_LOCK_UNLOCKED(tsk.pi_lock), \
INIT_TRACE_IRQFLAGS \
INIT_LOCKDEP \
}
diff --git a/include/linux/input.h b/include/linux/input.h
index 439954d..be2bf3a 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -990,6 +990,10 @@ struct input_dev {
#error "EV_MAX and INPUT_DEVICE_ID_EV_MAX do not match"
#endif
+#if KEY_MIN_INTERESTING != INPUT_DEVICE_ID_KEY_MIN_INTERESTING
+#error "KEY_MIN_INTERESTING and INPUT_DEVICE_ID_KEY_MIN_INTERESTING do not match"
+#endif
+
#if KEY_MAX != INPUT_DEVICE_ID_KEY_MAX
#error "KEY_MAX and INPUT_DEVICE_ID_KEY_MAX do not match"
#endif
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 0319f66..f7b01b9 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -44,6 +44,9 @@
* IRQF_TIMER - Flag to mark this interrupt as timer interrupt
* IRQF_PERCPU - Interrupt is per cpu
* IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing
+ * IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is
+ * registered first in an shared interrupt is considered for
+ * performance reasons)
*/
#define IRQF_DISABLED 0x00000020
#define IRQF_SAMPLE_RANDOM 0x00000040
@@ -52,22 +55,29 @@
#define IRQF_TIMER 0x00000200
#define IRQF_PERCPU 0x00000400
#define IRQF_NOBALANCING 0x00000800
+#define IRQF_IRQPOLL 0x00001000
/*
- * Migration helpers. Scheduled for removal in 1/2007
+ * Migration helpers. Scheduled for removal in 9/2007
* Do not use for new code !
*/
-#define SA_INTERRUPT IRQF_DISABLED
-#define SA_SAMPLE_RANDOM IRQF_SAMPLE_RANDOM
-#define SA_SHIRQ IRQF_SHARED
-#define SA_PROBEIRQ IRQF_PROBE_SHARED
-#define SA_PERCPU IRQF_PERCPU
-
-#define SA_TRIGGER_LOW IRQF_TRIGGER_LOW
-#define SA_TRIGGER_HIGH IRQF_TRIGGER_HIGH
-#define SA_TRIGGER_FALLING IRQF_TRIGGER_FALLING
-#define SA_TRIGGER_RISING IRQF_TRIGGER_RISING
-#define SA_TRIGGER_MASK IRQF_TRIGGER_MASK
+static inline
+unsigned long __deprecated deprecated_irq_flag(unsigned long flag)
+{
+ return flag;
+}
+
+#define SA_INTERRUPT deprecated_irq_flag(IRQF_DISABLED)
+#define SA_SAMPLE_RANDOM deprecated_irq_flag(IRQF_SAMPLE_RANDOM)
+#define SA_SHIRQ deprecated_irq_flag(IRQF_SHARED)
+#define SA_PROBEIRQ deprecated_irq_flag(IRQF_PROBE_SHARED)
+#define SA_PERCPU deprecated_irq_flag(IRQF_PERCPU)
+
+#define SA_TRIGGER_LOW deprecated_irq_flag(IRQF_TRIGGER_LOW)
+#define SA_TRIGGER_HIGH deprecated_irq_flag(IRQF_TRIGGER_HIGH)
+#define SA_TRIGGER_FALLING deprecated_irq_flag(IRQF_TRIGGER_FALLING)
+#define SA_TRIGGER_RISING deprecated_irq_flag(IRQF_TRIGGER_RISING)
+#define SA_TRIGGER_MASK deprecated_irq_flag(IRQF_TRIGGER_MASK)
typedef irqreturn_t (*irq_handler_t)(int, void *);
@@ -83,11 +93,11 @@ struct irqaction {
};
extern irqreturn_t no_action(int cpl, void *dev_id);
-extern int request_irq(unsigned int, irq_handler_t handler,
+extern int __must_check request_irq(unsigned int, irq_handler_t handler,
unsigned long, const char *, void *);
extern void free_irq(unsigned int, void *);
-extern int devm_request_irq(struct device *dev, unsigned int irq,
+extern int __must_check devm_request_irq(struct device *dev, unsigned int irq,
irq_handler_t handler, unsigned long irqflags,
const char *devname, void *dev_id);
extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
diff --git a/include/linux/ioctl32.h b/include/linux/ioctl32.h
deleted file mode 100644
index 948809d..0000000
--- a/include/linux/ioctl32.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef IOCTL32_H
-#define IOCTL32_H 1
-
-#include <linux/compiler.h> /* for __deprecated */
-
-struct file;
-
-typedef int (*ioctl_trans_handler_t)(unsigned int, unsigned int,
- unsigned long, struct file *);
-
-struct ioctl_trans {
- unsigned long cmd;
- ioctl_trans_handler_t handler;
- struct ioctl_trans *next;
-};
-
-#endif
diff --git a/include/linux/ipc.h b/include/linux/ipc.h
index 6da6772..1980867 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -92,16 +92,19 @@ extern struct ipc_namespace init_ipc_ns;
#ifdef CONFIG_SYSVIPC
#define INIT_IPC_NS(ns) .ns = &init_ipc_ns,
-extern int copy_ipcs(unsigned long flags, struct task_struct *tsk);
+extern struct ipc_namespace *copy_ipcs(unsigned long flags,
+ struct ipc_namespace *ns);
#else
#define INIT_IPC_NS(ns)
-static inline int copy_ipcs(unsigned long flags, struct task_struct *tsk)
-{ return 0; }
+static inline struct ipc_namespace *copy_ipcs(unsigned long flags,
+ struct ipc_namespace *ns)
+{
+ return ns;
+}
#endif
#ifdef CONFIG_IPC_NS
extern void free_ipc_ns(struct kref *kref);
-extern int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns);
#endif
static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index a689940..1695054 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -147,8 +147,6 @@ struct irq_chip {
* @dir: /proc/irq/ procfs entry
* @affinity_entry: /proc/irq/smp_affinity procfs entry on SMP
* @name: flow handler name for /proc/interrupts output
- *
- * Pad this out to 32 bytes for cache and indexing reasons.
*/
struct irq_desc {
irq_flow_handler_t handle_irq;
@@ -175,7 +173,7 @@ struct irq_desc {
struct proc_dir_entry *dir;
#endif
const char *name;
-} ____cacheline_aligned;
+} ____cacheline_internodealigned_in_smp;
extern struct irq_desc irq_desc[NR_IRQS];
diff --git a/include/linux/isdn/capiutil.h b/include/linux/isdn/capiutil.h
index 63bd9cf..5a52f2c 100644
--- a/include/linux/isdn/capiutil.h
+++ b/include/linux/isdn/capiutil.h
@@ -187,7 +187,6 @@ typedef struct {
#define CDEBUG_SIZE 1024
#define CDEBUG_GSIZE 4096
-_cdebbuf *cdebbuf_alloc(void);
void cdebbuf_free(_cdebbuf *cdb);
int cdebug_init(void);
void cdebug_exit(void);
diff --git a/include/linux/isdn_divertif.h b/include/linux/isdn_divertif.h
index 0e7e44c..07821ca 100644
--- a/include/linux/isdn_divertif.h
+++ b/include/linux/isdn_divertif.h
@@ -24,6 +24,10 @@
#define DIVERT_REL_ERR 0x04 /* module not registered */
#define DIVERT_REG_NAME isdn_register_divert
+#ifdef __KERNEL__
+#include <linux/isdnif.h>
+#include <linux/types.h>
+
/***************************************************************/
/* structure exchanging data between isdn hl and divert module */
/***************************************************************/
@@ -40,3 +44,4 @@ typedef struct
/* function register */
/*********************/
extern int DIVERT_REG_NAME(isdn_divert_if *);
+#endif
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index 3e3b92d..12178d2 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -30,6 +30,9 @@ extern int sprint_symbol(char *buffer, unsigned long address);
/* Look up a kernel symbol and print it to the kernel messages. */
extern void __print_symbol(const char *fmt, unsigned long address);
+int lookup_symbol_name(unsigned long addr, char *symname);
+int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name);
+
#else /* !CONFIG_KALLSYMS */
static inline unsigned long kallsyms_lookup_name(const char *name)
@@ -58,6 +61,16 @@ static inline int sprint_symbol(char *buffer, unsigned long addr)
return 0;
}
+static inline int lookup_symbol_name(unsigned long addr, char *symname)
+{
+ return -ERANGE;
+}
+
+static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name)
+{
+ return -ERANGE;
+}
+
/* Stupid that this does nothing, but I didn't create this mess. */
#define __print_symbol(fmt, addr)
#endif /*CONFIG_KALLSYMS*/
diff --git a/include/linux/kdebug.h b/include/linux/kdebug.h
new file mode 100644
index 0000000..5db38d6
--- /dev/null
+++ b/include/linux/kdebug.h
@@ -0,0 +1,20 @@
+#ifndef _LINUX_KDEBUG_H
+#define _LINUX_KDEBUG_H
+
+#include <asm/kdebug.h>
+
+struct die_args {
+ struct pt_regs *regs;
+ const char *str;
+ long err;
+ int trapnr;
+ int signr;
+};
+
+int register_die_notifier(struct notifier_block *nb);
+int unregister_die_notifier(struct notifier_block *nb);
+
+int notify_die(enum die_val val, const char *str,
+ struct pt_regs *regs, long err, int trap, int sig);
+
+#endif /* _LINUX_KDEBUG_H */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index e2f41b0..144b615 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -35,7 +35,8 @@ extern const char linux_proc_banner[];
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
+
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 696e5ec..8c2c7fc 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -7,6 +7,8 @@
#include <linux/linkage.h>
#include <linux/compat.h>
#include <linux/ioport.h>
+#include <linux/elfcore.h>
+#include <linux/elf.h>
#include <asm/kexec.h>
/* Verify architecture specific macros are defined */
@@ -31,6 +33,19 @@
#error KEXEC_ARCH not defined
#endif
+#define KEXEC_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
+#define KEXEC_CORE_NOTE_NAME "CORE"
+#define KEXEC_CORE_NOTE_NAME_BYTES ALIGN(sizeof(KEXEC_CORE_NOTE_NAME), 4)
+#define KEXEC_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4)
+/*
+ * The per-cpu notes area is a list of notes terminated by a "NULL"
+ * note header. For kdump, the code in vmcore.c runs in the context
+ * of the second kernel to combine them into one note.
+ */
+#define KEXEC_NOTE_BYTES ( (KEXEC_NOTE_HEAD_BYTES * 2) + \
+ KEXEC_CORE_NOTE_NAME_BYTES + \
+ KEXEC_CORE_NOTE_DESC_BYTES )
+
/*
* This structure is used to hold the arguments that are used when loading
* kernel binaries.
@@ -136,7 +151,7 @@ extern struct kimage *kexec_crash_image;
/* Location of a reserved region to hold the crash kernel.
*/
extern struct resource crashk_res;
-typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+typedef u32 note_buf_t[KEXEC_NOTE_BYTES/4];
extern note_buf_t *crash_notes;
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 769be39..23adf60 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -78,7 +78,7 @@ struct kprobe {
kprobe_opcode_t *addr;
/* Allow user to indicate symbol name of the probe point */
- char *symbol_name;
+ const char *symbol_name;
/* Offset into the symbol */
unsigned int offset;
@@ -123,12 +123,18 @@ DECLARE_PER_CPU(struct kprobe *, current_kprobe);
DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
#ifdef ARCH_SUPPORTS_KRETPROBES
-extern void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs);
+extern void arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ struct pt_regs *regs);
+extern int arch_trampoline_kprobe(struct kprobe *p);
#else /* ARCH_SUPPORTS_KRETPROBES */
static inline void arch_prepare_kretprobe(struct kretprobe *rp,
struct pt_regs *regs)
{
}
+static inline int arch_trampoline_kprobe(struct kprobe *p)
+{
+ return 0;
+}
#endif /* ARCH_SUPPORTS_KRETPROBES */
/*
* Function-return probe -
@@ -157,6 +163,16 @@ struct kretprobe_instance {
struct task_struct *task;
};
+static inline void kretprobe_assert(struct kretprobe_instance *ri,
+ unsigned long orig_ret_address, unsigned long trampoline_address)
+{
+ if (!orig_ret_address || (orig_ret_address == trampoline_address)) {
+ printk("kretprobe BUG!: Processing kretprobe %p @ %p\n",
+ ri->rp, ri->rp->kp.addr);
+ BUG();
+ }
+}
+
extern spinlock_t kretprobe_lock;
extern struct mutex kprobe_mutex;
extern int arch_prepare_kprobe(struct kprobe *p);
@@ -199,8 +215,6 @@ void jprobe_return(void);
int register_kretprobe(struct kretprobe *rp);
void unregister_kretprobe(struct kretprobe *rp);
-struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp);
-void add_rp_inst(struct kretprobe_instance *ri);
void kprobe_flush_task(struct task_struct *tk);
void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
#else /* CONFIG_KPROBES */
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 275354f..e6edca8 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -11,7 +11,7 @@
#include <asm/types.h>
#include <linux/ioctl.h>
-#define KVM_API_VERSION 4
+#define KVM_API_VERSION 12
/*
* Architectural interrupt line count, and the size of the bitmap needed
@@ -33,37 +33,39 @@ struct kvm_memory_region {
/* for kvm_memory_region::flags */
#define KVM_MEM_LOG_DIRTY_PAGES 1UL
-
-#define KVM_EXIT_TYPE_FAIL_ENTRY 1
-#define KVM_EXIT_TYPE_VM_EXIT 2
+struct kvm_memory_alias {
+ __u32 slot; /* this has a different namespace than memory slots */
+ __u32 flags;
+ __u64 guest_phys_addr;
+ __u64 memory_size;
+ __u64 target_phys_addr;
+};
enum kvm_exit_reason {
KVM_EXIT_UNKNOWN = 0,
KVM_EXIT_EXCEPTION = 1,
KVM_EXIT_IO = 2,
- KVM_EXIT_CPUID = 3,
+ KVM_EXIT_HYPERCALL = 3,
KVM_EXIT_DEBUG = 4,
KVM_EXIT_HLT = 5,
KVM_EXIT_MMIO = 6,
KVM_EXIT_IRQ_WINDOW_OPEN = 7,
KVM_EXIT_SHUTDOWN = 8,
+ KVM_EXIT_FAIL_ENTRY = 9,
+ KVM_EXIT_INTR = 10,
};
-/* for KVM_RUN */
+/* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */
struct kvm_run {
/* in */
- __u32 emulated; /* skip current instruction */
- __u32 mmio_completed; /* mmio request completed */
__u8 request_interrupt_window;
__u8 padding1[7];
/* out */
- __u32 exit_type;
__u32 exit_reason;
- __u32 instruction_length;
__u8 ready_for_interrupt_injection;
__u8 if_flag;
- __u16 padding2;
+ __u8 padding2[2];
/* in (pre_kvm_run), out (post_kvm_run) */
__u64 cr8;
@@ -72,29 +74,26 @@ struct kvm_run {
union {
/* KVM_EXIT_UNKNOWN */
struct {
- __u32 hardware_exit_reason;
+ __u64 hardware_exit_reason;
} hw;
+ /* KVM_EXIT_FAIL_ENTRY */
+ struct {
+ __u64 hardware_entry_failure_reason;
+ } fail_entry;
/* KVM_EXIT_EXCEPTION */
struct {
__u32 exception;
__u32 error_code;
} ex;
/* KVM_EXIT_IO */
- struct {
+ struct kvm_io {
#define KVM_EXIT_IO_IN 0
#define KVM_EXIT_IO_OUT 1
__u8 direction;
__u8 size; /* bytes */
- __u8 string;
- __u8 string_down;
- __u8 rep;
- __u8 pad;
__u16 port;
- __u64 count;
- union {
- __u64 address;
- __u32 value;
- };
+ __u32 count;
+ __u64 data_offset; /* relative to kvm_run start */
} io;
struct {
} debug;
@@ -105,6 +104,13 @@ struct kvm_run {
__u32 len;
__u8 is_write;
} mmio;
+ /* KVM_EXIT_HYPERCALL */
+ struct {
+ __u64 args[6];
+ __u64 ret;
+ __u32 longmode;
+ __u32 pad;
+ } hypercall;
};
};
@@ -118,6 +124,21 @@ struct kvm_regs {
__u64 rip, rflags;
};
+/* for KVM_GET_FPU and KVM_SET_FPU */
+struct kvm_fpu {
+ __u8 fpr[8][16];
+ __u16 fcw;
+ __u16 fsw;
+ __u8 ftwx; /* in fxsave format */
+ __u8 pad1;
+ __u16 last_opcode;
+ __u64 last_ip;
+ __u64 last_dp;
+ __u8 xmm[16][16];
+ __u32 mxcsr;
+ __u32 pad2;
+};
+
struct kvm_segment {
__u64 base;
__u32 limit;
@@ -210,38 +231,74 @@ struct kvm_dirty_log {
};
};
+struct kvm_cpuid_entry {
+ __u32 function;
+ __u32 eax;
+ __u32 ebx;
+ __u32 ecx;
+ __u32 edx;
+ __u32 padding;
+};
+
+/* for KVM_SET_CPUID */
+struct kvm_cpuid {
+ __u32 nent;
+ __u32 padding;
+ struct kvm_cpuid_entry entries[0];
+};
+
+/* for KVM_SET_SIGNAL_MASK */
+struct kvm_signal_mask {
+ __u32 len;
+ __u8 sigset[0];
+};
+
#define KVMIO 0xAE
/*
* ioctls for /dev/kvm fds:
*/
-#define KVM_GET_API_VERSION _IO(KVMIO, 1)
-#define KVM_CREATE_VM _IO(KVMIO, 2) /* returns a VM fd */
-#define KVM_GET_MSR_INDEX_LIST _IOWR(KVMIO, 15, struct kvm_msr_list)
+#define KVM_GET_API_VERSION _IO(KVMIO, 0x00)
+#define KVM_CREATE_VM _IO(KVMIO, 0x01) /* returns a VM fd */
+#define KVM_GET_MSR_INDEX_LIST _IOWR(KVMIO, 0x02, struct kvm_msr_list)
+/*
+ * Check if a kvm extension is available. Argument is extension number,
+ * return is 1 (yes) or 0 (no, sorry).
+ */
+#define KVM_CHECK_EXTENSION _IO(KVMIO, 0x03)
+/*
+ * Get size for mmap(vcpu_fd)
+ */
+#define KVM_GET_VCPU_MMAP_SIZE _IO(KVMIO, 0x04) /* in bytes */
/*
* ioctls for VM fds
*/
-#define KVM_SET_MEMORY_REGION _IOW(KVMIO, 10, struct kvm_memory_region)
+#define KVM_SET_MEMORY_REGION _IOW(KVMIO, 0x40, struct kvm_memory_region)
/*
* KVM_CREATE_VCPU receives as a parameter the vcpu slot, and returns
* a vcpu fd.
*/
-#define KVM_CREATE_VCPU _IOW(KVMIO, 11, int)
-#define KVM_GET_DIRTY_LOG _IOW(KVMIO, 12, struct kvm_dirty_log)
+#define KVM_CREATE_VCPU _IO(KVMIO, 0x41)
+#define KVM_GET_DIRTY_LOG _IOW(KVMIO, 0x42, struct kvm_dirty_log)
+#define KVM_SET_MEMORY_ALIAS _IOW(KVMIO, 0x43, struct kvm_memory_alias)
/*
* ioctls for vcpu fds
*/
-#define KVM_RUN _IOWR(KVMIO, 2, struct kvm_run)
-#define KVM_GET_REGS _IOR(KVMIO, 3, struct kvm_regs)
-#define KVM_SET_REGS _IOW(KVMIO, 4, struct kvm_regs)
-#define KVM_GET_SREGS _IOR(KVMIO, 5, struct kvm_sregs)
-#define KVM_SET_SREGS _IOW(KVMIO, 6, struct kvm_sregs)
-#define KVM_TRANSLATE _IOWR(KVMIO, 7, struct kvm_translation)
-#define KVM_INTERRUPT _IOW(KVMIO, 8, struct kvm_interrupt)
-#define KVM_DEBUG_GUEST _IOW(KVMIO, 9, struct kvm_debug_guest)
-#define KVM_GET_MSRS _IOWR(KVMIO, 13, struct kvm_msrs)
-#define KVM_SET_MSRS _IOW(KVMIO, 14, struct kvm_msrs)
+#define KVM_RUN _IO(KVMIO, 0x80)
+#define KVM_GET_REGS _IOR(KVMIO, 0x81, struct kvm_regs)
+#define KVM_SET_REGS _IOW(KVMIO, 0x82, struct kvm_regs)
+#define KVM_GET_SREGS _IOR(KVMIO, 0x83, struct kvm_sregs)
+#define KVM_SET_SREGS _IOW(KVMIO, 0x84, struct kvm_sregs)
+#define KVM_TRANSLATE _IOWR(KVMIO, 0x85, struct kvm_translation)
+#define KVM_INTERRUPT _IOW(KVMIO, 0x86, struct kvm_interrupt)
+#define KVM_DEBUG_GUEST _IOW(KVMIO, 0x87, struct kvm_debug_guest)
+#define KVM_GET_MSRS _IOWR(KVMIO, 0x88, struct kvm_msrs)
+#define KVM_SET_MSRS _IOW(KVMIO, 0x89, struct kvm_msrs)
+#define KVM_SET_CPUID _IOW(KVMIO, 0x8a, struct kvm_cpuid)
+#define KVM_SET_SIGNAL_MASK _IOW(KVMIO, 0x8b, struct kvm_signal_mask)
+#define KVM_GET_FPU _IOR(KVMIO, 0x8c, struct kvm_fpu)
+#define KVM_SET_FPU _IOW(KVMIO, 0x8d, struct kvm_fpu)
#endif
diff --git a/include/linux/libata.h b/include/linux/libata.h
index d8cfc72..7906d75 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -296,18 +296,8 @@ enum {
/* how hard are we gonna try to probe/recover devices */
ATA_PROBE_MAX_TRIES = 3,
- ATA_EH_RESET_TRIES = 3,
ATA_EH_DEV_TRIES = 3,
- /* Drive spinup time (time from power-on to the first D2H FIS)
- * in msecs - 8s currently. Failing to get ready in this time
- * isn't critical. It will result in reset failure for
- * controllers which can't wait for the first D2H FIS. libata
- * will retry, so it just has to be long enough to spin up
- * most devices.
- */
- ATA_SPINUP_WAIT = 8000,
-
/* Horkage types. May be set by libata or controller on drives
(some horkage may be drive/controller pair dependant */
@@ -348,8 +338,9 @@ struct ata_queued_cmd;
/* typedefs */
typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
-typedef int (*ata_prereset_fn_t)(struct ata_port *ap);
-typedef int (*ata_reset_fn_t)(struct ata_port *ap, unsigned int *classes);
+typedef int (*ata_prereset_fn_t)(struct ata_port *ap, unsigned long deadline);
+typedef int (*ata_reset_fn_t)(struct ata_port *ap, unsigned int *classes,
+ unsigned long deadline);
typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *classes);
struct ata_ioports {
@@ -494,7 +485,6 @@ struct ata_eh_info {
unsigned int dev_action[ATA_MAX_DEVICES]; /* dev EH action */
unsigned int flags; /* ATA_EHI_* flags */
- unsigned long hotplug_timestamp;
unsigned int probe_mask;
char desc[ATA_EH_DESC_LEN];
@@ -688,13 +678,17 @@ extern void __sata_phy_reset(struct ata_port *ap);
extern void sata_phy_reset(struct ata_port *ap);
extern void ata_bus_reset(struct ata_port *ap);
extern int sata_set_spd(struct ata_port *ap);
-extern int sata_phy_debounce(struct ata_port *ap, const unsigned long *param);
-extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param);
-extern int ata_std_prereset(struct ata_port *ap);
-extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes);
-extern int sata_port_hardreset(struct ata_port *ap,
- const unsigned long *timing);
-extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class);
+extern int sata_phy_debounce(struct ata_port *ap, const unsigned long *param,
+ unsigned long deadline);
+extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param,
+ unsigned long deadline);
+extern int ata_std_prereset(struct ata_port *ap, unsigned long deadline);
+extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes,
+ unsigned long deadline);
+extern int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing,
+ unsigned long deadline);
+extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class,
+ unsigned long deadline);
extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
extern void ata_port_disable(struct ata_port *);
extern void ata_std_ports(struct ata_ioports *ioaddr);
@@ -750,6 +744,7 @@ extern void ata_host_resume(struct ata_host *host);
extern int ata_ratelimit(void);
extern int ata_busy_sleep(struct ata_port *ap,
unsigned long timeout_pat, unsigned long timeout);
+extern int ata_wait_ready(struct ata_port *ap, unsigned long deadline);
extern void ata_port_queue_task(struct ata_port *ap, work_func_t fn,
void *data, unsigned long delay);
extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
@@ -919,12 +914,7 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
static inline void __ata_ehi_hotplugged(struct ata_eh_info *ehi)
{
- if (ehi->flags & ATA_EHI_HOTPLUGGED)
- return;
-
ehi->flags |= ATA_EHI_HOTPLUGGED | ATA_EHI_RESUME_LINK;
- ehi->hotplug_timestamp = jiffies;
-
ehi->action |= ATA_EH_SOFTRESET;
ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1;
}
diff --git a/include/linux/list.h b/include/linux/list.h
index f9d71ea..9202703 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -426,6 +426,17 @@ static inline void list_splice_init_rcu(struct list_head *list,
container_of(ptr, type, member)
/**
+ * list_first_entry - get the first element from a list
+ * @ptr: the list head to take the element from.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+ list_entry((ptr)->next, type, member)
+
+/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index f6a81e0..05707e2 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -119,6 +119,9 @@ struct nlm_file {
* couldn't be granted because of a conflicting lock).
*/
#define NLM_NEVER (~(unsigned long) 0)
+/* timeout on non-blocking call: */
+#define NLM_TIMEOUT (7 * HZ)
+
struct nlm_block {
struct kref b_count; /* Reference count */
struct list_head b_list; /* linked list of all blocks */
@@ -130,6 +133,13 @@ struct nlm_block {
unsigned int b_id; /* block id */
unsigned char b_granted; /* VFS granted lock */
struct nlm_file * b_file; /* file in question */
+ struct cache_req * b_cache_req; /* deferred request handling */
+ struct file_lock * b_fl; /* set for GETLK */
+ struct cache_deferred_req * b_deferred_req;
+ unsigned int b_flags; /* block flags */
+#define B_QUEUED 1 /* lock queued */
+#define B_GOT_CALLBACK 2 /* got lock or conflicting lock */
+#define B_TIMED_OUT 4 /* filesystem too slow to respond */
};
/*
@@ -185,8 +195,8 @@ typedef int (*nlm_host_match_fn_t)(struct nlm_host *cur, struct nlm_host *ref)
__be32 nlmsvc_lock(struct svc_rqst *, struct nlm_file *,
struct nlm_lock *, int, struct nlm_cookie *);
__be32 nlmsvc_unlock(struct nlm_file *, struct nlm_lock *);
-__be32 nlmsvc_testlock(struct nlm_file *, struct nlm_lock *,
- struct nlm_lock *);
+__be32 nlmsvc_testlock(struct svc_rqst *, struct nlm_file *,
+ struct nlm_lock *, struct nlm_lock *, struct nlm_cookie *);
__be32 nlmsvc_cancel_blocked(struct nlm_file *, struct nlm_lock *);
unsigned long nlmsvc_retry_blocked(void);
void nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
diff --git a/include/linux/loop.h b/include/linux/loop.h
index 191a595..0b99b31 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -64,6 +64,8 @@ struct loop_device {
wait_queue_head_t lo_event;
request_queue_t *lo_queue;
+ struct gendisk *lo_disk;
+ struct list_head lo_list;
};
#endif /* __KERNEL__ */
diff --git a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h
index bdc0112..580b3f4 100644
--- a/include/linux/mc146818rtc.h
+++ b/include/linux/mc146818rtc.h
@@ -22,8 +22,15 @@ extern spinlock_t rtc_lock; /* serialize CMOS RAM access */
/* Some RTCs extend the mc146818 register set to support alarms of more
* than 24 hours in the future; or dates that include a century code.
* This platform_data structure can pass this information to the driver.
+ *
+ * Also, some platforms need suspend()/resume() hooks to kick in special
+ * handling of wake alarms, e.g. activating ACPI BIOS hooks or setting up
+ * a separate wakeup alarm used by some almost-clone chips.
*/
struct cmos_rtc_board_info {
+ void (*wake_on)(struct device *dev);
+ void (*wake_off)(struct device *dev);
+
u8 rtc_day_alarm; /* zero, or register index */
u8 rtc_mon_alarm; /* zero, or register index */
u8 rtc_century; /* zero, or register index */
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 75e55dc..e10a90a 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -2,18 +2,29 @@
#define _LINUX_MIGRATE_H
#include <linux/mm.h>
+#include <linux/mempolicy.h>
+#include <linux/pagemap.h>
typedef struct page *new_page_t(struct page *, unsigned long private, int **);
+#ifdef CONFIG_MIGRATION
/* Check if a vma is migratable */
static inline int vma_migratable(struct vm_area_struct *vma)
{
if (vma->vm_flags & (VM_IO|VM_HUGETLB|VM_PFNMAP|VM_RESERVED))
return 0;
+ /*
+ * Migration allocates pages in the highest zone. If we cannot
+ * do so then migration (at least from node to node) is not
+ * possible.
+ */
+ if (vma->vm_file &&
+ gfp_zone(mapping_gfp_mask(vma->vm_file->f_mapping))
+ < policy_zone)
+ return 0;
return 1;
}
-#ifdef CONFIG_MIGRATION
extern int isolate_lru_page(struct page *p, struct list_head *pagelist);
extern int putback_lru_pages(struct list_head *l);
extern int migrate_page(struct address_space *,
@@ -28,6 +39,8 @@ extern int migrate_vmas(struct mm_struct *mm,
const nodemask_t *from, const nodemask_t *to,
unsigned long flags);
#else
+static inline int vma_migratable(struct vm_area_struct *vma)
+ { return 0; }
static inline int isolate_lru_page(struct page *p, struct list_head *list)
{ return -ENOSYS; }
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
index 326da7d..dff9ea3 100644
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -29,6 +29,7 @@
#define TUN_MINOR 200
#define HPET_MINOR 228
+#define KVM_MINOR 232
struct device;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 60e0e4a..4670ebd 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -267,21 +267,31 @@ static inline int get_page_unless_zero(struct page *page)
return atomic_inc_not_zero(&page->_count);
}
+static inline struct page *compound_head(struct page *page)
+{
+ if (unlikely(PageTail(page)))
+ return page->first_page;
+ return page;
+}
+
static inline int page_count(struct page *page)
{
- if (unlikely(PageCompound(page)))
- page = (struct page *)page_private(page);
- return atomic_read(&page->_count);
+ return atomic_read(&compound_head(page)->_count);
}
static inline void get_page(struct page *page)
{
- if (unlikely(PageCompound(page)))
- page = (struct page *)page_private(page);
+ page = compound_head(page);
VM_BUG_ON(atomic_read(&page->_count) == 0);
atomic_inc(&page->_count);
}
+static inline struct page *virt_to_head_page(const void *x)
+{
+ struct page *page = virt_to_page(x);
+ return compound_head(page);
+}
+
/*
* Setup the page count before being freed into the page allocator for
* the first time (boot or memory hotplug)
@@ -314,6 +324,18 @@ static inline compound_page_dtor *get_compound_page_dtor(struct page *page)
return (compound_page_dtor *)page[1].lru.next;
}
+static inline int compound_order(struct page *page)
+{
+ if (!PageHead(page))
+ return 0;
+ return (unsigned long)page[1].lru.prev;
+}
+
+static inline void set_compound_order(struct page *page, unsigned long order)
+{
+ page[1].lru.prev = (void *)order;
+}
+
/*
* Multiple processes may "see" the same page. E.g. for untouched
* mappings of /dev/null, all processes see the same page full of
@@ -850,8 +872,26 @@ static inline int vma_wants_writenotify(struct vm_area_struct *vma)
extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl));
+#ifdef __PAGETABLE_PUD_FOLDED
+static inline int __pud_alloc(struct mm_struct *mm, pgd_t *pgd,
+ unsigned long address)
+{
+ return 0;
+}
+#else
int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address);
+#endif
+
+#ifdef __PAGETABLE_PMD_FOLDED
+static inline int __pmd_alloc(struct mm_struct *mm, pud_t *pud,
+ unsigned long address)
+{
+ return 0;
+}
+#else
int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address);
+#endif
+
int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address);
int __pte_alloc_kernel(pmd_t *pmd, unsigned long address);
@@ -1130,6 +1170,11 @@ struct page *follow_page(struct vm_area_struct *, unsigned long address,
#define FOLL_GET 0x04 /* do get_page on page */
#define FOLL_ANON 0x08 /* give ZERO_PAGE if no pgtable */
+typedef int (*pte_fn_t)(pte_t *pte, struct page *pmd_page, unsigned long addr,
+ void *data);
+extern int apply_to_page_range(struct mm_struct *mm, unsigned long address,
+ unsigned long size, pte_fn_t fn, void *data);
+
#ifdef CONFIG_PROC_FS
void vm_stat_account(struct mm_struct *, unsigned long, struct file *, long);
#else
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index c3852fd..e30687b 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -19,10 +19,16 @@ struct page {
unsigned long flags; /* Atomic flags, some possibly
* updated asynchronously */
atomic_t _count; /* Usage count, see below. */
- atomic_t _mapcount; /* Count of ptes mapped in mms,
+ union {
+ atomic_t _mapcount; /* Count of ptes mapped in mms,
* to show when page is mapped
* & limit reverse map searches.
*/
+ struct { /* SLUB uses */
+ short unsigned int inuse;
+ short unsigned int offset;
+ };
+ };
union {
struct {
unsigned long private; /* Mapping-private opaque data:
@@ -43,8 +49,15 @@ struct page {
#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
spinlock_t ptl;
#endif
+ struct { /* SLUB uses */
+ struct page *first_page; /* Compound pages */
+ struct kmem_cache *slab; /* Pointer to slab */
+ };
+ };
+ union {
+ pgoff_t index; /* Our offset within mapping. */
+ void *freelist; /* SLUB: pointer to free object */
};
- pgoff_t index; /* Our offset within mapping. */
struct list_head lru; /* Pageout list, eg. active_list
* protected by zone->lru_lock !
*/
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index ee9e314..2f1544e 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -784,6 +784,18 @@ void sparse_init(void);
void memory_present(int nid, unsigned long start, unsigned long end);
unsigned long __init node_memmap_size_bytes(int, unsigned long, unsigned long);
+/*
+ * If it is possible to have holes within a MAX_ORDER_NR_PAGES, then we
+ * need to check pfn validility within that MAX_ORDER_NR_PAGES block.
+ * pfn_valid_within() should be used in this case; we optimise this away
+ * when we have no holes within a MAX_ORDER_NR_PAGES block.
+ */
+#ifdef CONFIG_HOLES_IN_ZONE
+#define pfn_valid_within(pfn) pfn_valid(pfn)
+#else
+#define pfn_valid_within(pfn) (1)
+#endif
+
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _LINUX_MMZONE_H */
diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h
index 4af0b1f..1fa4d98 100644
--- a/include/linux/mnt_namespace.h
+++ b/include/linux/mnt_namespace.h
@@ -14,10 +14,9 @@ struct mnt_namespace {
int event;
};
-extern int copy_mnt_ns(int, struct task_struct *);
-extern void __put_mnt_ns(struct mnt_namespace *ns);
-extern struct mnt_namespace *dup_mnt_ns(struct task_struct *,
+extern struct mnt_namespace *copy_mnt_ns(int, struct mnt_namespace *,
struct fs_struct *);
+extern void __put_mnt_ns(struct mnt_namespace *ns);
static inline void put_mnt_ns(struct mnt_namespace *ns)
{
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index e96b2de..af04a55 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -262,6 +262,7 @@ struct i2c_device_id {
/* Input */
#define INPUT_DEVICE_ID_EV_MAX 0x1f
+#define INPUT_DEVICE_ID_KEY_MIN_INTERESTING 0x71
#define INPUT_DEVICE_ID_KEY_MAX 0x1ff
#define INPUT_DEVICE_ID_REL_MAX 0x0f
#define INPUT_DEVICE_ID_ABS_MAX 0x3f
diff --git a/include/linux/module.h b/include/linux/module.h
index f0b0faf..6d3dc9c 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -370,16 +370,14 @@ struct module *module_text_address(unsigned long addr);
struct module *__module_text_address(unsigned long addr);
int is_module_address(unsigned long addr);
-/* Returns module and fills in value, defined and namebuf, or NULL if
+/* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
symnum out of range. */
-struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
- char *type, char *name, size_t namelen);
+int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
+ char *name, char *module_name, int *exported);
/* Look for this name: can be of form module:name. */
unsigned long module_kallsyms_lookup_name(const char *name);
-int is_exported(const char *name, const struct module *mod);
-
extern void __module_put_and_exit(struct module *mod, long code)
__attribute__((noreturn));
#define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code);
@@ -456,6 +454,8 @@ const char *module_address_lookup(unsigned long addr,
unsigned long *symbolsize,
unsigned long *offset,
char **modname);
+int lookup_module_symbol_name(unsigned long addr, char *symname);
+int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name);
/* For extable.c to search modules' exception tables. */
const struct exception_table_entry *search_module_extables(unsigned long addr);
@@ -527,20 +527,24 @@ static inline const char *module_address_lookup(unsigned long addr,
return NULL;
}
-static inline struct module *module_get_kallsym(unsigned int symnum,
- unsigned long *value,
- char *type, char *name,
- size_t namelen)
+static inline int lookup_module_symbol_name(unsigned long addr, char *symname)
{
- return NULL;
+ return -ERANGE;
}
-static inline unsigned long module_kallsyms_lookup_name(const char *name)
+static inline int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name)
{
- return 0;
+ return -ERANGE;
}
-static inline int is_exported(const char *name, const struct module *mod)
+static inline int module_get_kallsym(unsigned int symnum, unsigned long *value,
+ char *type, char *name,
+ char *module_name, int *exported)
+{
+ return -ERANGE;
+}
+
+static inline unsigned long module_kallsyms_lookup_name(const char *name)
{
return 0;
}
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index fa253fa..0e09c00 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -205,7 +205,8 @@ struct fat_mount_options {
numtail:1, /* Does first alias have a numeric '~1' type tail? */
atari:1, /* Use Atari GEMDOS variation of MS-DOS fs */
flush:1, /* write things quickly */
- nocase:1; /* Does this need case conversion? 0=need case conversion*/
+ nocase:1, /* Does this need case conversion? 0=need case conversion*/
+ usefree:1; /* Use free_clusters for FAT32 */
};
#define FAT_HASH_BITS 8
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index c95d5e6..52b4378 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -82,7 +82,7 @@ struct nfs_server {
struct rpc_clnt * client_acl; /* ACL RPC client handle */
struct nfs_iostats * io_stats; /* I/O statistics */
struct backing_dev_info backing_dev_info;
- atomic_t writeback; /* number of writeback pages */
+ atomic_long_t writeback; /* number of writeback pages */
int flags; /* various flags */
unsigned int caps; /* server capabilities */
unsigned int rsize; /* read size */
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index 0b9f0dc..189e0dc 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -31,10 +31,11 @@ struct nsproxy {
};
extern struct nsproxy init_nsproxy;
-struct nsproxy *dup_namespaces(struct nsproxy *orig);
int copy_namespaces(int flags, struct task_struct *tsk);
void get_task_namespaces(struct task_struct *tsk);
void free_nsproxy(struct nsproxy *ns);
+int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **,
+ struct fs_struct *);
static inline void put_nsproxy(struct nsproxy *ns)
{
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 9632659..ae2d79f 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -6,6 +6,7 @@
#define PAGE_FLAGS_H
#include <linux/types.h>
+#include <linux/mm_types.h>
/*
* Various page->flags bits:
@@ -82,13 +83,11 @@
#define PG_private 11 /* If pagecache, has fs-private data */
#define PG_writeback 12 /* Page is under writeback */
-#define PG_nosave 13 /* Used for system suspend/resume */
#define PG_compound 14 /* Part of a compound page */
#define PG_swapcache 15 /* Swap page: swp_entry_t in private */
#define PG_mappedtodisk 16 /* Has blocks allocated on-disk */
#define PG_reclaim 17 /* To be reclaimed asap */
-#define PG_nosave_free 18 /* Used for system suspend/resume */
#define PG_buddy 19 /* Page is free, on buddy lists */
/* PG_owner_priv_1 users should have descriptive aliases */
@@ -214,16 +213,6 @@ static inline void SetPageUptodate(struct page *page)
ret; \
})
-#define PageNosave(page) test_bit(PG_nosave, &(page)->flags)
-#define SetPageNosave(page) set_bit(PG_nosave, &(page)->flags)
-#define TestSetPageNosave(page) test_and_set_bit(PG_nosave, &(page)->flags)
-#define ClearPageNosave(page) clear_bit(PG_nosave, &(page)->flags)
-#define TestClearPageNosave(page) test_and_clear_bit(PG_nosave, &(page)->flags)
-
-#define PageNosaveFree(page) test_bit(PG_nosave_free, &(page)->flags)
-#define SetPageNosaveFree(page) set_bit(PG_nosave_free, &(page)->flags)
-#define ClearPageNosaveFree(page) clear_bit(PG_nosave_free, &(page)->flags)
-
#define PageBuddy(page) test_bit(PG_buddy, &(page)->flags)
#define __SetPageBuddy(page) __set_bit(PG_buddy, &(page)->flags)
#define __ClearPageBuddy(page) __clear_bit(PG_buddy, &(page)->flags)
@@ -241,6 +230,34 @@ static inline void SetPageUptodate(struct page *page)
#define __SetPageCompound(page) __set_bit(PG_compound, &(page)->flags)
#define __ClearPageCompound(page) __clear_bit(PG_compound, &(page)->flags)
+/*
+ * PG_reclaim is used in combination with PG_compound to mark the
+ * head and tail of a compound page
+ *
+ * PG_compound & PG_reclaim => Tail page
+ * PG_compound & ~PG_reclaim => Head page
+ */
+
+#define PG_head_tail_mask ((1L << PG_compound) | (1L << PG_reclaim))
+
+#define PageTail(page) ((page->flags & PG_head_tail_mask) \
+ == PG_head_tail_mask)
+
+static inline void __SetPageTail(struct page *page)
+{
+ page->flags |= PG_head_tail_mask;
+}
+
+static inline void __ClearPageTail(struct page *page)
+{
+ page->flags &= ~PG_head_tail_mask;
+}
+
+#define PageHead(page) ((page->flags & PG_head_tail_mask) \
+ == (1L << PG_compound))
+#define __SetPageHead(page) __SetPageCompound(page)
+#define __ClearPageHead(page) __ClearPageCompound(page)
+
#ifdef CONFIG_SWAP
#define PageSwapCache(page) test_bit(PG_swapcache, &(page)->flags)
#define SetPageSwapCache(page) set_bit(PG_swapcache, &(page)->flags)
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 7a8dcb8..8a83537 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -11,6 +11,7 @@
#include <linux/compiler.h>
#include <asm/uaccess.h>
#include <linux/gfp.h>
+#include <linux/bitops.h>
/*
* Bits in mapping->flags. The lower __GFP_BITS_SHIFT bits are the page
@@ -19,6 +20,16 @@
#define AS_EIO (__GFP_BITS_SHIFT + 0) /* IO error on async write */
#define AS_ENOSPC (__GFP_BITS_SHIFT + 1) /* ENOSPC on async write */
+static inline void mapping_set_error(struct address_space *mapping, int error)
+{
+ if (error) {
+ if (error == -ENOSPC)
+ set_bit(AS_ENOSPC, &mapping->flags);
+ else
+ set_bit(AS_EIO, &mapping->flags);
+ }
+}
+
static inline gfp_t mapping_gfp_mask(struct address_space * mapping)
{
return (__force gfp_t)mapping->flags & __GFP_BITS_MASK;
@@ -95,12 +106,23 @@ static inline struct page *grab_cache_page(struct address_space *mapping, unsign
extern struct page * grab_cache_page_nowait(struct address_space *mapping,
unsigned long index);
+extern struct page * read_cache_page_async(struct address_space *mapping,
+ unsigned long index, filler_t *filler,
+ void *data);
extern struct page * read_cache_page(struct address_space *mapping,
unsigned long index, filler_t *filler,
void *data);
extern int read_cache_pages(struct address_space *mapping,
struct list_head *pages, filler_t *filler, void *data);
+static inline struct page *read_mapping_page_async(
+ struct address_space *mapping,
+ unsigned long index, void *data)
+{
+ filler_t *filler = (filler_t *)mapping->a_ops->readpage;
+ return read_cache_page_async(mapping, index, filler, data);
+}
+
static inline struct page *read_mapping_page(struct address_space *mapping,
unsigned long index, void *data)
{
diff --git a/include/linux/parport.h b/include/linux/parport.h
index 80682aa..9cdd694 100644
--- a/include/linux/parport.h
+++ b/include/linux/parport.h
@@ -279,6 +279,10 @@ struct parport {
int dma;
int muxport; /* which muxport (if any) this is */
int portnum; /* which physical parallel port (not mux) */
+ struct device *dev; /* Physical device associated with IO/DMA.
+ * This may unfortulately be null if the
+ * port has a legacy driver.
+ */
struct parport *physport;
/* If this is a non-default mux
@@ -289,7 +293,7 @@ struct parport {
following structure members are
meaningless: devices, cad, muxsel,
waithead, waittail, flags, pdir,
- ieee1284, *_lock.
+ dev, ieee1284, *_lock.
It this is a default mux parport, or
there is no mux involved, this points to
@@ -302,7 +306,7 @@ struct parport {
struct pardevice *waithead;
struct pardevice *waittail;
-
+
struct list_head list;
unsigned int flags;
diff --git a/include/linux/parport_pc.h b/include/linux/parport_pc.h
index 1cc0f6b..ea8c6d8 100644
--- a/include/linux/parport_pc.h
+++ b/include/linux/parport_pc.h
@@ -38,7 +38,6 @@ struct parport_pc_private {
/* buffer suitable for DMA, if DMA enabled */
char *dma_buf;
dma_addr_t dma_handle;
- struct pci_dev *dev;
struct list_head list;
struct parport *port;
};
@@ -232,7 +231,7 @@ extern int parport_pc_claim_resources(struct parport *p);
extern struct parport *parport_pc_probe_port (unsigned long base,
unsigned long base_hi,
int irq, int dma,
- struct pci_dev *dev);
+ struct device *dev);
extern void parport_pc_unregister_port (struct parport *p);
#endif
diff --git a/include/linux/phantom.h b/include/linux/phantom.h
new file mode 100644
index 0000000..d3ebbfa
--- /dev/null
+++ b/include/linux/phantom.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2005-2007 Jiri Slaby <jirislaby@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __PHANTOM_H
+#define __PHANTOM_H
+
+#include <asm/types.h>
+
+/* PHN_(G/S)ET_REG param */
+struct phm_reg {
+ __u32 reg;
+ __u32 value;
+};
+
+/* PHN_(G/S)ET_REGS param */
+struct phm_regs {
+ __u32 count;
+ __u32 mask;
+ __u32 values[8];
+};
+
+#define PH_IOC_MAGIC 'p'
+#define PHN_GET_REG _IOWR(PH_IOC_MAGIC, 0, struct phm_reg *)
+#define PHN_SET_REG _IOW (PH_IOC_MAGIC, 1, struct phm_reg *)
+#define PHN_GET_REGS _IOWR(PH_IOC_MAGIC, 2, struct phm_regs *)
+#define PHN_SET_REGS _IOW (PH_IOC_MAGIC, 3, struct phm_regs *)
+#define PH_IOC_MAXNR 3
+
+#define PHN_CONTROL 0x6 /* control byte in iaddr space */
+#define PHN_CTL_AMP 0x1 /* switch after torques change */
+#define PHN_CTL_BUT 0x2 /* is button switched */
+#define PHN_CTL_IRQ 0x10 /* is irq enabled */
+
+#define PHN_ZERO_FORCE 2048 /* zero torque on motor */
+
+#endif
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index 2833806..169c6c2 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -29,7 +29,7 @@ static inline void get_pid_ns(struct pid_namespace *ns)
kref_get(&ns->kref);
}
-extern int copy_pid_ns(int flags, struct task_struct *tsk);
+extern struct pid_namespace *copy_pid_ns(int flags, struct pid_namespace *ns);
extern void free_pid_ns(struct kref *kref);
static inline void put_pid_ns(struct pid_namespace *ns)
diff --git a/include/linux/pmu.h b/include/linux/pmu.h
index b0952e5..37ca573 100644
--- a/include/linux/pmu.h
+++ b/include/linux/pmu.h
@@ -225,4 +225,12 @@ extern unsigned int pmu_power_flags;
/* Backlight */
extern void pmu_backlight_init(void);
+/* some code needs to know if the PMU was suspended for hibernation */
+#ifdef CONFIG_PM
+extern int pmu_sys_suspended;
+#else
+/* if power management is not configured it can't be suspended */
+#define pmu_sys_suspended 0
+#endif
+
#endif /* __KERNEL__ */
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 9a5226f..2a1897e 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -177,6 +177,7 @@ static inline void pnp_set_card_drvdata (struct pnp_card_link *pcard, void *data
struct pnp_dev {
struct device dev; /* Driver Model device interface */
+ u64 dma_mask;
unsigned char number; /* used as an index, must be unique */
int status;
@@ -363,6 +364,7 @@ int pnp_add_device(struct pnp_dev *dev);
int pnp_device_attach(struct pnp_dev *pnp_dev);
void pnp_device_detach(struct pnp_dev *pnp_dev);
extern struct list_head pnp_global;
+extern int pnp_platform_devices;
/* multidevice card support */
int pnp_add_card(struct pnp_card *card);
@@ -410,6 +412,7 @@ static inline int pnp_init_device(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_add_device(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_device_attach(struct pnp_dev *pnp_dev) { return -ENODEV; }
static inline void pnp_device_detach(struct pnp_dev *pnp_dev) { ; }
+#define pnp_platform_devices 0
/* multidevice card support */
static inline int pnp_add_card(struct pnp_card *card) { return -ENODEV; }
diff --git a/include/linux/poison.h b/include/linux/poison.h
index 89580b7..d93c300 100644
--- a/include/linux/poison.h
+++ b/include/linux/poison.h
@@ -15,8 +15,11 @@
* Magic nums for obj red zoning.
* Placed in the first word before and the first word after an obj.
*/
-#define RED_INACTIVE 0x5A2CF071UL /* when obj is inactive */
-#define RED_ACTIVE 0x170FC2A5UL /* when obj is active */
+#define RED_INACTIVE 0x09F911029D74E35BULL /* when obj is inactive */
+#define RED_ACTIVE 0xD84156C5635688C0ULL /* when obj is active */
+
+#define SLUB_RED_INACTIVE 0xbb
+#define SLUB_RED_ACTIVE 0xcc
/* ...and for poisoning */
#define POISON_INUSE 0x5a /* for use-uninitialised poisoning */
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index be4652a..3469f96 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -104,6 +104,10 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir);
unsigned long task_vsize(struct mm_struct *);
int task_statm(struct mm_struct *, int *, int *, int *, int *);
char *task_mem(struct mm_struct *, char *);
+void clear_refs_smap(struct mm_struct *mm);
+
+struct proc_dir_entry *de_get(struct proc_dir_entry *de);
+void de_put(struct proc_dir_entry *de);
extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
struct proc_dir_entry *parent);
diff --git a/include/linux/quicklist.h b/include/linux/quicklist.h
new file mode 100644
index 0000000..9371c61
--- /dev/null
+++ b/include/linux/quicklist.h
@@ -0,0 +1,94 @@
+#ifndef LINUX_QUICKLIST_H
+#define LINUX_QUICKLIST_H
+/*
+ * Fast allocations and disposal of pages. Pages must be in the condition
+ * as needed after allocation when they are freed. Per cpu lists of pages
+ * are kept that only contain node local pages.
+ *
+ * (C) 2007, SGI. Christoph Lameter <clameter@sgi.com>
+ */
+#include <linux/kernel.h>
+#include <linux/gfp.h>
+#include <linux/percpu.h>
+
+#ifdef CONFIG_QUICKLIST
+
+struct quicklist {
+ void *page;
+ int nr_pages;
+};
+
+DECLARE_PER_CPU(struct quicklist, quicklist)[CONFIG_NR_QUICK];
+
+/*
+ * The two key functions quicklist_alloc and quicklist_free are inline so
+ * that they may be custom compiled for the platform.
+ * Specifying a NULL ctor can remove constructor support. Specifying
+ * a constant quicklist allows the determination of the exact address
+ * in the per cpu area.
+ *
+ * The fast patch in quicklist_alloc touched only a per cpu cacheline and
+ * the first cacheline of the page itself. There is minmal overhead involved.
+ */
+static inline void *quicklist_alloc(int nr, gfp_t flags, void (*ctor)(void *))
+{
+ struct quicklist *q;
+ void **p = NULL;
+
+ q =&get_cpu_var(quicklist)[nr];
+ p = q->page;
+ if (likely(p)) {
+ q->page = p[0];
+ p[0] = NULL;
+ q->nr_pages--;
+ }
+ put_cpu_var(quicklist);
+ if (likely(p))
+ return p;
+
+ p = (void *)__get_free_page(flags | __GFP_ZERO);
+ if (ctor && p)
+ ctor(p);
+ return p;
+}
+
+static inline void __quicklist_free(int nr, void (*dtor)(void *), void *p,
+ struct page *page)
+{
+ struct quicklist *q;
+ int nid = page_to_nid(page);
+
+ if (unlikely(nid != numa_node_id())) {
+ if (dtor)
+ dtor(p);
+ __free_page(page);
+ return;
+ }
+
+ q = &get_cpu_var(quicklist)[nr];
+ *(void **)p = q->page;
+ q->page = p;
+ q->nr_pages++;
+ put_cpu_var(quicklist);
+}
+
+static inline void quicklist_free(int nr, void (*dtor)(void *), void *pp)
+{
+ __quicklist_free(nr, dtor, pp, virt_to_page(pp));
+}
+
+static inline void quicklist_free_page(int nr, void (*dtor)(void *),
+ struct page *page)
+{
+ __quicklist_free(nr, dtor, page_address(page), page);
+}
+
+void quicklist_trim(int nr, void (*dtor)(void *),
+ unsigned long min_pages, unsigned long max_free);
+
+unsigned long quicklist_total_size(void);
+
+#endif
+
+#endif /* LINUX_QUICKLIST_H */
+
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 77db80a..6243982 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -44,8 +44,6 @@
typedef __kernel_uid32_t qid_t; /* Type in which we store ids in memory */
typedef __u64 qsize_t; /* Type in which we store sizes */
-extern spinlock_t dq_data_lock;
-
/* Size of blocks in which are counted size limits */
#define QUOTABLOCK_BITS 10
#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
@@ -139,6 +137,8 @@ struct if_dqinfo {
#include <linux/dqblk_v1.h>
#include <linux/dqblk_v2.h>
+extern spinlock_t dq_data_lock;
+
/* Maximal numbers of writes for quota operation (insert/delete/update)
* (over VFS all formats) */
#define DQUOT_INIT_ALLOC max(V1_INIT_ALLOC, V2_INIT_ALLOC)
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 90c23f6..5110201 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -37,9 +37,6 @@ extern int dquot_release(struct dquot *dquot);
extern int dquot_commit_info(struct super_block *sb, int type);
extern int dquot_mark_dquot_dirty(struct dquot *dquot);
-int remove_inode_dquot_ref(struct inode *inode, int type,
- struct list_head *tofree_head);
-
extern int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path);
extern int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
int format_id, int type);
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
index 3a28742..1e5488e 100644
--- a/include/linux/reiserfs_fs_sb.h
+++ b/include/linux/reiserfs_fs_sb.h
@@ -401,9 +401,10 @@ struct reiserfs_sb_info {
int reserved_blocks; /* amount of blocks reserved for further allocations */
spinlock_t bitmap_lock; /* this lock on now only used to protect reserved_blocks variable */
struct dentry *priv_root; /* root of /.reiserfs_priv */
+#ifdef CONFIG_REISERFS_FS_XATTR
struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */
struct rw_semaphore xattr_dir_sem;
-
+#endif
int j_errno;
#ifdef CONFIG_QUOTA
char *s_qf_names[MAXQUOTAS];
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
new file mode 100644
index 0000000..7c1ffba
--- /dev/null
+++ b/include/linux/rfkill.h
@@ -0,0 +1,89 @@
+#ifndef __RFKILL_H
+#define __RFKILL_H
+
+/*
+ * Copyright (C) 2006 Ivo van Doorn
+ * Copyright (C) 2007 Dmitry Torokhov
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+
+/**
+ * enum rfkill_type - type of rfkill switch.
+ * RFKILL_TYPE_WLAN: switch is no a Wireless network devices.
+ * RFKILL_TYPE_BlUETOOTH: switch is on a bluetooth device.
+ * RFKILL_TYPE_IRDA: switch is on an infrared devices.
+ */
+enum rfkill_type {
+ RFKILL_TYPE_WLAN = 0,
+ RFKILL_TYPE_BLUETOOTH = 1,
+ RFKILL_TYPE_IRDA = 2,
+ RFKILL_TYPE_MAX = 3,
+};
+
+enum rfkill_state {
+ RFKILL_STATE_OFF = 0,
+ RFKILL_STATE_ON = 1,
+};
+
+/**
+ * struct rfkill - rfkill control structure.
+ * @name: Name of the switch.
+ * @type: Radio type which the button controls, the value stored
+ * here should be a value from enum rfkill_type.
+ * @state: State of the switch (on/off).
+ * @user_claim: Set when the switch is controlled exlusively by userspace.
+ * @mutex: Guards switch state transitions
+ * @data: Pointer to the RF button drivers private data which will be
+ * passed along when toggling radio state.
+ * @toggle_radio(): Mandatory handler to control state of the radio.
+ * @dev: Device structure integrating the switch into device tree.
+ * @node: Used to place switch into list of all switches known to the
+ * the system.
+ *
+ * This structure represents a RF switch located on a network device.
+ */
+struct rfkill {
+ char *name;
+ enum rfkill_type type;
+
+ enum rfkill_state state;
+ bool user_claim;
+
+ struct mutex mutex;
+
+ void *data;
+ int (*toggle_radio)(void *data, enum rfkill_state state);
+
+ struct device dev;
+ struct list_head node;
+};
+#define to_rfkill(d) container_of(d, struct rfkill, dev)
+
+struct rfkill *rfkill_allocate(struct device *parent, enum rfkill_type type);
+void rfkill_free(struct rfkill *rfkill);
+int rfkill_register(struct rfkill *rfkill);
+void rfkill_unregister(struct rfkill *rfkill);
+
+void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state);
+
+#endif /* RFKILL_H */
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 5e22d45..6d5e4a4 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -4,7 +4,7 @@
* service. It is used with both the legacy mc146818 and also EFI
* Struct rtc_time and first 12 ioctl by Paul Gortmaker, 1996 - separated out
* from <linux/mc146818rtc.h> to this file for 2.4 kernels.
- *
+ *
* Copyright (C) 1999 Hewlett-Packard Co.
* Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
*/
@@ -13,7 +13,7 @@
/*
* The struct used to pass data via the following ioctl. Similar to the
- * struct tm in <time.h>, but it needs to be here so that the kernel
+ * struct tm in <time.h>, but it needs to be here so that the kernel
* source is self contained, allowing cross-compiles, etc. etc.
*/
@@ -50,7 +50,7 @@ struct rtc_wkalrm {
* pll_value*pll_posmult/pll_clock
* -ve pll_value means clock will run slower by
* pll_value*pll_negmult/pll_clock
- */
+ */
struct rtc_pll_info {
int pll_ctrl; /* placeholder for fancier control */
@@ -106,7 +106,6 @@ extern int rtc_year_days(unsigned int day, unsigned int month, unsigned int year
extern int rtc_valid_tm(struct rtc_time *tm);
extern int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time);
extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm);
-extern void rtc_merge_alarm(struct rtc_time *now, struct rtc_time *alarm);
#include <linux/device.h>
#include <linux/seq_file.h>
@@ -136,7 +135,7 @@ struct rtc_task;
struct rtc_device
{
- struct class_device class_dev;
+ struct device dev;
struct module *owner;
int id;
@@ -145,7 +144,6 @@ struct rtc_device
const struct rtc_class_ops *ops;
struct mutex ops_lock;
- struct class_device *rtc_dev;
struct cdev char_dev;
struct mutex char_lock;
@@ -169,35 +167,34 @@ struct rtc_device
unsigned int uie_timer_active:1;
#endif
};
-#define to_rtc_device(d) container_of(d, struct rtc_device, class_dev)
+#define to_rtc_device(d) container_of(d, struct rtc_device, dev)
extern struct rtc_device *rtc_device_register(const char *name,
struct device *dev,
const struct rtc_class_ops *ops,
struct module *owner);
-extern void rtc_device_unregister(struct rtc_device *rdev);
-extern int rtc_interface_register(struct class_interface *intf);
+extern void rtc_device_unregister(struct rtc_device *rtc);
-extern int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm);
-extern int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm);
-extern int rtc_set_mmss(struct class_device *class_dev, unsigned long secs);
-extern int rtc_read_alarm(struct class_device *class_dev,
+extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm);
+extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm);
+extern int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs);
+extern int rtc_read_alarm(struct rtc_device *rtc,
struct rtc_wkalrm *alrm);
-extern int rtc_set_alarm(struct class_device *class_dev,
+extern int rtc_set_alarm(struct rtc_device *rtc,
struct rtc_wkalrm *alrm);
-extern void rtc_update_irq(struct class_device *class_dev,
+extern void rtc_update_irq(struct rtc_device *rtc,
unsigned long num, unsigned long events);
-extern struct class_device *rtc_class_open(char *name);
-extern void rtc_class_close(struct class_device *class_dev);
+extern struct rtc_device *rtc_class_open(char *name);
+extern void rtc_class_close(struct rtc_device *rtc);
-extern int rtc_irq_register(struct class_device *class_dev,
+extern int rtc_irq_register(struct rtc_device *rtc,
struct rtc_task *task);
-extern void rtc_irq_unregister(struct class_device *class_dev,
+extern void rtc_irq_unregister(struct rtc_device *rtc,
struct rtc_task *task);
-extern int rtc_irq_set_state(struct class_device *class_dev,
+extern int rtc_irq_set_state(struct rtc_device *rtc,
struct rtc_task *task, int enabled);
-extern int rtc_irq_set_freq(struct class_device *class_dev,
+extern int rtc_irq_set_freq(struct rtc_device *rtc,
struct rtc_task *task, int freq);
typedef struct rtc_task {
diff --git a/include/linux/sched.h b/include/linux/sched.h
index a170758..3d95c48 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -194,6 +194,14 @@ extern void sched_init_smp(void);
extern void init_idle(struct task_struct *idle, int cpu);
extern cpumask_t nohz_cpu_mask;
+#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ)
+extern int select_nohz_load_balancer(int cpu);
+#else
+static inline int select_nohz_load_balancer(int cpu)
+{
+ return 0;
+}
+#endif
/*
* Only dump TASK_* tasks. (0 for all tasks)
@@ -226,6 +234,7 @@ extern void scheduler_tick(void);
extern void softlockup_tick(void);
extern void spawn_softlockup_task(void);
extern void touch_softlockup_watchdog(void);
+extern void touch_all_softlockup_watchdogs(void);
#else
static inline void softlockup_tick(void)
{
@@ -236,6 +245,9 @@ static inline void spawn_softlockup_task(void)
static inline void touch_softlockup_watchdog(void)
{
}
+static inline void touch_all_softlockup_watchdogs(void)
+{
+}
#endif
@@ -668,8 +680,14 @@ struct sched_group {
/*
* CPU power of this group, SCHED_LOAD_SCALE being max power for a
* single CPU. This is read only (except for setup, hotplug CPU).
+ * Note : Never change cpu_power without recompute its reciprocal
+ */
+ unsigned int __cpu_power;
+ /*
+ * reciprocal value of cpu_power to avoid expensive divides
+ * (see include/linux/reciprocal_div.h)
*/
- unsigned long cpu_power;
+ u32 reciprocal_cpu_power;
};
struct sched_domain {
@@ -801,8 +819,8 @@ struct task_struct {
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
struct thread_info *thread_info;
atomic_t usage;
- unsigned long flags; /* per process flags, defined below */
- unsigned long ptrace;
+ unsigned int flags; /* per process flags, defined below */
+ unsigned int ptrace;
int lock_depth; /* BKL lock depth */
@@ -825,7 +843,7 @@ struct task_struct {
unsigned long long sched_time; /* sched_clock time spent running */
enum sleep_type sleep_type;
- unsigned long policy;
+ unsigned int policy;
cpumask_t cpus_allowed;
unsigned int time_slice, first_time_slice;
@@ -845,11 +863,11 @@ struct task_struct {
/* task state */
struct linux_binfmt *binfmt;
- long exit_state;
+ int exit_state;
int exit_code, exit_signal;
int pdeath_signal; /* The signal sent when the parent dies */
/* ??? */
- unsigned long personality;
+ unsigned int personality;
unsigned did_exec:1;
pid_t pid;
pid_t tgid;
@@ -881,7 +899,7 @@ struct task_struct {
int __user *set_child_tid; /* CLONE_CHILD_SETTID */
int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
- unsigned long rt_priority;
+ unsigned int rt_priority;
cputime_t utime, stime;
unsigned long nvcsw, nivcsw; /* context switch counts */
struct timespec start_time;
@@ -1641,10 +1659,7 @@ static inline void arch_pick_mmap_layout(struct mm_struct *mm)
extern long sched_setaffinity(pid_t pid, cpumask_t new_mask);
extern long sched_getaffinity(pid_t pid, cpumask_t *mask);
-#include <linux/sysdev.h>
extern int sched_mc_power_savings, sched_smt_power_savings;
-extern struct sysdev_attribute attr_sched_mc_power_savings, attr_sched_smt_power_savings;
-extern int sched_create_sysfs_power_savings_entries(struct sysdev_class *cls);
extern void normalize_rt_tasks(void);
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 586aaba..aa2653a 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -39,7 +39,8 @@
#define PORT_RSA 13
#define PORT_NS16550A 14
#define PORT_XSCALE 15
-#define PORT_MAX_8250 15 /* max port ID */
+#define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */
+#define PORT_MAX_8250 16 /* max port ID */
/*
* ARM specific type numbers. These are not currently guaranteed
@@ -135,6 +136,9 @@
/* Xilinx uartlite */
#define PORT_UARTLITE 74
+/* Blackfin bf5xx */
+#define PORT_BFIN 75
+
#ifdef __KERNEL__
#include <linux/compiler.h>
@@ -230,6 +234,8 @@ struct uart_port {
#define UPIO_MEM32 (3)
#define UPIO_AU (4) /* Au1x00 type IO */
#define UPIO_TSI (5) /* Tsi108/109 type IO */
+#define UPIO_DWAPB (6) /* DesignWare APB UART */
+#define UPIO_RM9000 (7) /* RM9000 type IO */
unsigned int read_status_mask; /* driver specific */
unsigned int ignore_status_mask; /* driver specific */
@@ -260,6 +266,7 @@ struct uart_port {
#define UPF_CONS_FLOW ((__force upf_t) (1 << 23))
#define UPF_SHARE_IRQ ((__force upf_t) (1 << 24))
#define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28))
+#define UPF_FIXED_PORT ((__force upf_t) (1 << 29))
#define UPF_DEAD ((__force upf_t) (1 << 30))
#define UPF_IOREMAP ((__force upf_t) (1 << 31))
@@ -276,6 +283,7 @@ struct uart_port {
struct device *dev; /* parent device */
unsigned char hub6; /* this should be in the 8250 driver */
unsigned char unused[3];
+ void *private_data; /* generic platform data pointer */
};
/*
diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
index 3c8a6aa..1c5ed7d 100644
--- a/include/linux/serial_reg.h
+++ b/include/linux/serial_reg.h
@@ -38,6 +38,8 @@
#define UART_IIR_RDI 0x04 /* Receiver data interrupt */
#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */
+#define UART_IIR_BUSY 0x07 /* DesignWare APB Busy Detect */
+
#define UART_FCR 2 /* Out: FIFO Control Register */
#define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */
#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 1ef822e..71829ef 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -21,28 +21,25 @@ typedef struct kmem_cache kmem_cache_t __deprecated;
* The ones marked DEBUG are only valid if CONFIG_SLAB_DEBUG is set.
*/
#define SLAB_DEBUG_FREE 0x00000100UL /* DEBUG: Perform (expensive) checks on free */
-#define SLAB_DEBUG_INITIAL 0x00000200UL /* DEBUG: Call constructor (as verifier) */
#define SLAB_RED_ZONE 0x00000400UL /* DEBUG: Red zone objs in a cache */
#define SLAB_POISON 0x00000800UL /* DEBUG: Poison objects */
#define SLAB_HWCACHE_ALIGN 0x00002000UL /* Align objs on cache lines */
#define SLAB_CACHE_DMA 0x00004000UL /* Use GFP_DMA memory */
-#define SLAB_MUST_HWCACHE_ALIGN 0x00008000UL /* Force alignment even if debuggin is active */
#define SLAB_STORE_USER 0x00010000UL /* DEBUG: Store the last owner for bug hunting */
#define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */
#define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_create() fails */
#define SLAB_DESTROY_BY_RCU 0x00080000UL /* Defer freeing slabs to RCU */
#define SLAB_MEM_SPREAD 0x00100000UL /* Spread some memory over cpuset */
+#define SLAB_TRACE 0x00200000UL /* Trace allocations and frees */
/* Flags passed to a constructor functions */
#define SLAB_CTOR_CONSTRUCTOR 0x001UL /* If not set, then deconstructor */
-#define SLAB_CTOR_ATOMIC 0x002UL /* Tell constructor it can't sleep */
-#define SLAB_CTOR_VERIFY 0x004UL /* Tell constructor it's a verify call */
/*
* struct kmem_cache related prototypes
*/
void __init kmem_cache_init(void);
-extern int slab_is_available(void);
+int slab_is_available(void);
struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
unsigned long,
@@ -57,6 +54,18 @@ unsigned int kmem_cache_size(struct kmem_cache *);
const char *kmem_cache_name(struct kmem_cache *);
int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr);
+/*
+ * Please use this macro to create slab caches. Simply specify the
+ * name of the structure and maybe some flags that are listed above.
+ *
+ * The alignment of the struct determines object alignment. If you
+ * f.e. add ____cacheline_aligned_in_smp to the struct declaration
+ * then the objects will be properly aligned in SMP configurations.
+ */
+#define KMEM_CACHE(__struct, __flags) kmem_cache_create(#__struct,\
+ sizeof(struct __struct), __alignof__(struct __struct),\
+ (__flags), NULL, NULL)
+
#ifdef CONFIG_NUMA
extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
#else
@@ -72,8 +81,9 @@ static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
*/
void *__kmalloc(size_t, gfp_t);
void *__kzalloc(size_t, gfp_t);
+void * __must_check krealloc(const void *, size_t, gfp_t);
void kfree(const void *);
-unsigned int ksize(const void *);
+size_t ksize(const void *);
/**
* kcalloc - allocate memory for an array. The memory is set to zero.
@@ -94,9 +104,14 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
* the appropriate general cache at compile time.
*/
-#ifdef CONFIG_SLAB
+#if defined(CONFIG_SLAB) || defined(CONFIG_SLUB)
+#ifdef CONFIG_SLUB
+#include <linux/slub_def.h>
+#else
#include <linux/slab_def.h>
+#endif /* !CONFIG_SLUB */
#else
+
/*
* Fallback definitions for an allocator not wanting to provide
* its own optimized kmalloc definitions (like SLOB).
@@ -183,7 +198,7 @@ static inline void *__kmalloc_node(size_t size, gfp_t flags, int node)
* allocator where we care about the real place the memory allocation
* request comes from.
*/
-#ifdef CONFIG_DEBUG_SLAB
+#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB)
extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
#define kmalloc_track_caller(size, flags) \
__kmalloc_track_caller(size, flags, __builtin_return_address(0))
@@ -201,7 +216,7 @@ extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
* standard allocator where we care about the real place the memory
* allocation request comes from.
*/
-#ifdef CONFIG_DEBUG_SLAB
+#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB)
extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, void *);
#define kmalloc_node_track_caller(size, flags, node) \
__kmalloc_node_track_caller(size, flags, node, \
@@ -218,6 +233,9 @@ extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, void *);
#endif /* DEBUG_SLAB */
+extern const struct seq_operations slabinfo_op;
+ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *);
+
#endif /* __KERNEL__ */
#endif /* _LINUX_SLAB_H */
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
new file mode 100644
index 0000000..ea27065
--- /dev/null
+++ b/include/linux/slub_def.h
@@ -0,0 +1,206 @@
+#ifndef _LINUX_SLUB_DEF_H
+#define _LINUX_SLUB_DEF_H
+
+/*
+ * SLUB : A Slab allocator without object queues.
+ *
+ * (C) 2007 SGI, Christoph Lameter <clameter@sgi.com>
+ */
+#include <linux/types.h>
+#include <linux/gfp.h>
+#include <linux/workqueue.h>
+#include <linux/kobject.h>
+
+struct kmem_cache_node {
+ spinlock_t list_lock; /* Protect partial list and nr_partial */
+ unsigned long nr_partial;
+ atomic_long_t nr_slabs;
+ struct list_head partial;
+ struct list_head full;
+};
+
+/*
+ * Slab cache management.
+ */
+struct kmem_cache {
+ /* Used for retriving partial slabs etc */
+ unsigned long flags;
+ int size; /* The size of an object including meta data */
+ int objsize; /* The size of an object without meta data */
+ int offset; /* Free pointer offset. */
+ unsigned int order;
+
+ /*
+ * Avoid an extra cache line for UP, SMP and for the node local to
+ * struct kmem_cache.
+ */
+ struct kmem_cache_node local_node;
+
+ /* Allocation and freeing of slabs */
+ int objects; /* Number of objects in slab */
+ int refcount; /* Refcount for slab cache destroy */
+ void (*ctor)(void *, struct kmem_cache *, unsigned long);
+ void (*dtor)(void *, struct kmem_cache *, unsigned long);
+ int inuse; /* Offset to metadata */
+ int align; /* Alignment */
+ const char *name; /* Name (only for display!) */
+ struct list_head list; /* List of slab caches */
+ struct kobject kobj; /* For sysfs */
+
+#ifdef CONFIG_NUMA
+ int defrag_ratio;
+ struct kmem_cache_node *node[MAX_NUMNODES];
+#endif
+ struct page *cpu_slab[NR_CPUS];
+};
+
+/*
+ * Kmalloc subsystem.
+ */
+#define KMALLOC_SHIFT_LOW 3
+
+#ifdef CONFIG_LARGE_ALLOCS
+#define KMALLOC_SHIFT_HIGH 25
+#else
+#if !defined(CONFIG_MMU) || NR_CPUS > 512 || MAX_NUMNODES > 256
+#define KMALLOC_SHIFT_HIGH 20
+#else
+#define KMALLOC_SHIFT_HIGH 18
+#endif
+#endif
+
+/*
+ * We keep the general caches in an array of slab caches that are used for
+ * 2^x bytes of allocations.
+ */
+extern struct kmem_cache kmalloc_caches[KMALLOC_SHIFT_HIGH + 1];
+
+/*
+ * Sorry that the following has to be that ugly but some versions of GCC
+ * have trouble with constant propagation and loops.
+ */
+static inline int kmalloc_index(int size)
+{
+ /*
+ * We should return 0 if size == 0 but we use the smallest object
+ * here for SLAB legacy reasons.
+ */
+ WARN_ON_ONCE(size == 0);
+
+ if (size > 64 && size <= 96)
+ return 1;
+ if (size > 128 && size <= 192)
+ return 2;
+ if (size <= 8) return 3;
+ if (size <= 16) return 4;
+ if (size <= 32) return 5;
+ if (size <= 64) return 6;
+ if (size <= 128) return 7;
+ if (size <= 256) return 8;
+ if (size <= 512) return 9;
+ if (size <= 1024) return 10;
+ if (size <= 2 * 1024) return 11;
+ if (size <= 4 * 1024) return 12;
+ if (size <= 8 * 1024) return 13;
+ if (size <= 16 * 1024) return 14;
+ if (size <= 32 * 1024) return 15;
+ if (size <= 64 * 1024) return 16;
+ if (size <= 128 * 1024) return 17;
+ if (size <= 256 * 1024) return 18;
+#if KMALLOC_SHIFT_HIGH > 18
+ if (size <= 512 * 1024) return 19;
+ if (size <= 1024 * 1024) return 20;
+#endif
+#if KMALLOC_SHIFT_HIGH > 20
+ if (size <= 2 * 1024 * 1024) return 21;
+ if (size <= 4 * 1024 * 1024) return 22;
+ if (size <= 8 * 1024 * 1024) return 23;
+ if (size <= 16 * 1024 * 1024) return 24;
+ if (size <= 32 * 1024 * 1024) return 25;
+#endif
+ return -1;
+
+/*
+ * What we really wanted to do and cannot do because of compiler issues is:
+ * int i;
+ * for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++)
+ * if (size <= (1 << i))
+ * return i;
+ */
+}
+
+/*
+ * Find the slab cache for a given combination of allocation flags and size.
+ *
+ * This ought to end up with a global pointer to the right cache
+ * in kmalloc_caches.
+ */
+static inline struct kmem_cache *kmalloc_slab(size_t size)
+{
+ int index = kmalloc_index(size);
+
+ if (index == 0)
+ return NULL;
+
+ if (index < 0) {
+ /*
+ * Generate a link failure. Would be great if we could
+ * do something to stop the compile here.
+ */
+ extern void __kmalloc_size_too_large(void);
+ __kmalloc_size_too_large();
+ }
+ return &kmalloc_caches[index];
+}
+
+#ifdef CONFIG_ZONE_DMA
+#define SLUB_DMA __GFP_DMA
+#else
+/* Disable DMA functionality */
+#define SLUB_DMA 0
+#endif
+
+static inline void *kmalloc(size_t size, gfp_t flags)
+{
+ if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) {
+ struct kmem_cache *s = kmalloc_slab(size);
+
+ if (!s)
+ return NULL;
+
+ return kmem_cache_alloc(s, flags);
+ } else
+ return __kmalloc(size, flags);
+}
+
+static inline void *kzalloc(size_t size, gfp_t flags)
+{
+ if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) {
+ struct kmem_cache *s = kmalloc_slab(size);
+
+ if (!s)
+ return NULL;
+
+ return kmem_cache_zalloc(s, flags);
+ } else
+ return __kzalloc(size, flags);
+}
+
+#ifdef CONFIG_NUMA
+extern void *__kmalloc_node(size_t size, gfp_t flags, int node);
+
+static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
+{
+ if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) {
+ struct kmem_cache *s = kmalloc_slab(size);
+
+ if (!s)
+ return NULL;
+
+ return kmem_cache_alloc_node(s, flags, node);
+ } else
+ return __kmalloc_node(size, flags, node);
+}
+#endif
+
+#endif /* _LINUX_SLUB_DEF_H */
diff --git a/include/linux/spi/Kbuild b/include/linux/spi/Kbuild
new file mode 100644
index 0000000..d375a08
--- /dev/null
+++ b/include/linux/spi/Kbuild
@@ -0,0 +1 @@
+header-y += spidev.h
diff --git a/include/linux/spi/ad7877.h b/include/linux/spi/ad7877.h
new file mode 100644
index 0000000..cdbed81
--- /dev/null
+++ b/include/linux/spi/ad7877.h
@@ -0,0 +1,24 @@
+/* linux/spi/ad7877.h */
+
+/* Touchscreen characteristics vary between boards and models. The
+ * platform_data for the device's "struct device" holds this information.
+ *
+ * It's OK if the min/max values are zero.
+ */
+struct ad7877_platform_data {
+ u16 model; /* 7877 */
+ u16 vref_delay_usecs; /* 0 for external vref; etc */
+ u16 x_plate_ohms;
+ u16 y_plate_ohms;
+
+ u16 x_min, x_max;
+ u16 y_min, y_max;
+ u16 pressure_min, pressure_max;
+
+ u8 stopacq_polarity; /* 1 = Active HIGH, 0 = Active LOW */
+ u8 first_conversion_delay; /* 0 = 0.5us, 1 = 128us, 2 = 1ms, 3 = 8ms */
+ u8 acquisition_time; /* 0 = 2us, 1 = 4us, 2 = 8us, 3 = 16us */
+ u8 averaging; /* 0 = 1, 1 = 4, 2 = 8, 3 = 16 */
+ u8 pen_down_acc_interval; /* 0 = covert once, 1 = every 0.5 ms,
+ 2 = ever 1 ms, 3 = every 8 ms,*/
+};
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 4f0f8c2..b6bedc3 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -32,11 +32,12 @@ extern struct bus_type spi_bus_type;
* @max_speed_hz: Maximum clock rate to be used with this chip
* (on this board); may be changed by the device's driver.
* The spi_transfer.speed_hz can override this for each transfer.
- * @chip-select: Chipselect, distinguishing chips handled by "master".
+ * @chip_select: Chipselect, distinguishing chips handled by @master.
* @mode: The spi mode defines how data is clocked out and in.
* This may be changed by the device's driver.
- * The "active low" default for chipselect mode can be overridden,
- * as can the "MSB first" default for each word in a transfer.
+ * The "active low" default for chipselect mode can be overridden
+ * (by specifying SPI_CS_HIGH) as can the "MSB first" default for
+ * each word in a transfer (by specifying SPI_LSB_FIRST).
* @bits_per_word: Data transfers involve one or more words; word sizes
* like eight or 12 bits are common. In-memory wordsizes are
* powers of two bytes (e.g. 20 bit samples use 32 bits).
@@ -48,14 +49,18 @@ extern struct bus_type spi_bus_type;
* @controller_state: Controller's runtime state
* @controller_data: Board-specific definitions for controller, such as
* FIFO initialization parameters; from board_info.controller_data
+ * @modalias: Name of the driver to use with this device, or an alias
+ * for that name. This appears in the sysfs "modalias" attribute
+ * for driver coldplugging, and in uevents used for hotplugging
*
- * An spi_device is used to interchange data between an SPI slave
+ * A @spi_device is used to interchange data between an SPI slave
* (usually a discrete chip) and CPU memory.
*
- * In "dev", the platform_data is used to hold information about this
+ * In @dev, the platform_data is used to hold information about this
* device that's meaningful to the device's protocol driver, but not
* to its controller. One example might be an identifier for a chip
- * variant with slightly different functionality.
+ * variant with slightly different functionality; another might be
+ * information about how this particular board wires the chip's pins.
*/
struct spi_device {
struct device dev;
@@ -77,13 +82,15 @@ struct spi_device {
void *controller_data;
const char *modalias;
- // likely need more hooks for more protocol options affecting how
- // the controller talks to each chip, like:
- // - memory packing (12 bit samples into low bits, others zeroed)
- // - priority
- // - drop chipselect after each word
- // - chipselect delays
- // - ...
+ /*
+ * likely need more hooks for more protocol options affecting how
+ * the controller talks to each chip, like:
+ * - memory packing (12 bit samples into low bits, others zeroed)
+ * - priority
+ * - drop chipselect after each word
+ * - chipselect delays
+ * - ...
+ */
};
static inline struct spi_device *to_spi_device(struct device *dev)
@@ -146,6 +153,11 @@ static inline struct spi_driver *to_spi_driver(struct device_driver *drv)
extern int spi_register_driver(struct spi_driver *sdrv);
+/**
+ * spi_unregister_driver - reverse effect of spi_register_driver
+ * @sdrv: the driver to unregister
+ * Context: can sleep
+ */
static inline void spi_unregister_driver(struct spi_driver *sdrv)
{
if (sdrv)
@@ -165,18 +177,20 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
* @setup: updates the device mode and clocking records used by a
* device's SPI controller; protocol code may call this. This
* must fail if an unrecognized or unsupported mode is requested.
+ * It's always safe to call this unless transfers are pending on
+ * the device whose settings are being modified.
* @transfer: adds a message to the controller's transfer queue.
* @cleanup: frees controller-specific state
*
- * Each SPI master controller can communicate with one or more spi_device
+ * Each SPI master controller can communicate with one or more @spi_device
* children. These make a small bus, sharing MOSI, MISO and SCK signals
* but not chip select signals. Each device may be configured to use a
* different clock rate, since those shared signals are ignored unless
* the chip is selected.
*
* The driver for an SPI controller manages access to those devices through
- * a queue of spi_message transactions, copyin data between CPU memory and
- * an SPI slave device). For each such message it queues, it calls the
+ * a queue of spi_message transactions, copying data between CPU memory and
+ * an SPI slave device. For each such message it queues, it calls the
* message's completion function when the transaction completes.
*/
struct spi_master {
@@ -280,27 +294,27 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum);
* struct spi_transfer - a read/write buffer pair
* @tx_buf: data to be written (dma-safe memory), or NULL
* @rx_buf: data to be read (dma-safe memory), or NULL
- * @tx_dma: DMA address of tx_buf, if spi_message.is_dma_mapped
- * @rx_dma: DMA address of rx_buf, if spi_message.is_dma_mapped
+ * @tx_dma: DMA address of tx_buf, if @spi_message.is_dma_mapped
+ * @rx_dma: DMA address of rx_buf, if @spi_message.is_dma_mapped
* @len: size of rx and tx buffers (in bytes)
* @speed_hz: Select a speed other then the device default for this
- * transfer. If 0 the default (from spi_device) is used.
+ * transfer. If 0 the default (from @spi_device) is used.
* @bits_per_word: select a bits_per_word other then the device default
- * for this transfer. If 0 the default (from spi_device) is used.
+ * for this transfer. If 0 the default (from @spi_device) is used.
* @cs_change: affects chipselect after this transfer completes
* @delay_usecs: microseconds to delay after this transfer before
* (optionally) changing the chipselect status, then starting
- * the next transfer or completing this spi_message.
- * @transfer_list: transfers are sequenced through spi_message.transfers
+ * the next transfer or completing this @spi_message.
+ * @transfer_list: transfers are sequenced through @spi_message.transfers
*
* SPI transfers always write the same number of bytes as they read.
- * Protocol drivers should always provide rx_buf and/or tx_buf.
+ * Protocol drivers should always provide @rx_buf and/or @tx_buf.
* In some cases, they may also want to provide DMA addresses for
* the data being transferred; that may reduce overhead, when the
* underlying driver uses dma.
*
* If the transmit buffer is null, zeroes will be shifted out
- * while filling rx_buf. If the receive buffer is null, the data
+ * while filling @rx_buf. If the receive buffer is null, the data
* shifted in will be discarded. Only "len" bytes shift out (or in).
* It's an error to try to shift out a partial word. (For example, by
* shifting out three bytes with word size of sixteen or twenty bits;
@@ -309,7 +323,7 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum);
* In-memory data values are always in native CPU byte order, translated
* from the wire byte order (big-endian except with SPI_LSB_FIRST). So
* for example when bits_per_word is sixteen, buffers are 2N bytes long
- * and hold N sixteen bit words in CPU byte order.
+ * (@len = 2N) and hold N sixteen bit words in CPU byte order.
*
* When the word size of the SPI transfer is not a power-of-two multiple
* of eight bits, those in-memory words include extra bits. In-memory
@@ -318,7 +332,7 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum);
*
* All SPI transfers start with the relevant chipselect active. Normally
* it stays selected until after the last transfer in a message. Drivers
- * can affect the chipselect signal using cs_change:
+ * can affect the chipselect signal using cs_change.
*
* (i) If the transfer isn't the last one in the message, this flag is
* used to make the chipselect briefly go inactive in the middle of the
@@ -372,7 +386,7 @@ struct spi_transfer {
* @queue: for use by whichever driver currently owns the message
* @state: for use by whichever driver currently owns the message
*
- * An spi_message is used to execute an atomic sequence of data transfers,
+ * A @spi_message is used to execute an atomic sequence of data transfers,
* each represented by a struct spi_transfer. The sequence is "atomic"
* in the sense that no other spi_message may use that SPI bus until that
* sequence completes. On some systems, many such sequences can execute as
@@ -464,8 +478,9 @@ static inline void spi_message_free(struct spi_message *m)
}
/**
- * spi_setup -- setup SPI mode and clock rate
+ * spi_setup - setup SPI mode and clock rate
* @spi: the device whose settings are being modified
+ * Context: can sleep
*
* SPI protocol drivers may need to update the transfer mode if the
* device doesn't work with the mode 0 default. They may likewise need
@@ -474,7 +489,7 @@ static inline void spi_message_free(struct spi_message *m)
* The changes take effect the next time the device is selected and data
* is transferred to or from it.
*
- * Note that this call wil fail if the protocol driver specifies an option
+ * Note that this call will fail if the protocol driver specifies an option
* that the underlying controller or its driver does not support. For
* example, not all hardware supports wire transfers using nine bit words,
* LSB-first wire encoding, or active-high chipselects.
@@ -487,9 +502,10 @@ spi_setup(struct spi_device *spi)
/**
- * spi_async -- asynchronous SPI transfer
+ * spi_async - asynchronous SPI transfer
* @spi: device with which data will be exchanged
* @message: describes the data transfers, including completion callback
+ * Context: any (irqs may be blocked, etc)
*
* This call may be used in_irq and other contexts which can't sleep,
* as well as from task contexts which can sleep.
@@ -535,6 +551,7 @@ extern int spi_sync(struct spi_device *spi, struct spi_message *message);
* @spi: device to which data will be written
* @buf: data buffer
* @len: data buffer size
+ * Context: can sleep
*
* This writes the buffer and returns zero or a negative error code.
* Callable only from contexts that can sleep.
@@ -558,8 +575,9 @@ spi_write(struct spi_device *spi, const u8 *buf, size_t len)
* @spi: device from which data will be read
* @buf: data buffer
* @len: data buffer size
+ * Context: can sleep
*
- * This writes the buffer and returns zero or a negative error code.
+ * This reads the buffer and returns zero or a negative error code.
* Callable only from contexts that can sleep.
*/
static inline int
@@ -585,6 +603,7 @@ extern int spi_write_then_read(struct spi_device *spi,
* spi_w8r8 - SPI synchronous 8 bit write followed by 8 bit read
* @spi: device with which data will be exchanged
* @cmd: command to be written before data is read back
+ * Context: can sleep
*
* This returns the (unsigned) eight bit number returned by the
* device, or else a negative error code. Callable only from
@@ -605,6 +624,7 @@ static inline ssize_t spi_w8r8(struct spi_device *spi, u8 cmd)
* spi_w8r16 - SPI synchronous 8 bit write followed by 16 bit read
* @spi: device with which data will be exchanged
* @cmd: command to be written before data is read back
+ * Context: can sleep
*
* This returns the (unsigned) sixteen bit number returned by the
* device, or else a negative error code. Callable only from
diff --git a/include/linux/spi/spidev.h b/include/linux/spi/spidev.h
new file mode 100644
index 0000000..7d700be
--- /dev/null
+++ b/include/linux/spi/spidev.h
@@ -0,0 +1,124 @@
+/*
+ * include/linux/spi/spidev.h
+ *
+ * Copyright (C) 2006 SWAPP
+ * Andrea Paterniani <a.paterniani@swapp-eng.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef SPIDEV_H
+#define SPIDEV_H
+
+
+/* User space versions of kernel symbols for SPI clocking modes,
+ * matching <linux/spi/spi.h>
+ */
+
+#define SPI_CPHA 0x01
+#define SPI_CPOL 0x02
+
+#define SPI_MODE_0 (0|0)
+#define SPI_MODE_1 (0|SPI_CPHA)
+#define SPI_MODE_2 (SPI_CPOL|0)
+#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)
+
+
+/*---------------------------------------------------------------------------*/
+
+/* IOCTL commands */
+
+#define SPI_IOC_MAGIC 'k'
+
+/**
+ * struct spi_ioc_transfer - describes a single SPI transfer
+ * @tx_buf: Holds pointer to userspace buffer with transmit data, or null.
+ * If no data is provided, zeroes are shifted out.
+ * @rx_buf: Holds pointer to userspace buffer for receive data, or null.
+ * @len: Length of tx and rx buffers, in bytes.
+ * @speed_hz: Temporary override of the device's bitrate.
+ * @bits_per_word: Temporary override of the device's wordsize.
+ * @delay_usecs: If nonzero, how long to delay after the last bit transfer
+ * before optionally deselecting the device before the next transfer.
+ * @cs_change: True to deselect device before starting the next transfer.
+ *
+ * This structure is mapped directly to the kernel spi_transfer structure;
+ * the fields have the same meanings, except of course that the pointers
+ * are in a different address space (and may be of different sizes in some
+ * cases, such as 32-bit i386 userspace over a 64-bit x86_64 kernel).
+ * Zero-initialize the structure, including currently unused fields, to
+ * accomodate potential future updates.
+ *
+ * SPI_IOC_MESSAGE gives userspace the equivalent of kernel spi_sync().
+ * Pass it an array of related transfers, they'll execute together.
+ * Each transfer may be half duplex (either direction) or full duplex.
+ *
+ * struct spi_ioc_transfer mesg[4];
+ * ...
+ * status = ioctl(fd, SPI_IOC_MESSAGE(4), mesg);
+ *
+ * So for example one transfer might send a nine bit command (right aligned
+ * in a 16-bit word), the next could read a block of 8-bit data before
+ * terminating that command by temporarily deselecting the chip; the next
+ * could send a different nine bit command (re-selecting the chip), and the
+ * last transfer might write some register values.
+ */
+struct spi_ioc_transfer {
+ __u64 tx_buf;
+ __u64 rx_buf;
+
+ __u32 len;
+ __u32 speed_hz;
+
+ __u16 delay_usecs;
+ __u8 bits_per_word;
+ __u8 cs_change;
+ __u32 pad;
+
+ /* If the contents of 'struct spi_ioc_transfer' ever change
+ * incompatibly, then the ioctl number (currently 0) must change;
+ * ioctls with constant size fields get a bit more in the way of
+ * error checking than ones (like this) where that field varies.
+ *
+ * NOTE: struct layout is the same in 64bit and 32bit userspace.
+ */
+};
+
+/* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */
+#define SPI_MSGSIZE(N) \
+ ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \
+ ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0)
+#define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
+
+
+/* Read / Write of SPI mode (SPI_MODE_0..SPI_MODE_3) */
+#define SPI_IOC_RD_MODE _IOR(SPI_IOC_MAGIC, 1, __u8)
+#define SPI_IOC_WR_MODE _IOW(SPI_IOC_MAGIC, 1, __u8)
+
+/* Read / Write SPI bit justification */
+#define SPI_IOC_RD_LSB_FIRST _IOR(SPI_IOC_MAGIC, 2, __u8)
+#define SPI_IOC_WR_LSB_FIRST _IOW(SPI_IOC_MAGIC, 2, __u8)
+
+/* Read / Write SPI device word length (1..N) */
+#define SPI_IOC_RD_BITS_PER_WORD _IOR(SPI_IOC_MAGIC, 3, __u8)
+#define SPI_IOC_WR_BITS_PER_WORD _IOW(SPI_IOC_MAGIC, 3, __u8)
+
+/* Read / Write SPI device default max speed hz */
+#define SPI_IOC_RD_MAX_SPEED_HZ _IOR(SPI_IOC_MAGIC, 4, __u32)
+#define SPI_IOC_WR_MAX_SPEED_HZ _IOW(SPI_IOC_MAGIC, 4, __u32)
+
+
+
+#endif /* SPIDEV_H */
diff --git a/include/linux/spinlock_types.h b/include/linux/spinlock_types.h
index dc5fb69..210549b 100644
--- a/include/linux/spinlock_types.h
+++ b/include/linux/spinlock_types.h
@@ -85,6 +85,12 @@ typedef struct {
RW_DEP_MAP_INIT(lockname) }
#endif
+/*
+ * SPIN_LOCK_UNLOCKED and RW_LOCK_UNLOCKED defeat lockdep state tracking and
+ * are hence deprecated.
+ * Please use DEFINE_SPINLOCK()/DEFINE_RWLOCK() or
+ * __SPIN_LOCK_UNLOCKED()/__RW_LOCK_UNLOCKED() as appropriate.
+ */
#define SPIN_LOCK_UNLOCKED __SPIN_LOCK_UNLOCKED(old_style_spin_init)
#define RW_LOCK_UNLOCKED __RW_LOCK_UNLOCKED(old_style_rw_init)
diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h
index 50e2b01..1d2b084 100644
--- a/include/linux/stacktrace.h
+++ b/include/linux/stacktrace.h
@@ -6,15 +6,13 @@ struct stack_trace {
unsigned int nr_entries, max_entries;
unsigned long *entries;
int skip; /* input argument: How many entries to skip */
- int all_contexts; /* input argument: if true do than one stack */
};
-extern void save_stack_trace(struct stack_trace *trace,
- struct task_struct *task);
+extern void save_stack_trace(struct stack_trace *trace);
extern void print_stack_trace(struct stack_trace *trace, int spaces);
#else
-# define save_stack_trace(trace, task) do { } while (0)
+# define save_stack_trace(trace) do { } while (0)
# define print_stack_trace(trace) do { } while (0)
#endif
diff --git a/include/linux/stat.h b/include/linux/stat.h
index 679ef0d..611c398 100644
--- a/include/linux/stat.h
+++ b/include/linux/stat.h
@@ -53,6 +53,9 @@
#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
+#define UTIME_NOW ((1l << 30) - 1l)
+#define UTIME_OMIT ((1l << 30) - 2l)
+
#include <linux/types.h>
#include <linux/time.h>
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index bf99bd4..9d2aa1a 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -1,13 +1,14 @@
#ifndef _LINUX_SWSUSP_H
#define _LINUX_SWSUSP_H
-#if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32)
+#if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
#include <asm/suspend.h>
#endif
#include <linux/swap.h>
#include <linux/notifier.h>
#include <linux/init.h>
#include <linux/pm.h>
+#include <linux/mm.h>
/* struct pbe is used for creating lists of pages that should be restored
* atomically during the resume from disk, because the page frames they have
@@ -23,36 +24,32 @@ struct pbe {
extern void drain_local_pages(void);
extern void mark_free_pages(struct zone *zone);
-#ifdef CONFIG_PM
-/* kernel/power/swsusp.c */
-extern int software_suspend(void);
-
-#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
+#if defined(CONFIG_PM) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
extern int pm_prepare_console(void);
extern void pm_restore_console(void);
#else
static inline int pm_prepare_console(void) { return 0; }
static inline void pm_restore_console(void) {}
-#endif /* defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) */
+#endif
+
+#if defined(CONFIG_PM) && defined(CONFIG_SOFTWARE_SUSPEND)
+/* kernel/power/snapshot.c */
+extern void __init register_nosave_region(unsigned long, unsigned long);
+extern int swsusp_page_is_forbidden(struct page *);
+extern void swsusp_set_page_free(struct page *);
+extern void swsusp_unset_page_free(struct page *);
+extern unsigned long get_safe_page(gfp_t gfp_mask);
#else
-static inline int software_suspend(void)
-{
- printk("Warning: fake suspend called\n");
- return -ENOSYS;
-}
-#endif /* CONFIG_PM */
+static inline void register_nosave_region(unsigned long b, unsigned long e) {}
+static inline int swsusp_page_is_forbidden(struct page *p) { return 0; }
+static inline void swsusp_set_page_free(struct page *p) {}
+static inline void swsusp_unset_page_free(struct page *p) {}
+#endif /* defined(CONFIG_PM) && defined(CONFIG_SOFTWARE_SUSPEND) */
void save_processor_state(void);
void restore_processor_state(void);
struct saved_context;
void __save_processor_state(struct saved_context *ctxt);
void __restore_processor_state(struct saved_context *ctxt);
-unsigned long get_safe_page(gfp_t gfp_mask);
-
-/*
- * XXX: We try to keep some more pages free so that I/O operations succeed
- * without paging. Might this be more?
- */
-#define PAGES_FOR_IO 1024
#endif /* _LINUX_SWSUSP_H */
diff --git a/include/linux/svga.h b/include/linux/svga.h
index eadb981..e1cc552 100644
--- a/include/linux/svga.h
+++ b/include/linux/svga.h
@@ -112,6 +112,7 @@ void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area);
void svga_tilefill(struct fb_info *info, struct fb_tilerect *rect);
void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit);
void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor);
+int svga_get_tilemax(struct fb_info *info);
int svga_compute_pll(const struct svga_pll *pll, u32 f_wanted, u16 *m, u16 *n, u16 *r, int node);
int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, int node);
diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h
index 389ccf8..e699ab2 100644
--- a/include/linux/sysdev.h
+++ b/include/linux/sysdev.h
@@ -22,6 +22,7 @@
#define _SYSDEV_H_
#include <linux/kobject.h>
+#include <linux/module.h>
#include <linux/pm.h>
diff --git a/include/linux/tifm.h b/include/linux/tifm.h
index 2a19698..6b3a318 100644
--- a/include/linux/tifm.h
+++ b/include/linux/tifm.h
@@ -63,6 +63,7 @@ enum {
#define TIFM_CTRL_LED 0x00000040
#define TIFM_CTRL_FAST_CLK 0x00000100
+#define TIFM_CTRL_POWER_MASK 0x00000007
#define TIFM_SOCK_STATE_OCCUPIED 0x00000008
#define TIFM_SOCK_STATE_POWERED 0x00000080
diff --git a/include/linux/time.h b/include/linux/time.h
index 8ea8dea..dda9be6 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -109,7 +109,7 @@ extern void do_gettimeofday(struct timeval *tv);
extern int do_settimeofday(struct timespec *tv);
extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz);
#define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts)
-extern long do_utimes(int dfd, char __user *filename, struct timeval *times);
+extern long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags);
struct itimerval;
extern int do_setitimer(int which, struct itimerval *value,
struct itimerval *ovalue);
@@ -119,6 +119,7 @@ extern void getnstimeofday(struct timespec *tv);
extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
extern int timekeeping_is_continuous(void);
+extern void update_wall_time(void);
/**
* timespec_to_ns - Convert timespec to nanoseconds
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 719113b..e0c5c16 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -37,6 +37,7 @@ extern struct tvec_t_base_s boot_tvec_bases;
TIMER_INITIALIZER(_function, _expires, _data)
void fastcall init_timer(struct timer_list * timer);
+void fastcall init_timer_deferrable(struct timer_list *timer);
static inline void setup_timer(struct timer_list * timer,
void (*function)(unsigned long),
diff --git a/include/linux/tty.h b/include/linux/tty.h
index dee72b9..bb45760 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -313,6 +313,7 @@ extern int tty_hung_up_p(struct file * filp);
extern void do_SAK(struct tty_struct *tty);
extern void __do_SAK(struct tty_struct *tty);
extern void disassociate_ctty(int priv);
+extern void no_tty(void);
extern void tty_flip_buffer_push(struct tty_struct *tty);
extern speed_t tty_get_baud_rate(struct tty_struct *tty);
extern speed_t tty_termios_baud_rate(struct ktermios *termios);
@@ -333,7 +334,6 @@ extern int tty_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
extern dev_t tty_devnum(struct tty_struct *tty);
extern void proc_clear_tty(struct task_struct *p);
-extern void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
extern struct tty_struct *get_current_tty(void);
extern struct mutex tty_mutex;
diff --git a/include/linux/uinput.h b/include/linux/uinput.h
index 1fd61ee..a6c1e8e 100644
--- a/include/linux/uinput.h
+++ b/include/linux/uinput.h
@@ -32,6 +32,8 @@
* - first public version
*/
+#include <linux/input.h>
+
#define UINPUT_VERSION 3
#ifdef __KERNEL__
diff --git a/include/linux/usb_sl811.h b/include/linux/usb_sl811.h
new file mode 100644
index 0000000..4f2d012
--- /dev/null
+++ b/include/linux/usb_sl811.h
@@ -0,0 +1,26 @@
+
+/*
+ * board initialization should put one of these into dev->platform_data
+ * and place the sl811hs onto platform_bus named "sl811-hcd".
+ */
+
+struct sl811_platform_data {
+ unsigned can_wakeup:1;
+
+ /* given port_power, msec/2 after power on till power good */
+ u8 potpg;
+
+ /* mA/2 power supplied on this port (max = default = 250) */
+ u8 power;
+
+ /* sl811 relies on an external source of VBUS current */
+ void (*port_power)(struct device *dev, int is_on);
+
+ /* pulse sl811 nRST (probably with a GPIO) */
+ void (*reset)(struct device *dev);
+
+ // some boards need something like these:
+ // int (*check_overcurrent)(struct device *dev);
+ // void (*clock_enable)(struct device *dev, int is_on);
+};
+
diff --git a/include/linux/utsname.h b/include/linux/utsname.h
index e10267d..f8d3b32 100644
--- a/include/linux/utsname.h
+++ b/include/linux/utsname.h
@@ -49,9 +49,7 @@ static inline void get_uts_ns(struct uts_namespace *ns)
}
#ifdef CONFIG_UTS_NS
-extern int unshare_utsname(unsigned long unshare_flags,
- struct uts_namespace **new_uts);
-extern int copy_utsname(int flags, struct task_struct *tsk);
+extern struct uts_namespace *copy_utsname(int flags, struct uts_namespace *ns);
extern void free_uts_ns(struct kref *kref);
static inline void put_uts_ns(struct uts_namespace *ns)
@@ -59,21 +57,12 @@ static inline void put_uts_ns(struct uts_namespace *ns)
kref_put(&ns->kref, free_uts_ns);
}
#else
-static inline int unshare_utsname(unsigned long unshare_flags,
- struct uts_namespace **new_uts)
+static inline struct uts_namespace *copy_utsname(int flags,
+ struct uts_namespace *ns)
{
- if (unshare_flags & CLONE_NEWUTS)
- return -EINVAL;
-
- return 0;
+ return ns;
}
-static inline int copy_utsname(int flags, struct task_struct *tsk)
-{
- if (flags & CLONE_NEWUTS)
- return -EINVAL;
- return 0;
-}
static inline void put_uts_ns(struct uts_namespace *ns)
{
}
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 924e502..4b7ee83 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -53,6 +53,7 @@ extern void vunmap(void *addr);
extern int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
unsigned long pgoff);
+void vmalloc_sync_all(void);
/*
* Lowlevel-APIs (not for driver use!)
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index e0db669..d961635 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -9,6 +9,7 @@
#include <linux/vt.h>
#include <linux/kd.h>
#include <linux/tty.h>
+#include <linux/mutex.h>
#include <linux/console_struct.h>
#include <linux/mm.h>
@@ -82,7 +83,7 @@ void reset_vc(struct vc_data *vc);
#define CON_BUF_SIZE (CONFIG_BASE_SMALL ? 256 : PAGE_SIZE)
extern char con_buf[CON_BUF_SIZE];
-extern struct semaphore con_buf_sem;
+extern struct mutex con_buf_mtx;
extern char vt_dont_switch;
struct vt_spawn_console {
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index b8abfc7..f16ba1e 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -121,6 +121,12 @@ struct execute_work {
init_timer(&(_work)->timer); \
} while (0)
+#define INIT_DELAYED_WORK_DEFERRABLE(_work, _func) \
+ do { \
+ INIT_WORK(&(_work)->work, (_func)); \
+ init_timer_deferrable(&(_work)->timer); \
+ } while (0)
+
/**
* work_pending - Find out whether a work item is currently pending
* @work: The work item in question
diff --git a/include/math-emu/extended.h b/include/math-emu/extended.h
deleted file mode 100644
index 84770fc..0000000
--- a/include/math-emu/extended.h
+++ /dev/null
@@ -1,396 +0,0 @@
-/* Software floating-point emulation.
- Definitions for IEEE Extended Precision.
- Copyright (C) 1999 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Jakub Jelinek (jj@ultra.linux.cz).
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, write to the Free Software Foundation, Inc.,
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-
-#ifndef __MATH_EMU_EXTENDED_H__
-#define __MATH_EMU_EXTENDED_H__
-
-#if _FP_W_TYPE_SIZE < 32
-#error "Here's a nickel, kid. Go buy yourself a real computer."
-#endif
-
-#if _FP_W_TYPE_SIZE < 64
-#define _FP_FRACTBITS_E (4*_FP_W_TYPE_SIZE)
-#else
-#define _FP_FRACTBITS_E (2*_FP_W_TYPE_SIZE)
-#endif
-
-#define _FP_FRACBITS_E 64
-#define _FP_FRACXBITS_E (_FP_FRACTBITS_E - _FP_FRACBITS_E)
-#define _FP_WFRACBITS_E (_FP_WORKBITS + _FP_FRACBITS_E)
-#define _FP_WFRACXBITS_E (_FP_FRACTBITS_E - _FP_WFRACBITS_E)
-#define _FP_EXPBITS_E 15
-#define _FP_EXPBIAS_E 16383
-#define _FP_EXPMAX_E 32767
-
-#define _FP_QNANBIT_E \
- ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE)
-#define _FP_IMPLBIT_E \
- ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE)
-#define _FP_OVERFLOW_E \
- ((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE))
-
-#if _FP_W_TYPE_SIZE < 64
-
-union _FP_UNION_E
-{
- long double flt;
- struct
- {
-#if __BYTE_ORDER == __BIG_ENDIAN
- unsigned long pad1 : _FP_W_TYPE_SIZE;
- unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
- unsigned long sign : 1;
- unsigned long exp : _FP_EXPBITS_E;
- unsigned long frac1 : _FP_W_TYPE_SIZE;
- unsigned long frac0 : _FP_W_TYPE_SIZE;
-#else
- unsigned long frac0 : _FP_W_TYPE_SIZE;
- unsigned long frac1 : _FP_W_TYPE_SIZE;
- unsigned exp : _FP_EXPBITS_E;
- unsigned sign : 1;
-#endif /* not bigendian */
- } bits __attribute__((packed));
-};
-
-
-#define FP_DECL_E(X) _FP_DECL(4,X)
-
-#define FP_UNPACK_RAW_E(X, val) \
- do { \
- union _FP_UNION_E _flo; _flo.flt = (val); \
- \
- X##_f[2] = 0; X##_f[3] = 0; \
- X##_f[0] = _flo.bits.frac0; \
- X##_f[1] = _flo.bits.frac1; \
- X##_e = _flo.bits.exp; \
- X##_s = _flo.bits.sign; \
- if (!X##_e && (X##_f[1] || X##_f[0]) \
- && !(X##_f[1] & _FP_IMPLBIT_E)) \
- { \
- X##_e++; \
- FP_SET_EXCEPTION(FP_EX_DENORM); \
- } \
- } while (0)
-
-#define FP_UNPACK_RAW_EP(X, val) \
- do { \
- union _FP_UNION_E *_flo = \
- (union _FP_UNION_E *)(val); \
- \
- X##_f[2] = 0; X##_f[3] = 0; \
- X##_f[0] = _flo->bits.frac0; \
- X##_f[1] = _flo->bits.frac1; \
- X##_e = _flo->bits.exp; \
- X##_s = _flo->bits.sign; \
- if (!X##_e && (X##_f[1] || X##_f[0]) \
- && !(X##_f[1] & _FP_IMPLBIT_E)) \
- { \
- X##_e++; \
- FP_SET_EXCEPTION(FP_EX_DENORM); \
- } \
- } while (0)
-
-#define FP_PACK_RAW_E(val, X) \
- do { \
- union _FP_UNION_E _flo; \
- \
- if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \
- else X##_f[1] &= ~(_FP_IMPLBIT_E); \
- _flo.bits.frac0 = X##_f[0]; \
- _flo.bits.frac1 = X##_f[1]; \
- _flo.bits.exp = X##_e; \
- _flo.bits.sign = X##_s; \
- \
- (val) = _flo.flt; \
- } while (0)
-
-#define FP_PACK_RAW_EP(val, X) \
- do { \
- if (!FP_INHIBIT_RESULTS) \
- { \
- union _FP_UNION_E *_flo = \
- (union _FP_UNION_E *)(val); \
- \
- if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \
- else X##_f[1] &= ~(_FP_IMPLBIT_E); \
- _flo->bits.frac0 = X##_f[0]; \
- _flo->bits.frac1 = X##_f[1]; \
- _flo->bits.exp = X##_e; \
- _flo->bits.sign = X##_s; \
- } \
- } while (0)
-
-#define FP_UNPACK_E(X,val) \
- do { \
- FP_UNPACK_RAW_E(X,val); \
- _FP_UNPACK_CANONICAL(E,4,X); \
- } while (0)
-
-#define FP_UNPACK_EP(X,val) \
- do { \
- FP_UNPACK_RAW_2_P(X,val); \
- _FP_UNPACK_CANONICAL(E,4,X); \
- } while (0)
-
-#define FP_PACK_E(val,X) \
- do { \
- _FP_PACK_CANONICAL(E,4,X); \
- FP_PACK_RAW_E(val,X); \
- } while (0)
-
-#define FP_PACK_EP(val,X) \
- do { \
- _FP_PACK_CANONICAL(E,4,X); \
- FP_PACK_RAW_EP(val,X); \
- } while (0)
-
-#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,4,X)
-#define FP_NEG_E(R,X) _FP_NEG(E,4,R,X)
-#define FP_ADD_E(R,X,Y) _FP_ADD(E,4,R,X,Y)
-#define FP_SUB_E(R,X,Y) _FP_SUB(E,4,R,X,Y)
-#define FP_MUL_E(R,X,Y) _FP_MUL(E,4,R,X,Y)
-#define FP_DIV_E(R,X,Y) _FP_DIV(E,4,R,X,Y)
-#define FP_SQRT_E(R,X) _FP_SQRT(E,4,R,X)
-
-/*
- * Square root algorithms:
- * We have just one right now, maybe Newton approximation
- * should be added for those machines where division is fast.
- * This has special _E version because standard _4 square
- * root would not work (it has to start normally with the
- * second word and not the first), but as we have to do it
- * anyway, we optimize it by doing most of the calculations
- * in two UWtype registers instead of four.
- */
-
-#define _FP_SQRT_MEAT_E(R, S, T, X, q) \
- do { \
- q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
- _FP_FRAC_SRL_4(X, (_FP_WORKBITS)); \
- while (q) \
- { \
- T##_f[1] = S##_f[1] + q; \
- if (T##_f[1] <= X##_f[1]) \
- { \
- S##_f[1] = T##_f[1] + q; \
- X##_f[1] -= T##_f[1]; \
- R##_f[1] += q; \
- } \
- _FP_FRAC_SLL_2(X, 1); \
- q >>= 1; \
- } \
- q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
- while (q) \
- { \
- T##_f[0] = S##_f[0] + q; \
- T##_f[1] = S##_f[1]; \
- if (T##_f[1] < X##_f[1] || \
- (T##_f[1] == X##_f[1] && \
- T##_f[0] <= X##_f[0])) \
- { \
- S##_f[0] = T##_f[0] + q; \
- S##_f[1] += (T##_f[0] > S##_f[0]); \
- _FP_FRAC_DEC_2(X, T); \
- R##_f[0] += q; \
- } \
- _FP_FRAC_SLL_2(X, 1); \
- q >>= 1; \
- } \
- _FP_FRAC_SLL_4(R, (_FP_WORKBITS)); \
- if (X##_f[0] | X##_f[1]) \
- { \
- if (S##_f[1] < X##_f[1] || \
- (S##_f[1] == X##_f[1] && \
- S##_f[0] < X##_f[0])) \
- R##_f[0] |= _FP_WORK_ROUND; \
- R##_f[0] |= _FP_WORK_STICKY; \
- } \
- } while (0)
-
-#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,4,r,X,Y,un)
-#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,4,r,X,Y)
-
-#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,4,r,X,rsz,rsg)
-#define FP_TO_INT_ROUND_E(r,X,rsz,rsg) _FP_TO_INT_ROUND(E,4,r,X,rsz,rsg)
-#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,4,X,r,rs,rt)
-
-#define _FP_FRAC_HIGH_E(X) (X##_f[2])
-#define _FP_FRAC_HIGH_RAW_E(X) (X##_f[1])
-
-#else /* not _FP_W_TYPE_SIZE < 64 */
-union _FP_UNION_E
-{
- long double flt /* __attribute__((mode(TF))) */ ;
- struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
- unsigned long pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
- unsigned sign : 1;
- unsigned exp : _FP_EXPBITS_E;
- unsigned long frac : _FP_W_TYPE_SIZE;
-#else
- unsigned long frac : _FP_W_TYPE_SIZE;
- unsigned exp : _FP_EXPBITS_E;
- unsigned sign : 1;
-#endif
- } bits;
-};
-
-#define FP_DECL_E(X) _FP_DECL(2,X)
-
-#define FP_UNPACK_RAW_E(X, val) \
- do { \
- union _FP_UNION_E _flo; _flo.flt = (val); \
- \
- X##_f0 = _flo.bits.frac; \
- X##_f1 = 0; \
- X##_e = _flo.bits.exp; \
- X##_s = _flo.bits.sign; \
- if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E)) \
- { \
- X##_e++; \
- FP_SET_EXCEPTION(FP_EX_DENORM); \
- } \
- } while (0)
-
-#define FP_UNPACK_RAW_EP(X, val) \
- do { \
- union _FP_UNION_E *_flo = \
- (union _FP_UNION_E *)(val); \
- \
- X##_f0 = _flo->bits.frac; \
- X##_f1 = 0; \
- X##_e = _flo->bits.exp; \
- X##_s = _flo->bits.sign; \
- if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E)) \
- { \
- X##_e++; \
- FP_SET_EXCEPTION(FP_EX_DENORM); \
- } \
- } while (0)
-
-#define FP_PACK_RAW_E(val, X) \
- do { \
- union _FP_UNION_E _flo; \
- \
- if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \
- else X##_f0 &= ~(_FP_IMPLBIT_E); \
- _flo.bits.frac = X##_f0; \
- _flo.bits.exp = X##_e; \
- _flo.bits.sign = X##_s; \
- \
- (val) = _flo.flt; \
- } while (0)
-
-#define FP_PACK_RAW_EP(fs, val, X) \
- do { \
- if (!FP_INHIBIT_RESULTS) \
- { \
- union _FP_UNION_E *_flo = \
- (union _FP_UNION_E *)(val); \
- \
- if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \
- else X##_f0 &= ~(_FP_IMPLBIT_E); \
- _flo->bits.frac = X##_f0; \
- _flo->bits.exp = X##_e; \
- _flo->bits.sign = X##_s; \
- } \
- } while (0)
-
-
-#define FP_UNPACK_E(X,val) \
- do { \
- FP_UNPACK_RAW_E(X,val); \
- _FP_UNPACK_CANONICAL(E,2,X); \
- } while (0)
-
-#define FP_UNPACK_EP(X,val) \
- do { \
- FP_UNPACK_RAW_EP(X,val); \
- _FP_UNPACK_CANONICAL(E,2,X); \
- } while (0)
-
-#define FP_PACK_E(val,X) \
- do { \
- _FP_PACK_CANONICAL(E,2,X); \
- FP_PACK_RAW_E(val,X); \
- } while (0)
-
-#define FP_PACK_EP(val,X) \
- do { \
- _FP_PACK_CANONICAL(E,2,X); \
- FP_PACK_RAW_EP(val,X); \
- } while (0)
-
-#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,2,X)
-#define FP_NEG_E(R,X) _FP_NEG(E,2,R,X)
-#define FP_ADD_E(R,X,Y) _FP_ADD(E,2,R,X,Y)
-#define FP_SUB_E(R,X,Y) _FP_SUB(E,2,R,X,Y)
-#define FP_MUL_E(R,X,Y) _FP_MUL(E,2,R,X,Y)
-#define FP_DIV_E(R,X,Y) _FP_DIV(E,2,R,X,Y)
-#define FP_SQRT_E(R,X) _FP_SQRT(E,2,R,X)
-
-/*
- * Square root algorithms:
- * We have just one right now, maybe Newton approximation
- * should be added for those machines where division is fast.
- * We optimize it by doing most of the calculations
- * in one UWtype registers instead of two, although we don't
- * have to.
- */
-#define _FP_SQRT_MEAT_E(R, S, T, X, q) \
- do { \
- q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
- _FP_FRAC_SRL_2(X, (_FP_WORKBITS)); \
- while (q) \
- { \
- T##_f0 = S##_f0 + q; \
- if (T##_f0 <= X##_f0) \
- { \
- S##_f0 = T##_f0 + q; \
- X##_f0 -= T##_f0; \
- R##_f0 += q; \
- } \
- _FP_FRAC_SLL_1(X, 1); \
- q >>= 1; \
- } \
- _FP_FRAC_SLL_2(R, (_FP_WORKBITS)); \
- if (X##_f0) \
- { \
- if (S##_f0 < X##_f0) \
- R##_f0 |= _FP_WORK_ROUND; \
- R##_f0 |= _FP_WORK_STICKY; \
- } \
- } while (0)
-
-#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,2,r,X,Y,un)
-#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y)
-
-#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,2,r,X,rsz,rsg)
-#define FP_TO_INT_ROUND_E(r,X,rsz,rsg) _FP_TO_INT_ROUND(E,2,r,X,rsz,rsg)
-#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,2,X,r,rs,rt)
-
-#define _FP_FRAC_HIGH_E(X) (X##_f1)
-#define _FP_FRAC_HIGH_RAW_E(X) (X##_f0)
-
-#endif /* not _FP_W_TYPE_SIZE < 64 */
-
-#endif /* __MATH_EMU_EXTENDED_H__ */
diff --git a/include/net/sock.h b/include/net/sock.h
index 25c37e3..689b886 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1361,15 +1361,6 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool)
extern __u32 sysctl_wmem_max;
extern __u32 sysctl_rmem_max;
-#ifdef CONFIG_NET
-int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
-#else
-static inline int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
- return -ENODEV;
-}
-#endif
-
extern void sk_init(void);
#ifdef CONFIG_SYSCTL
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index 8c339f5..90ef552 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -108,6 +108,11 @@ typedef struct dev_node_t {
struct pcmcia_socket;
struct config_t;
+struct pcmcia_dynids {
+ spinlock_t lock;
+ struct list_head list;
+};
+
struct pcmcia_driver {
int (*probe) (struct pcmcia_device *dev);
void (*remove) (struct pcmcia_device *dev);
@@ -118,6 +123,7 @@ struct pcmcia_driver {
struct module *owner;
struct pcmcia_device_id *id_table;
struct device_driver drv;
+ struct pcmcia_dynids dynids;
};
/* driver registration */
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 765589f..5342ac6 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -431,9 +431,11 @@ struct ib_wc {
u8 port_num; /* valid only for DR SMPs on switches */
};
-enum ib_cq_notify {
- IB_CQ_SOLICITED,
- IB_CQ_NEXT_COMP
+enum ib_cq_notify_flags {
+ IB_CQ_SOLICITED = 1 << 0,
+ IB_CQ_NEXT_COMP = 1 << 1,
+ IB_CQ_SOLICITED_MASK = IB_CQ_SOLICITED | IB_CQ_NEXT_COMP,
+ IB_CQ_REPORT_MISSED_EVENTS = 1 << 2,
};
enum ib_srq_attr_mask {
@@ -912,6 +914,8 @@ struct ib_device {
u32 flags;
+ int num_comp_vectors;
+
struct iw_cm_verbs *iwcm;
int (*query_device)(struct ib_device *device,
@@ -978,6 +982,7 @@ struct ib_device {
struct ib_recv_wr *recv_wr,
struct ib_recv_wr **bad_recv_wr);
struct ib_cq * (*create_cq)(struct ib_device *device, int cqe,
+ int comp_vector,
struct ib_ucontext *context,
struct ib_udata *udata);
int (*destroy_cq)(struct ib_cq *cq);
@@ -987,7 +992,7 @@ struct ib_device {
struct ib_wc *wc);
int (*peek_cq)(struct ib_cq *cq, int wc_cnt);
int (*req_notify_cq)(struct ib_cq *cq,
- enum ib_cq_notify cq_notify);
+ enum ib_cq_notify_flags flags);
int (*req_ncomp_notif)(struct ib_cq *cq,
int wc_cnt);
struct ib_mr * (*get_dma_mr)(struct ib_pd *pd,
@@ -1358,13 +1363,15 @@ static inline int ib_post_recv(struct ib_qp *qp,
* @cq_context: Context associated with the CQ returned to the user via
* the associated completion and event handlers.
* @cqe: The minimum size of the CQ.
+ * @comp_vector - Completion vector used to signal completion events.
+ * Must be >= 0 and < context->num_comp_vectors.
*
* Users can examine the cq structure to determine the actual CQ size.
*/
struct ib_cq *ib_create_cq(struct ib_device *device,
ib_comp_handler comp_handler,
void (*event_handler)(struct ib_event *, void *),
- void *cq_context, int cqe);
+ void *cq_context, int cqe, int comp_vector);
/**
* ib_resize_cq - Modifies the capacity of the CQ.
@@ -1414,14 +1421,34 @@ int ib_peek_cq(struct ib_cq *cq, int wc_cnt);
/**
* ib_req_notify_cq - Request completion notification on a CQ.
* @cq: The CQ to generate an event for.
- * @cq_notify: If set to %IB_CQ_SOLICITED, completion notification will
- * occur on the next solicited event. If set to %IB_CQ_NEXT_COMP,
- * notification will occur on the next completion.
+ * @flags:
+ * Must contain exactly one of %IB_CQ_SOLICITED or %IB_CQ_NEXT_COMP
+ * to request an event on the next solicited event or next work
+ * completion at any type, respectively. %IB_CQ_REPORT_MISSED_EVENTS
+ * may also be |ed in to request a hint about missed events, as
+ * described below.
+ *
+ * Return Value:
+ * < 0 means an error occurred while requesting notification
+ * == 0 means notification was requested successfully, and if
+ * IB_CQ_REPORT_MISSED_EVENTS was passed in, then no events
+ * were missed and it is safe to wait for another event. In
+ * this case is it guaranteed that any work completions added
+ * to the CQ since the last CQ poll will trigger a completion
+ * notification event.
+ * > 0 is only returned if IB_CQ_REPORT_MISSED_EVENTS was passed
+ * in. It means that the consumer must poll the CQ again to
+ * make sure it is empty to avoid missing an event because of a
+ * race between requesting notification and an entry being
+ * added to the CQ. This return value means it is possible
+ * (but not guaranteed) that a work completion has been added
+ * to the CQ since the last poll without triggering a
+ * completion notification event.
*/
static inline int ib_req_notify_cq(struct ib_cq *cq,
- enum ib_cq_notify cq_notify)
+ enum ib_cq_notify_flags flags)
{
- return cq->device->req_notify_cq(cq, cq_notify);
+ return cq->device->req_notify_cq(cq, flags);
}
/**
diff --git a/include/video/mach64.h b/include/video/mach64.h
index 09a7f4a..a8332e5 100644
--- a/include/video/mach64.h
+++ b/include/video/mach64.h
@@ -885,6 +885,7 @@
#define SDRAM 4
#define SGRAM 5
#define WRAM 6
+#define SDRAM32 6
#define DAC_INTERNAL 0x00
#define DAC_IBMRGB514 0x01
diff --git a/include/video/permedia2.h b/include/video/permedia2.h
index b95d362..9e49c95 100644
--- a/include/video/permedia2.h
+++ b/include/video/permedia2.h
@@ -154,6 +154,10 @@
#define PM2VI_RD_CLK1_PRESCALE 0x204
#define PM2VI_RD_CLK1_FEEDBACK 0x205
#define PM2VI_RD_CLK1_POSTSCALE 0x206
+#define PM2VI_RD_MCLK_CONTROL 0x20D
+#define PM2VI_RD_MCLK_PRESCALE 0x20E
+#define PM2VI_RD_MCLK_FEEDBACK 0x20F
+#define PM2VI_RD_MCLK_POSTSCALE 0x210
#define PM2VI_RD_CURSOR_PALETTE 0x303
#define PM2VI_RD_CURSOR_PATTERN 0x400
diff --git a/include/video/tgafb.h b/include/video/tgafb.h
index be2b3e9..03d0dbe 100644
--- a/include/video/tgafb.h
+++ b/include/video/tgafb.h
@@ -39,6 +39,7 @@
#define TGA_RASTEROP_REG 0x0034
#define TGA_PIXELSHIFT_REG 0x0038
#define TGA_DEEP_REG 0x0050
+#define TGA_START_REG 0x0054
#define TGA_PIXELMASK_REG 0x005c
#define TGA_CURSOR_BASE_REG 0x0060
#define TGA_HORIZ_REG 0x0064
@@ -140,7 +141,7 @@
/*
- * Useful defines for managing the BT463 on the 24-plane TGAs
+ * Useful defines for managing the BT463 on the 24-plane TGAs/SFB+s
*/
#define BT463_ADDR_LO 0x0
@@ -168,12 +169,35 @@
#define BT463_WINDOW_TYPE_BASE 0x0300
/*
+ * Useful defines for managing the BT459 on the 8-plane SFB+s
+ */
+
+#define BT459_ADDR_LO 0x0
+#define BT459_ADDR_HI 0x1
+#define BT459_REG_ACC 0x2
+#define BT459_PALETTE 0x3
+
+#define BT459_CUR_CLR_1 0x0181
+#define BT459_CUR_CLR_2 0x0182
+#define BT459_CUR_CLR_3 0x0183
+
+#define BT459_CMD_REG_0 0x0201
+#define BT459_CMD_REG_1 0x0202
+#define BT459_CMD_REG_2 0x0203
+
+#define BT459_READ_MASK 0x0204
+
+#define BT459_BLINK_MASK 0x0206
+
+#define BT459_CUR_CMD_REG 0x0300
+
+/*
* The framebuffer driver private data.
*/
struct tga_par {
- /* PCI device. */
- struct pci_dev *pdev;
+ /* PCI/TC device. */
+ struct device *dev;
/* Device dependent information. */
void __iomem *tga_mem_base;
@@ -235,4 +259,21 @@ BT463_WRITE(struct tga_par *par, u32 m, u16 a, u8 v)
TGA_WRITE_REG(par, m << 10 | v, TGA_RAMDAC_REG);
}
+static inline void
+BT459_LOAD_ADDR(struct tga_par *par, u16 a)
+{
+ TGA_WRITE_REG(par, BT459_ADDR_LO << 2, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(par, a & 0xff, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, BT459_ADDR_HI << 2, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(par, a >> 8, TGA_RAMDAC_REG);
+}
+
+static inline void
+BT459_WRITE(struct tga_par *par, u32 m, u16 a, u8 v)
+{
+ BT459_LOAD_ADDR(par, a);
+ TGA_WRITE_REG(par, m << 2, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(par, v, TGA_RAMDAC_REG);
+}
+
#endif /* TGAFB_H */
diff --git a/init/Kconfig b/init/Kconfig
index b170aa1..d0edf42 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -80,16 +80,20 @@ config LOCALVERSION_AUTO
default y
help
This will try to automatically determine if the current tree is a
- release tree by looking for git tags that
- belong to the current top of tree revision.
+ release tree by looking for git tags that belong to the current
+ top of tree revision.
A string of the format -gxxxxxxxx will be added to the localversion
- if a git based tree is found. The string generated by this will be
+ if a git-based tree is found. The string generated by this will be
appended after any matching localversion* files, and after the value
- set in CONFIG_LOCALVERSION
+ set in CONFIG_LOCALVERSION.
- Note: This requires Perl, and a git repository, but not necessarily
- the git or cogito tools to be installed.
+ (The actual string used here is the first eight characters produced
+ by running the command:
+
+ $ git rev-parse --verify HEAD
+
+ which is done within the script "scripts/setlocalversion".)
config SWAP
bool "Support for paging of anonymous memory (swap)"
@@ -262,6 +266,23 @@ config IKCONFIG_PROC
This option enables access to the kernel configuration file
through /proc/config.gz.
+config LOG_BUF_SHIFT
+ int "Kernel log buffer size (16 => 64KB, 17 => 128KB)"
+ range 12 21
+ default 17 if S390 || LOCKDEP
+ default 16 if X86_NUMAQ || IA64
+ default 15 if SMP
+ default 14
+ help
+ Select kernel log buffer size as a power of 2.
+ Defaults and Examples:
+ 17 => 128 KB for S/390
+ 16 => 64 KB for x86 NUMAQ or IA-64
+ 15 => 32 KB for SMP
+ 14 => 16 KB for uniprocessor
+ 13 => 8 KB
+ 12 => 4 KB
+
config CPUSETS
bool "Cpuset support"
depends on SMP
@@ -352,7 +373,7 @@ menuconfig EMBEDDED
config UID16
bool "Enable 16-bit UID system calls" if EMBEDDED
- depends on ARM || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && SPARC32_COMPAT) || UML || (X86_64 && IA32_EMULATION)
+ depends on ARM || BFIN || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && SPARC32_COMPAT) || UML || (X86_64 && IA32_EMULATION)
default y
help
This enables the legacy 16-bit UID syscall wrappers.
@@ -474,15 +495,6 @@ config SHMEM
option replaces shmem and tmpfs with the much simpler ramfs code,
which may be appropriate on small systems without swap.
-config SLAB
- default y
- bool "Use full SLAB allocator" if (EMBEDDED && !SMP && !SPARSEMEM)
- help
- Disabling this replaces the advanced SLAB allocator and
- kmalloc support with the drastically simpler SLOB allocator.
- SLOB is more space efficient but does not scale well and is
- more susceptible to fragmentation.
-
config VM_EVENT_COUNTERS
default y
bool "Enable VM event counters for /proc/vmstat" if EMBEDDED
@@ -492,6 +504,46 @@ config VM_EVENT_COUNTERS
on EMBEDDED systems. /proc/vmstat will only show page counts
if VM event counters are disabled.
+choice
+ prompt "Choose SLAB allocator"
+ default SLAB
+ help
+ This option allows to select a slab allocator.
+
+config SLAB
+ bool "SLAB"
+ help
+ The regular slab allocator that is established and known to work
+ well in all environments. It organizes chache hot objects in
+ per cpu and per node queues. SLAB is the default choice for
+ slab allocator.
+
+config SLUB
+ depends on EXPERIMENTAL && !ARCH_USES_SLAB_PAGE_STRUCT
+ bool "SLUB (Unqueued Allocator)"
+ help
+ SLUB is a slab allocator that minimizes cache line usage
+ instead of managing queues of cached objects (SLAB approach).
+ Per cpu caching is realized using slabs of objects instead
+ of queues of objects. SLUB can use memory efficiently
+ way and has enhanced diagnostics.
+
+config SLOB
+#
+# SLOB cannot support SMP because SLAB_DESTROY_BY_RCU does not work
+# properly.
+#
+ depends on EMBEDDED && !SMP && !SPARSEMEM
+ bool "SLOB (Simple Allocator)"
+ help
+ SLOB replaces the SLAB allocator with a drastically simpler
+ allocator. SLOB is more space efficient that SLAB but does not
+ scale well (single lock for all operations) and is more susceptible
+ to fragmentation. SLOB it is a great choice to reduce
+ memory usage and code size for embedded systems.
+
+endchoice
+
endmenu # General setup
config RT_MUTEXES
@@ -507,10 +559,6 @@ config BASE_SMALL
default 0 if BASE_FULL
default 1 if !BASE_FULL
-config SLOB
- default !SLAB
- bool
-
menu "Loadable module support"
config MODULES
diff --git a/init/do_mounts.c b/init/do_mounts.c
index dc1ec08..3f57ed4 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -9,6 +9,7 @@
#include <linux/delay.h>
#include <linux/mount.h>
#include <linux/device.h>
+#include <linux/init.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_fs_sb.h>
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index 2cfd7cb..b222ce9 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -55,11 +55,12 @@ static void __init handle_initrd(void)
sys_mount(".", "/", NULL, MS_MOVE, NULL);
sys_chroot(".");
- current->flags |= PF_NOFREEZE;
pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
if (pid > 0) {
- while (pid != sys_wait4(-1, NULL, 0, NULL))
+ while (pid != sys_wait4(-1, NULL, 0, NULL)) {
+ try_to_freeze();
yield();
+ }
}
/* move initrd to rootfs' /old */
diff --git a/init/main.c b/init/main.c
index 80f09f3..c1537e0 100644
--- a/init/main.c
+++ b/init/main.c
@@ -82,7 +82,7 @@
#warning gcc-4.1.0 is known to miscompile the kernel. A different compiler version is recommended.
#endif
-static int init(void *);
+static int kernel_init(void *);
extern void init_IRQ(void);
extern void fork_init(unsigned long);
@@ -94,7 +94,6 @@ extern void pidmap_init(void);
extern void prio_tree_init(void);
extern void radix_tree_init(void);
extern void free_initmem(void);
-extern void prepare_namespace(void);
#ifdef CONFIG_ACPI
extern void acpi_early_init(void);
#else
@@ -384,11 +383,6 @@ static void __init setup_per_cpu_areas(void)
static void __init smp_init(void)
{
unsigned int cpu;
- unsigned highest = 0;
-
- for_each_cpu_mask(cpu, cpu_possible_map)
- highest = cpu;
- nr_cpu_ids = highest + 1;
/* FIXME: This should be done in userspace --RR */
for_each_present_cpu(cpu) {
@@ -431,7 +425,7 @@ static void __init setup_command_line(char *command_line)
static void noinline rest_init(void)
__releases(kernel_lock)
{
- kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
+ kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
numa_default_policy();
unlock_kernel();
@@ -654,6 +648,7 @@ static void __init do_initcalls(void)
int count = preempt_count();
for (call = __initcall_start; call < __initcall_end; call++) {
+ ktime_t t0, t1, delta;
char *msg = NULL;
char msgbuf[40];
int result;
@@ -663,10 +658,26 @@ static void __init do_initcalls(void)
print_fn_descriptor_symbol(": %s()",
(unsigned long) *call);
printk("\n");
+ t0 = ktime_get();
}
result = (*call)();
+ if (initcall_debug) {
+ t1 = ktime_get();
+ delta = ktime_sub(t1, t0);
+
+ printk("initcall 0x%p", *call);
+ print_fn_descriptor_symbol(": %s()",
+ (unsigned long) *call);
+ printk(" returned %d.\n", result);
+
+ printk("initcall 0x%p ran for %Ld msecs: ",
+ *call, (unsigned long long)delta.tv64 >> 20);
+ print_fn_descriptor_symbol("%s()\n",
+ (unsigned long) *call);
+ }
+
if (result && result != -ENODEV && initcall_debug) {
sprintf(msgbuf, "error code %d", result);
msg = msgbuf;
@@ -768,7 +779,7 @@ static int noinline init_post(void)
panic("No init found. Try passing init= option to kernel.");
}
-static int __init init(void * unused)
+static int __init kernel_init(void * unused)
{
lock_kernel();
/*
diff --git a/ipc/compat.c b/ipc/compat.c
index fa18141..8b44aa9 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -542,6 +542,8 @@ static inline int put_compat_shminfo64(struct shminfo64 *smi,
if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64)))
return -EFAULT;
+ if (smi->shmmax > INT_MAX)
+ smi->shmmax = INT_MAX;
err = __put_user(smi->shmmax, &up64->shmmax);
err |= __put_user(smi->shmmin, &up64->shmmin);
err |= __put_user(smi->shmmni, &up64->shmmni);
@@ -557,6 +559,8 @@ static inline int put_compat_shminfo(struct shminfo64 *smi,
if (!access_ok(VERIFY_WRITE, up, sizeof(*up)))
return -EFAULT;
+ if (smi->shmmax > INT_MAX)
+ smi->shmmax = INT_MAX;
err = __put_user(smi->shmmax, &up->shmmax);
err |= __put_user(smi->shmmin, &up->shmmin);
err |= __put_user(smi->shmmni, &up->shmmni);
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 554ac36..d17821d 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -215,8 +215,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags
{
struct mqueue_inode_info *p = (struct mqueue_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&p->vfs_inode);
}
diff --git a/ipc/sem.c b/ipc/sem.c
index d3e12ef..9964b22 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -75,7 +75,6 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/time.h>
-#include <linux/smp_lock.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/audit.h>
diff --git a/ipc/util.c b/ipc/util.c
index 0b65238..7536a72 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -21,7 +21,6 @@
#include <linux/shm.h>
#include <linux/init.h>
#include <linux/msg.h>
-#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/capability.h>
@@ -85,53 +84,20 @@ err_mem:
return ERR_PTR(err);
}
-int unshare_ipcs(unsigned long unshare_flags, struct ipc_namespace **new_ipc)
+struct ipc_namespace *copy_ipcs(unsigned long flags, struct ipc_namespace *ns)
{
- struct ipc_namespace *new;
-
- if (unshare_flags & CLONE_NEWIPC) {
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- new = clone_ipc_ns(current->nsproxy->ipc_ns);
- if (IS_ERR(new))
- return PTR_ERR(new);
-
- *new_ipc = new;
- }
-
- return 0;
-}
-
-int copy_ipcs(unsigned long flags, struct task_struct *tsk)
-{
- struct ipc_namespace *old_ns = tsk->nsproxy->ipc_ns;
struct ipc_namespace *new_ns;
- int err = 0;
- if (!old_ns)
- return 0;
-
- get_ipc_ns(old_ns);
+ BUG_ON(!ns);
+ get_ipc_ns(ns);
if (!(flags & CLONE_NEWIPC))
- return 0;
+ return ns;
- if (!capable(CAP_SYS_ADMIN)) {
- err = -EPERM;
- goto out;
- }
+ new_ns = clone_ipc_ns(ns);
- new_ns = clone_ipc_ns(old_ns);
- if (!new_ns) {
- err = -ENOMEM;
- goto out;
- }
-
- tsk->nsproxy->ipc_ns = new_ns;
-out:
- put_ipc_ns(old_ns);
- return err;
+ put_ipc_ns(ns);
+ return new_ns;
}
void free_ipc_ns(struct kref *kref)
@@ -145,11 +111,11 @@ void free_ipc_ns(struct kref *kref)
kfree(ns);
}
#else
-int copy_ipcs(unsigned long flags, struct task_struct *tsk)
+struct ipc_namespace *copy_ipcs(unsigned long flags, struct ipc_namespace *ns)
{
if (flags & CLONE_NEWIPC)
- return -EINVAL;
- return 0;
+ return ERR_PTR(-EINVAL);
+ return ns;
}
#endif
diff --git a/kernel/Makefile b/kernel/Makefile
index ac6b27a..642d427 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -8,7 +8,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
signal.o sys.o kmod.o workqueue.o pid.o \
rcupdate.o extable.o params.o posix-timers.o \
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
- hrtimer.o rwsem.o latency.o nsproxy.o srcu.o
+ hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-y += time/
diff --git a/kernel/audit.c b/kernel/audit.c
index 4e9d208..d13276d 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -515,8 +515,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
err = -EPERM;
break;
case AUDIT_USER:
- case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
- case AUDIT_FIRST_USER_MSG2...AUDIT_LAST_USER_MSG2:
+ case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
+ case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
if (security_netlink_recv(skb, CAP_AUDIT_WRITE))
err = -EPERM;
break;
@@ -614,8 +614,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
loginuid, sid);
break;
case AUDIT_USER:
- case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
- case AUDIT_FIRST_USER_MSG2...AUDIT_LAST_USER_MSG2:
+ case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
+ case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
if (!audit_enabled && msg_type != AUDIT_USER_AVC)
return 0;
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index f382b0f..88b416d 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -42,7 +42,6 @@
#include <linux/seq_file.h>
#include <linux/security.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/stat.h>
#include <linux/string.h>
@@ -822,11 +821,22 @@ static int update_cpumask(struct cpuset *cs, char *buf)
return -EACCES;
trialcs = *cs;
- retval = cpulist_parse(buf, trialcs.cpus_allowed);
- if (retval < 0)
- return retval;
+
+ /*
+ * We allow a cpuset's cpus_allowed to be empty; if it has attached
+ * tasks, we'll catch it later when we validate the change and return
+ * -ENOSPC.
+ */
+ if (!buf[0] || (buf[0] == '\n' && !buf[1])) {
+ cpus_clear(trialcs.cpus_allowed);
+ } else {
+ retval = cpulist_parse(buf, trialcs.cpus_allowed);
+ if (retval < 0)
+ return retval;
+ }
cpus_and(trialcs.cpus_allowed, trialcs.cpus_allowed, cpu_online_map);
- if (cpus_empty(trialcs.cpus_allowed))
+ /* cpus_allowed cannot be empty for a cpuset with attached tasks. */
+ if (atomic_read(&cs->count) && cpus_empty(trialcs.cpus_allowed))
return -ENOSPC;
retval = validate_change(cs, &trialcs);
if (retval < 0)
@@ -919,16 +929,27 @@ static int update_nodemask(struct cpuset *cs, char *buf)
return -EACCES;
trialcs = *cs;
- retval = nodelist_parse(buf, trialcs.mems_allowed);
- if (retval < 0)
- goto done;
+
+ /*
+ * We allow a cpuset's mems_allowed to be empty; if it has attached
+ * tasks, we'll catch it later when we validate the change and return
+ * -ENOSPC.
+ */
+ if (!buf[0] || (buf[0] == '\n' && !buf[1])) {
+ nodes_clear(trialcs.mems_allowed);
+ } else {
+ retval = nodelist_parse(buf, trialcs.mems_allowed);
+ if (retval < 0)
+ goto done;
+ }
nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, node_online_map);
oldmem = cs->mems_allowed;
if (nodes_equal(oldmem, trialcs.mems_allowed)) {
retval = 0; /* Too easy - nothing to do */
goto done;
}
- if (nodes_empty(trialcs.mems_allowed)) {
+ /* mems_allowed cannot be empty for a cpuset with attached tasks. */
+ if (atomic_read(&cs->count) && nodes_empty(trialcs.mems_allowed)) {
retval = -ENOSPC;
goto done;
}
@@ -2200,10 +2221,6 @@ void cpuset_fork(struct task_struct *child)
* it is holding that mutex while calling check_for_release(),
* which calls kmalloc(), so can't be called holding callback_mutex().
*
- * We don't need to task_lock() this reference to tsk->cpuset,
- * because tsk is already marked PF_EXITING, so attach_task() won't
- * mess with it, or task is a failed fork, never visible to attach_task.
- *
* the_top_cpuset_hack:
*
* Set the exiting tasks cpuset to the root cpuset (top_cpuset).
@@ -2242,8 +2259,10 @@ void cpuset_exit(struct task_struct *tsk)
{
struct cpuset *cs;
+ task_lock(current);
cs = tsk->cpuset;
tsk->cpuset = &top_cpuset; /* the_top_cpuset_hack - see above */
+ task_unlock(current);
if (notify_on_release(cs)) {
char *pathbuf = NULL;
@@ -2351,6 +2370,8 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
* z's node is in our tasks mems_allowed, yes. If it's not a
* __GFP_HARDWALL request and this zone's nodes is in the nearest
* mem_exclusive cpuset ancestor to this tasks cpuset, yes.
+ * If the task has been OOM killed and has access to memory reserves
+ * as specified by the TIF_MEMDIE flag, yes.
* Otherwise, no.
*
* If __GFP_HARDWALL is set, cpuset_zone_allowed_softwall()
@@ -2368,7 +2389,8 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
* calls get to this routine, we should just shut up and say 'yes'.
*
* GFP_USER allocations are marked with the __GFP_HARDWALL bit,
- * and do not allow allocations outside the current tasks cpuset.
+ * and do not allow allocations outside the current tasks cpuset
+ * unless the task has been OOM killed as is marked TIF_MEMDIE.
* GFP_KERNEL allocations are not so marked, so can escape to the
* nearest enclosing mem_exclusive ancestor cpuset.
*
@@ -2392,6 +2414,7 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
* affect that:
* in_interrupt - any node ok (current task context irrelevant)
* GFP_ATOMIC - any node ok
+ * TIF_MEMDIE - any node ok
* GFP_KERNEL - any node in enclosing mem_exclusive cpuset ok
* GFP_USER - only nodes in current tasks mems allowed ok.
*
@@ -2413,6 +2436,12 @@ int __cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask)
might_sleep_if(!(gfp_mask & __GFP_HARDWALL));
if (node_isset(node, current->mems_allowed))
return 1;
+ /*
+ * Allow tasks that have access to memory reserves because they have
+ * been OOM killed to get memory anywhere.
+ */
+ if (unlikely(test_thread_flag(TIF_MEMDIE)))
+ return 1;
if (gfp_mask & __GFP_HARDWALL) /* If hardwall request, stop here */
return 0;
@@ -2438,7 +2467,9 @@ int __cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask)
*
* If we're in interrupt, yes, we can always allocate.
* If __GFP_THISNODE is set, yes, we can always allocate. If zone
- * z's node is in our tasks mems_allowed, yes. Otherwise, no.
+ * z's node is in our tasks mems_allowed, yes. If the task has been
+ * OOM killed and has access to memory reserves as specified by the
+ * TIF_MEMDIE flag, yes. Otherwise, no.
*
* The __GFP_THISNODE placement logic is really handled elsewhere,
* by forcibly using a zonelist starting at a specified node, and by
@@ -2462,6 +2493,12 @@ int __cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
node = zone_to_nid(z);
if (node_isset(node, current->mems_allowed))
return 1;
+ /*
+ * Allow tasks that have access to memory reserves because they have
+ * been OOM killed to get memory anywhere.
+ */
+ if (unlikely(test_thread_flag(TIF_MEMDIE)))
+ return 1;
return 0;
}
diff --git a/kernel/delayacct.c b/kernel/delayacct.c
index 766d591..c0148ae 100644
--- a/kernel/delayacct.c
+++ b/kernel/delayacct.c
@@ -31,11 +31,7 @@ __setup("nodelayacct", delayacct_setup_disable);
void delayacct_init(void)
{
- delayacct_cache = kmem_cache_create("delayacct_cache",
- sizeof(struct task_delay_info),
- 0,
- SLAB_PANIC,
- NULL, NULL);
+ delayacct_cache = KMEM_CACHE(task_delay_info, SLAB_PANIC);
delayacct_tsk_init(&init_task);
}
diff --git a/kernel/die_notifier.c b/kernel/die_notifier.c
new file mode 100644
index 0000000..0d98827
--- /dev/null
+++ b/kernel/die_notifier.c
@@ -0,0 +1,38 @@
+
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/vmalloc.h>
+#include <linux/kdebug.h>
+
+
+static ATOMIC_NOTIFIER_HEAD(die_chain);
+
+int notify_die(enum die_val val, const char *str,
+ struct pt_regs *regs, long err, int trap, int sig)
+{
+ struct die_args args = {
+ .regs = regs,
+ .str = str,
+ .err = err,
+ .trapnr = trap,
+ .signr = sig,
+
+ };
+
+ return atomic_notifier_call_chain(&die_chain, val, &args);
+}
+
+int register_die_notifier(struct notifier_block *nb)
+{
+ vmalloc_sync_all();
+ return atomic_notifier_chain_register(&die_chain, nb);
+}
+EXPORT_SYMBOL_GPL(register_die_notifier);
+
+int unregister_die_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&die_chain, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_die_notifier);
+
+
diff --git a/kernel/exit.c b/kernel/exit.c
index b55ed4c..f5a7abb 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -7,7 +7,6 @@
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/capability.h>
#include <linux/completion.h>
@@ -1033,6 +1032,8 @@ asmlinkage void sys_exit_group(int error_code)
static int eligible_child(pid_t pid, int options, struct task_struct *p)
{
+ int err;
+
if (pid > 0) {
if (p->pid != pid)
return 0;
@@ -1066,8 +1067,9 @@ static int eligible_child(pid_t pid, int options, struct task_struct *p)
if (delay_group_leader(p))
return 2;
- if (security_task_wait(p))
- return 0;
+ err = security_task_wait(p);
+ if (err)
+ return err;
return 1;
}
@@ -1449,6 +1451,7 @@ static long do_wait(pid_t pid, int options, struct siginfo __user *infop,
DECLARE_WAITQUEUE(wait, current);
struct task_struct *tsk;
int flag, retval;
+ int allowed, denied;
add_wait_queue(&current->signal->wait_chldexit,&wait);
repeat:
@@ -1457,6 +1460,7 @@ repeat:
* match our criteria, even if we are not able to reap it yet.
*/
flag = 0;
+ allowed = denied = 0;
current->state = TASK_INTERRUPTIBLE;
read_lock(&tasklist_lock);
tsk = current;
@@ -1472,6 +1476,12 @@ repeat:
if (!ret)
continue;
+ if (unlikely(ret < 0)) {
+ denied = ret;
+ continue;
+ }
+ allowed = 1;
+
switch (p->state) {
case TASK_TRACED:
/*
@@ -1570,6 +1580,8 @@ check_continued:
goto repeat;
}
retval = -ECHILD;
+ if (unlikely(denied) && !allowed)
+ retval = denied;
end:
current->state = TASK_RUNNING;
remove_wait_queue(&current->signal->wait_chldexit,&wait);
diff --git a/kernel/fork.c b/kernel/fork.c
index ffccefb..a8dd75d 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -14,7 +14,6 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/unistd.h>
-#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/completion.h>
@@ -1425,8 +1424,7 @@ static void sighand_ctor(void *data, struct kmem_cache *cachep, unsigned long fl
{
struct sighand_struct *sighand = data;
- if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
spin_lock_init(&sighand->siglock);
}
@@ -1517,26 +1515,6 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
}
/*
- * Unshare the mnt_namespace structure if it is being shared
- */
-static int unshare_mnt_namespace(unsigned long unshare_flags,
- struct mnt_namespace **new_nsp, struct fs_struct *new_fs)
-{
- struct mnt_namespace *ns = current->nsproxy->mnt_ns;
-
- if ((unshare_flags & CLONE_NEWNS) && ns) {
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- *new_nsp = dup_mnt_ns(current, new_fs ? new_fs : current->fs);
- if (!*new_nsp)
- return -ENOMEM;
- }
-
- return 0;
-}
-
-/*
* Unsharing of sighand is not supported yet
*/
static int unshare_sighand(unsigned long unshare_flags, struct sighand_struct **new_sighp)
@@ -1594,16 +1572,6 @@ static int unshare_semundo(unsigned long unshare_flags, struct sem_undo_list **n
return 0;
}
-#ifndef CONFIG_IPC_NS
-static inline int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns)
-{
- if (flags & CLONE_NEWIPC)
- return -EINVAL;
-
- return 0;
-}
-#endif
-
/*
* unshare allows a process to 'unshare' part of the process
* context which was originally shared using clone. copy_*
@@ -1616,14 +1584,11 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
{
int err = 0;
struct fs_struct *fs, *new_fs = NULL;
- struct mnt_namespace *ns, *new_ns = NULL;
struct sighand_struct *new_sigh = NULL;
struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
struct files_struct *fd, *new_fd = NULL;
struct sem_undo_list *new_ulist = NULL;
struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL;
- struct uts_namespace *uts, *new_uts = NULL;
- struct ipc_namespace *ipc, *new_ipc = NULL;
check_unshare_flags(&unshare_flags);
@@ -1638,36 +1603,24 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
goto bad_unshare_out;
if ((err = unshare_fs(unshare_flags, &new_fs)))
goto bad_unshare_cleanup_thread;
- if ((err = unshare_mnt_namespace(unshare_flags, &new_ns, new_fs)))
- goto bad_unshare_cleanup_fs;
if ((err = unshare_sighand(unshare_flags, &new_sigh)))
- goto bad_unshare_cleanup_ns;
+ goto bad_unshare_cleanup_fs;
if ((err = unshare_vm(unshare_flags, &new_mm)))
goto bad_unshare_cleanup_sigh;
if ((err = unshare_fd(unshare_flags, &new_fd)))
goto bad_unshare_cleanup_vm;
if ((err = unshare_semundo(unshare_flags, &new_ulist)))
goto bad_unshare_cleanup_fd;
- if ((err = unshare_utsname(unshare_flags, &new_uts)))
+ if ((err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy,
+ new_fs)))
goto bad_unshare_cleanup_semundo;
- if ((err = unshare_ipcs(unshare_flags, &new_ipc)))
- goto bad_unshare_cleanup_uts;
-
- if (new_ns || new_uts || new_ipc) {
- old_nsproxy = current->nsproxy;
- new_nsproxy = dup_namespaces(old_nsproxy);
- if (!new_nsproxy) {
- err = -ENOMEM;
- goto bad_unshare_cleanup_ipc;
- }
- }
- if (new_fs || new_ns || new_mm || new_fd || new_ulist ||
- new_uts || new_ipc) {
+ if (new_fs || new_mm || new_fd || new_ulist || new_nsproxy) {
task_lock(current);
if (new_nsproxy) {
+ old_nsproxy = current->nsproxy;
current->nsproxy = new_nsproxy;
new_nsproxy = old_nsproxy;
}
@@ -1678,12 +1631,6 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
new_fs = fs;
}
- if (new_ns) {
- ns = current->nsproxy->mnt_ns;
- current->nsproxy->mnt_ns = new_ns;
- new_ns = ns;
- }
-
if (new_mm) {
mm = current->mm;
active_mm = current->active_mm;
@@ -1699,32 +1646,12 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
new_fd = fd;
}
- if (new_uts) {
- uts = current->nsproxy->uts_ns;
- current->nsproxy->uts_ns = new_uts;
- new_uts = uts;
- }
-
- if (new_ipc) {
- ipc = current->nsproxy->ipc_ns;
- current->nsproxy->ipc_ns = new_ipc;
- new_ipc = ipc;
- }
-
task_unlock(current);
}
if (new_nsproxy)
put_nsproxy(new_nsproxy);
-bad_unshare_cleanup_ipc:
- if (new_ipc)
- put_ipc_ns(new_ipc);
-
-bad_unshare_cleanup_uts:
- if (new_uts)
- put_uts_ns(new_uts);
-
bad_unshare_cleanup_semundo:
bad_unshare_cleanup_fd:
if (new_fd)
@@ -1739,10 +1666,6 @@ bad_unshare_cleanup_sigh:
if (atomic_dec_and_test(&new_sigh->count))
kmem_cache_free(sighand_cachep, new_sigh);
-bad_unshare_cleanup_ns:
- if (new_ns)
- put_mnt_ns(new_ns);
-
bad_unshare_cleanup_fs:
if (new_fs)
put_fs_struct(new_fs);
diff --git a/kernel/futex.c b/kernel/futex.c
index 5a270b5..600bc9d 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -48,6 +48,7 @@
#include <linux/pagemap.h>
#include <linux/syscalls.h>
#include <linux/signal.h>
+#include <linux/module.h>
#include <asm/futex.h>
#include "rtmutex_common.h"
@@ -55,32 +56,6 @@
#define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8)
/*
- * Futexes are matched on equal values of this key.
- * The key type depends on whether it's a shared or private mapping.
- * Don't rearrange members without looking at hash_futex().
- *
- * offset is aligned to a multiple of sizeof(u32) (== 4) by definition.
- * We set bit 0 to indicate if it's an inode-based key.
- */
-union futex_key {
- struct {
- unsigned long pgoff;
- struct inode *inode;
- int offset;
- } shared;
- struct {
- unsigned long address;
- struct mm_struct *mm;
- int offset;
- } private;
- struct {
- unsigned long word;
- void *ptr;
- int offset;
- } both;
-};
-
-/*
* Priority Inheritance state:
*/
struct futex_pi_state {
@@ -175,7 +150,7 @@ static inline int match_futex(union futex_key *key1, union futex_key *key2)
*
* Should be called with &current->mm->mmap_sem but NOT any spinlocks.
*/
-static int get_futex_key(u32 __user *uaddr, union futex_key *key)
+int get_futex_key(u32 __user *uaddr, union futex_key *key)
{
unsigned long address = (unsigned long)uaddr;
struct mm_struct *mm = current->mm;
@@ -246,6 +221,7 @@ static int get_futex_key(u32 __user *uaddr, union futex_key *key)
}
return err;
}
+EXPORT_SYMBOL_GPL(get_futex_key);
/*
* Take a reference to the resource addressed by a key.
@@ -254,7 +230,7 @@ static int get_futex_key(u32 __user *uaddr, union futex_key *key)
* NOTE: mmap_sem MUST be held between get_futex_key() and calling this
* function, if it is called at all. mmap_sem keeps key->shared.inode valid.
*/
-static inline void get_key_refs(union futex_key *key)
+inline void get_futex_key_refs(union futex_key *key)
{
if (key->both.ptr != 0) {
if (key->both.offset & 1)
@@ -263,12 +239,13 @@ static inline void get_key_refs(union futex_key *key)
atomic_inc(&key->private.mm->mm_count);
}
}
+EXPORT_SYMBOL_GPL(get_futex_key_refs);
/*
* Drop a reference to the resource addressed by a key.
* The hash bucket spinlock must not be held.
*/
-static void drop_key_refs(union futex_key *key)
+void drop_futex_key_refs(union futex_key *key)
{
if (key->both.ptr != 0) {
if (key->both.offset & 1)
@@ -277,6 +254,7 @@ static void drop_key_refs(union futex_key *key)
mmdrop(key->private.mm);
}
}
+EXPORT_SYMBOL_GPL(drop_futex_key_refs);
static inline int get_futex_value_locked(u32 *dest, u32 __user *from)
{
@@ -873,7 +851,7 @@ static int futex_requeue(u32 __user *uaddr1, u32 __user *uaddr2,
this->lock_ptr = &hb2->lock;
}
this->key = key2;
- get_key_refs(&key2);
+ get_futex_key_refs(&key2);
drop_count++;
if (ret - nr_wake >= nr_requeue)
@@ -886,9 +864,9 @@ out_unlock:
if (hb1 != hb2)
spin_unlock(&hb2->lock);
- /* drop_key_refs() must be called outside the spinlocks. */
+ /* drop_futex_key_refs() must be called outside the spinlocks. */
while (--drop_count >= 0)
- drop_key_refs(&key1);
+ drop_futex_key_refs(&key1);
out:
up_read(&current->mm->mmap_sem);
@@ -906,7 +884,7 @@ queue_lock(struct futex_q *q, int fd, struct file *filp)
init_waitqueue_head(&q->waiters);
- get_key_refs(&q->key);
+ get_futex_key_refs(&q->key);
hb = hash_futex(&q->key);
q->lock_ptr = &hb->lock;
@@ -925,7 +903,7 @@ static inline void
queue_unlock(struct futex_q *q, struct futex_hash_bucket *hb)
{
spin_unlock(&hb->lock);
- drop_key_refs(&q->key);
+ drop_futex_key_refs(&q->key);
}
/*
@@ -980,7 +958,7 @@ static int unqueue_me(struct futex_q *q)
ret = 1;
}
- drop_key_refs(&q->key);
+ drop_futex_key_refs(&q->key);
return ret;
}
@@ -999,15 +977,18 @@ static void unqueue_me_pi(struct futex_q *q, struct futex_hash_bucket *hb)
spin_unlock(&hb->lock);
- drop_key_refs(&q->key);
+ drop_futex_key_refs(&q->key);
}
-static int futex_wait(u32 __user *uaddr, u32 val, unsigned long time)
+static long futex_wait_restart(struct restart_block *restart);
+static int futex_wait_abstime(u32 __user *uaddr, u32 val,
+ int timed, unsigned long abs_time)
{
struct task_struct *curr = current;
DECLARE_WAITQUEUE(wait, curr);
struct futex_hash_bucket *hb;
struct futex_q q;
+ unsigned long time_left = 0;
u32 uval;
int ret;
@@ -1087,8 +1068,21 @@ static int futex_wait(u32 __user *uaddr, u32 val, unsigned long time)
* !list_empty() is safe here without any lock.
* q.lock_ptr != 0 is not safe, because of ordering against wakeup.
*/
- if (likely(!list_empty(&q.list)))
- time = schedule_timeout(time);
+ time_left = 0;
+ if (likely(!list_empty(&q.list))) {
+ unsigned long rel_time;
+
+ if (timed) {
+ unsigned long now = jiffies;
+ if (time_after(now, abs_time))
+ rel_time = 0;
+ else
+ rel_time = abs_time - now;
+ } else
+ rel_time = MAX_SCHEDULE_TIMEOUT;
+
+ time_left = schedule_timeout(rel_time);
+ }
__set_current_state(TASK_RUNNING);
/*
@@ -1099,13 +1093,25 @@ static int futex_wait(u32 __user *uaddr, u32 val, unsigned long time)
/* If we were woken (and unqueued), we succeeded, whatever. */
if (!unqueue_me(&q))
return 0;
- if (time == 0)
+ if (time_left == 0)
return -ETIMEDOUT;
+
/*
* We expect signal_pending(current), but another thread may
* have handled it for us already.
*/
- return -EINTR;
+ if (time_left == MAX_SCHEDULE_TIMEOUT)
+ return -ERESTARTSYS;
+ else {
+ struct restart_block *restart;
+ restart = &current_thread_info()->restart_block;
+ restart->fn = futex_wait_restart;
+ restart->arg0 = (unsigned long)uaddr;
+ restart->arg1 = (unsigned long)val;
+ restart->arg2 = (unsigned long)timed;
+ restart->arg3 = abs_time;
+ return -ERESTART_RESTARTBLOCK;
+ }
out_unlock_release_sem:
queue_unlock(&q, hb);
@@ -1115,6 +1121,24 @@ static int futex_wait(u32 __user *uaddr, u32 val, unsigned long time)
return ret;
}
+static int futex_wait(u32 __user *uaddr, u32 val, unsigned long rel_time)
+{
+ int timed = (rel_time != MAX_SCHEDULE_TIMEOUT);
+ return futex_wait_abstime(uaddr, val, timed, jiffies+rel_time);
+}
+
+static long futex_wait_restart(struct restart_block *restart)
+{
+ u32 __user *uaddr = (u32 __user *)restart->arg0;
+ u32 val = (u32)restart->arg1;
+ int timed = (int)restart->arg2;
+ unsigned long abs_time = restart->arg3;
+
+ restart->fn = do_no_restart_syscall;
+ return (long)futex_wait_abstime(uaddr, val, timed, abs_time);
+}
+
+
/*
* Userspace tried a 0 -> TID atomic transition of the futex value
* and failed. The kernel side here does the whole locking operation:
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 1b30331..c9f4f04 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -669,6 +669,7 @@ hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval)
return orun;
}
+EXPORT_SYMBOL_GPL(hrtimer_forward);
/*
* enqueue_hrtimer - internal function to (re)start a timer
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index aff1f0f..32e1ab1 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -48,7 +48,7 @@ handle_bad_irq(unsigned int irq, struct irq_desc *desc)
*
* Controller mappings for all interrupt sources:
*/
-struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned = {
+struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
[0 ... NR_IRQS-1] = {
.status = IRQ_DISABLED,
.chip = &no_irq_chip,
@@ -180,6 +180,8 @@ fastcall unsigned int __do_IRQ(unsigned int irq)
if (desc->chip->ack)
desc->chip->ack(irq);
action_ret = handle_IRQ_event(irq, desc->action);
+ if (!noirqdebug)
+ note_interrupt(irq, desc, action_ret);
desc->chip->end(irq);
return 1;
}
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 5597c15..203a518 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -317,10 +317,7 @@ int setup_irq(unsigned int irq, struct irqaction *new)
}
*p = new;
-#if defined(CONFIG_IRQ_PER_CPU)
- if (new->flags & IRQF_PERCPU)
- desc->status |= IRQ_PER_CPU;
-#endif
+
/* Exclude IRQ from balancing */
if (new->flags & IRQF_NOBALANCING)
desc->status |= IRQ_NO_BALANCING;
@@ -328,6 +325,11 @@ int setup_irq(unsigned int irq, struct irqaction *new)
if (!shared) {
irq_chip_set_defaults(desc->chip);
+#if defined(CONFIG_IRQ_PER_CPU)
+ if (new->flags & IRQF_PERCPU)
+ desc->status |= IRQ_PER_CPU;
+#endif
+
/* Setup the type (level, edge polarity) if configured: */
if (new->flags & IRQF_TRIGGER_MASK) {
if (desc->chip && desc->chip->set_type)
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 2db91eb..ddde0ef 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -66,12 +66,19 @@ static int name_unique(unsigned int irq, struct irqaction *new_action)
{
struct irq_desc *desc = irq_desc + irq;
struct irqaction *action;
+ unsigned long flags;
+ int ret = 1;
- for (action = desc->action ; action; action = action->next)
+ spin_lock_irqsave(&desc->lock, flags);
+ for (action = desc->action ; action; action = action->next) {
if ((action != new_action) && action->name &&
- !strcmp(new_action->name, action->name))
- return 0;
- return 1;
+ !strcmp(new_action->name, action->name)) {
+ ret = 0;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&desc->lock, flags);
+ return ret;
}
void register_handler_proc(unsigned int irq, struct irqaction *action)
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 9d8c79b..b0d81aa 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -146,7 +146,9 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
if (unlikely(irqfixup)) {
/* Don't punish working computers */
- if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) {
+ if ((irqfixup == 2 && ((irq == 0) ||
+ (desc->action->flags & IRQF_IRQPOLL))) ||
+ action_ret == IRQ_NONE) {
int ok = misrouted_irq(irq);
if (action_ret == IRQ_NONE)
desc->irqs_unhandled -= ok;
diff --git a/kernel/itimer.c b/kernel/itimer.c
index 307c6a6..3205e8e 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -7,7 +7,6 @@
/* These are all the functions necessary to implement itimers */
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/syscalls.h>
#include <linux/time.h>
@@ -139,59 +138,11 @@ enum hrtimer_restart it_real_fn(struct hrtimer *timer)
}
/*
- * We do not care about correctness. We just sanitize the values so
- * the ktime_t operations which expect normalized values do not
- * break. This converts negative values to long timeouts similar to
- * the code in kernel versions < 2.6.16
- *
- * Print a limited number of warning messages when an invalid timeval
- * is detected.
- */
-static void fixup_timeval(struct timeval *tv, int interval)
-{
- static int warnlimit = 10;
- unsigned long tmp;
-
- if (warnlimit > 0) {
- warnlimit--;
- printk(KERN_WARNING
- "setitimer: %s (pid = %d) provided "
- "invalid timeval %s: tv_sec = %ld tv_usec = %ld\n",
- current->comm, current->pid,
- interval ? "it_interval" : "it_value",
- tv->tv_sec, (long) tv->tv_usec);
- }
-
- tmp = tv->tv_usec;
- if (tmp >= USEC_PER_SEC) {
- tv->tv_usec = tmp % USEC_PER_SEC;
- tv->tv_sec += tmp / USEC_PER_SEC;
- }
-
- tmp = tv->tv_sec;
- if (tmp > LONG_MAX)
- tv->tv_sec = LONG_MAX;
-}
-
-/*
* Returns true if the timeval is in canonical form
*/
#define timeval_valid(t) \
(((t)->tv_sec >= 0) && (((unsigned long) (t)->tv_usec) < USEC_PER_SEC))
-/*
- * Check for invalid timevals, sanitize them and print a limited
- * number of warnings.
- */
-static void check_itimerval(struct itimerval *value) {
-
- if (unlikely(!timeval_valid(&value->it_value)))
- fixup_timeval(&value->it_value, 0);
-
- if (unlikely(!timeval_valid(&value->it_interval)))
- fixup_timeval(&value->it_interval, 1);
-}
-
int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
{
struct task_struct *tsk = current;
@@ -201,15 +152,10 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
/*
* Validate the timevals in value.
- *
- * Note: Although the spec requires that invalid values shall
- * return -EINVAL, we just fixup the value and print a limited
- * number of warnings in order not to break users of this
- * historical misfeature.
- *
- * Scheduled for replacement in March 2007
*/
- check_itimerval(value);
+ if (!timeval_valid(&value->it_value) ||
+ !timeval_valid(&value->it_interval))
+ return -EINVAL;
switch (which) {
case ITIMER_REAL:
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 5a0de84..f1bda23 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -214,8 +214,10 @@ static unsigned long get_symbol_pos(unsigned long addr,
symbol_end = (unsigned long)_etext;
}
- *symbolsize = symbol_end - symbol_start;
- *offset = addr - symbol_start;
+ if (symbolsize)
+ *symbolsize = symbol_end - symbol_start;
+ if (offset)
+ *offset = addr - symbol_start;
return low;
}
@@ -267,6 +269,42 @@ const char *kallsyms_lookup(unsigned long addr,
return NULL;
}
+int lookup_symbol_name(unsigned long addr, char *symname)
+{
+ symname[0] = '\0';
+ symname[KSYM_NAME_LEN] = '\0';
+
+ if (is_ksym_addr(addr)) {
+ unsigned long pos;
+
+ pos = get_symbol_pos(addr, NULL, NULL);
+ /* Grab name */
+ kallsyms_expand_symbol(get_symbol_offset(pos), symname);
+ return 0;
+ }
+ /* see if it's in a module */
+ return lookup_module_symbol_name(addr, symname);
+}
+
+int lookup_symbol_attrs(unsigned long addr, unsigned long *size,
+ unsigned long *offset, char *modname, char *name)
+{
+ name[0] = '\0';
+ name[KSYM_NAME_LEN] = '\0';
+
+ if (is_ksym_addr(addr)) {
+ unsigned long pos;
+
+ pos = get_symbol_pos(addr, size, offset);
+ /* Grab name */
+ kallsyms_expand_symbol(get_symbol_offset(pos), name);
+ modname[0] = '\0';
+ return 0;
+ }
+ /* see if it's in a module */
+ return lookup_module_symbol_attrs(addr, size, offset, modname, name);
+}
+
/* Look up a kernel symbol and return it in a text buffer. */
int sprint_symbol(char *buffer, unsigned long address)
{
@@ -301,25 +339,20 @@ void __print_symbol(const char *fmt, unsigned long address)
struct kallsym_iter
{
loff_t pos;
- struct module *owner;
unsigned long value;
unsigned int nameoff; /* If iterating in core kernel symbols */
char type;
char name[KSYM_NAME_LEN+1];
+ char module_name[MODULE_NAME_LEN + 1];
+ int exported;
};
static int get_ksymbol_mod(struct kallsym_iter *iter)
{
- iter->owner = module_get_kallsym(iter->pos - kallsyms_num_syms,
- &iter->value, &iter->type,
- iter->name, sizeof(iter->name));
- if (iter->owner == NULL)
+ if (module_get_kallsym(iter->pos - kallsyms_num_syms, &iter->value,
+ &iter->type, iter->name, iter->module_name,
+ &iter->exported) < 0)
return 0;
-
- /* Label it "global" if it is exported, "local" if not exported. */
- iter->type = is_exported(iter->name, iter->owner)
- ? toupper(iter->type) : tolower(iter->type);
-
return 1;
}
@@ -328,7 +361,7 @@ static unsigned long get_ksymbol_core(struct kallsym_iter *iter)
{
unsigned off = iter->nameoff;
- iter->owner = NULL;
+ iter->module_name[0] = '\0';
iter->value = kallsyms_addresses[iter->pos];
iter->type = kallsyms_get_symbol_type(off);
@@ -392,12 +425,17 @@ static int s_show(struct seq_file *m, void *p)
if (!iter->name[0])
return 0;
- if (iter->owner)
+ if (iter->module_name[0]) {
+ char type;
+
+ /* Label it "global" if it is exported,
+ * "local" if not exported. */
+ type = iter->exported ? toupper(iter->type) :
+ tolower(iter->type);
seq_printf(m, "%0*lx %c %s\t[%s]\n",
(int)(2*sizeof(void*)),
- iter->value, iter->type, iter->name,
- module_name(iter->owner));
- else
+ iter->value, type, iter->name, iter->module_name);
+ } else
seq_printf(m, "%0*lx %c %s\n",
(int)(2*sizeof(void*)),
iter->value, iter->type, iter->name);
@@ -432,18 +470,11 @@ static int kallsyms_open(struct inode *inode, struct file *file)
return ret;
}
-static int kallsyms_release(struct inode *inode, struct file *file)
-{
- struct seq_file *m = (struct seq_file *)file->private_data;
- kfree(m->private);
- return seq_release(inode, file);
-}
-
static const struct file_operations kallsyms_operations = {
.open = kallsyms_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = kallsyms_release,
+ .release = seq_release_private,
};
static int __init kallsyms_init(void)
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 2a59c8a..25db14b 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1118,8 +1118,8 @@ void crash_save_cpu(struct pt_regs *regs, int cpu)
memset(&prstatus, 0, sizeof(prstatus));
prstatus.pr_pid = current->pid;
elf_core_copy_regs(&prstatus.pr_reg, regs);
- buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
- sizeof(prstatus));
+ buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
+ &prstatus, sizeof(prstatus));
final_note(buf);
}
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 7962761..49cc4b9 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -23,7 +23,6 @@
#include <linux/syscalls.h>
#include <linux/unistd.h>
#include <linux/kmod.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/mnt_namespace.h>
#include <linux/completion.h>
@@ -166,6 +165,12 @@ static int ____call_usermodehelper(void *data)
/* We can run anywhere, unlike our parent keventd(). */
set_cpus_allowed(current, CPU_MASK_ALL);
+ /*
+ * Our parent is keventd, which runs with elevated scheduling priority.
+ * Avoid propagating that into the userspace child.
+ */
+ set_user_nice(current, 0);
+
retval = -EPERM;
if (current->fs->root)
retval = kernel_execve(sub_info->path,
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index d25a9ad..9e47d8c 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -35,16 +35,19 @@
#include <linux/hash.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/stddef.h>
#include <linux/module.h>
#include <linux/moduleloader.h>
#include <linux/kallsyms.h>
#include <linux/freezer.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
+#include <linux/kdebug.h>
+
#include <asm-generic/sections.h>
#include <asm/cacheflush.h>
#include <asm/errno.h>
-#include <asm/kdebug.h>
+#include <asm/uaccess.h>
#define KPROBE_HASH_BITS 6
#define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS)
@@ -63,6 +66,9 @@ static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
static atomic_t kprobe_count;
+/* NOTE: change this value only with kprobe_mutex held */
+static bool kprobe_enabled;
+
DEFINE_MUTEX(kprobe_mutex); /* Protects kprobe_table */
DEFINE_SPINLOCK(kretprobe_lock); /* Protects kretprobe_inst_table */
static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
@@ -132,9 +138,8 @@ kprobe_opcode_t __kprobes *get_insn_slot(void)
struct kprobe_insn_page *kip;
struct hlist_node *pos;
- retry:
- hlist_for_each(pos, &kprobe_insn_pages) {
- kip = hlist_entry(pos, struct kprobe_insn_page, hlist);
+ retry:
+ hlist_for_each_entry(kip, pos, &kprobe_insn_pages, hlist) {
if (kip->nused < INSNS_PER_PAGE) {
int i;
for (i = 0; i < INSNS_PER_PAGE; i++) {
@@ -155,9 +160,8 @@ kprobe_opcode_t __kprobes *get_insn_slot(void)
}
/* All out of space. Need to allocate a new page. Use slot 0. */
kip = kmalloc(sizeof(struct kprobe_insn_page), GFP_KERNEL);
- if (!kip) {
+ if (!kip)
return NULL;
- }
/*
* Use module_alloc so this page is within +/- 2GB of where the
@@ -213,9 +217,8 @@ static int __kprobes collect_garbage_slots(void)
if (check_safety() != 0)
return -EAGAIN;
- hlist_for_each_safe(pos, next, &kprobe_insn_pages) {
+ hlist_for_each_entry_safe(kip, pos, next, &kprobe_insn_pages, hlist) {
int i;
- kip = hlist_entry(pos, struct kprobe_insn_page, hlist);
if (kip->ngarbage == 0)
continue;
kip->ngarbage = 0; /* we will collect all garbages */
@@ -234,8 +237,7 @@ void __kprobes free_insn_slot(kprobe_opcode_t * slot, int dirty)
struct kprobe_insn_page *kip;
struct hlist_node *pos;
- hlist_for_each(pos, &kprobe_insn_pages) {
- kip = hlist_entry(pos, struct kprobe_insn_page, hlist);
+ hlist_for_each_entry(kip, pos, &kprobe_insn_pages, hlist) {
if (kip->insns <= slot &&
slot < kip->insns + (INSNS_PER_PAGE * MAX_INSN_SIZE)) {
int i = (slot - kip->insns) / MAX_INSN_SIZE;
@@ -248,9 +250,9 @@ void __kprobes free_insn_slot(kprobe_opcode_t * slot, int dirty)
break;
}
}
- if (dirty && (++kprobe_garbage_slots > INSNS_PER_PAGE)) {
+
+ if (dirty && ++kprobe_garbage_slots > INSNS_PER_PAGE)
collect_garbage_slots();
- }
}
#endif
@@ -316,7 +318,6 @@ static void __kprobes aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
reset_kprobe_instance();
}
}
- return;
}
static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
@@ -362,46 +363,6 @@ void __kprobes kprobes_inc_nmissed_count(struct kprobe *p)
}
/* Called with kretprobe_lock held */
-struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)
-{
- struct hlist_node *node;
- struct kretprobe_instance *ri;
- hlist_for_each_entry(ri, node, &rp->free_instances, uflist)
- return ri;
- return NULL;
-}
-
-/* Called with kretprobe_lock held */
-static struct kretprobe_instance __kprobes *get_used_rp_inst(struct kretprobe
- *rp)
-{
- struct hlist_node *node;
- struct kretprobe_instance *ri;
- hlist_for_each_entry(ri, node, &rp->used_instances, uflist)
- return ri;
- return NULL;
-}
-
-/* Called with kretprobe_lock held */
-void __kprobes add_rp_inst(struct kretprobe_instance *ri)
-{
- /*
- * Remove rp inst off the free list -
- * Add it back when probed function returns
- */
- hlist_del(&ri->uflist);
-
- /* Add rp inst onto table */
- INIT_HLIST_NODE(&ri->hlist);
- hlist_add_head(&ri->hlist,
- &kretprobe_inst_table[hash_ptr(ri->task, KPROBE_HASH_BITS)]);
-
- /* Also add this rp inst to the used list. */
- INIT_HLIST_NODE(&ri->uflist);
- hlist_add_head(&ri->uflist, &ri->rp->used_instances);
-}
-
-/* Called with kretprobe_lock held */
void __kprobes recycle_rp_inst(struct kretprobe_instance *ri,
struct hlist_head *head)
{
@@ -454,7 +415,9 @@ void __kprobes kprobe_flush_task(struct task_struct *tk)
static inline void free_rp_inst(struct kretprobe *rp)
{
struct kretprobe_instance *ri;
- while ((ri = get_free_rp_inst(rp)) != NULL) {
+ struct hlist_node *pos, *next;
+
+ hlist_for_each_entry_safe(ri, pos, next, &rp->free_instances, uflist) {
hlist_del(&ri->uflist);
kfree(ri);
}
@@ -535,8 +498,8 @@ static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
static int __kprobes in_kprobes_functions(unsigned long addr)
{
- if (addr >= (unsigned long)__kprobes_text_start
- && addr < (unsigned long)__kprobes_text_end)
+ if (addr >= (unsigned long)__kprobes_text_start &&
+ addr < (unsigned long)__kprobes_text_end)
return -EINVAL;
return 0;
}
@@ -563,19 +526,24 @@ static int __kprobes __register_kprobe(struct kprobe *p,
return -EINVAL;
p->addr = (kprobe_opcode_t *)(((char *)p->addr)+ p->offset);
- if ((!kernel_text_address((unsigned long) p->addr)) ||
- in_kprobes_functions((unsigned long) p->addr))
+ if (!kernel_text_address((unsigned long) p->addr) ||
+ in_kprobes_functions((unsigned long) p->addr))
return -EINVAL;
p->mod_refcounted = 0;
- /* Check are we probing a module */
- if ((probed_mod = module_text_address((unsigned long) p->addr))) {
+
+ /*
+ * Check if are we probing a module.
+ */
+ probed_mod = module_text_address((unsigned long) p->addr);
+ if (probed_mod) {
struct module *calling_mod = module_text_address(called_from);
- /* We must allow modules to probe themself and
- * in this case avoid incrementing the module refcount,
- * so as to allow unloading of self probing modules.
+ /*
+ * We must allow modules to probe themself and in this case
+ * avoid incrementing the module refcount, so as to allow
+ * unloading of self probing modules.
*/
- if (calling_mod && (calling_mod != probed_mod)) {
+ if (calling_mod && calling_mod != probed_mod) {
if (unlikely(!try_module_get(probed_mod)))
return -EINVAL;
p->mod_refcounted = 1;
@@ -593,19 +561,21 @@ static int __kprobes __register_kprobe(struct kprobe *p,
goto out;
}
- if ((ret = arch_prepare_kprobe(p)) != 0)
+ ret = arch_prepare_kprobe(p);
+ if (ret)
goto out;
INIT_HLIST_NODE(&p->hlist);
hlist_add_head_rcu(&p->hlist,
&kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
- if (atomic_add_return(1, &kprobe_count) == \
+ if (kprobe_enabled) {
+ if (atomic_add_return(1, &kprobe_count) == \
(ARCH_INACTIVE_KPROBE_COUNT + 1))
- register_page_fault_notifier(&kprobe_page_fault_nb);
-
- arch_arm_kprobe(p);
+ register_page_fault_notifier(&kprobe_page_fault_nb);
+ arch_arm_kprobe(p);
+ }
out:
mutex_unlock(&kprobe_mutex);
@@ -616,8 +586,7 @@ out:
int __kprobes register_kprobe(struct kprobe *p)
{
- return __register_kprobe(p,
- (unsigned long)__builtin_return_address(0));
+ return __register_kprobe(p, (unsigned long)__builtin_return_address(0));
}
void __kprobes unregister_kprobe(struct kprobe *p)
@@ -641,11 +610,16 @@ void __kprobes unregister_kprobe(struct kprobe *p)
return;
}
valid_p:
- if ((old_p == p) || ((old_p->pre_handler == aggr_pre_handler) &&
- (p->list.next == &old_p->list) &&
- (p->list.prev == &old_p->list))) {
- /* Only probe on the hash list */
- arch_disarm_kprobe(p);
+ if (old_p == p ||
+ (old_p->pre_handler == aggr_pre_handler &&
+ p->list.next == &old_p->list && p->list.prev == &old_p->list)) {
+ /*
+ * Only probe on the hash list. Disarm only if kprobes are
+ * enabled - otherwise, the breakpoint would already have
+ * been removed. We save on flushing icache.
+ */
+ if (kprobe_enabled)
+ arch_disarm_kprobe(p);
hlist_del_rcu(&old_p->hlist);
cleanup_p = 1;
} else {
@@ -656,9 +630,11 @@ valid_p:
mutex_unlock(&kprobe_mutex);
synchronize_sched();
- if (p->mod_refcounted &&
- (mod = module_text_address((unsigned long)p->addr)))
- module_put(mod);
+ if (p->mod_refcounted) {
+ mod = module_text_address((unsigned long)p->addr);
+ if (mod)
+ module_put(mod);
+ }
if (cleanup_p) {
if (p != old_p) {
@@ -729,7 +705,21 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p,
/*TODO: consider to only swap the RA after the last pre_handler fired */
spin_lock_irqsave(&kretprobe_lock, flags);
- arch_prepare_kretprobe(rp, regs);
+ if (!hlist_empty(&rp->free_instances)) {
+ struct kretprobe_instance *ri;
+
+ ri = hlist_entry(rp->free_instances.first,
+ struct kretprobe_instance, uflist);
+ ri->rp = rp;
+ ri->task = current;
+ arch_prepare_kretprobe(ri, regs);
+
+ /* XXX(hch): why is there no hlist_move_head? */
+ hlist_del(&ri->uflist);
+ hlist_add_head(&ri->uflist, &ri->rp->used_instances);
+ hlist_add_head(&ri->hlist, kretprobe_inst_table_head(ri->task));
+ } else
+ rp->nmissed++;
spin_unlock_irqrestore(&kretprobe_lock, flags);
return 0;
}
@@ -792,11 +782,13 @@ void __kprobes unregister_kretprobe(struct kretprobe *rp)
{
unsigned long flags;
struct kretprobe_instance *ri;
+ struct hlist_node *pos, *next;
unregister_kprobe(&rp->kp);
+
/* No race here */
spin_lock_irqsave(&kretprobe_lock, flags);
- while ((ri = get_used_rp_inst(rp)) != NULL) {
+ hlist_for_each_entry_safe(ri, pos, next, &rp->used_instances, uflist) {
ri->rp = NULL;
hlist_del(&ri->uflist);
}
@@ -816,6 +808,9 @@ static int __init init_kprobes(void)
}
atomic_set(&kprobe_count, 0);
+ /* By default, kprobes are enabled */
+ kprobe_enabled = true;
+
err = arch_init_kprobes();
if (!err)
err = register_die_notifier(&kprobe_exceptions_nb);
@@ -825,7 +820,7 @@ static int __init init_kprobes(void)
#ifdef CONFIG_DEBUG_FS
static void __kprobes report_probe(struct seq_file *pi, struct kprobe *p,
- const char *sym, int offset,char *modname)
+ const char *sym, int offset,char *modname)
{
char *kprobe_type;
@@ -867,13 +862,13 @@ static int __kprobes show_kprobe_addr(struct seq_file *pi, void *v)
struct kprobe *p, *kp;
const char *sym = NULL;
unsigned int i = *(loff_t *) v;
- unsigned long size, offset = 0;
+ unsigned long offset = 0;
char *modname, namebuf[128];
head = &kprobe_table[i];
preempt_disable();
hlist_for_each_entry_rcu(p, node, head, hlist) {
- sym = kallsyms_lookup((unsigned long)p->addr, &size,
+ sym = kallsyms_lookup((unsigned long)p->addr, NULL,
&offset, &modname, namebuf);
if (p->pre_handler == aggr_pre_handler) {
list_for_each_entry_rcu(kp, &p->list, list)
@@ -904,21 +899,149 @@ static struct file_operations debugfs_kprobes_operations = {
.release = seq_release,
};
+static void __kprobes enable_all_kprobes(void)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct kprobe *p;
+ unsigned int i;
+
+ mutex_lock(&kprobe_mutex);
+
+ /* If kprobes are already enabled, just return */
+ if (kprobe_enabled)
+ goto already_enabled;
+
+ /*
+ * Re-register the page fault notifier only if there are any
+ * active probes at the time of enabling kprobes globally
+ */
+ if (atomic_read(&kprobe_count) > ARCH_INACTIVE_KPROBE_COUNT)
+ register_page_fault_notifier(&kprobe_page_fault_nb);
+
+ for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
+ head = &kprobe_table[i];
+ hlist_for_each_entry_rcu(p, node, head, hlist)
+ arch_arm_kprobe(p);
+ }
+
+ kprobe_enabled = true;
+ printk(KERN_INFO "Kprobes globally enabled\n");
+
+already_enabled:
+ mutex_unlock(&kprobe_mutex);
+ return;
+}
+
+static void __kprobes disable_all_kprobes(void)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct kprobe *p;
+ unsigned int i;
+
+ mutex_lock(&kprobe_mutex);
+
+ /* If kprobes are already disabled, just return */
+ if (!kprobe_enabled)
+ goto already_disabled;
+
+ kprobe_enabled = false;
+ printk(KERN_INFO "Kprobes globally disabled\n");
+ for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
+ head = &kprobe_table[i];
+ hlist_for_each_entry_rcu(p, node, head, hlist) {
+ if (!arch_trampoline_kprobe(p))
+ arch_disarm_kprobe(p);
+ }
+ }
+
+ mutex_unlock(&kprobe_mutex);
+ /* Allow all currently running kprobes to complete */
+ synchronize_sched();
+
+ mutex_lock(&kprobe_mutex);
+ /* Unconditionally unregister the page_fault notifier */
+ unregister_page_fault_notifier(&kprobe_page_fault_nb);
+
+already_disabled:
+ mutex_unlock(&kprobe_mutex);
+ return;
+}
+
+/*
+ * XXX: The debugfs bool file interface doesn't allow for callbacks
+ * when the bool state is switched. We can reuse that facility when
+ * available
+ */
+static ssize_t read_enabled_file_bool(struct file *file,
+ char __user *user_buf, size_t count, loff_t *ppos)
+{
+ char buf[3];
+
+ if (kprobe_enabled)
+ buf[0] = '1';
+ else
+ buf[0] = '0';
+ buf[1] = '\n';
+ buf[2] = 0x00;
+ return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
+}
+
+static ssize_t write_enabled_file_bool(struct file *file,
+ const char __user *user_buf, size_t count, loff_t *ppos)
+{
+ char buf[32];
+ int buf_size;
+
+ buf_size = min(count, (sizeof(buf)-1));
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+
+ switch (buf[0]) {
+ case 'y':
+ case 'Y':
+ case '1':
+ enable_all_kprobes();
+ break;
+ case 'n':
+ case 'N':
+ case '0':
+ disable_all_kprobes();
+ break;
+ }
+
+ return count;
+}
+
+static struct file_operations fops_kp = {
+ .read = read_enabled_file_bool,
+ .write = write_enabled_file_bool,
+};
+
static int __kprobes debugfs_kprobe_init(void)
{
struct dentry *dir, *file;
+ unsigned int value = 1;
dir = debugfs_create_dir("kprobes", NULL);
if (!dir)
return -ENOMEM;
- file = debugfs_create_file("list", 0444, dir , 0 ,
+ file = debugfs_create_file("list", 0444, dir, NULL,
&debugfs_kprobes_operations);
if (!file) {
debugfs_remove(dir);
return -ENOMEM;
}
+ file = debugfs_create_file("enabled", 0600, dir,
+ &value, &fops_kp);
+ if (!file) {
+ debugfs_remove(dir);
+ return -ENOMEM;
+ }
+
return 0;
}
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 7065a68..1a5ff22 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -257,9 +257,8 @@ static int save_trace(struct stack_trace *trace)
trace->entries = stack_trace + nr_stack_trace_entries;
trace->skip = 3;
- trace->all_contexts = 0;
- save_stack_trace(trace, NULL);
+ save_stack_trace(trace);
trace->max_entries = trace->nr_entries;
@@ -341,10 +340,7 @@ static const char *usage_str[] =
const char * __get_key_name(struct lockdep_subclass_key *key, char *str)
{
- unsigned long offs, size;
- char *modname;
-
- return kallsyms_lookup((unsigned long)key, &size, &offs, &modname, str);
+ return kallsyms_lookup((unsigned long)key, NULL, NULL, NULL, str);
}
void
@@ -1313,8 +1309,9 @@ out_unlock_set:
/*
* Look up a dependency chain. If the key is not present yet then
- * add it and return 0 - in this case the new dependency chain is
- * validated. If the key is already hashed, return 1.
+ * add it and return 1 - in this case the new dependency chain is
+ * validated. If the key is already hashed, return 0.
+ * (On return with 1 graph_lock is held.)
*/
static inline int lookup_chain_cache(u64 chain_key, struct lock_class *class)
{
@@ -1577,7 +1574,7 @@ valid_state(struct task_struct *curr, struct held_lock *this,
* Mark a lock with a usage bit, and validate the state transition:
*/
static int mark_lock(struct task_struct *curr, struct held_lock *this,
- enum lock_usage_bit new_bit, unsigned long ip)
+ enum lock_usage_bit new_bit)
{
unsigned int new_mask = 1 << new_bit, ret = 1;
@@ -1600,14 +1597,6 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this,
this->class->usage_mask |= new_mask;
-#ifdef CONFIG_TRACE_IRQFLAGS
- if (new_bit == LOCK_ENABLED_HARDIRQS ||
- new_bit == LOCK_ENABLED_HARDIRQS_READ)
- ip = curr->hardirq_enable_ip;
- else if (new_bit == LOCK_ENABLED_SOFTIRQS ||
- new_bit == LOCK_ENABLED_SOFTIRQS_READ)
- ip = curr->softirq_enable_ip;
-#endif
if (!save_trace(this->class->usage_traces + new_bit))
return 0;
@@ -1806,7 +1795,7 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this,
* Mark all held locks with a usage bit:
*/
static int
-mark_held_locks(struct task_struct *curr, int hardirq, unsigned long ip)
+mark_held_locks(struct task_struct *curr, int hardirq)
{
enum lock_usage_bit usage_bit;
struct held_lock *hlock;
@@ -1826,7 +1815,7 @@ mark_held_locks(struct task_struct *curr, int hardirq, unsigned long ip)
else
usage_bit = LOCK_ENABLED_SOFTIRQS;
}
- if (!mark_lock(curr, hlock, usage_bit, ip))
+ if (!mark_lock(curr, hlock, usage_bit))
return 0;
}
@@ -1879,7 +1868,7 @@ void trace_hardirqs_on(void)
* We are going to turn hardirqs on, so set the
* usage bit for all held locks:
*/
- if (!mark_held_locks(curr, 1, ip))
+ if (!mark_held_locks(curr, 1))
return;
/*
* If we have softirqs enabled, then set the usage
@@ -1887,7 +1876,7 @@ void trace_hardirqs_on(void)
* this bit from being set before)
*/
if (curr->softirqs_enabled)
- if (!mark_held_locks(curr, 0, ip))
+ if (!mark_held_locks(curr, 0))
return;
curr->hardirq_enable_ip = ip;
@@ -1955,7 +1944,7 @@ void trace_softirqs_on(unsigned long ip)
* enabled too:
*/
if (curr->hardirqs_enabled)
- mark_held_locks(curr, 0, ip);
+ mark_held_locks(curr, 0);
}
/*
@@ -2093,43 +2082,43 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
if (read) {
if (curr->hardirq_context)
if (!mark_lock(curr, hlock,
- LOCK_USED_IN_HARDIRQ_READ, ip))
+ LOCK_USED_IN_HARDIRQ_READ))
return 0;
if (curr->softirq_context)
if (!mark_lock(curr, hlock,
- LOCK_USED_IN_SOFTIRQ_READ, ip))
+ LOCK_USED_IN_SOFTIRQ_READ))
return 0;
} else {
if (curr->hardirq_context)
- if (!mark_lock(curr, hlock, LOCK_USED_IN_HARDIRQ, ip))
+ if (!mark_lock(curr, hlock, LOCK_USED_IN_HARDIRQ))
return 0;
if (curr->softirq_context)
- if (!mark_lock(curr, hlock, LOCK_USED_IN_SOFTIRQ, ip))
+ if (!mark_lock(curr, hlock, LOCK_USED_IN_SOFTIRQ))
return 0;
}
}
if (!hardirqs_off) {
if (read) {
if (!mark_lock(curr, hlock,
- LOCK_ENABLED_HARDIRQS_READ, ip))
+ LOCK_ENABLED_HARDIRQS_READ))
return 0;
if (curr->softirqs_enabled)
if (!mark_lock(curr, hlock,
- LOCK_ENABLED_SOFTIRQS_READ, ip))
+ LOCK_ENABLED_SOFTIRQS_READ))
return 0;
} else {
if (!mark_lock(curr, hlock,
- LOCK_ENABLED_HARDIRQS, ip))
+ LOCK_ENABLED_HARDIRQS))
return 0;
if (curr->softirqs_enabled)
if (!mark_lock(curr, hlock,
- LOCK_ENABLED_SOFTIRQS, ip))
+ LOCK_ENABLED_SOFTIRQS))
return 0;
}
}
#endif
/* mark it as used: */
- if (!mark_lock(curr, hlock, LOCK_USED, ip))
+ if (!mark_lock(curr, hlock, LOCK_USED))
return 0;
out_calc_hash:
/*
diff --git a/kernel/module.c b/kernel/module.c
index 1eb8ca5..d36e454 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/moduleloader.h>
#include <linux/init.h>
+#include <linux/kallsyms.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
@@ -310,14 +311,14 @@ static int split_block(unsigned int i, unsigned short size)
{
/* Reallocation required? */
if (pcpu_num_used + 1 > pcpu_num_allocated) {
- int *new = kmalloc(sizeof(new[0]) * pcpu_num_allocated*2,
- GFP_KERNEL);
+ int *new;
+
+ new = krealloc(pcpu_size, sizeof(new[0])*pcpu_num_allocated*2,
+ GFP_KERNEL);
if (!new)
return 0;
- memcpy(new, pcpu_size, sizeof(new[0])*pcpu_num_allocated);
pcpu_num_allocated *= 2;
- kfree(pcpu_size);
pcpu_size = new;
}
@@ -1471,7 +1472,7 @@ static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
}
#ifdef CONFIG_KALLSYMS
-int is_exported(const char *name, const struct module *mod)
+static int is_exported(const char *name, const struct module *mod)
{
if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab))
return 1;
@@ -2097,8 +2098,10 @@ static const char *get_ksymbol(struct module *mod,
if (!best)
return NULL;
- *size = nextval - mod->symtab[best].st_value;
- *offset = addr - mod->symtab[best].st_value;
+ if (size)
+ *size = nextval - mod->symtab[best].st_value;
+ if (offset)
+ *offset = addr - mod->symtab[best].st_value;
return mod->strtab + mod->symtab[best].st_name;
}
@@ -2123,8 +2126,58 @@ const char *module_address_lookup(unsigned long addr,
return NULL;
}
-struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
- char *type, char *name, size_t namelen)
+int lookup_module_symbol_name(unsigned long addr, char *symname)
+{
+ struct module *mod;
+
+ mutex_lock(&module_mutex);
+ list_for_each_entry(mod, &modules, list) {
+ if (within(addr, mod->module_init, mod->init_size) ||
+ within(addr, mod->module_core, mod->core_size)) {
+ const char *sym;
+
+ sym = get_ksymbol(mod, addr, NULL, NULL);
+ if (!sym)
+ goto out;
+ strlcpy(symname, sym, KSYM_NAME_LEN + 1);
+ mutex_unlock(&module_mutex);
+ return 0;
+ }
+ }
+out:
+ mutex_unlock(&module_mutex);
+ return -ERANGE;
+}
+
+int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
+ unsigned long *offset, char *modname, char *name)
+{
+ struct module *mod;
+
+ mutex_lock(&module_mutex);
+ list_for_each_entry(mod, &modules, list) {
+ if (within(addr, mod->module_init, mod->init_size) ||
+ within(addr, mod->module_core, mod->core_size)) {
+ const char *sym;
+
+ sym = get_ksymbol(mod, addr, size, offset);
+ if (!sym)
+ goto out;
+ if (modname)
+ strlcpy(modname, mod->name, MODULE_NAME_LEN + 1);
+ if (name)
+ strlcpy(name, sym, KSYM_NAME_LEN + 1);
+ mutex_unlock(&module_mutex);
+ return 0;
+ }
+ }
+out:
+ mutex_unlock(&module_mutex);
+ return -ERANGE;
+}
+
+int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
+ char *name, char *module_name, int *exported)
{
struct module *mod;
@@ -2134,14 +2187,16 @@ struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
*value = mod->symtab[symnum].st_value;
*type = mod->symtab[symnum].st_info;
strlcpy(name, mod->strtab + mod->symtab[symnum].st_name,
- namelen);
+ KSYM_NAME_LEN + 1);
+ strlcpy(module_name, mod->name, MODULE_NAME_LEN + 1);
+ *exported = is_exported(name, mod);
mutex_unlock(&module_mutex);
- return mod;
+ return 0;
}
symnum -= mod->num_symtab;
}
mutex_unlock(&module_mutex);
- return NULL;
+ return -ERANGE;
}
static unsigned long mod_find_symname(struct module *mod, const char *name)
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index f5b9ee6..1bc4b55 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -38,10 +38,8 @@ void get_task_namespaces(struct task_struct *tsk)
/*
* creates a copy of "orig" with refcount 1.
- * This does not grab references to the contained namespaces,
- * so that needs to be done by dup_namespaces.
*/
-static inline struct nsproxy *clone_namespaces(struct nsproxy *orig)
+static inline struct nsproxy *clone_nsproxy(struct nsproxy *orig)
{
struct nsproxy *ns;
@@ -52,26 +50,49 @@ static inline struct nsproxy *clone_namespaces(struct nsproxy *orig)
}
/*
- * copies the nsproxy, setting refcount to 1, and grabbing a
- * reference to all contained namespaces. Called from
- * sys_unshare()
+ * Create new nsproxy and all of its the associated namespaces.
+ * Return the newly created nsproxy. Do not attach this to the task,
+ * leave it to the caller to do proper locking and attach it to task.
*/
-struct nsproxy *dup_namespaces(struct nsproxy *orig)
+static struct nsproxy *create_new_namespaces(int flags, struct task_struct *tsk,
+ struct fs_struct *new_fs)
{
- struct nsproxy *ns = clone_namespaces(orig);
+ struct nsproxy *new_nsp;
- if (ns) {
- if (ns->mnt_ns)
- get_mnt_ns(ns->mnt_ns);
- if (ns->uts_ns)
- get_uts_ns(ns->uts_ns);
- if (ns->ipc_ns)
- get_ipc_ns(ns->ipc_ns);
- if (ns->pid_ns)
- get_pid_ns(ns->pid_ns);
- }
+ new_nsp = clone_nsproxy(tsk->nsproxy);
+ if (!new_nsp)
+ return ERR_PTR(-ENOMEM);
- return ns;
+ new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, new_fs);
+ if (IS_ERR(new_nsp->mnt_ns))
+ goto out_ns;
+
+ new_nsp->uts_ns = copy_utsname(flags, tsk->nsproxy->uts_ns);
+ if (IS_ERR(new_nsp->uts_ns))
+ goto out_uts;
+
+ new_nsp->ipc_ns = copy_ipcs(flags, tsk->nsproxy->ipc_ns);
+ if (IS_ERR(new_nsp->ipc_ns))
+ goto out_ipc;
+
+ new_nsp->pid_ns = copy_pid_ns(flags, tsk->nsproxy->pid_ns);
+ if (IS_ERR(new_nsp->pid_ns))
+ goto out_pid;
+
+ return new_nsp;
+
+out_pid:
+ if (new_nsp->ipc_ns)
+ put_ipc_ns(new_nsp->ipc_ns);
+out_ipc:
+ if (new_nsp->uts_ns)
+ put_uts_ns(new_nsp->uts_ns);
+out_uts:
+ if (new_nsp->mnt_ns)
+ put_mnt_ns(new_nsp->mnt_ns);
+out_ns:
+ kfree(new_nsp);
+ return ERR_PTR(-ENOMEM);
}
/*
@@ -92,47 +113,21 @@ int copy_namespaces(int flags, struct task_struct *tsk)
if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC)))
return 0;
- new_ns = clone_namespaces(old_ns);
- if (!new_ns) {
- err = -ENOMEM;
+ if (!capable(CAP_SYS_ADMIN)) {
+ err = -EPERM;
goto out;
}
- tsk->nsproxy = new_ns;
-
- err = copy_mnt_ns(flags, tsk);
- if (err)
- goto out_ns;
-
- err = copy_utsname(flags, tsk);
- if (err)
- goto out_uts;
-
- err = copy_ipcs(flags, tsk);
- if (err)
- goto out_ipc;
-
- err = copy_pid_ns(flags, tsk);
- if (err)
- goto out_pid;
+ new_ns = create_new_namespaces(flags, tsk, tsk->fs);
+ if (IS_ERR(new_ns)) {
+ err = PTR_ERR(new_ns);
+ goto out;
+ }
+ tsk->nsproxy = new_ns;
out:
put_nsproxy(old_ns);
return err;
-
-out_pid:
- if (new_ns->ipc_ns)
- put_ipc_ns(new_ns->ipc_ns);
-out_ipc:
- if (new_ns->uts_ns)
- put_uts_ns(new_ns->uts_ns);
-out_uts:
- if (new_ns->mnt_ns)
- put_mnt_ns(new_ns->mnt_ns);
-out_ns:
- tsk->nsproxy = old_ns;
- kfree(new_ns);
- goto out;
}
void free_nsproxy(struct nsproxy *ns)
@@ -147,3 +142,41 @@ void free_nsproxy(struct nsproxy *ns)
put_pid_ns(ns->pid_ns);
kfree(ns);
}
+
+/*
+ * Called from unshare. Unshare all the namespaces part of nsproxy.
+ * On sucess, returns the new nsproxy and a reference to old nsproxy
+ * to make sure it stays around.
+ */
+int unshare_nsproxy_namespaces(unsigned long unshare_flags,
+ struct nsproxy **new_nsp, struct fs_struct *new_fs)
+{
+ struct nsproxy *old_ns = current->nsproxy;
+ int err = 0;
+
+ if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC)))
+ return 0;
+
+#ifndef CONFIG_IPC_NS
+ if (unshare_flags & CLONE_NEWIPC)
+ return -EINVAL;
+#endif
+
+#ifndef CONFIG_UTS_NS
+ if (unshare_flags & CLONE_NEWUTS)
+ return -EINVAL;
+#endif
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ get_nsproxy(old_ns);
+
+ *new_nsp = create_new_namespaces(unshare_flags, current,
+ new_fs ? new_fs : current->fs);
+ if (IS_ERR(*new_nsp)) {
+ err = PTR_ERR(*new_nsp);
+ put_nsproxy(old_ns);
+ }
+ return err;
+}
diff --git a/kernel/params.c b/kernel/params.c
index 3121723..e61c46c 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -269,7 +269,7 @@ int param_get_invbool(char *buffer, struct kernel_param *kp)
return param_get_bool(buffer, &dummy);
}
-/* We cheat here and temporarily mangle the string. */
+/* We break the rule and mangle the string. */
static int param_array(const char *name,
const char *val,
unsigned int min, unsigned int max,
diff --git a/kernel/pid.c b/kernel/pid.c
index 78f2aee..d3ad724 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -360,16 +360,11 @@ struct pid *find_ge_pid(int nr)
}
EXPORT_SYMBOL_GPL(find_get_pid);
-int copy_pid_ns(int flags, struct task_struct *tsk)
+struct pid_namespace *copy_pid_ns(int flags, struct pid_namespace *old_ns)
{
- struct pid_namespace *old_ns = tsk->nsproxy->pid_ns;
- int err = 0;
-
- if (!old_ns)
- return 0;
-
+ BUG_ON(!old_ns);
get_pid_ns(old_ns);
- return err;
+ return old_ns;
}
void free_pid_ns(struct kref *kref)
@@ -412,7 +407,5 @@ void __init pidmap_init(void)
set_bit(0, init_pid_ns.pidmap[0].page);
atomic_dec(&init_pid_ns.pidmap[0].nr_free);
- pid_cachep = kmem_cache_create("pid", sizeof(struct pid),
- __alignof__(struct pid),
- SLAB_PANIC, NULL, NULL);
+ pid_cachep = KMEM_CACHE(pid, SLAB_PANIC);
}
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 657f776..1de710e1 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -971,7 +971,7 @@ static void check_thread_timers(struct task_struct *tsk,
maxfire = 20;
tsk->it_prof_expires = cputime_zero;
while (!list_empty(timers)) {
- struct cpu_timer_list *t = list_entry(timers->next,
+ struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || cputime_lt(prof_ticks(tsk), t->expires.cpu)) {
@@ -986,7 +986,7 @@ static void check_thread_timers(struct task_struct *tsk,
maxfire = 20;
tsk->it_virt_expires = cputime_zero;
while (!list_empty(timers)) {
- struct cpu_timer_list *t = list_entry(timers->next,
+ struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || cputime_lt(virt_ticks(tsk), t->expires.cpu)) {
@@ -1001,7 +1001,7 @@ static void check_thread_timers(struct task_struct *tsk,
maxfire = 20;
tsk->it_sched_expires = 0;
while (!list_empty(timers)) {
- struct cpu_timer_list *t = list_entry(timers->next,
+ struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || tsk->sched_time < t->expires.sched) {
@@ -1057,7 +1057,7 @@ static void check_process_timers(struct task_struct *tsk,
maxfire = 20;
prof_expires = cputime_zero;
while (!list_empty(timers)) {
- struct cpu_timer_list *t = list_entry(timers->next,
+ struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || cputime_lt(ptime, t->expires.cpu)) {
@@ -1072,7 +1072,7 @@ static void check_process_timers(struct task_struct *tsk,
maxfire = 20;
virt_expires = cputime_zero;
while (!list_empty(timers)) {
- struct cpu_timer_list *t = list_entry(timers->next,
+ struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || cputime_lt(utime, t->expires.cpu)) {
@@ -1087,7 +1087,7 @@ static void check_process_timers(struct task_struct *tsk,
maxfire = 20;
sched_expires = 0;
while (!list_empty(timers)) {
- struct cpu_timer_list *t = list_entry(timers->next,
+ struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || sched_time < t->expires.sched) {
@@ -1400,7 +1400,7 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
*/
head = &tsk->signal->cpu_timers[clock_idx];
if (list_empty(head) ||
- cputime_ge(list_entry(head->next,
+ cputime_ge(list_first_entry(head,
struct cpu_timer_list, entry)->expires.cpu,
*newval)) {
/*
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 44318ca..588c99d 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -31,7 +31,6 @@
* POSIX clocks & timers
*/
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/time.h>
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 51a4dd0..495b7d4 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -78,17 +78,22 @@ config PM_SYSFS_DEPRECATED
are likely to be bus or driver specific.
config SOFTWARE_SUSPEND
- bool "Software Suspend"
- depends on PM && SWAP && ((X86 && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP))
+ bool "Software Suspend (Hibernation)"
+ depends on PM && SWAP && (((X86 || PPC64_SWSUSP) && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP))
---help---
- Enable the suspend to disk (STD) functionality.
+ Enable the suspend to disk (STD) functionality, which is usually
+ called "hibernation" in user interfaces. STD checkpoints the
+ system and powers it off; and restores that checkpoint on reboot.
You can suspend your machine with 'echo disk > /sys/power/state'.
Alternatively, you can use the additional userland tools available
from <http://suspend.sf.net>.
In principle it does not require ACPI or APM, although for example
- ACPI will be used if available.
+ ACPI will be used for the final steps when it is available. One
+ of the reasons to use software suspend is that the firmware hooks
+ for suspend states like suspend-to-RAM (STR) often don't work very
+ well with Linux.
It creates an image which is saved in your active swap. Upon the next
boot, pass the 'resume=/dev/swappartition' argument to the kernel to
@@ -134,7 +139,7 @@ config PM_STD_PARTITION
config SUSPEND_SMP
bool
- depends on HOTPLUG_CPU && X86 && PM
+ depends on HOTPLUG_CPU && (X86 || PPC64) && PM
default y
config APM_EMULATION
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 8df51c2..0633137 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -130,15 +130,25 @@ int pm_suspend_disk(void)
{
int error;
+ /* The snapshot device should not be opened while we're running */
+ if (!atomic_add_unless(&snapshot_device_available, -1, 0))
+ return -EBUSY;
+
+ /* Allocate memory management structures */
+ error = create_basic_memory_bitmaps();
+ if (error)
+ goto Exit;
+
error = prepare_processes();
if (error)
- return error;
+ goto Finish;
if (pm_disk_mode == PM_DISK_TESTPROC) {
printk("swsusp debug: Waiting for 5 seconds.\n");
mdelay(5000);
goto Thaw;
}
+
/* Free memory before shutting down devices. */
error = swsusp_shrink_memory();
if (error)
@@ -196,6 +206,10 @@ int pm_suspend_disk(void)
resume_console();
Thaw:
unprepare_processes();
+ Finish:
+ free_basic_memory_bitmaps();
+ Exit:
+ atomic_inc(&snapshot_device_available);
return error;
}
@@ -239,13 +253,21 @@ static int software_resume(void)
}
pr_debug("PM: Checking swsusp image.\n");
-
error = swsusp_check();
if (error)
- goto Done;
+ goto Unlock;
- pr_debug("PM: Preparing processes for restore.\n");
+ /* The snapshot device should not be opened while we're running */
+ if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
+ error = -EBUSY;
+ goto Unlock;
+ }
+ error = create_basic_memory_bitmaps();
+ if (error)
+ goto Finish;
+
+ pr_debug("PM: Preparing processes for restore.\n");
error = prepare_processes();
if (error) {
swsusp_close();
@@ -280,7 +302,11 @@ static int software_resume(void)
printk(KERN_ERR "PM: Restore failed, recovering.\n");
unprepare_processes();
Done:
+ free_basic_memory_bitmaps();
+ Finish:
+ atomic_inc(&snapshot_device_available);
/* For success case, the suspend path will release the lock */
+ Unlock:
mutex_unlock(&pm_mutex);
pr_debug("PM: Resume from disk failed.\n");
return 0;
@@ -324,7 +350,34 @@ static const char * const pm_disk_modes[] = {
static ssize_t disk_show(struct kset *kset, char *buf)
{
- return sprintf(buf, "%s\n", pm_disk_modes[pm_disk_mode]);
+ int i;
+ char *start = buf;
+
+ for (i = PM_DISK_PLATFORM; i < PM_DISK_MAX; i++) {
+ if (!pm_disk_modes[i])
+ continue;
+ switch (i) {
+ case PM_DISK_SHUTDOWN:
+ case PM_DISK_REBOOT:
+ case PM_DISK_TEST:
+ case PM_DISK_TESTPROC:
+ break;
+ default:
+ if (pm_ops && pm_ops->enter &&
+ (i == pm_ops->pm_disk_mode))
+ break;
+ /* not a valid mode, continue with loop */
+ continue;
+ }
+ if (i == pm_disk_mode)
+ buf += sprintf(buf, "[%s]", pm_disk_modes[i]);
+ else
+ buf += sprintf(buf, "%s", pm_disk_modes[i]);
+ if (i+1 != PM_DISK_MAX)
+ buf += sprintf(buf, " ");
+ }
+ buf += sprintf(buf, "\n");
+ return buf-start;
}
diff --git a/kernel/power/main.c b/kernel/power/main.c
index b21c2a5..f6dda68 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -184,17 +184,21 @@ static void suspend_finish(suspend_state_t state)
static const char * const pm_states[PM_SUSPEND_MAX] = {
[PM_SUSPEND_STANDBY] = "standby",
[PM_SUSPEND_MEM] = "mem",
-#ifdef CONFIG_SOFTWARE_SUSPEND
[PM_SUSPEND_DISK] = "disk",
-#endif
};
static inline int valid_state(suspend_state_t state)
{
/* Suspend-to-disk does not really need low-level support.
- * It can work with reboot if needed. */
+ * It can work with shutdown/reboot if needed. If it isn't
+ * configured, then it cannot be supported.
+ */
if (state == PM_SUSPEND_DISK)
+#ifdef CONFIG_SOFTWARE_SUSPEND
return 1;
+#else
+ return 0;
+#endif
/* all other states need lowlevel support and need to be
* valid to the lowlevel implementation, no valid callback
@@ -244,15 +248,6 @@ static int enter_state(suspend_state_t state)
return error;
}
-/*
- * This is main interface to the outside world. It needs to be
- * called from process context.
- */
-int software_suspend(void)
-{
- return enter_state(PM_SUSPEND_DISK);
-}
-
/**
* pm_suspend - Externally visible function for suspending system.
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 33bd94c..34b4354 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -14,8 +14,18 @@ struct swsusp_info {
#ifdef CONFIG_SOFTWARE_SUSPEND
-extern int pm_suspend_disk(void);
+/*
+ * Keep some memory free so that I/O operations can succeed without paging
+ * [Might this be more than 4 MB?]
+ */
+#define PAGES_FOR_IO ((4096 * 1024) >> PAGE_SHIFT)
+/*
+ * Keep 1 MB of memory free so that device drivers can allocate some pages in
+ * their .suspend() routines without breaking the suspend to disk.
+ */
+#define SPARE_PAGES ((1024 * 1024) >> PAGE_SHIFT)
+extern int pm_suspend_disk(void);
#else
static inline int pm_suspend_disk(void)
{
@@ -48,6 +58,8 @@ extern sector_t swsusp_resume_block;
extern asmlinkage int swsusp_arch_suspend(void);
extern asmlinkage int swsusp_arch_resume(void);
+extern int create_basic_memory_bitmaps(void);
+extern void free_basic_memory_bitmaps(void);
extern unsigned int count_data_pages(void);
/**
@@ -138,30 +150,12 @@ struct resume_swap_area {
#define PMOPS_ENTER 2
#define PMOPS_FINISH 3
-/**
- * The bitmap is used for tracing allocated swap pages
- *
- * The entire bitmap consists of a number of bitmap_page
- * structures linked with the help of the .next member.
- * Thus each page can be allocated individually, so we only
- * need to make 0-order memory allocations to create
- * the bitmap.
- */
-
-#define BITMAP_PAGE_SIZE (PAGE_SIZE - sizeof(void *))
-#define BITMAP_PAGE_CHUNKS (BITMAP_PAGE_SIZE / sizeof(long))
-#define BITS_PER_CHUNK (sizeof(long) * 8)
-#define BITMAP_PAGE_BITS (BITMAP_PAGE_CHUNKS * BITS_PER_CHUNK)
-
-struct bitmap_page {
- unsigned long chunks[BITMAP_PAGE_CHUNKS];
- struct bitmap_page *next;
-};
+/* If unset, the snapshot device cannot be open. */
+extern atomic_t snapshot_device_available;
-extern void free_bitmap(struct bitmap_page *bitmap);
-extern struct bitmap_page *alloc_bitmap(unsigned int nr_bits);
-extern sector_t alloc_swapdev_block(int swap, struct bitmap_page *bitmap);
-extern void free_all_swap_pages(int swap, struct bitmap_page *bitmap);
+extern sector_t alloc_swapdev_block(int swap);
+extern void free_all_swap_pages(int swap);
+extern int swsusp_swap_in_use(void);
extern int swsusp_check(void);
extern int swsusp_shrink_memory(void);
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 6d566bf..0884193 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -8,7 +8,6 @@
#undef DEBUG
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/suspend.h>
#include <linux/module.h>
@@ -25,10 +24,9 @@
static inline int freezeable(struct task_struct * p)
{
- if ((p == current) ||
+ if ((p == current) ||
(p->flags & PF_NOFREEZE) ||
- (p->exit_state == EXIT_ZOMBIE) ||
- (p->exit_state == EXIT_DEAD))
+ (p->exit_state != 0))
return 0;
return 1;
}
@@ -47,8 +45,10 @@ void refrigerator(void)
recalc_sigpending(); /* We sent fake signal, clean it up */
spin_unlock_irq(&current->sighand->siglock);
- while (frozen(current)) {
- current->state = TASK_UNINTERRUPTIBLE;
+ for (;;) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ if (!frozen(current))
+ break;
schedule();
}
pr_debug("%s left refrigerator\n", current->comm);
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 704c25a..b703977 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -14,13 +14,13 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/suspend.h>
-#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/bitops.h>
#include <linux/spinlock.h>
#include <linux/kernel.h>
#include <linux/pm.h>
#include <linux/device.h>
+#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/syscalls.h>
#include <linux/console.h>
@@ -34,6 +34,10 @@
#include "power.h"
+static int swsusp_page_is_free(struct page *);
+static void swsusp_set_page_forbidden(struct page *);
+static void swsusp_unset_page_forbidden(struct page *);
+
/* List of PBEs needed for restoring the pages that were allocated before
* the suspend and included in the suspend image, but have also been
* allocated by the "resume" kernel, so their contents cannot be written
@@ -67,15 +71,15 @@ static void *get_image_page(gfp_t gfp_mask, int safe_needed)
res = (void *)get_zeroed_page(gfp_mask);
if (safe_needed)
- while (res && PageNosaveFree(virt_to_page(res))) {
+ while (res && swsusp_page_is_free(virt_to_page(res))) {
/* The page is unsafe, mark it for swsusp_free() */
- SetPageNosave(virt_to_page(res));
+ swsusp_set_page_forbidden(virt_to_page(res));
allocated_unsafe_pages++;
res = (void *)get_zeroed_page(gfp_mask);
}
if (res) {
- SetPageNosave(virt_to_page(res));
- SetPageNosaveFree(virt_to_page(res));
+ swsusp_set_page_forbidden(virt_to_page(res));
+ swsusp_set_page_free(virt_to_page(res));
}
return res;
}
@@ -91,8 +95,8 @@ static struct page *alloc_image_page(gfp_t gfp_mask)
page = alloc_page(gfp_mask);
if (page) {
- SetPageNosave(page);
- SetPageNosaveFree(page);
+ swsusp_set_page_forbidden(page);
+ swsusp_set_page_free(page);
}
return page;
}
@@ -110,9 +114,9 @@ static inline void free_image_page(void *addr, int clear_nosave_free)
page = virt_to_page(addr);
- ClearPageNosave(page);
+ swsusp_unset_page_forbidden(page);
if (clear_nosave_free)
- ClearPageNosaveFree(page);
+ swsusp_unset_page_free(page);
__free_page(page);
}
@@ -224,11 +228,6 @@ static void chain_free(struct chain_allocator *ca, int clear_page_nosave)
* of type unsigned long each). It also contains the pfns that
* correspond to the start and end of the represented memory area and
* the number of bit chunks in the block.
- *
- * NOTE: Memory bitmaps are used for two types of operations only:
- * "set a bit" and "find the next bit set". Moreover, the searching
- * is always carried out after all of the "set a bit" operations
- * on given bitmap.
*/
#define BM_END_OF_MAP (~0UL)
@@ -443,15 +442,13 @@ static void memory_bm_free(struct memory_bitmap *bm, int clear_nosave_free)
}
/**
- * memory_bm_set_bit - set the bit in the bitmap @bm that corresponds
+ * memory_bm_find_bit - find the bit in the bitmap @bm that corresponds
* to given pfn. The cur_zone_bm member of @bm and the cur_block member
* of @bm->cur_zone_bm are updated.
- *
- * If the bit cannot be set, the function returns -EINVAL .
*/
-static int
-memory_bm_set_bit(struct memory_bitmap *bm, unsigned long pfn)
+static void memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn,
+ void **addr, unsigned int *bit_nr)
{
struct zone_bitmap *zone_bm;
struct bm_block *bb;
@@ -463,8 +460,8 @@ memory_bm_set_bit(struct memory_bitmap *bm, unsigned long pfn)
/* We don't assume that the zones are sorted by pfns */
while (pfn < zone_bm->start_pfn || pfn >= zone_bm->end_pfn) {
zone_bm = zone_bm->next;
- if (unlikely(!zone_bm))
- return -EINVAL;
+
+ BUG_ON(!zone_bm);
}
bm->cur.zone_bm = zone_bm;
}
@@ -475,13 +472,40 @@ memory_bm_set_bit(struct memory_bitmap *bm, unsigned long pfn)
while (pfn >= bb->end_pfn) {
bb = bb->next;
- if (unlikely(!bb))
- return -EINVAL;
+
+ BUG_ON(!bb);
}
zone_bm->cur_block = bb;
pfn -= bb->start_pfn;
- set_bit(pfn % BM_BITS_PER_CHUNK, bb->data + pfn / BM_BITS_PER_CHUNK);
- return 0;
+ *bit_nr = pfn % BM_BITS_PER_CHUNK;
+ *addr = bb->data + pfn / BM_BITS_PER_CHUNK;
+}
+
+static void memory_bm_set_bit(struct memory_bitmap *bm, unsigned long pfn)
+{
+ void *addr;
+ unsigned int bit;
+
+ memory_bm_find_bit(bm, pfn, &addr, &bit);
+ set_bit(bit, addr);
+}
+
+static void memory_bm_clear_bit(struct memory_bitmap *bm, unsigned long pfn)
+{
+ void *addr;
+ unsigned int bit;
+
+ memory_bm_find_bit(bm, pfn, &addr, &bit);
+ clear_bit(bit, addr);
+}
+
+static int memory_bm_test_bit(struct memory_bitmap *bm, unsigned long pfn)
+{
+ void *addr;
+ unsigned int bit;
+
+ memory_bm_find_bit(bm, pfn, &addr, &bit);
+ return test_bit(bit, addr);
}
/* Two auxiliary functions for memory_bm_next_pfn */
@@ -564,6 +588,199 @@ static unsigned long memory_bm_next_pfn(struct memory_bitmap *bm)
}
/**
+ * This structure represents a range of page frames the contents of which
+ * should not be saved during the suspend.
+ */
+
+struct nosave_region {
+ struct list_head list;
+ unsigned long start_pfn;
+ unsigned long end_pfn;
+};
+
+static LIST_HEAD(nosave_regions);
+
+/**
+ * register_nosave_region - register a range of page frames the contents
+ * of which should not be saved during the suspend (to be used in the early
+ * initialization code)
+ */
+
+void __init
+register_nosave_region(unsigned long start_pfn, unsigned long end_pfn)
+{
+ struct nosave_region *region;
+
+ if (start_pfn >= end_pfn)
+ return;
+
+ if (!list_empty(&nosave_regions)) {
+ /* Try to extend the previous region (they should be sorted) */
+ region = list_entry(nosave_regions.prev,
+ struct nosave_region, list);
+ if (region->end_pfn == start_pfn) {
+ region->end_pfn = end_pfn;
+ goto Report;
+ }
+ }
+ /* This allocation cannot fail */
+ region = alloc_bootmem_low(sizeof(struct nosave_region));
+ region->start_pfn = start_pfn;
+ region->end_pfn = end_pfn;
+ list_add_tail(&region->list, &nosave_regions);
+ Report:
+ printk("swsusp: Registered nosave memory region: %016lx - %016lx\n",
+ start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT);
+}
+
+/*
+ * Set bits in this map correspond to the page frames the contents of which
+ * should not be saved during the suspend.
+ */
+static struct memory_bitmap *forbidden_pages_map;
+
+/* Set bits in this map correspond to free page frames. */
+static struct memory_bitmap *free_pages_map;
+
+/*
+ * Each page frame allocated for creating the image is marked by setting the
+ * corresponding bits in forbidden_pages_map and free_pages_map simultaneously
+ */
+
+void swsusp_set_page_free(struct page *page)
+{
+ if (free_pages_map)
+ memory_bm_set_bit(free_pages_map, page_to_pfn(page));
+}
+
+static int swsusp_page_is_free(struct page *page)
+{
+ return free_pages_map ?
+ memory_bm_test_bit(free_pages_map, page_to_pfn(page)) : 0;
+}
+
+void swsusp_unset_page_free(struct page *page)
+{
+ if (free_pages_map)
+ memory_bm_clear_bit(free_pages_map, page_to_pfn(page));
+}
+
+static void swsusp_set_page_forbidden(struct page *page)
+{
+ if (forbidden_pages_map)
+ memory_bm_set_bit(forbidden_pages_map, page_to_pfn(page));
+}
+
+int swsusp_page_is_forbidden(struct page *page)
+{
+ return forbidden_pages_map ?
+ memory_bm_test_bit(forbidden_pages_map, page_to_pfn(page)) : 0;
+}
+
+static void swsusp_unset_page_forbidden(struct page *page)
+{
+ if (forbidden_pages_map)
+ memory_bm_clear_bit(forbidden_pages_map, page_to_pfn(page));
+}
+
+/**
+ * mark_nosave_pages - set bits corresponding to the page frames the
+ * contents of which should not be saved in a given bitmap.
+ */
+
+static void mark_nosave_pages(struct memory_bitmap *bm)
+{
+ struct nosave_region *region;
+
+ if (list_empty(&nosave_regions))
+ return;
+
+ list_for_each_entry(region, &nosave_regions, list) {
+ unsigned long pfn;
+
+ printk("swsusp: Marking nosave pages: %016lx - %016lx\n",
+ region->start_pfn << PAGE_SHIFT,
+ region->end_pfn << PAGE_SHIFT);
+
+ for (pfn = region->start_pfn; pfn < region->end_pfn; pfn++)
+ memory_bm_set_bit(bm, pfn);
+ }
+}
+
+/**
+ * create_basic_memory_bitmaps - create bitmaps needed for marking page
+ * frames that should not be saved and free page frames. The pointers
+ * forbidden_pages_map and free_pages_map are only modified if everything
+ * goes well, because we don't want the bits to be used before both bitmaps
+ * are set up.
+ */
+
+int create_basic_memory_bitmaps(void)
+{
+ struct memory_bitmap *bm1, *bm2;
+ int error = 0;
+
+ BUG_ON(forbidden_pages_map || free_pages_map);
+
+ bm1 = kzalloc(sizeof(struct memory_bitmap), GFP_KERNEL);
+ if (!bm1)
+ return -ENOMEM;
+
+ error = memory_bm_create(bm1, GFP_KERNEL, PG_ANY);
+ if (error)
+ goto Free_first_object;
+
+ bm2 = kzalloc(sizeof(struct memory_bitmap), GFP_KERNEL);
+ if (!bm2)
+ goto Free_first_bitmap;
+
+ error = memory_bm_create(bm2, GFP_KERNEL, PG_ANY);
+ if (error)
+ goto Free_second_object;
+
+ forbidden_pages_map = bm1;
+ free_pages_map = bm2;
+ mark_nosave_pages(forbidden_pages_map);
+
+ printk("swsusp: Basic memory bitmaps created\n");
+
+ return 0;
+
+ Free_second_object:
+ kfree(bm2);
+ Free_first_bitmap:
+ memory_bm_free(bm1, PG_UNSAFE_CLEAR);
+ Free_first_object:
+ kfree(bm1);
+ return -ENOMEM;
+}
+
+/**
+ * free_basic_memory_bitmaps - free memory bitmaps allocated by
+ * create_basic_memory_bitmaps(). The auxiliary pointers are necessary
+ * so that the bitmaps themselves are not referred to while they are being
+ * freed.
+ */
+
+void free_basic_memory_bitmaps(void)
+{
+ struct memory_bitmap *bm1, *bm2;
+
+ BUG_ON(!(forbidden_pages_map && free_pages_map));
+
+ bm1 = forbidden_pages_map;
+ bm2 = free_pages_map;
+ forbidden_pages_map = NULL;
+ free_pages_map = NULL;
+ memory_bm_free(bm1, PG_UNSAFE_CLEAR);
+ kfree(bm1);
+ memory_bm_free(bm2, PG_UNSAFE_CLEAR);
+ kfree(bm2);
+
+ printk("swsusp: Basic memory bitmaps freed\n");
+}
+
+/**
* snapshot_additional_pages - estimate the number of additional pages
* be needed for setting up the suspend image data structures for given
* zone (usually the returned value is greater than the exact number)
@@ -615,7 +832,8 @@ static struct page *saveable_highmem_page(unsigned long pfn)
BUG_ON(!PageHighMem(page));
- if (PageNosave(page) || PageReserved(page) || PageNosaveFree(page))
+ if (swsusp_page_is_forbidden(page) || swsusp_page_is_free(page) ||
+ PageReserved(page))
return NULL;
return page;
@@ -670,7 +888,7 @@ static struct page *saveable_page(unsigned long pfn)
BUG_ON(PageHighMem(page));
- if (PageNosave(page) || PageNosaveFree(page))
+ if (swsusp_page_is_forbidden(page) || swsusp_page_is_free(page))
return NULL;
if (PageReserved(page) && pfn_is_nosave(pfn))
@@ -810,9 +1028,10 @@ void swsusp_free(void)
if (pfn_valid(pfn)) {
struct page *page = pfn_to_page(pfn);
- if (PageNosave(page) && PageNosaveFree(page)) {
- ClearPageNosave(page);
- ClearPageNosaveFree(page);
+ if (swsusp_page_is_forbidden(page) &&
+ swsusp_page_is_free(page)) {
+ swsusp_unset_page_forbidden(page);
+ swsusp_unset_page_free(page);
__free_page(page);
}
}
@@ -1135,7 +1354,7 @@ static int mark_unsafe_pages(struct memory_bitmap *bm)
max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages;
for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++)
if (pfn_valid(pfn))
- ClearPageNosaveFree(pfn_to_page(pfn));
+ swsusp_unset_page_free(pfn_to_page(pfn));
}
/* Mark pages that correspond to the "original" pfns as "unsafe" */
@@ -1144,7 +1363,7 @@ static int mark_unsafe_pages(struct memory_bitmap *bm)
pfn = memory_bm_next_pfn(bm);
if (likely(pfn != BM_END_OF_MAP)) {
if (likely(pfn_valid(pfn)))
- SetPageNosaveFree(pfn_to_page(pfn));
+ swsusp_set_page_free(pfn_to_page(pfn));
else
return -EFAULT;
}
@@ -1310,14 +1529,14 @@ prepare_highmem_image(struct memory_bitmap *bm, unsigned int *nr_highmem_p)
struct page *page;
page = alloc_page(__GFP_HIGHMEM);
- if (!PageNosaveFree(page)) {
+ if (!swsusp_page_is_free(page)) {
/* The page is "safe", set its bit the bitmap */
memory_bm_set_bit(bm, page_to_pfn(page));
safe_highmem_pages++;
}
/* Mark the page as allocated */
- SetPageNosave(page);
- SetPageNosaveFree(page);
+ swsusp_set_page_forbidden(page);
+ swsusp_set_page_free(page);
}
memory_bm_position_reset(bm);
safe_highmem_bm = bm;
@@ -1349,7 +1568,7 @@ get_highmem_page_buffer(struct page *page, struct chain_allocator *ca)
struct highmem_pbe *pbe;
void *kaddr;
- if (PageNosave(page) && PageNosaveFree(page)) {
+ if (swsusp_page_is_forbidden(page) && swsusp_page_is_free(page)) {
/* We have allocated the "original" page frame and we can
* use it directly to store the loaded page.
*/
@@ -1511,14 +1730,14 @@ prepare_image(struct memory_bitmap *new_bm, struct memory_bitmap *bm)
error = -ENOMEM;
goto Free;
}
- if (!PageNosaveFree(virt_to_page(lp))) {
+ if (!swsusp_page_is_free(virt_to_page(lp))) {
/* The page is "safe", add it to the list */
lp->next = safe_pages_list;
safe_pages_list = lp;
}
/* Mark the page as allocated */
- SetPageNosave(virt_to_page(lp));
- SetPageNosaveFree(virt_to_page(lp));
+ swsusp_set_page_forbidden(virt_to_page(lp));
+ swsusp_set_page_free(virt_to_page(lp));
nr_pages--;
}
/* Free the reserved safe pages so that chain_alloc() can use them */
@@ -1547,7 +1766,7 @@ static void *get_buffer(struct memory_bitmap *bm, struct chain_allocator *ca)
if (PageHighMem(page))
return get_highmem_page_buffer(page, ca);
- if (PageNosave(page) && PageNosaveFree(page))
+ if (swsusp_page_is_forbidden(page) && swsusp_page_is_free(page))
/* We have allocated the "original" page frame and we can
* use it directly to store the loaded page.
*/
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index b18c155..b8b235c 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -12,7 +12,6 @@
*/
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/file.h>
#include <linux/utsname.h>
#include <linux/version.h>
@@ -243,7 +242,6 @@ struct swap_map_page {
struct swap_map_handle {
struct swap_map_page *cur;
sector_t cur_swap;
- struct bitmap_page *bitmap;
unsigned int k;
};
@@ -252,9 +250,6 @@ static void release_swap_writer(struct swap_map_handle *handle)
if (handle->cur)
free_page((unsigned long)handle->cur);
handle->cur = NULL;
- if (handle->bitmap)
- free_bitmap(handle->bitmap);
- handle->bitmap = NULL;
}
static int get_swap_writer(struct swap_map_handle *handle)
@@ -262,12 +257,7 @@ static int get_swap_writer(struct swap_map_handle *handle)
handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_KERNEL);
if (!handle->cur)
return -ENOMEM;
- handle->bitmap = alloc_bitmap(count_swap_pages(root_swap, 0));
- if (!handle->bitmap) {
- release_swap_writer(handle);
- return -ENOMEM;
- }
- handle->cur_swap = alloc_swapdev_block(root_swap, handle->bitmap);
+ handle->cur_swap = alloc_swapdev_block(root_swap);
if (!handle->cur_swap) {
release_swap_writer(handle);
return -ENOSPC;
@@ -284,7 +274,7 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf,
if (!handle->cur)
return -EINVAL;
- offset = alloc_swapdev_block(root_swap, handle->bitmap);
+ offset = alloc_swapdev_block(root_swap);
error = write_page(buf, offset, bio_chain);
if (error)
return error;
@@ -293,7 +283,7 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf,
error = wait_on_bio_chain(bio_chain);
if (error)
goto out;
- offset = alloc_swapdev_block(root_swap, handle->bitmap);
+ offset = alloc_swapdev_block(root_swap);
if (!offset)
return -ENOSPC;
handle->cur->next_swap = offset;
@@ -430,7 +420,8 @@ int swsusp_write(void)
}
}
if (error)
- free_all_swap_pages(root_swap, handle.bitmap);
+ free_all_swap_pages(root_swap);
+
release_swap_writer(&handle);
out:
swsusp_close();
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index 1753708..5da304c 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -50,6 +50,7 @@
#include <linux/syscalls.h>
#include <linux/highmem.h>
#include <linux/time.h>
+#include <linux/rbtree.h>
#include "power.h"
@@ -74,72 +75,69 @@ static inline unsigned int count_highmem_pages(void) { return 0; }
/**
* The following functions are used for tracing the allocated
* swap pages, so that they can be freed in case of an error.
- *
- * The functions operate on a linked bitmap structure defined
- * in power.h
*/
-void free_bitmap(struct bitmap_page *bitmap)
-{
- struct bitmap_page *bp;
+struct swsusp_extent {
+ struct rb_node node;
+ unsigned long start;
+ unsigned long end;
+};
- while (bitmap) {
- bp = bitmap->next;
- free_page((unsigned long)bitmap);
- bitmap = bp;
- }
-}
+static struct rb_root swsusp_extents = RB_ROOT;
-struct bitmap_page *alloc_bitmap(unsigned int nr_bits)
+static int swsusp_extents_insert(unsigned long swap_offset)
{
- struct bitmap_page *bitmap, *bp;
- unsigned int n;
-
- if (!nr_bits)
- return NULL;
-
- bitmap = (struct bitmap_page *)get_zeroed_page(GFP_KERNEL);
- bp = bitmap;
- for (n = BITMAP_PAGE_BITS; n < nr_bits; n += BITMAP_PAGE_BITS) {
- bp->next = (struct bitmap_page *)get_zeroed_page(GFP_KERNEL);
- bp = bp->next;
- if (!bp) {
- free_bitmap(bitmap);
- return NULL;
+ struct rb_node **new = &(swsusp_extents.rb_node);
+ struct rb_node *parent = NULL;
+ struct swsusp_extent *ext;
+
+ /* Figure out where to put the new node */
+ while (*new) {
+ ext = container_of(*new, struct swsusp_extent, node);
+ parent = *new;
+ if (swap_offset < ext->start) {
+ /* Try to merge */
+ if (swap_offset == ext->start - 1) {
+ ext->start--;
+ return 0;
+ }
+ new = &((*new)->rb_left);
+ } else if (swap_offset > ext->end) {
+ /* Try to merge */
+ if (swap_offset == ext->end + 1) {
+ ext->end++;
+ return 0;
+ }
+ new = &((*new)->rb_right);
+ } else {
+ /* It already is in the tree */
+ return -EINVAL;
}
}
- return bitmap;
-}
-
-static int bitmap_set(struct bitmap_page *bitmap, unsigned long bit)
-{
- unsigned int n;
-
- n = BITMAP_PAGE_BITS;
- while (bitmap && n <= bit) {
- n += BITMAP_PAGE_BITS;
- bitmap = bitmap->next;
- }
- if (!bitmap)
- return -EINVAL;
- n -= BITMAP_PAGE_BITS;
- bit -= n;
- n = 0;
- while (bit >= BITS_PER_CHUNK) {
- bit -= BITS_PER_CHUNK;
- n++;
- }
- bitmap->chunks[n] |= (1UL << bit);
+ /* Add the new node and rebalance the tree. */
+ ext = kzalloc(sizeof(struct swsusp_extent), GFP_KERNEL);
+ if (!ext)
+ return -ENOMEM;
+
+ ext->start = swap_offset;
+ ext->end = swap_offset;
+ rb_link_node(&ext->node, parent, new);
+ rb_insert_color(&ext->node, &swsusp_extents);
return 0;
}
-sector_t alloc_swapdev_block(int swap, struct bitmap_page *bitmap)
+/**
+ * alloc_swapdev_block - allocate a swap page and register that it has
+ * been allocated, so that it can be freed in case of an error.
+ */
+
+sector_t alloc_swapdev_block(int swap)
{
unsigned long offset;
offset = swp_offset(get_swap_page_of_type(swap));
if (offset) {
- if (bitmap_set(bitmap, offset))
+ if (swsusp_extents_insert(offset))
swap_free(swp_entry(swap, offset));
else
return swapdev_block(swap, offset);
@@ -147,23 +145,34 @@ sector_t alloc_swapdev_block(int swap, struct bitmap_page *bitmap)
return 0;
}
-void free_all_swap_pages(int swap, struct bitmap_page *bitmap)
+/**
+ * free_all_swap_pages - free swap pages allocated for saving image data.
+ * It also frees the extents used to register which swap entres had been
+ * allocated.
+ */
+
+void free_all_swap_pages(int swap)
{
- unsigned int bit, n;
- unsigned long test;
-
- bit = 0;
- while (bitmap) {
- for (n = 0; n < BITMAP_PAGE_CHUNKS; n++)
- for (test = 1UL; test; test <<= 1) {
- if (bitmap->chunks[n] & test)
- swap_free(swp_entry(swap, bit));
- bit++;
- }
- bitmap = bitmap->next;
+ struct rb_node *node;
+
+ while ((node = swsusp_extents.rb_node)) {
+ struct swsusp_extent *ext;
+ unsigned long offset;
+
+ ext = container_of(node, struct swsusp_extent, node);
+ rb_erase(node, &swsusp_extents);
+ for (offset = ext->start; offset <= ext->end; offset++)
+ swap_free(swp_entry(swap, offset));
+
+ kfree(ext);
}
}
+int swsusp_swap_in_use(void)
+{
+ return (swsusp_extents.rb_node != NULL);
+}
+
/**
* swsusp_show_speed - print the time elapsed between two events represented by
* @start and @stop
@@ -224,7 +233,7 @@ int swsusp_shrink_memory(void)
long size, highmem_size;
highmem_size = count_highmem_pages();
- size = count_data_pages() + PAGES_FOR_IO;
+ size = count_data_pages() + PAGES_FOR_IO + SPARE_PAGES;
tmp = size;
size += highmem_size;
for_each_zone (zone)
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 7cf6713..040560d 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -33,25 +33,29 @@
static struct snapshot_data {
struct snapshot_handle handle;
int swap;
- struct bitmap_page *bitmap;
int mode;
char frozen;
char ready;
char platform_suspend;
} snapshot_state;
-static atomic_t device_available = ATOMIC_INIT(1);
+atomic_t snapshot_device_available = ATOMIC_INIT(1);
static int snapshot_open(struct inode *inode, struct file *filp)
{
struct snapshot_data *data;
- if (!atomic_add_unless(&device_available, -1, 0))
+ if (!atomic_add_unless(&snapshot_device_available, -1, 0))
return -EBUSY;
- if ((filp->f_flags & O_ACCMODE) == O_RDWR)
+ if ((filp->f_flags & O_ACCMODE) == O_RDWR) {
+ atomic_inc(&snapshot_device_available);
return -ENOSYS;
-
+ }
+ if(create_basic_memory_bitmaps()) {
+ atomic_inc(&snapshot_device_available);
+ return -ENOMEM;
+ }
nonseekable_open(inode, filp);
data = &snapshot_state;
filp->private_data = data;
@@ -64,7 +68,6 @@ static int snapshot_open(struct inode *inode, struct file *filp)
data->swap = -1;
data->mode = O_WRONLY;
}
- data->bitmap = NULL;
data->frozen = 0;
data->ready = 0;
data->platform_suspend = 0;
@@ -77,16 +80,15 @@ static int snapshot_release(struct inode *inode, struct file *filp)
struct snapshot_data *data;
swsusp_free();
+ free_basic_memory_bitmaps();
data = filp->private_data;
- free_all_swap_pages(data->swap, data->bitmap);
- free_bitmap(data->bitmap);
+ free_all_swap_pages(data->swap);
if (data->frozen) {
mutex_lock(&pm_mutex);
thaw_processes();
- enable_nonboot_cpus();
mutex_unlock(&pm_mutex);
}
- atomic_inc(&device_available);
+ atomic_inc(&snapshot_device_available);
return 0;
}
@@ -294,14 +296,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
error = -ENODEV;
break;
}
- if (!data->bitmap) {
- data->bitmap = alloc_bitmap(count_swap_pages(data->swap, 0));
- if (!data->bitmap) {
- error = -ENOMEM;
- break;
- }
- }
- offset = alloc_swapdev_block(data->swap, data->bitmap);
+ offset = alloc_swapdev_block(data->swap);
if (offset) {
offset <<= PAGE_SHIFT;
error = put_user(offset, (sector_t __user *)arg);
@@ -315,13 +310,11 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
error = -ENODEV;
break;
}
- free_all_swap_pages(data->swap, data->bitmap);
- free_bitmap(data->bitmap);
- data->bitmap = NULL;
+ free_all_swap_pages(data->swap);
break;
case SNAPSHOT_SET_SWAP_FILE:
- if (!data->bitmap) {
+ if (!swsusp_swap_in_use()) {
/*
* User space encodes device types as two-byte values,
* so we need to recode them
@@ -420,7 +413,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
break;
case SNAPSHOT_SET_SWAP_AREA:
- if (data->bitmap) {
+ if (swsusp_swap_in_use()) {
error = -EPERM;
} else {
struct resume_swap_area swap_area;
diff --git a/kernel/printk.c b/kernel/printk.c
index 4b47e59..0bbdeac 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -20,7 +20,6 @@
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
-#include <linux/smp_lock.h>
#include <linux/console.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -931,8 +930,16 @@ void register_console(struct console *console)
{
int i;
unsigned long flags;
+ struct console *bootconsole = NULL;
- if (preferred_console < 0)
+ if (console_drivers) {
+ if (console->flags & CON_BOOT)
+ return;
+ if (console_drivers->flags & CON_BOOT)
+ bootconsole = console_drivers;
+ }
+
+ if (preferred_console < 0 || bootconsole || !console_drivers)
preferred_console = selected_console;
/*
@@ -978,8 +985,11 @@ void register_console(struct console *console)
if (!(console->flags & CON_ENABLED))
return;
- if (console_drivers && (console_drivers->flags & CON_BOOT)) {
- unregister_console(console_drivers);
+ if (bootconsole) {
+ printk(KERN_INFO "console handover: boot [%s%d] -> real [%s%d]\n",
+ bootconsole->name, bootconsole->index,
+ console->name, console->index);
+ unregister_console(bootconsole);
console->flags &= ~CON_PRINTBUFFER;
}
@@ -1030,16 +1040,11 @@ int unregister_console(struct console *console)
}
}
- /* If last console is removed, we re-enable picking the first
- * one that gets registered. Without that, pmac early boot console
- * would prevent fbcon from taking over.
- *
+ /*
* If this isn't the last console and it has CON_CONSDEV set, we
* need to set it on the next preferred console.
*/
- if (console_drivers == NULL)
- preferred_console = selected_console;
- else if (console->flags & CON_CONSDEV)
+ if (console_drivers != NULL && console->flags & CON_CONSDEV)
console_drivers->flags |= CON_CONSDEV;
release_console_sem();
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index bcd14e8..55ba82a 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -502,10 +502,6 @@ static struct rcu_torture_ops sched_ops = {
.name = "sched"
};
-static struct rcu_torture_ops *torture_ops[] =
- { &rcu_ops, &rcu_sync_ops, &rcu_bh_ops, &rcu_bh_sync_ops, &srcu_ops,
- &sched_ops, NULL };
-
/*
* RCU torture writer kthread. Repeatedly substitutes a new structure
* for that pointed to by rcu_torture_current, freeing the old structure
@@ -534,7 +530,7 @@ rcu_torture_writer(void *arg)
rp->rtort_mbtest = 1;
rcu_assign_pointer(rcu_torture_current, rp);
smp_wmb();
- if (old_rp != NULL) {
+ if (old_rp) {
i = old_rp->rtort_pipe_count;
if (i > RCU_TORTURE_PIPE_LEN)
i = RCU_TORTURE_PIPE_LEN;
@@ -685,7 +681,7 @@ rcu_torture_printk(char *page)
atomic_read(&rcu_torture_wcount[i]));
}
cnt += sprintf(&page[cnt], "\n");
- if (cur_ops->stats != NULL)
+ if (cur_ops->stats)
cnt += cur_ops->stats(&page[cnt]);
return cnt;
}
@@ -749,13 +745,13 @@ static void rcu_torture_shuffle_tasks(void)
set_cpus_allowed(current, tmp_mask);
- if (reader_tasks != NULL) {
+ if (reader_tasks) {
for (i = 0; i < nrealreaders; i++)
if (reader_tasks[i])
set_cpus_allowed(reader_tasks[i], tmp_mask);
}
- if (fakewriter_tasks != NULL) {
+ if (fakewriter_tasks) {
for (i = 0; i < nfakewriters; i++)
if (fakewriter_tasks[i])
set_cpus_allowed(fakewriter_tasks[i], tmp_mask);
@@ -808,21 +804,21 @@ rcu_torture_cleanup(void)
int i;
fullstop = 1;
- if (shuffler_task != NULL) {
+ if (shuffler_task) {
VERBOSE_PRINTK_STRING("Stopping rcu_torture_shuffle task");
kthread_stop(shuffler_task);
}
shuffler_task = NULL;
- if (writer_task != NULL) {
+ if (writer_task) {
VERBOSE_PRINTK_STRING("Stopping rcu_torture_writer task");
kthread_stop(writer_task);
}
writer_task = NULL;
- if (reader_tasks != NULL) {
+ if (reader_tasks) {
for (i = 0; i < nrealreaders; i++) {
- if (reader_tasks[i] != NULL) {
+ if (reader_tasks[i]) {
VERBOSE_PRINTK_STRING(
"Stopping rcu_torture_reader task");
kthread_stop(reader_tasks[i]);
@@ -834,9 +830,9 @@ rcu_torture_cleanup(void)
}
rcu_torture_current = NULL;
- if (fakewriter_tasks != NULL) {
+ if (fakewriter_tasks) {
for (i = 0; i < nfakewriters; i++) {
- if (fakewriter_tasks[i] != NULL) {
+ if (fakewriter_tasks[i]) {
VERBOSE_PRINTK_STRING(
"Stopping rcu_torture_fakewriter task");
kthread_stop(fakewriter_tasks[i]);
@@ -847,7 +843,7 @@ rcu_torture_cleanup(void)
fakewriter_tasks = NULL;
}
- if (stats_task != NULL) {
+ if (stats_task) {
VERBOSE_PRINTK_STRING("Stopping rcu_torture_stats task");
kthread_stop(stats_task);
}
@@ -858,7 +854,7 @@ rcu_torture_cleanup(void)
rcu_torture_stats_print(); /* -After- the stats thread is stopped! */
- if (cur_ops->cleanup != NULL)
+ if (cur_ops->cleanup)
cur_ops->cleanup();
if (atomic_read(&n_rcu_torture_error))
rcu_torture_print_module_parms("End of test: FAILURE");
@@ -866,27 +862,28 @@ rcu_torture_cleanup(void)
rcu_torture_print_module_parms("End of test: SUCCESS");
}
-static int
+static int __init
rcu_torture_init(void)
{
int i;
int cpu;
int firsterr = 0;
+ static struct rcu_torture_ops *torture_ops[] =
+ { &rcu_ops, &rcu_sync_ops, &rcu_bh_ops, &rcu_bh_sync_ops,
+ &srcu_ops, &sched_ops, };
/* Process args and tell the world that the torturer is on the job. */
-
- for (i = 0; cur_ops = torture_ops[i], cur_ops != NULL; i++) {
+ for (i = 0; i < ARRAY_SIZE(torture_ops); i++) {
cur_ops = torture_ops[i];
- if (strcmp(torture_type, cur_ops->name) == 0) {
+ if (strcmp(torture_type, cur_ops->name) == 0)
break;
- }
}
- if (cur_ops == NULL) {
+ if (i == ARRAY_SIZE(torture_ops)) {
printk(KERN_ALERT "rcutorture: invalid torture type: \"%s\"\n",
torture_type);
return (-EINVAL);
}
- if (cur_ops->init != NULL)
+ if (cur_ops->init)
cur_ops->init(); /* no "goto unwind" prior to this point!!! */
if (nreaders >= 0)
@@ -899,7 +896,7 @@ rcu_torture_init(void)
/* Set up the freelist. */
INIT_LIST_HEAD(&rcu_torture_freelist);
- for (i = 0; i < sizeof(rcu_tortures) / sizeof(rcu_tortures[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(rcu_tortures); i++) {
rcu_tortures[i].rtort_mbtest = 0;
list_add_tail(&rcu_tortures[i].rtort_free,
&rcu_torture_freelist);
diff --git a/kernel/rwsem.c b/kernel/rwsem.c
index 291ded5..9a87886 100644
--- a/kernel/rwsem.c
+++ b/kernel/rwsem.c
@@ -60,7 +60,7 @@ int down_write_trylock(struct rw_semaphore *sem)
int ret = __down_write_trylock(sem);
if (ret == 1)
- rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_);
+ rwsem_acquire(&sem->dep_map, 0, 1, _RET_IP_);
return ret;
}
diff --git a/kernel/sched.c b/kernel/sched.c
index 960d7c5..a3a0408 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -52,8 +52,9 @@
#include <linux/tsacct_kern.h>
#include <linux/kprobes.h>
#include <linux/delayacct.h>
-#include <asm/tlb.h>
+#include <linux/reciprocal_div.h>
+#include <asm/tlb.h>
#include <asm/unistd.h>
/*
@@ -168,7 +169,7 @@ unsigned long long __attribute__((weak)) sched_clock(void)
(MAX_BONUS / 2 + DELTA((p)) + 1) / MAX_BONUS - 1))
#define TASK_PREEMPTS_CURR(p, rq) \
- ((p)->prio < (rq)->curr->prio)
+ (((p)->prio < (rq)->curr->prio) && ((p)->array == (rq)->active))
#define SCALE_PRIO(x, prio) \
max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO / 2), MIN_TIMESLICE)
@@ -181,6 +182,27 @@ static unsigned int static_prio_timeslice(int static_prio)
return SCALE_PRIO(DEF_TIMESLICE, static_prio);
}
+#ifdef CONFIG_SMP
+/*
+ * Divide a load by a sched group cpu_power : (load / sg->__cpu_power)
+ * Since cpu_power is a 'constant', we can use a reciprocal divide.
+ */
+static inline u32 sg_div_cpu_power(const struct sched_group *sg, u32 load)
+{
+ return reciprocal_divide(load, sg->reciprocal_cpu_power);
+}
+
+/*
+ * Each time a sched group cpu_power is changed,
+ * we must compute its reciprocal value
+ */
+static inline void sg_inc_cpu_power(struct sched_group *sg, u32 val)
+{
+ sg->__cpu_power += val;
+ sg->reciprocal_cpu_power = reciprocal_value(sg->__cpu_power);
+}
+#endif
+
/*
* task_timeslice() scales user-nice values [ -20 ... 0 ... 19 ]
* to time slice values: [800ms ... 100ms ... 5ms]
@@ -223,6 +245,10 @@ struct rq {
unsigned long raw_weighted_load;
#ifdef CONFIG_SMP
unsigned long cpu_load[3];
+ unsigned char idle_at_tick;
+#ifdef CONFIG_NO_HZ
+ unsigned char in_nohz_recently;
+#endif
#endif
unsigned long long nr_switches;
@@ -278,7 +304,7 @@ struct rq {
struct lock_class_key rq_lock_key;
};
-static DEFINE_PER_CPU(struct rq, runqueues);
+static DEFINE_PER_CPU(struct rq, runqueues) ____cacheline_aligned_in_smp;
static inline int cpu_of(struct rq *rq)
{
@@ -1049,6 +1075,17 @@ static void resched_task(struct task_struct *p)
if (!tsk_is_polling(p))
smp_send_reschedule(cpu);
}
+
+static void resched_cpu(int cpu)
+{
+ struct rq *rq = cpu_rq(cpu);
+ unsigned long flags;
+
+ if (!spin_trylock_irqsave(&rq->lock, flags))
+ return;
+ resched_task(cpu_curr(cpu));
+ spin_unlock_irqrestore(&rq->lock, flags);
+}
#else
static inline void resched_task(struct task_struct *p)
{
@@ -1241,7 +1278,8 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p, int this_cpu)
}
/* Adjust by relative CPU power of the group */
- avg_load = (avg_load * SCHED_LOAD_SCALE) / group->cpu_power;
+ avg_load = sg_div_cpu_power(group,
+ avg_load * SCHED_LOAD_SCALE);
if (local_group) {
this_load = avg_load;
@@ -1368,7 +1406,16 @@ static int wake_idle(int cpu, struct task_struct *p)
struct sched_domain *sd;
int i;
- if (idle_cpu(cpu))
+ /*
+ * If it is idle, then it is the best cpu to run this task.
+ *
+ * This cpu is also the best, if it has more than one task already.
+ * Siblings must be also busy(in most cases) as they didn't already
+ * pickup the extra load from this cpu and hence we need not check
+ * sibling runqueue info. This will avoid the checks and cache miss
+ * penalities associated with that.
+ */
+ if (idle_cpu(cpu) || cpu_rq(cpu)->nr_running > 1)
return cpu;
for_each_domain(cpu, sd) {
@@ -2352,12 +2399,13 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
}
total_load += avg_load;
- total_pwr += group->cpu_power;
+ total_pwr += group->__cpu_power;
/* Adjust by relative CPU power of the group */
- avg_load = (avg_load * SCHED_LOAD_SCALE) / group->cpu_power;
+ avg_load = sg_div_cpu_power(group,
+ avg_load * SCHED_LOAD_SCALE);
- group_capacity = group->cpu_power / SCHED_LOAD_SCALE;
+ group_capacity = group->__cpu_power / SCHED_LOAD_SCALE;
if (local_group) {
this_load = avg_load;
@@ -2468,8 +2516,8 @@ group_next:
max_pull = min(max_load - avg_load, max_load - busiest_load_per_task);
/* How much load to actually move to equalise the imbalance */
- *imbalance = min(max_pull * busiest->cpu_power,
- (avg_load - this_load) * this->cpu_power)
+ *imbalance = min(max_pull * busiest->__cpu_power,
+ (avg_load - this_load) * this->__cpu_power)
/ SCHED_LOAD_SCALE;
/*
@@ -2503,28 +2551,29 @@ small_imbalance:
* moving them.
*/
- pwr_now += busiest->cpu_power *
- min(busiest_load_per_task, max_load);
- pwr_now += this->cpu_power *
- min(this_load_per_task, this_load);
+ pwr_now += busiest->__cpu_power *
+ min(busiest_load_per_task, max_load);
+ pwr_now += this->__cpu_power *
+ min(this_load_per_task, this_load);
pwr_now /= SCHED_LOAD_SCALE;
/* Amount of load we'd subtract */
- tmp = busiest_load_per_task * SCHED_LOAD_SCALE /
- busiest->cpu_power;
+ tmp = sg_div_cpu_power(busiest,
+ busiest_load_per_task * SCHED_LOAD_SCALE);
if (max_load > tmp)
- pwr_move += busiest->cpu_power *
+ pwr_move += busiest->__cpu_power *
min(busiest_load_per_task, max_load - tmp);
/* Amount of load we'd add */
- if (max_load * busiest->cpu_power <
+ if (max_load * busiest->__cpu_power <
busiest_load_per_task * SCHED_LOAD_SCALE)
- tmp = max_load * busiest->cpu_power / this->cpu_power;
+ tmp = sg_div_cpu_power(this,
+ max_load * busiest->__cpu_power);
else
- tmp = busiest_load_per_task * SCHED_LOAD_SCALE /
- this->cpu_power;
- pwr_move += this->cpu_power *
- min(this_load_per_task, this_load + tmp);
+ tmp = sg_div_cpu_power(this,
+ busiest_load_per_task * SCHED_LOAD_SCALE);
+ pwr_move += this->__cpu_power *
+ min(this_load_per_task, this_load + tmp);
pwr_move /= SCHED_LOAD_SCALE;
/* Move if we gain throughput */
@@ -2657,6 +2706,12 @@ redo:
double_rq_unlock(this_rq, busiest);
local_irq_restore(flags);
+ /*
+ * some other cpu did the load balance for us.
+ */
+ if (nr_moved && this_cpu != smp_processor_id())
+ resched_cpu(this_cpu);
+
/* All tasks on this runqueue were pinned by CPU affinity */
if (unlikely(all_pinned)) {
cpu_clear(cpu_of(busiest), cpus);
@@ -2927,32 +2982,98 @@ static void update_load(struct rq *this_rq)
}
}
+#ifdef CONFIG_NO_HZ
+static struct {
+ atomic_t load_balancer;
+ cpumask_t cpu_mask;
+} nohz ____cacheline_aligned = {
+ .load_balancer = ATOMIC_INIT(-1),
+ .cpu_mask = CPU_MASK_NONE,
+};
+
/*
- * run_rebalance_domains is triggered when needed from the scheduler tick.
+ * This routine will try to nominate the ilb (idle load balancing)
+ * owner among the cpus whose ticks are stopped. ilb owner will do the idle
+ * load balancing on behalf of all those cpus. If all the cpus in the system
+ * go into this tickless mode, then there will be no ilb owner (as there is
+ * no need for one) and all the cpus will sleep till the next wakeup event
+ * arrives...
*
+ * For the ilb owner, tick is not stopped. And this tick will be used
+ * for idle load balancing. ilb owner will still be part of
+ * nohz.cpu_mask..
+ *
+ * While stopping the tick, this cpu will become the ilb owner if there
+ * is no other owner. And will be the owner till that cpu becomes busy
+ * or if all cpus in the system stop their ticks at which point
+ * there is no need for ilb owner.
+ *
+ * When the ilb owner becomes busy, it nominates another owner, during the
+ * next busy scheduler_tick()
+ */
+int select_nohz_load_balancer(int stop_tick)
+{
+ int cpu = smp_processor_id();
+
+ if (stop_tick) {
+ cpu_set(cpu, nohz.cpu_mask);
+ cpu_rq(cpu)->in_nohz_recently = 1;
+
+ /*
+ * If we are going offline and still the leader, give up!
+ */
+ if (cpu_is_offline(cpu) &&
+ atomic_read(&nohz.load_balancer) == cpu) {
+ if (atomic_cmpxchg(&nohz.load_balancer, cpu, -1) != cpu)
+ BUG();
+ return 0;
+ }
+
+ /* time for ilb owner also to sleep */
+ if (cpus_weight(nohz.cpu_mask) == num_online_cpus()) {
+ if (atomic_read(&nohz.load_balancer) == cpu)
+ atomic_set(&nohz.load_balancer, -1);
+ return 0;
+ }
+
+ if (atomic_read(&nohz.load_balancer) == -1) {
+ /* make me the ilb owner */
+ if (atomic_cmpxchg(&nohz.load_balancer, -1, cpu) == -1)
+ return 1;
+ } else if (atomic_read(&nohz.load_balancer) == cpu)
+ return 1;
+ } else {
+ if (!cpu_isset(cpu, nohz.cpu_mask))
+ return 0;
+
+ cpu_clear(cpu, nohz.cpu_mask);
+
+ if (atomic_read(&nohz.load_balancer) == cpu)
+ if (atomic_cmpxchg(&nohz.load_balancer, cpu, -1) != cpu)
+ BUG();
+ }
+ return 0;
+}
+#endif
+
+static DEFINE_SPINLOCK(balancing);
+
+/*
* It checks each scheduling domain to see if it is due to be balanced,
* and initiates a balancing operation if so.
*
* Balancing parameters are set up in arch_init_sched_domains.
*/
-static DEFINE_SPINLOCK(balancing);
-
-static void run_rebalance_domains(struct softirq_action *h)
+static inline void rebalance_domains(int cpu, enum idle_type idle)
{
- int this_cpu = smp_processor_id(), balance = 1;
- struct rq *this_rq = cpu_rq(this_cpu);
+ int balance = 1;
+ struct rq *rq = cpu_rq(cpu);
unsigned long interval;
struct sched_domain *sd;
- /*
- * We are idle if there are no processes running. This
- * is valid even if we are the idle process (SMT).
- */
- enum idle_type idle = !this_rq->nr_running ?
- SCHED_IDLE : NOT_IDLE;
- /* Earliest time when we have to call run_rebalance_domains again */
+ /* Earliest time when we have to do rebalance again */
unsigned long next_balance = jiffies + 60*HZ;
- for_each_domain(this_cpu, sd) {
+ for_each_domain(cpu, sd) {
if (!(sd->flags & SD_LOAD_BALANCE))
continue;
@@ -2971,7 +3092,7 @@ static void run_rebalance_domains(struct softirq_action *h)
}
if (time_after_eq(jiffies, sd->last_balance + interval)) {
- if (load_balance(this_cpu, this_rq, sd, idle, &balance)) {
+ if (load_balance(cpu, rq, sd, idle, &balance)) {
/*
* We've pulled tasks over so either we're no
* longer idle, or one of our SMT siblings is
@@ -2995,7 +3116,114 @@ out:
if (!balance)
break;
}
- this_rq->next_balance = next_balance;
+ rq->next_balance = next_balance;
+}
+
+/*
+ * run_rebalance_domains is triggered when needed from the scheduler tick.
+ * In CONFIG_NO_HZ case, the idle load balance owner will do the
+ * rebalancing for all the cpus for whom scheduler ticks are stopped.
+ */
+static void run_rebalance_domains(struct softirq_action *h)
+{
+ int local_cpu = smp_processor_id();
+ struct rq *local_rq = cpu_rq(local_cpu);
+ enum idle_type idle = local_rq->idle_at_tick ? SCHED_IDLE : NOT_IDLE;
+
+ rebalance_domains(local_cpu, idle);
+
+#ifdef CONFIG_NO_HZ
+ /*
+ * If this cpu is the owner for idle load balancing, then do the
+ * balancing on behalf of the other idle cpus whose ticks are
+ * stopped.
+ */
+ if (local_rq->idle_at_tick &&
+ atomic_read(&nohz.load_balancer) == local_cpu) {
+ cpumask_t cpus = nohz.cpu_mask;
+ struct rq *rq;
+ int balance_cpu;
+
+ cpu_clear(local_cpu, cpus);
+ for_each_cpu_mask(balance_cpu, cpus) {
+ /*
+ * If this cpu gets work to do, stop the load balancing
+ * work being done for other cpus. Next load
+ * balancing owner will pick it up.
+ */
+ if (need_resched())
+ break;
+
+ rebalance_domains(balance_cpu, SCHED_IDLE);
+
+ rq = cpu_rq(balance_cpu);
+ if (time_after(local_rq->next_balance, rq->next_balance))
+ local_rq->next_balance = rq->next_balance;
+ }
+ }
+#endif
+}
+
+/*
+ * Trigger the SCHED_SOFTIRQ if it is time to do periodic load balancing.
+ *
+ * In case of CONFIG_NO_HZ, this is the place where we nominate a new
+ * idle load balancing owner or decide to stop the periodic load balancing,
+ * if the whole system is idle.
+ */
+static inline void trigger_load_balance(int cpu)
+{
+ struct rq *rq = cpu_rq(cpu);
+#ifdef CONFIG_NO_HZ
+ /*
+ * If we were in the nohz mode recently and busy at the current
+ * scheduler tick, then check if we need to nominate new idle
+ * load balancer.
+ */
+ if (rq->in_nohz_recently && !rq->idle_at_tick) {
+ rq->in_nohz_recently = 0;
+
+ if (atomic_read(&nohz.load_balancer) == cpu) {
+ cpu_clear(cpu, nohz.cpu_mask);
+ atomic_set(&nohz.load_balancer, -1);
+ }
+
+ if (atomic_read(&nohz.load_balancer) == -1) {
+ /*
+ * simple selection for now: Nominate the
+ * first cpu in the nohz list to be the next
+ * ilb owner.
+ *
+ * TBD: Traverse the sched domains and nominate
+ * the nearest cpu in the nohz.cpu_mask.
+ */
+ int ilb = first_cpu(nohz.cpu_mask);
+
+ if (ilb != NR_CPUS)
+ resched_cpu(ilb);
+ }
+ }
+
+ /*
+ * If this cpu is idle and doing idle load balancing for all the
+ * cpus with ticks stopped, is it time for that to stop?
+ */
+ if (rq->idle_at_tick && atomic_read(&nohz.load_balancer) == cpu &&
+ cpus_weight(nohz.cpu_mask) == num_online_cpus()) {
+ resched_cpu(cpu);
+ return;
+ }
+
+ /*
+ * If this cpu is idle and the idle load balancing is done by
+ * someone else, then no need raise the SCHED_SOFTIRQ
+ */
+ if (rq->idle_at_tick && atomic_read(&nohz.load_balancer) != cpu &&
+ cpu_isset(cpu, nohz.cpu_mask))
+ return;
+#endif
+ if (time_after_eq(jiffies, rq->next_balance))
+ raise_softirq(SCHED_SOFTIRQ);
}
#else
/*
@@ -3218,16 +3446,17 @@ void scheduler_tick(void)
unsigned long long now = sched_clock();
struct task_struct *p = current;
int cpu = smp_processor_id();
+ int idle_at_tick = idle_cpu(cpu);
struct rq *rq = cpu_rq(cpu);
update_cpu_clock(p, rq, now);
- if (p != rq->idle)
+ if (!idle_at_tick)
task_running_tick(rq, p);
#ifdef CONFIG_SMP
update_load(rq);
- if (time_after_eq(jiffies, rq->next_balance))
- raise_softirq(SCHED_SOFTIRQ);
+ rq->idle_at_tick = idle_at_tick;
+ trigger_load_balance(cpu);
#endif
}
@@ -3847,13 +4076,13 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
struct prio_array *array;
unsigned long flags;
struct rq *rq;
- int oldprio;
+ int delta;
BUG_ON(prio < 0 || prio > MAX_PRIO);
rq = task_rq_lock(p, &flags);
- oldprio = p->prio;
+ delta = prio - p->prio;
array = p->array;
if (array)
dequeue_task(p, array);
@@ -3869,13 +4098,11 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
enqueue_task(p, array);
/*
* Reschedule if we are currently running on this runqueue and
- * our priority decreased, or if we are not currently running on
- * this runqueue and our priority is higher than the current's
+ * our priority decreased, or if our priority became higher
+ * than the current's.
*/
- if (task_running(rq, p)) {
- if (p->prio > oldprio)
- resched_task(rq->curr);
- } else if (TASK_PREEMPTS_CURR(p, rq))
+ if (TASK_PREEMPTS_CURR(p, rq) ||
+ (delta > 0 && task_running(rq, p)))
resched_task(rq->curr);
}
task_rq_unlock(rq, &flags);
@@ -3923,10 +4150,12 @@ void set_user_nice(struct task_struct *p, long nice)
enqueue_task(p, array);
inc_raw_weighted_load(rq, p);
/*
- * If the task increased its priority or is running and
- * lowered its priority, then reschedule its CPU:
+ * Reschedule if we are currently running on this runqueue and
+ * our priority decreased, or if our priority became higher
+ * than the current's.
*/
- if (delta < 0 || (delta > 0 && task_running(rq, p)))
+ if (TASK_PREEMPTS_CURR(p, rq) ||
+ (delta > 0 && task_running(rq, p)))
resched_task(rq->curr);
}
out_unlock:
@@ -4153,13 +4382,11 @@ recheck:
__activate_task(p, rq);
/*
* Reschedule if we are currently running on this runqueue and
- * our priority decreased, or if we are not currently running on
- * this runqueue and our priority is higher than the current's
+ * our priority decreased, or our priority became higher
+ * than the current's.
*/
- if (task_running(rq, p)) {
- if (p->prio > oldprio)
- resched_task(rq->curr);
- } else if (TASK_PREEMPTS_CURR(p, rq))
+ if (TASK_PREEMPTS_CURR(p, rq) ||
+ (task_running(rq, p) && p->prio > oldprio))
resched_task(rq->curr);
}
__task_rq_unlock(rq);
@@ -4750,6 +4977,8 @@ void show_state_filter(unsigned long state_filter)
show_task(p);
} while_each_thread(g, p);
+ touch_all_softlockup_watchdogs();
+
read_unlock(&tasklist_lock);
/*
* Only show locks if all tasks are dumped:
@@ -5244,6 +5473,11 @@ int __init migration_init(void)
#endif
#ifdef CONFIG_SMP
+
+/* Number of possible processor ids */
+int nr_cpu_ids __read_mostly = NR_CPUS;
+EXPORT_SYMBOL(nr_cpu_ids);
+
#undef SCHED_DOMAIN_DEBUG
#ifdef SCHED_DOMAIN_DEBUG
static void sched_domain_debug(struct sched_domain *sd, int cpu)
@@ -5299,7 +5533,7 @@ static void sched_domain_debug(struct sched_domain *sd, int cpu)
break;
}
- if (!group->cpu_power) {
+ if (!group->__cpu_power) {
printk("\n");
printk(KERN_ERR "ERROR: domain->cpu_power not "
"set\n");
@@ -5476,7 +5710,7 @@ init_sched_build_groups(cpumask_t span, const cpumask_t *cpu_map,
continue;
sg->cpumask = CPU_MASK_NONE;
- sg->cpu_power = 0;
+ sg->__cpu_power = 0;
for_each_cpu_mask(j, span) {
if (group_fn(j, cpu_map, NULL) != group)
@@ -6165,7 +6399,7 @@ next_sg:
continue;
}
- sg->cpu_power += sd->groups->cpu_power;
+ sg_inc_cpu_power(sg, sd->groups->__cpu_power);
}
sg = sg->next;
if (sg != group_head)
@@ -6240,6 +6474,8 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd)
child = sd->child;
+ sd->groups->__cpu_power = 0;
+
/*
* For perf policy, if the groups in child domain share resources
* (for example cores sharing some portions of the cache hierarchy
@@ -6250,18 +6486,16 @@ static void init_sched_groups_power(int cpu, struct sched_domain *sd)
if (!child || (!(sd->flags & SD_POWERSAVINGS_BALANCE) &&
(child->flags &
(SD_SHARE_CPUPOWER | SD_SHARE_PKG_RESOURCES)))) {
- sd->groups->cpu_power = SCHED_LOAD_SCALE;
+ sg_inc_cpu_power(sd->groups, SCHED_LOAD_SCALE);
return;
}
- sd->groups->cpu_power = 0;
-
/*
* add cpu_power of each child group to this groups cpu_power
*/
group = child->groups;
do {
- sd->groups->cpu_power += group->cpu_power;
+ sg_inc_cpu_power(sd->groups, group->__cpu_power);
group = group->next;
} while (group != child->groups);
}
@@ -6421,7 +6655,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
sd = &per_cpu(node_domains, j);
sd->groups = sg;
}
- sg->cpu_power = 0;
+ sg->__cpu_power = 0;
sg->cpumask = nodemask;
sg->next = sg;
cpus_or(covered, covered, nodemask);
@@ -6449,7 +6683,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
"Can not alloc domain group for node %d\n", j);
goto error;
}
- sg->cpu_power = 0;
+ sg->__cpu_power = 0;
sg->cpumask = tmp;
sg->next = prev->next;
cpus_or(covered, covered, tmp);
@@ -6726,6 +6960,7 @@ int in_sched_functions(unsigned long addr)
void __init sched_init(void)
{
int i, j, k;
+ int highest_cpu = 0;
for_each_possible_cpu(i) {
struct prio_array *array;
@@ -6760,11 +6995,13 @@ void __init sched_init(void)
// delimiter for bitsearch
__set_bit(MAX_PRIO, array->bitmap);
}
+ highest_cpu = i;
}
set_load_weight(&init_task);
#ifdef CONFIG_SMP
+ nr_cpu_ids = highest_cpu + 1;
open_softirq(SCHED_SOFTIRQ, run_rebalance_domains, NULL);
#endif
diff --git a/kernel/signal.c b/kernel/signal.c
index 3670225..1368e67 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -12,7 +12,6 @@
#include <linux/slab.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/fs.h>
@@ -2636,9 +2635,5 @@ __attribute__((weak)) const char *arch_vma_name(struct vm_area_struct *vma)
void __init signals_init(void)
{
- sigqueue_cachep =
- kmem_cache_create("sigqueue",
- sizeof(struct sigqueue),
- __alignof__(struct sigqueue),
- SLAB_PANIC, NULL, NULL);
+ sigqueue_cachep = KMEM_CACHE(sigqueue, SLAB_PANIC);
}
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index 50afeb8..8fa7040 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -34,12 +34,32 @@ static struct notifier_block panic_block = {
.notifier_call = softlock_panic,
};
+/*
+ * Returns seconds, approximately. We don't need nanosecond
+ * resolution, and we don't need to waste time with a big divide when
+ * 2^30ns == 1.074s.
+ */
+static unsigned long get_timestamp(void)
+{
+ return sched_clock() >> 30; /* 2^30 ~= 10^9 */
+}
+
void touch_softlockup_watchdog(void)
{
- __raw_get_cpu_var(touch_timestamp) = jiffies;
+ __raw_get_cpu_var(touch_timestamp) = get_timestamp();
}
EXPORT_SYMBOL(touch_softlockup_watchdog);
+void touch_all_softlockup_watchdogs(void)
+{
+ int cpu;
+
+ /* Cause each CPU to re-update its timestamp rather than complain */
+ for_each_online_cpu(cpu)
+ per_cpu(touch_timestamp, cpu) = 0;
+}
+EXPORT_SYMBOL(touch_all_softlockup_watchdogs);
+
/*
* This callback runs from the timer interrupt, and checks
* whether the watchdog thread has hung or not:
@@ -48,9 +68,18 @@ void softlockup_tick(void)
{
int this_cpu = smp_processor_id();
unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu);
+ unsigned long print_timestamp;
+ unsigned long now;
+
+ if (touch_timestamp == 0) {
+ touch_softlockup_watchdog();
+ return;
+ }
+
+ print_timestamp = per_cpu(print_timestamp, this_cpu);
- /* prevent double reports: */
- if (per_cpu(print_timestamp, this_cpu) == touch_timestamp ||
+ /* report at most once a second */
+ if (print_timestamp < (touch_timestamp + 1) ||
did_panic ||
!per_cpu(watchdog_task, this_cpu))
return;
@@ -61,12 +90,14 @@ void softlockup_tick(void)
return;
}
+ now = get_timestamp();
+
/* Wake up the high-prio watchdog task every second: */
- if (time_after(jiffies, touch_timestamp + HZ))
+ if (now > (touch_timestamp + 1))
wake_up_process(per_cpu(watchdog_task, this_cpu));
/* Warn about unreasonable 10+ seconds delays: */
- if (time_after(jiffies, touch_timestamp + 10*HZ)) {
+ if (now > (touch_timestamp + 10)) {
per_cpu(print_timestamp, this_cpu) = touch_timestamp;
spin_lock(&print_lock);
@@ -82,11 +113,14 @@ void softlockup_tick(void)
*/
static int watchdog(void * __bind_cpu)
{
- struct sched_param param = { .sched_priority = 99 };
+ struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
sched_setscheduler(current, SCHED_FIFO, &param);
current->flags |= PF_NOFREEZE;
+ /* initialize timestamp */
+ touch_softlockup_watchdog();
+
/*
* Run briefly once per second to reset the softlockup timestamp.
* If this gets delayed for more than 10 seconds then the
@@ -118,7 +152,7 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
printk("watchdog for %i failed\n", hotcpu);
return NOTIFY_BAD;
}
- per_cpu(touch_timestamp, hotcpu) = jiffies;
+ per_cpu(touch_timestamp, hotcpu) = 0;
per_cpu(watchdog_task, hotcpu) = p;
kthread_bind(p, hotcpu);
break;
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
index 1245804..daabb74 100644
--- a/kernel/stop_machine.c
+++ b/kernel/stop_machine.c
@@ -1,11 +1,12 @@
/* Copyright 2005 Rusty Russell rusty@rustcorp.com.au IBM Corporation.
* GPL v2 and any later version.
*/
-#include <linux/stop_machine.h>
-#include <linux/kthread.h>
-#include <linux/sched.h>
#include <linux/cpu.h>
#include <linux/err.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/stop_machine.h>
#include <linux/syscalls.h>
#include <asm/atomic.h>
#include <asm/semaphore.h>
@@ -208,3 +209,4 @@ int stop_machine_run(int (*fn)(void *), void *data, unsigned int cpu)
return ret;
}
+EXPORT_SYMBOL_GPL(stop_machine_run);
diff --git a/kernel/sys.c b/kernel/sys.c
index 123b165..926bf9d 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -881,7 +881,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
#ifdef CONFIG_SOFTWARE_SUSPEND
case LINUX_REBOOT_CMD_SW_SUSPEND:
{
- int ret = software_suspend();
+ int ret = pm_suspend(PM_SUSPEND_DISK);
unlock_kernel();
return ret;
}
@@ -1923,6 +1923,16 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
if (retval)
return retval;
+ if (resource == RLIMIT_CPU && new_rlim.rlim_cur == 0) {
+ /*
+ * The caller is asking for an immediate RLIMIT_CPU
+ * expiry. But we use the zero value to mean "it was
+ * never set". So let's cheat and make it one second
+ * instead
+ */
+ new_rlim.rlim_cur = 1;
+ }
+
task_lock(current->group_leader);
*old_rlim = new_rlim;
task_unlock(current->group_leader);
@@ -1944,15 +1954,6 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
unsigned long rlim_cur = new_rlim.rlim_cur;
cputime_t cputime;
- if (rlim_cur == 0) {
- /*
- * The caller is asking for an immediate RLIMIT_CPU
- * expiry. But we use the zero value to mean "it was
- * never set". So let's cheat and make it one second
- * instead
- */
- rlim_cur = 1;
- }
cputime = secs_to_cputime(rlim_cur);
read_lock(&tasklist_lock);
spin_lock_irq(&current->sighand->siglock);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c904748..f0664bd 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -76,6 +76,7 @@ extern int pid_max_min, pid_max_max;
extern int sysctl_drop_caches;
extern int percpu_pagelist_fraction;
extern int compat_log;
+extern int maps_protect;
/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
static int maxolduid = 65535;
@@ -603,6 +604,16 @@ static ctl_table kern_table[] = {
.proc_handler = &proc_dointvec,
},
#endif
+#ifdef CONFIG_PROC_FS
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "maps_protect",
+ .data = &maps_protect,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+#endif
{ .ctl_name = 0 }
};
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index ad7d239..906cae7 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -524,9 +524,7 @@ void __init taskstats_init_early(void)
{
unsigned int i;
- taskstats_cache = kmem_cache_create("taskstats_cache",
- sizeof(struct taskstats),
- 0, SLAB_PANIC, NULL, NULL);
+ taskstats_cache = KMEM_CACHE(taskstats, SLAB_PANIC);
for_each_possible_cpu(i) {
INIT_LIST_HEAD(&(per_cpu(listener_array, i).list));
init_rwsem(&(per_cpu(listener_array, i).sem));
diff --git a/kernel/time.c b/kernel/time.c
index ba18ec4..f04791f 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -31,7 +31,6 @@
#include <linux/timex.h>
#include <linux/capability.h>
#include <linux/errno.h>
-#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/security.h>
#include <linux/fs.h>
@@ -247,6 +246,36 @@ struct timespec current_fs_time(struct super_block *sb)
}
EXPORT_SYMBOL(current_fs_time);
+/*
+ * Convert jiffies to milliseconds and back.
+ *
+ * Avoid unnecessary multiplications/divisions in the
+ * two most common HZ cases:
+ */
+unsigned int inline jiffies_to_msecs(const unsigned long j)
+{
+#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
+ return (MSEC_PER_SEC / HZ) * j;
+#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
+ return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
+#else
+ return (j * MSEC_PER_SEC) / HZ;
+#endif
+}
+EXPORT_SYMBOL(jiffies_to_msecs);
+
+unsigned int inline jiffies_to_usecs(const unsigned long j)
+{
+#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
+ return (USEC_PER_SEC / HZ) * j;
+#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
+ return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
+#else
+ return (j * USEC_PER_SEC) / HZ;
+#endif
+}
+EXPORT_SYMBOL(jiffies_to_usecs);
+
/**
* timespec_trunc - Truncate timespec to a granularity
* @t: Timespec
@@ -473,36 +502,6 @@ struct timeval ns_to_timeval(const s64 nsec)
EXPORT_SYMBOL(ns_to_timeval);
/*
- * Convert jiffies to milliseconds and back.
- *
- * Avoid unnecessary multiplications/divisions in the
- * two most common HZ cases:
- */
-unsigned int jiffies_to_msecs(const unsigned long j)
-{
-#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
- return (MSEC_PER_SEC / HZ) * j;
-#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
- return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC);
-#else
- return (j * MSEC_PER_SEC) / HZ;
-#endif
-}
-EXPORT_SYMBOL(jiffies_to_msecs);
-
-unsigned int jiffies_to_usecs(const unsigned long j)
-{
-#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
- return (USEC_PER_SEC / HZ) * j;
-#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
- return (j + (HZ / USEC_PER_SEC) - 1)/(HZ / USEC_PER_SEC);
-#else
- return (j * USEC_PER_SEC) / HZ;
-#endif
-}
-EXPORT_SYMBOL(jiffies_to_usecs);
-
-/*
* When we convert to jiffies then we interpret incoming values
* the following way:
*
diff --git a/kernel/time/Makefile b/kernel/time/Makefile
index 93bccba..99b6034 100644
--- a/kernel/time/Makefile
+++ b/kernel/time/Makefile
@@ -1,4 +1,4 @@
-obj-y += ntp.o clocksource.o jiffies.o timer_list.o
+obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS) += clockevents.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index bfda3f7..a96ec9a 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -31,7 +31,7 @@ DEFINE_PER_CPU(struct tick_device, tick_cpu_device);
*/
ktime_t tick_next_period;
ktime_t tick_period;
-static int tick_do_timer_cpu = -1;
+int tick_do_timer_cpu __read_mostly = -1;
DEFINE_SPINLOCK(tick_device_lock);
/*
@@ -295,6 +295,12 @@ static void tick_shutdown(unsigned int *cpup)
clockevents_exchange_device(dev, NULL);
td->evtdev = NULL;
}
+ /* Transfer the do_timer job away from this cpu */
+ if (*cpup == tick_do_timer_cpu) {
+ int cpu = first_cpu(cpu_online_map);
+
+ tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : -1;
+ }
spin_unlock_irqrestore(&tick_device_lock, flags);
}
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index c9d203b..bb13f27 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -5,6 +5,7 @@ DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
extern spinlock_t tick_device_lock;
extern ktime_t tick_next_period;
extern ktime_t tick_period;
+extern int tick_do_timer_cpu __read_mostly;
extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
extern void tick_handle_periodic(struct clock_event_device *dev);
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 51556b9..3483e6c 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -217,10 +217,30 @@ void tick_nohz_stop_sched_tick(void)
* the scheduler tick in nohz_restart_sched_tick.
*/
if (!ts->tick_stopped) {
+ if (select_nohz_load_balancer(1)) {
+ /*
+ * sched tick not stopped!
+ */
+ cpu_clear(cpu, nohz_cpu_mask);
+ goto out;
+ }
+
ts->idle_tick = ts->sched_timer.expires;
ts->tick_stopped = 1;
ts->idle_jiffies = last_jiffies;
}
+
+ /*
+ * If this cpu is the one which updates jiffies, then
+ * give up the assignment and let it be taken by the
+ * cpu which runs the tick timer next, which might be
+ * this cpu as well. If we don't drop this here the
+ * jiffies might be stale and do_timer() never
+ * invoked.
+ */
+ if (cpu == tick_do_timer_cpu)
+ tick_do_timer_cpu = -1;
+
/*
* calculate the expiry time for the next timer wheel
* timer
@@ -273,6 +293,7 @@ void tick_nohz_restart_sched_tick(void)
now = ktime_get();
local_irq_disable();
+ select_nohz_load_balancer(0);
tick_do_update_jiffies64(now);
cpu_clear(cpu, nohz_cpu_mask);
@@ -338,12 +359,24 @@ static void tick_nohz_handler(struct clock_event_device *dev)
{
struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
struct pt_regs *regs = get_irq_regs();
+ int cpu = smp_processor_id();
ktime_t now = ktime_get();
dev->next_event.tv64 = KTIME_MAX;
+ /*
+ * Check if the do_timer duty was dropped. We don't care about
+ * concurrency: This happens only when the cpu in charge went
+ * into a long sleep. If two cpus happen to assign themself to
+ * this duty, then the jiffies update is still serialized by
+ * xtime_lock.
+ */
+ if (unlikely(tick_do_timer_cpu == -1))
+ tick_do_timer_cpu = cpu;
+
/* Check, if the jiffies need an update */
- tick_do_update_jiffies64(now);
+ if (tick_do_timer_cpu == cpu)
+ tick_do_update_jiffies64(now);
/*
* When we are idle and the tick is stopped, we have to touch
@@ -431,9 +464,23 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
struct hrtimer_cpu_base *base = timer->base->cpu_base;
struct pt_regs *regs = get_irq_regs();
ktime_t now = ktime_get();
+ int cpu = smp_processor_id();
+
+#ifdef CONFIG_NO_HZ
+ /*
+ * Check if the do_timer duty was dropped. We don't care about
+ * concurrency: This happens only when the cpu in charge went
+ * into a long sleep. If two cpus happen to assign themself to
+ * this duty, then the jiffies update is still serialized by
+ * xtime_lock.
+ */
+ if (unlikely(tick_do_timer_cpu == -1))
+ tick_do_timer_cpu = cpu;
+#endif
/* Check, if the jiffies need an update */
- tick_do_update_jiffies64(now);
+ if (tick_do_timer_cpu == cpu)
+ tick_do_update_jiffies64(now);
/*
* Do not call, when we are not in irq context and have
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
new file mode 100644
index 0000000..f9217bf
--- /dev/null
+++ b/kernel/time/timekeeping.c
@@ -0,0 +1,476 @@
+/*
+ * linux/kernel/time/timekeeping.c
+ *
+ * Kernel timekeeping code and accessor functions
+ *
+ * This code was moved from linux/kernel/timer.c.
+ * Please see that file for copyright and history logs.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sysdev.h>
+#include <linux/clocksource.h>
+#include <linux/jiffies.h>
+#include <linux/time.h>
+#include <linux/tick.h>
+
+
+/*
+ * This read-write spinlock protects us from races in SMP while
+ * playing with xtime and avenrun.
+ */
+__attribute__((weak)) __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
+
+EXPORT_SYMBOL(xtime_lock);
+
+
+/*
+ * The current time
+ * wall_to_monotonic is what we need to add to xtime (or xtime corrected
+ * for sub jiffie times) to get to monotonic time. Monotonic is pegged
+ * at zero at system boot time, so wall_to_monotonic will be negative,
+ * however, we will ALWAYS keep the tv_nsec part positive so we can use
+ * the usual normalization.
+ */
+struct timespec xtime __attribute__ ((aligned (16)));
+struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
+
+EXPORT_SYMBOL(xtime);
+
+
+static struct clocksource *clock; /* pointer to current clocksource */
+
+
+#ifdef CONFIG_GENERIC_TIME
+/**
+ * __get_nsec_offset - Returns nanoseconds since last call to periodic_hook
+ *
+ * private function, must hold xtime_lock lock when being
+ * called. Returns the number of nanoseconds since the
+ * last call to update_wall_time() (adjusted by NTP scaling)
+ */
+static inline s64 __get_nsec_offset(void)
+{
+ cycle_t cycle_now, cycle_delta;
+ s64 ns_offset;
+
+ /* read clocksource: */
+ cycle_now = clocksource_read(clock);
+
+ /* calculate the delta since the last update_wall_time: */
+ cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
+
+ /* convert to nanoseconds: */
+ ns_offset = cyc2ns(clock, cycle_delta);
+
+ return ns_offset;
+}
+
+/**
+ * __get_realtime_clock_ts - Returns the time of day in a timespec
+ * @ts: pointer to the timespec to be set
+ *
+ * Returns the time of day in a timespec. Used by
+ * do_gettimeofday() and get_realtime_clock_ts().
+ */
+static inline void __get_realtime_clock_ts(struct timespec *ts)
+{
+ unsigned long seq;
+ s64 nsecs;
+
+ do {
+ seq = read_seqbegin(&xtime_lock);
+
+ *ts = xtime;
+ nsecs = __get_nsec_offset();
+
+ } while (read_seqretry(&xtime_lock, seq));
+
+ timespec_add_ns(ts, nsecs);
+}
+
+/**
+ * getnstimeofday - Returns the time of day in a timespec
+ * @ts: pointer to the timespec to be set
+ *
+ * Returns the time of day in a timespec.
+ */
+void getnstimeofday(struct timespec *ts)
+{
+ __get_realtime_clock_ts(ts);
+}
+
+EXPORT_SYMBOL(getnstimeofday);
+
+/**
+ * do_gettimeofday - Returns the time of day in a timeval
+ * @tv: pointer to the timeval to be set
+ *
+ * NOTE: Users should be converted to using get_realtime_clock_ts()
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+ struct timespec now;
+
+ __get_realtime_clock_ts(&now);
+ tv->tv_sec = now.tv_sec;
+ tv->tv_usec = now.tv_nsec/1000;
+}
+
+EXPORT_SYMBOL(do_gettimeofday);
+/**
+ * do_settimeofday - Sets the time of day
+ * @tv: pointer to the timespec variable containing the new time
+ *
+ * Sets the time of day to the new time and update NTP and notify hrtimers
+ */
+int do_settimeofday(struct timespec *tv)
+{
+ unsigned long flags;
+ time_t wtm_sec, sec = tv->tv_sec;
+ long wtm_nsec, nsec = tv->tv_nsec;
+
+ if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
+ return -EINVAL;
+
+ write_seqlock_irqsave(&xtime_lock, flags);
+
+ nsec -= __get_nsec_offset();
+
+ wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
+ wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
+
+ set_normalized_timespec(&xtime, sec, nsec);
+ set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+
+ clock->error = 0;
+ ntp_clear();
+
+ update_vsyscall(&xtime, clock);
+
+ write_sequnlock_irqrestore(&xtime_lock, flags);
+
+ /* signal hrtimers about time change */
+ clock_was_set();
+
+ return 0;
+}
+
+EXPORT_SYMBOL(do_settimeofday);
+
+/**
+ * change_clocksource - Swaps clocksources if a new one is available
+ *
+ * Accumulates current time interval and initializes new clocksource
+ */
+static void change_clocksource(void)
+{
+ struct clocksource *new;
+ cycle_t now;
+ u64 nsec;
+
+ new = clocksource_get_next();
+
+ if (clock == new)
+ return;
+
+ now = clocksource_read(new);
+ nsec = __get_nsec_offset();
+ timespec_add_ns(&xtime, nsec);
+
+ clock = new;
+ clock->cycle_last = now;
+
+ clock->error = 0;
+ clock->xtime_nsec = 0;
+ clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
+
+ tick_clock_notify();
+
+ printk(KERN_INFO "Time: %s clocksource has been installed.\n",
+ clock->name);
+}
+#else
+static inline void change_clocksource(void) { }
+#endif
+
+/**
+ * timekeeping_is_continuous - check to see if timekeeping is free running
+ */
+int timekeeping_is_continuous(void)
+{
+ unsigned long seq;
+ int ret;
+
+ do {
+ seq = read_seqbegin(&xtime_lock);
+
+ ret = clock->flags & CLOCK_SOURCE_VALID_FOR_HRES;
+
+ } while (read_seqretry(&xtime_lock, seq));
+
+ return ret;
+}
+
+/**
+ * read_persistent_clock - Return time in seconds from the persistent clock.
+ *
+ * Weak dummy function for arches that do not yet support it.
+ * Returns seconds from epoch using the battery backed persistent clock.
+ * Returns zero if unsupported.
+ *
+ * XXX - Do be sure to remove it once all arches implement it.
+ */
+unsigned long __attribute__((weak)) read_persistent_clock(void)
+{
+ return 0;
+}
+
+/*
+ * timekeeping_init - Initializes the clocksource and common timekeeping values
+ */
+void __init timekeeping_init(void)
+{
+ unsigned long flags;
+ unsigned long sec = read_persistent_clock();
+
+ write_seqlock_irqsave(&xtime_lock, flags);
+
+ ntp_clear();
+
+ clock = clocksource_get_next();
+ clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
+ clock->cycle_last = clocksource_read(clock);
+
+ xtime.tv_sec = sec;
+ xtime.tv_nsec = 0;
+ set_normalized_timespec(&wall_to_monotonic,
+ -xtime.tv_sec, -xtime.tv_nsec);
+
+ write_sequnlock_irqrestore(&xtime_lock, flags);
+}
+
+/* flag for if timekeeping is suspended */
+static int timekeeping_suspended;
+/* time in seconds when suspend began */
+static unsigned long timekeeping_suspend_time;
+
+/**
+ * timekeeping_resume - Resumes the generic timekeeping subsystem.
+ * @dev: unused
+ *
+ * This is for the generic clocksource timekeeping.
+ * xtime/wall_to_monotonic/jiffies/etc are
+ * still managed by arch specific suspend/resume code.
+ */
+static int timekeeping_resume(struct sys_device *dev)
+{
+ unsigned long flags;
+ unsigned long now = read_persistent_clock();
+
+ write_seqlock_irqsave(&xtime_lock, flags);
+
+ if (now && (now > timekeeping_suspend_time)) {
+ unsigned long sleep_length = now - timekeeping_suspend_time;
+
+ xtime.tv_sec += sleep_length;
+ wall_to_monotonic.tv_sec -= sleep_length;
+ }
+ /* re-base the last cycle value */
+ clock->cycle_last = clocksource_read(clock);
+ clock->error = 0;
+ timekeeping_suspended = 0;
+ write_sequnlock_irqrestore(&xtime_lock, flags);
+
+ touch_softlockup_watchdog();
+
+ clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL);
+
+ /* Resume hrtimers */
+ hres_timers_resume();
+
+ return 0;
+}
+
+static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
+{
+ unsigned long flags;
+
+ write_seqlock_irqsave(&xtime_lock, flags);
+ timekeeping_suspended = 1;
+ timekeeping_suspend_time = read_persistent_clock();
+ write_sequnlock_irqrestore(&xtime_lock, flags);
+
+ clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL);
+
+ return 0;
+}
+
+/* sysfs resume/suspend bits for timekeeping */
+static struct sysdev_class timekeeping_sysclass = {
+ .resume = timekeeping_resume,
+ .suspend = timekeeping_suspend,
+ set_kset_name("timekeeping"),
+};
+
+static struct sys_device device_timer = {
+ .id = 0,
+ .cls = &timekeeping_sysclass,
+};
+
+static int __init timekeeping_init_device(void)
+{
+ int error = sysdev_class_register(&timekeeping_sysclass);
+ if (!error)
+ error = sysdev_register(&device_timer);
+ return error;
+}
+
+device_initcall(timekeeping_init_device);
+
+/*
+ * If the error is already larger, we look ahead even further
+ * to compensate for late or lost adjustments.
+ */
+static __always_inline int clocksource_bigadjust(s64 error, s64 *interval,
+ s64 *offset)
+{
+ s64 tick_error, i;
+ u32 look_ahead, adj;
+ s32 error2, mult;
+
+ /*
+ * Use the current error value to determine how much to look ahead.
+ * The larger the error the slower we adjust for it to avoid problems
+ * with losing too many ticks, otherwise we would overadjust and
+ * produce an even larger error. The smaller the adjustment the
+ * faster we try to adjust for it, as lost ticks can do less harm
+ * here. This is tuned so that an error of about 1 msec is adusted
+ * within about 1 sec (or 2^20 nsec in 2^SHIFT_HZ ticks).
+ */
+ error2 = clock->error >> (TICK_LENGTH_SHIFT + 22 - 2 * SHIFT_HZ);
+ error2 = abs(error2);
+ for (look_ahead = 0; error2 > 0; look_ahead++)
+ error2 >>= 2;
+
+ /*
+ * Now calculate the error in (1 << look_ahead) ticks, but first
+ * remove the single look ahead already included in the error.
+ */
+ tick_error = current_tick_length() >>
+ (TICK_LENGTH_SHIFT - clock->shift + 1);
+ tick_error -= clock->xtime_interval >> 1;
+ error = ((error - tick_error) >> look_ahead) + tick_error;
+
+ /* Finally calculate the adjustment shift value. */
+ i = *interval;
+ mult = 1;
+ if (error < 0) {
+ error = -error;
+ *interval = -*interval;
+ *offset = -*offset;
+ mult = -1;
+ }
+ for (adj = 0; error > i; adj++)
+ error >>= 1;
+
+ *interval <<= adj;
+ *offset <<= adj;
+ return mult << adj;
+}
+
+/*
+ * Adjust the multiplier to reduce the error value,
+ * this is optimized for the most common adjustments of -1,0,1,
+ * for other values we can do a bit more work.
+ */
+static void clocksource_adjust(struct clocksource *clock, s64 offset)
+{
+ s64 error, interval = clock->cycle_interval;
+ int adj;
+
+ error = clock->error >> (TICK_LENGTH_SHIFT - clock->shift - 1);
+ if (error > interval) {
+ error >>= 2;
+ if (likely(error <= interval))
+ adj = 1;
+ else
+ adj = clocksource_bigadjust(error, &interval, &offset);
+ } else if (error < -interval) {
+ error >>= 2;
+ if (likely(error >= -interval)) {
+ adj = -1;
+ interval = -interval;
+ offset = -offset;
+ } else
+ adj = clocksource_bigadjust(error, &interval, &offset);
+ } else
+ return;
+
+ clock->mult += adj;
+ clock->xtime_interval += interval;
+ clock->xtime_nsec -= offset;
+ clock->error -= (interval - offset) <<
+ (TICK_LENGTH_SHIFT - clock->shift);
+}
+
+/**
+ * update_wall_time - Uses the current clocksource to increment the wall time
+ *
+ * Called from the timer interrupt, must hold a write on xtime_lock.
+ */
+void update_wall_time(void)
+{
+ cycle_t offset;
+
+ /* Make sure we're fully resumed: */
+ if (unlikely(timekeeping_suspended))
+ return;
+
+#ifdef CONFIG_GENERIC_TIME
+ offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask;
+#else
+ offset = clock->cycle_interval;
+#endif
+ clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
+
+ /* normally this loop will run just once, however in the
+ * case of lost or late ticks, it will accumulate correctly.
+ */
+ while (offset >= clock->cycle_interval) {
+ /* accumulate one interval */
+ clock->xtime_nsec += clock->xtime_interval;
+ clock->cycle_last += clock->cycle_interval;
+ offset -= clock->cycle_interval;
+
+ if (clock->xtime_nsec >= (u64)NSEC_PER_SEC << clock->shift) {
+ clock->xtime_nsec -= (u64)NSEC_PER_SEC << clock->shift;
+ xtime.tv_sec++;
+ second_overflow();
+ }
+
+ /* interpolator bits */
+ time_interpolator_update(clock->xtime_interval
+ >> clock->shift);
+
+ /* accumulate error between NTP and clock interval */
+ clock->error += current_tick_length();
+ clock->error -= clock->xtime_interval << (TICK_LENGTH_SHIFT - clock->shift);
+ }
+
+ /* correct the clock when NTP error is too big */
+ clocksource_adjust(clock, offset);
+
+ /* store full nanoseconds into xtime */
+ xtime.tv_nsec = (s64)clock->xtime_nsec >> clock->shift;
+ clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift;
+
+ /* check to see if there is a new clocksource to use */
+ change_clocksource();
+ update_vsyscall(&xtime, clock);
+}
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index 59df5e8..b734ca4 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -38,17 +38,12 @@ DECLARE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases);
static void print_name_offset(struct seq_file *m, void *sym)
{
- unsigned long addr = (unsigned long)sym;
- char namebuf[KSYM_NAME_LEN+1];
- unsigned long size, offset;
- const char *sym_name;
- char *modname;
-
- sym_name = kallsyms_lookup(addr, &size, &offset, &modname, namebuf);
- if (sym_name)
- SEQ_printf(m, "%s", sym_name);
- else
+ char symname[KSYM_NAME_LEN+1];
+
+ if (lookup_symbol_name((unsigned long)sym, symname) < 0)
SEQ_printf(m, "<%p>", sym);
+ else
+ SEQ_printf(m, "%s", symname);
}
static void
diff --git a/kernel/time/timer_stats.c b/kernel/time/timer_stats.c
index 1bc4882..868f1bc 100644
--- a/kernel/time/timer_stats.c
+++ b/kernel/time/timer_stats.c
@@ -257,16 +257,12 @@ void timer_stats_update_stats(void *timer, pid_t pid, void *startf,
static void print_name_offset(struct seq_file *m, unsigned long addr)
{
- char namebuf[KSYM_NAME_LEN+1];
- unsigned long size, offset;
- const char *sym_name;
- char *modname;
-
- sym_name = kallsyms_lookup(addr, &size, &offset, &modname, namebuf);
- if (sym_name)
- seq_printf(m, "%s", sym_name);
- else
+ char symname[KSYM_NAME_LEN+1];
+
+ if (lookup_symbol_name(addr, symname) < 0)
seq_printf(m, "<%p>", (void *)addr);
+ else
+ seq_printf(m, "%s", symname);
}
static int tstats_show(struct seq_file *m, void *v)
diff --git a/kernel/timer.c b/kernel/timer.c
index b22bd39..7a64483 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/timer.c
*
- * Kernel internal timers, kernel timekeeping, basic process system calls
+ * Kernel internal timers, basic process system calls
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
@@ -74,7 +74,7 @@ struct tvec_t_base_s {
tvec_t tv3;
tvec_t tv4;
tvec_t tv5;
-} ____cacheline_aligned_in_smp;
+} ____cacheline_aligned;
typedef struct tvec_t_base_s tvec_base_t;
@@ -82,6 +82,37 @@ tvec_base_t boot_tvec_bases;
EXPORT_SYMBOL(boot_tvec_bases);
static DEFINE_PER_CPU(tvec_base_t *, tvec_bases) = &boot_tvec_bases;
+/*
+ * Note that all tvec_bases is 2 byte aligned and lower bit of
+ * base in timer_list is guaranteed to be zero. Use the LSB for
+ * the new flag to indicate whether the timer is deferrable
+ */
+#define TBASE_DEFERRABLE_FLAG (0x1)
+
+/* Functions below help us manage 'deferrable' flag */
+static inline unsigned int tbase_get_deferrable(tvec_base_t *base)
+{
+ return ((unsigned int)(unsigned long)base & TBASE_DEFERRABLE_FLAG);
+}
+
+static inline tvec_base_t *tbase_get_base(tvec_base_t *base)
+{
+ return ((tvec_base_t *)((unsigned long)base & ~TBASE_DEFERRABLE_FLAG));
+}
+
+static inline void timer_set_deferrable(struct timer_list *timer)
+{
+ timer->base = ((tvec_base_t *)((unsigned long)(timer->base) |
+ TBASE_DEFERRABLE_FLAG));
+}
+
+static inline void
+timer_set_base(struct timer_list *timer, tvec_base_t *new_base)
+{
+ timer->base = (tvec_base_t *)((unsigned long)(new_base) |
+ tbase_get_deferrable(timer->base));
+}
+
/**
* __round_jiffies - function to round jiffies to a full second
* @j: the time in (absolute) jiffies that should be rounded
@@ -295,6 +326,13 @@ void fastcall init_timer(struct timer_list *timer)
}
EXPORT_SYMBOL(init_timer);
+void fastcall init_timer_deferrable(struct timer_list *timer)
+{
+ init_timer(timer);
+ timer_set_deferrable(timer);
+}
+EXPORT_SYMBOL(init_timer_deferrable);
+
static inline void detach_timer(struct timer_list *timer,
int clear_pending)
{
@@ -325,10 +363,11 @@ static tvec_base_t *lock_timer_base(struct timer_list *timer,
tvec_base_t *base;
for (;;) {
- base = timer->base;
+ tvec_base_t *prelock_base = timer->base;
+ base = tbase_get_base(prelock_base);
if (likely(base != NULL)) {
spin_lock_irqsave(&base->lock, *flags);
- if (likely(base == timer->base))
+ if (likely(prelock_base == timer->base))
return base;
/* The timer has migrated to another CPU */
spin_unlock_irqrestore(&base->lock, *flags);
@@ -365,11 +404,11 @@ int __mod_timer(struct timer_list *timer, unsigned long expires)
*/
if (likely(base->running_timer != timer)) {
/* See the comment in lock_timer_base() */
- timer->base = NULL;
+ timer_set_base(timer, NULL);
spin_unlock(&base->lock);
base = new_base;
spin_lock(&base->lock);
- timer->base = base;
+ timer_set_base(timer, base);
}
}
@@ -397,7 +436,7 @@ void add_timer_on(struct timer_list *timer, int cpu)
timer_stats_timer_set_start_info(timer);
BUG_ON(timer_pending(timer) || !timer->function);
spin_lock_irqsave(&base->lock, flags);
- timer->base = base;
+ timer_set_base(timer, base);
internal_add_timer(base, timer);
spin_unlock_irqrestore(&base->lock, flags);
}
@@ -550,7 +589,7 @@ static int cascade(tvec_base_t *base, tvec_t *tv, int index)
* don't have to detach them individually.
*/
list_for_each_entry_safe(timer, tmp, &tv_list, entry) {
- BUG_ON(timer->base != base);
+ BUG_ON(tbase_get_base(timer->base) != base);
internal_add_timer(base, timer);
}
@@ -590,7 +629,7 @@ static inline void __run_timers(tvec_base_t *base)
void (*fn)(unsigned long);
unsigned long data;
- timer = list_entry(head->next,struct timer_list,entry);
+ timer = list_first_entry(head, struct timer_list,entry);
fn = timer->function;
data = timer->data;
@@ -636,6 +675,9 @@ static unsigned long __next_timer_interrupt(tvec_base_t *base)
index = slot = timer_jiffies & TVR_MASK;
do {
list_for_each_entry(nte, base->tv1.vec + slot, entry) {
+ if (tbase_get_deferrable(nte->base))
+ continue;
+
found = 1;
expires = nte->expires;
/* Look at the cascade bucket(s)? */
@@ -752,455 +794,6 @@ unsigned long next_timer_interrupt(void)
#endif
-/******************************************************************/
-
-/*
- * The current time
- * wall_to_monotonic is what we need to add to xtime (or xtime corrected
- * for sub jiffie times) to get to monotonic time. Monotonic is pegged
- * at zero at system boot time, so wall_to_monotonic will be negative,
- * however, we will ALWAYS keep the tv_nsec part positive so we can use
- * the usual normalization.
- */
-struct timespec xtime __attribute__ ((aligned (16)));
-struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
-
-EXPORT_SYMBOL(xtime);
-
-
-/* XXX - all of this timekeeping code should be later moved to time.c */
-#include <linux/clocksource.h>
-static struct clocksource *clock; /* pointer to current clocksource */
-
-#ifdef CONFIG_GENERIC_TIME
-/**
- * __get_nsec_offset - Returns nanoseconds since last call to periodic_hook
- *
- * private function, must hold xtime_lock lock when being
- * called. Returns the number of nanoseconds since the
- * last call to update_wall_time() (adjusted by NTP scaling)
- */
-static inline s64 __get_nsec_offset(void)
-{
- cycle_t cycle_now, cycle_delta;
- s64 ns_offset;
-
- /* read clocksource: */
- cycle_now = clocksource_read(clock);
-
- /* calculate the delta since the last update_wall_time: */
- cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
-
- /* convert to nanoseconds: */
- ns_offset = cyc2ns(clock, cycle_delta);
-
- return ns_offset;
-}
-
-/**
- * __get_realtime_clock_ts - Returns the time of day in a timespec
- * @ts: pointer to the timespec to be set
- *
- * Returns the time of day in a timespec. Used by
- * do_gettimeofday() and get_realtime_clock_ts().
- */
-static inline void __get_realtime_clock_ts(struct timespec *ts)
-{
- unsigned long seq;
- s64 nsecs;
-
- do {
- seq = read_seqbegin(&xtime_lock);
-
- *ts = xtime;
- nsecs = __get_nsec_offset();
-
- } while (read_seqretry(&xtime_lock, seq));
-
- timespec_add_ns(ts, nsecs);
-}
-
-/**
- * getnstimeofday - Returns the time of day in a timespec
- * @ts: pointer to the timespec to be set
- *
- * Returns the time of day in a timespec.
- */
-void getnstimeofday(struct timespec *ts)
-{
- __get_realtime_clock_ts(ts);
-}
-
-EXPORT_SYMBOL(getnstimeofday);
-
-/**
- * do_gettimeofday - Returns the time of day in a timeval
- * @tv: pointer to the timeval to be set
- *
- * NOTE: Users should be converted to using get_realtime_clock_ts()
- */
-void do_gettimeofday(struct timeval *tv)
-{
- struct timespec now;
-
- __get_realtime_clock_ts(&now);
- tv->tv_sec = now.tv_sec;
- tv->tv_usec = now.tv_nsec/1000;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-/**
- * do_settimeofday - Sets the time of day
- * @tv: pointer to the timespec variable containing the new time
- *
- * Sets the time of day to the new time and update NTP and notify hrtimers
- */
-int do_settimeofday(struct timespec *tv)
-{
- unsigned long flags;
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irqsave(&xtime_lock, flags);
-
- nsec -= __get_nsec_offset();
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- clock->error = 0;
- ntp_clear();
-
- update_vsyscall(&xtime, clock);
-
- write_sequnlock_irqrestore(&xtime_lock, flags);
-
- /* signal hrtimers about time change */
- clock_was_set();
-
- return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
-/**
- * change_clocksource - Swaps clocksources if a new one is available
- *
- * Accumulates current time interval and initializes new clocksource
- */
-static void change_clocksource(void)
-{
- struct clocksource *new;
- cycle_t now;
- u64 nsec;
-
- new = clocksource_get_next();
-
- if (clock == new)
- return;
-
- now = clocksource_read(new);
- nsec = __get_nsec_offset();
- timespec_add_ns(&xtime, nsec);
-
- clock = new;
- clock->cycle_last = now;
-
- clock->error = 0;
- clock->xtime_nsec = 0;
- clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
-
- tick_clock_notify();
-
- printk(KERN_INFO "Time: %s clocksource has been installed.\n",
- clock->name);
-}
-#else
-static inline void change_clocksource(void) { }
-#endif
-
-/**
- * timekeeping_is_continuous - check to see if timekeeping is free running
- */
-int timekeeping_is_continuous(void)
-{
- unsigned long seq;
- int ret;
-
- do {
- seq = read_seqbegin(&xtime_lock);
-
- ret = clock->flags & CLOCK_SOURCE_VALID_FOR_HRES;
-
- } while (read_seqretry(&xtime_lock, seq));
-
- return ret;
-}
-
-/**
- * read_persistent_clock - Return time in seconds from the persistent clock.
- *
- * Weak dummy function for arches that do not yet support it.
- * Returns seconds from epoch using the battery backed persistent clock.
- * Returns zero if unsupported.
- *
- * XXX - Do be sure to remove it once all arches implement it.
- */
-unsigned long __attribute__((weak)) read_persistent_clock(void)
-{
- return 0;
-}
-
-/*
- * timekeeping_init - Initializes the clocksource and common timekeeping values
- */
-void __init timekeeping_init(void)
-{
- unsigned long flags;
- unsigned long sec = read_persistent_clock();
-
- write_seqlock_irqsave(&xtime_lock, flags);
-
- ntp_clear();
-
- clock = clocksource_get_next();
- clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
- clock->cycle_last = clocksource_read(clock);
-
- xtime.tv_sec = sec;
- xtime.tv_nsec = 0;
- set_normalized_timespec(&wall_to_monotonic,
- -xtime.tv_sec, -xtime.tv_nsec);
-
- write_sequnlock_irqrestore(&xtime_lock, flags);
-}
-
-/* flag for if timekeeping is suspended */
-static int timekeeping_suspended;
-/* time in seconds when suspend began */
-static unsigned long timekeeping_suspend_time;
-
-/**
- * timekeeping_resume - Resumes the generic timekeeping subsystem.
- * @dev: unused
- *
- * This is for the generic clocksource timekeeping.
- * xtime/wall_to_monotonic/jiffies/etc are
- * still managed by arch specific suspend/resume code.
- */
-static int timekeeping_resume(struct sys_device *dev)
-{
- unsigned long flags;
- unsigned long now = read_persistent_clock();
-
- write_seqlock_irqsave(&xtime_lock, flags);
-
- if (now && (now > timekeeping_suspend_time)) {
- unsigned long sleep_length = now - timekeeping_suspend_time;
-
- xtime.tv_sec += sleep_length;
- wall_to_monotonic.tv_sec -= sleep_length;
- }
- /* re-base the last cycle value */
- clock->cycle_last = clocksource_read(clock);
- clock->error = 0;
- timekeeping_suspended = 0;
- write_sequnlock_irqrestore(&xtime_lock, flags);
-
- touch_softlockup_watchdog();
-
- clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL);
-
- /* Resume hrtimers */
- hres_timers_resume();
-
- return 0;
-}
-
-static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
-{
- unsigned long flags;
-
- write_seqlock_irqsave(&xtime_lock, flags);
- timekeeping_suspended = 1;
- timekeeping_suspend_time = read_persistent_clock();
- write_sequnlock_irqrestore(&xtime_lock, flags);
-
- clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL);
-
- return 0;
-}
-
-/* sysfs resume/suspend bits for timekeeping */
-static struct sysdev_class timekeeping_sysclass = {
- .resume = timekeeping_resume,
- .suspend = timekeeping_suspend,
- set_kset_name("timekeeping"),
-};
-
-static struct sys_device device_timer = {
- .id = 0,
- .cls = &timekeeping_sysclass,
-};
-
-static int __init timekeeping_init_device(void)
-{
- int error = sysdev_class_register(&timekeeping_sysclass);
- if (!error)
- error = sysdev_register(&device_timer);
- return error;
-}
-
-device_initcall(timekeeping_init_device);
-
-/*
- * If the error is already larger, we look ahead even further
- * to compensate for late or lost adjustments.
- */
-static __always_inline int clocksource_bigadjust(s64 error, s64 *interval,
- s64 *offset)
-{
- s64 tick_error, i;
- u32 look_ahead, adj;
- s32 error2, mult;
-
- /*
- * Use the current error value to determine how much to look ahead.
- * The larger the error the slower we adjust for it to avoid problems
- * with losing too many ticks, otherwise we would overadjust and
- * produce an even larger error. The smaller the adjustment the
- * faster we try to adjust for it, as lost ticks can do less harm
- * here. This is tuned so that an error of about 1 msec is adusted
- * within about 1 sec (or 2^20 nsec in 2^SHIFT_HZ ticks).
- */
- error2 = clock->error >> (TICK_LENGTH_SHIFT + 22 - 2 * SHIFT_HZ);
- error2 = abs(error2);
- for (look_ahead = 0; error2 > 0; look_ahead++)
- error2 >>= 2;
-
- /*
- * Now calculate the error in (1 << look_ahead) ticks, but first
- * remove the single look ahead already included in the error.
- */
- tick_error = current_tick_length() >>
- (TICK_LENGTH_SHIFT - clock->shift + 1);
- tick_error -= clock->xtime_interval >> 1;
- error = ((error - tick_error) >> look_ahead) + tick_error;
-
- /* Finally calculate the adjustment shift value. */
- i = *interval;
- mult = 1;
- if (error < 0) {
- error = -error;
- *interval = -*interval;
- *offset = -*offset;
- mult = -1;
- }
- for (adj = 0; error > i; adj++)
- error >>= 1;
-
- *interval <<= adj;
- *offset <<= adj;
- return mult << adj;
-}
-
-/*
- * Adjust the multiplier to reduce the error value,
- * this is optimized for the most common adjustments of -1,0,1,
- * for other values we can do a bit more work.
- */
-static void clocksource_adjust(struct clocksource *clock, s64 offset)
-{
- s64 error, interval = clock->cycle_interval;
- int adj;
-
- error = clock->error >> (TICK_LENGTH_SHIFT - clock->shift - 1);
- if (error > interval) {
- error >>= 2;
- if (likely(error <= interval))
- adj = 1;
- else
- adj = clocksource_bigadjust(error, &interval, &offset);
- } else if (error < -interval) {
- error >>= 2;
- if (likely(error >= -interval)) {
- adj = -1;
- interval = -interval;
- offset = -offset;
- } else
- adj = clocksource_bigadjust(error, &interval, &offset);
- } else
- return;
-
- clock->mult += adj;
- clock->xtime_interval += interval;
- clock->xtime_nsec -= offset;
- clock->error -= (interval - offset) <<
- (TICK_LENGTH_SHIFT - clock->shift);
-}
-
-/**
- * update_wall_time - Uses the current clocksource to increment the wall time
- *
- * Called from the timer interrupt, must hold a write on xtime_lock.
- */
-static void update_wall_time(void)
-{
- cycle_t offset;
-
- /* Make sure we're fully resumed: */
- if (unlikely(timekeeping_suspended))
- return;
-
-#ifdef CONFIG_GENERIC_TIME
- offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask;
-#else
- offset = clock->cycle_interval;
-#endif
- clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
-
- /* normally this loop will run just once, however in the
- * case of lost or late ticks, it will accumulate correctly.
- */
- while (offset >= clock->cycle_interval) {
- /* accumulate one interval */
- clock->xtime_nsec += clock->xtime_interval;
- clock->cycle_last += clock->cycle_interval;
- offset -= clock->cycle_interval;
-
- if (clock->xtime_nsec >= (u64)NSEC_PER_SEC << clock->shift) {
- clock->xtime_nsec -= (u64)NSEC_PER_SEC << clock->shift;
- xtime.tv_sec++;
- second_overflow();
- }
-
- /* interpolator bits */
- time_interpolator_update(clock->xtime_interval
- >> clock->shift);
-
- /* accumulate error between NTP and clock interval */
- clock->error += current_tick_length();
- clock->error -= clock->xtime_interval << (TICK_LENGTH_SHIFT - clock->shift);
- }
-
- /* correct the clock when NTP error is too big */
- clocksource_adjust(clock, offset);
-
- /* store full nanoseconds into xtime */
- xtime.tv_nsec = (s64)clock->xtime_nsec >> clock->shift;
- clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift;
-
- /* check to see if there is a new clocksource to use */
- change_clocksource();
- update_vsyscall(&xtime, clock);
-}
-
/*
* Called from the timer interrupt handler to charge one tick to the current
* process. user_tick is 1 if the tick is user time, 0 for system.
@@ -1264,14 +857,6 @@ static inline void calc_load(unsigned long ticks)
}
/*
- * This read-write spinlock protects us from races in SMP while
- * playing with xtime and avenrun.
- */
-__attribute__((weak)) __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
-
-EXPORT_SYMBOL(xtime_lock);
-
-/*
* This function runs timers and the timer-tq in bottom half context.
*/
static void run_timer_softirq(struct softirq_action *h)
@@ -1617,6 +1202,13 @@ static int __devinit init_timers_cpu(int cpu)
cpu_to_node(cpu));
if (!base)
return -ENOMEM;
+
+ /* Make sure that tvec_base is 2 byte aligned */
+ if (tbase_get_deferrable(base)) {
+ WARN_ON(1);
+ kfree(base);
+ return -ENOMEM;
+ }
memset(base, 0, sizeof(*base));
per_cpu(tvec_bases, cpu) = base;
} else {
@@ -1656,9 +1248,9 @@ static void migrate_timer_list(tvec_base_t *new_base, struct list_head *head)
struct timer_list *timer;
while (!list_empty(head)) {
- timer = list_entry(head->next, struct timer_list, entry);
+ timer = list_first_entry(head, struct timer_list, entry);
detach_timer(timer, 0);
- timer->base = new_base;
+ timer_set_base(timer, new_base);
internal_add_timer(new_base, timer);
}
}
diff --git a/kernel/uid16.c b/kernel/uid16.c
index 187e2a4..dd308ba 100644
--- a/kernel/uid16.c
+++ b/kernel/uid16.c
@@ -6,7 +6,6 @@
#include <linux/mm.h>
#include <linux/utsname.h>
#include <linux/mman.h>
-#include <linux/smp_lock.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/prctl.h>
diff --git a/kernel/utsname.c b/kernel/utsname.c
index c859164..160c8c5 100644
--- a/kernel/utsname.c
+++ b/kernel/utsname.c
@@ -32,58 +32,25 @@ static struct uts_namespace *clone_uts_ns(struct uts_namespace *old_ns)
}
/*
- * unshare the current process' utsname namespace.
- * called only in sys_unshare()
- */
-int unshare_utsname(unsigned long unshare_flags, struct uts_namespace **new_uts)
-{
- if (unshare_flags & CLONE_NEWUTS) {
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- *new_uts = clone_uts_ns(current->nsproxy->uts_ns);
- if (!*new_uts)
- return -ENOMEM;
- }
-
- return 0;
-}
-
-/*
* Copy task tsk's utsname namespace, or clone it if flags
* specifies CLONE_NEWUTS. In latter case, changes to the
* utsname of this process won't be seen by parent, and vice
* versa.
*/
-int copy_utsname(int flags, struct task_struct *tsk)
+struct uts_namespace *copy_utsname(int flags, struct uts_namespace *old_ns)
{
- struct uts_namespace *old_ns = tsk->nsproxy->uts_ns;
struct uts_namespace *new_ns;
- int err = 0;
-
- if (!old_ns)
- return 0;
+ BUG_ON(!old_ns);
get_uts_ns(old_ns);
if (!(flags & CLONE_NEWUTS))
- return 0;
-
- if (!capable(CAP_SYS_ADMIN)) {
- err = -EPERM;
- goto out;
- }
+ return old_ns;
new_ns = clone_uts_ns(old_ns);
- if (!new_ns) {
- err = -ENOMEM;
- goto out;
- }
- tsk->nsproxy->uts_ns = new_ns;
-out:
put_uts_ns(old_ns);
- return err;
+ return new_ns;
}
void free_uts_ns(struct kref *kref)
diff --git a/lib/Kconfig b/lib/Kconfig
index 3842499..96d6e8c 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -111,4 +111,9 @@ config HAS_IOPORT
depends on HAS_IOMEM && !NO_IOPORT
default y
+config HAS_DMA
+ boolean
+ depends on !NO_DMA
+ default y
+
endmenu
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 79afd00..ee05b8a 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -86,23 +86,6 @@ config DEBUG_SHIRQ
Drivers ought to be able to handle interrupts coming in at those
points; some don't and need to be caught.
-config LOG_BUF_SHIFT
- int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" if DEBUG_KERNEL
- range 12 21
- default 17 if S390 || LOCKDEP
- default 16 if X86_NUMAQ || IA64
- default 15 if SMP
- default 14
- help
- Select kernel log buffer size as a power of 2.
- Defaults and Examples:
- 17 => 128 KB for S/390
- 16 => 64 KB for x86 NUMAQ or IA-64
- 15 => 32 KB for SMP
- 14 => 16 KB for uniprocessor
- 13 => 8 KB
- 12 => 4 KB
-
config DETECT_SOFTLOCKUP
bool "Detect Soft Lockups"
depends on DEBUG_KERNEL && !S390
@@ -201,6 +184,16 @@ config DEBUG_MUTEXES
This feature allows mutex semantics violations to be detected and
reported.
+config DEBUG_SEMAPHORE
+ bool "Semaphore debugging"
+ depends on DEBUG_KERNEL
+ depends on ALPHA || FRV
+ default n
+ help
+ If you say Y here then semaphore processing will issue lots of
+ verbose debugging messages. If you suspect a semaphore problem or a
+ kernel hacker asks for this option then say Y. Otherwise say N.
+
config DEBUG_LOCK_ALLOC
bool "Lock debugging: detect incorrect freeing of live locks"
depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
@@ -320,7 +313,7 @@ config DEBUG_HIGHMEM
config DEBUG_BUGVERBOSE
bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED
depends on BUG
- depends on ARM || ARM26 || AVR32 || M32R || M68K || SPARC32 || SPARC64 || FRV || SUPERH || GENERIC_BUG
+ depends on ARM || ARM26 || AVR32 || M32R || M68K || SPARC32 || SPARC64 || FRV || SUPERH || GENERIC_BUG || BFIN
default !EMBEDDED
help
Say Y here to make BUG() panics output the file name and line number
@@ -333,6 +326,9 @@ config DEBUG_INFO
help
If you say Y here the resulting kernel image will include
debugging info resulting in a larger kernel image.
+ This adds debug symbols to the kernel and modules (gcc -g), and
+ is needed if you intend to use kernel crashdump or binary object
+ tools like crash, kgdb, LKCD, gdb, etc on the kernel.
Say Y here only if you plan to debug the kernel.
If unsure, say N.
@@ -357,7 +353,7 @@ config DEBUG_LIST
config FRAME_POINTER
bool "Compile the kernel with frame pointers"
- depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH)
+ depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH || BFIN)
default y if DEBUG_INFO && UML
help
If you say Y here the resulting kernel image will be slightly larger
diff --git a/lib/cpumask.c b/lib/cpumask.c
index 1ea2c18..bb4f76d 100644
--- a/lib/cpumask.c
+++ b/lib/cpumask.c
@@ -15,9 +15,6 @@ int __next_cpu(int n, const cpumask_t *srcp)
}
EXPORT_SYMBOL(__next_cpu);
-int nr_cpu_ids;
-EXPORT_SYMBOL(nr_cpu_ids);
-
int __any_online_cpu(const cpumask_t *mask)
{
int cpu;
diff --git a/lib/fault-inject.c b/lib/fault-inject.c
index 0fabd12..b18fc2f 100644
--- a/lib/fault-inject.c
+++ b/lib/fault-inject.c
@@ -72,9 +72,8 @@ static bool fail_stacktrace(struct fault_attr *attr)
trace.entries = entries;
trace.max_entries = depth;
trace.skip = 1;
- trace.all_contexts = 0;
- save_stack_trace(&trace, NULL);
+ save_stack_trace(&trace);
for (n = 0; n < trace.nr_entries; n++) {
if (attr->reject_start <= entries[n] &&
entries[n] < attr->reject_end)
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 9970e55..10c13ad 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -778,7 +778,6 @@ swiotlb_dma_supported(struct device *hwdev, u64 mask)
return virt_to_bus(io_tlb_end - 1) <= mask;
}
-EXPORT_SYMBOL(swiotlb_init);
EXPORT_SYMBOL(swiotlb_map_single);
EXPORT_SYMBOL(swiotlb_unmap_single);
EXPORT_SYMBOL(swiotlb_map_sg);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index cbab1df..0172902 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -825,6 +825,17 @@ int vsscanf(const char * buf, const char * fmt, va_list args)
break;
str = next;
}
+
+ /*
+ * Now we've come all the way through so either the input string or the
+ * format ended. In the former case, there can be a %n at the current
+ * position in the format that needs to be filled.
+ */
+ if (*fmt == '%' && *(fmt + 1) == 'n') {
+ int *p = (int *)va_arg(args, int *);
+ *p = str - buf;
+ }
+
return num;
}
diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c
index fceb97c..7e1e311 100644
--- a/lib/zlib_inflate/inflate.c
+++ b/lib/zlib_inflate/inflate.c
@@ -743,12 +743,14 @@ int zlib_inflate(z_streamp strm, int flush)
strm->data_type = state->bits + (state->last ? 64 : 0) +
(state->mode == TYPE ? 128 : 0);
- if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
- ret = Z_BUF_ERROR;
if (flush == Z_PACKET_FLUSH && ret == Z_OK &&
- (strm->avail_out != 0 || strm->avail_in == 0))
+ strm->avail_out != 0 && strm->avail_in == 0)
return zlib_inflateSyncPacket(strm);
+
+ if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+ ret = Z_BUF_ERROR;
+
return ret;
}
diff --git a/mm/Kconfig b/mm/Kconfig
index 7942b33..1ac718f 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -163,3 +163,8 @@ config ZONE_DMA_FLAG
default "0" if !ZONE_DMA
default "1"
+config NR_QUICK
+ int
+ depends on QUICKLIST
+ default "1"
+
diff --git a/mm/Makefile b/mm/Makefile
index f3c077e..a9148ea 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -25,7 +25,10 @@ obj-$(CONFIG_TMPFS_POSIX_ACL) += shmem_acl.o
obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
obj-$(CONFIG_SLOB) += slob.o
obj-$(CONFIG_SLAB) += slab.o
+obj-$(CONFIG_SLUB) += slub.o
obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
obj-$(CONFIG_FS_XIP) += filemap_xip.o
obj-$(CONFIG_MIGRATION) += migrate.o
obj-$(CONFIG_SMP) += allocpercpu.o
+obj-$(CONFIG_QUICKLIST) += quicklist.o
+
diff --git a/mm/filemap.c b/mm/filemap.c
index 5dfc093..9cbf4fe 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -868,6 +868,7 @@ void do_generic_mapping_read(struct address_space *mapping,
unsigned long last_index;
unsigned long next_index;
unsigned long prev_index;
+ unsigned int prev_offset;
loff_t isize;
struct page *cached_page;
int error;
@@ -876,7 +877,8 @@ void do_generic_mapping_read(struct address_space *mapping,
cached_page = NULL;
index = *ppos >> PAGE_CACHE_SHIFT;
next_index = index;
- prev_index = ra.prev_page;
+ prev_index = ra.prev_index;
+ prev_offset = ra.prev_offset;
last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
offset = *ppos & ~PAGE_CACHE_MASK;
@@ -924,10 +926,10 @@ page_ok:
flush_dcache_page(page);
/*
- * When (part of) the same page is read multiple times
- * in succession, only mark it as accessed the first time.
+ * When a sequential read accesses a page several times,
+ * only mark it as accessed the first time.
*/
- if (prev_index != index)
+ if (prev_index != index || offset != prev_offset)
mark_page_accessed(page);
prev_index = index;
@@ -945,6 +947,8 @@ page_ok:
offset += ret;
index += offset >> PAGE_CACHE_SHIFT;
offset &= ~PAGE_CACHE_MASK;
+ prev_offset = offset;
+ ra.prev_offset = offset;
page_cache_release(page);
if (ret == nr && desc->count)
@@ -1106,6 +1110,45 @@ success:
return size;
}
+/*
+ * Performs necessary checks before doing a write
+ * @iov: io vector request
+ * @nr_segs: number of segments in the iovec
+ * @count: number of bytes to write
+ * @access_flags: type of access: %VERIFY_READ or %VERIFY_WRITE
+ *
+ * Adjust number of segments and amount of bytes to write (nr_segs should be
+ * properly initialized first). Returns appropriate error code that caller
+ * should return or zero in case that write should be allowed.
+ */
+int generic_segment_checks(const struct iovec *iov,
+ unsigned long *nr_segs, size_t *count, int access_flags)
+{
+ unsigned long seg;
+ size_t cnt = 0;
+ for (seg = 0; seg < *nr_segs; seg++) {
+ const struct iovec *iv = &iov[seg];
+
+ /*
+ * If any segment has a negative length, or the cumulative
+ * length ever wraps negative then return -EINVAL.
+ */
+ cnt += iv->iov_len;
+ if (unlikely((ssize_t)(cnt|iv->iov_len) < 0))
+ return -EINVAL;
+ if (access_ok(access_flags, iv->iov_base, iv->iov_len))
+ continue;
+ if (seg == 0)
+ return -EFAULT;
+ *nr_segs = seg;
+ cnt -= iv->iov_len; /* This segment is no good */
+ break;
+ }
+ *count = cnt;
+ return 0;
+}
+EXPORT_SYMBOL(generic_segment_checks);
+
/**
* generic_file_aio_read - generic filesystem read routine
* @iocb: kernel I/O control block
@@ -1127,24 +1170,9 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
loff_t *ppos = &iocb->ki_pos;
count = 0;
- for (seg = 0; seg < nr_segs; seg++) {
- const struct iovec *iv = &iov[seg];
-
- /*
- * If any segment has a negative length, or the cumulative
- * length ever wraps negative then return -EINVAL.
- */
- count += iv->iov_len;
- if (unlikely((ssize_t)(count|iv->iov_len) < 0))
- return -EINVAL;
- if (access_ok(VERIFY_WRITE, iv->iov_base, iv->iov_len))
- continue;
- if (seg == 0)
- return -EFAULT;
- nr_segs = seg;
- count -= iv->iov_len; /* This segment is no good */
- break;
- }
+ retval = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE);
+ if (retval)
+ return retval;
/* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
if (filp->f_flags & O_DIRECT) {
@@ -1446,30 +1474,6 @@ page_not_uptodate:
majmin = VM_FAULT_MAJOR;
count_vm_event(PGMAJFAULT);
}
- lock_page(page);
-
- /* Did it get unhashed while we waited for it? */
- if (!page->mapping) {
- unlock_page(page);
- page_cache_release(page);
- goto retry_all;
- }
-
- /* Did somebody else get it up-to-date? */
- if (PageUptodate(page)) {
- unlock_page(page);
- goto success;
- }
-
- error = mapping->a_ops->readpage(file, page);
- if (!error) {
- wait_on_page_locked(page);
- if (PageUptodate(page))
- goto success;
- } else if (error == AOP_TRUNCATED_PAGE) {
- page_cache_release(page);
- goto retry_find;
- }
/*
* Umm, take care of errors if the page isn't up-to-date.
@@ -1726,7 +1730,7 @@ int generic_file_readonly_mmap(struct file * file, struct vm_area_struct * vma)
EXPORT_SYMBOL(generic_file_mmap);
EXPORT_SYMBOL(generic_file_readonly_mmap);
-static inline struct page *__read_cache_page(struct address_space *mapping,
+static struct page *__read_cache_page(struct address_space *mapping,
unsigned long index,
int (*filler)(void *,struct page*),
void *data)
@@ -1763,17 +1767,11 @@ repeat:
return page;
}
-/**
- * read_cache_page - read into page cache, fill it if needed
- * @mapping: the page's address_space
- * @index: the page index
- * @filler: function to perform the read
- * @data: destination for read data
- *
- * Read into the page cache. If a page already exists,
- * and PageUptodate() is not set, try to fill the page.
+/*
+ * Same as read_cache_page, but don't wait for page to become unlocked
+ * after submitting it to the filler.
*/
-struct page *read_cache_page(struct address_space *mapping,
+struct page *read_cache_page_async(struct address_space *mapping,
unsigned long index,
int (*filler)(void *,struct page*),
void *data)
@@ -1805,6 +1803,39 @@ retry:
page = ERR_PTR(err);
}
out:
+ mark_page_accessed(page);
+ return page;
+}
+EXPORT_SYMBOL(read_cache_page_async);
+
+/**
+ * read_cache_page - read into page cache, fill it if needed
+ * @mapping: the page's address_space
+ * @index: the page index
+ * @filler: function to perform the read
+ * @data: destination for read data
+ *
+ * Read into the page cache. If a page already exists, and PageUptodate() is
+ * not set, try to fill the page then wait for it to become unlocked.
+ *
+ * If the page does not get brought uptodate, return -EIO.
+ */
+struct page *read_cache_page(struct address_space *mapping,
+ unsigned long index,
+ int (*filler)(void *,struct page*),
+ void *data)
+{
+ struct page *page;
+
+ page = read_cache_page_async(mapping, index, filler, data);
+ if (IS_ERR(page))
+ goto out;
+ wait_on_page_locked(page);
+ if (!PageUptodate(page)) {
+ page_cache_release(page);
+ page = ERR_PTR(-EIO);
+ }
+ out:
return page;
}
EXPORT_SYMBOL(read_cache_page);
@@ -2211,30 +2242,14 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
size_t ocount; /* original count */
size_t count; /* after file limit checks */
struct inode *inode = mapping->host;
- unsigned long seg;
loff_t pos;
ssize_t written;
ssize_t err;
ocount = 0;
- for (seg = 0; seg < nr_segs; seg++) {
- const struct iovec *iv = &iov[seg];
-
- /*
- * If any segment has a negative length, or the cumulative
- * length ever wraps negative then return -EINVAL.
- */
- ocount += iv->iov_len;
- if (unlikely((ssize_t)(ocount|iv->iov_len) < 0))
- return -EINVAL;
- if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len))
- continue;
- if (seg == 0)
- return -EFAULT;
- nr_segs = seg;
- ocount -= iv->iov_len; /* This segment is no good */
- break;
- }
+ err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);
+ if (err)
+ return err;
count = ocount;
pos = *ppos;
@@ -2294,10 +2309,10 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
* semantics.
*/
endbyte = pos + written_buffered - written - 1;
- err = do_sync_file_range(file, pos, endbyte,
- SYNC_FILE_RANGE_WAIT_BEFORE|
- SYNC_FILE_RANGE_WRITE|
- SYNC_FILE_RANGE_WAIT_AFTER);
+ err = do_sync_mapping_range(file->f_mapping, pos, endbyte,
+ SYNC_FILE_RANGE_WAIT_BEFORE|
+ SYNC_FILE_RANGE_WRITE|
+ SYNC_FILE_RANGE_WAIT_AFTER);
if (err == 0) {
written = written_buffered;
invalidate_mapping_pages(mapping,
diff --git a/mm/internal.h b/mm/internal.h
index d527b80..a3110c0 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -24,7 +24,7 @@ static inline void set_page_count(struct page *page, int v)
*/
static inline void set_page_refcounted(struct page *page)
{
- VM_BUG_ON(PageCompound(page) && page_private(page) != (unsigned long)page);
+ VM_BUG_ON(PageCompound(page) && PageTail(page));
VM_BUG_ON(atomic_read(&page->_count));
set_page_count(page, 1);
}
diff --git a/mm/madvise.c b/mm/madvise.c
index 603c525..e75096b 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -12,6 +12,24 @@
#include <linux/hugetlb.h>
/*
+ * Any behaviour which results in changes to the vma->vm_flags needs to
+ * take mmap_sem for writing. Others, which simply traverse vmas, need
+ * to only take it for reading.
+ */
+static int madvise_need_mmap_write(int behavior)
+{
+ switch (behavior) {
+ case MADV_REMOVE:
+ case MADV_WILLNEED:
+ case MADV_DONTNEED:
+ return 0;
+ default:
+ /* be safe, default to 1. list exceptions explicitly */
+ return 1;
+ }
+}
+
+/*
* We can potentially split a vm area into separate
* areas, each area with its own behavior.
*/
@@ -183,9 +201,9 @@ static long madvise_remove(struct vm_area_struct *vma,
+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
/* vmtruncate_range needs to take i_mutex and i_alloc_sem */
- up_write(&current->mm->mmap_sem);
+ up_read(&current->mm->mmap_sem);
error = vmtruncate_range(mapping->host, offset, endoff);
- down_write(&current->mm->mmap_sem);
+ down_read(&current->mm->mmap_sem);
return error;
}
@@ -270,7 +288,10 @@ asmlinkage long sys_madvise(unsigned long start, size_t len_in, int behavior)
int error = -EINVAL;
size_t len;
- down_write(&current->mm->mmap_sem);
+ if (madvise_need_mmap_write(behavior))
+ down_write(&current->mm->mmap_sem);
+ else
+ down_read(&current->mm->mmap_sem);
if (start & ~PAGE_MASK)
goto out;
@@ -332,6 +353,10 @@ asmlinkage long sys_madvise(unsigned long start, size_t len_in, int behavior)
vma = find_vma(current->mm, start);
}
out:
- up_write(&current->mm->mmap_sem);
+ if (madvise_need_mmap_write(behavior))
+ up_write(&current->mm->mmap_sem);
+ else
+ up_read(&current->mm->mmap_sem);
+
return error;
}
diff --git a/mm/memory.c b/mm/memory.c
index e7066e7..1d647ab 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1448,6 +1448,100 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
}
EXPORT_SYMBOL(remap_pfn_range);
+static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
+ unsigned long addr, unsigned long end,
+ pte_fn_t fn, void *data)
+{
+ pte_t *pte;
+ int err;
+ struct page *pmd_page;
+ spinlock_t *uninitialized_var(ptl);
+
+ pte = (mm == &init_mm) ?
+ pte_alloc_kernel(pmd, addr) :
+ pte_alloc_map_lock(mm, pmd, addr, &ptl);
+ if (!pte)
+ return -ENOMEM;
+
+ BUG_ON(pmd_huge(*pmd));
+
+ pmd_page = pmd_page(*pmd);
+
+ do {
+ err = fn(pte, pmd_page, addr, data);
+ if (err)
+ break;
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+
+ if (mm != &init_mm)
+ pte_unmap_unlock(pte-1, ptl);
+ return err;
+}
+
+static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
+ unsigned long addr, unsigned long end,
+ pte_fn_t fn, void *data)
+{
+ pmd_t *pmd;
+ unsigned long next;
+ int err;
+
+ pmd = pmd_alloc(mm, pud, addr);
+ if (!pmd)
+ return -ENOMEM;
+ do {
+ next = pmd_addr_end(addr, end);
+ err = apply_to_pte_range(mm, pmd, addr, next, fn, data);
+ if (err)
+ break;
+ } while (pmd++, addr = next, addr != end);
+ return err;
+}
+
+static int apply_to_pud_range(struct mm_struct *mm, pgd_t *pgd,
+ unsigned long addr, unsigned long end,
+ pte_fn_t fn, void *data)
+{
+ pud_t *pud;
+ unsigned long next;
+ int err;
+
+ pud = pud_alloc(mm, pgd, addr);
+ if (!pud)
+ return -ENOMEM;
+ do {
+ next = pud_addr_end(addr, end);
+ err = apply_to_pmd_range(mm, pud, addr, next, fn, data);
+ if (err)
+ break;
+ } while (pud++, addr = next, addr != end);
+ return err;
+}
+
+/*
+ * Scan a region of virtual memory, filling in page tables as necessary
+ * and calling a provided function on each leaf page table.
+ */
+int apply_to_page_range(struct mm_struct *mm, unsigned long addr,
+ unsigned long size, pte_fn_t fn, void *data)
+{
+ pgd_t *pgd;
+ unsigned long next;
+ unsigned long end = addr + size;
+ int err;
+
+ BUG_ON(addr >= end);
+ pgd = pgd_offset(mm, addr);
+ do {
+ next = pgd_addr_end(addr, end);
+ err = apply_to_pud_range(mm, pgd, addr, next, fn, data);
+ if (err)
+ break;
+ } while (pgd++, addr = next, addr != end);
+ return err;
+}
+EXPORT_SYMBOL_GPL(apply_to_page_range);
+
/*
* handle_pte_fault chooses page fault handler according to an entry
* which was read non-atomically. Before making any commitment, on
@@ -2539,12 +2633,6 @@ int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
spin_unlock(&mm->page_table_lock);
return 0;
}
-#else
-/* Workaround for gcc 2.96 */
-int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
-{
- return 0;
-}
#endif /* __PAGETABLE_PUD_FOLDED */
#ifndef __PAGETABLE_PMD_FOLDED
@@ -2573,12 +2661,6 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
spin_unlock(&mm->page_table_lock);
return 0;
}
-#else
-/* Workaround for gcc 2.96 */
-int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
-{
- return 0;
-}
#endif /* __PAGETABLE_PMD_FOLDED */
int make_pages_present(unsigned long addr, unsigned long end)
diff --git a/mm/mmap.c b/mm/mmap.c
index 88da687..cc1f543 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1200,6 +1200,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
if (len > TASK_SIZE)
return -ENOMEM;
+ if (flags & MAP_FIXED)
+ return addr;
+
if (addr) {
addr = PAGE_ALIGN(addr);
vma = find_vma(mm, addr);
@@ -1273,6 +1276,9 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
if (len > TASK_SIZE)
return -ENOMEM;
+ if (flags & MAP_FIXED)
+ return addr;
+
/* requesting a specific address */
if (addr) {
addr = PAGE_ALIGN(addr);
@@ -1360,39 +1366,21 @@ unsigned long
get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
unsigned long pgoff, unsigned long flags)
{
- unsigned long ret;
-
- if (!(flags & MAP_FIXED)) {
- unsigned long (*get_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
-
- get_area = current->mm->get_unmapped_area;
- if (file && file->f_op && file->f_op->get_unmapped_area)
- get_area = file->f_op->get_unmapped_area;
- addr = get_area(file, addr, len, pgoff, flags);
- if (IS_ERR_VALUE(addr))
- return addr;
- }
+ unsigned long (*get_area)(struct file *, unsigned long,
+ unsigned long, unsigned long, unsigned long);
+
+ get_area = current->mm->get_unmapped_area;
+ if (file && file->f_op && file->f_op->get_unmapped_area)
+ get_area = file->f_op->get_unmapped_area;
+ addr = get_area(file, addr, len, pgoff, flags);
+ if (IS_ERR_VALUE(addr))
+ return addr;
if (addr > TASK_SIZE - len)
return -ENOMEM;
if (addr & ~PAGE_MASK)
return -EINVAL;
- if (file && is_file_hugepages(file)) {
- /*
- * Check if the given range is hugepage aligned, and
- * can be made suitable for hugepages.
- */
- ret = prepare_hugepage_range(addr, len, pgoff);
- } else {
- /*
- * Ensure that a normal request is not falling in a
- * reserved hugepage range. For some archs like IA-64,
- * there is a separate region for hugepages.
- */
- ret = is_hugepage_only_range(current->mm, addr, len);
- }
- if (ret)
- return -EINVAL;
+
return addr;
}
diff --git a/mm/nommu.c b/mm/nommu.c
index 1f60194..2b16b00 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -262,6 +262,14 @@ void vunmap(void *addr)
}
/*
+ * Implement a stub for vmalloc_sync_all() if the architecture chose not to
+ * have one.
+ */
+void __attribute__((weak)) vmalloc_sync_all(void)
+{
+}
+
+/*
* sys_brk() for the most part doesn't need the global kernel
* lock, except when an application is doing something nasty
* like trying to un-brk an area that has already been mapped
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 3791edf..a700141 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -147,9 +147,11 @@ unsigned long badness(struct task_struct *p, unsigned long uptime)
* Adjust the score by oomkilladj.
*/
if (p->oomkilladj) {
- if (p->oomkilladj > 0)
+ if (p->oomkilladj > 0) {
+ if (!points)
+ points = 1;
points <<= p->oomkilladj;
- else
+ } else
points >>= -(p->oomkilladj);
}
@@ -397,6 +399,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
struct task_struct *p;
unsigned long points = 0;
unsigned long freed = 0;
+ int constraint;
blocking_notifier_call_chain(&oom_notify_list, 0, &freed);
if (freed > 0)
@@ -411,14 +414,18 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
show_mem();
}
- cpuset_lock();
- read_lock(&tasklist_lock);
+ if (sysctl_panic_on_oom == 2)
+ panic("out of memory. Compulsory panic_on_oom is selected.\n");
/*
* Check if there were limitations on the allocation (only relevant for
* NUMA) that may require different handling.
*/
- switch (constrained_alloc(zonelist, gfp_mask)) {
+ constraint = constrained_alloc(zonelist, gfp_mask);
+ cpuset_lock();
+ read_lock(&tasklist_lock);
+
+ switch (constraint) {
case CONSTRAINT_MEMORY_POLICY:
oom_kill_process(current, points,
"No available memory (MPOL_BIND)");
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index a794945..63cd888 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -119,6 +119,44 @@ static void background_writeout(unsigned long _min_pages);
* We make sure that the background writeout level is below the adjusted
* clamping level.
*/
+
+static unsigned long highmem_dirtyable_memory(unsigned long total)
+{
+#ifdef CONFIG_HIGHMEM
+ int node;
+ unsigned long x = 0;
+
+ for_each_online_node(node) {
+ struct zone *z =
+ &NODE_DATA(node)->node_zones[ZONE_HIGHMEM];
+
+ x += zone_page_state(z, NR_FREE_PAGES)
+ + zone_page_state(z, NR_INACTIVE)
+ + zone_page_state(z, NR_ACTIVE);
+ }
+ /*
+ * Make sure that the number of highmem pages is never larger
+ * than the number of the total dirtyable memory. This can only
+ * occur in very strange VM situations but we want to make sure
+ * that this does not occur.
+ */
+ return min(x, total);
+#else
+ return 0;
+#endif
+}
+
+static unsigned long determine_dirtyable_memory(void)
+{
+ unsigned long x;
+
+ x = global_page_state(NR_FREE_PAGES)
+ + global_page_state(NR_INACTIVE)
+ + global_page_state(NR_ACTIVE);
+ x -= highmem_dirtyable_memory(x);
+ return x + 1; /* Ensure that we never return 0 */
+}
+
static void
get_dirty_limits(long *pbackground, long *pdirty,
struct address_space *mapping)
@@ -128,20 +166,12 @@ get_dirty_limits(long *pbackground, long *pdirty,
int unmapped_ratio;
long background;
long dirty;
- unsigned long available_memory = vm_total_pages;
+ unsigned long available_memory = determine_dirtyable_memory();
struct task_struct *tsk;
-#ifdef CONFIG_HIGHMEM
- /*
- * We always exclude high memory from our count.
- */
- available_memory -= totalhigh_pages;
-#endif
-
-
unmapped_ratio = 100 - ((global_page_state(NR_FILE_MAPPED) +
global_page_state(NR_ANON_PAGES)) * 100) /
- vm_total_pages;
+ available_memory;
dirty_ratio = vm_dirty_ratio;
if (dirty_ratio > unmapped_ratio / 2)
@@ -653,12 +683,7 @@ retry:
}
ret = (*writepage)(page, wbc);
- if (ret) {
- if (ret == -ENOSPC)
- set_bit(AS_ENOSPC, &mapping->flags);
- else
- set_bit(AS_EIO, &mapping->flags);
- }
+ mapping_set_error(mapping, ret);
if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE))
unlock_page(page);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 353ce90..6fd0b74 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -103,7 +103,7 @@ int min_free_kbytes = 1024;
unsigned long __meminitdata nr_kernel_pages;
unsigned long __meminitdata nr_all_pages;
-static unsigned long __initdata dma_reserve;
+static unsigned long __meminitdata dma_reserve;
#ifdef CONFIG_ARCH_POPULATES_NODE_MAP
/*
@@ -126,10 +126,10 @@ static unsigned long __initdata dma_reserve;
#endif
#endif
- struct node_active_region __initdata early_node_map[MAX_ACTIVE_REGIONS];
- int __initdata nr_nodemap_entries;
- unsigned long __initdata arch_zone_lowest_possible_pfn[MAX_NR_ZONES];
- unsigned long __initdata arch_zone_highest_possible_pfn[MAX_NR_ZONES];
+ struct node_active_region __meminitdata early_node_map[MAX_ACTIVE_REGIONS];
+ int __meminitdata nr_nodemap_entries;
+ unsigned long __meminitdata arch_zone_lowest_possible_pfn[MAX_NR_ZONES];
+ unsigned long __meminitdata arch_zone_highest_possible_pfn[MAX_NR_ZONES];
#ifdef CONFIG_MEMORY_HOTPLUG_RESERVE
unsigned long __initdata node_boundary_start_pfn[MAX_NUMNODES];
unsigned long __initdata node_boundary_end_pfn[MAX_NUMNODES];
@@ -156,10 +156,8 @@ static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
static int page_is_consistent(struct zone *zone, struct page *page)
{
-#ifdef CONFIG_HOLES_IN_ZONE
- if (!pfn_valid(page_to_pfn(page)))
+ if (!pfn_valid_within(page_to_pfn(page)))
return 0;
-#endif
if (zone != page_zone(page))
return 0;
@@ -227,7 +225,7 @@ static void bad_page(struct page *page)
static void free_compound_page(struct page *page)
{
- __free_pages_ok(page, (unsigned long)page[1].lru.prev);
+ __free_pages_ok(page, compound_order(page));
}
static void prep_compound_page(struct page *page, unsigned long order)
@@ -236,12 +234,13 @@ static void prep_compound_page(struct page *page, unsigned long order)
int nr_pages = 1 << order;
set_compound_page_dtor(page, free_compound_page);
- page[1].lru.prev = (void *)order;
- for (i = 0; i < nr_pages; i++) {
+ set_compound_order(page, order);
+ __SetPageHead(page);
+ for (i = 1; i < nr_pages; i++) {
struct page *p = page + i;
- __SetPageCompound(p);
- set_page_private(p, (unsigned long)page);
+ __SetPageTail(p);
+ p->first_page = page;
}
}
@@ -250,16 +249,19 @@ static void destroy_compound_page(struct page *page, unsigned long order)
int i;
int nr_pages = 1 << order;
- if (unlikely((unsigned long)page[1].lru.prev != order))
+ if (unlikely(compound_order(page) != order))
bad_page(page);
- for (i = 0; i < nr_pages; i++) {
+ if (unlikely(!PageHead(page)))
+ bad_page(page);
+ __ClearPageHead(page);
+ for (i = 1; i < nr_pages; i++) {
struct page *p = page + i;
- if (unlikely(!PageCompound(p) |
- (page_private(p) != (unsigned long)page)))
+ if (unlikely(!PageTail(p) |
+ (p->first_page != page)))
bad_page(page);
- __ClearPageCompound(p);
+ __ClearPageTail(p);
}
}
@@ -346,10 +348,8 @@ __find_combined_index(unsigned long page_idx, unsigned int order)
static inline int page_is_buddy(struct page *page, struct page *buddy,
int order)
{
-#ifdef CONFIG_HOLES_IN_ZONE
- if (!pfn_valid(page_to_pfn(buddy)))
+ if (!pfn_valid_within(page_to_pfn(buddy)))
return 0;
-#endif
if (page_zone_id(page) != page_zone_id(buddy))
return 0;
@@ -433,13 +433,18 @@ static inline int free_pages_check(struct page *page)
1 << PG_private |
1 << PG_locked |
1 << PG_active |
- 1 << PG_reclaim |
1 << PG_slab |
1 << PG_swapcache |
1 << PG_writeback |
1 << PG_reserved |
1 << PG_buddy ))))
bad_page(page);
+ /*
+ * PageReclaim == PageTail. It is only an error
+ * for PageReclaim to be set if PageCompound is clear.
+ */
+ if (unlikely(!PageCompound(page) && PageReclaim(page)))
+ bad_page(page);
if (PageDirty(page))
__ClearPageDirty(page);
/*
@@ -665,7 +670,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
}
#if MAX_NUMNODES > 1
-int nr_node_ids __read_mostly;
+int nr_node_ids __read_mostly = MAX_NUMNODES;
EXPORT_SYMBOL(nr_node_ids);
/*
@@ -770,8 +775,8 @@ void mark_free_pages(struct zone *zone)
if (pfn_valid(pfn)) {
struct page *page = pfn_to_page(pfn);
- if (!PageNosave(page))
- ClearPageNosaveFree(page);
+ if (!swsusp_page_is_forbidden(page))
+ swsusp_unset_page_free(page);
}
for (order = MAX_ORDER - 1; order >= 0; --order)
@@ -780,7 +785,7 @@ void mark_free_pages(struct zone *zone)
pfn = page_to_pfn(list_entry(curr, struct page, lru));
for (i = 0; i < (1UL << order); i++)
- SetPageNosaveFree(pfn_to_page(pfn + i));
+ swsusp_set_page_free(pfn_to_page(pfn + i));
}
spin_unlock_irqrestore(&zone->lock, flags);
@@ -2174,7 +2179,7 @@ void __init setup_per_cpu_pageset(void)
#endif
-static __meminit
+static __meminit noinline
int zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages)
{
int i;
@@ -2262,7 +2267,7 @@ __meminit int init_currently_empty_zone(struct zone *zone,
* Basic iterator support. Return the first range of PFNs for a node
* Note: nid == MAX_NUMNODES returns first region regardless of node
*/
-static int __init first_active_region_index_in_nid(int nid)
+static int __meminit first_active_region_index_in_nid(int nid)
{
int i;
@@ -2277,7 +2282,7 @@ static int __init first_active_region_index_in_nid(int nid)
* Basic iterator support. Return the next active range of PFNs for a node
* Note: nid == MAX_NUMNODES returns next region regardles of node
*/
-static int __init next_active_region_index_in_nid(int index, int nid)
+static int __meminit next_active_region_index_in_nid(int index, int nid)
{
for (index = index + 1; index < nr_nodemap_entries; index++)
if (nid == MAX_NUMNODES || early_node_map[index].nid == nid)
@@ -2430,7 +2435,7 @@ static void __init account_node_boundary(unsigned int nid,
* with no available memory, a warning is printed and the start and end
* PFNs will be 0.
*/
-void __init get_pfn_range_for_nid(unsigned int nid,
+void __meminit get_pfn_range_for_nid(unsigned int nid,
unsigned long *start_pfn, unsigned long *end_pfn)
{
int i;
@@ -2455,7 +2460,7 @@ void __init get_pfn_range_for_nid(unsigned int nid,
* Return the number of pages a zone spans in a node, including holes
* present_pages = zone_spanned_pages_in_node() - zone_absent_pages_in_node()
*/
-unsigned long __init zone_spanned_pages_in_node(int nid,
+unsigned long __meminit zone_spanned_pages_in_node(int nid,
unsigned long zone_type,
unsigned long *ignored)
{
@@ -2483,7 +2488,7 @@ unsigned long __init zone_spanned_pages_in_node(int nid,
* Return the number of holes in a range on a node. If nid is MAX_NUMNODES,
* then all holes in the requested range will be accounted for.
*/
-unsigned long __init __absent_pages_in_range(int nid,
+unsigned long __meminit __absent_pages_in_range(int nid,
unsigned long range_start_pfn,
unsigned long range_end_pfn)
{
@@ -2543,7 +2548,7 @@ unsigned long __init absent_pages_in_range(unsigned long start_pfn,
}
/* Return the number of page frames in holes in a zone on a node */
-unsigned long __init zone_absent_pages_in_node(int nid,
+unsigned long __meminit zone_absent_pages_in_node(int nid,
unsigned long zone_type,
unsigned long *ignored)
{
@@ -2579,7 +2584,7 @@ static inline unsigned long zone_absent_pages_in_node(int nid,
#endif
-static void __init calculate_node_totalpages(struct pglist_data *pgdat,
+static void __meminit calculate_node_totalpages(struct pglist_data *pgdat,
unsigned long *zones_size, unsigned long *zholes_size)
{
unsigned long realtotalpages, totalpages = 0;
@@ -2687,7 +2692,7 @@ static void __meminit free_area_init_core(struct pglist_data *pgdat,
}
}
-static void __init alloc_node_mem_map(struct pglist_data *pgdat)
+static void __meminit alloc_node_mem_map(struct pglist_data *pgdat)
{
/* Skip empty nodes */
if (!pgdat->node_spanned_pages)
@@ -3203,7 +3208,8 @@ int min_free_kbytes_sysctl_handler(ctl_table *table, int write,
struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
{
proc_dointvec(table, write, file, buffer, length, ppos);
- setup_per_zone_pages_min();
+ if (write)
+ setup_per_zone_pages_min();
return 0;
}
diff --git a/mm/quicklist.c b/mm/quicklist.c
new file mode 100644
index 0000000..ae8189c
--- /dev/null
+++ b/mm/quicklist.c
@@ -0,0 +1,88 @@
+/*
+ * Quicklist support.
+ *
+ * Quicklists are light weight lists of pages that have a defined state
+ * on alloc and free. Pages must be in the quicklist specific defined state
+ * (zero by default) when the page is freed. It seems that the initial idea
+ * for such lists first came from Dave Miller and then various other people
+ * improved on it.
+ *
+ * Copyright (C) 2007 SGI,
+ * Christoph Lameter <clameter@sgi.com>
+ * Generalized, added support for multiple lists and
+ * constructors / destructors.
+ */
+#include <linux/kernel.h>
+
+#include <linux/mm.h>
+#include <linux/mmzone.h>
+#include <linux/module.h>
+#include <linux/quicklist.h>
+
+DEFINE_PER_CPU(struct quicklist, quicklist)[CONFIG_NR_QUICK];
+
+#define FRACTION_OF_NODE_MEM 16
+
+static unsigned long max_pages(unsigned long min_pages)
+{
+ unsigned long node_free_pages, max;
+
+ node_free_pages = node_page_state(numa_node_id(),
+ NR_FREE_PAGES);
+ max = node_free_pages / FRACTION_OF_NODE_MEM;
+ return max(max, min_pages);
+}
+
+static long min_pages_to_free(struct quicklist *q,
+ unsigned long min_pages, long max_free)
+{
+ long pages_to_free;
+
+ pages_to_free = q->nr_pages - max_pages(min_pages);
+
+ return min(pages_to_free, max_free);
+}
+
+/*
+ * Trim down the number of pages in the quicklist
+ */
+void quicklist_trim(int nr, void (*dtor)(void *),
+ unsigned long min_pages, unsigned long max_free)
+{
+ long pages_to_free;
+ struct quicklist *q;
+
+ q = &get_cpu_var(quicklist)[nr];
+ if (q->nr_pages > min_pages) {
+ pages_to_free = min_pages_to_free(q, min_pages, max_free);
+
+ while (pages_to_free > 0) {
+ /*
+ * We pass a gfp_t of 0 to quicklist_alloc here
+ * because we will never call into the page allocator.
+ */
+ void *p = quicklist_alloc(nr, 0, NULL);
+
+ if (dtor)
+ dtor(p);
+ free_page((unsigned long)p);
+ pages_to_free--;
+ }
+ }
+ put_cpu_var(quicklist);
+}
+
+unsigned long quicklist_total_size(void)
+{
+ unsigned long count = 0;
+ int cpu;
+ struct quicklist *ql, *q;
+
+ for_each_online_cpu(cpu) {
+ ql = per_cpu(quicklist, cpu);
+ for (q = ql; q < ql + CONFIG_NR_QUICK; q++)
+ count += q->nr_pages;
+ }
+ return count;
+}
+
diff --git a/mm/readahead.c b/mm/readahead.c
index 93d9ee6..9861e88 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -37,7 +37,7 @@ void
file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping)
{
ra->ra_pages = mapping->backing_dev_info->ra_pages;
- ra->prev_page = -1;
+ ra->prev_index = -1;
}
EXPORT_SYMBOL_GPL(file_ra_state_init);
@@ -202,17 +202,19 @@ out:
* size: Number of pages in that read
* Together, these form the "current window".
* Together, start and size represent the `readahead window'.
- * prev_page: The page which the readahead algorithm most-recently inspected.
+ * prev_index: The page which the readahead algorithm most-recently inspected.
* It is mainly used to detect sequential file reading.
* If page_cache_readahead sees that it is again being called for
* a page which it just looked at, it can return immediately without
* making any state changes.
+ * offset: Offset in the prev_index where the last read ended - used for
+ * detection of sequential file reading.
* ahead_start,
* ahead_size: Together, these form the "ahead window".
* ra_pages: The externally controlled max readahead for this fd.
*
* When readahead is in the off state (size == 0), readahead is disabled.
- * In this state, prev_page is used to detect the resumption of sequential I/O.
+ * In this state, prev_index is used to detect the resumption of sequential I/O.
*
* The readahead code manages two windows - the "current" and the "ahead"
* windows. The intent is that while the application is walking the pages
@@ -415,7 +417,7 @@ static int make_ahead_window(struct address_space *mapping, struct file *filp,
ra->ahead_size = get_next_ra_size(ra);
ra->ahead_start = ra->start + ra->size;
- block = force || (ra->prev_page >= ra->ahead_start);
+ block = force || (ra->prev_index >= ra->ahead_start);
ret = blockable_page_cache_readahead(mapping, filp,
ra->ahead_start, ra->ahead_size, ra, block);
@@ -467,12 +469,13 @@ page_cache_readahead(struct address_space *mapping, struct file_ra_state *ra,
* We avoid doing extra work and bogusly perturbing the readahead
* window expansion logic.
*/
- if (offset == ra->prev_page && --req_size)
+ if (offset == ra->prev_index && --req_size)
++offset;
- /* Note that prev_page == -1 if it is a first read */
- sequential = (offset == ra->prev_page + 1);
- ra->prev_page = offset;
+ /* Note that prev_index == -1 if it is a first read */
+ sequential = (offset == ra->prev_index + 1);
+ ra->prev_index = offset;
+ ra->prev_offset = 0;
max = get_max_readahead(ra);
newsize = min(req_size, max);
@@ -481,7 +484,7 @@ page_cache_readahead(struct address_space *mapping, struct file_ra_state *ra,
if (newsize == 0 || (ra->flags & RA_FLAG_INCACHE))
goto out;
- ra->prev_page += newsize - 1;
+ ra->prev_index += newsize - 1;
/*
* Special case - first read at start of file. We'll assume it's
@@ -537,18 +540,18 @@ page_cache_readahead(struct address_space *mapping, struct file_ra_state *ra,
* we get called back on the first page of the ahead window which
* will allow us to submit more IO.
*/
- if (ra->prev_page >= ra->ahead_start) {
+ if (ra->prev_index >= ra->ahead_start) {
ra->start = ra->ahead_start;
ra->size = ra->ahead_size;
make_ahead_window(mapping, filp, ra, 0);
recheck:
- /* prev_page shouldn't overrun the ahead window */
- ra->prev_page = min(ra->prev_page,
+ /* prev_index shouldn't overrun the ahead window */
+ ra->prev_index = min(ra->prev_index,
ra->ahead_start + ra->ahead_size - 1);
}
out:
- return ra->prev_page + 1;
+ return ra->prev_index + 1;
}
EXPORT_SYMBOL_GPL(page_cache_readahead);
diff --git a/mm/rmap.c b/mm/rmap.c
index 59da5b7..304f519 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -162,8 +162,7 @@ void anon_vma_unlink(struct vm_area_struct *vma)
static void anon_vma_ctor(void *data, struct kmem_cache *cachep,
unsigned long flags)
{
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
struct anon_vma *anon_vma = data;
spin_lock_init(&anon_vma->lock);
@@ -506,6 +505,7 @@ int page_mkclean(struct page *page)
return ret;
}
+EXPORT_SYMBOL_GPL(page_mkclean);
/**
* page_set_anon_rmap - setup new anonymous rmap
diff --git a/mm/shmem.c b/mm/shmem.c
index b2a35eb..f01e8de 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2358,8 +2358,7 @@ static void init_once(void *foo, struct kmem_cache *cachep,
{
struct shmem_inode_info *p = (struct shmem_inode_info *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
inode_init_once(&p->vfs_inode);
#ifdef CONFIG_TMPFS_POSIX_ACL
p->i_acl = NULL;
diff --git a/mm/slab.c b/mm/slab.c
index 168bfe9..acda7e2 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -116,8 +116,7 @@
#include <asm/page.h>
/*
- * DEBUG - 1 for kmem_cache_create() to honour; SLAB_DEBUG_INITIAL,
- * SLAB_RED_ZONE & SLAB_POISON.
+ * DEBUG - 1 for kmem_cache_create() to honour; SLAB_RED_ZONE & SLAB_POISON.
* 0 for faster, smaller code (especially in the critical paths).
*
* STATS - 1 to collect stats for /proc/slabinfo.
@@ -149,10 +148,11 @@
* Usually, the kmalloc caches are cache_line_size() aligned, except when
* DEBUG and FORCED_DEBUG are enabled, then they are BYTES_PER_WORD aligned.
* Some archs want to perform DMA into kmalloc caches and need a guaranteed
- * alignment larger than BYTES_PER_WORD. ARCH_KMALLOC_MINALIGN allows that.
- * Note that this flag disables some debug features.
+ * alignment larger than the alignment of a 64-bit integer.
+ * ARCH_KMALLOC_MINALIGN allows that.
+ * Note that increasing this value may disable some debug features.
*/
-#define ARCH_KMALLOC_MINALIGN 0
+#define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long)
#endif
#ifndef ARCH_SLAB_MINALIGN
@@ -172,15 +172,15 @@
/* Legal flag mask for kmem_cache_create(). */
#if DEBUG
-# define CREATE_MASK (SLAB_DEBUG_INITIAL | SLAB_RED_ZONE | \
+# define CREATE_MASK (SLAB_RED_ZONE | \
SLAB_POISON | SLAB_HWCACHE_ALIGN | \
SLAB_CACHE_DMA | \
- SLAB_MUST_HWCACHE_ALIGN | SLAB_STORE_USER | \
+ SLAB_STORE_USER | \
SLAB_RECLAIM_ACCOUNT | SLAB_PANIC | \
SLAB_DESTROY_BY_RCU | SLAB_MEM_SPREAD)
#else
# define CREATE_MASK (SLAB_HWCACHE_ALIGN | \
- SLAB_CACHE_DMA | SLAB_MUST_HWCACHE_ALIGN | \
+ SLAB_CACHE_DMA | \
SLAB_RECLAIM_ACCOUNT | SLAB_PANIC | \
SLAB_DESTROY_BY_RCU | SLAB_MEM_SPREAD)
#endif
@@ -389,7 +389,6 @@ struct kmem_cache {
unsigned int buffer_size;
u32 reciprocal_buffer_size;
/* 3) touched by every alloc & free from the backend */
- struct kmem_list3 *nodelists[MAX_NUMNODES];
unsigned int flags; /* constant flags */
unsigned int num; /* # of objs per slab */
@@ -444,6 +443,17 @@ struct kmem_cache {
int obj_offset;
int obj_size;
#endif
+ /*
+ * We put nodelists[] at the end of kmem_cache, because we want to size
+ * this array to nr_node_ids slots instead of MAX_NUMNODES
+ * (see kmem_cache_init())
+ * We still use [MAX_NUMNODES] and not [1] or [0] because cache_cache
+ * is statically defined, so we reserve the max number of nodes.
+ */
+ struct kmem_list3 *nodelists[MAX_NUMNODES];
+ /*
+ * Do not add fields after nodelists[]
+ */
};
#define CFLGS_OFF_SLAB (0x80000000UL)
@@ -527,19 +537,22 @@ static int obj_size(struct kmem_cache *cachep)
return cachep->obj_size;
}
-static unsigned long *dbg_redzone1(struct kmem_cache *cachep, void *objp)
+static unsigned long long *dbg_redzone1(struct kmem_cache *cachep, void *objp)
{
BUG_ON(!(cachep->flags & SLAB_RED_ZONE));
- return (unsigned long*) (objp+obj_offset(cachep)-BYTES_PER_WORD);
+ return (unsigned long long*) (objp + obj_offset(cachep) -
+ sizeof(unsigned long long));
}
-static unsigned long *dbg_redzone2(struct kmem_cache *cachep, void *objp)
+static unsigned long long *dbg_redzone2(struct kmem_cache *cachep, void *objp)
{
BUG_ON(!(cachep->flags & SLAB_RED_ZONE));
if (cachep->flags & SLAB_STORE_USER)
- return (unsigned long *)(objp + cachep->buffer_size -
- 2 * BYTES_PER_WORD);
- return (unsigned long *)(objp + cachep->buffer_size - BYTES_PER_WORD);
+ return (unsigned long long *)(objp + cachep->buffer_size -
+ sizeof(unsigned long long) -
+ BYTES_PER_WORD);
+ return (unsigned long long *) (objp + cachep->buffer_size -
+ sizeof(unsigned long long));
}
static void **dbg_userword(struct kmem_cache *cachep, void *objp)
@@ -552,8 +565,8 @@ static void **dbg_userword(struct kmem_cache *cachep, void *objp)
#define obj_offset(x) 0
#define obj_size(cachep) (cachep->buffer_size)
-#define dbg_redzone1(cachep, objp) ({BUG(); (unsigned long *)NULL;})
-#define dbg_redzone2(cachep, objp) ({BUG(); (unsigned long *)NULL;})
+#define dbg_redzone1(cachep, objp) ({BUG(); (unsigned long long *)NULL;})
+#define dbg_redzone2(cachep, objp) ({BUG(); (unsigned long long *)NULL;})
#define dbg_userword(cachep, objp) ({BUG(); (void **)NULL;})
#endif
@@ -592,8 +605,7 @@ static inline void page_set_cache(struct page *page, struct kmem_cache *cache)
static inline struct kmem_cache *page_get_cache(struct page *page)
{
- if (unlikely(PageCompound(page)))
- page = (struct page *)page_private(page);
+ page = compound_head(page);
BUG_ON(!PageSlab(page));
return (struct kmem_cache *)page->lru.next;
}
@@ -605,21 +617,19 @@ static inline void page_set_slab(struct page *page, struct slab *slab)
static inline struct slab *page_get_slab(struct page *page)
{
- if (unlikely(PageCompound(page)))
- page = (struct page *)page_private(page);
BUG_ON(!PageSlab(page));
return (struct slab *)page->lru.prev;
}
static inline struct kmem_cache *virt_to_cache(const void *obj)
{
- struct page *page = virt_to_page(obj);
+ struct page *page = virt_to_head_page(obj);
return page_get_cache(page);
}
static inline struct slab *virt_to_slab(const void *obj)
{
- struct page *page = virt_to_page(obj);
+ struct page *page = virt_to_head_page(obj);
return page_get_slab(page);
}
@@ -678,9 +688,6 @@ static struct kmem_cache cache_cache = {
.shared = 1,
.buffer_size = sizeof(struct kmem_cache),
.name = "kmem_cache",
-#if DEBUG
- .obj_size = sizeof(struct kmem_cache),
-#endif
};
#define BAD_ALIEN_MAGIC 0x01020304ul
@@ -1223,19 +1230,20 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb,
*/
list_for_each_entry(cachep, &cache_chain, next) {
struct array_cache *nc;
- struct array_cache *shared;
+ struct array_cache *shared = NULL;
struct array_cache **alien = NULL;
nc = alloc_arraycache(node, cachep->limit,
cachep->batchcount);
if (!nc)
goto bad;
- shared = alloc_arraycache(node,
+ if (cachep->shared) {
+ shared = alloc_arraycache(node,
cachep->shared * cachep->batchcount,
0xbaadf00d);
- if (!shared)
- goto bad;
-
+ if (!shared)
+ goto bad;
+ }
if (use_alien_caches) {
alien = alloc_alien_cache(node, cachep->limit);
if (!alien)
@@ -1317,8 +1325,8 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb,
shared = l3->shared;
if (shared) {
- free_block(cachep, l3->shared->entry,
- l3->shared->avail, node);
+ free_block(cachep, shared->entry,
+ shared->avail, node);
l3->shared = NULL;
}
@@ -1439,6 +1447,15 @@ void __init kmem_cache_init(void)
cache_cache.array[smp_processor_id()] = &initarray_cache.cache;
cache_cache.nodelists[node] = &initkmem_list3[CACHE_CACHE];
+ /*
+ * struct kmem_cache size depends on nr_node_ids, which
+ * can be less than MAX_NUMNODES.
+ */
+ cache_cache.buffer_size = offsetof(struct kmem_cache, nodelists) +
+ nr_node_ids * sizeof(struct kmem_list3 *);
+#if DEBUG
+ cache_cache.obj_size = cache_cache.buffer_size;
+#endif
cache_cache.buffer_size = ALIGN(cache_cache.buffer_size,
cache_line_size());
cache_cache.reciprocal_buffer_size =
@@ -1763,7 +1780,7 @@ static void print_objinfo(struct kmem_cache *cachep, void *objp, int lines)
char *realobj;
if (cachep->flags & SLAB_RED_ZONE) {
- printk(KERN_ERR "Redzone: 0x%lx/0x%lx.\n",
+ printk(KERN_ERR "Redzone: 0x%llx/0x%llx.\n",
*dbg_redzone1(cachep, objp),
*dbg_redzone2(cachep, objp));
}
@@ -1932,7 +1949,7 @@ static void slab_destroy(struct kmem_cache *cachep, struct slab *slabp)
* For setting up all the kmem_list3s for cache whose buffer_size is same as
* size of kmem_list3.
*/
-static void set_up_list3s(struct kmem_cache *cachep, int index)
+static void __init set_up_list3s(struct kmem_cache *cachep, int index)
{
int node;
@@ -2154,13 +2171,15 @@ kmem_cache_create (const char *name, size_t size, size_t align,
*/
res = probe_kernel_address(pc->name, tmp);
if (res) {
- printk("SLAB: cache with size %d has lost its name\n",
+ printk(KERN_ERR
+ "SLAB: cache with size %d has lost its name\n",
pc->buffer_size);
continue;
}
if (!strcmp(pc->name, name)) {
- printk("kmem_cache_create: duplicate cache %s\n", name);
+ printk(KERN_ERR
+ "kmem_cache_create: duplicate cache %s\n", name);
dump_stack();
goto oops;
}
@@ -2168,12 +2187,6 @@ kmem_cache_create (const char *name, size_t size, size_t align,
#if DEBUG
WARN_ON(strchr(name, ' ')); /* It confuses parsers */
- if ((flags & SLAB_DEBUG_INITIAL) && !ctor) {
- /* No constructor, but inital state check requested */
- printk(KERN_ERR "%s: No con, but init state check "
- "requested - %s\n", __FUNCTION__, name);
- flags &= ~SLAB_DEBUG_INITIAL;
- }
#if FORCED_DEBUG
/*
* Enable redzoning and last user accounting, except for caches with
@@ -2230,7 +2243,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
* is greater than BYTES_PER_WORD.
*/
if (flags & SLAB_RED_ZONE || flags & SLAB_STORE_USER)
- ralign = BYTES_PER_WORD;
+ ralign = __alignof__(unsigned long long);
/* 2) arch mandated alignment */
if (ralign < ARCH_SLAB_MINALIGN) {
@@ -2241,7 +2254,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
ralign = align;
}
/* disable debug if necessary */
- if (ralign > BYTES_PER_WORD)
+ if (ralign > __alignof__(unsigned long long))
flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER);
/*
* 4) Store it.
@@ -2262,8 +2275,8 @@ kmem_cache_create (const char *name, size_t size, size_t align,
*/
if (flags & SLAB_RED_ZONE) {
/* add space for red zone words */
- cachep->obj_offset += BYTES_PER_WORD;
- size += 2 * BYTES_PER_WORD;
+ cachep->obj_offset += sizeof(unsigned long long);
+ size += 2 * sizeof(unsigned long long);
}
if (flags & SLAB_STORE_USER) {
/* user store requires one word storage behind the end of
@@ -2297,7 +2310,8 @@ kmem_cache_create (const char *name, size_t size, size_t align,
left_over = calculate_slab_order(cachep, size, align, flags);
if (!cachep->num) {
- printk("kmem_cache_create: couldn't create cache %s.\n", name);
+ printk(KERN_ERR
+ "kmem_cache_create: couldn't create cache %s.\n", name);
kmem_cache_free(&cache_cache, cachep);
cachep = NULL;
goto oops;
@@ -2736,19 +2750,10 @@ static int cache_grow(struct kmem_cache *cachep,
* Be lazy and only check for valid flags here, keeping it out of the
* critical path in kmem_cache_alloc().
*/
- BUG_ON(flags & ~(GFP_DMA | GFP_LEVEL_MASK | __GFP_NO_GROW));
- if (flags & __GFP_NO_GROW)
- return 0;
+ BUG_ON(flags & ~(GFP_DMA | GFP_LEVEL_MASK));
ctor_flags = SLAB_CTOR_CONSTRUCTOR;
local_flags = (flags & GFP_LEVEL_MASK);
- if (!(local_flags & __GFP_WAIT))
- /*
- * Not allowed to sleep. Need to tell a constructor about
- * this - it might need to know...
- */
- ctor_flags |= SLAB_CTOR_ATOMIC;
-
/* Take the l3 list lock to change the colour_next on this node */
check_irq_off();
l3 = cachep->nodelists[nodeid];
@@ -2832,7 +2837,7 @@ static void kfree_debugcheck(const void *objp)
static inline void verify_redzone_free(struct kmem_cache *cache, void *obj)
{
- unsigned long redzone1, redzone2;
+ unsigned long long redzone1, redzone2;
redzone1 = *dbg_redzone1(cache, obj);
redzone2 = *dbg_redzone2(cache, obj);
@@ -2848,7 +2853,7 @@ static inline void verify_redzone_free(struct kmem_cache *cache, void *obj)
else
slab_error(cache, "memory outside object was overwritten");
- printk(KERN_ERR "%p: redzone 1:0x%lx, redzone 2:0x%lx.\n",
+ printk(KERN_ERR "%p: redzone 1:0x%llx, redzone 2:0x%llx.\n",
obj, redzone1, redzone2);
}
@@ -2861,7 +2866,7 @@ static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp,
objp -= obj_offset(cachep);
kfree_debugcheck(objp);
- page = virt_to_page(objp);
+ page = virt_to_head_page(objp);
slabp = page_get_slab(page);
@@ -2878,15 +2883,6 @@ static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp,
BUG_ON(objnr >= cachep->num);
BUG_ON(objp != index_to_obj(cachep, slabp, objnr));
- if (cachep->flags & SLAB_DEBUG_INITIAL) {
- /*
- * Need to call the slab's constructor so the caller can
- * perform a verify of its state (debugging). Called without
- * the cache-lock held.
- */
- cachep->ctor(objp + obj_offset(cachep),
- cachep, SLAB_CTOR_CONSTRUCTOR | SLAB_CTOR_VERIFY);
- }
if (cachep->flags & SLAB_POISON && cachep->dtor) {
/* we want to cache poison the object,
* call the destruction callback
@@ -2990,6 +2986,14 @@ retry:
slabp = list_entry(entry, struct slab, list);
check_slabp(cachep, slabp);
check_spinlock_acquired(cachep);
+
+ /*
+ * The slab was either on partial or free list so
+ * there must be at least one object available for
+ * allocation.
+ */
+ BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
+
while (slabp->inuse < cachep->num && batchcount--) {
STATS_INC_ALLOCED(cachep);
STATS_INC_ACTIVE(cachep);
@@ -3065,7 +3069,7 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep,
slab_error(cachep, "double free, or memory outside"
" object was overwritten");
printk(KERN_ERR
- "%p: redzone 1:0x%lx, redzone 2:0x%lx\n",
+ "%p: redzone 1:0x%llx, redzone 2:0x%llx\n",
objp, *dbg_redzone1(cachep, objp),
*dbg_redzone2(cachep, objp));
}
@@ -3077,20 +3081,14 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep,
struct slab *slabp;
unsigned objnr;
- slabp = page_get_slab(virt_to_page(objp));
+ slabp = page_get_slab(virt_to_head_page(objp));
objnr = (unsigned)(objp - slabp->s_mem) / cachep->buffer_size;
slab_bufctl(slabp)[objnr] = BUFCTL_ACTIVE;
}
#endif
objp += obj_offset(cachep);
- if (cachep->ctor && cachep->flags & SLAB_POISON) {
- unsigned long ctor_flags = SLAB_CTOR_CONSTRUCTOR;
-
- if (!(flags & __GFP_WAIT))
- ctor_flags |= SLAB_CTOR_ATOMIC;
-
- cachep->ctor(objp, cachep, ctor_flags);
- }
+ if (cachep->ctor && cachep->flags & SLAB_POISON)
+ cachep->ctor(objp, cachep, SLAB_CTOR_CONSTRUCTOR);
#if ARCH_SLAB_MINALIGN
if ((u32)objp & (ARCH_SLAB_MINALIGN-1)) {
printk(KERN_ERR "0x%p: not aligned to ARCH_SLAB_MINALIGN=%d\n",
@@ -3145,7 +3143,7 @@ static int __init failslab_debugfs(void)
struct dentry *dir;
int err;
- err = init_fault_attr_dentries(&failslab.attr, "failslab");
+ err = init_fault_attr_dentries(&failslab.attr, "failslab");
if (err)
return err;
dir = failslab.attr.dentries.dir;
@@ -3183,9 +3181,6 @@ static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags)
check_irq_off();
- if (should_failslab(cachep, flags))
- return NULL;
-
ac = cpu_cache_get(cachep);
if (likely(ac->avail)) {
STATS_INC_ALLOCHIT(cachep);
@@ -3259,7 +3254,7 @@ retry:
flags | GFP_THISNODE, nid);
}
- if (!obj && !(flags & __GFP_NO_GROW)) {
+ if (!obj) {
/*
* This allocation will be performed within the constraints
* of the current cpuset / memory policy requirements.
@@ -3377,6 +3372,9 @@ __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid,
unsigned long save_flags;
void *ptr;
+ if (should_failslab(cachep, flags))
+ return NULL;
+
cache_alloc_debugcheck_before(cachep, flags);
local_irq_save(save_flags);
@@ -3447,6 +3445,9 @@ __cache_alloc(struct kmem_cache *cachep, gfp_t flags, void *caller)
unsigned long save_flags;
void *objp;
+ if (should_failslab(cachep, flags))
+ return NULL;
+
cache_alloc_debugcheck_before(cachep, flags);
local_irq_save(save_flags);
objp = __do_cache_alloc(cachep, flags);
@@ -3740,6 +3741,53 @@ EXPORT_SYMBOL(__kmalloc);
#endif
/**
+ * krealloc - reallocate memory. The contents will remain unchanged.
+ *
+ * @p: object to reallocate memory for.
+ * @new_size: how many bytes of memory are required.
+ * @flags: the type of memory to allocate.
+ *
+ * The contents of the object pointed to are preserved up to the
+ * lesser of the new and old sizes. If @p is %NULL, krealloc()
+ * behaves exactly like kmalloc(). If @size is 0 and @p is not a
+ * %NULL pointer, the object pointed to is freed.
+ */
+void *krealloc(const void *p, size_t new_size, gfp_t flags)
+{
+ struct kmem_cache *cache, *new_cache;
+ void *ret;
+
+ if (unlikely(!p))
+ return kmalloc_track_caller(new_size, flags);
+
+ if (unlikely(!new_size)) {
+ kfree(p);
+ return NULL;
+ }
+
+ cache = virt_to_cache(p);
+ new_cache = __find_general_cachep(new_size, flags);
+
+ /*
+ * If new size fits in the current cache, bail out.
+ */
+ if (likely(cache == new_cache))
+ return (void *)p;
+
+ /*
+ * We are on the slow-path here so do not use __cache_alloc
+ * because it bloats kernel text.
+ */
+ ret = kmalloc_track_caller(new_size, flags);
+ if (ret) {
+ memcpy(ret, p, min(new_size, ksize(p)));
+ kfree(p);
+ }
+ return ret;
+}
+EXPORT_SYMBOL(krealloc);
+
+/**
* kmem_cache_free - Deallocate an object
* @cachep: The cache the allocation was from.
* @objp: The previously allocated object.
@@ -3815,12 +3863,15 @@ static int alloc_kmemlist(struct kmem_cache *cachep)
goto fail;
}
- new_shared = alloc_arraycache(node,
+ new_shared = NULL;
+ if (cachep->shared) {
+ new_shared = alloc_arraycache(node,
cachep->shared*cachep->batchcount,
0xbaadf00d);
- if (!new_shared) {
- free_alien_cache(new_alien);
- goto fail;
+ if (!new_shared) {
+ free_alien_cache(new_alien);
+ goto fail;
+ }
}
l3 = cachep->nodelists[node];
@@ -3978,10 +4029,8 @@ static int enable_cpucache(struct kmem_cache *cachep)
* to a larger limit. Thus disabled by default.
*/
shared = 0;
-#ifdef CONFIG_SMP
- if (cachep->buffer_size <= PAGE_SIZE)
+ if (cachep->buffer_size <= PAGE_SIZE && num_possible_cpus() > 1)
shared = 8;
-#endif
#if DEBUG
/*
@@ -4383,16 +4432,12 @@ static void handle_slab(unsigned long *n, struct kmem_cache *c, struct slab *s)
static void show_symbol(struct seq_file *m, unsigned long address)
{
#ifdef CONFIG_KALLSYMS
- char *modname;
- const char *name;
unsigned long offset, size;
- char namebuf[KSYM_NAME_LEN+1];
-
- name = kallsyms_lookup(address, &size, &offset, &modname, namebuf);
+ char modname[MODULE_NAME_LEN + 1], name[KSYM_NAME_LEN + 1];
- if (name) {
+ if (lookup_symbol_attrs(address, &size, &offset, modname, name) == 0) {
seq_printf(m, "%s+%#lx/%#lx", name, offset, size);
- if (modname)
+ if (modname[0])
seq_printf(m, " [%s]", modname);
return;
}
@@ -4481,7 +4526,7 @@ const struct seq_operations slabstats_op = {
* allocated with either kmalloc() or kmem_cache_alloc(). The object
* must not be freed during the duration of the call.
*/
-unsigned int ksize(const void *objp)
+size_t ksize(const void *objp)
{
if (unlikely(objp == NULL))
return 0;
diff --git a/mm/slob.c b/mm/slob.c
index 5adc29c..c6933bc 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -21,7 +21,7 @@
*
* SLAB is emulated on top of SLOB by simply calling constructors and
* destructors for every SLAB allocation. Objects are returned with
- * the 8-byte alignment unless the SLAB_MUST_HWCACHE_ALIGN flag is
+ * the 8-byte alignment unless the SLAB_HWCACHE_ALIGN flag is
* set, in which case the low-level allocator will fragment blocks to
* create the proper alignment. Again, objects of page-size or greater
* are allocated by calling __get_free_pages. As SLAB objects know
@@ -150,15 +150,6 @@ static void slob_free(void *block, int size)
spin_unlock_irqrestore(&slob_lock, flags);
}
-static int FASTCALL(find_order(int size));
-static int fastcall find_order(int size)
-{
- int order = 0;
- for ( ; size > 4096 ; size >>=1)
- order++;
- return order;
-}
-
void *__kmalloc(size_t size, gfp_t gfp)
{
slob_t *m;
@@ -174,7 +165,7 @@ void *__kmalloc(size_t size, gfp_t gfp)
if (!bb)
return 0;
- bb->order = find_order(size);
+ bb->order = get_order(size);
bb->pages = (void *)__get_free_pages(gfp, bb->order);
if (bb->pages) {
@@ -190,6 +181,39 @@ void *__kmalloc(size_t size, gfp_t gfp)
}
EXPORT_SYMBOL(__kmalloc);
+/**
+ * krealloc - reallocate memory. The contents will remain unchanged.
+ *
+ * @p: object to reallocate memory for.
+ * @new_size: how many bytes of memory are required.
+ * @flags: the type of memory to allocate.
+ *
+ * The contents of the object pointed to are preserved up to the
+ * lesser of the new and old sizes. If @p is %NULL, krealloc()
+ * behaves exactly like kmalloc(). If @size is 0 and @p is not a
+ * %NULL pointer, the object pointed to is freed.
+ */
+void *krealloc(const void *p, size_t new_size, gfp_t flags)
+{
+ void *ret;
+
+ if (unlikely(!p))
+ return kmalloc_track_caller(new_size, flags);
+
+ if (unlikely(!new_size)) {
+ kfree(p);
+ return NULL;
+ }
+
+ ret = kmalloc_track_caller(new_size, flags);
+ if (ret) {
+ memcpy(ret, p, min(new_size, ksize(p)));
+ kfree(p);
+ }
+ return ret;
+}
+EXPORT_SYMBOL(krealloc);
+
void kfree(const void *block)
{
bigblock_t *bb, **last = &bigblocks;
@@ -219,7 +243,7 @@ void kfree(const void *block)
EXPORT_SYMBOL(kfree);
-unsigned int ksize(const void *block)
+size_t ksize(const void *block)
{
bigblock_t *bb;
unsigned long flags;
@@ -262,10 +286,11 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
c->ctor = ctor;
c->dtor = dtor;
/* ignore alignment unless it's forced */
- c->align = (flags & SLAB_MUST_HWCACHE_ALIGN) ? SLOB_ALIGN : 0;
+ c->align = (flags & SLAB_HWCACHE_ALIGN) ? SLOB_ALIGN : 0;
if (c->align < align)
c->align = align;
- }
+ } else if (flags & SLAB_PANIC)
+ panic("Cannot create slab cache %s\n", name);
return c;
}
@@ -284,7 +309,7 @@ void *kmem_cache_alloc(struct kmem_cache *c, gfp_t flags)
if (c->size < PAGE_SIZE)
b = slob_alloc(c->size, flags, c->align);
else
- b = (void *)__get_free_pages(flags, find_order(c->size));
+ b = (void *)__get_free_pages(flags, get_order(c->size));
if (c->ctor)
c->ctor(b, c, SLAB_CTOR_CONSTRUCTOR);
@@ -311,7 +336,7 @@ void kmem_cache_free(struct kmem_cache *c, void *b)
if (c->size < PAGE_SIZE)
slob_free(b, c->size);
else
- free_pages((unsigned long)b, find_order(c->size));
+ free_pages((unsigned long)b, get_order(c->size));
}
EXPORT_SYMBOL(kmem_cache_free);
diff --git a/mm/slub.c b/mm/slub.c
new file mode 100644
index 0000000..5db3da5
--- /dev/null
+++ b/mm/slub.c
@@ -0,0 +1,3520 @@
+/*
+ * SLUB: A slab allocator that limits cache line use instead of queuing
+ * objects in per cpu and per node lists.
+ *
+ * The allocator synchronizes using per slab locks and only
+ * uses a centralized lock to manage a pool of partial slabs.
+ *
+ * (C) 2007 SGI, Christoph Lameter <clameter@sgi.com>
+ */
+
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/bit_spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/slab.h>
+#include <linux/seq_file.h>
+#include <linux/cpu.h>
+#include <linux/cpuset.h>
+#include <linux/mempolicy.h>
+#include <linux/ctype.h>
+#include <linux/kallsyms.h>
+
+/*
+ * Lock order:
+ * 1. slab_lock(page)
+ * 2. slab->list_lock
+ *
+ * The slab_lock protects operations on the object of a particular
+ * slab and its metadata in the page struct. If the slab lock
+ * has been taken then no allocations nor frees can be performed
+ * on the objects in the slab nor can the slab be added or removed
+ * from the partial or full lists since this would mean modifying
+ * the page_struct of the slab.
+ *
+ * The list_lock protects the partial and full list on each node and
+ * the partial slab counter. If taken then no new slabs may be added or
+ * removed from the lists nor make the number of partial slabs be modified.
+ * (Note that the total number of slabs is an atomic value that may be
+ * modified without taking the list lock).
+ *
+ * The list_lock is a centralized lock and thus we avoid taking it as
+ * much as possible. As long as SLUB does not have to handle partial
+ * slabs, operations can continue without any centralized lock. F.e.
+ * allocating a long series of objects that fill up slabs does not require
+ * the list lock.
+ *
+ * The lock order is sometimes inverted when we are trying to get a slab
+ * off a list. We take the list_lock and then look for a page on the list
+ * to use. While we do that objects in the slabs may be freed. We can
+ * only operate on the slab if we have also taken the slab_lock. So we use
+ * a slab_trylock() on the slab. If trylock was successful then no frees
+ * can occur anymore and we can use the slab for allocations etc. If the
+ * slab_trylock() does not succeed then frees are in progress in the slab and
+ * we must stay away from it for a while since we may cause a bouncing
+ * cacheline if we try to acquire the lock. So go onto the next slab.
+ * If all pages are busy then we may allocate a new slab instead of reusing
+ * a partial slab. A new slab has noone operating on it and thus there is
+ * no danger of cacheline contention.
+ *
+ * Interrupts are disabled during allocation and deallocation in order to
+ * make the slab allocator safe to use in the context of an irq. In addition
+ * interrupts are disabled to ensure that the processor does not change
+ * while handling per_cpu slabs, due to kernel preemption.
+ *
+ * SLUB assigns one slab for allocation to each processor.
+ * Allocations only occur from these slabs called cpu slabs.
+ *
+ * Slabs with free elements are kept on a partial list.
+ * There is no list for full slabs. If an object in a full slab is
+ * freed then the slab will show up again on the partial lists.
+ * Otherwise there is no need to track full slabs unless we have to
+ * track full slabs for debugging purposes.
+ *
+ * Slabs are freed when they become empty. Teardown and setup is
+ * minimal so we rely on the page allocators per cpu caches for
+ * fast frees and allocs.
+ *
+ * Overloading of page flags that are otherwise used for LRU management.
+ *
+ * PageActive The slab is used as a cpu cache. Allocations
+ * may be performed from the slab. The slab is not
+ * on any slab list and cannot be moved onto one.
+ *
+ * PageError Slab requires special handling due to debug
+ * options set. This moves slab handling out of
+ * the fast path.
+ */
+
+/*
+ * Issues still to be resolved:
+ *
+ * - The per cpu array is updated for each new slab and and is a remote
+ * cacheline for most nodes. This could become a bouncing cacheline given
+ * enough frequent updates. There are 16 pointers in a cacheline.so at
+ * max 16 cpus could compete. Likely okay.
+ *
+ * - Support PAGE_ALLOC_DEBUG. Should be easy to do.
+ *
+ * - Variable sizing of the per node arrays
+ */
+
+/* Enable to test recovery from slab corruption on boot */
+#undef SLUB_RESILIENCY_TEST
+
+#if PAGE_SHIFT <= 12
+
+/*
+ * Small page size. Make sure that we do not fragment memory
+ */
+#define DEFAULT_MAX_ORDER 1
+#define DEFAULT_MIN_OBJECTS 4
+
+#else
+
+/*
+ * Large page machines are customarily able to handle larger
+ * page orders.
+ */
+#define DEFAULT_MAX_ORDER 2
+#define DEFAULT_MIN_OBJECTS 8
+
+#endif
+
+/*
+ * Mininum number of partial slabs. These will be left on the partial
+ * lists even if they are empty. kmem_cache_shrink may reclaim them.
+ */
+#define MIN_PARTIAL 2
+
+/*
+ * Maximum number of desirable partial slabs.
+ * The existence of more partial slabs makes kmem_cache_shrink
+ * sort the partial list by the number of objects in the.
+ */
+#define MAX_PARTIAL 10
+
+#define DEBUG_DEFAULT_FLAGS (SLAB_DEBUG_FREE | SLAB_RED_ZONE | \
+ SLAB_POISON | SLAB_STORE_USER)
+/*
+ * Set of flags that will prevent slab merging
+ */
+#define SLUB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \
+ SLAB_TRACE | SLAB_DESTROY_BY_RCU)
+
+#define SLUB_MERGE_SAME (SLAB_DEBUG_FREE | SLAB_RECLAIM_ACCOUNT | \
+ SLAB_CACHE_DMA)
+
+#ifndef ARCH_KMALLOC_MINALIGN
+#define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long long)
+#endif
+
+#ifndef ARCH_SLAB_MINALIGN
+#define ARCH_SLAB_MINALIGN __alignof__(unsigned long long)
+#endif
+
+/* Internal SLUB flags */
+#define __OBJECT_POISON 0x80000000 /* Poison object */
+
+static int kmem_size = sizeof(struct kmem_cache);
+
+#ifdef CONFIG_SMP
+static struct notifier_block slab_notifier;
+#endif
+
+static enum {
+ DOWN, /* No slab functionality available */
+ PARTIAL, /* kmem_cache_open() works but kmalloc does not */
+ UP, /* Everything works */
+ SYSFS /* Sysfs up */
+} slab_state = DOWN;
+
+/* A list of all slab caches on the system */
+static DECLARE_RWSEM(slub_lock);
+LIST_HEAD(slab_caches);
+
+#ifdef CONFIG_SYSFS
+static int sysfs_slab_add(struct kmem_cache *);
+static int sysfs_slab_alias(struct kmem_cache *, const char *);
+static void sysfs_slab_remove(struct kmem_cache *);
+#else
+static int sysfs_slab_add(struct kmem_cache *s) { return 0; }
+static int sysfs_slab_alias(struct kmem_cache *s, const char *p) { return 0; }
+static void sysfs_slab_remove(struct kmem_cache *s) {}
+#endif
+
+/********************************************************************
+ * Core slab cache functions
+ *******************************************************************/
+
+int slab_is_available(void)
+{
+ return slab_state >= UP;
+}
+
+static inline struct kmem_cache_node *get_node(struct kmem_cache *s, int node)
+{
+#ifdef CONFIG_NUMA
+ return s->node[node];
+#else
+ return &s->local_node;
+#endif
+}
+
+/*
+ * Object debugging
+ */
+static void print_section(char *text, u8 *addr, unsigned int length)
+{
+ int i, offset;
+ int newline = 1;
+ char ascii[17];
+
+ ascii[16] = 0;
+
+ for (i = 0; i < length; i++) {
+ if (newline) {
+ printk(KERN_ERR "%10s 0x%p: ", text, addr + i);
+ newline = 0;
+ }
+ printk(" %02x", addr[i]);
+ offset = i % 16;
+ ascii[offset] = isgraph(addr[i]) ? addr[i] : '.';
+ if (offset == 15) {
+ printk(" %s\n",ascii);
+ newline = 1;
+ }
+ }
+ if (!newline) {
+ i %= 16;
+ while (i < 16) {
+ printk(" ");
+ ascii[i] = ' ';
+ i++;
+ }
+ printk(" %s\n", ascii);
+ }
+}
+
+/*
+ * Slow version of get and set free pointer.
+ *
+ * This requires touching the cache lines of kmem_cache.
+ * The offset can also be obtained from the page. In that
+ * case it is in the cacheline that we already need to touch.
+ */
+static void *get_freepointer(struct kmem_cache *s, void *object)
+{
+ return *(void **)(object + s->offset);
+}
+
+static void set_freepointer(struct kmem_cache *s, void *object, void *fp)
+{
+ *(void **)(object + s->offset) = fp;
+}
+
+/*
+ * Tracking user of a slab.
+ */
+struct track {
+ void *addr; /* Called from address */
+ int cpu; /* Was running on cpu */
+ int pid; /* Pid context */
+ unsigned long when; /* When did the operation occur */
+};
+
+enum track_item { TRACK_ALLOC, TRACK_FREE };
+
+static struct track *get_track(struct kmem_cache *s, void *object,
+ enum track_item alloc)
+{
+ struct track *p;
+
+ if (s->offset)
+ p = object + s->offset + sizeof(void *);
+ else
+ p = object + s->inuse;
+
+ return p + alloc;
+}
+
+static void set_track(struct kmem_cache *s, void *object,
+ enum track_item alloc, void *addr)
+{
+ struct track *p;
+
+ if (s->offset)
+ p = object + s->offset + sizeof(void *);
+ else
+ p = object + s->inuse;
+
+ p += alloc;
+ if (addr) {
+ p->addr = addr;
+ p->cpu = smp_processor_id();
+ p->pid = current ? current->pid : -1;
+ p->when = jiffies;
+ } else
+ memset(p, 0, sizeof(struct track));
+}
+
+static void init_tracking(struct kmem_cache *s, void *object)
+{
+ if (s->flags & SLAB_STORE_USER) {
+ set_track(s, object, TRACK_FREE, NULL);
+ set_track(s, object, TRACK_ALLOC, NULL);
+ }
+}
+
+static void print_track(const char *s, struct track *t)
+{
+ if (!t->addr)
+ return;
+
+ printk(KERN_ERR "%s: ", s);
+ __print_symbol("%s", (unsigned long)t->addr);
+ printk(" jiffies_ago=%lu cpu=%u pid=%d\n", jiffies - t->when, t->cpu, t->pid);
+}
+
+static void print_trailer(struct kmem_cache *s, u8 *p)
+{
+ unsigned int off; /* Offset of last byte */
+
+ if (s->flags & SLAB_RED_ZONE)
+ print_section("Redzone", p + s->objsize,
+ s->inuse - s->objsize);
+
+ printk(KERN_ERR "FreePointer 0x%p -> 0x%p\n",
+ p + s->offset,
+ get_freepointer(s, p));
+
+ if (s->offset)
+ off = s->offset + sizeof(void *);
+ else
+ off = s->inuse;
+
+ if (s->flags & SLAB_STORE_USER) {
+ print_track("Last alloc", get_track(s, p, TRACK_ALLOC));
+ print_track("Last free ", get_track(s, p, TRACK_FREE));
+ off += 2 * sizeof(struct track);
+ }
+
+ if (off != s->size)
+ /* Beginning of the filler is the free pointer */
+ print_section("Filler", p + off, s->size - off);
+}
+
+static void object_err(struct kmem_cache *s, struct page *page,
+ u8 *object, char *reason)
+{
+ u8 *addr = page_address(page);
+
+ printk(KERN_ERR "*** SLUB %s: %s@0x%p slab 0x%p\n",
+ s->name, reason, object, page);
+ printk(KERN_ERR " offset=%tu flags=0x%04lx inuse=%u freelist=0x%p\n",
+ object - addr, page->flags, page->inuse, page->freelist);
+ if (object > addr + 16)
+ print_section("Bytes b4", object - 16, 16);
+ print_section("Object", object, min(s->objsize, 128));
+ print_trailer(s, object);
+ dump_stack();
+}
+
+static void slab_err(struct kmem_cache *s, struct page *page, char *reason, ...)
+{
+ va_list args;
+ char buf[100];
+
+ va_start(args, reason);
+ vsnprintf(buf, sizeof(buf), reason, args);
+ va_end(args);
+ printk(KERN_ERR "*** SLUB %s: %s in slab @0x%p\n", s->name, buf,
+ page);
+ dump_stack();
+}
+
+static void init_object(struct kmem_cache *s, void *object, int active)
+{
+ u8 *p = object;
+
+ if (s->flags & __OBJECT_POISON) {
+ memset(p, POISON_FREE, s->objsize - 1);
+ p[s->objsize -1] = POISON_END;
+ }
+
+ if (s->flags & SLAB_RED_ZONE)
+ memset(p + s->objsize,
+ active ? SLUB_RED_ACTIVE : SLUB_RED_INACTIVE,
+ s->inuse - s->objsize);
+}
+
+static int check_bytes(u8 *start, unsigned int value, unsigned int bytes)
+{
+ while (bytes) {
+ if (*start != (u8)value)
+ return 0;
+ start++;
+ bytes--;
+ }
+ return 1;
+}
+
+
+static int check_valid_pointer(struct kmem_cache *s, struct page *page,
+ void *object)
+{
+ void *base;
+
+ if (!object)
+ return 1;
+
+ base = page_address(page);
+ if (object < base || object >= base + s->objects * s->size ||
+ (object - base) % s->size) {
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Object layout:
+ *
+ * object address
+ * Bytes of the object to be managed.
+ * If the freepointer may overlay the object then the free
+ * pointer is the first word of the object.
+ * Poisoning uses 0x6b (POISON_FREE) and the last byte is
+ * 0xa5 (POISON_END)
+ *
+ * object + s->objsize
+ * Padding to reach word boundary. This is also used for Redzoning.
+ * Padding is extended to word size if Redzoning is enabled
+ * and objsize == inuse.
+ * We fill with 0xbb (RED_INACTIVE) for inactive objects and with
+ * 0xcc (RED_ACTIVE) for objects in use.
+ *
+ * object + s->inuse
+ * A. Free pointer (if we cannot overwrite object on free)
+ * B. Tracking data for SLAB_STORE_USER
+ * C. Padding to reach required alignment boundary
+ * Padding is done using 0x5a (POISON_INUSE)
+ *
+ * object + s->size
+ *
+ * If slabcaches are merged then the objsize and inuse boundaries are to
+ * be ignored. And therefore no slab options that rely on these boundaries
+ * may be used with merged slabcaches.
+ */
+
+static void restore_bytes(struct kmem_cache *s, char *message, u8 data,
+ void *from, void *to)
+{
+ printk(KERN_ERR "@@@ SLUB %s: Restoring %s (0x%x) from 0x%p-0x%p\n",
+ s->name, message, data, from, to - 1);
+ memset(from, data, to - from);
+}
+
+static int check_pad_bytes(struct kmem_cache *s, struct page *page, u8 *p)
+{
+ unsigned long off = s->inuse; /* The end of info */
+
+ if (s->offset)
+ /* Freepointer is placed after the object. */
+ off += sizeof(void *);
+
+ if (s->flags & SLAB_STORE_USER)
+ /* We also have user information there */
+ off += 2 * sizeof(struct track);
+
+ if (s->size == off)
+ return 1;
+
+ if (check_bytes(p + off, POISON_INUSE, s->size - off))
+ return 1;
+
+ object_err(s, page, p, "Object padding check fails");
+
+ /*
+ * Restore padding
+ */
+ restore_bytes(s, "object padding", POISON_INUSE, p + off, p + s->size);
+ return 0;
+}
+
+static int slab_pad_check(struct kmem_cache *s, struct page *page)
+{
+ u8 *p;
+ int length, remainder;
+
+ if (!(s->flags & SLAB_POISON))
+ return 1;
+
+ p = page_address(page);
+ length = s->objects * s->size;
+ remainder = (PAGE_SIZE << s->order) - length;
+ if (!remainder)
+ return 1;
+
+ if (!check_bytes(p + length, POISON_INUSE, remainder)) {
+ slab_err(s, page, "Padding check failed");
+ restore_bytes(s, "slab padding", POISON_INUSE, p + length,
+ p + length + remainder);
+ return 0;
+ }
+ return 1;
+}
+
+static int check_object(struct kmem_cache *s, struct page *page,
+ void *object, int active)
+{
+ u8 *p = object;
+ u8 *endobject = object + s->objsize;
+
+ if (s->flags & SLAB_RED_ZONE) {
+ unsigned int red =
+ active ? SLUB_RED_ACTIVE : SLUB_RED_INACTIVE;
+
+ if (!check_bytes(endobject, red, s->inuse - s->objsize)) {
+ object_err(s, page, object,
+ active ? "Redzone Active" : "Redzone Inactive");
+ restore_bytes(s, "redzone", red,
+ endobject, object + s->inuse);
+ return 0;
+ }
+ } else {
+ if ((s->flags & SLAB_POISON) && s->objsize < s->inuse &&
+ !check_bytes(endobject, POISON_INUSE,
+ s->inuse - s->objsize)) {
+ object_err(s, page, p, "Alignment padding check fails");
+ /*
+ * Fix it so that there will not be another report.
+ *
+ * Hmmm... We may be corrupting an object that now expects
+ * to be longer than allowed.
+ */
+ restore_bytes(s, "alignment padding", POISON_INUSE,
+ endobject, object + s->inuse);
+ }
+ }
+
+ if (s->flags & SLAB_POISON) {
+ if (!active && (s->flags & __OBJECT_POISON) &&
+ (!check_bytes(p, POISON_FREE, s->objsize - 1) ||
+ p[s->objsize - 1] != POISON_END)) {
+
+ object_err(s, page, p, "Poison check failed");
+ restore_bytes(s, "Poison", POISON_FREE,
+ p, p + s->objsize -1);
+ restore_bytes(s, "Poison", POISON_END,
+ p + s->objsize - 1, p + s->objsize);
+ return 0;
+ }
+ /*
+ * check_pad_bytes cleans up on its own.
+ */
+ check_pad_bytes(s, page, p);
+ }
+
+ if (!s->offset && active)
+ /*
+ * Object and freepointer overlap. Cannot check
+ * freepointer while object is allocated.
+ */
+ return 1;
+
+ /* Check free pointer validity */
+ if (!check_valid_pointer(s, page, get_freepointer(s, p))) {
+ object_err(s, page, p, "Freepointer corrupt");
+ /*
+ * No choice but to zap it and thus loose the remainder
+ * of the free objects in this slab. May cause
+ * another error because the object count maybe
+ * wrong now.
+ */
+ set_freepointer(s, p, NULL);
+ return 0;
+ }
+ return 1;
+}
+
+static int check_slab(struct kmem_cache *s, struct page *page)
+{
+ VM_BUG_ON(!irqs_disabled());
+
+ if (!PageSlab(page)) {
+ slab_err(s, page, "Not a valid slab page flags=%lx "
+ "mapping=0x%p count=%d", page->flags, page->mapping,
+ page_count(page));
+ return 0;
+ }
+ if (page->offset * sizeof(void *) != s->offset) {
+ slab_err(s, page, "Corrupted offset %lu flags=0x%lx "
+ "mapping=0x%p count=%d",
+ (unsigned long)(page->offset * sizeof(void *)),
+ page->flags,
+ page->mapping,
+ page_count(page));
+ return 0;
+ }
+ if (page->inuse > s->objects) {
+ slab_err(s, page, "inuse %u > max %u @0x%p flags=%lx "
+ "mapping=0x%p count=%d",
+ s->name, page->inuse, s->objects, page->flags,
+ page->mapping, page_count(page));
+ return 0;
+ }
+ /* Slab_pad_check fixes things up after itself */
+ slab_pad_check(s, page);
+ return 1;
+}
+
+/*
+ * Determine if a certain object on a page is on the freelist and
+ * therefore free. Must hold the slab lock for cpu slabs to
+ * guarantee that the chains are consistent.
+ */
+static int on_freelist(struct kmem_cache *s, struct page *page, void *search)
+{
+ int nr = 0;
+ void *fp = page->freelist;
+ void *object = NULL;
+
+ while (fp && nr <= s->objects) {
+ if (fp == search)
+ return 1;
+ if (!check_valid_pointer(s, page, fp)) {
+ if (object) {
+ object_err(s, page, object,
+ "Freechain corrupt");
+ set_freepointer(s, object, NULL);
+ break;
+ } else {
+ slab_err(s, page, "Freepointer 0x%p corrupt",
+ fp);
+ page->freelist = NULL;
+ page->inuse = s->objects;
+ printk(KERN_ERR "@@@ SLUB %s: Freelist "
+ "cleared. Slab 0x%p\n",
+ s->name, page);
+ return 0;
+ }
+ break;
+ }
+ object = fp;
+ fp = get_freepointer(s, object);
+ nr++;
+ }
+
+ if (page->inuse != s->objects - nr) {
+ slab_err(s, page, "Wrong object count. Counter is %d but "
+ "counted were %d", s, page, page->inuse,
+ s->objects - nr);
+ page->inuse = s->objects - nr;
+ printk(KERN_ERR "@@@ SLUB %s: Object count adjusted. "
+ "Slab @0x%p\n", s->name, page);
+ }
+ return search == NULL;
+}
+
+/*
+ * Tracking of fully allocated slabs for debugging
+ */
+static void add_full(struct kmem_cache_node *n, struct page *page)
+{
+ spin_lock(&n->list_lock);
+ list_add(&page->lru, &n->full);
+ spin_unlock(&n->list_lock);
+}
+
+static void remove_full(struct kmem_cache *s, struct page *page)
+{
+ struct kmem_cache_node *n;
+
+ if (!(s->flags & SLAB_STORE_USER))
+ return;
+
+ n = get_node(s, page_to_nid(page));
+
+ spin_lock(&n->list_lock);
+ list_del(&page->lru);
+ spin_unlock(&n->list_lock);
+}
+
+static int alloc_object_checks(struct kmem_cache *s, struct page *page,
+ void *object)
+{
+ if (!check_slab(s, page))
+ goto bad;
+
+ if (object && !on_freelist(s, page, object)) {
+ slab_err(s, page, "Object 0x%p already allocated", object);
+ goto bad;
+ }
+
+ if (!check_valid_pointer(s, page, object)) {
+ object_err(s, page, object, "Freelist Pointer check fails");
+ goto bad;
+ }
+
+ if (!object)
+ return 1;
+
+ if (!check_object(s, page, object, 0))
+ goto bad;
+
+ return 1;
+bad:
+ if (PageSlab(page)) {
+ /*
+ * If this is a slab page then lets do the best we can
+ * to avoid issues in the future. Marking all objects
+ * as used avoids touching the remainder.
+ */
+ printk(KERN_ERR "@@@ SLUB: %s slab 0x%p. Marking all objects used.\n",
+ s->name, page);
+ page->inuse = s->objects;
+ page->freelist = NULL;
+ /* Fix up fields that may be corrupted */
+ page->offset = s->offset / sizeof(void *);
+ }
+ return 0;
+}
+
+static int free_object_checks(struct kmem_cache *s, struct page *page,
+ void *object)
+{
+ if (!check_slab(s, page))
+ goto fail;
+
+ if (!check_valid_pointer(s, page, object)) {
+ slab_err(s, page, "Invalid object pointer 0x%p", object);
+ goto fail;
+ }
+
+ if (on_freelist(s, page, object)) {
+ slab_err(s, page, "Object 0x%p already free", object);
+ goto fail;
+ }
+
+ if (!check_object(s, page, object, 1))
+ return 0;
+
+ if (unlikely(s != page->slab)) {
+ if (!PageSlab(page))
+ slab_err(s, page, "Attempt to free object(0x%p) "
+ "outside of slab", object);
+ else
+ if (!page->slab) {
+ printk(KERN_ERR
+ "SLUB <none>: no slab for object 0x%p.\n",
+ object);
+ dump_stack();
+ }
+ else
+ slab_err(s, page, "object at 0x%p belongs "
+ "to slab %s", object, page->slab->name);
+ goto fail;
+ }
+ return 1;
+fail:
+ printk(KERN_ERR "@@@ SLUB: %s slab 0x%p object at 0x%p not freed.\n",
+ s->name, page, object);
+ return 0;
+}
+
+/*
+ * Slab allocation and freeing
+ */
+static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
+{
+ struct page * page;
+ int pages = 1 << s->order;
+
+ if (s->order)
+ flags |= __GFP_COMP;
+
+ if (s->flags & SLAB_CACHE_DMA)
+ flags |= SLUB_DMA;
+
+ if (node == -1)
+ page = alloc_pages(flags, s->order);
+ else
+ page = alloc_pages_node(node, flags, s->order);
+
+ if (!page)
+ return NULL;
+
+ mod_zone_page_state(page_zone(page),
+ (s->flags & SLAB_RECLAIM_ACCOUNT) ?
+ NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
+ pages);
+
+ return page;
+}
+
+static void setup_object(struct kmem_cache *s, struct page *page,
+ void *object)
+{
+ if (PageError(page)) {
+ init_object(s, object, 0);
+ init_tracking(s, object);
+ }
+
+ if (unlikely(s->ctor))
+ s->ctor(object, s, SLAB_CTOR_CONSTRUCTOR);
+}
+
+static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
+{
+ struct page *page;
+ struct kmem_cache_node *n;
+ void *start;
+ void *end;
+ void *last;
+ void *p;
+
+ BUG_ON(flags & ~(GFP_DMA | GFP_LEVEL_MASK));
+
+ if (flags & __GFP_WAIT)
+ local_irq_enable();
+
+ page = allocate_slab(s, flags & GFP_LEVEL_MASK, node);
+ if (!page)
+ goto out;
+
+ n = get_node(s, page_to_nid(page));
+ if (n)
+ atomic_long_inc(&n->nr_slabs);
+ page->offset = s->offset / sizeof(void *);
+ page->slab = s;
+ page->flags |= 1 << PG_slab;
+ if (s->flags & (SLAB_DEBUG_FREE | SLAB_RED_ZONE | SLAB_POISON |
+ SLAB_STORE_USER | SLAB_TRACE))
+ page->flags |= 1 << PG_error;
+
+ start = page_address(page);
+ end = start + s->objects * s->size;
+
+ if (unlikely(s->flags & SLAB_POISON))
+ memset(start, POISON_INUSE, PAGE_SIZE << s->order);
+
+ last = start;
+ for (p = start + s->size; p < end; p += s->size) {
+ setup_object(s, page, last);
+ set_freepointer(s, last, p);
+ last = p;
+ }
+ setup_object(s, page, last);
+ set_freepointer(s, last, NULL);
+
+ page->freelist = start;
+ page->inuse = 0;
+out:
+ if (flags & __GFP_WAIT)
+ local_irq_disable();
+ return page;
+}
+
+static void __free_slab(struct kmem_cache *s, struct page *page)
+{
+ int pages = 1 << s->order;
+
+ if (unlikely(PageError(page) || s->dtor)) {
+ void *start = page_address(page);
+ void *end = start + (pages << PAGE_SHIFT);
+ void *p;
+
+ slab_pad_check(s, page);
+ for (p = start; p <= end - s->size; p += s->size) {
+ if (s->dtor)
+ s->dtor(p, s, 0);
+ check_object(s, page, p, 0);
+ }
+ }
+
+ mod_zone_page_state(page_zone(page),
+ (s->flags & SLAB_RECLAIM_ACCOUNT) ?
+ NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
+ - pages);
+
+ page->mapping = NULL;
+ __free_pages(page, s->order);
+}
+
+static void rcu_free_slab(struct rcu_head *h)
+{
+ struct page *page;
+
+ page = container_of((struct list_head *)h, struct page, lru);
+ __free_slab(page->slab, page);
+}
+
+static void free_slab(struct kmem_cache *s, struct page *page)
+{
+ if (unlikely(s->flags & SLAB_DESTROY_BY_RCU)) {
+ /*
+ * RCU free overloads the RCU head over the LRU
+ */
+ struct rcu_head *head = (void *)&page->lru;
+
+ call_rcu(head, rcu_free_slab);
+ } else
+ __free_slab(s, page);
+}
+
+static void discard_slab(struct kmem_cache *s, struct page *page)
+{
+ struct kmem_cache_node *n = get_node(s, page_to_nid(page));
+
+ atomic_long_dec(&n->nr_slabs);
+ reset_page_mapcount(page);
+ page->flags &= ~(1 << PG_slab | 1 << PG_error);
+ free_slab(s, page);
+}
+
+/*
+ * Per slab locking using the pagelock
+ */
+static __always_inline void slab_lock(struct page *page)
+{
+ bit_spin_lock(PG_locked, &page->flags);
+}
+
+static __always_inline void slab_unlock(struct page *page)
+{
+ bit_spin_unlock(PG_locked, &page->flags);
+}
+
+static __always_inline int slab_trylock(struct page *page)
+{
+ int rc = 1;
+
+ rc = bit_spin_trylock(PG_locked, &page->flags);
+ return rc;
+}
+
+/*
+ * Management of partially allocated slabs
+ */
+static void add_partial_tail(struct kmem_cache_node *n, struct page *page)
+{
+ spin_lock(&n->list_lock);
+ n->nr_partial++;
+ list_add_tail(&page->lru, &n->partial);
+ spin_unlock(&n->list_lock);
+}
+
+static void add_partial(struct kmem_cache_node *n, struct page *page)
+{
+ spin_lock(&n->list_lock);
+ n->nr_partial++;
+ list_add(&page->lru, &n->partial);
+ spin_unlock(&n->list_lock);
+}
+
+static void remove_partial(struct kmem_cache *s,
+ struct page *page)
+{
+ struct kmem_cache_node *n = get_node(s, page_to_nid(page));
+
+ spin_lock(&n->list_lock);
+ list_del(&page->lru);
+ n->nr_partial--;
+ spin_unlock(&n->list_lock);
+}
+
+/*
+ * Lock page and remove it from the partial list
+ *
+ * Must hold list_lock
+ */
+static int lock_and_del_slab(struct kmem_cache_node *n, struct page *page)
+{
+ if (slab_trylock(page)) {
+ list_del(&page->lru);
+ n->nr_partial--;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Try to get a partial slab from a specific node
+ */
+static struct page *get_partial_node(struct kmem_cache_node *n)
+{
+ struct page *page;
+
+ /*
+ * Racy check. If we mistakenly see no partial slabs then we
+ * just allocate an empty slab. If we mistakenly try to get a
+ * partial slab then get_partials() will return NULL.
+ */
+ if (!n || !n->nr_partial)
+ return NULL;
+
+ spin_lock(&n->list_lock);
+ list_for_each_entry(page, &n->partial, lru)
+ if (lock_and_del_slab(n, page))
+ goto out;
+ page = NULL;
+out:
+ spin_unlock(&n->list_lock);
+ return page;
+}
+
+/*
+ * Get a page from somewhere. Search in increasing NUMA
+ * distances.
+ */
+static struct page *get_any_partial(struct kmem_cache *s, gfp_t flags)
+{
+#ifdef CONFIG_NUMA
+ struct zonelist *zonelist;
+ struct zone **z;
+ struct page *page;
+
+ /*
+ * The defrag ratio allows to configure the tradeoffs between
+ * inter node defragmentation and node local allocations.
+ * A lower defrag_ratio increases the tendency to do local
+ * allocations instead of scanning throught the partial
+ * lists on other nodes.
+ *
+ * If defrag_ratio is set to 0 then kmalloc() always
+ * returns node local objects. If its higher then kmalloc()
+ * may return off node objects in order to avoid fragmentation.
+ *
+ * A higher ratio means slabs may be taken from other nodes
+ * thus reducing the number of partial slabs on those nodes.
+ *
+ * If /sys/slab/xx/defrag_ratio is set to 100 (which makes
+ * defrag_ratio = 1000) then every (well almost) allocation
+ * will first attempt to defrag slab caches on other nodes. This
+ * means scanning over all nodes to look for partial slabs which
+ * may be a bit expensive to do on every slab allocation.
+ */
+ if (!s->defrag_ratio || get_cycles() % 1024 > s->defrag_ratio)
+ return NULL;
+
+ zonelist = &NODE_DATA(slab_node(current->mempolicy))
+ ->node_zonelists[gfp_zone(flags)];
+ for (z = zonelist->zones; *z; z++) {
+ struct kmem_cache_node *n;
+
+ n = get_node(s, zone_to_nid(*z));
+
+ if (n && cpuset_zone_allowed_hardwall(*z, flags) &&
+ n->nr_partial > MIN_PARTIAL) {
+ page = get_partial_node(n);
+ if (page)
+ return page;
+ }
+ }
+#endif
+ return NULL;
+}
+
+/*
+ * Get a partial page, lock it and return it.
+ */
+static struct page *get_partial(struct kmem_cache *s, gfp_t flags, int node)
+{
+ struct page *page;
+ int searchnode = (node == -1) ? numa_node_id() : node;
+
+ page = get_partial_node(get_node(s, searchnode));
+ if (page || (flags & __GFP_THISNODE))
+ return page;
+
+ return get_any_partial(s, flags);
+}
+
+/*
+ * Move a page back to the lists.
+ *
+ * Must be called with the slab lock held.
+ *
+ * On exit the slab lock will have been dropped.
+ */
+static void putback_slab(struct kmem_cache *s, struct page *page)
+{
+ struct kmem_cache_node *n = get_node(s, page_to_nid(page));
+
+ if (page->inuse) {
+
+ if (page->freelist)
+ add_partial(n, page);
+ else if (PageError(page) && (s->flags & SLAB_STORE_USER))
+ add_full(n, page);
+ slab_unlock(page);
+
+ } else {
+ if (n->nr_partial < MIN_PARTIAL) {
+ /*
+ * Adding an empty page to the partial slabs in order
+ * to avoid page allocator overhead. This page needs to
+ * come after all the others that are not fully empty
+ * in order to make sure that we do maximum
+ * defragmentation.
+ */
+ add_partial_tail(n, page);
+ slab_unlock(page);
+ } else {
+ slab_unlock(page);
+ discard_slab(s, page);
+ }
+ }
+}
+
+/*
+ * Remove the cpu slab
+ */
+static void deactivate_slab(struct kmem_cache *s, struct page *page, int cpu)
+{
+ s->cpu_slab[cpu] = NULL;
+ ClearPageActive(page);
+
+ putback_slab(s, page);
+}
+
+static void flush_slab(struct kmem_cache *s, struct page *page, int cpu)
+{
+ slab_lock(page);
+ deactivate_slab(s, page, cpu);
+}
+
+/*
+ * Flush cpu slab.
+ * Called from IPI handler with interrupts disabled.
+ */
+static void __flush_cpu_slab(struct kmem_cache *s, int cpu)
+{
+ struct page *page = s->cpu_slab[cpu];
+
+ if (likely(page))
+ flush_slab(s, page, cpu);
+}
+
+static void flush_cpu_slab(void *d)
+{
+ struct kmem_cache *s = d;
+ int cpu = smp_processor_id();
+
+ __flush_cpu_slab(s, cpu);
+}
+
+static void flush_all(struct kmem_cache *s)
+{
+#ifdef CONFIG_SMP
+ on_each_cpu(flush_cpu_slab, s, 1, 1);
+#else
+ unsigned long flags;
+
+ local_irq_save(flags);
+ flush_cpu_slab(s);
+ local_irq_restore(flags);
+#endif
+}
+
+/*
+ * slab_alloc is optimized to only modify two cachelines on the fast path
+ * (aside from the stack):
+ *
+ * 1. The page struct
+ * 2. The first cacheline of the object to be allocated.
+ *
+ * The only cache lines that are read (apart from code) is the
+ * per cpu array in the kmem_cache struct.
+ *
+ * Fastpath is not possible if we need to get a new slab or have
+ * debugging enabled (which means all slabs are marked with PageError)
+ */
+static void *slab_alloc(struct kmem_cache *s,
+ gfp_t gfpflags, int node, void *addr)
+{
+ struct page *page;
+ void **object;
+ unsigned long flags;
+ int cpu;
+
+ local_irq_save(flags);
+ cpu = smp_processor_id();
+ page = s->cpu_slab[cpu];
+ if (!page)
+ goto new_slab;
+
+ slab_lock(page);
+ if (unlikely(node != -1 && page_to_nid(page) != node))
+ goto another_slab;
+redo:
+ object = page->freelist;
+ if (unlikely(!object))
+ goto another_slab;
+ if (unlikely(PageError(page)))
+ goto debug;
+
+have_object:
+ page->inuse++;
+ page->freelist = object[page->offset];
+ slab_unlock(page);
+ local_irq_restore(flags);
+ return object;
+
+another_slab:
+ deactivate_slab(s, page, cpu);
+
+new_slab:
+ page = get_partial(s, gfpflags, node);
+ if (likely(page)) {
+have_slab:
+ s->cpu_slab[cpu] = page;
+ SetPageActive(page);
+ goto redo;
+ }
+
+ page = new_slab(s, gfpflags, node);
+ if (page) {
+ cpu = smp_processor_id();
+ if (s->cpu_slab[cpu]) {
+ /*
+ * Someone else populated the cpu_slab while we enabled
+ * interrupts, or we have got scheduled on another cpu.
+ * The page may not be on the requested node.
+ */
+ if (node == -1 ||
+ page_to_nid(s->cpu_slab[cpu]) == node) {
+ /*
+ * Current cpuslab is acceptable and we
+ * want the current one since its cache hot
+ */
+ discard_slab(s, page);
+ page = s->cpu_slab[cpu];
+ slab_lock(page);
+ goto redo;
+ }
+ /* Dump the current slab */
+ flush_slab(s, s->cpu_slab[cpu], cpu);
+ }
+ slab_lock(page);
+ goto have_slab;
+ }
+ local_irq_restore(flags);
+ return NULL;
+debug:
+ if (!alloc_object_checks(s, page, object))
+ goto another_slab;
+ if (s->flags & SLAB_STORE_USER)
+ set_track(s, object, TRACK_ALLOC, addr);
+ if (s->flags & SLAB_TRACE) {
+ printk(KERN_INFO "TRACE %s alloc 0x%p inuse=%d fp=0x%p\n",
+ s->name, object, page->inuse,
+ page->freelist);
+ dump_stack();
+ }
+ init_object(s, object, 1);
+ goto have_object;
+}
+
+void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags)
+{
+ return slab_alloc(s, gfpflags, -1, __builtin_return_address(0));
+}
+EXPORT_SYMBOL(kmem_cache_alloc);
+
+#ifdef CONFIG_NUMA
+void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node)
+{
+ return slab_alloc(s, gfpflags, node, __builtin_return_address(0));
+}
+EXPORT_SYMBOL(kmem_cache_alloc_node);
+#endif
+
+/*
+ * The fastpath only writes the cacheline of the page struct and the first
+ * cacheline of the object.
+ *
+ * No special cachelines need to be read
+ */
+static void slab_free(struct kmem_cache *s, struct page *page,
+ void *x, void *addr)
+{
+ void *prior;
+ void **object = (void *)x;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ slab_lock(page);
+
+ if (unlikely(PageError(page)))
+ goto debug;
+checks_ok:
+ prior = object[page->offset] = page->freelist;
+ page->freelist = object;
+ page->inuse--;
+
+ if (unlikely(PageActive(page)))
+ /*
+ * Cpu slabs are never on partial lists and are
+ * never freed.
+ */
+ goto out_unlock;
+
+ if (unlikely(!page->inuse))
+ goto slab_empty;
+
+ /*
+ * Objects left in the slab. If it
+ * was not on the partial list before
+ * then add it.
+ */
+ if (unlikely(!prior))
+ add_partial(get_node(s, page_to_nid(page)), page);
+
+out_unlock:
+ slab_unlock(page);
+ local_irq_restore(flags);
+ return;
+
+slab_empty:
+ if (prior)
+ /*
+ * Slab on the partial list.
+ */
+ remove_partial(s, page);
+
+ slab_unlock(page);
+ discard_slab(s, page);
+ local_irq_restore(flags);
+ return;
+
+debug:
+ if (!free_object_checks(s, page, x))
+ goto out_unlock;
+ if (!PageActive(page) && !page->freelist)
+ remove_full(s, page);
+ if (s->flags & SLAB_STORE_USER)
+ set_track(s, x, TRACK_FREE, addr);
+ if (s->flags & SLAB_TRACE) {
+ printk(KERN_INFO "TRACE %s free 0x%p inuse=%d fp=0x%p\n",
+ s->name, object, page->inuse,
+ page->freelist);
+ print_section("Object", (void *)object, s->objsize);
+ dump_stack();
+ }
+ init_object(s, object, 0);
+ goto checks_ok;
+}
+
+void kmem_cache_free(struct kmem_cache *s, void *x)
+{
+ struct page *page;
+
+ page = virt_to_head_page(x);
+
+ slab_free(s, page, x, __builtin_return_address(0));
+}
+EXPORT_SYMBOL(kmem_cache_free);
+
+/* Figure out on which slab object the object resides */
+static struct page *get_object_page(const void *x)
+{
+ struct page *page = virt_to_head_page(x);
+
+ if (!PageSlab(page))
+ return NULL;
+
+ return page;
+}
+
+/*
+ * kmem_cache_open produces objects aligned at "size" and the first object
+ * is placed at offset 0 in the slab (We have no metainformation on the
+ * slab, all slabs are in essence "off slab").
+ *
+ * In order to get the desired alignment one just needs to align the
+ * size.
+ *
+ * Notice that the allocation order determines the sizes of the per cpu
+ * caches. Each processor has always one slab available for allocations.
+ * Increasing the allocation order reduces the number of times that slabs
+ * must be moved on and off the partial lists and therefore may influence
+ * locking overhead.
+ *
+ * The offset is used to relocate the free list link in each object. It is
+ * therefore possible to move the free list link behind the object. This
+ * is necessary for RCU to work properly and also useful for debugging.
+ */
+
+/*
+ * Mininum / Maximum order of slab pages. This influences locking overhead
+ * and slab fragmentation. A higher order reduces the number of partial slabs
+ * and increases the number of allocations possible without having to
+ * take the list_lock.
+ */
+static int slub_min_order;
+static int slub_max_order = DEFAULT_MAX_ORDER;
+
+/*
+ * Minimum number of objects per slab. This is necessary in order to
+ * reduce locking overhead. Similar to the queue size in SLAB.
+ */
+static int slub_min_objects = DEFAULT_MIN_OBJECTS;
+
+/*
+ * Merge control. If this is set then no merging of slab caches will occur.
+ */
+static int slub_nomerge;
+
+/*
+ * Debug settings:
+ */
+static int slub_debug;
+
+static char *slub_debug_slabs;
+
+/*
+ * Calculate the order of allocation given an slab object size.
+ *
+ * The order of allocation has significant impact on other elements
+ * of the system. Generally order 0 allocations should be preferred
+ * since they do not cause fragmentation in the page allocator. Larger
+ * objects may have problems with order 0 because there may be too much
+ * space left unused in a slab. We go to a higher order if more than 1/8th
+ * of the slab would be wasted.
+ *
+ * In order to reach satisfactory performance we must ensure that
+ * a minimum number of objects is in one slab. Otherwise we may
+ * generate too much activity on the partial lists. This is less a
+ * concern for large slabs though. slub_max_order specifies the order
+ * where we begin to stop considering the number of objects in a slab.
+ *
+ * Higher order allocations also allow the placement of more objects
+ * in a slab and thereby reduce object handling overhead. If the user
+ * has requested a higher mininum order then we start with that one
+ * instead of zero.
+ */
+static int calculate_order(int size)
+{
+ int order;
+ int rem;
+
+ for (order = max(slub_min_order, fls(size - 1) - PAGE_SHIFT);
+ order < MAX_ORDER; order++) {
+ unsigned long slab_size = PAGE_SIZE << order;
+
+ if (slub_max_order > order &&
+ slab_size < slub_min_objects * size)
+ continue;
+
+ if (slab_size < size)
+ continue;
+
+ rem = slab_size % size;
+
+ if (rem <= (PAGE_SIZE << order) / 8)
+ break;
+
+ }
+ if (order >= MAX_ORDER)
+ return -E2BIG;
+ return order;
+}
+
+/*
+ * Function to figure out which alignment to use from the
+ * various ways of specifying it.
+ */
+static unsigned long calculate_alignment(unsigned long flags,
+ unsigned long align, unsigned long size)
+{
+ /*
+ * If the user wants hardware cache aligned objects then
+ * follow that suggestion if the object is sufficiently
+ * large.
+ *
+ * The hardware cache alignment cannot override the
+ * specified alignment though. If that is greater
+ * then use it.
+ */
+ if ((flags & SLAB_HWCACHE_ALIGN) &&
+ size > L1_CACHE_BYTES / 2)
+ return max_t(unsigned long, align, L1_CACHE_BYTES);
+
+ if (align < ARCH_SLAB_MINALIGN)
+ return ARCH_SLAB_MINALIGN;
+
+ return ALIGN(align, sizeof(void *));
+}
+
+static void init_kmem_cache_node(struct kmem_cache_node *n)
+{
+ n->nr_partial = 0;
+ atomic_long_set(&n->nr_slabs, 0);
+ spin_lock_init(&n->list_lock);
+ INIT_LIST_HEAD(&n->partial);
+ INIT_LIST_HEAD(&n->full);
+}
+
+#ifdef CONFIG_NUMA
+/*
+ * No kmalloc_node yet so do it by hand. We know that this is the first
+ * slab on the node for this slabcache. There are no concurrent accesses
+ * possible.
+ *
+ * Note that this function only works on the kmalloc_node_cache
+ * when allocating for the kmalloc_node_cache.
+ */
+static struct kmem_cache_node * __init early_kmem_cache_node_alloc(gfp_t gfpflags,
+ int node)
+{
+ struct page *page;
+ struct kmem_cache_node *n;
+
+ BUG_ON(kmalloc_caches->size < sizeof(struct kmem_cache_node));
+
+ page = new_slab(kmalloc_caches, gfpflags | GFP_THISNODE, node);
+ /* new_slab() disables interupts */
+ local_irq_enable();
+
+ BUG_ON(!page);
+ n = page->freelist;
+ BUG_ON(!n);
+ page->freelist = get_freepointer(kmalloc_caches, n);
+ page->inuse++;
+ kmalloc_caches->node[node] = n;
+ init_object(kmalloc_caches, n, 1);
+ init_kmem_cache_node(n);
+ atomic_long_inc(&n->nr_slabs);
+ add_partial(n, page);
+ return n;
+}
+
+static void free_kmem_cache_nodes(struct kmem_cache *s)
+{
+ int node;
+
+ for_each_online_node(node) {
+ struct kmem_cache_node *n = s->node[node];
+ if (n && n != &s->local_node)
+ kmem_cache_free(kmalloc_caches, n);
+ s->node[node] = NULL;
+ }
+}
+
+static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags)
+{
+ int node;
+ int local_node;
+
+ if (slab_state >= UP)
+ local_node = page_to_nid(virt_to_page(s));
+ else
+ local_node = 0;
+
+ for_each_online_node(node) {
+ struct kmem_cache_node *n;
+
+ if (local_node == node)
+ n = &s->local_node;
+ else {
+ if (slab_state == DOWN) {
+ n = early_kmem_cache_node_alloc(gfpflags,
+ node);
+ continue;
+ }
+ n = kmem_cache_alloc_node(kmalloc_caches,
+ gfpflags, node);
+
+ if (!n) {
+ free_kmem_cache_nodes(s);
+ return 0;
+ }
+
+ }
+ s->node[node] = n;
+ init_kmem_cache_node(n);
+ }
+ return 1;
+}
+#else
+static void free_kmem_cache_nodes(struct kmem_cache *s)
+{
+}
+
+static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags)
+{
+ init_kmem_cache_node(&s->local_node);
+ return 1;
+}
+#endif
+
+/*
+ * calculate_sizes() determines the order and the distribution of data within
+ * a slab object.
+ */
+static int calculate_sizes(struct kmem_cache *s)
+{
+ unsigned long flags = s->flags;
+ unsigned long size = s->objsize;
+ unsigned long align = s->align;
+
+ /*
+ * Determine if we can poison the object itself. If the user of
+ * the slab may touch the object after free or before allocation
+ * then we should never poison the object itself.
+ */
+ if ((flags & SLAB_POISON) && !(flags & SLAB_DESTROY_BY_RCU) &&
+ !s->ctor && !s->dtor)
+ s->flags |= __OBJECT_POISON;
+ else
+ s->flags &= ~__OBJECT_POISON;
+
+ /*
+ * Round up object size to the next word boundary. We can only
+ * place the free pointer at word boundaries and this determines
+ * the possible location of the free pointer.
+ */
+ size = ALIGN(size, sizeof(void *));
+
+ /*
+ * If we are redzoning then check if there is some space between the
+ * end of the object and the free pointer. If not then add an
+ * additional word, so that we can establish a redzone between
+ * the object and the freepointer to be able to check for overwrites.
+ */
+ if ((flags & SLAB_RED_ZONE) && size == s->objsize)
+ size += sizeof(void *);
+
+ /*
+ * With that we have determined how much of the slab is in actual
+ * use by the object. This is the potential offset to the free
+ * pointer.
+ */
+ s->inuse = size;
+
+ if (((flags & (SLAB_DESTROY_BY_RCU | SLAB_POISON)) ||
+ s->ctor || s->dtor)) {
+ /*
+ * Relocate free pointer after the object if it is not
+ * permitted to overwrite the first word of the object on
+ * kmem_cache_free.
+ *
+ * This is the case if we do RCU, have a constructor or
+ * destructor or are poisoning the objects.
+ */
+ s->offset = size;
+ size += sizeof(void *);
+ }
+
+ if (flags & SLAB_STORE_USER)
+ /*
+ * Need to store information about allocs and frees after
+ * the object.
+ */
+ size += 2 * sizeof(struct track);
+
+ if (flags & DEBUG_DEFAULT_FLAGS)
+ /*
+ * Add some empty padding so that we can catch
+ * overwrites from earlier objects rather than let
+ * tracking information or the free pointer be
+ * corrupted if an user writes before the start
+ * of the object.
+ */
+ size += sizeof(void *);
+ /*
+ * Determine the alignment based on various parameters that the
+ * user specified (this is unecessarily complex due to the attempt
+ * to be compatible with SLAB. Should be cleaned up some day).
+ */
+ align = calculate_alignment(flags, align, s->objsize);
+
+ /*
+ * SLUB stores one object immediately after another beginning from
+ * offset 0. In order to align the objects we have to simply size
+ * each object to conform to the alignment.
+ */
+ size = ALIGN(size, align);
+ s->size = size;
+
+ s->order = calculate_order(size);
+ if (s->order < 0)
+ return 0;
+
+ /*
+ * Determine the number of objects per slab
+ */
+ s->objects = (PAGE_SIZE << s->order) / size;
+
+ /*
+ * Verify that the number of objects is within permitted limits.
+ * The page->inuse field is only 16 bit wide! So we cannot have
+ * more than 64k objects per slab.
+ */
+ if (!s->objects || s->objects > 65535)
+ return 0;
+ return 1;
+
+}
+
+static int __init finish_bootstrap(void)
+{
+ struct list_head *h;
+ int err;
+
+ slab_state = SYSFS;
+
+ list_for_each(h, &slab_caches) {
+ struct kmem_cache *s =
+ container_of(h, struct kmem_cache, list);
+
+ err = sysfs_slab_add(s);
+ BUG_ON(err);
+ }
+ return 0;
+}
+
+static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags,
+ const char *name, size_t size,
+ size_t align, unsigned long flags,
+ void (*ctor)(void *, struct kmem_cache *, unsigned long),
+ void (*dtor)(void *, struct kmem_cache *, unsigned long))
+{
+ memset(s, 0, kmem_size);
+ s->name = name;
+ s->ctor = ctor;
+ s->dtor = dtor;
+ s->objsize = size;
+ s->flags = flags;
+ s->align = align;
+
+ /*
+ * The page->offset field is only 16 bit wide. This is an offset
+ * in units of words from the beginning of an object. If the slab
+ * size is bigger then we cannot move the free pointer behind the
+ * object anymore.
+ *
+ * On 32 bit platforms the limit is 256k. On 64bit platforms
+ * the limit is 512k.
+ *
+ * Debugging or ctor/dtors may create a need to move the free
+ * pointer. Fail if this happens.
+ */
+ if (s->size >= 65535 * sizeof(void *)) {
+ BUG_ON(flags & (SLAB_RED_ZONE | SLAB_POISON |
+ SLAB_STORE_USER | SLAB_DESTROY_BY_RCU));
+ BUG_ON(ctor || dtor);
+ }
+ else
+ /*
+ * Enable debugging if selected on the kernel commandline.
+ */
+ if (slub_debug && (!slub_debug_slabs ||
+ strncmp(slub_debug_slabs, name,
+ strlen(slub_debug_slabs)) == 0))
+ s->flags |= slub_debug;
+
+ if (!calculate_sizes(s))
+ goto error;
+
+ s->refcount = 1;
+#ifdef CONFIG_NUMA
+ s->defrag_ratio = 100;
+#endif
+
+ if (init_kmem_cache_nodes(s, gfpflags & ~SLUB_DMA))
+ return 1;
+error:
+ if (flags & SLAB_PANIC)
+ panic("Cannot create slab %s size=%lu realsize=%u "
+ "order=%u offset=%u flags=%lx\n",
+ s->name, (unsigned long)size, s->size, s->order,
+ s->offset, flags);
+ return 0;
+}
+EXPORT_SYMBOL(kmem_cache_open);
+
+/*
+ * Check if a given pointer is valid
+ */
+int kmem_ptr_validate(struct kmem_cache *s, const void *object)
+{
+ struct page * page;
+ void *addr;
+
+ page = get_object_page(object);
+
+ if (!page || s != page->slab)
+ /* No slab or wrong slab */
+ return 0;
+
+ addr = page_address(page);
+ if (object < addr || object >= addr + s->objects * s->size)
+ /* Out of bounds */
+ return 0;
+
+ if ((object - addr) % s->size)
+ /* Improperly aligned */
+ return 0;
+
+ /*
+ * We could also check if the object is on the slabs freelist.
+ * But this would be too expensive and it seems that the main
+ * purpose of kmem_ptr_valid is to check if the object belongs
+ * to a certain slab.
+ */
+ return 1;
+}
+EXPORT_SYMBOL(kmem_ptr_validate);
+
+/*
+ * Determine the size of a slab object
+ */
+unsigned int kmem_cache_size(struct kmem_cache *s)
+{
+ return s->objsize;
+}
+EXPORT_SYMBOL(kmem_cache_size);
+
+const char *kmem_cache_name(struct kmem_cache *s)
+{
+ return s->name;
+}
+EXPORT_SYMBOL(kmem_cache_name);
+
+/*
+ * Attempt to free all slabs on a node
+ */
+static int free_list(struct kmem_cache *s, struct kmem_cache_node *n,
+ struct list_head *list)
+{
+ int slabs_inuse = 0;
+ unsigned long flags;
+ struct page *page, *h;
+
+ spin_lock_irqsave(&n->list_lock, flags);
+ list_for_each_entry_safe(page, h, list, lru)
+ if (!page->inuse) {
+ list_del(&page->lru);
+ discard_slab(s, page);
+ } else
+ slabs_inuse++;
+ spin_unlock_irqrestore(&n->list_lock, flags);
+ return slabs_inuse;
+}
+
+/*
+ * Release all resources used by slab cache
+ */
+static int kmem_cache_close(struct kmem_cache *s)
+{
+ int node;
+
+ flush_all(s);
+
+ /* Attempt to free all objects */
+ for_each_online_node(node) {
+ struct kmem_cache_node *n = get_node(s, node);
+
+ n->nr_partial -= free_list(s, n, &n->partial);
+ if (atomic_long_read(&n->nr_slabs))
+ return 1;
+ }
+ free_kmem_cache_nodes(s);
+ return 0;
+}
+
+/*
+ * Close a cache and release the kmem_cache structure
+ * (must be used for caches created using kmem_cache_create)
+ */
+void kmem_cache_destroy(struct kmem_cache *s)
+{
+ down_write(&slub_lock);
+ s->refcount--;
+ if (!s->refcount) {
+ list_del(&s->list);
+ if (kmem_cache_close(s))
+ WARN_ON(1);
+ sysfs_slab_remove(s);
+ kfree(s);
+ }
+ up_write(&slub_lock);
+}
+EXPORT_SYMBOL(kmem_cache_destroy);
+
+/********************************************************************
+ * Kmalloc subsystem
+ *******************************************************************/
+
+struct kmem_cache kmalloc_caches[KMALLOC_SHIFT_HIGH + 1] __cacheline_aligned;
+EXPORT_SYMBOL(kmalloc_caches);
+
+#ifdef CONFIG_ZONE_DMA
+static struct kmem_cache *kmalloc_caches_dma[KMALLOC_SHIFT_HIGH + 1];
+#endif
+
+static int __init setup_slub_min_order(char *str)
+{
+ get_option (&str, &slub_min_order);
+
+ return 1;
+}
+
+__setup("slub_min_order=", setup_slub_min_order);
+
+static int __init setup_slub_max_order(char *str)
+{
+ get_option (&str, &slub_max_order);
+
+ return 1;
+}
+
+__setup("slub_max_order=", setup_slub_max_order);
+
+static int __init setup_slub_min_objects(char *str)
+{
+ get_option (&str, &slub_min_objects);
+
+ return 1;
+}
+
+__setup("slub_min_objects=", setup_slub_min_objects);
+
+static int __init setup_slub_nomerge(char *str)
+{
+ slub_nomerge = 1;
+ return 1;
+}
+
+__setup("slub_nomerge", setup_slub_nomerge);
+
+static int __init setup_slub_debug(char *str)
+{
+ if (!str || *str != '=')
+ slub_debug = DEBUG_DEFAULT_FLAGS;
+ else {
+ str++;
+ if (*str == 0 || *str == ',')
+ slub_debug = DEBUG_DEFAULT_FLAGS;
+ else
+ for( ;*str && *str != ','; str++)
+ switch (*str) {
+ case 'f' : case 'F' :
+ slub_debug |= SLAB_DEBUG_FREE;
+ break;
+ case 'z' : case 'Z' :
+ slub_debug |= SLAB_RED_ZONE;
+ break;
+ case 'p' : case 'P' :
+ slub_debug |= SLAB_POISON;
+ break;
+ case 'u' : case 'U' :
+ slub_debug |= SLAB_STORE_USER;
+ break;
+ case 't' : case 'T' :
+ slub_debug |= SLAB_TRACE;
+ break;
+ default:
+ printk(KERN_ERR "slub_debug option '%c' "
+ "unknown. skipped\n",*str);
+ }
+ }
+
+ if (*str == ',')
+ slub_debug_slabs = str + 1;
+ return 1;
+}
+
+__setup("slub_debug", setup_slub_debug);
+
+static struct kmem_cache *create_kmalloc_cache(struct kmem_cache *s,
+ const char *name, int size, gfp_t gfp_flags)
+{
+ unsigned int flags = 0;
+
+ if (gfp_flags & SLUB_DMA)
+ flags = SLAB_CACHE_DMA;
+
+ down_write(&slub_lock);
+ if (!kmem_cache_open(s, gfp_flags, name, size, ARCH_KMALLOC_MINALIGN,
+ flags, NULL, NULL))
+ goto panic;
+
+ list_add(&s->list, &slab_caches);
+ up_write(&slub_lock);
+ if (sysfs_slab_add(s))
+ goto panic;
+ return s;
+
+panic:
+ panic("Creation of kmalloc slab %s size=%d failed.\n", name, size);
+}
+
+static struct kmem_cache *get_slab(size_t size, gfp_t flags)
+{
+ int index = kmalloc_index(size);
+
+ if (!index)
+ return NULL;
+
+ /* Allocation too large? */
+ BUG_ON(index < 0);
+
+#ifdef CONFIG_ZONE_DMA
+ if ((flags & SLUB_DMA)) {
+ struct kmem_cache *s;
+ struct kmem_cache *x;
+ char *text;
+ size_t realsize;
+
+ s = kmalloc_caches_dma[index];
+ if (s)
+ return s;
+
+ /* Dynamically create dma cache */
+ x = kmalloc(kmem_size, flags & ~SLUB_DMA);
+ if (!x)
+ panic("Unable to allocate memory for dma cache\n");
+
+ if (index <= KMALLOC_SHIFT_HIGH)
+ realsize = 1 << index;
+ else {
+ if (index == 1)
+ realsize = 96;
+ else
+ realsize = 192;
+ }
+
+ text = kasprintf(flags & ~SLUB_DMA, "kmalloc_dma-%d",
+ (unsigned int)realsize);
+ s = create_kmalloc_cache(x, text, realsize, flags);
+ kmalloc_caches_dma[index] = s;
+ return s;
+ }
+#endif
+ return &kmalloc_caches[index];
+}
+
+void *__kmalloc(size_t size, gfp_t flags)
+{
+ struct kmem_cache *s = get_slab(size, flags);
+
+ if (s)
+ return slab_alloc(s, flags, -1, __builtin_return_address(0));
+ return NULL;
+}
+EXPORT_SYMBOL(__kmalloc);
+
+#ifdef CONFIG_NUMA
+void *__kmalloc_node(size_t size, gfp_t flags, int node)
+{
+ struct kmem_cache *s = get_slab(size, flags);
+
+ if (s)
+ return slab_alloc(s, flags, node, __builtin_return_address(0));
+ return NULL;
+}
+EXPORT_SYMBOL(__kmalloc_node);
+#endif
+
+size_t ksize(const void *object)
+{
+ struct page *page = get_object_page(object);
+ struct kmem_cache *s;
+
+ BUG_ON(!page);
+ s = page->slab;
+ BUG_ON(!s);
+
+ /*
+ * Debugging requires use of the padding between object
+ * and whatever may come after it.
+ */
+ if (s->flags & (SLAB_RED_ZONE | SLAB_POISON))
+ return s->objsize;
+
+ /*
+ * If we have the need to store the freelist pointer
+ * back there or track user information then we can
+ * only use the space before that information.
+ */
+ if (s->flags & (SLAB_DESTROY_BY_RCU | SLAB_STORE_USER))
+ return s->inuse;
+
+ /*
+ * Else we can use all the padding etc for the allocation
+ */
+ return s->size;
+}
+EXPORT_SYMBOL(ksize);
+
+void kfree(const void *x)
+{
+ struct kmem_cache *s;
+ struct page *page;
+
+ if (!x)
+ return;
+
+ page = virt_to_head_page(x);
+ s = page->slab;
+
+ slab_free(s, page, (void *)x, __builtin_return_address(0));
+}
+EXPORT_SYMBOL(kfree);
+
+/*
+ * kmem_cache_shrink removes empty slabs from the partial lists
+ * and then sorts the partially allocated slabs by the number
+ * of items in use. The slabs with the most items in use
+ * come first. New allocations will remove these from the
+ * partial list because they are full. The slabs with the
+ * least items are placed last. If it happens that the objects
+ * are freed then the page can be returned to the page allocator.
+ */
+int kmem_cache_shrink(struct kmem_cache *s)
+{
+ int node;
+ int i;
+ struct kmem_cache_node *n;
+ struct page *page;
+ struct page *t;
+ struct list_head *slabs_by_inuse =
+ kmalloc(sizeof(struct list_head) * s->objects, GFP_KERNEL);
+ unsigned long flags;
+
+ if (!slabs_by_inuse)
+ return -ENOMEM;
+
+ flush_all(s);
+ for_each_online_node(node) {
+ n = get_node(s, node);
+
+ if (!n->nr_partial)
+ continue;
+
+ for (i = 0; i < s->objects; i++)
+ INIT_LIST_HEAD(slabs_by_inuse + i);
+
+ spin_lock_irqsave(&n->list_lock, flags);
+
+ /*
+ * Build lists indexed by the items in use in
+ * each slab or free slabs if empty.
+ *
+ * Note that concurrent frees may occur while
+ * we hold the list_lock. page->inuse here is
+ * the upper limit.
+ */
+ list_for_each_entry_safe(page, t, &n->partial, lru) {
+ if (!page->inuse && slab_trylock(page)) {
+ /*
+ * Must hold slab lock here because slab_free
+ * may have freed the last object and be
+ * waiting to release the slab.
+ */
+ list_del(&page->lru);
+ n->nr_partial--;
+ slab_unlock(page);
+ discard_slab(s, page);
+ } else {
+ if (n->nr_partial > MAX_PARTIAL)
+ list_move(&page->lru,
+ slabs_by_inuse + page->inuse);
+ }
+ }
+
+ if (n->nr_partial <= MAX_PARTIAL)
+ goto out;
+
+ /*
+ * Rebuild the partial list with the slabs filled up
+ * most first and the least used slabs at the end.
+ */
+ for (i = s->objects - 1; i >= 0; i--)
+ list_splice(slabs_by_inuse + i, n->partial.prev);
+
+ out:
+ spin_unlock_irqrestore(&n->list_lock, flags);
+ }
+
+ kfree(slabs_by_inuse);
+ return 0;
+}
+EXPORT_SYMBOL(kmem_cache_shrink);
+
+/**
+ * krealloc - reallocate memory. The contents will remain unchanged.
+ *
+ * @p: object to reallocate memory for.
+ * @new_size: how many bytes of memory are required.
+ * @flags: the type of memory to allocate.
+ *
+ * The contents of the object pointed to are preserved up to the
+ * lesser of the new and old sizes. If @p is %NULL, krealloc()
+ * behaves exactly like kmalloc(). If @size is 0 and @p is not a
+ * %NULL pointer, the object pointed to is freed.
+ */
+void *krealloc(const void *p, size_t new_size, gfp_t flags)
+{
+ struct kmem_cache *new_cache;
+ void *ret;
+ struct page *page;
+
+ if (unlikely(!p))
+ return kmalloc(new_size, flags);
+
+ if (unlikely(!new_size)) {
+ kfree(p);
+ return NULL;
+ }
+
+ page = virt_to_head_page(p);
+
+ new_cache = get_slab(new_size, flags);
+
+ /*
+ * If new size fits in the current cache, bail out.
+ */
+ if (likely(page->slab == new_cache))
+ return (void *)p;
+
+ ret = kmalloc(new_size, flags);
+ if (ret) {
+ memcpy(ret, p, min(new_size, ksize(p)));
+ kfree(p);
+ }
+ return ret;
+}
+EXPORT_SYMBOL(krealloc);
+
+/********************************************************************
+ * Basic setup of slabs
+ *******************************************************************/
+
+void __init kmem_cache_init(void)
+{
+ int i;
+
+#ifdef CONFIG_NUMA
+ /*
+ * Must first have the slab cache available for the allocations of the
+ * struct kmalloc_cache_node's. There is special bootstrap code in
+ * kmem_cache_open for slab_state == DOWN.
+ */
+ create_kmalloc_cache(&kmalloc_caches[0], "kmem_cache_node",
+ sizeof(struct kmem_cache_node), GFP_KERNEL);
+#endif
+
+ /* Able to allocate the per node structures */
+ slab_state = PARTIAL;
+
+ /* Caches that are not of the two-to-the-power-of size */
+ create_kmalloc_cache(&kmalloc_caches[1],
+ "kmalloc-96", 96, GFP_KERNEL);
+ create_kmalloc_cache(&kmalloc_caches[2],
+ "kmalloc-192", 192, GFP_KERNEL);
+
+ for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++)
+ create_kmalloc_cache(&kmalloc_caches[i],
+ "kmalloc", 1 << i, GFP_KERNEL);
+
+ slab_state = UP;
+
+ /* Provide the correct kmalloc names now that the caches are up */
+ for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++)
+ kmalloc_caches[i]. name =
+ kasprintf(GFP_KERNEL, "kmalloc-%d", 1 << i);
+
+#ifdef CONFIG_SMP
+ register_cpu_notifier(&slab_notifier);
+#endif
+
+ if (nr_cpu_ids) /* Remove when nr_cpu_ids is fixed upstream ! */
+ kmem_size = offsetof(struct kmem_cache, cpu_slab)
+ + nr_cpu_ids * sizeof(struct page *);
+
+ printk(KERN_INFO "SLUB: Genslabs=%d, HWalign=%d, Order=%d-%d, MinObjects=%d,"
+ " Processors=%d, Nodes=%d\n",
+ KMALLOC_SHIFT_HIGH, L1_CACHE_BYTES,
+ slub_min_order, slub_max_order, slub_min_objects,
+ nr_cpu_ids, nr_node_ids);
+}
+
+/*
+ * Find a mergeable slab cache
+ */
+static int slab_unmergeable(struct kmem_cache *s)
+{
+ if (slub_nomerge || (s->flags & SLUB_NEVER_MERGE))
+ return 1;
+
+ if (s->ctor || s->dtor)
+ return 1;
+
+ return 0;
+}
+
+static struct kmem_cache *find_mergeable(size_t size,
+ size_t align, unsigned long flags,
+ void (*ctor)(void *, struct kmem_cache *, unsigned long),
+ void (*dtor)(void *, struct kmem_cache *, unsigned long))
+{
+ struct list_head *h;
+
+ if (slub_nomerge || (flags & SLUB_NEVER_MERGE))
+ return NULL;
+
+ if (ctor || dtor)
+ return NULL;
+
+ size = ALIGN(size, sizeof(void *));
+ align = calculate_alignment(flags, align, size);
+ size = ALIGN(size, align);
+
+ list_for_each(h, &slab_caches) {
+ struct kmem_cache *s =
+ container_of(h, struct kmem_cache, list);
+
+ if (slab_unmergeable(s))
+ continue;
+
+ if (size > s->size)
+ continue;
+
+ if (((flags | slub_debug) & SLUB_MERGE_SAME) !=
+ (s->flags & SLUB_MERGE_SAME))
+ continue;
+ /*
+ * Check if alignment is compatible.
+ * Courtesy of Adrian Drzewiecki
+ */
+ if ((s->size & ~(align -1)) != s->size)
+ continue;
+
+ if (s->size - size >= sizeof(void *))
+ continue;
+
+ return s;
+ }
+ return NULL;
+}
+
+struct kmem_cache *kmem_cache_create(const char *name, size_t size,
+ size_t align, unsigned long flags,
+ void (*ctor)(void *, struct kmem_cache *, unsigned long),
+ void (*dtor)(void *, struct kmem_cache *, unsigned long))
+{
+ struct kmem_cache *s;
+
+ down_write(&slub_lock);
+ s = find_mergeable(size, align, flags, dtor, ctor);
+ if (s) {
+ s->refcount++;
+ /*
+ * Adjust the object sizes so that we clear
+ * the complete object on kzalloc.
+ */
+ s->objsize = max(s->objsize, (int)size);
+ s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
+ if (sysfs_slab_alias(s, name))
+ goto err;
+ } else {
+ s = kmalloc(kmem_size, GFP_KERNEL);
+ if (s && kmem_cache_open(s, GFP_KERNEL, name,
+ size, align, flags, ctor, dtor)) {
+ if (sysfs_slab_add(s)) {
+ kfree(s);
+ goto err;
+ }
+ list_add(&s->list, &slab_caches);
+ } else
+ kfree(s);
+ }
+ up_write(&slub_lock);
+ return s;
+
+err:
+ up_write(&slub_lock);
+ if (flags & SLAB_PANIC)
+ panic("Cannot create slabcache %s\n", name);
+ else
+ s = NULL;
+ return s;
+}
+EXPORT_SYMBOL(kmem_cache_create);
+
+void *kmem_cache_zalloc(struct kmem_cache *s, gfp_t flags)
+{
+ void *x;
+
+ x = slab_alloc(s, flags, -1, __builtin_return_address(0));
+ if (x)
+ memset(x, 0, s->objsize);
+ return x;
+}
+EXPORT_SYMBOL(kmem_cache_zalloc);
+
+#ifdef CONFIG_SMP
+static void for_all_slabs(void (*func)(struct kmem_cache *, int), int cpu)
+{
+ struct list_head *h;
+
+ down_read(&slub_lock);
+ list_for_each(h, &slab_caches) {
+ struct kmem_cache *s =
+ container_of(h, struct kmem_cache, list);
+
+ func(s, cpu);
+ }
+ up_read(&slub_lock);
+}
+
+/*
+ * Use the cpu notifier to insure that the slab are flushed
+ * when necessary.
+ */
+static int __cpuinit slab_cpuup_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ long cpu = (long)hcpu;
+
+ switch (action) {
+ case CPU_UP_CANCELED:
+ case CPU_DEAD:
+ for_all_slabs(__flush_cpu_slab, cpu);
+ break;
+ default:
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata slab_notifier =
+ { &slab_cpuup_callback, NULL, 0 };
+
+#endif
+
+#ifdef CONFIG_NUMA
+
+/*****************************************************************
+ * Generic reaper used to support the page allocator
+ * (the cpu slabs are reaped by a per slab workqueue).
+ *
+ * Maybe move this to the page allocator?
+ ****************************************************************/
+
+static DEFINE_PER_CPU(unsigned long, reap_node);
+
+static void init_reap_node(int cpu)
+{
+ int node;
+
+ node = next_node(cpu_to_node(cpu), node_online_map);
+ if (node == MAX_NUMNODES)
+ node = first_node(node_online_map);
+
+ __get_cpu_var(reap_node) = node;
+}
+
+static void next_reap_node(void)
+{
+ int node = __get_cpu_var(reap_node);
+
+ /*
+ * Also drain per cpu pages on remote zones
+ */
+ if (node != numa_node_id())
+ drain_node_pages(node);
+
+ node = next_node(node, node_online_map);
+ if (unlikely(node >= MAX_NUMNODES))
+ node = first_node(node_online_map);
+ __get_cpu_var(reap_node) = node;
+}
+#else
+#define init_reap_node(cpu) do { } while (0)
+#define next_reap_node(void) do { } while (0)
+#endif
+
+#define REAPTIMEOUT_CPUC (2*HZ)
+
+#ifdef CONFIG_SMP
+static DEFINE_PER_CPU(struct delayed_work, reap_work);
+
+static void cache_reap(struct work_struct *unused)
+{
+ next_reap_node();
+ refresh_cpu_vm_stats(smp_processor_id());
+ schedule_delayed_work(&__get_cpu_var(reap_work),
+ REAPTIMEOUT_CPUC);
+}
+
+static void __devinit start_cpu_timer(int cpu)
+{
+ struct delayed_work *reap_work = &per_cpu(reap_work, cpu);
+
+ /*
+ * When this gets called from do_initcalls via cpucache_init(),
+ * init_workqueues() has already run, so keventd will be setup
+ * at that time.
+ */
+ if (keventd_up() && reap_work->work.func == NULL) {
+ init_reap_node(cpu);
+ INIT_DELAYED_WORK(reap_work, cache_reap);
+ schedule_delayed_work_on(cpu, reap_work, HZ + 3 * cpu);
+ }
+}
+
+static int __init cpucache_init(void)
+{
+ int cpu;
+
+ /*
+ * Register the timers that drain pcp pages and update vm statistics
+ */
+ for_each_online_cpu(cpu)
+ start_cpu_timer(cpu);
+ return 0;
+}
+__initcall(cpucache_init);
+#endif
+
+#ifdef SLUB_RESILIENCY_TEST
+static unsigned long validate_slab_cache(struct kmem_cache *s);
+
+static void resiliency_test(void)
+{
+ u8 *p;
+
+ printk(KERN_ERR "SLUB resiliency testing\n");
+ printk(KERN_ERR "-----------------------\n");
+ printk(KERN_ERR "A. Corruption after allocation\n");
+
+ p = kzalloc(16, GFP_KERNEL);
+ p[16] = 0x12;
+ printk(KERN_ERR "\n1. kmalloc-16: Clobber Redzone/next pointer"
+ " 0x12->0x%p\n\n", p + 16);
+
+ validate_slab_cache(kmalloc_caches + 4);
+
+ /* Hmmm... The next two are dangerous */
+ p = kzalloc(32, GFP_KERNEL);
+ p[32 + sizeof(void *)] = 0x34;
+ printk(KERN_ERR "\n2. kmalloc-32: Clobber next pointer/next slab"
+ " 0x34 -> -0x%p\n", p);
+ printk(KERN_ERR "If allocated object is overwritten then not detectable\n\n");
+
+ validate_slab_cache(kmalloc_caches + 5);
+ p = kzalloc(64, GFP_KERNEL);
+ p += 64 + (get_cycles() & 0xff) * sizeof(void *);
+ *p = 0x56;
+ printk(KERN_ERR "\n3. kmalloc-64: corrupting random byte 0x56->0x%p\n",
+ p);
+ printk(KERN_ERR "If allocated object is overwritten then not detectable\n\n");
+ validate_slab_cache(kmalloc_caches + 6);
+
+ printk(KERN_ERR "\nB. Corruption after free\n");
+ p = kzalloc(128, GFP_KERNEL);
+ kfree(p);
+ *p = 0x78;
+ printk(KERN_ERR "1. kmalloc-128: Clobber first word 0x78->0x%p\n\n", p);
+ validate_slab_cache(kmalloc_caches + 7);
+
+ p = kzalloc(256, GFP_KERNEL);
+ kfree(p);
+ p[50] = 0x9a;
+ printk(KERN_ERR "\n2. kmalloc-256: Clobber 50th byte 0x9a->0x%p\n\n", p);
+ validate_slab_cache(kmalloc_caches + 8);
+
+ p = kzalloc(512, GFP_KERNEL);
+ kfree(p);
+ p[512] = 0xab;
+ printk(KERN_ERR "\n3. kmalloc-512: Clobber redzone 0xab->0x%p\n\n", p);
+ validate_slab_cache(kmalloc_caches + 9);
+}
+#else
+static void resiliency_test(void) {};
+#endif
+
+/*
+ * These are not as efficient as kmalloc for the non debug case.
+ * We do not have the page struct available so we have to touch one
+ * cacheline in struct kmem_cache to check slab flags.
+ */
+void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, void *caller)
+{
+ struct kmem_cache *s = get_slab(size, gfpflags);
+
+ if (!s)
+ return NULL;
+
+ return slab_alloc(s, gfpflags, -1, caller);
+}
+
+void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
+ int node, void *caller)
+{
+ struct kmem_cache *s = get_slab(size, gfpflags);
+
+ if (!s)
+ return NULL;
+
+ return slab_alloc(s, gfpflags, node, caller);
+}
+
+#ifdef CONFIG_SYSFS
+
+static int validate_slab(struct kmem_cache *s, struct page *page)
+{
+ void *p;
+ void *addr = page_address(page);
+ unsigned long map[BITS_TO_LONGS(s->objects)];
+
+ if (!check_slab(s, page) ||
+ !on_freelist(s, page, NULL))
+ return 0;
+
+ /* Now we know that a valid freelist exists */
+ bitmap_zero(map, s->objects);
+
+ for(p = page->freelist; p; p = get_freepointer(s, p)) {
+ set_bit((p - addr) / s->size, map);
+ if (!check_object(s, page, p, 0))
+ return 0;
+ }
+
+ for(p = addr; p < addr + s->objects * s->size; p += s->size)
+ if (!test_bit((p - addr) / s->size, map))
+ if (!check_object(s, page, p, 1))
+ return 0;
+ return 1;
+}
+
+static void validate_slab_slab(struct kmem_cache *s, struct page *page)
+{
+ if (slab_trylock(page)) {
+ validate_slab(s, page);
+ slab_unlock(page);
+ } else
+ printk(KERN_INFO "SLUB %s: Skipped busy slab 0x%p\n",
+ s->name, page);
+
+ if (s->flags & DEBUG_DEFAULT_FLAGS) {
+ if (!PageError(page))
+ printk(KERN_ERR "SLUB %s: PageError not set "
+ "on slab 0x%p\n", s->name, page);
+ } else {
+ if (PageError(page))
+ printk(KERN_ERR "SLUB %s: PageError set on "
+ "slab 0x%p\n", s->name, page);
+ }
+}
+
+static int validate_slab_node(struct kmem_cache *s, struct kmem_cache_node *n)
+{
+ unsigned long count = 0;
+ struct page *page;
+ unsigned long flags;
+
+ spin_lock_irqsave(&n->list_lock, flags);
+
+ list_for_each_entry(page, &n->partial, lru) {
+ validate_slab_slab(s, page);
+ count++;
+ }
+ if (count != n->nr_partial)
+ printk(KERN_ERR "SLUB %s: %ld partial slabs counted but "
+ "counter=%ld\n", s->name, count, n->nr_partial);
+
+ if (!(s->flags & SLAB_STORE_USER))
+ goto out;
+
+ list_for_each_entry(page, &n->full, lru) {
+ validate_slab_slab(s, page);
+ count++;
+ }
+ if (count != atomic_long_read(&n->nr_slabs))
+ printk(KERN_ERR "SLUB: %s %ld slabs counted but "
+ "counter=%ld\n", s->name, count,
+ atomic_long_read(&n->nr_slabs));
+
+out:
+ spin_unlock_irqrestore(&n->list_lock, flags);
+ return count;
+}
+
+static unsigned long validate_slab_cache(struct kmem_cache *s)
+{
+ int node;
+ unsigned long count = 0;
+
+ flush_all(s);
+ for_each_online_node(node) {
+ struct kmem_cache_node *n = get_node(s, node);
+
+ count += validate_slab_node(s, n);
+ }
+ return count;
+}
+
+/*
+ * Generate lists of locations where slabcache objects are allocated
+ * and freed.
+ */
+
+struct location {
+ unsigned long count;
+ void *addr;
+};
+
+struct loc_track {
+ unsigned long max;
+ unsigned long count;
+ struct location *loc;
+};
+
+static void free_loc_track(struct loc_track *t)
+{
+ if (t->max)
+ free_pages((unsigned long)t->loc,
+ get_order(sizeof(struct location) * t->max));
+}
+
+static int alloc_loc_track(struct loc_track *t, unsigned long max)
+{
+ struct location *l;
+ int order;
+
+ if (!max)
+ max = PAGE_SIZE / sizeof(struct location);
+
+ order = get_order(sizeof(struct location) * max);
+
+ l = (void *)__get_free_pages(GFP_KERNEL, order);
+
+ if (!l)
+ return 0;
+
+ if (t->count) {
+ memcpy(l, t->loc, sizeof(struct location) * t->count);
+ free_loc_track(t);
+ }
+ t->max = max;
+ t->loc = l;
+ return 1;
+}
+
+static int add_location(struct loc_track *t, struct kmem_cache *s,
+ void *addr)
+{
+ long start, end, pos;
+ struct location *l;
+ void *caddr;
+
+ start = -1;
+ end = t->count;
+
+ for ( ; ; ) {
+ pos = start + (end - start + 1) / 2;
+
+ /*
+ * There is nothing at "end". If we end up there
+ * we need to add something to before end.
+ */
+ if (pos == end)
+ break;
+
+ caddr = t->loc[pos].addr;
+ if (addr == caddr) {
+ t->loc[pos].count++;
+ return 1;
+ }
+
+ if (addr < caddr)
+ end = pos;
+ else
+ start = pos;
+ }
+
+ /*
+ * Not found. Insert new tracking element
+ */
+ if (t->count >= t->max && !alloc_loc_track(t, 2 * t->max))
+ return 0;
+
+ l = t->loc + pos;
+ if (pos < t->count)
+ memmove(l + 1, l,
+ (t->count - pos) * sizeof(struct location));
+ t->count++;
+ l->count = 1;
+ l->addr = addr;
+ return 1;
+}
+
+static void process_slab(struct loc_track *t, struct kmem_cache *s,
+ struct page *page, enum track_item alloc)
+{
+ void *addr = page_address(page);
+ unsigned long map[BITS_TO_LONGS(s->objects)];
+ void *p;
+
+ bitmap_zero(map, s->objects);
+ for (p = page->freelist; p; p = get_freepointer(s, p))
+ set_bit((p - addr) / s->size, map);
+
+ for (p = addr; p < addr + s->objects * s->size; p += s->size)
+ if (!test_bit((p - addr) / s->size, map)) {
+ void *addr = get_track(s, p, alloc)->addr;
+
+ add_location(t, s, addr);
+ }
+}
+
+static int list_locations(struct kmem_cache *s, char *buf,
+ enum track_item alloc)
+{
+ int n = 0;
+ unsigned long i;
+ struct loc_track t;
+ int node;
+
+ t.count = 0;
+ t.max = 0;
+
+ /* Push back cpu slabs */
+ flush_all(s);
+
+ for_each_online_node(node) {
+ struct kmem_cache_node *n = get_node(s, node);
+ unsigned long flags;
+ struct page *page;
+
+ if (!atomic_read(&n->nr_slabs))
+ continue;
+
+ spin_lock_irqsave(&n->list_lock, flags);
+ list_for_each_entry(page, &n->partial, lru)
+ process_slab(&t, s, page, alloc);
+ list_for_each_entry(page, &n->full, lru)
+ process_slab(&t, s, page, alloc);
+ spin_unlock_irqrestore(&n->list_lock, flags);
+ }
+
+ for (i = 0; i < t.count; i++) {
+ void *addr = t.loc[i].addr;
+
+ if (n > PAGE_SIZE - 100)
+ break;
+ n += sprintf(buf + n, "%7ld ", t.loc[i].count);
+ if (addr)
+ n += sprint_symbol(buf + n, (unsigned long)t.loc[i].addr);
+ else
+ n += sprintf(buf + n, "<not-available>");
+ n += sprintf(buf + n, "\n");
+ }
+
+ free_loc_track(&t);
+ if (!t.count)
+ n += sprintf(buf, "No data\n");
+ return n;
+}
+
+static unsigned long count_partial(struct kmem_cache_node *n)
+{
+ unsigned long flags;
+ unsigned long x = 0;
+ struct page *page;
+
+ spin_lock_irqsave(&n->list_lock, flags);
+ list_for_each_entry(page, &n->partial, lru)
+ x += page->inuse;
+ spin_unlock_irqrestore(&n->list_lock, flags);
+ return x;
+}
+
+enum slab_stat_type {
+ SL_FULL,
+ SL_PARTIAL,
+ SL_CPU,
+ SL_OBJECTS
+};
+
+#define SO_FULL (1 << SL_FULL)
+#define SO_PARTIAL (1 << SL_PARTIAL)
+#define SO_CPU (1 << SL_CPU)
+#define SO_OBJECTS (1 << SL_OBJECTS)
+
+static unsigned long slab_objects(struct kmem_cache *s,
+ char *buf, unsigned long flags)
+{
+ unsigned long total = 0;
+ int cpu;
+ int node;
+ int x;
+ unsigned long *nodes;
+ unsigned long *per_cpu;
+
+ nodes = kzalloc(2 * sizeof(unsigned long) * nr_node_ids, GFP_KERNEL);
+ per_cpu = nodes + nr_node_ids;
+
+ for_each_possible_cpu(cpu) {
+ struct page *page = s->cpu_slab[cpu];
+ int node;
+
+ if (page) {
+ node = page_to_nid(page);
+ if (flags & SO_CPU) {
+ int x = 0;
+
+ if (flags & SO_OBJECTS)
+ x = page->inuse;
+ else
+ x = 1;
+ total += x;
+ nodes[node] += x;
+ }
+ per_cpu[node]++;
+ }
+ }
+
+ for_each_online_node(node) {
+ struct kmem_cache_node *n = get_node(s, node);
+
+ if (flags & SO_PARTIAL) {
+ if (flags & SO_OBJECTS)
+ x = count_partial(n);
+ else
+ x = n->nr_partial;
+ total += x;
+ nodes[node] += x;
+ }
+
+ if (flags & SO_FULL) {
+ int full_slabs = atomic_read(&n->nr_slabs)
+ - per_cpu[node]
+ - n->nr_partial;
+
+ if (flags & SO_OBJECTS)
+ x = full_slabs * s->objects;
+ else
+ x = full_slabs;
+ total += x;
+ nodes[node] += x;
+ }
+ }
+
+ x = sprintf(buf, "%lu", total);
+#ifdef CONFIG_NUMA
+ for_each_online_node(node)
+ if (nodes[node])
+ x += sprintf(buf + x, " N%d=%lu",
+ node, nodes[node]);
+#endif
+ kfree(nodes);
+ return x + sprintf(buf + x, "\n");
+}
+
+static int any_slab_objects(struct kmem_cache *s)
+{
+ int node;
+ int cpu;
+
+ for_each_possible_cpu(cpu)
+ if (s->cpu_slab[cpu])
+ return 1;
+
+ for_each_node(node) {
+ struct kmem_cache_node *n = get_node(s, node);
+
+ if (n->nr_partial || atomic_read(&n->nr_slabs))
+ return 1;
+ }
+ return 0;
+}
+
+#define to_slab_attr(n) container_of(n, struct slab_attribute, attr)
+#define to_slab(n) container_of(n, struct kmem_cache, kobj);
+
+struct slab_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct kmem_cache *s, char *buf);
+ ssize_t (*store)(struct kmem_cache *s, const char *x, size_t count);
+};
+
+#define SLAB_ATTR_RO(_name) \
+ static struct slab_attribute _name##_attr = __ATTR_RO(_name)
+
+#define SLAB_ATTR(_name) \
+ static struct slab_attribute _name##_attr = \
+ __ATTR(_name, 0644, _name##_show, _name##_store)
+
+static ssize_t slab_size_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", s->size);
+}
+SLAB_ATTR_RO(slab_size);
+
+static ssize_t align_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", s->align);
+}
+SLAB_ATTR_RO(align);
+
+static ssize_t object_size_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", s->objsize);
+}
+SLAB_ATTR_RO(object_size);
+
+static ssize_t objs_per_slab_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", s->objects);
+}
+SLAB_ATTR_RO(objs_per_slab);
+
+static ssize_t order_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", s->order);
+}
+SLAB_ATTR_RO(order);
+
+static ssize_t ctor_show(struct kmem_cache *s, char *buf)
+{
+ if (s->ctor) {
+ int n = sprint_symbol(buf, (unsigned long)s->ctor);
+
+ return n + sprintf(buf + n, "\n");
+ }
+ return 0;
+}
+SLAB_ATTR_RO(ctor);
+
+static ssize_t dtor_show(struct kmem_cache *s, char *buf)
+{
+ if (s->dtor) {
+ int n = sprint_symbol(buf, (unsigned long)s->dtor);
+
+ return n + sprintf(buf + n, "\n");
+ }
+ return 0;
+}
+SLAB_ATTR_RO(dtor);
+
+static ssize_t aliases_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", s->refcount - 1);
+}
+SLAB_ATTR_RO(aliases);
+
+static ssize_t slabs_show(struct kmem_cache *s, char *buf)
+{
+ return slab_objects(s, buf, SO_FULL|SO_PARTIAL|SO_CPU);
+}
+SLAB_ATTR_RO(slabs);
+
+static ssize_t partial_show(struct kmem_cache *s, char *buf)
+{
+ return slab_objects(s, buf, SO_PARTIAL);
+}
+SLAB_ATTR_RO(partial);
+
+static ssize_t cpu_slabs_show(struct kmem_cache *s, char *buf)
+{
+ return slab_objects(s, buf, SO_CPU);
+}
+SLAB_ATTR_RO(cpu_slabs);
+
+static ssize_t objects_show(struct kmem_cache *s, char *buf)
+{
+ return slab_objects(s, buf, SO_FULL|SO_PARTIAL|SO_CPU|SO_OBJECTS);
+}
+SLAB_ATTR_RO(objects);
+
+static ssize_t sanity_checks_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_DEBUG_FREE));
+}
+
+static ssize_t sanity_checks_store(struct kmem_cache *s,
+ const char *buf, size_t length)
+{
+ s->flags &= ~SLAB_DEBUG_FREE;
+ if (buf[0] == '1')
+ s->flags |= SLAB_DEBUG_FREE;
+ return length;
+}
+SLAB_ATTR(sanity_checks);
+
+static ssize_t trace_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_TRACE));
+}
+
+static ssize_t trace_store(struct kmem_cache *s, const char *buf,
+ size_t length)
+{
+ s->flags &= ~SLAB_TRACE;
+ if (buf[0] == '1')
+ s->flags |= SLAB_TRACE;
+ return length;
+}
+SLAB_ATTR(trace);
+
+static ssize_t reclaim_account_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_RECLAIM_ACCOUNT));
+}
+
+static ssize_t reclaim_account_store(struct kmem_cache *s,
+ const char *buf, size_t length)
+{
+ s->flags &= ~SLAB_RECLAIM_ACCOUNT;
+ if (buf[0] == '1')
+ s->flags |= SLAB_RECLAIM_ACCOUNT;
+ return length;
+}
+SLAB_ATTR(reclaim_account);
+
+static ssize_t hwcache_align_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_HWCACHE_ALIGN));
+}
+SLAB_ATTR_RO(hwcache_align);
+
+#ifdef CONFIG_ZONE_DMA
+static ssize_t cache_dma_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_CACHE_DMA));
+}
+SLAB_ATTR_RO(cache_dma);
+#endif
+
+static ssize_t destroy_by_rcu_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_DESTROY_BY_RCU));
+}
+SLAB_ATTR_RO(destroy_by_rcu);
+
+static ssize_t red_zone_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_RED_ZONE));
+}
+
+static ssize_t red_zone_store(struct kmem_cache *s,
+ const char *buf, size_t length)
+{
+ if (any_slab_objects(s))
+ return -EBUSY;
+
+ s->flags &= ~SLAB_RED_ZONE;
+ if (buf[0] == '1')
+ s->flags |= SLAB_RED_ZONE;
+ calculate_sizes(s);
+ return length;
+}
+SLAB_ATTR(red_zone);
+
+static ssize_t poison_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_POISON));
+}
+
+static ssize_t poison_store(struct kmem_cache *s,
+ const char *buf, size_t length)
+{
+ if (any_slab_objects(s))
+ return -EBUSY;
+
+ s->flags &= ~SLAB_POISON;
+ if (buf[0] == '1')
+ s->flags |= SLAB_POISON;
+ calculate_sizes(s);
+ return length;
+}
+SLAB_ATTR(poison);
+
+static ssize_t store_user_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", !!(s->flags & SLAB_STORE_USER));
+}
+
+static ssize_t store_user_store(struct kmem_cache *s,
+ const char *buf, size_t length)
+{
+ if (any_slab_objects(s))
+ return -EBUSY;
+
+ s->flags &= ~SLAB_STORE_USER;
+ if (buf[0] == '1')
+ s->flags |= SLAB_STORE_USER;
+ calculate_sizes(s);
+ return length;
+}
+SLAB_ATTR(store_user);
+
+static ssize_t validate_show(struct kmem_cache *s, char *buf)
+{
+ return 0;
+}
+
+static ssize_t validate_store(struct kmem_cache *s,
+ const char *buf, size_t length)
+{
+ if (buf[0] == '1')
+ validate_slab_cache(s);
+ else
+ return -EINVAL;
+ return length;
+}
+SLAB_ATTR(validate);
+
+static ssize_t shrink_show(struct kmem_cache *s, char *buf)
+{
+ return 0;
+}
+
+static ssize_t shrink_store(struct kmem_cache *s,
+ const char *buf, size_t length)
+{
+ if (buf[0] == '1') {
+ int rc = kmem_cache_shrink(s);
+
+ if (rc)
+ return rc;
+ } else
+ return -EINVAL;
+ return length;
+}
+SLAB_ATTR(shrink);
+
+static ssize_t alloc_calls_show(struct kmem_cache *s, char *buf)
+{
+ if (!(s->flags & SLAB_STORE_USER))
+ return -ENOSYS;
+ return list_locations(s, buf, TRACK_ALLOC);
+}
+SLAB_ATTR_RO(alloc_calls);
+
+static ssize_t free_calls_show(struct kmem_cache *s, char *buf)
+{
+ if (!(s->flags & SLAB_STORE_USER))
+ return -ENOSYS;
+ return list_locations(s, buf, TRACK_FREE);
+}
+SLAB_ATTR_RO(free_calls);
+
+#ifdef CONFIG_NUMA
+static ssize_t defrag_ratio_show(struct kmem_cache *s, char *buf)
+{
+ return sprintf(buf, "%d\n", s->defrag_ratio / 10);
+}
+
+static ssize_t defrag_ratio_store(struct kmem_cache *s,
+ const char *buf, size_t length)
+{
+ int n = simple_strtoul(buf, NULL, 10);
+
+ if (n < 100)
+ s->defrag_ratio = n * 10;
+ return length;
+}
+SLAB_ATTR(defrag_ratio);
+#endif
+
+static struct attribute * slab_attrs[] = {
+ &slab_size_attr.attr,
+ &object_size_attr.attr,
+ &objs_per_slab_attr.attr,
+ &order_attr.attr,
+ &objects_attr.attr,
+ &slabs_attr.attr,
+ &partial_attr.attr,
+ &cpu_slabs_attr.attr,
+ &ctor_attr.attr,
+ &dtor_attr.attr,
+ &aliases_attr.attr,
+ &align_attr.attr,
+ &sanity_checks_attr.attr,
+ &trace_attr.attr,
+ &hwcache_align_attr.attr,
+ &reclaim_account_attr.attr,
+ &destroy_by_rcu_attr.attr,
+ &red_zone_attr.attr,
+ &poison_attr.attr,
+ &store_user_attr.attr,
+ &validate_attr.attr,
+ &shrink_attr.attr,
+ &alloc_calls_attr.attr,
+ &free_calls_attr.attr,
+#ifdef CONFIG_ZONE_DMA
+ &cache_dma_attr.attr,
+#endif
+#ifdef CONFIG_NUMA
+ &defrag_ratio_attr.attr,
+#endif
+ NULL
+};
+
+static struct attribute_group slab_attr_group = {
+ .attrs = slab_attrs,
+};
+
+static ssize_t slab_attr_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf)
+{
+ struct slab_attribute *attribute;
+ struct kmem_cache *s;
+ int err;
+
+ attribute = to_slab_attr(attr);
+ s = to_slab(kobj);
+
+ if (!attribute->show)
+ return -EIO;
+
+ err = attribute->show(s, buf);
+
+ return err;
+}
+
+static ssize_t slab_attr_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buf, size_t len)
+{
+ struct slab_attribute *attribute;
+ struct kmem_cache *s;
+ int err;
+
+ attribute = to_slab_attr(attr);
+ s = to_slab(kobj);
+
+ if (!attribute->store)
+ return -EIO;
+
+ err = attribute->store(s, buf, len);
+
+ return err;
+}
+
+static struct sysfs_ops slab_sysfs_ops = {
+ .show = slab_attr_show,
+ .store = slab_attr_store,
+};
+
+static struct kobj_type slab_ktype = {
+ .sysfs_ops = &slab_sysfs_ops,
+};
+
+static int uevent_filter(struct kset *kset, struct kobject *kobj)
+{
+ struct kobj_type *ktype = get_ktype(kobj);
+
+ if (ktype == &slab_ktype)
+ return 1;
+ return 0;
+}
+
+static struct kset_uevent_ops slab_uevent_ops = {
+ .filter = uevent_filter,
+};
+
+decl_subsys(slab, &slab_ktype, &slab_uevent_ops);
+
+#define ID_STR_LENGTH 64
+
+/* Create a unique string id for a slab cache:
+ * format
+ * :[flags-]size:[memory address of kmemcache]
+ */
+static char *create_unique_id(struct kmem_cache *s)
+{
+ char *name = kmalloc(ID_STR_LENGTH, GFP_KERNEL);
+ char *p = name;
+
+ BUG_ON(!name);
+
+ *p++ = ':';
+ /*
+ * First flags affecting slabcache operations. We will only
+ * get here for aliasable slabs so we do not need to support
+ * too many flags. The flags here must cover all flags that
+ * are matched during merging to guarantee that the id is
+ * unique.
+ */
+ if (s->flags & SLAB_CACHE_DMA)
+ *p++ = 'd';
+ if (s->flags & SLAB_RECLAIM_ACCOUNT)
+ *p++ = 'a';
+ if (s->flags & SLAB_DEBUG_FREE)
+ *p++ = 'F';
+ if (p != name + 1)
+ *p++ = '-';
+ p += sprintf(p, "%07d", s->size);
+ BUG_ON(p > name + ID_STR_LENGTH - 1);
+ return name;
+}
+
+static int sysfs_slab_add(struct kmem_cache *s)
+{
+ int err;
+ const char *name;
+ int unmergeable;
+
+ if (slab_state < SYSFS)
+ /* Defer until later */
+ return 0;
+
+ unmergeable = slab_unmergeable(s);
+ if (unmergeable) {
+ /*
+ * Slabcache can never be merged so we can use the name proper.
+ * This is typically the case for debug situations. In that
+ * case we can catch duplicate names easily.
+ */
+ sysfs_remove_link(&slab_subsys.kobj, s->name);
+ name = s->name;
+ } else {
+ /*
+ * Create a unique name for the slab as a target
+ * for the symlinks.
+ */
+ name = create_unique_id(s);
+ }
+
+ kobj_set_kset_s(s, slab_subsys);
+ kobject_set_name(&s->kobj, name);
+ kobject_init(&s->kobj);
+ err = kobject_add(&s->kobj);
+ if (err)
+ return err;
+
+ err = sysfs_create_group(&s->kobj, &slab_attr_group);
+ if (err)
+ return err;
+ kobject_uevent(&s->kobj, KOBJ_ADD);
+ if (!unmergeable) {
+ /* Setup first alias */
+ sysfs_slab_alias(s, s->name);
+ kfree(name);
+ }
+ return 0;
+}
+
+static void sysfs_slab_remove(struct kmem_cache *s)
+{
+ kobject_uevent(&s->kobj, KOBJ_REMOVE);
+ kobject_del(&s->kobj);
+}
+
+/*
+ * Need to buffer aliases during bootup until sysfs becomes
+ * available lest we loose that information.
+ */
+struct saved_alias {
+ struct kmem_cache *s;
+ const char *name;
+ struct saved_alias *next;
+};
+
+struct saved_alias *alias_list;
+
+static int sysfs_slab_alias(struct kmem_cache *s, const char *name)
+{
+ struct saved_alias *al;
+
+ if (slab_state == SYSFS) {
+ /*
+ * If we have a leftover link then remove it.
+ */
+ sysfs_remove_link(&slab_subsys.kobj, name);
+ return sysfs_create_link(&slab_subsys.kobj,
+ &s->kobj, name);
+ }
+
+ al = kmalloc(sizeof(struct saved_alias), GFP_KERNEL);
+ if (!al)
+ return -ENOMEM;
+
+ al->s = s;
+ al->name = name;
+ al->next = alias_list;
+ alias_list = al;
+ return 0;
+}
+
+static int __init slab_sysfs_init(void)
+{
+ int err;
+
+ err = subsystem_register(&slab_subsys);
+ if (err) {
+ printk(KERN_ERR "Cannot register slab subsystem.\n");
+ return -ENOSYS;
+ }
+
+ finish_bootstrap();
+
+ while (alias_list) {
+ struct saved_alias *al = alias_list;
+
+ alias_list = alias_list->next;
+ err = sysfs_slab_alias(al->s, al->name);
+ BUG_ON(err);
+ kfree(al);
+ }
+
+ resiliency_test();
+ return 0;
+}
+
+__initcall(slab_sysfs_init);
+#else
+__initcall(finish_bootstrap);
+#endif
diff --git a/mm/sparse.c b/mm/sparse.c
index ac26eb0..6f3fff9 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -44,7 +44,7 @@ EXPORT_SYMBOL(page_to_nid);
#endif
#ifdef CONFIG_SPARSEMEM_EXTREME
-static struct mem_section *sparse_index_alloc(int nid)
+static struct mem_section noinline *sparse_index_alloc(int nid)
{
struct mem_section *section = NULL;
unsigned long array_size = SECTIONS_PER_ROOT *
@@ -61,7 +61,7 @@ static struct mem_section *sparse_index_alloc(int nid)
return section;
}
-static int sparse_index_init(unsigned long section_nr, int nid)
+static int __meminit sparse_index_init(unsigned long section_nr, int nid)
{
static DEFINE_SPINLOCK(index_init_lock);
unsigned long root = SECTION_NR_TO_ROOT(section_nr);
@@ -138,7 +138,7 @@ static inline int sparse_early_nid(struct mem_section *section)
}
/* Record a memory area against a node. */
-void memory_present(int nid, unsigned long start, unsigned long end)
+void __init memory_present(int nid, unsigned long start, unsigned long end)
{
unsigned long pfn;
@@ -197,7 +197,7 @@ struct page *sparse_decode_mem_map(unsigned long coded_mem_map, unsigned long pn
return ((struct page *)coded_mem_map) + section_nr_to_pfn(pnum);
}
-static int sparse_init_one_section(struct mem_section *ms,
+static int __meminit sparse_init_one_section(struct mem_section *ms,
unsigned long pnum, struct page *mem_map)
{
if (!valid_section(ms))
@@ -209,7 +209,7 @@ static int sparse_init_one_section(struct mem_section *ms,
return 1;
}
-static struct page *sparse_early_mem_map_alloc(unsigned long pnum)
+static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
{
struct page *map;
struct mem_section *ms = __nr_to_section(pnum);
@@ -272,7 +272,7 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
* Allocate the accumulated non-linear sections, allocate a mem_map
* for each and record the physical to section mapping.
*/
-void sparse_init(void)
+void __init sparse_init(void)
{
unsigned long pnum;
struct page *map;
@@ -288,6 +288,7 @@ void sparse_init(void)
}
}
+#ifdef CONFIG_MEMORY_HOTPLUG
/*
* returns the number of sections whose mem_maps were properly
* set. If this is <=0, then that means that the passed-in
@@ -327,3 +328,4 @@ out:
__kfree_section_memmap(memmap, nr_pages);
return ret;
}
+#endif
diff --git a/mm/swap.c b/mm/swap.c
index 2ed7be3..218c52a 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -55,7 +55,7 @@ static void fastcall __page_cache_release(struct page *page)
static void put_compound_page(struct page *page)
{
- page = (struct page *)page_private(page);
+ page = compound_head(page);
if (put_page_testzero(page)) {
compound_page_dtor *dtor;
diff --git a/mm/swapfile.c b/mm/swapfile.c
index a2d9bb4..acc172c 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1531,9 +1531,6 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
error = PTR_ERR(page);
goto bad_swap;
}
- wait_on_page_locked(page);
- if (!PageUptodate(page))
- goto bad_swap;
kmap(page);
swap_header = page_address(page);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index cb5aabd..faa2a52 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -755,3 +755,10 @@ out_einval_locked:
}
EXPORT_SYMBOL(remap_vmalloc_range);
+/*
+ * Implement a stub for vmalloc_sync_all() if the architecture chose not to
+ * have one.
+ */
+void __attribute__((weak)) vmalloc_sync_all(void)
+{
+}
diff --git a/mm/vmscan.c b/mm/vmscan.c
index db023e2..1c8e75a1 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -284,12 +284,8 @@ static void handle_write_error(struct address_space *mapping,
struct page *page, int error)
{
lock_page(page);
- if (page_mapping(page) == mapping) {
- if (error == -ENOSPC)
- set_bit(AS_ENOSPC, &mapping->flags);
- else
- set_bit(AS_EIO, &mapping->flags);
- }
+ if (page_mapping(page) == mapping)
+ mapping_set_error(mapping, error);
unlock_page(page);
}
@@ -1323,8 +1319,6 @@ static int kswapd(void *p)
for ( ; ; ) {
unsigned long new_order;
- try_to_freeze();
-
prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
new_order = pgdat->kswapd_max_order;
pgdat->kswapd_max_order = 0;
@@ -1335,12 +1329,19 @@ static int kswapd(void *p)
*/
order = new_order;
} else {
- schedule();
+ if (!freezing(current))
+ schedule();
+
order = pgdat->kswapd_max_order;
}
finish_wait(&pgdat->kswapd_wait, &wait);
- balance_pgdat(pgdat, order);
+ if (!try_to_freeze()) {
+ /* We can speed up thawing tasks if we don't call
+ * balance_pgdat after returning from the refrigerator
+ */
+ balance_pgdat(pgdat, order);
+ }
}
return 0;
}
diff --git a/net/Kconfig b/net/Kconfig
index 5b22278..caeacd1 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -225,6 +225,8 @@ source "net/ieee80211/Kconfig"
endmenu
+source "net/rfkill/Kconfig"
+
endif # if NET
endmenu # Networking
diff --git a/net/Makefile b/net/Makefile
index 9fdb60c..34e5b2d 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_IEEE80211) += ieee80211/
obj-$(CONFIG_TIPC) += tipc/
obj-$(CONFIG_NETLABEL) += netlabel/
obj-$(CONFIG_IUCV) += iucv/
+obj-$(CONFIG_RFKILL) += rfkill/
ifeq ($(CONFIG_NET),y)
obj-$(CONFIG_SYSCTL) += sysctl_net.o
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index f6a92a0..fbdfb12 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1844,7 +1844,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
.sendpage = sock_no_sendpage,
};
-#include <linux/smp_lock.h>
SOCKOPS_WRAP(atalk_dgram, PF_APPLETALK);
static struct notifier_block ddp_notifier = {
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 6ded952..429e13a 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -23,7 +23,6 @@
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>
-#include <linux/smp_lock.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <net/ax25.h>
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index ab2db55..1c8f4a0 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -37,7 +37,6 @@
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/errno.h>
-#include <linux/smp_lock.h>
#include <linux/net.h>
#include <net/sock.h>
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 832b5f4..bfc9a35 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -499,6 +499,15 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char
break;
case HCI_FILTER:
+ {
+ struct hci_filter *f = &hci_pi(sk)->filter;
+
+ uf.type_mask = f->type_mask;
+ uf.opcode = f->opcode;
+ uf.event_mask[0] = *((u32 *) f->event_mask + 0);
+ uf.event_mask[1] = *((u32 *) f->event_mask + 1);
+ }
+
len = min_t(unsigned int, len, sizeof(uf));
if (copy_from_user(&uf, optval, len)) {
err = -EFAULT;
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 801d687..2583540 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -305,7 +305,7 @@ int hci_register_sysfs(struct hci_dev *hdev)
BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
- dev->class = bt_class;
+ dev->bus = &bt_bus;
dev->parent = hdev->parent;
strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE);
@@ -322,6 +322,10 @@ int hci_register_sysfs(struct hci_dev *hdev)
if (device_create_file(dev, bt_attrs[i]) < 0)
BT_ERR("Failed to create device attribute");
+ if (sysfs_create_link(&bt_class->subsys.kobj,
+ &dev->kobj, kobject_name(&dev->kobj)) < 0)
+ BT_ERR("Failed to create class symlink");
+
return 0;
}
@@ -329,6 +333,9 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
{
BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
+ sysfs_remove_link(&bt_class->subsys.kobj,
+ kobject_name(&hdev->dev.kobj));
+
device_del(&hdev->dev);
}
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index a586787..a59b1fb 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -954,11 +954,17 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
switch (optname) {
case L2CAP_OPTIONS:
+ opts.imtu = l2cap_pi(sk)->imtu;
+ opts.omtu = l2cap_pi(sk)->omtu;
+ opts.flush_to = l2cap_pi(sk)->flush_to;
+ opts.mode = 0x00;
+
len = min_t(unsigned int, sizeof(opts), optlen);
if (copy_from_user((char *) &opts, optval, len)) {
err = -EFAULT;
break;
}
+
l2cap_pi(sk)->imtu = opts.imtu;
l2cap_pi(sk)->omtu = opts.omtu;
break;
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index fe7df90..52e04df 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -622,7 +622,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst
bacpy(&addr.l2_bdaddr, src);
addr.l2_family = AF_BLUETOOTH;
addr.l2_psm = 0;
- *err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));
+ *err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
if (*err < 0)
goto failed;
@@ -643,7 +643,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst
bacpy(&addr.l2_bdaddr, dst);
addr.l2_family = AF_BLUETOOTH;
addr.l2_psm = htobs(RFCOMM_PSM);
- *err = sock->ops->connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
+ *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
if (*err == 0 || *err == -EINPROGRESS)
return s;
@@ -1058,6 +1058,12 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
case BT_DISCONN:
d->state = BT_CLOSED;
__rfcomm_dlc_close(d, 0);
+
+ if (list_empty(&s->dlcs)) {
+ s->state = BT_DISCONN;
+ rfcomm_send_disc(s, 0);
+ }
+
break;
}
} else {
@@ -1067,6 +1073,10 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
s->state = BT_CONNECTED;
rfcomm_process_connect(s);
break;
+
+ case BT_DISCONN:
+ rfcomm_session_put(s);
+ break;
}
}
return 0;
@@ -1757,19 +1767,12 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s)
BT_DBG("session %p", s);
- if (sock_create_lite(PF_BLUETOOTH, sock->type, BTPROTO_L2CAP, &nsock))
+ err = kernel_accept(sock, &nsock, O_NONBLOCK);
+ if (err < 0)
return;
- nsock->ops = sock->ops;
-
__module_get(nsock->ops->owner);
- err = sock->ops->accept(sock, nsock, O_NONBLOCK);
- if (err < 0) {
- sock_release(nsock);
- return;
- }
-
/* Set our callbacks */
nsock->sk->sk_data_ready = rfcomm_l2data_ready;
nsock->sk->sk_state_change = rfcomm_l2state_change;
@@ -1885,7 +1888,7 @@ static int rfcomm_add_listener(bdaddr_t *ba)
bacpy(&addr.l2_bdaddr, ba);
addr.l2_family = AF_BLUETOOTH;
addr.l2_psm = htobs(RFCOMM_PSM);
- err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));
+ err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
if (err < 0) {
BT_ERR("Bind failed %d", err);
goto failed;
@@ -1898,7 +1901,7 @@ static int rfcomm_add_listener(bdaddr_t *ba)
release_sock(sk);
/* Start listening on the socket */
- err = sock->ops->listen(sock, 10);
+ err = kernel_listen(sock, 10);
if (err) {
BT_ERR("Listen failed %d", err);
goto failed;
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 9a7a44f..b2b1cce 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -517,9 +517,10 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
if (dlc->state == BT_CLOSED) {
if (!dev->tty) {
if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
- rfcomm_dev_hold(dev);
- rfcomm_dev_del(dev);
+ if (rfcomm_dev_get(dev->id) == NULL)
+ return;
+ rfcomm_dev_del(dev);
/* We have to drop DLC lock here, otherwise
rfcomm_dev_put() will dead lock if it's
the last reference. */
@@ -974,8 +975,12 @@ static void rfcomm_tty_hangup(struct tty_struct *tty)
rfcomm_tty_flush_buffer(tty);
- if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
+ if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
+ if (rfcomm_dev_get(dev->id) == NULL)
+ return;
rfcomm_dev_del(dev);
+ rfcomm_dev_put(dev);
+ }
}
static int rfcomm_tty_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *unused)
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index ebb0861..0e035d6 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -13,7 +13,6 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include "br_private.h"
#include "br_private_stp.h"
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 3e246b3..a786e78 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -14,7 +14,6 @@
*/
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/etherdevice.h>
#include <linux/rtnetlink.h>
diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c
index 030aa79..24e0ca4 100644
--- a/net/bridge/br_stp_timer.c
+++ b/net/bridge/br_stp_timer.c
@@ -15,7 +15,6 @@
#include <linux/kernel.h>
#include <linux/times.h>
-#include <linux/smp_lock.h>
#include "br_private.h"
#include "br_private_stp.h"
diff --git a/net/core/dev.c b/net/core/dev.c
index f27d4ab..4317c1b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2377,9 +2377,9 @@ static int __init dev_proc_init(void)
out:
return rc;
out_softnet:
- proc_net_remove("softnet_stat");
-out_dev2:
proc_net_remove("ptype");
+out_dev2:
+ proc_net_remove("softnet_stat");
out_dev:
proc_net_remove("dev");
goto out;
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index b316435..758dafe 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -9,7 +9,6 @@
* Copyright (C) 2002 Red Hat, Inc.
*/
-#include <linux/smp_lock.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/string.h>
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index b92a322..9cd3a1c 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -117,7 +117,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/slab.h>
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 16aae8e..041fba3 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -92,7 +92,6 @@
#include <asm/uaccess.h>
#include <asm/system.h>
-#include <linux/smp_lock.h>
#include <linux/inet.h>
#include <linux/igmp.h>
#include <linux/inetdevice.h>
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 8b124ea..bd4c295 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -252,7 +252,6 @@
#include <linux/fcntl.h>
#include <linux/poll.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/random.h>
#include <linux/bootmem.h>
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 0faacf9..53232dd 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -40,7 +40,6 @@
#include <linux/compiler.h>
#include <linux/module.h>
-#include <linux/smp_lock.h>
/* People can turn this off for buggy TCP's found in printers etc. */
int sysctl_tcp_retrans_collapse __read_mostly = 1;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 18cb928..6dd3772 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -42,7 +42,6 @@
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/icmpv6.h>
-#include <linux/smp_lock.h>
#include <linux/netfilter_ipv6.h>
#include <net/ip.h>
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index da07e9a..bbe99f8 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -198,7 +198,7 @@ config IP6_NF_RAW
and OUTPUT chains.
If you want to compile it as a module, say M here and read
- <file:Documentation/modules.txt>. If unsure, say `N'.
+ <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
endmenu
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index 392f8bc..15419dd 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -1961,7 +1961,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = {
.sendpage = sock_no_sendpage,
};
-#include <linux/smp_lock.h>
SOCKOPS_WRAP(ipx_dgram, PF_IPX);
static struct packet_type ipx_8023_packet_type = {
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 06c97c6..dcd7e32 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -2538,7 +2538,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
};
#endif /* CONFIG_IRDA_ULTRA */
-#include <linux/smp_lock.h>
SOCKOPS_WRAP(irda_stream, PF_IRDA);
SOCKOPS_WRAP(irda_seqpacket, PF_IRDA);
SOCKOPS_WRAP(irda_dgram, PF_IRDA);
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index c558f32..ea6211c 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -100,7 +100,7 @@ config NF_CT_PROTO_SCTP
tracking code will be able to do state tracking on SCTP connections.
If you want to compile it as a module, say M here and read
- Documentation/modules.txt. If unsure, say `N'.
+ <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
config NF_CONNTRACK_AMANDA
tristate "Amanda backup protocol support"
@@ -279,8 +279,8 @@ config NETFILTER_XT_TARGET_CONNMARK
affects the connection mark value rather than the packet mark value.
If you want to compile it as a module, say M here and read
- <file:Documentation/modules.txt>. The module will be called
- ipt_CONNMARK.o. If unsure, say `N'.
+ <file:Documentation/kbuild/modules.txt>. The module will be called
+ ipt_CONNMARK.ko. If unsure, say `N'.
config NETFILTER_XT_TARGET_DSCP
tristate '"DSCP" target support'
@@ -341,7 +341,7 @@ config NETFILTER_XT_TARGET_NOTRACK
no protocol helpers for the selected packets).
If you want to compile it as a module, say M here and read
- <file:Documentation/modules.txt>. If unsure, say `N'.
+ <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
config NETFILTER_XT_TARGET_SECMARK
tristate '"SECMARK" target support'
@@ -397,7 +397,7 @@ config NETFILTER_XT_MATCH_COMMENT
comments in your iptables ruleset.
If you want to compile it as a module, say M here and read
- <file:Documentation/modules.txt>. If unsure, say `N'.
+ <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
config NETFILTER_XT_MATCH_CONNBYTES
tristate '"connbytes" per-connection counter match support'
@@ -409,7 +409,7 @@ config NETFILTER_XT_MATCH_CONNBYTES
number of bytes and/or packets for each direction within a connection.
If you want to compile it as a module, say M here and read
- <file:Documentation/modules.txt>. If unsure, say `N'.
+ <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
config NETFILTER_XT_MATCH_CONNMARK
tristate '"connmark" connection mark match support'
@@ -421,8 +421,8 @@ config NETFILTER_XT_MATCH_CONNMARK
connection mark value previously set for the session by `CONNMARK'.
If you want to compile it as a module, say M here and read
- <file:Documentation/modules.txt>. The module will be called
- ipt_connmark.o. If unsure, say `N'.
+ <file:Documentation/kbuild/modules.txt>. The module will be called
+ ipt_connmark.ko. If unsure, say `N'.
config NETFILTER_XT_MATCH_CONNTRACK
tristate '"conntrack" connection tracking match support'
@@ -446,7 +446,7 @@ config NETFILTER_XT_MATCH_DCCP
and DCCP flags.
If you want to compile it as a module, say M here and read
- <file:Documentation/modules.txt>. If unsure, say `N'.
+ <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
config NETFILTER_XT_MATCH_DSCP
tristate '"DSCP" match support'
@@ -565,7 +565,7 @@ config NETFILTER_XT_MATCH_QUOTA
byte counter.
If you want to compile it as a module, say M here and read
- <file:Documentation/modules.txt>. If unsure, say `N'.
+ <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
config NETFILTER_XT_MATCH_REALM
tristate '"realm" match support'
@@ -579,7 +579,7 @@ config NETFILTER_XT_MATCH_REALM
in tc world.
If you want to compile it as a module, say M here and read
- <file:Documentation/modules.txt>. If unsure, say `N'.
+ <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
config NETFILTER_XT_MATCH_SCTP
tristate '"sctp" protocol match support (EXPERIMENTAL)'
@@ -590,7 +590,7 @@ config NETFILTER_XT_MATCH_SCTP
and SCTP chunk types.
If you want to compile it as a module, say M here and read
- <file:Documentation/modules.txt>. If unsure, say `N'.
+ <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
config NETFILTER_XT_MATCH_STATE
tristate '"state" match support'
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 507828d..1f15821 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -45,7 +45,6 @@
#include <linux/rtnetlink.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
#include <linux/notifier.h>
#include <linux/security.h>
#include <linux/jhash.h>
diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig
new file mode 100644
index 0000000..8b31759
--- /dev/null
+++ b/net/rfkill/Kconfig
@@ -0,0 +1,24 @@
+#
+# RF switch subsystem configuration
+#
+menuconfig RFKILL
+ tristate "RF switch subsystem support"
+ help
+ Say Y here if you want to have control over RF switches
+ found on many WiFi, Bluetooth and IRDA cards.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rfkill.
+
+config RFKILL_INPUT
+ tristate "Input layer to RF switch connector"
+ depends on RFKILL && INPUT
+ help
+ Say Y here if you want kernel automatically toggle state
+ of RF switches on and off when user presses appropriate
+ button or a key on the keyboard. Without this module you
+ need a some kind of userspace application to control
+ state of the switches.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rfkill-input.
diff --git a/net/rfkill/Makefile b/net/rfkill/Makefile
new file mode 100644
index 0000000..b38c430
--- /dev/null
+++ b/net/rfkill/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the RF switch subsystem.
+#
+
+obj-$(CONFIG_RFKILL) += rfkill.o
+obj-$(CONFIG_RFKILL_INPUT) += rfkill-input.o
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
new file mode 100644
index 0000000..e5c840c
--- /dev/null
+++ b/net/rfkill/rfkill-input.c
@@ -0,0 +1,174 @@
+/*
+ * Input layer to RF Kill interface connector
+ *
+ * Copyright (c) 2007 Dmitry Torokhov
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/init.h>
+#include <linux/rfkill.h>
+
+MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
+MODULE_DESCRIPTION("Input layer to RF switch connector");
+MODULE_LICENSE("GPL");
+
+struct rfkill_task {
+ struct work_struct work;
+ enum rfkill_type type;
+ struct mutex mutex; /* ensures that task is serialized */
+ spinlock_t lock; /* for accessing last and desired state */
+ unsigned long last; /* last schedule */
+ enum rfkill_state desired_state; /* on/off */
+ enum rfkill_state current_state; /* on/off */
+};
+
+static void rfkill_task_handler(struct work_struct *work)
+{
+ struct rfkill_task *task = container_of(work, struct rfkill_task, work);
+ enum rfkill_state state;
+
+ mutex_lock(&task->mutex);
+
+ /*
+ * Use temp variable to fetch desired state to keep it
+ * consistent even if rfkill_schedule_toggle() runs in
+ * another thread or interrupts us.
+ */
+ state = task->desired_state;
+
+ if (state != task->current_state) {
+ rfkill_switch_all(task->type, state);
+ task->current_state = state;
+ }
+
+ mutex_unlock(&task->mutex);
+}
+
+static void rfkill_schedule_toggle(struct rfkill_task *task)
+{
+ unsigned int flags;
+
+ spin_lock_irqsave(&task->lock, flags);
+
+ if (time_after(jiffies, task->last + msecs_to_jiffies(200))) {
+ task->desired_state = !task->desired_state;
+ task->last = jiffies;
+ schedule_work(&task->work);
+ }
+
+ spin_unlock_irqrestore(&task->lock, flags);
+}
+
+#define DEFINE_RFKILL_TASK(n, t) \
+ struct rfkill_task n = { \
+ .work = __WORK_INITIALIZER(n.work, \
+ rfkill_task_handler), \
+ .type = t, \
+ .mutex = __MUTEX_INITIALIZER(n.mutex), \
+ .lock = __SPIN_LOCK_UNLOCKED(n.lock), \
+ .desired_state = RFKILL_STATE_ON, \
+ .current_state = RFKILL_STATE_ON, \
+ }
+
+static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN);
+static DEFINE_RFKILL_TASK(rfkill_bt, RFKILL_TYPE_BLUETOOTH);
+
+static void rfkill_event(struct input_handle *handle, unsigned int type,
+ unsigned int code, int down)
+{
+ if (type == EV_KEY && down == 1) {
+ switch (code) {
+ case KEY_WLAN:
+ rfkill_schedule_toggle(&rfkill_wlan);
+ break;
+ case KEY_BLUETOOTH:
+ rfkill_schedule_toggle(&rfkill_bt);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
+ const struct input_device_id *id)
+{
+ struct input_handle *handle;
+ int error;
+
+ handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+ if (!handle)
+ return -ENOMEM;
+
+ handle->dev = dev;
+ handle->handler = handler;
+ handle->name = "rfkill";
+
+ error = input_register_handle(handle);
+ if (error)
+ goto err_free_handle;
+
+ error = input_open_device(handle);
+ if (error)
+ goto err_unregister_handle;
+
+ return 0;
+
+ err_unregister_handle:
+ input_unregister_handle(handle);
+ err_free_handle:
+ kfree(handle);
+ return error;
+}
+
+static void rfkill_disconnect(struct input_handle *handle)
+{
+ input_close_device(handle);
+ input_unregister_handle(handle);
+ kfree(handle);
+}
+
+static const struct input_device_id rfkill_ids[] = {
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+ .evbit = { BIT(EV_KEY) },
+ .keybit = { [LONG(KEY_WLAN)] = BIT(KEY_WLAN) },
+ },
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+ .evbit = { BIT(EV_KEY) },
+ .keybit = { [LONG(KEY_BLUETOOTH)] = BIT(KEY_BLUETOOTH) },
+ },
+ { }
+};
+
+static struct input_handler rfkill_handler = {
+ .event = rfkill_event,
+ .connect = rfkill_connect,
+ .disconnect = rfkill_disconnect,
+ .name = "rfkill",
+ .id_table = rfkill_ids,
+};
+
+static int __init rfkill_handler_init(void)
+{
+ return input_register_handler(&rfkill_handler);
+}
+
+static void __exit rfkill_handler_exit(void)
+{
+ input_unregister_handler(&rfkill_handler);
+ flush_scheduled_work();
+}
+
+module_init(rfkill_handler_init);
+module_exit(rfkill_handler_exit);
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
new file mode 100644
index 0000000..a973603
--- /dev/null
+++ b/net/rfkill/rfkill.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2006 Ivo van Doorn
+ * Copyright (C) 2007 Dmitry Torokhov
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/workqueue.h>
+#include <linux/capability.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/rfkill.h>
+
+MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");
+MODULE_VERSION("1.0");
+MODULE_DESCRIPTION("RF switch support");
+MODULE_LICENSE("GPL");
+
+static LIST_HEAD(rfkill_list); /* list of registered rf switches */
+static DEFINE_MUTEX(rfkill_mutex);
+
+static enum rfkill_state rfkill_states[RFKILL_TYPE_MAX];
+
+static int rfkill_toggle_radio(struct rfkill *rfkill,
+ enum rfkill_state state)
+{
+ int retval;
+
+ retval = mutex_lock_interruptible(&rfkill->mutex);
+ if (retval)
+ return retval;
+
+ if (state != rfkill->state) {
+ retval = rfkill->toggle_radio(rfkill->data, state);
+ if (!retval)
+ rfkill->state = state;
+ }
+
+ mutex_unlock(&rfkill->mutex);
+ return retval;
+}
+
+/**
+ * rfkill_switch_all - Toggle state of all switches of given type
+ * @type: type of interfaces to be affeceted
+ * @state: the new state
+ *
+ * This function toggles state of all switches of given type unless
+ * a specific switch is claimed by userspace in which case it is
+ * left alone.
+ */
+
+void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
+{
+ struct rfkill *rfkill;
+
+ mutex_lock(&rfkill_mutex);
+
+ rfkill_states[type] = state;
+
+ list_for_each_entry(rfkill, &rfkill_list, node) {
+ if (!rfkill->user_claim)
+ rfkill_toggle_radio(rfkill, state);
+ }
+
+ mutex_unlock(&rfkill_mutex);
+}
+EXPORT_SYMBOL(rfkill_switch_all);
+
+static ssize_t rfkill_name_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rfkill *rfkill = to_rfkill(dev);
+
+ return sprintf(buf, "%s\n", rfkill->name);
+}
+
+static ssize_t rfkill_type_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rfkill *rfkill = to_rfkill(dev);
+ const char *type;
+
+ switch (rfkill->type) {
+ case RFKILL_TYPE_WLAN:
+ type = "wlan";
+ break;
+ case RFKILL_TYPE_BLUETOOTH:
+ type = "bluetooth";
+ break;
+ case RFKILL_TYPE_IRDA:
+ type = "irda";
+ break;
+ default:
+ BUG();
+ }
+
+ return sprintf(buf, "%s\n", type);
+}
+
+static ssize_t rfkill_state_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rfkill *rfkill = to_rfkill(dev);
+
+ return sprintf(buf, "%d\n", rfkill->state);
+}
+
+static ssize_t rfkill_state_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct rfkill *rfkill = to_rfkill(dev);
+ unsigned int state = simple_strtoul(buf, NULL, 0);
+ int error;
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ error = rfkill_toggle_radio(rfkill,
+ state ? RFKILL_STATE_ON : RFKILL_STATE_OFF);
+ if (error)
+ return error;
+
+ return count;
+}
+
+static ssize_t rfkill_claim_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rfkill *rfkill = to_rfkill(dev);
+
+ return sprintf(buf, "%d", rfkill->user_claim);
+}
+
+static ssize_t rfkill_claim_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct rfkill *rfkill = to_rfkill(dev);
+ bool claim = !!simple_strtoul(buf, NULL, 0);
+ int error;
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ /*
+ * Take the global lock to make sure the kernel is not in
+ * the middle of rfkill_switch_all
+ */
+ error = mutex_lock_interruptible(&rfkill_mutex);
+ if (error)
+ return error;
+
+ if (rfkill->user_claim != claim) {
+ if (!claim)
+ rfkill_toggle_radio(rfkill,
+ rfkill_states[rfkill->type]);
+ rfkill->user_claim = claim;
+ }
+
+ mutex_unlock(&rfkill_mutex);
+
+ return count;
+}
+
+static struct device_attribute rfkill_dev_attrs[] = {
+ __ATTR(name, S_IRUGO, rfkill_name_show, NULL),
+ __ATTR(type, S_IRUGO, rfkill_type_show, NULL),
+ __ATTR(state, S_IRUGO, rfkill_state_show, rfkill_state_store),
+ __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store),
+ __ATTR_NULL
+};
+
+static void rfkill_release(struct device *dev)
+{
+ struct rfkill *rfkill = to_rfkill(dev);
+
+ kfree(rfkill);
+ module_put(THIS_MODULE);
+}
+
+#ifdef CONFIG_PM
+static int rfkill_suspend(struct device *dev, pm_message_t state)
+{
+ struct rfkill *rfkill = to_rfkill(dev);
+
+ if (dev->power.power_state.event != state.event) {
+ if (state.event == PM_EVENT_SUSPEND) {
+ mutex_lock(&rfkill->mutex);
+
+ if (rfkill->state == RFKILL_STATE_ON)
+ rfkill->toggle_radio(rfkill->data,
+ RFKILL_STATE_OFF);
+
+ mutex_unlock(&rfkill->mutex);
+ }
+
+ dev->power.power_state = state;
+ }
+
+ return 0;
+}
+
+static int rfkill_resume(struct device *dev)
+{
+ struct rfkill *rfkill = to_rfkill(dev);
+
+ if (dev->power.power_state.event != PM_EVENT_ON) {
+ mutex_lock(&rfkill->mutex);
+
+ if (rfkill->state == RFKILL_STATE_ON)
+ rfkill->toggle_radio(rfkill->data, RFKILL_STATE_ON);
+
+ mutex_unlock(&rfkill->mutex);
+ }
+
+ dev->power.power_state = PMSG_ON;
+ return 0;
+}
+#else
+#define rfkill_suspend NULL
+#define rfkill_resume NULL
+#endif
+
+static struct class rfkill_class = {
+ .name = "rfkill",
+ .dev_release = rfkill_release,
+ .dev_attrs = rfkill_dev_attrs,
+ .suspend = rfkill_suspend,
+ .resume = rfkill_resume,
+};
+
+static int rfkill_add_switch(struct rfkill *rfkill)
+{
+ int retval;
+
+ retval = mutex_lock_interruptible(&rfkill_mutex);
+ if (retval)
+ return retval;
+
+ retval = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]);
+ if (retval)
+ goto out;
+
+ list_add_tail(&rfkill->node, &rfkill_list);
+
+ out:
+ mutex_unlock(&rfkill_mutex);
+ return retval;
+}
+
+static void rfkill_remove_switch(struct rfkill *rfkill)
+{
+ mutex_lock(&rfkill_mutex);
+ list_del_init(&rfkill->node);
+ rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF);
+ mutex_unlock(&rfkill_mutex);
+}
+
+/**
+ * rfkill_allocate - allocate memory for rfkill structure.
+ * @parent: device that has rf switch on it
+ * @type: type of the switch (wlan, bluetooth, irda)
+ *
+ * This function should be called by the network driver when it needs
+ * rfkill structure. Once the structure is allocated the driver shoud
+ * finish its initialization by setting name, private data, enable_radio
+ * and disable_radio methods and then register it with rfkill_register().
+ * NOTE: If registration fails the structure shoudl be freed by calling
+ * rfkill_free() otherwise rfkill_unregister() should be used.
+ */
+struct rfkill *rfkill_allocate(struct device *parent, enum rfkill_type type)
+{
+ struct rfkill *rfkill;
+ struct device *dev;
+
+ rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL);
+ if (rfkill)
+ return NULL;
+
+ mutex_init(&rfkill->mutex);
+ INIT_LIST_HEAD(&rfkill->node);
+ rfkill->type = type;
+
+ dev = &rfkill->dev;
+ dev->class = &rfkill_class;
+ dev->parent = parent;
+ device_initialize(dev);
+
+ __module_get(THIS_MODULE);
+
+ return rfkill;
+}
+EXPORT_SYMBOL(rfkill_allocate);
+
+/**
+ * rfkill_free - Mark rfkill structure for deletion
+ * @rfkill: rfkill structure to be destroyed
+ *
+ * Decrements reference count of rfkill structure so it is destoryed.
+ * Note that rfkill_free() should _not_ be called after rfkill_unregister().
+ */
+void rfkill_free(struct rfkill *rfkill)
+{
+ if (rfkill)
+ put_device(&rfkill->dev);
+}
+EXPORT_SYMBOL(rfkill_free);
+
+/**
+ * rfkill_register - Register a rfkill structure.
+ * @rfkill: rfkill structure to be registered
+ *
+ * This function should be called by the network driver when the rfkill
+ * structure needs to be registered. Immediately from registration the
+ * switch driver should be able to service calls to toggle_radio.
+ */
+int rfkill_register(struct rfkill *rfkill)
+{
+ static atomic_t rfkill_no = ATOMIC_INIT(0);
+ struct device *dev = &rfkill->dev;
+ int error;
+
+ if (!rfkill->toggle_radio)
+ return -EINVAL;
+
+ error = rfkill_add_switch(rfkill);
+ if (error)
+ return error;
+
+ snprintf(dev->bus_id, sizeof(dev->bus_id),
+ "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1);
+
+ error = device_add(dev);
+ if (error) {
+ rfkill_remove_switch(rfkill);
+ return error;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(rfkill_register);
+
+/**
+ * rfkill_unregister - Uegister a rfkill structure.
+ * @rfkill: rfkill structure to be unregistered
+ *
+ * This function should be called by the network driver during device
+ * teardown to destroy rfkill structure. Note that rfkill_free() should
+ * _not_ be called after rfkill_unregister().
+ */
+void rfkill_unregister(struct rfkill *rfkill)
+{
+ device_del(&rfkill->dev);
+ rfkill_remove_switch(rfkill);
+ put_device(&rfkill->dev);
+}
+EXPORT_SYMBOL(rfkill_unregister);
+
+/*
+ * Rfkill module initialization/deinitialization.
+ */
+static int __init rfkill_init(void)
+{
+ int error;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(rfkill_states); i++)
+ rfkill_states[i] = RFKILL_STATE_ON;
+
+ error = class_register(&rfkill_class);
+ if (error) {
+ printk(KERN_ERR "rfkill: unable to register rfkill class\n");
+ return error;
+ }
+
+ return 0;
+}
+
+static void __exit rfkill_exit(void)
+{
+ class_unregister(&rfkill_class);
+}
+
+module_init(rfkill_init);
+module_exit(rfkill_exit);
diff --git a/net/socket.c b/net/socket.c
index 1ad62c0..98a8f67 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -261,8 +261,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
{
struct socket_alloc *ei = (struct socket_alloc *)foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR))
- == SLAB_CTOR_CONSTRUCTOR)
+ if (flags & SLAB_CTOR_CONSTRUCTOR)
inode_init_once(&ei->vfs_inode);
}
@@ -314,8 +313,19 @@ static int sockfs_delete_dentry(struct dentry *dentry)
dentry->d_flags |= DCACHE_UNHASHED;
return 0;
}
+
+/*
+ * sockfs_dname() is called from d_path().
+ */
+static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen)
+{
+ return dynamic_dname(dentry, buffer, buflen, "socket:[%lu]",
+ dentry->d_inode->i_ino);
+}
+
static struct dentry_operations sockfs_dentry_operations = {
.d_delete = sockfs_delete_dentry,
+ .d_dname = sockfs_dname,
};
/*
@@ -355,14 +365,9 @@ static int sock_alloc_fd(struct file **filep)
static int sock_attach_fd(struct socket *sock, struct file *file)
{
- struct qstr this;
- char name[32];
-
- this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
- this.name = name;
- this.hash = 0;
+ struct qstr name = { .name = "" };
- file->f_path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
+ file->f_path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
if (unlikely(!file->f_path.dentry))
return -ENOMEM;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 9b9ea50..ad39b47 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -828,8 +828,7 @@ init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
{
struct rpc_inode *rpci = (struct rpc_inode *) foo;
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
+ if (flags & SLAB_CTOR_CONSTRUCTOR) {
inode_init_once(&rpci->vfs_inode);
rpci->private = NULL;
rpci->nreaders = 0;
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 4a53e94..9901451 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -763,9 +763,9 @@ void *rpc_malloc(struct rpc_task *task, size_t size)
else
buf = kmalloc(size, gfp);
*buf = size;
- dprintk("RPC: %5u allocated buffer of size %u at %p\n",
+ dprintk("RPC: %5u allocated buffer of size %zu at %p\n",
task->tk_pid, size, buf);
- return (void *) ++buf;
+ return ++buf;
}
/**
@@ -775,14 +775,14 @@ void *rpc_malloc(struct rpc_task *task, size_t size)
*/
void rpc_free(void *buffer)
{
- size_t size, *buf = (size_t *) buffer;
+ size_t size, *buf = buffer;
if (!buffer)
return;
size = *buf;
buf--;
- dprintk("RPC: freeing buffer of size %u at %p\n",
+ dprintk("RPC: freeing buffer of size %zu at %p\n",
size, buf);
if (size <= RPC_BUFFER_MAXSIZE)
mempool_free(buf, rpc_buffer_mempool);
diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig
index 3891cc0..f9e367d 100644
--- a/net/tipc/Kconfig
+++ b/net/tipc/Kconfig
@@ -18,7 +18,7 @@ config TIPC
This protocol support is also available as a module ( = code which
can be inserted in and removed from the running kernel whenever you
want). The module will be called tipc. If you want to compile it
- as a module, say M here and read <file:Documentation/modules.txt>.
+ as a module, say M here and read <file:Documentation/kbuild/modules.txt>.
If in doubt, say N.
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index aec8cf1..fc12ba5 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -111,7 +111,6 @@
#include <net/scm.h>
#include <linux/init.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include <linux/rtnetlink.h>
#include <linux/mount.h>
#include <net/checksum.h>
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 0d6002fc..479927c 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1605,7 +1605,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
.sendpage = sock_no_sendpage,
};
-#include <linux/smp_lock.h>
SOCKOPS_WRAP(x25_proto, AF_X25);
static struct packet_type x25_packet_type = {
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index e2ad2dc..a525112 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -131,13 +131,13 @@ $(multi-objs-y:.o=.lst) : modname = $(modname-multi)
quiet_cmd_cc_s_c = CC $(quiet_modtag) $@
cmd_cc_s_c = $(CC) $(c_flags) -fverbose-asm -S -o $@ $<
-%.s: %.c FORCE
+$(obj)/%.s: $(src)/%.c FORCE
$(call if_changed_dep,cc_s_c)
quiet_cmd_cc_i_c = CPP $(quiet_modtag) $@
cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $<
-%.i: %.c FORCE
+$(obj)/%.i: $(src)/%.c FORCE
$(call if_changed_dep,cc_i_c)
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
@@ -146,7 +146,7 @@ cmd_cc_symtypes_c = \
| $(GENKSYMS) -T $@ >/dev/null; \
test -s $@ || rm -f $@
-%.symtypes : %.c FORCE
+$(obj)/%.symtypes : $(src)/%.c FORCE
$(call if_changed_dep,cc_symtypes_c)
# C (.c) files
@@ -198,14 +198,13 @@ define rule_cc_o_c
endef
# Built-in and composite module parts
-
-%.o: %.c FORCE
+$(obj)/%.o: $(src)/%.c FORCE
$(call cmd,force_checksrc)
$(call if_changed_rule,cc_o_c)
# Single-part modules are special since we need to mark them in $(MODVERDIR)
-$(single-used-m): %.o: %.c FORCE
+$(single-used-m): $(obj)/%.o: $(src)/%.c FORCE
$(call cmd,force_checksrc)
$(call if_changed_rule,cc_o_c)
@{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod)
@@ -215,7 +214,7 @@ quiet_cmd_cc_lst_c = MKLST $@
$(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \
System.map $(OBJDUMP) > $@
-%.lst: %.c FORCE
+$(obj)/%.lst: $(src)/%.c FORCE
$(call if_changed_dep,cc_lst_c)
# Compile assembler sources (.S)
@@ -229,13 +228,13 @@ $(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE)
quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
cmd_as_s_S = $(CPP) $(a_flags) -o $@ $<
-%.s: %.S FORCE
+$(obj)/%.s: $(src)/%.S FORCE
$(call if_changed_dep,as_s_S)
quiet_cmd_as_o_S = AS $(quiet_modtag) $@
cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
-%.o: %.S FORCE
+$(obj)/%.o: $(src)/%.S FORCE
$(call if_changed_dep,as_o_S)
targets += $(real-objs-y) $(real-objs-m) $(lib-y)
@@ -246,7 +245,7 @@ targets += $(extra-y) $(MAKECMDGOALS) $(always)
quiet_cmd_cpp_lds_S = LDS $@
cmd_cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ -o $@ $<
-%.lds: %.lds.S FORCE
+$(obj)/%.lds: $(src)/%.lds.S FORCE
$(call if_changed_dep,cpp_lds_S)
# Build the compiled-in targets
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index 575afbe..6943a7a 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -114,7 +114,7 @@ hostcxx_flags = -Wp,-MD,$(depfile) $(__hostcxx_flags)
quiet_cmd_host-csingle = HOSTCC $@
cmd_host-csingle = $(HOSTCC) $(hostc_flags) -o $@ $< \
$(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
-$(host-csingle): %: %.c FORCE
+$(host-csingle): $(obj)/%: $(src)/%.c FORCE
$(call if_changed_dep,host-csingle)
# Link an executable based on list of .o files, all plain c
@@ -123,14 +123,14 @@ quiet_cmd_host-cmulti = HOSTLD $@
cmd_host-cmulti = $(HOSTCC) $(HOSTLDFLAGS) -o $@ \
$(addprefix $(obj)/,$($(@F)-objs)) \
$(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
-$(host-cmulti): %: $(host-cobjs) $(host-cshlib) FORCE
+$(host-cmulti): $(obj)/%: $(host-cobjs) $(host-cshlib) FORCE
$(call if_changed,host-cmulti)
# Create .o file from a single .c file
# host-cobjs -> .o
quiet_cmd_host-cobjs = HOSTCC $@
cmd_host-cobjs = $(HOSTCC) $(hostc_flags) -c -o $@ $<
-$(host-cobjs): %.o: %.c FORCE
+$(host-cobjs): $(obj)/%.o: $(src)/%.c FORCE
$(call if_changed_dep,host-cobjs)
# Link an executable based on list of .o files, a mixture of .c and .cc
@@ -140,20 +140,20 @@ quiet_cmd_host-cxxmulti = HOSTLD $@
$(foreach o,objs cxxobjs,\
$(addprefix $(obj)/,$($(@F)-$(o)))) \
$(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
-$(host-cxxmulti): %: $(host-cobjs) $(host-cxxobjs) $(host-cshlib) FORCE
+$(host-cxxmulti): $(obj)/%: $(host-cobjs) $(host-cxxobjs) $(host-cshlib) FORCE
$(call if_changed,host-cxxmulti)
# Create .o file from a single .cc (C++) file
quiet_cmd_host-cxxobjs = HOSTCXX $@
cmd_host-cxxobjs = $(HOSTCXX) $(hostcxx_flags) -c -o $@ $<
-$(host-cxxobjs): %.o: %.cc FORCE
+$(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
$(call if_changed_dep,host-cxxobjs)
# Compile .c file, create position independent .o file
# host-cshobjs -> .o
quiet_cmd_host-cshobjs = HOSTCC -fPIC $@
cmd_host-cshobjs = $(HOSTCC) $(hostc_flags) -fPIC -c -o $@ $<
-$(host-cshobjs): %.o: %.c FORCE
+$(host-cshobjs): $(obj)/%.o: $(src)/%.c FORCE
$(call if_changed_dep,host-cshobjs)
# Link a shared library, based on position independent .o files
@@ -162,7 +162,7 @@ quiet_cmd_host-cshlib = HOSTLLD -shared $@
cmd_host-cshlib = $(HOSTCC) $(HOSTLDFLAGS) -shared -o $@ \
$(addprefix $(obj)/,$($(@F:.so=-objs))) \
$(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
-$(host-cshlib): %: $(host-cshobjs) FORCE
+$(host-cshlib): $(obj)/%: $(host-cshobjs) FORCE
$(call if_changed,host-cshlib)
targets += $(host-csingle) $(host-cmulti) $(host-cobjs)\
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 65e0a79..d5bbbcc 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -63,16 +63,16 @@ quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
$(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \
$(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \
$(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
- $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \
- $(wildcard vmlinux) $(filter-out FORCE,$^)
+ $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w)
PHONY += __modpost
__modpost: $(modules:.ko=.o) FORCE
- $(call cmd,modpost)
+ $(call cmd,modpost) $(wildcard vmlinux) $(filter-out FORCE,$^)
quiet_cmd_kernel-mod = MODPOST $@
- cmd_kernel-mod = $(cmd_modpost)
+ cmd_kernel-mod = $(cmd_modpost) $(KBUILD_VMLINUX_OBJS)
+PHONY += vmlinux
vmlinux: FORCE
$(call cmd,kernel-mod)
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index 6bc7e7c..8912c0f 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -249,6 +249,8 @@ void parse_config_file(char *map, size_t len)
found:
if (!memcmp(q - 7, "_MODULE", 7))
q -= 7;
+ if( (q-p-7) < 0 )
+ continue;
use_config(p+7, q-p-7);
}
}
diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh
new file mode 100755
index 0000000..f98171f
--- /dev/null
+++ b/scripts/checksyscalls.sh
@@ -0,0 +1,118 @@
+#!/bin/sh
+#
+# Check if current architecture are missing any function calls compared
+# to i386.
+# i386 define a number of legacy system calls that are i386 specific
+# and listed below so they are ignored.
+#
+# Usage:
+# syscallchk gcc gcc-options
+#
+
+ignore_list() {
+cat << EOF
+#include <asm/types.h>
+#include <asm/unistd.h>
+
+/* System calls for 32-bit kernels only */
+#if BITS_PER_LONG == 64
+#define __IGNORE_sendfile64
+#define __IGNORE_ftruncate64
+#define __IGNORE_truncate64
+#define __IGNORE_stat64
+#define __IGNORE_lstat64
+#define __IGNORE_fstat64
+#define __IGNORE_fcntl64
+#define __IGNORE_fadvise64_64
+#define __IGNORE_fstatat64
+#define __IGNORE_fstatfs64
+#define __IGNORE_statfs64
+#endif
+
+/* i386-specific or historical system calls */
+#define __IGNORE_break
+#define __IGNORE_stty
+#define __IGNORE_gtty
+#define __IGNORE_ftime
+#define __IGNORE_prof
+#define __IGNORE_lock
+#define __IGNORE_mpx
+#define __IGNORE_ulimit
+#define __IGNORE_profil
+#define __IGNORE_ioperm
+#define __IGNORE_iopl
+#define __IGNORE_idle
+#define __IGNORE_modify_ldt
+#define __IGNORE_ugetrlimit
+#define __IGNORE_mmap2
+#define __IGNORE_vm86
+#define __IGNORE_vm86old
+#define __IGNORE_set_thread_area
+#define __IGNORE_get_thread_area
+#define __IGNORE_madvise1
+#define __IGNORE_oldstat
+#define __IGNORE_oldfstat
+#define __IGNORE_oldlstat
+#define __IGNORE_oldolduname
+#define __IGNORE_olduname
+#define __IGNORE_umount2
+#define __IGNORE_umount
+#define __IGNORE_waitpid
+#define __IGNORE_stime
+#define __IGNORE_nice
+#define __IGNORE_signal
+#define __IGNORE_sigaction
+#define __IGNORE_sgetmask
+#define __IGNORE_sigsuspend
+#define __IGNORE_sigpending
+#define __IGNORE_ssetmask
+#define __IGNORE_readdir
+#define __IGNORE_socketcall
+#define __IGNORE_ipc
+#define __IGNORE_sigreturn
+#define __IGNORE_sigprocmask
+#define __IGNORE_bdflush
+#define __IGNORE__llseek
+#define __IGNORE__newselect
+#define __IGNORE_create_module
+#define __IGNORE_delete_module
+#define __IGNORE_query_module
+#define __IGNORE_get_kernel_syms
+/* ... including the "new" 32-bit uid syscalls */
+#define __IGNORE_lchown32
+#define __IGNORE_getuid32
+#define __IGNORE_getgid32
+#define __IGNORE_geteuid32
+#define __IGNORE_getegid32
+#define __IGNORE_setreuid32
+#define __IGNORE_setregid32
+#define __IGNORE_getgroups32
+#define __IGNORE_setgroups32
+#define __IGNORE_fchown32
+#define __IGNORE_setresuid32
+#define __IGNORE_getresuid32
+#define __IGNORE_setresgid32
+#define __IGNORE_getresgid32
+#define __IGNORE_chown32
+#define __IGNORE_setuid32
+#define __IGNORE_setgid32
+#define __IGNORE_setfsuid32
+#define __IGNORE_setfsgid32
+
+/* Unmerged syscalls for AFS, STREAMS, etc. */
+#define __IGNORE_afs_syscall
+#define __IGNORE_getpmsg
+#define __IGNORE_putpmsg
+#define __IGNORE_vserver
+EOF
+}
+
+syscall_list() {
+sed -n -e '/^\#define/ { s/[^_]*__NR_\([^[:space:]]*\).*/\
+\#if !defined \(__NR_\1\) \&\& !defined \(__IGNORE_\1\)\
+\#warning syscall \1 not implemented\
+\#endif/p }' $1
+}
+
+(ignore_list && syscall_list ${srctree}/include/asm-i386/unistd.h) | \
+$* -E -x c - > /dev/null
diff --git a/scripts/cleanfile b/scripts/cleanfile
new file mode 100755
index 0000000..f1ba8aa
--- /dev/null
+++ b/scripts/cleanfile
@@ -0,0 +1,126 @@
+#!/usr/bin/perl -w
+#
+# Clean a text file -- or directory of text files -- of stealth whitespace.
+# WARNING: this can be a highly destructive operation. Use with caution.
+#
+
+use bytes;
+use File::Basename;
+
+#
+# Clean up space-tab sequences, either by removing spaces or
+# replacing them with tabs.
+sub clean_space_tabs($)
+{
+ no bytes; # Tab alignment depends on characters
+
+ my($li) = @_;
+ my($lo) = '';
+ my $pos = 0;
+ my $nsp = 0;
+ my($i, $c);
+
+ for ($i = 0; $i < length($li); $i++) {
+ $c = substr($li, $i, 1);
+ if ($c eq "\t") {
+ my $npos = ($pos+$nsp+8) & ~7;
+ my $ntab = ($npos >> 3) - ($pos >> 3);
+ $lo .= "\t" x $ntab;
+ $pos = $npos;
+ $nsp = 0;
+ } elsif ($c eq "\n" || $c eq "\r") {
+ $lo .= " " x $nsp;
+ $pos += $nsp;
+ $nsp = 0;
+ $lo .= $c;
+ $pos = 0;
+ } elsif ($c eq " ") {
+ $nsp++;
+ } else {
+ $lo .= " " x $nsp;
+ $pos += $nsp;
+ $nsp = 0;
+ $lo .= $c;
+ $pos++;
+ }
+ }
+ $lo .= " " x $nsp;
+ return $lo;
+}
+
+$name = basename($0);
+
+foreach $f ( @ARGV ) {
+ print STDERR "$name: $f\n";
+
+ if (! -f $f) {
+ print STDERR "$f: not a file\n";
+ next;
+ }
+
+ if (!open(FILE, '+<', $f)) {
+ print STDERR "$name: Cannot open file: $f: $!\n";
+ next;
+ }
+
+ binmode FILE;
+
+ # First, verify that it is not a binary file; consider any file
+ # with a zero byte to be a binary file. Is there any better, or
+ # additional, heuristic that should be applied?
+ $is_binary = 0;
+
+ while (read(FILE, $data, 65536) > 0) {
+ if ($data =~ /\0/) {
+ $is_binary = 1;
+ last;
+ }
+ }
+
+ if ($is_binary) {
+ print STDERR "$name: $f: binary file\n";
+ next;
+ }
+
+ seek(FILE, 0, 0);
+
+ $in_bytes = 0;
+ $out_bytes = 0;
+ $blank_bytes = 0;
+
+ @blanks = ();
+ @lines = ();
+
+ while ( defined($line = <FILE>) ) {
+ $in_bytes += length($line);
+ $line =~ s/[ \t\r]*$//; # Remove trailing spaces
+ $line = clean_space_tabs($line);
+
+ if ( $line eq "\n" ) {
+ push(@blanks, $line);
+ $blank_bytes += length($line);
+ } else {
+ push(@lines, @blanks);
+ $out_bytes += $blank_bytes;
+ push(@lines, $line);
+ $out_bytes += length($line);
+ @blanks = ();
+ $blank_bytes = 0;
+ }
+ }
+
+ # Any blanks at the end of the file are discarded
+
+ if ($in_bytes != $out_bytes) {
+ # Only write to the file if changed
+ seek(FILE, 0, 0);
+ print FILE @lines;
+
+ if ( !defined($where = tell(FILE)) ||
+ !truncate(FILE, $where) ) {
+ die "$name: Failed to truncate modified file: $f: $!\n";
+ }
+ }
+
+ close(FILE);
+}
diff --git a/scripts/cleanpatch b/scripts/cleanpatch
new file mode 100755
index 0000000..a53f987
--- /dev/null
+++ b/scripts/cleanpatch
@@ -0,0 +1,206 @@
+#!/usr/bin/perl -w
+#
+# Clean a patch file -- or directory of patch files -- of stealth whitespace.
+# WARNING: this can be a highly destructive operation. Use with caution.
+#
+
+use bytes;
+use File::Basename;
+
+#
+# Clean up space-tab sequences, either by removing spaces or
+# replacing them with tabs.
+sub clean_space_tabs($)
+{
+ no bytes; # Tab alignment depends on characters
+
+ my($li) = @_;
+ my($lo) = '';
+ my $pos = 0;
+ my $nsp = 0;
+ my($i, $c);
+
+ for ($i = 0; $i < length($li); $i++) {
+ $c = substr($li, $i, 1);
+ if ($c eq "\t") {
+ my $npos = ($pos+$nsp+8) & ~7;
+ my $ntab = ($npos >> 3) - ($pos >> 3);
+ $lo .= "\t" x $ntab;
+ $pos = $npos;
+ $nsp = 0;
+ } elsif ($c eq "\n" || $c eq "\r") {
+ $lo .= " " x $nsp;
+ $pos += $nsp;
+ $nsp = 0;
+ $lo .= $c;
+ $pos = 0;
+ } elsif ($c eq " ") {
+ $nsp++;
+ } else {
+ $lo .= " " x $nsp;
+ $pos += $nsp;
+ $nsp = 0;
+ $lo .= $c;
+ $pos++;
+ }
+ }
+ $lo .= " " x $nsp;
+ return $lo;
+}
+
+$name = basename($0);
+
+foreach $f ( @ARGV ) {
+ print STDERR "$name: $f\n";
+
+ if (! -f $f) {
+ print STDERR "$f: not a file\n";
+ next;
+ }
+
+ if (!open(FILE, '+<', $f)) {
+ print STDERR "$name: Cannot open file: $f: $!\n";
+ next;
+ }
+
+ binmode FILE;
+
+ # First, verify that it is not a binary file; consider any file
+ # with a zero byte to be a binary file. Is there any better, or
+ # additional, heuristic that should be applied?
+ $is_binary = 0;
+
+ while (read(FILE, $data, 65536) > 0) {
+ if ($data =~ /\0/) {
+ $is_binary = 1;
+ last;
+ }
+ }
+
+ if ($is_binary) {
+ print STDERR "$name: $f: binary file\n";
+ next;
+ }
+
+ seek(FILE, 0, 0);
+
+ $in_bytes = 0;
+ $out_bytes = 0;
+
+ @lines = ();
+
+ $in_hunk = 0;
+ $err = 0;
+
+ while ( defined($line = <FILE>) ) {
+ $in_bytes += length($line);
+
+ if (!$in_hunk) {
+ if ($line =~ /^\@\@\s+\-([0-9]+),([0-9]+)\s+\+([0-9]+),([0-9]+)\s\@\@/) {
+ $minus_lines = $2;
+ $plus_lines = $4;
+ if ($minus_lines || $plus_lines) {
+ $in_hunk = 1;
+ @hunk_lines = ($line);
+ }
+ } else {
+ push(@lines, $line);
+ $out_bytes += length($line);
+ }
+ } else {
+ # We're in a hunk
+
+ if ($line =~ /^\+/) {
+ $plus_lines--;
+
+ $text = substr($line, 1);
+ $text =~ s/[ \t\r]*$//; # Remove trailing spaces
+ $text = clean_space_tabs($text);
+
+ push(@hunk_lines, '+'.$text);
+ } elsif ($line =~ /^\-/) {
+ $minus_lines--;
+ push(@hunk_lines, $line);
+ } elsif ($line =~ /^ /) {
+ $plus_lines--;
+ $minus_lines--;
+ push(@hunk_lines, $line);
+ } else {
+ print STDERR "$name: $f: malformed patch\n";
+ $err = 1;
+ last;
+ }
+
+ if ($plus_lines < 0 || $minus_lines < 0) {
+ print STDERR "$name: $f: malformed patch\n";
+ $err = 1;
+ last;
+ } elsif ($plus_lines == 0 && $minus_lines == 0) {
+ # End of a hunk. Process this hunk.
+ my $i;
+ my $l;
+ my @h = ();
+ my $adj = 0;
+ my $done = 0;
+
+ for ($i = scalar(@hunk_lines)-1; $i > 0; $i--) {
+ $l = $hunk_lines[$i];
+ if (!$done && $l eq "+\n") {
+ $adj++; # Skip this line
+ } elsif ($l =~ /^[ +]/) {
+ $done = 1;
+ unshift(@h, $l);
+ } else {
+ unshift(@h, $l);
+ }
+ }
+
+ $l = $hunk_lines[0]; # Hunk header
+ undef @hunk_lines; # Free memory
+
+ if ($adj) {
+ die unless
+ ($l =~ /^\@\@\s+\-([0-9]+),([0-9]+)\s+\+([0-9]+),([0-9]+)\s\@\@(.*)$/);
+ my $mstart = $1;
+ my $mlin = $2;
+ my $pstart = $3;
+ my $plin = $4;
+ my $tail = $5; # doesn't include the final newline
+
+ $l = sprintf("@@ -%d,%d +%d,%d @@%s\n",
+ $mstart, $mlin, $pstart, $plin-$adj,
+ $tail);
+ }
+ unshift(@h, $l);
+
+ # Transfer to the output array
+ foreach $l (@h) {
+ $out_bytes += length($l);
+ push(@lines, $l);
+ }
+
+ $in_hunk = 0;
+ }
+ }
+ }
+
+ if ($in_hunk) {
+ print STDERR "$name: $f: malformed patch\n";
+ $err = 1;
+ }
+
+ if (!$err) {
+ if ($in_bytes != $out_bytes) {
+ # Only write to the file if changed
+ seek(FILE, 0, 0);
+ print FILE @lines;
+
+ if ( !defined($where = tell(FILE)) ||
+ !truncate(FILE, $where) ) {
+ die "$name: Failed to truncate modified file: $f: $!\n";
+ }
+ }
+ }
+
+ close(FILE);
+}
diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh
index 43f75d6..683eb12 100644
--- a/scripts/gen_initramfs_list.sh
+++ b/scripts/gen_initramfs_list.sh
@@ -171,7 +171,7 @@ dir_filelist() {
${dep_list}header "$1"
srcdir=$(echo "$1" | sed -e 's://*:/:g')
- dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" 2>/dev/null)
+ dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n")
# If $dirlist is only one line, then the directory is empty
if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
@@ -191,9 +191,10 @@ input_file() {
source="$1"
if [ -f "$1" ]; then
${dep_list}header "$1"
- is_cpio="$(echo "$1" | sed 's/^.*\.cpio/cpio/')"
+ is_cpio="$(echo "$1" | sed 's/^.*\.cpio\(\..*\)\?/cpio/')"
if [ $2 -eq 0 -a ${is_cpio} == "cpio" ]; then
cpio_file=$1
+ echo "$1" | grep -q '^.*\.cpio\..*' && is_cpio_compressed="compressed"
[ ! -z ${dep_list} ] && echo "$1"
return 0
fi
@@ -223,6 +224,7 @@ cpio_file=
cpio_list=
output="/dev/stdout"
output_file=""
+is_cpio_compressed=
arg="$1"
case "$arg" in
@@ -282,7 +284,11 @@ if [ ! -z ${output_file} ]; then
cpio_tfile=${cpio_file}
fi
rm ${cpio_list}
- cat ${cpio_tfile} | gzip -f -9 - > ${output_file}
+ if [ "${is_cpio_compressed}" = "compressed" ]; then
+ cat ${cpio_tfile} > ${output_file}
+ else
+ cat ${cpio_tfile} | gzip -f -9 - > ${output_file}
+ fi
[ -z ${cpio_file} ] && rm ${cpio_tfile}
fi
exit 0
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
index b038182..511023b 100644
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -516,7 +516,8 @@ int main(int argc, char **argv)
genksyms_usage();
return 1;
}
- if ((strcmp(arch, "v850") == 0) || (strcmp(arch, "h8300") == 0))
+ if ((strcmp(arch, "v850") == 0) || (strcmp(arch, "h8300") == 0)
+ || (strcmp(arch, "blackfin") == 0))
mod_prefix = "_";
{
extern int yydebug;
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 7e7e147..fb2bb30 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -140,6 +140,7 @@ endif
clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
.tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c
+clean-files += mconf qconf gconf
# Needed for systems without gettext
KBUILD_HAVE_NLS := $(shell \
@@ -183,8 +184,8 @@ $(obj)/.tmp_qtcheck:
done; \
if [ -z "$$dir" ]; then \
echo "*"; \
- echo "* Unable to find the QT installation. Please make sure that"; \
- echo "* the QT development package is correctly installed and"; \
+ echo "* Unable to find the QT3 installation. Please make sure that"; \
+ echo "* the QT3 development package is correctly installed and"; \
echo "* either install pkg-config or set the QTDIR environment"; \
echo "* variable to the correct location."; \
echo "*"; \
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 124b341..1199baf 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -558,6 +558,7 @@ int main(int ac, char **av)
if (stat(".config", &tmpstat)) {
printf(_("***\n"
"*** You have not yet configured your kernel!\n"
+ "*** (missing kernel .config file)\n"
"***\n"
"*** Please run some configurator (e.g. \"make oldconfig\" or\n"
"*** \"make menuconfig\" or \"make xconfig\").\n"
diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped
index 800f8c7..0fdc904 100644
--- a/scripts/kconfig/lex.zconf.c_shipped
+++ b/scripts/kconfig/lex.zconf.c_shipped
@@ -2264,7 +2264,7 @@ FILE *zconf_fopen(const char *name)
FILE *f;
f = fopen(name, "r");
- if (!f && name[0] != '/') {
+ if (!f && name != NULL && name[0] != '/') {
env = getenv(SRCTREE);
if (env) {
sprintf(fullname, "%s/%s", env, name);
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 9b2706a..8a07ee4 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -64,6 +64,7 @@ int zconf_lineno(void);
char *zconf_curname(void);
/* confdata.c */
+const char *conf_get_configname(void);
char *conf_get_default_confname(void);
void sym_set_change_count(int count);
void sym_add_change_count(int count);
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index fd695e1..7e17eba 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -188,6 +188,7 @@ int on_key_esc(WINDOW *win);
int on_key_resize(void);
void init_dialog(const char *backtitle);
+void set_dialog_backtitle(const char *backtitle);
void reset_dialog(void);
void end_dialog(void);
void attr_clear(WINDOW * win, int height, int width, chtype attr);
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
index d54440f..a1bddef 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -272,6 +272,11 @@ void init_dialog(const char *backtitle)
color_setup(getenv("MENUCONFIG_COLOR"));
}
+void set_dialog_backtitle(const char *backtitle)
+{
+ dlg.backtitle = backtitle;
+}
+
void reset_dialog(void)
{
initscr(); /* Init curses */
@@ -336,7 +341,7 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
newl = 1;
word = tempstr;
while (word && *word) {
- sp = index(word, ' ');
+ sp = strchr(word, ' ');
if (sp)
*sp++ = 0;
@@ -348,7 +353,7 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
if (wlen > room ||
(newl && wlen < 4 && sp
&& wlen + 1 + strlen(sp) > room
- && (!(sp2 = index(sp, ' '))
+ && (!(sp2 = strchr(sp, ' '))
|| wlen + 1 + (sp2 - sp) > room))) {
cur_y++;
cur_x = x;
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 3f9a132..d0e4fa5 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -26,7 +26,6 @@
#include "lkc.h"
#include "lxdialog/dialog.h"
-static char menu_backtitle[128];
static const char mconf_readme[] = N_(
"Overview\n"
"--------\n"
@@ -271,7 +270,6 @@ search_help[] = N_(
" USB$ => find all CONFIG_ symbols ending with USB\n"
"\n");
-static char filename[PATH_MAX+1] = ".config";
static int indent;
static struct termios ios_org;
static int rows = 0, cols = 0;
@@ -395,6 +393,28 @@ static struct gstr get_relations_str(struct symbol **sym_arr)
return res;
}
+static char filename[PATH_MAX+1];
+static void set_config_filename(const char *config_filename)
+{
+ static char menu_backtitle[PATH_MAX+128];
+ int size;
+ struct symbol *sym;
+
+ sym = sym_lookup("KERNELVERSION", 0);
+ sym_calc_value(sym);
+ size = snprintf(menu_backtitle, sizeof(menu_backtitle),
+ _("%s - Linux Kernel v%s Configuration"),
+ config_filename, sym_get_string_value(sym));
+ if (size >= sizeof(menu_backtitle))
+ menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
+ set_dialog_backtitle(menu_backtitle);
+
+ size = snprintf(filename, sizeof(filename), "%s", config_filename);
+ if (size >= sizeof(filename))
+ filename[sizeof(filename)-1] = '\0';
+}
+
+
static void search_conf(void)
{
struct symbol **sym_arr;
@@ -816,8 +836,10 @@ static void conf_load(void)
case 0:
if (!dialog_input_result[0])
return;
- if (!conf_read(dialog_input_result))
+ if (!conf_read(dialog_input_result)) {
+ set_config_filename(dialog_input_result);
return;
+ }
show_textbox(NULL, _("File does not exist!"), 5, 38);
break;
case 1:
@@ -840,8 +862,10 @@ static void conf_save(void)
case 0:
if (!dialog_input_result[0])
return;
- if (!conf_write(dialog_input_result))
+ if (!conf_write(dialog_input_result)) {
+ set_config_filename(dialog_input_result);
return;
+ }
show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60);
break;
case 1:
@@ -860,7 +884,6 @@ static void conf_cleanup(void)
int main(int ac, char **av)
{
- struct symbol *sym;
char *mode;
int res;
@@ -871,11 +894,6 @@ int main(int ac, char **av)
conf_parse(av[1]);
conf_read(NULL);
- sym = sym_lookup("KERNELVERSION", 0);
- sym_calc_value(sym);
- sprintf(menu_backtitle, _("Linux Kernel v%s Configuration"),
- sym_get_string_value(sym));
-
mode = getenv("MENUCONFIG_MODE");
if (mode) {
if (!strcasecmp(mode, "single_menu"))
@@ -886,7 +904,8 @@ int main(int ac, char **av)
atexit(conf_cleanup);
init_wsize();
reset_dialog();
- init_dialog(menu_backtitle);
+ init_dialog(NULL);
+ set_config_filename(conf_get_configname());
do {
conf(&rootmenu);
dialog_clear();
@@ -903,7 +922,7 @@ int main(int ac, char **av)
switch (res) {
case 0:
- if (conf_write(NULL)) {
+ if (conf_write(filename)) {
fprintf(stderr, _("\n\n"
"Error during writing of the kernel configuration.\n"
"Your kernel configuration changes were NOT saved."
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index c86c27f..f14aeac 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -203,7 +203,7 @@ void sym_check_prop(struct symbol *sym)
else if (sym2->type == S_UNKNOWN)
prop_warn(prop,
"'select' used by config symbol '%s' "
- "refer to undefined symbol '%s'",
+ "refers to undefined symbol '%s'",
sym->name, sym2->name);
else if (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE)
prop_warn(prop,
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index 512c2f5..f2a23a9 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -1182,7 +1182,7 @@ void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
Parent::contentsContextMenuEvent(e);
}
-ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name)
+ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
: Parent(parent, name), result(NULL)
{
setCaption("Search Config");
@@ -1206,6 +1206,9 @@ ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name)
info = new ConfigInfoView(split, name);
connect(list->list, SIGNAL(menuChanged(struct menu *)),
info, SLOT(setInfo(struct menu *)));
+ connect(list->list, SIGNAL(menuChanged(struct menu *)),
+ parent, SLOT(setMenuLink(struct menu *)));
+
layout1->addWidget(split);
if (name) {
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index 6fc1c5f..b3b5657 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -279,7 +279,7 @@ class ConfigSearchWindow : public QDialog {
Q_OBJECT
typedef class QDialog Parent;
public:
- ConfigSearchWindow(QWidget* parent, const char *name = 0);
+ ConfigSearchWindow(ConfigMainWindow* parent, const char *name = 0);
public slots:
void saveSettings(void);
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 8f06c47..c35dcc5 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -786,13 +786,15 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
return NULL;
}
+/* return NULL when dependencies are OK */
struct symbol *sym_check_deps(struct symbol *sym)
{
struct symbol *sym2;
struct property *prop;
if (sym->flags & SYMBOL_CHECK) {
- printf("Warning! Found recursive dependency: %s", sym->name);
+ fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
+ sym->prop->file->name, sym->prop->lineno, sym->name);
return sym;
}
if (sym->flags & SYMBOL_CHECKED)
@@ -816,13 +818,8 @@ struct symbol *sym_check_deps(struct symbol *sym)
goto out;
}
out:
- if (sym2) {
- printf(" %s", sym->name);
- if (sym2 == sym) {
- printf("\n");
- sym2 = NULL;
- }
- }
+ if (sym2)
+ fprintf(stderr, " -> %s%s", sym->name, sym2 == sym? "\n": "");
sym->flags &= ~SYMBOL_CHECK;
return sym2;
}
diff --git a/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l
index cfa4607..187d38c 100644
--- a/scripts/kconfig/zconf.l
+++ b/scripts/kconfig/zconf.l
@@ -265,7 +265,7 @@ FILE *zconf_fopen(const char *name)
FILE *f;
f = fopen(name, "r");
- if (!f && name[0] != '/') {
+ if (!f && name != NULL && name[0] != '/') {
env = getenv(SRCTREE);
if (env) {
sprintf(fullname, "%s/%s", env, name);
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index d777fe8..9a06b67 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -2132,9 +2132,11 @@ void conf_parse(const char *name)
}
menu_finalize(&rootmenu);
for_all_symbols(i, sym) {
- sym_check_deps(sym);
+ if (sym_check_deps(sym))
+ zconfnerrs++;
}
-
+ if (zconfnerrs)
+ exit(1);
sym_set_change_count(1);
}
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 04a5864..92eb02b 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -501,9 +501,11 @@ void conf_parse(const char *name)
}
menu_finalize(&rootmenu);
for_all_symbols(i, sym) {
- sym_check_deps(sym);
+ if (sym_check_deps(sym))
+ zconfnerrs++;
}
-
+ if (zconfnerrs)
+ exit(1);
sym_set_change_count(1);
}
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 8be269f..a325a0c 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -159,7 +159,8 @@ my $warnings = 0;
my $type_constant = '\%([-_\w]+)';
my $type_func = '(\w+)\(\)';
my $type_param = '\@(\w+)';
-my $type_struct = '\&((struct\s*)?[_\w]+)';
+my $type_struct = '\&((struct\s*)*[_\w]+)';
+my $type_struct_xml = '\\\amp;((struct\s*)*[_\w]+)';
my $type_env = '(\$\w+)';
# Output conversion substitutions.
@@ -168,7 +169,8 @@ my $type_env = '(\$\w+)';
# these work fairly well
my %highlights_html = ( $type_constant, "<i>\$1</i>",
$type_func, "<b>\$1</b>",
- $type_struct, "<i>\$1</i>",
+ $type_struct_xml, "<i>\$1</i>",
+ $type_env, "<b><i>\$1</i></b>",
$type_param, "<tt><b>\$1</b></tt>" );
my $blankline_html = "<p>";
@@ -326,12 +328,21 @@ while ($ARGV[0] =~ m/^-(.*)/) {
}
}
+# get kernel version from env
+sub get_kernel_version() {
+ my $version;
+
+ if (defined($ENV{'KERNELVERSION'})) {
+ $version = $ENV{'KERNELVERSION'};
+ }
+ return $version;
+}
# generate a sequence of code that will splice in highlighting information
# using the s// operator.
my $dohighlight = "";
foreach my $pattern (keys %highlights) {
-# print "scanning pattern $pattern ($highlights{$pattern})\n";
+# print STDERR "scanning pattern:$pattern, highlight:($highlights{$pattern})\n";
$dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
}
@@ -378,13 +389,19 @@ sub output_highlight {
# confess "output_highlight got called with no args?\n";
# }
+# print STDERR "contents b4:$contents\n";
eval $dohighlight;
die $@ if $@;
+ if ($output_mode eq "html") {
+ $contents =~ s/\\\\//;
+ }
+# print STDERR "contents af:$contents\n";
+
foreach $line (split "\n", $contents) {
- if ($line eq ""){
+ if ($line eq ""){
print $lineprefix, $blankline;
} else {
- $line =~ s/\\\\\\/\&/g;
+ $line =~ s/\\\\\\/\&/g;
print $lineprefix, $line;
}
print "\n";
@@ -414,7 +431,7 @@ sub output_enum_html(%) {
print "<b>enum ".$args{'enum'}."</b> {<br>\n";
$count = 0;
foreach $parameter (@{$args{'parameterlist'}}) {
- print " <b>".$parameter."</b>";
+ print " <b>".$parameter."</b>";
if ($count != $#{$args{'parameterlist'}}) {
$count++;
print ",\n";
@@ -462,15 +479,16 @@ sub output_struct_html(%) {
my $parameter_name = $parameter;
$parameter_name =~ s/\[.*//;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
$type = $args{'parametertypes'}{$parameter};
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
# pointer-to-function
- print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n";
+ print "&nbsp; &nbsp; <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n";
} elsif ($type =~ m/^(.*?)\s*(:.*)/) {
- print " <i>$1</i> <b>$parameter</b>$2;<br>\n";
+ # bitfield
+ print "&nbsp; &nbsp; <i>$1</i> <b>$parameter</b>$2;<br>\n";
} else {
- print " <i>$type</i> <b>$parameter</b>;<br>\n";
+ print "&nbsp; &nbsp; <i>$type</i> <b>$parameter</b>;<br>\n";
}
}
print "};<br>\n";
@@ -483,7 +501,7 @@ sub output_struct_html(%) {
my $parameter_name = $parameter;
$parameter_name =~ s/\[.*//;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
print "<dt><b>".$parameter."</b>\n";
print "<dd>";
output_highlight($args{'parameterdescs'}{$parameter_name});
@@ -525,7 +543,7 @@ sub output_function_html(%) {
my $parameter_name = $parameter;
$parameter_name =~ s/\[.*//;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
print "<dt><b>".$parameter."</b>\n";
print "<dd>";
output_highlight($args{'parameterdescs'}{$parameter_name});
@@ -592,6 +610,7 @@ sub output_function_xml(%) {
print "<refmeta>\n";
print " <refentrytitle><phrase>".$args{'function'}."</phrase></refentrytitle>\n";
print " <manvolnum>9</manvolnum>\n";
+ print " <refmiscinfo class=\"version\">" . get_kernel_version() . "</refmiscinfo>\n";
print "</refmeta>\n";
print "<refnamediv>\n";
print " <refname>".$args{'function'}."</refname>\n";
@@ -668,6 +687,7 @@ sub output_struct_xml(%) {
print "<refmeta>\n";
print " <refentrytitle><phrase>".$args{'type'}." ".$args{'struct'}."</phrase></refentrytitle>\n";
print " <manvolnum>9</manvolnum>\n";
+ print " <refmiscinfo class=\"version\">" . get_kernel_version() . "</refmiscinfo>\n";
print "</refmeta>\n";
print "<refnamediv>\n";
print " <refname>".$args{'type'}." ".$args{'struct'}."</refname>\n";
@@ -691,7 +711,7 @@ sub output_struct_xml(%) {
$parameter_name =~ s/\[.*//;
defined($args{'parameterdescs'}{$parameter_name}) || next;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
$type = $args{'parametertypes'}{$parameter};
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
# pointer-to-function
@@ -752,6 +772,7 @@ sub output_enum_xml(%) {
print "<refmeta>\n";
print " <refentrytitle><phrase>enum ".$args{'enum'}."</phrase></refentrytitle>\n";
print " <manvolnum>9</manvolnum>\n";
+ print " <refmiscinfo class=\"version\">" . get_kernel_version() . "</refmiscinfo>\n";
print "</refmeta>\n";
print "<refnamediv>\n";
print " <refname>enum ".$args{'enum'}."</refname>\n";
@@ -767,11 +788,11 @@ sub output_enum_xml(%) {
print "enum ".$args{'enum'}." {\n";
$count = 0;
foreach $parameter (@{$args{'parameterlist'}}) {
- print " $parameter";
- if ($count != $#{$args{'parameterlist'}}) {
+ print " $parameter";
+ if ($count != $#{$args{'parameterlist'}}) {
$count++;
print ",";
- }
+ }
print "\n";
}
print "};";
@@ -1007,7 +1028,7 @@ sub output_enum_man(%) {
print "enum ".$args{'enum'}." {\n";
$count = 0;
foreach my $parameter (@{$args{'parameterlist'}}) {
- print ".br\n.BI \" $parameter\"\n";
+ print ".br\n.BI \" $parameter\"\n";
if ($count == $#{$args{'parameterlist'}}) {
print "\n};\n";
last;
@@ -1054,7 +1075,7 @@ sub output_struct_man(%) {
my $parameter_name = $parameter;
$parameter_name =~ s/\[.*//;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
$type = $args{'parametertypes'}{$parameter};
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
# pointer-to-function
@@ -1077,7 +1098,7 @@ sub output_struct_man(%) {
my $parameter_name = $parameter;
$parameter_name =~ s/\[.*//;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
print ".IP \"".$parameter."\" 12\n";
output_highlight($args{'parameterdescs'}{$parameter_name});
}
@@ -1187,7 +1208,7 @@ sub output_enum_text(%) {
print "enum ".$args{'enum'}." {\n";
$count = 0;
foreach $parameter (@{$args{'parameterlist'}}) {
- print "\t$parameter";
+ print "\t$parameter";
if ($count != $#{$args{'parameterlist'}}) {
$count++;
print ",";
@@ -1232,7 +1253,7 @@ sub output_struct_text(%) {
my $parameter_name = $parameter;
$parameter_name =~ s/\[.*//;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
$type = $args{'parametertypes'}{$parameter};
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
# pointer-to-function
@@ -1252,7 +1273,7 @@ sub output_struct_text(%) {
my $parameter_name = $parameter;
$parameter_name =~ s/\[.*//;
- ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+ ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
print "$parameter\n\t";
print $args{'parameterdescs'}{$parameter_name}."\n";
}
@@ -1284,7 +1305,7 @@ sub output_declaration {
( $function_only == 1 && defined($function_table{$name})) ||
( $function_only == 2 && !defined($function_table{$name})))
{
- &$func(@_);
+ &$func(@_);
$section_counter++;
}
}
@@ -1317,8 +1338,8 @@ sub dump_struct($$) {
my $file = shift;
if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) {
- $declaration_name = $2;
- my $members = $3;
+ $declaration_name = $2;
+ my $members = $3;
# ignore embedded structs or unions
$members =~ s/{.*?}//g;
@@ -1345,7 +1366,7 @@ sub dump_struct($$) {
});
}
else {
- print STDERR "Error(${file}:$.): Cannot parse struct or union!\n";
+ print STDERR "Error(${file}:$.): Cannot parse struct or union!\n";
++$errors;
}
}
@@ -1356,15 +1377,15 @@ sub dump_enum($$) {
$x =~ s@/\*.*?\*/@@gos; # strip comments.
if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
- $declaration_name = $1;
- my $members = $2;
+ $declaration_name = $1;
+ my $members = $2;
foreach my $arg (split ',', $members) {
$arg =~ s/^\s*(\w+).*/$1/;
push @parameterlist, $arg;
if (!$parameterdescs{$arg}) {
- $parameterdescs{$arg} = $undescribed;
- print STDERR "Warning(${file}:$.): Enum value '$arg' ".
+ $parameterdescs{$arg} = $undescribed;
+ print STDERR "Warning(${file}:$.): Enum value '$arg' ".
"not described in enum '$declaration_name'\n";
}
@@ -1382,7 +1403,7 @@ sub dump_enum($$) {
});
}
else {
- print STDERR "Error(${file}:$.): Cannot parse enum!\n";
+ print STDERR "Error(${file}:$.): Cannot parse enum!\n";
++$errors;
}
}
@@ -1393,12 +1414,12 @@ sub dump_typedef($$) {
$x =~ s@/\*.*?\*/@@gos; # strip comments.
while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
- $x =~ s/\(*.\)\s*;$/;/;
+ $x =~ s/\(*.\)\s*;$/;/;
$x =~ s/\[*.\]\s*;$/;/;
}
if ($x =~ /typedef.*\s+(\w+)\s*;/) {
- $declaration_name = $1;
+ $declaration_name = $1;
output_declaration($declaration_name,
'typedef',
@@ -1410,7 +1431,7 @@ sub dump_typedef($$) {
});
}
else {
- print STDERR "Error(${file}:$.): Cannot parse typedef!\n";
+ print STDERR "Error(${file}:$.): Cannot parse typedef!\n";
++$errors;
}
}
@@ -1424,14 +1445,14 @@ sub create_parameterlist($$$) {
# temporarily replace commas inside function pointer definition
while ($args =~ /(\([^\),]+),/) {
- $args =~ s/(\([^\),]+),/$1#/g;
+ $args =~ s/(\([^\),]+),/$1#/g;
}
foreach my $arg (split($splitter, $args)) {
# strip comments
$arg =~ s/\/\*.*\*\///;
- # strip leading/trailing spaces
- $arg =~ s/^\s*//;
+ # strip leading/trailing spaces
+ $arg =~ s/^\s*//;
$arg =~ s/\s*$//;
$arg =~ s/\s+/ /;
@@ -1456,7 +1477,16 @@ sub create_parameterlist($$$) {
if ($args[0] =~ m/\*/) {
$args[0] =~ s/(\*+)\s*/ $1/;
}
- my @first_arg = split('\s+', shift @args);
+
+ my @first_arg;
+ if ($args[0] =~ /^(.*\s+)(.*?\[.*\].*)$/) {
+ shift @args;
+ push(@first_arg, split('\s+', $1));
+ push(@first_arg, $2);
+ } else {
+ @first_arg = split('\s+', shift @args);
+ }
+
unshift(@args, pop @first_arg);
$type = join " ", @first_arg;
@@ -1514,15 +1544,15 @@ sub push_parameter($$$) {
$parameterdescs{$param_name} = $undescribed;
if (($type eq 'function') || ($type eq 'enum')) {
- print STDERR "Warning(${file}:$.): Function parameter ".
+ print STDERR "Warning(${file}:$.): Function parameter ".
"or member '$param' not " .
"described in '$declaration_name'\n";
}
print STDERR "Warning(${file}:$.):".
- " No description found for parameter '$param'\n";
+ " No description found for parameter '$param'\n";
++$warnings;
- }
- }
+ }
+ }
push @parameterlist, $param;
$parametertypes{$param} = $type;
@@ -1664,10 +1694,10 @@ sub process_state3_function($$) {
# do nothing
}
elsif ($x =~ /([^\{]*)/) {
- $prototype .= $1;
+ $prototype .= $1;
}
if (($x =~ /\{/) || ($x =~ /\#define/) || ($x =~ /;/)) {
- $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
+ $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
$prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
$prototype =~ s@^\s+@@gos; # strip leading spaces
dump_function($prototype,$file);
@@ -1688,17 +1718,17 @@ sub process_state3_type($$) {
}
while (1) {
- if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
+ if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
$prototype .= $1 . $2;
($2 eq '{') && $brcount++;
($2 eq '}') && $brcount--;
if (($2 eq ';') && ($brcount == 0)) {
- dump_declaration($prototype,$file);
+ dump_declaration($prototype,$file);
reset_state();
- last;
+ last;
}
$x = $3;
- } else {
+ } else {
$prototype .= $x;
last;
}
@@ -1756,7 +1786,7 @@ sub process_file($) {
} else {
$section = $1;
}
- }
+ }
elsif (/$doc_decl/o) {
$identifier = $1;
if (/\s*([\w\s]+?)\s*-/) {
@@ -1849,13 +1879,13 @@ sub process_file($) {
}
} elsif ($state == 3) { # scanning for function '{' (end of prototype)
if ($decl_type eq 'function') {
- process_state3_function($_, $file);
+ process_state3_function($_, $file);
} else {
- process_state3_type($_, $file);
+ process_state3_type($_, $file);
}
} elsif ($state == 4) {
# Documentation block
- if (/$doc_block/) {
+ if (/$doc_block/) {
dump_section($section, $contents);
output_intro({'sectionlist' => \@sectionlist,
'sections' => \%sections });
@@ -1873,7 +1903,7 @@ sub process_file($) {
} else {
$section = $1;
}
- }
+ }
elsif (/$doc_end/)
{
dump_section($section, $contents);
@@ -1900,8 +1930,8 @@ sub process_file($) {
{
$contents .= $1 . "\n";
}
- }
- }
+ }
+ }
}
if ($initial_section_counter == $section_counter) {
print STDERR "Warning(${file}): no structured comments found\n";
diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h
index 82d0af4..a8740df 100755
--- a/scripts/mkcompile_h
+++ b/scripts/mkcompile_h
@@ -18,19 +18,32 @@ fi
# Do not expand names
set -f
-if [ -r .version ]; then
- VERSION=`cat .version`
+# Fix the language to get consistent output
+LC_ALL=C
+export LC_ALL
+
+if [ -z "$KBUILD_BUILD_VERSION" ]; then
+ if [ -r .version ]; then
+ VERSION=`cat .version`
+ else
+ VERSION=0
+ echo 0 > .version
+ fi
else
- VERSION=0
- echo 0 > .version
+ VERSION=$KBUILD_BUILD_VERSION
fi
+if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then
+ TIMESTAMP=`date`
+else
+ TIMESTAMP=$KBUILD_BUILD_TIMESTAMP
+fi
UTS_VERSION="#$VERSION"
CONFIG_FLAGS=""
if [ -n "$SMP" ] ; then CONFIG_FLAGS="SMP"; fi
if [ -n "$PREEMPT" ] ; then CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT"; fi
-UTS_VERSION="$UTS_VERSION $CONFIG_FLAGS `LC_ALL=C LANG=C date`"
+UTS_VERSION="$UTS_VERSION $CONFIG_FLAGS $TIMESTAMP"
# Truncate to maximum length
@@ -46,7 +59,7 @@ UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/"
echo \#define UTS_VERSION \"`echo $UTS_VERSION | $UTS_TRUNCATE`\"
- echo \#define LINUX_COMPILE_TIME \"`LC_ALL=C LANG=C date +%T`\"
+ echo \#define LINUX_COMPILE_TIME \"`date +%T`\"
echo \#define LINUX_COMPILE_BY \"`whoami`\"
echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\"
@@ -58,7 +71,7 @@ UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/"
echo \#define LINUX_COMPILE_DOMAIN
fi
- echo \#define LINUX_COMPILER \"`LC_ALL=C LANG=C $CC -v 2>&1 | tail -n 1`\"
+ echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | tail -n 1`\"
) > .tmpcompile
# Only replace the real compile.h if the new one is different,
diff --git a/scripts/mkuboot.sh b/scripts/mkuboot.sh
index 4b06c5e..2e3d3cd 100755
--- a/scripts/mkuboot.sh
+++ b/scripts/mkuboot.sh
@@ -4,7 +4,7 @@
# Build U-Boot image when `mkimage' tool is available.
#
-MKIMAGE=$(type -path ${CROSS_COMPILE}mkimage)
+MKIMAGE=$(type -path "${CROSS_COMPILE}mkimage")
if [ -z "${MKIMAGE}" ]; then
MKIMAGE=$(type -path mkimage)
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index b2f73ff..ed1244d 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -37,7 +37,6 @@ typedef unsigned char __u8;
* even potentially has different endianness and word sizes, since
* we handle those differences explicitly below */
#include "../../include/linux/mod_devicetable.h"
-#include "../../include/linux/input.h"
#define ADD(str, sep, cond, field) \
do { \
@@ -416,31 +415,33 @@ static int do_input_entry(const char *filename, struct input_device_id *id,
sprintf(alias + strlen(alias), "-e*");
if (id->flags & INPUT_DEVICE_ID_MATCH_EVBIT)
- do_input(alias, id->evbit, 0, EV_MAX);
+ do_input(alias, id->evbit, 0, INPUT_DEVICE_ID_EV_MAX);
sprintf(alias + strlen(alias), "k*");
if (id->flags & INPUT_DEVICE_ID_MATCH_KEYBIT)
- do_input(alias, id->keybit, KEY_MIN_INTERESTING, KEY_MAX);
+ do_input(alias, id->keybit,
+ INPUT_DEVICE_ID_KEY_MIN_INTERESTING,
+ INPUT_DEVICE_ID_KEY_MAX);
sprintf(alias + strlen(alias), "r*");
if (id->flags & INPUT_DEVICE_ID_MATCH_RELBIT)
- do_input(alias, id->relbit, 0, REL_MAX);
+ do_input(alias, id->relbit, 0, INPUT_DEVICE_ID_REL_MAX);
sprintf(alias + strlen(alias), "a*");
if (id->flags & INPUT_DEVICE_ID_MATCH_ABSBIT)
- do_input(alias, id->absbit, 0, ABS_MAX);
+ do_input(alias, id->absbit, 0, INPUT_DEVICE_ID_ABS_MAX);
sprintf(alias + strlen(alias), "m*");
if (id->flags & INPUT_DEVICE_ID_MATCH_MSCIT)
- do_input(alias, id->mscbit, 0, MSC_MAX);
+ do_input(alias, id->mscbit, 0, INPUT_DEVICE_ID_MSC_MAX);
sprintf(alias + strlen(alias), "l*");
if (id->flags & INPUT_DEVICE_ID_MATCH_LEDBIT)
- do_input(alias, id->ledbit, 0, LED_MAX);
+ do_input(alias, id->ledbit, 0, INPUT_DEVICE_ID_LED_MAX);
sprintf(alias + strlen(alias), "s*");
if (id->flags & INPUT_DEVICE_ID_MATCH_SNDBIT)
- do_input(alias, id->sndbit, 0, SND_MAX);
+ do_input(alias, id->sndbit, 0, INPUT_DEVICE_ID_SND_MAX);
sprintf(alias + strlen(alias), "f*");
if (id->flags & INPUT_DEVICE_ID_MATCH_FFBIT)
- do_input(alias, id->ffbit, 0, FF_MAX);
+ do_input(alias, id->ffbit, 0, INPUT_DEVICE_ID_FF_MAX);
sprintf(alias + strlen(alias), "w*");
if (id->flags & INPUT_DEVICE_ID_MATCH_SWBIT)
- do_input(alias, id->swbit, 0, SW_MAX);
+ do_input(alias, id->swbit, 0, INPUT_DEVICE_ID_SW_MAX);
return 1;
}
diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c
index 725d61c..db3881f 100644
--- a/scripts/mod/mk_elfconfig.c
+++ b/scripts/mod/mk_elfconfig.c
@@ -55,7 +55,8 @@ main(int argc, char **argv)
else
exit(1);
- if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0))
+ if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0)
+ || (strcmp(argv[1], "blackfin") == 0))
printf("#define MODULE_SYMBOL_PREFIX \"_\"\n");
else
printf("#define MODULE_SYMBOL_PREFIX \"\"\n");
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 78d659c..480e18b 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -55,6 +55,17 @@ void warn(const char *fmt, ...)
va_end(arglist);
}
+void merror(const char *fmt, ...)
+{
+ va_list arglist;
+
+ fprintf(stderr, "ERROR: ");
+
+ va_start(arglist, fmt);
+ vfprintf(stderr, fmt, arglist);
+ va_end(arglist);
+}
+
static int is_vmlinux(const char *modname)
{
const char *myname;
@@ -333,10 +344,10 @@ void release_file(void *file, unsigned long size)
munmap(file, size);
}
-static void parse_elf(struct elf_info *info, const char *filename)
+static int parse_elf(struct elf_info *info, const char *filename)
{
unsigned int i;
- Elf_Ehdr *hdr = info->hdr;
+ Elf_Ehdr *hdr;
Elf_Shdr *sechdrs;
Elf_Sym *sym;
@@ -346,9 +357,18 @@ static void parse_elf(struct elf_info *info, const char *filename)
exit(1);
}
info->hdr = hdr;
- if (info->size < sizeof(*hdr))
- goto truncated;
-
+ if (info->size < sizeof(*hdr)) {
+ /* file too small, assume this is an empty .o file */
+ return 0;
+ }
+ /* Is this a valid ELF file? */
+ if ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||
+ (hdr->e_ident[EI_MAG1] != ELFMAG1) ||
+ (hdr->e_ident[EI_MAG2] != ELFMAG2) ||
+ (hdr->e_ident[EI_MAG3] != ELFMAG3)) {
+ /* Not an ELF file - silently ignore it */
+ return 0;
+ }
/* Fix endianness in ELF header */
hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
@@ -371,8 +391,10 @@ static void parse_elf(struct elf_info *info, const char *filename)
= (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
const char *secname;
- if (sechdrs[i].sh_offset > info->size)
- goto truncated;
+ if (sechdrs[i].sh_offset > info->size) {
+ fatal("%s is truncated. sechdrs[i].sh_offset=%u > sizeof(*hrd)=%ul\n", filename, (unsigned int)sechdrs[i].sh_offset, sizeof(*hdr));
+ return 0;
+ }
secname = secstrings + sechdrs[i].sh_name;
if (strcmp(secname, ".modinfo") == 0) {
info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
@@ -407,10 +429,7 @@ static void parse_elf(struct elf_info *info, const char *filename)
sym->st_value = TO_NATIVE(sym->st_value);
sym->st_size = TO_NATIVE(sym->st_size);
}
- return;
-
- truncated:
- fatal("%s is truncated.\n", filename);
+ return 1;
}
static void parse_elf_finish(struct elf_info *info)
@@ -581,9 +600,17 @@ static int strrcmp(const char *s, const char *sub)
* the pattern is identified by:
* tosec = .init.text | .exit.text | .init.data
* fromsec = .data
- * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one
+ * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console
*
* Pattern 3:
+ * Whitelist all references from .pci_fixup* section to .init.text
+ * This is part of the PCI init when built-in
+ *
+ * Pattern 4:
+ * Whitelist all refereces from .text.head to .init.data
+ * Whitelist all refereces from .text.head to .init.text
+ *
+ * Pattern 5:
* Some symbols belong to init section but still it is ok to reference
* these from non-init sections as these symbols don't have any memory
* allocated for them and symbol address and value are same. So even
@@ -591,6 +618,40 @@ static int strrcmp(const char *s, const char *sub)
* For ex. symbols marking the init section boundaries.
* This pattern is identified by
* refsymname = __init_begin, _sinittext, _einittext
+ *
+ * Pattern 6:
+ * During the early init phase we have references from .init.text to
+ * .text we have an intended section mismatch - do not warn about it.
+ * See kernel_init() in init/main.c
+ * tosec = .init.text
+ * fromsec = .text
+ * atsym = kernel_init
+ *
+ * Pattern 7:
+ * Logos used in drivers/video/logo reside in __initdata but the
+ * funtion that references them are EXPORT_SYMBOL() so cannot be
+ * marker __init. So we whitelist them here.
+ * The pattern is:
+ * tosec = .init.data
+ * fromsec = .text*
+ * refsymname = logo_
+ *
+ * Pattern 8:
+ * Symbols contained in .paravirtprobe may safely reference .init.text.
+ * The pattern is:
+ * tosec = .init.text
+ * fromsec = .paravirtprobe
+ *
+ * Pattern 9:
+ * Some of functions are common code between boot time and hotplug
+ * time. The bootmem allocater is called only boot time in its
+ * functions. So it's ok to reference.
+ * tosec = .init.text
+ *
+ * Pattern 10:
+ * ia64 has machvec table for each platform. It is mixture of function
+ * pointer of .init.text and .text.
+ * fromsec = .machvec
**/
static int secref_whitelist(const char *modname, const char *tosec,
const char *fromsec, const char *atsym,
@@ -617,6 +678,12 @@ static int secref_whitelist(const char *modname, const char *tosec,
NULL
};
+ const char *pat4sym[] = {
+ "sparse_index_alloc",
+ "zone_wait_table_init",
+ NULL
+ };
+
/* Check for pattern 1 */
if (strcmp(tosec, ".init.data") != 0)
f1 = 0;
@@ -642,25 +709,50 @@ static int secref_whitelist(const char *modname, const char *tosec,
if (f1 && f2)
return 1;
- /* Whitelist all references from .pci_fixup section if vmlinux
- * Whitelist all refereces from .text.head to .init.data if vmlinux
- * Whitelist all refereces from .text.head to .init.text if vmlinux
- */
- if (is_vmlinux(modname)) {
- if ((strcmp(fromsec, ".pci_fixup") == 0) &&
- (strcmp(tosec, ".init.text") == 0))
+ /* Check for pattern 3 */
+ if ((strncmp(fromsec, ".pci_fixup", strlen(".pci_fixup")) == 0) &&
+ (strcmp(tosec, ".init.text") == 0))
+ return 1;
+
+ /* Check for pattern 4 */
+ if ((strcmp(fromsec, ".text.head") == 0) &&
+ ((strcmp(tosec, ".init.data") == 0) ||
+ (strcmp(tosec, ".init.text") == 0)))
+ return 1;
+
+ /* Check for pattern 5 */
+ for (s = pat3refsym; *s; s++)
+ if (strcmp(refsymname, *s) == 0)
+ return 1;
+
+ /* Check for pattern 6 */
+ if ((strcmp(tosec, ".init.text") == 0) &&
+ (strcmp(fromsec, ".text") == 0) &&
+ (strcmp(refsymname, "kernel_init") == 0))
return 1;
- if ((strcmp(fromsec, ".text.head") == 0) &&
- ((strcmp(tosec, ".init.data") == 0) ||
- (strcmp(tosec, ".init.text") == 0)))
+ /* Check for pattern 7 */
+ if ((strcmp(tosec, ".init.data") == 0) &&
+ (strncmp(fromsec, ".text", strlen(".text")) == 0) &&
+ (strncmp(refsymname, "logo_", strlen("logo_")) == 0))
return 1;
- /* Check for pattern 3 */
- for (s = pat3refsym; *s; s++)
- if (strcmp(refsymname, *s) == 0)
+ /* Check for pattern 8 */
+ if ((strcmp(tosec, ".init.text") == 0) &&
+ (strcmp(fromsec, ".paravirtprobe") == 0))
+ return 1;
+
+ /* Check for pattern 9 */
+ if ((strcmp(tosec, ".init.text") == 0) &&
+ (strcmp(fromsec, ".text") == 0))
+ for (s = pat4sym; *s; s++)
+ if (strcmp(atsym, *s) == 0)
return 1;
- }
+
+ /* Check for pattern 10 */
+ if (strcmp(fromsec, ".machvec") == 0)
+ return 1;
+
return 0;
}
@@ -1090,7 +1182,8 @@ static void read_symbols(char *modname)
struct elf_info info = { };
Elf_Sym *sym;
- parse_elf(&info, modname);
+ if (!parse_elf(&info, modname))
+ return;
mod = new_module(modname);
@@ -1265,9 +1358,14 @@ static int add_versions(struct buffer *b, struct module *mod)
exp = find_symbol(s->name);
if (!exp || exp->module == mod) {
if (have_vmlinux && !s->weak) {
- warn("\"%s\" [%s.ko] undefined!\n",
- s->name, mod->name);
- err = warn_unresolved ? 0 : 1;
+ if (warn_unresolved) {
+ warn("\"%s\" [%s.ko] undefined!\n",
+ s->name, mod->name);
+ } else {
+ merror("\"%s\" [%s.ko] undefined!\n",
+ s->name, mod->name);
+ err = 1;
+ }
}
continue;
}
@@ -1318,6 +1416,7 @@ static void add_depends(struct buffer *b, struct module *mod,
buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n");
buf_printf(b, "\"depends=");
for (s = mod->unres; s; s = s->next) {
+ const char *p;
if (!s->module)
continue;
@@ -1325,8 +1424,11 @@ static void add_depends(struct buffer *b, struct module *mod,
continue;
s->module->seen = 1;
- buf_printf(b, "%s%s", first ? "" : ",",
- strrchr(s->module->name, '/') + 1);
+ if ((p = strrchr(s->module->name, '/')) != NULL)
+ p++;
+ else
+ p = s->module->name;
+ buf_printf(b, "%s%s", first ? "" : ",", p);
first = 0;
}
buf_printf(b, "\";\n");
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index d398c61..0858caa 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -145,3 +145,4 @@ void release_file(void *file, unsigned long size);
void fatal(const char *fmt, ...);
void warn(const char *fmt, ...);
+void merror(const char *fmt, ...);
diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c
index 8a28756..6873d5a 100644
--- a/scripts/mod/sumversion.c
+++ b/scripts/mod/sumversion.c
@@ -397,10 +397,9 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen)
(int) strlen(basename) - 2, basename);
file = grab_file(filelist, &len);
- if (!file) {
- warn("could not find versions for %s\n", filelist);
+ if (!file)
+ /* not a module or .mod file missing - ignore */
return;
- }
sources = strchr(file, '\n');
if (!sources) {
diff --git a/security/capability.c b/security/capability.c
index b868e7e..38296a0 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -17,7 +17,6 @@
#include <linux/mman.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
-#include <linux/smp_lock.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/ptrace.h>
diff --git a/security/commoncap.c b/security/commoncap.c
index 5a5ef5c..384379e 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -17,7 +17,6 @@
#include <linux/mman.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
-#include <linux/smp_lock.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/ptrace.h>
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 885a9a9..ad8dd4e 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -35,7 +35,6 @@
#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
-#include <linux/smp_lock.h>
#include <linux/spinlock.h>
#include <linux/syscalls.h>
#include <linux/file.h>
@@ -1758,12 +1757,11 @@ static inline void flush_unauthorized_files(struct files_struct * files)
}
}
file_list_unlock();
-
- /* Reset controlling tty. */
- if (drop_tty)
- proc_set_tty(current, NULL);
}
mutex_unlock(&tty_mutex);
+ /* Reset controlling tty. */
+ if (drop_tty)
+ no_tty();
/* Revalidate access to inherited open files. */
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.c b/sound/aoa/codecs/snd-aoa-codec-onyx.c
index 7f980be..e91f9f6 100644
--- a/sound/aoa/codecs/snd-aoa-codec-onyx.c
+++ b/sound/aoa/codecs/snd-aoa-codec-onyx.c
@@ -1061,7 +1061,7 @@ static int onyx_i2c_attach(struct i2c_adapter *adapter)
busnode = pmac_i2c_get_bus_node(bus);
while ((dev = of_get_next_child(busnode, dev)) != NULL) {
- if (device_is_compatible(dev, "pcm3052")) {
+ if (of_device_is_compatible(dev, "pcm3052")) {
const u32 *addr;
printk(KERN_DEBUG PFX "found pcm3052\n");
addr = of_get_property(dev, "reg", NULL);
@@ -1074,7 +1074,7 @@ static int onyx_i2c_attach(struct i2c_adapter *adapter)
/* if that didn't work, try desperate mode for older
* machines that have stuff missing from the device tree */
- if (!device_is_compatible(busnode, "k2-i2c"))
+ if (!of_device_is_compatible(busnode, "k2-i2c"))
return -ENODEV;
printk(KERN_DEBUG PFX "found k2-i2c, checking if onyx chip is on it\n");
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c
index ceca384..041fe52 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.c
+++ b/sound/aoa/codecs/snd-aoa-codec-tas.c
@@ -938,7 +938,7 @@ static int tas_i2c_attach(struct i2c_adapter *adapter)
busnode = pmac_i2c_get_bus_node(bus);
while ((dev = of_get_next_child(busnode, dev)) != NULL) {
- if (device_is_compatible(dev, "tas3004")) {
+ if (of_device_is_compatible(dev, "tas3004")) {
const u32 *addr;
printk(KERN_DEBUG PFX "found tas3004\n");
addr = of_get_property(dev, "reg", NULL);
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
index 79fc4bc..0fccdbf 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-core.c
+++ b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
@@ -336,8 +336,8 @@ static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match)
}
while ((np = of_get_next_child(dev->ofdev.node, np))) {
- if (device_is_compatible(np, "i2sbus") ||
- device_is_compatible(np, "i2s-modem")) {
+ if (of_device_is_compatible(np, "i2sbus") ||
+ of_device_is_compatible(np, "i2s-modem")) {
got += i2sbus_add_dev(dev, control, np);
}
}
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 28db4be..19c65a8 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -260,7 +260,7 @@ static int pxa2xx_ac97_do_suspend(struct snd_card *card, pm_message_t state)
if (platform_ops && platform_ops->suspend)
platform_ops->suspend(platform_ops->priv);
GCR |= GCR_ACLINK_OFF;
- pxa_set_cken(CKEN2_AC97, 0);
+ pxa_set_cken(CKEN_AC97, 0);
return 0;
}
@@ -269,7 +269,7 @@ static int pxa2xx_ac97_do_resume(struct snd_card *card)
{
pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
- pxa_set_cken(CKEN2_AC97, 1);
+ pxa_set_cken(CKEN_AC97, 1);
if (platform_ops && platform_ops->resume)
platform_ops->resume(platform_ops->priv);
snd_ac97_resume(pxa2xx_ac97_ac97);
@@ -337,7 +337,7 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
/* Use GPIO 113 as AC97 Reset on Bulverde */
pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
#endif
- pxa_set_cken(CKEN2_AC97, 1);
+ pxa_set_cken(CKEN_AC97, 1);
ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus);
if (ret)
@@ -361,10 +361,10 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
err:
if (card)
snd_card_free(card);
- if (CKEN & CKEN2_AC97) {
+ if (CKEN & CKEN_AC97) {
GCR |= GCR_ACLINK_OFF;
free_irq(IRQ_AC97, NULL);
- pxa_set_cken(CKEN2_AC97, 0);
+ pxa_set_cken(CKEN_AC97, 0);
}
return ret;
}
@@ -378,7 +378,7 @@ static int __devexit pxa2xx_ac97_remove(struct platform_device *dev)
platform_set_drvdata(dev, NULL);
GCR |= GCR_ACLINK_OFF;
free_irq(IRQ_AC97, NULL);
- pxa_set_cken(CKEN2_AC97, 0);
+ pxa_set_cken(CKEN_AC97, 0);
}
return 0;
diff --git a/sound/core/control.c b/sound/core/control.c
index 86de725..1f1ab9c 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -22,7 +22,6 @@
#include <sound/driver.h>
#include <linux/threads.h>
#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/time.h>
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 96ffdf1..51ad95b 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -22,7 +22,6 @@
#include <sound/driver.h>
#include <linux/major.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/mutex.h>
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 74a2923..fccad8f 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -21,7 +21,6 @@
#include <sound/driver.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/string.h>
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index c4744bb..fc11572 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -28,7 +28,6 @@
#include <sound/driver.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/vmalloc.h>
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 3e276fc..9052348 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -21,7 +21,6 @@
#include <sound/driver.h>
#include <linux/mm.h>
-#include <linux/smp_lock.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/time.h>
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index d14dcbb..e470c3c7 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -23,7 +23,6 @@
#include <sound/core.h>
#include <linux/major.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/time.h>
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index 2eb9873..bc09923 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -22,7 +22,6 @@
#include <sound/driver.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/moduleparam.h>
#include <linux/mutex.h>
#include <sound/core.h>
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 694efe8..b31b528 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -23,7 +23,6 @@
#include <sound/driver.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/minors.h>
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 160e40e..67520b3 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -22,7 +22,6 @@
#include <sound/driver.h>
#include <linux/delay.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/mutex.h>
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 4c41930..4b30ae6 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -5,23 +5,22 @@
#
# Prompt user for primary drivers.
-config OBSOLETE_OSS
+config OSS_OBSOLETE
bool "Obsolete OSS drivers"
depends on SOUND_PRIME
help
This option enables support for obsolete OSS drivers that
- are scheduled for removal in the near future since there
- are ALSA drivers for the same hardware.
+ are scheduled for removal in the near future.
Please contact Adrian Bunk <bunk@stusta.de> if you had to
- say Y here because your soundcard is not properly supported
+ say Y here because your hardware is not properly supported
by ALSA.
If unsure, say N.
config SOUND_BT878
tristate "BT878 audio dma"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OSS_OBSOLETE
---help---
Audio DMA support for bt878 based grabber boards. As you might have
already noticed, bt878 is listed with two functions in /proc/pci.
@@ -45,22 +44,9 @@ config SOUND_BCM_CS4297A
note that CONFIG_KGDB should not be enabled at the same
time, since it also attempts to use this UART port.
-config SOUND_ES1371
- tristate "Creative Ensoniq AudioPCI 97 (ES1371)"
- depends on SOUND_PRIME && PCI && OBSOLETE_OSS
- help
- Say Y or M if you have a PCI sound card utilizing the Ensoniq
- ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if
- your sound card uses an ES1371 without removing your computer's
- cover, use lspci -n and look for the PCI ID 1274:1371. Since
- Ensoniq was bought by Creative Labs, Sound Blaster 64/PCI
- models are either ES1370 or ES1371 based. This driver differs
- slightly from OSS/Free, so PLEASE READ
- <file:Documentation/sound/oss/es1371>.
-
config SOUND_ICH
tristate "Intel ICH (i8xx) audio support"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OSS_OBSOLETE
help
Support for integral audio in Intel's I/O Controller Hub (ICH)
chipset, as used on the 810/820/840 motherboards.
@@ -362,7 +348,7 @@ config MSND_FIFOSIZE
config SOUND_VIA82CXXX
tristate "VIA 82C686 Audio Codec"
- depends on SOUND_PRIME && PCI
+ depends on SOUND_PRIME && PCI && OSS_OBSOLETE
help
Say Y here to include support for the audio codec found on VIA
82Cxxx-based chips. Typically these are built into a motherboard.
@@ -416,7 +402,7 @@ config SOUND_DMAP
config SOUND_CS4232
tristate "Crystal CS4232 based (PnP) cards"
- depends on SOUND_OSS
+ depends on SOUND_OSS && OSS_OBSOLETE
help
Say Y here if you have a card based on the Crystal CS4232 chip set,
which uses its own Plug and Play protocol.
@@ -735,7 +721,7 @@ config SOUND_WAVEARTIST
config SOUND_TVMIXER
tristate "TV card (bt848) mixer support"
- depends on SOUND_PRIME && I2C && VIDEO_V4L1
+ depends on SOUND_PRIME && I2C && VIDEO_V4L1 && OSS_OBSOLETE
help
Support for audio mixer facilities on the BT848 TV frame-grabber
card.
diff --git a/sound/oss/btaudio.c b/sound/oss/btaudio.c
index f813ae9..4d5cf05 100644
--- a/sound/oss/btaudio.c
+++ b/sound/oss/btaudio.c
@@ -344,7 +344,7 @@ static int btaudio_mixer_ioctl(struct inode *inode, struct file *file,
if (cmd == SOUND_OLD_MIXER_INFO) {
_old_mixer_info info;
memset(&info,0,sizeof(info));
- strlcpy(info.id,"bt878",sizeof(info.id)-1);
+ strlcpy(info.id, "bt878", sizeof(info.id));
strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name));
if (copy_to_user(argp, &info, sizeof(info)))
return -EFAULT;
diff --git a/sound/oss/dmasound/Kconfig b/sound/oss/dmasound/Kconfig
index 18e149f..71b3134 100644
--- a/sound/oss/dmasound/Kconfig
+++ b/sound/oss/dmasound/Kconfig
@@ -12,20 +12,6 @@ config DMASOUND_ATARI
want). If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>.
-config DMASOUND_PMAC
- tristate "PowerMac DMA sound support"
- depends on PPC32 && PPC_PMAC && SOUND && I2C && OBSOLETE_OSS
- select DMASOUND
- help
- If you want to use the internal audio of your PowerMac in Linux,
- answer Y to this question. This will provide a Sun-like /dev/audio,
- compatible with the Linux/i386 sound system. Otherwise, say N.
-
- This driver is also available as a module ( = code which can be
- inserted in and removed from the running kernel whenever you
- want). If you want to compile it as a module, say M here and read
- <file:Documentation/kbuild/modules.txt>.
-
config DMASOUND_PAULA
tristate "Amiga DMA sound support"
depends on (AMIGA || APUS) && SOUND
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
index 730fa1d..8f63880 100644
--- a/sound/oss/dmasound/dmasound_awacs.c
+++ b/sound/oss/dmasound/dmasound_awacs.c
@@ -362,7 +362,7 @@ setup_audio_gpio(const char *name, const char* compatible, int *gpio_addr, int*
of_get_property(np,"audio-gpio",NULL);
if (property != 0 && strcmp(property,name) == 0)
break;
- } else if (compatible && device_is_compatible(np, compatible))
+ } else if (compatible && of_device_is_compatible(np, compatible))
break;
np = of_get_next_child(gpiop, np);
}
@@ -2620,17 +2620,17 @@ get_codec_type(struct device_node *info)
if (info) {
/* must do awacs first to allow screamer to overide it */
- if (device_is_compatible(info, "awacs"))
+ if (of_device_is_compatible(info, "awacs"))
codec = AWACS_AWACS ;
- if (device_is_compatible(info, "screamer"))
+ if (of_device_is_compatible(info, "screamer"))
codec = AWACS_SCREAMER;
- if (device_is_compatible(info, "burgundy"))
+ if (of_device_is_compatible(info, "burgundy"))
codec = AWACS_BURGUNDY ;
- if (device_is_compatible(info, "daca"))
+ if (of_device_is_compatible(info, "daca"))
codec = AWACS_DACA;
- if (device_is_compatible(info, "tumbler"))
+ if (of_device_is_compatible(info, "tumbler"))
codec = AWACS_TUMBLER;
- if (device_is_compatible(info, "snapper"))
+ if (of_device_is_compatible(info, "snapper"))
codec = AWACS_SNAPPER;
}
return codec ;
@@ -2772,7 +2772,7 @@ set_hw_byteswap(struct device_node *io)
for (mio = io->parent; mio ; mio = mio->parent) {
if (strcmp(mio->name, "mac-io") == 0) {
- if (device_is_compatible(mio, "Keylargo"))
+ if (of_device_is_compatible(mio, "Keylargo"))
kl = 1;
break;
}
diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c
index 7ea9acc..b493660 100644
--- a/sound/oss/sh_dac_audio.c
+++ b/sound/oss/sh_dac_audio.c
@@ -104,7 +104,7 @@ static void dac_audio_set_rate(void)
unsigned long interval;
struct clk *clk;
- clk = clk_get("module_clk");
+ clk = clk_get(NULL, "module_clk");
interval = (clk_get_rate(clk) / 4) / rate;
clk_put(clk);
ctrl_outl(interval, TMU1_TCOR);
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c
index 016b918..a8057f2 100644
--- a/sound/oss/swarm_cs4297a.c
+++ b/sound/oss/swarm_cs4297a.c
@@ -75,7 +75,6 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/poll.h>
-#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/kernel.h>
diff --git a/sound/oss/trident.c b/sound/oss/trident.c
index 72a8a0e..d98d311 100644
--- a/sound/oss/trident.c
+++ b/sound/oss/trident.c
@@ -207,7 +207,6 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
#include <linux/ac97_codec.h>
#include <linux/bitops.h>
#include <linux/proc_fs.h>
diff --git a/sound/oss/via82cxxx_audio.c b/sound/oss/via82cxxx_audio.c
index 7ab3a73..5d3c037 100644
--- a/sound/oss/via82cxxx_audio.c
+++ b/sound/oss/via82cxxx_audio.c
@@ -32,7 +32,6 @@
#include <linux/poll.h>
#include <linux/soundcard.h>
#include <linux/ac97_codec.h>
-#include <linux/smp_lock.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index 2bae9c1..5a2bef4 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -843,7 +843,7 @@ static void __init detect_byte_swap(struct snd_pmac *chip)
/* if seems that Keylargo can't byte-swap */
for (mio = chip->node->parent; mio; mio = mio->parent) {
if (strcmp(mio->name, "mac-io") == 0) {
- if (device_is_compatible(mio, "Keylargo"))
+ if (of_device_is_compatible(mio, "Keylargo"))
chip->can_byte_swap = 0;
break;
}
@@ -910,7 +910,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
chip->node = of_find_node_by_name(NULL, "i2s-a");
if (chip->node && chip->node->parent &&
chip->node->parent->parent) {
- if (device_is_compatible(chip->node->parent->parent,
+ if (of_device_is_compatible(chip->node->parent->parent,
"K2-Keylargo"))
chip->is_k2 = 1;
}
@@ -941,22 +941,22 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
return -ENODEV;
}
/* This should be verified on older screamers */
- if (device_is_compatible(sound, "screamer")) {
+ if (of_device_is_compatible(sound, "screamer")) {
chip->model = PMAC_SCREAMER;
// chip->can_byte_swap = 0; /* FIXME: check this */
}
- if (device_is_compatible(sound, "burgundy")) {
+ if (of_device_is_compatible(sound, "burgundy")) {
chip->model = PMAC_BURGUNDY;
chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
}
- if (device_is_compatible(sound, "daca")) {
+ if (of_device_is_compatible(sound, "daca")) {
chip->model = PMAC_DACA;
chip->can_capture = 0; /* no capture */
chip->can_duplex = 0;
// chip->can_byte_swap = 0; /* FIXME: check this */
chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
}
- if (device_is_compatible(sound, "tumbler")) {
+ if (of_device_is_compatible(sound, "tumbler")) {
chip->model = PMAC_TUMBLER;
chip->can_capture = 0; /* no capture */
chip->can_duplex = 0;
@@ -965,7 +965,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
chip->freq_table = tumbler_freqs;
chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
}
- if (device_is_compatible(sound, "snapper")) {
+ if (of_device_is_compatible(sound, "snapper")) {
chip->model = PMAC_SNAPPER;
// chip->can_byte_swap = 0; /* FIXME: check this */
chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 54e333f..5821cdd 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -1060,7 +1060,7 @@ static struct device_node *find_compatible_audio_device(const char *name)
for (np = of_get_next_child(gpiop, NULL); np;
np = of_get_next_child(gpiop, np)) {
- if (device_is_compatible(np, name))
+ if (of_device_is_compatible(np, name))
break;
}
of_node_put(gpiop);
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 1bbbeff..b222755 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -256,7 +256,7 @@ static int pxa2xx_ac97_suspend(struct platform_device *pdev,
struct snd_soc_cpu_dai *dai)
{
GCR |= GCR_ACLINK_OFF;
- pxa_set_cken(CKEN2_AC97, 0);
+ pxa_set_cken(CKEN_AC97, 0);
return 0;
}
@@ -271,7 +271,7 @@ static int pxa2xx_ac97_resume(struct platform_device *pdev,
/* Use GPIO 113 as AC97 Reset on Bulverde */
pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
#endif
- pxa_set_cken(CKEN2_AC97, 1);
+ pxa_set_cken(CKEN_AC97, 1);
return 0;
}
@@ -296,14 +296,14 @@ static int pxa2xx_ac97_probe(struct platform_device *pdev)
/* Use GPIO 113 as AC97 Reset on Bulverde */
pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
#endif
- pxa_set_cken(CKEN2_AC97, 1);
+ pxa_set_cken(CKEN_AC97, 1);
return 0;
err:
- if (CKEN & CKEN2_AC97) {
+ if (CKEN & CKEN_AC97) {
GCR |= GCR_ACLINK_OFF;
free_irq(IRQ_AC97, NULL);
- pxa_set_cken(CKEN2_AC97, 0);
+ pxa_set_cken(CKEN_AC97, 0);
}
return ret;
}
@@ -312,7 +312,7 @@ static void pxa2xx_ac97_remove(struct platform_device *pdev)
{
GCR |= GCR_ACLINK_OFF;
free_irq(IRQ_AC97, NULL);
- pxa_set_cken(CKEN2_AC97, 0);
+ pxa_set_cken(CKEN_AC97, 0);
}
static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 575a613..50c5c83 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -149,7 +149,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
pxa_gpio_mode(gpio_bus[pxa_i2s.master].tx);
pxa_gpio_mode(gpio_bus[pxa_i2s.master].frm);
pxa_gpio_mode(gpio_bus[pxa_i2s.master].clk);
- pxa_set_cken(CKEN8_I2S, 1);
+ pxa_set_cken(CKEN_I2S, 1);
pxa_i2s_wait();
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -234,7 +234,7 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream)
if (SACR1 & (SACR1_DREC | SACR1_DRPL)) {
SACR0 &= ~SACR0_ENB;
pxa_i2s_wait();
- pxa_set_cken(CKEN8_I2S, 0);
+ pxa_set_cken(CKEN_I2S, 0);
}
}
diff --git a/usr/Kconfig b/usr/Kconfig
index 07727f3..86cecb5 100644
--- a/usr/Kconfig
+++ b/usr/Kconfig
@@ -17,7 +17,7 @@ config INITRAMFS_SOURCE
When multiple directories and files are specified then the
initramfs image will be the aggregate of all of them.
- See <file:Documentation/early-userspace/README for more details.
+ See <file:Documentation/early-userspace/README> for more details.
If you are not sure, leave it blank.