From 9c420b6780cbafa4c512d3dba532ad5910d8b578 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Wed, 14 Oct 2009 18:12:16 +0800 Subject: [PATCH] --- yaml --- r: 177853 b: refs/heads/master c: 1b93b3c3e94be2605759735a89fc935ba5f58dcf h: refs/heads/master i: 177851: cb8769aba13c729fdf38d25edc47b218db7beb8d v: v3 --- [refs] | 2 +- trunk/.gitignore | 7 +- trunk/Documentation/dontdiff | 1 - trunk/Documentation/kbuild/kbuild.txt | 14 - trunk/Documentation/kbuild/kconfig.txt | 8 +- trunk/Kbuild | 4 +- trunk/MAINTAINERS | 6 - trunk/Makefile | 96 +- trunk/arch/alpha/boot/bootp.c | 2 +- trunk/arch/alpha/boot/bootpz.c | 2 +- trunk/arch/alpha/boot/main.c | 2 +- trunk/arch/alpha/include/asm/asm-offsets.h | 1 - trunk/arch/alpha/include/asm/fcntl.h | 2 +- trunk/arch/arm/Makefile | 14 +- trunk/arch/arm/common/dmabounce.c | 12 +- trunk/arch/arm/include/asm/asm-offsets.h | 1 - trunk/arch/arm/include/asm/cacheflush.h | 17 +- trunk/arch/arm/include/asm/mach-types.h | 1 - trunk/arch/arm/mach-kirkwood/Kconfig | 6 - trunk/arch/arm/mach-kirkwood/Makefile | 1 - .../arm/mach-kirkwood/netspace_v2-setup.c | 325 ----- trunk/arch/arm/mach-pxa/Kconfig | 3 +- trunk/arch/arm/mach-pxa/devices.c | 2 +- .../arch/arm/mach-s3c2410/include/mach/spi.h | 2 - trunk/arch/arm/mm/cache-fa.S | 11 +- trunk/arch/arm/mm/cache-l2x0.c | 93 +- trunk/arch/arm/mm/cache-v3.S | 9 +- trunk/arch/arm/mm/cache-v4.S | 9 +- trunk/arch/arm/mm/cache-v4wb.S | 11 +- trunk/arch/arm/mm/cache-v4wt.S | 11 +- trunk/arch/arm/mm/cache-v6.S | 11 +- trunk/arch/arm/mm/cache-v7.S | 13 +- trunk/arch/arm/mm/flush.c | 4 +- trunk/arch/arm/mm/highmem.c | 2 +- trunk/arch/arm/mm/nommu.c | 2 +- trunk/arch/arm/mm/proc-arm1020.S | 11 +- trunk/arch/arm/mm/proc-arm1020e.S | 11 +- trunk/arch/arm/mm/proc-arm1022.S | 11 +- trunk/arch/arm/mm/proc-arm1026.S | 11 +- trunk/arch/arm/mm/proc-arm920.S | 11 +- trunk/arch/arm/mm/proc-arm922.S | 11 +- trunk/arch/arm/mm/proc-arm925.S | 11 +- trunk/arch/arm/mm/proc-arm926.S | 11 +- trunk/arch/arm/mm/proc-arm940.S | 9 +- trunk/arch/arm/mm/proc-arm946.S | 11 +- trunk/arch/arm/mm/proc-feroceon.S | 15 +- trunk/arch/arm/mm/proc-mohawk.S | 11 +- trunk/arch/arm/mm/proc-syms.c | 3 +- trunk/arch/arm/mm/proc-v6.S | 5 +- trunk/arch/arm/mm/proc-xsc3.S | 11 +- trunk/arch/arm/mm/proc-xscale.S | 13 +- trunk/arch/arm/tools/Makefile | 2 +- trunk/arch/arm/tools/gen-mach-types | 2 +- trunk/arch/arm/tools/mach-types | 44 +- trunk/arch/avr32/include/asm/asm-offsets.h | 1 - trunk/arch/blackfin/include/asm/asm-offsets.h | 1 - trunk/arch/cris/arch-v32/kernel/head.S | 1 + trunk/arch/cris/include/asm/asm-offsets.h | 1 - trunk/arch/cris/kernel/asm-offsets.c | 1 + trunk/arch/cris/kernel/vmlinux.lds.S | 1 + trunk/arch/frv/include/asm/asm-offsets.h | 1 - trunk/arch/frv/kernel/setup.c | 2 +- trunk/arch/h8300/include/asm/asm-offsets.h | 1 - trunk/arch/ia64/Makefile | 2 +- trunk/arch/ia64/include/asm/asm-offsets.h | 1 - trunk/arch/ia64/include/asm/irq.h | 2 +- trunk/arch/ia64/kernel/Makefile | 7 +- trunk/arch/ia64/kvm/asm-offsets.c | 1 + trunk/arch/m68k/include/asm/asm-offsets.h | 1 - trunk/arch/m68k/kernel/head.S | 2 +- .../arch/microblaze/include/asm/asm-offsets.h | 1 - trunk/arch/mips/Kconfig | 14 + trunk/arch/mips/Makefile | 31 +- trunk/arch/mips/boot/compressed/Makefile | 100 ++ trunk/arch/mips/boot/compressed/dbg.c | 37 + trunk/arch/mips/boot/compressed/decompress.c | 126 ++ trunk/arch/mips/boot/compressed/dummy.c | 4 + trunk/arch/mips/boot/compressed/head.S | 56 + trunk/arch/mips/boot/compressed/ld.script | 150 +++ trunk/arch/mips/boot/compressed/uart-16550.c | 43 + trunk/arch/mips/include/asm/asm-offsets.h | 1 - trunk/arch/mips/include/asm/fcntl.h | 2 +- trunk/arch/mn10300/include/asm/asm-offsets.h | 1 - trunk/arch/parisc/include/asm/asm-offsets.h | 1 - trunk/arch/powerpc/include/asm/asm-offsets.h | 1 - trunk/arch/powerpc/platforms/52xx/efika.c | 2 +- trunk/arch/powerpc/platforms/amigaone/setup.c | 2 +- .../powerpc/platforms/cell/spufs/Makefile | 6 +- trunk/arch/powerpc/platforms/chrp/setup.c | 2 +- .../powerpc/platforms/powermac/bootx_init.c | 2 +- trunk/arch/s390/include/asm/asm-offsets.h | 1 - trunk/arch/score/include/asm/asm-offsets.h | 1 - trunk/arch/score/include/asm/cacheflush.h | 4 +- trunk/arch/score/include/asm/delay.h | 2 - trunk/arch/score/include/asm/page.h | 2 +- trunk/arch/score/kernel/setup.c | 1 - trunk/arch/score/mm/cache.c | 26 +- trunk/arch/score/mm/init.c | 5 + trunk/arch/sh/Makefile | 10 +- trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c | 2 +- trunk/arch/sh/include/asm/.gitignore | 1 + trunk/arch/sh/include/asm/asm-offsets.h | 1 - trunk/arch/sh/include/asm/machvec.h | 2 +- trunk/arch/sh/tools/Makefile | 4 +- trunk/arch/sh/tools/gen-mach-types | 2 +- trunk/arch/sparc/include/asm/asm-offsets.h | 1 - trunk/arch/sparc/include/asm/fcntl.h | 2 +- trunk/arch/um/Makefile | 2 +- trunk/arch/um/include/asm/asm-offsets.h | 1 - trunk/arch/x86/boot/header.S | 2 +- trunk/arch/x86/boot/version.c | 4 +- trunk/arch/x86/include/asm/asm-offsets.h | 1 - trunk/arch/x86/kernel/ptrace.c | 16 +- trunk/arch/xtensa/include/asm/asm-offsets.h | 1 - .../accessibility/braille/braille_console.c | 1 + trunk/drivers/hid/hid-lg.h | 2 + trunk/drivers/hwmon/Kconfig | 17 - trunk/drivers/hwmon/Makefile | 1 - trunk/drivers/hwmon/lis3lv02d_i2c.c | 183 --- trunk/drivers/leds/Kconfig | 33 - trunk/drivers/leds/Makefile | 4 - trunk/drivers/leds/leds-adp5520.c | 230 ---- trunk/drivers/leds/leds-alix2.c | 115 +- trunk/drivers/leds/leds-cobalt-qube.c | 4 +- trunk/drivers/leds/leds-cobalt-raq.c | 2 +- trunk/drivers/leds/leds-lt3593.c | 217 --- trunk/drivers/leds/leds-pwm.c | 5 +- trunk/drivers/leds/leds-regulator.c | 242 ---- trunk/drivers/leds/leds-ss4200.c | 556 -------- trunk/drivers/misc/Kconfig | 1 - trunk/drivers/mmc/core/sdio.c | 5 +- trunk/drivers/mmc/core/sdio_bus.c | 7 +- trunk/drivers/mmc/host/Kconfig | 37 +- trunk/drivers/mmc/host/Makefile | 6 +- trunk/drivers/mmc/host/sdhci-of-esdhc.c | 143 -- trunk/drivers/mmc/host/sdhci-of-hlwd.c | 65 - .../mmc/host/{sdhci-of-core.c => sdhci-of.c} | 143 +- trunk/drivers/mmc/host/sdhci-of.h | 42 - trunk/drivers/mmc/host/sdhci.h | 4 - trunk/drivers/mtd/maps/pxa2xx-flash.c | 13 +- trunk/drivers/net/wireless/iwlwifi/iwl-core.h | 2 +- trunk/drivers/pcmcia/pxa2xx_base.c | 6 +- trunk/drivers/platform/x86/compal-laptop.c | 1 + trunk/drivers/regulator/88pm8607.c | 685 ---------- trunk/drivers/regulator/Kconfig | 13 - trunk/drivers/regulator/Makefile | 4 +- trunk/drivers/regulator/ab3100.c | 33 +- trunk/drivers/regulator/core.c | 248 ++-- trunk/drivers/regulator/da903x.c | 2 +- trunk/drivers/regulator/lp3971.c | 4 +- trunk/drivers/regulator/max8660.c | 510 ------- trunk/drivers/regulator/mc13783-regulator.c | 245 ---- trunk/drivers/regulator/mc13783.c | 410 ++++++ trunk/drivers/regulator/twl-regulator.c | 147 +- trunk/drivers/regulator/wm831x-dcdc.c | 207 +-- trunk/drivers/regulator/wm831x-ldo.c | 2 +- trunk/drivers/rtc/rtc-ds1305.c | 2 - trunk/drivers/rtc/rtc-ds1307.c | 2 - trunk/drivers/rtc/rtc-ds1374.c | 2 - trunk/drivers/spi/Kconfig | 28 - trunk/drivers/spi/Makefile | 10 +- trunk/drivers/spi/atmel_spi.c | 6 +- trunk/drivers/spi/dw_spi.c | 944 ------------- trunk/drivers/spi/dw_spi_pci.c | 169 --- trunk/drivers/spi/spi_bfin5xx.c | 2 +- trunk/drivers/spi/spi_mpc8xxx.c | 2 +- trunk/drivers/spi/spi_s3c24xx.c | 244 +--- trunk/drivers/spi/spi_s3c24xx_fiq.S | 116 -- trunk/drivers/spi/spi_s3c24xx_fiq.h | 26 - trunk/drivers/spi/spi_s3c64xx.c | 1196 ----------------- trunk/drivers/spi/spi_sh_sci.c | 2 +- trunk/drivers/spi/spi_txx9.c | 6 +- trunk/drivers/spi/spidev.c | 18 +- trunk/drivers/staging/iio/ring_sw.h | 1 + trunk/drivers/staging/panel/panel.c | 2 +- trunk/drivers/video/atafb.c | 3 + trunk/drivers/video/backlight/adp5520_bl.c | 2 +- trunk/drivers/video/backlight/adx_bl.c | 2 +- trunk/drivers/video/backlight/atmel-pwm-bl.c | 2 +- trunk/drivers/video/backlight/backlight.c | 2 +- trunk/drivers/video/backlight/corgi_lcd.c | 2 +- trunk/drivers/video/backlight/cr_bllcd.c | 4 +- trunk/drivers/video/backlight/da903x_bl.c | 2 +- trunk/drivers/video/backlight/generic_bl.c | 2 +- trunk/drivers/video/backlight/hp680_bl.c | 2 +- trunk/drivers/video/backlight/jornada720_bl.c | 2 +- trunk/drivers/video/backlight/kb3886_bl.c | 2 +- trunk/drivers/video/backlight/locomolcd.c | 2 +- trunk/drivers/video/backlight/mbp_nvidia_bl.c | 20 +- trunk/drivers/video/backlight/omap1_bl.c | 2 +- trunk/drivers/video/backlight/progear_bl.c | 2 +- trunk/drivers/video/backlight/pwm_bl.c | 11 +- trunk/drivers/video/backlight/tosa_bl.c | 2 +- trunk/drivers/video/backlight/wm831x_bl.c | 2 +- trunk/drivers/video/via/viafbdev.c | 4 +- trunk/fs/Kconfig | 4 + trunk/fs/anon_inodes.c | 17 +- trunk/fs/binfmt_aout.c | 13 +- trunk/fs/binfmt_elf.c | 24 +- trunk/fs/binfmt_elf_fdpic.c | 29 +- trunk/fs/binfmt_flat.c | 6 +- trunk/fs/binfmt_som.c | 2 +- trunk/fs/btrfs/Kconfig | 1 + trunk/fs/btrfs/acl.c | 23 +- trunk/fs/btrfs/btrfs_inode.h | 5 +- trunk/fs/btrfs/ctree.c | 229 ++-- trunk/fs/btrfs/ctree.h | 40 +- trunk/fs/btrfs/dir-item.c | 19 +- trunk/fs/btrfs/disk-io.c | 27 +- trunk/fs/btrfs/extent-tree.c | 72 +- trunk/fs/btrfs/file.c | 669 +++++---- trunk/fs/btrfs/inode.c | 567 +++----- trunk/fs/btrfs/ioctl.c | 34 +- trunk/fs/btrfs/ordered-data.c | 115 +- trunk/fs/btrfs/ordered-data.h | 5 +- trunk/fs/btrfs/relocation.c | 38 +- trunk/fs/btrfs/super.c | 15 +- trunk/fs/btrfs/transaction.c | 44 +- trunk/fs/btrfs/transaction.h | 6 +- trunk/fs/btrfs/tree-log.c | 86 +- trunk/fs/btrfs/volumes.c | 2 +- trunk/fs/btrfs/xattr.c | 80 +- trunk/fs/btrfs/xattr.h | 9 +- trunk/fs/direct-io.c | 2 +- trunk/fs/ecryptfs/dentry.c | 2 +- trunk/fs/ecryptfs/inode.c | 6 +- trunk/fs/ecryptfs/main.c | 2 +- trunk/fs/exec.c | 40 +- trunk/fs/ext4/Kconfig | 1 + trunk/fs/gfs2/Kconfig | 1 + trunk/fs/gfs2/inode.c | 2 +- trunk/fs/inode.c | 26 +- trunk/fs/jbd/Kconfig | 1 + trunk/fs/jbd2/Kconfig | 1 + trunk/fs/jfs/jfs_txnmgr.c | 2 +- trunk/fs/namei.c | 2 +- trunk/fs/namespace.c | 3 +- trunk/fs/nfs/super.c | 8 - trunk/fs/nilfs2/Kconfig | 1 + trunk/fs/ntfs/inode.c | 6 +- trunk/fs/pipe.c | 18 + trunk/fs/ramfs/file-nommu.c | 2 +- trunk/fs/reiserfs/Kconfig | 1 + trunk/fs/reiserfs/inode.c | 18 +- trunk/fs/stack.c | 71 +- trunk/fs/sync.c | 59 +- trunk/fs/ubifs/file.c | 2 +- trunk/fs/xfs/linux-2.6/xfs_iops.c | 2 +- trunk/fs/xfs/xfs_iget.c | 4 +- trunk/include/asm-generic/fcntl.h | 2 +- trunk/include/linux/Kbuild | 1 - trunk/include/linux/backlight.h | 12 +- trunk/include/linux/binfmts.h | 10 +- trunk/include/linux/fs.h | 40 +- trunk/include/linux/fs_stack.h | 6 +- trunk/include/linux/init_task.h | 8 +- trunk/include/linux/kmemleak.h | 6 +- trunk/include/linux/leds-lp3944.h | 3 + trunk/include/linux/leds-pca9532.h | 2 +- trunk/include/linux/leds-regulator.h | 46 - trunk/include/linux/mfd/wm831x/pdata.h | 17 - trunk/include/linux/mmdebug.h | 2 + trunk/include/linux/mmzone.h | 2 +- trunk/include/linux/mnt_namespace.h | 1 - trunk/include/linux/page-flags.h | 2 +- trunk/include/linux/pwm_backlight.h | 2 +- trunk/include/linux/regulator/consumer.h | 2 - trunk/include/linux/regulator/machine.h | 6 +- trunk/include/linux/regulator/max8660.h | 57 - trunk/include/linux/sched.h | 2 + trunk/include/linux/spi/dw_spi.h | 212 --- trunk/include/linux/vermagic.h | 2 +- trunk/include/linux/vt.h | 4 - trunk/include/linux/writeback.h | 3 +- trunk/init/Makefile | 8 +- trunk/init/version.c | 4 +- trunk/kernel/bounds.c | 2 +- trunk/kernel/exit.c | 36 +- trunk/kernel/fork.c | 2 +- trunk/kernel/kexec.c | 2 +- trunk/kernel/module.c | 13 +- trunk/kernel/printk.c | 4 +- trunk/kernel/sysctl.c | 2 +- trunk/kernel/trace/trace.c | 2 +- trunk/lib/Kconfig.debug | 1 - trunk/lib/vsprintf.c | 13 +- trunk/mm/kmemleak.c | 188 ++- trunk/mm/readahead.c | 12 - trunk/mm/shmem.c | 2 - trunk/mm/slab.c | 10 +- trunk/net/socket.c | 19 + trunk/scripts/Kbuild.include | 6 - trunk/scripts/Makefile.lib | 2 +- trunk/scripts/Makefile.modbuiltin | 55 - trunk/scripts/basic/fixdep.c | 10 +- trunk/scripts/genksyms/keywords.c_shipped | 191 ++- trunk/scripts/genksyms/keywords.gperf | 2 - trunk/scripts/headers.sh | 2 + trunk/scripts/kconfig/Makefile | 1 - trunk/scripts/kconfig/confdata.c | 24 +- trunk/scripts/mkcompile_h | 2 +- trunk/scripts/mod/modpost.c | 2 +- trunk/scripts/package/Makefile | 20 +- trunk/scripts/package/buildtar | 6 +- trunk/scripts/tags.sh | 8 +- trunk/scripts/unifdef.c | 341 ++--- trunk/usr/gen_init_cpio.c | 5 +- 307 files changed, 3272 insertions(+), 9709 deletions(-) delete mode 100644 trunk/arch/alpha/include/asm/asm-offsets.h delete mode 100644 trunk/arch/arm/include/asm/asm-offsets.h delete mode 100644 trunk/arch/arm/include/asm/mach-types.h delete mode 100644 trunk/arch/arm/mach-kirkwood/netspace_v2-setup.c delete mode 100644 trunk/arch/avr32/include/asm/asm-offsets.h delete mode 100644 trunk/arch/blackfin/include/asm/asm-offsets.h delete mode 100644 trunk/arch/cris/include/asm/asm-offsets.h delete mode 100644 trunk/arch/frv/include/asm/asm-offsets.h delete mode 100644 trunk/arch/h8300/include/asm/asm-offsets.h delete mode 100644 trunk/arch/ia64/include/asm/asm-offsets.h delete mode 100644 trunk/arch/m68k/include/asm/asm-offsets.h delete mode 100644 trunk/arch/microblaze/include/asm/asm-offsets.h create mode 100644 trunk/arch/mips/boot/compressed/Makefile create mode 100644 trunk/arch/mips/boot/compressed/dbg.c create mode 100644 trunk/arch/mips/boot/compressed/decompress.c create mode 100644 trunk/arch/mips/boot/compressed/dummy.c create mode 100644 trunk/arch/mips/boot/compressed/head.S create mode 100644 trunk/arch/mips/boot/compressed/ld.script create mode 100644 trunk/arch/mips/boot/compressed/uart-16550.c delete mode 100644 trunk/arch/mips/include/asm/asm-offsets.h delete mode 100644 trunk/arch/mn10300/include/asm/asm-offsets.h delete mode 100644 trunk/arch/parisc/include/asm/asm-offsets.h delete mode 100644 trunk/arch/powerpc/include/asm/asm-offsets.h delete mode 100644 trunk/arch/s390/include/asm/asm-offsets.h delete mode 100644 trunk/arch/score/include/asm/asm-offsets.h create mode 100644 trunk/arch/sh/include/asm/.gitignore delete mode 100644 trunk/arch/sh/include/asm/asm-offsets.h delete mode 100644 trunk/arch/sparc/include/asm/asm-offsets.h delete mode 100644 trunk/arch/um/include/asm/asm-offsets.h delete mode 100644 trunk/arch/x86/include/asm/asm-offsets.h delete mode 100644 trunk/arch/xtensa/include/asm/asm-offsets.h delete mode 100644 trunk/drivers/hwmon/lis3lv02d_i2c.c delete mode 100644 trunk/drivers/leds/leds-adp5520.c delete mode 100644 trunk/drivers/leds/leds-lt3593.c delete mode 100644 trunk/drivers/leds/leds-regulator.c delete mode 100644 trunk/drivers/leds/leds-ss4200.c delete mode 100644 trunk/drivers/mmc/host/sdhci-of-esdhc.c delete mode 100644 trunk/drivers/mmc/host/sdhci-of-hlwd.c rename trunk/drivers/mmc/host/{sdhci-of-core.c => sdhci-of.c} (58%) delete mode 100644 trunk/drivers/mmc/host/sdhci-of.h delete mode 100644 trunk/drivers/regulator/88pm8607.c delete mode 100644 trunk/drivers/regulator/max8660.c delete mode 100644 trunk/drivers/regulator/mc13783-regulator.c create mode 100644 trunk/drivers/regulator/mc13783.c delete mode 100644 trunk/drivers/spi/dw_spi.c delete mode 100644 trunk/drivers/spi/dw_spi_pci.c delete mode 100644 trunk/drivers/spi/spi_s3c24xx_fiq.S delete mode 100644 trunk/drivers/spi/spi_s3c24xx_fiq.h delete mode 100644 trunk/drivers/spi/spi_s3c64xx.c delete mode 100644 trunk/include/linux/leds-regulator.h delete mode 100644 trunk/include/linux/regulator/max8660.h delete mode 100644 trunk/include/linux/spi/dw_spi.h delete mode 100644 trunk/scripts/Makefile.modbuiltin diff --git a/[refs] b/[refs] index e35ec085d01b..37fb7c50a901 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7c508e50be47737b9a72d0f15c3ef1146925e2d2 +refs/heads/master: 1b93b3c3e94be2605759735a89fc935ba5f58dcf diff --git a/trunk/.gitignore b/trunk/.gitignore index fb2190c61af0..946c7ec5c922 100644 --- a/trunk/.gitignore +++ b/trunk/.gitignore @@ -22,7 +22,6 @@ *.lst *.symtypes *.order -modules.builtin *.elf *.bin *.gz @@ -46,8 +45,14 @@ Module.symvers # # Generated include files # +include/asm +include/asm-*/asm-offsets.h include/config +include/linux/autoconf.h +include/linux/compile.h include/linux/version.h +include/linux/utsrelease.h +include/linux/bounds.h include/generated # stgit generated dirs diff --git a/trunk/Documentation/dontdiff b/trunk/Documentation/dontdiff index 3ad6acead949..e151b2a36267 100644 --- a/trunk/Documentation/dontdiff +++ b/trunk/Documentation/dontdiff @@ -103,7 +103,6 @@ gconf gen-devlist gen_crc32table gen_init_cpio -generated genheaders genksyms *_gray256.c diff --git a/trunk/Documentation/kbuild/kbuild.txt b/trunk/Documentation/kbuild/kbuild.txt index 6f8c1cabbc5d..bb3bf38f03da 100644 --- a/trunk/Documentation/kbuild/kbuild.txt +++ b/trunk/Documentation/kbuild/kbuild.txt @@ -1,17 +1,3 @@ -Output files - -modules.order --------------------------------------------------- -This file records the order in which modules appear in Makefiles. This -is used by modprobe to deterministically resolve aliases that match -multiple modules. - -modules.builtin --------------------------------------------------- -This file lists all modules that are built into the kernel. This is used -by modprobe to not fail when trying to load something builtin. - - Environment variables KCPPFLAGS diff --git a/trunk/Documentation/kbuild/kconfig.txt b/trunk/Documentation/kbuild/kconfig.txt index 49efae703979..849b5e56d06f 100644 --- a/trunk/Documentation/kbuild/kconfig.txt +++ b/trunk/Documentation/kbuild/kconfig.txt @@ -103,16 +103,10 @@ KCONFIG_AUTOCONFIG This environment variable can be set to specify the path & name of the "auto.conf" file. Its default value is "include/config/auto.conf". -KCONFIG_TRISTATE --------------------------------------------------- -This environment variable can be set to specify the path & name of the -"tristate.conf" file. Its default value is "include/config/tristate.conf". - KCONFIG_AUTOHEADER -------------------------------------------------- This environment variable can be set to specify the path & name of the -"autoconf.h" (header) file. -Its default value is "include/generated/autoconf.h". +"autoconf.h" (header) file. Its default value is "include/linux/autoconf.h". ====================================================================== diff --git a/trunk/Kbuild b/trunk/Kbuild index e3737ad72b5a..f056b4feee51 100644 --- a/trunk/Kbuild +++ b/trunk/Kbuild @@ -8,7 +8,7 @@ ##### # 1) Generate bounds.h -bounds-file := include/generated/bounds.h +bounds-file := include/linux/bounds.h always := $(bounds-file) targets := $(bounds-file) kernel/bounds.s @@ -43,7 +43,7 @@ $(obj)/$(bounds-file): kernel/bounds.s Kbuild # 2) Generate asm-offsets.h # -offsets-file := include/generated/asm-offsets.h +offsets-file := include/asm/asm-offsets.h always += $(offsets-file) targets += $(offsets-file) diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index efd2ef2c2660..0699782f8c5b 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -5434,12 +5434,6 @@ F: drivers/uwb/* F: include/linux/uwb.h F: include/linux/uwb/ -UNIFDEF -M: Tony Finch -W: http://dotat.at/prog/unifdef -S: Maintained -F: scripts/unifdef.c - UNIFORM CDROM DRIVER M: Jens Axboe W: http://www.kernel.dk diff --git a/trunk/Makefile b/trunk/Makefile index 8491b21b5537..33d4732a6c4a 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -334,9 +334,10 @@ CFLAGS_GCOV = -fprofile-arcs -ftest-coverage # Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option -LINUXINCLUDE := -I$(srctree)/arch/$(hdr-arch)/include -Iinclude \ - $(if $(KBUILD_SRC), -I$(srctree)/include) \ - -include include/generated/autoconf.h +LINUXINCLUDE := -Iinclude \ + $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \ + -I$(srctree)/arch/$(hdr-arch)/include \ + -include include/linux/autoconf.h KBUILD_CPPFLAGS := -D__KERNEL__ @@ -464,7 +465,7 @@ ifeq ($(KBUILD_EXTMOD),) # Carefully list dependencies so we do not try to build scripts twice # in parallel PHONY += scripts -scripts: scripts_basic include/config/auto.conf include/config/tristate.conf +scripts: scripts_basic include/config/auto.conf $(Q)$(MAKE) $(build)=$(@) # Objects we will link into vmlinux / subdirs we need to visit @@ -491,18 +492,18 @@ $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; # with it and forgot to run make oldconfig. # if auto.conf.cmd is missing then we are probably in a cleaned tree so # we execute the config step to be sure to catch updated Kconfig files -include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd +include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig else -# external modules needs include/generated/autoconf.h and include/config/auto.conf +# external modules needs include/linux/autoconf.h and include/config/auto.conf # but do not care if they are up-to-date. Use auto.conf to trigger the test PHONY += include/config/auto.conf include/config/auto.conf: - $(Q)test -e include/generated/autoconf.h -a -e $@ || ( \ + $(Q)test -e include/linux/autoconf.h -a -e $@ || ( \ echo; \ echo " ERROR: Kernel configuration is invalid."; \ - echo " include/generated/autoconf.h or $@ are missing.";\ + echo " include/linux/autoconf.h or $@ are missing."; \ echo " Run 'make oldconfig && make prepare' on kernel src to fix it."; \ echo; \ /bin/false) @@ -876,9 +877,6 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ; PHONY += $(vmlinux-dirs) $(vmlinux-dirs): prepare scripts $(Q)$(MAKE) $(build)=$@ -ifdef CONFIG_MODULES - $(Q)$(MAKE) $(modbuiltin)=$@ -endif # Build the kernel release string # @@ -957,6 +955,7 @@ PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3 # prepare3 is used to check if we are building in a separate output directory, # and if so do: # 1) Check that make has not been executed in the kernel src $(srctree) +# 2) Create the include2 directory, used for the second asm symlink prepare3: include/config/kernel.release ifneq ($(KBUILD_SRC),) @$(kecho) ' Using $(srctree) as source for kernel' @@ -965,13 +964,17 @@ ifneq ($(KBUILD_SRC),) echo " in the '$(srctree)' directory.";\ /bin/false; \ fi; + $(Q)if [ ! -d include2 ]; then \ + mkdir -p include2; \ + ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \ + fi endif # prepare2 creates a makefile if using a separate output directory prepare2: prepare3 outputmakefile -prepare1: prepare2 include/linux/version.h include/generated/utsrelease.h \ - include/config/auto.conf +prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \ + include/asm include/config/auto.conf $(cmd_crmodverdir) archprepare: prepare1 scripts_basic @@ -983,6 +986,42 @@ prepare0: archprepare FORCE # All the preparing.. prepare: prepare0 +# The asm symlink changes when $(ARCH) changes. +# Detect this and ask user to run make mrproper +# If asm is a stale symlink (point to dir that does not exist) remove it +define check-symlink + set -e; \ + if [ -L include/asm ]; then \ + asmlink=`readlink include/asm | cut -d '-' -f 2`; \ + if [ "$$asmlink" != "$(SRCARCH)" ]; then \ + echo "ERROR: the symlink $@ points to asm-$$asmlink but asm-$(SRCARCH) was expected"; \ + echo " set ARCH or save .config and run 'make mrproper' to fix it"; \ + exit 1; \ + fi; \ + test -e $$asmlink || rm include/asm; \ + elif [ -d include/asm ]; then \ + echo "ERROR: $@ is a directory but a symlink was expected";\ + exit 1; \ + fi +endef + +# We create the target directory of the symlink if it does +# not exist so the test in check-symlink works and we have a +# directory for generated filesas used by some architectures. +define create-symlink + if [ ! -L include/asm ]; then \ + $(kecho) ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \ + if [ ! -d include/asm-$(SRCARCH) ]; then \ + mkdir -p include/asm-$(SRCARCH); \ + fi; \ + ln -fsn asm-$(SRCARCH) $@; \ + fi +endef + +include/asm: FORCE + $(Q)$(check-symlink) + $(Q)$(create-symlink) + # Generate some files # --------------------------------------------------------------------------- @@ -1007,7 +1046,7 @@ endef include/linux/version.h: $(srctree)/Makefile FORCE $(call filechk,version.h) -include/generated/utsrelease.h: include/config/kernel.release FORCE +include/linux/utsrelease.h: include/config/kernel.release FORCE $(call filechk,utsrelease.h) PHONY += headerdep @@ -1037,6 +1076,11 @@ firmware_install: FORCE export INSTALL_HDR_PATH = $(objtree)/usr hdr-inst := -rR -f $(srctree)/scripts/Makefile.headersinst obj +# Find out where the Kbuild file is located to support +# arch/$(ARCH)/include/asm +hdr-dir = $(strip \ + $(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/asm/Kbuild), \ + arch/$(hdr-arch)/include/asm, include/asm-$(hdr-arch))) # If we do an all arch process set dst to asm-$(hdr-arch) hdr-dst = $(if $(KBUILD_HEADERS), dst=include/asm-$(hdr-arch), dst=include/asm) @@ -1051,10 +1095,10 @@ headers_install_all: PHONY += headers_install headers_install: __headers - $(if $(wildcard $(srctree)/arch/$(hdr-arch)/include/asm/Kbuild),, \ + $(if $(wildcard $(srctree)/$(hdr-dir)/Kbuild),, \ $(error Headers not exportable for the $(SRCARCH) architecture)) $(Q)$(MAKE) $(hdr-inst)=include - $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/asm $(hdr-dst) + $(Q)$(MAKE) $(hdr-inst)=$(hdr-dir) $(hdr-dst) PHONY += headers_check_all headers_check_all: headers_install_all @@ -1063,7 +1107,7 @@ headers_check_all: headers_install_all PHONY += headers_check headers_check: headers_install $(Q)$(MAKE) $(hdr-inst)=include HDRCHECK=1 - $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/asm $(hdr-dst) HDRCHECK=1 + $(Q)$(MAKE) $(hdr-inst)=$(hdr-dir) $(hdr-dst) HDRCHECK=1 # --------------------------------------------------------------------------- # Modules @@ -1083,7 +1127,6 @@ all: modules PHONY += modules modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order - $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.builtin) > $(objtree)/modules.builtin @$(kecho) ' Building modules, stage 2.'; $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild @@ -1113,7 +1156,6 @@ _modinst_: ln -s $(objtree) $(MODLIB)/build ; \ fi @cp -f $(objtree)/modules.order $(MODLIB)/ - @cp -f $(objtree)/modules.builtin $(MODLIB)/ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst # This depmod is only for convenience to give the initial @@ -1152,10 +1194,12 @@ CLEAN_FILES += vmlinux System.map \ .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map # Directories & files removed with 'make mrproper' -MRPROPER_DIRS += include/config usr/include include/generated -MRPROPER_FILES += .config .config.old .version .old_version \ - include/linux/version.h \ - Module.symvers tags TAGS cscope* +MRPROPER_DIRS += include/config include2 usr/include include/generated +MRPROPER_FILES += .config .config.old include/asm .version .old_version \ + include/linux/autoconf.h include/linux/version.h \ + include/linux/utsrelease.h \ + include/linux/bounds.h include/asm*/asm-offsets.h \ + Module.symvers Module.markers tags TAGS cscope* # clean - Delete most, but leave enough to build external modules # @@ -1174,7 +1218,7 @@ clean: archclean $(clean-dirs) \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '*.symtypes' -o -name 'modules.order' \ - -o -name modules.builtin -o -name '.tmp_*.o.*' \ + -o -name 'Module.markers' -o -name '.tmp_*.o.*' \ -o -name '*.gcno' \) -type f -print | xargs rm -f # mrproper - Delete all generated files, including .config @@ -1372,8 +1416,8 @@ $(clean-dirs): clean: rm-dirs := $(MODVERDIR) clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers \ - $(KBUILD_EXTMOD)/modules.order \ - $(KBUILD_EXTMOD)/modules.builtin + $(KBUILD_EXTMOD)/Module.markers \ + $(KBUILD_EXTMOD)/modules.order clean: $(clean-dirs) $(call cmd,rmdirs) $(call cmd,rmfiles) diff --git a/trunk/arch/alpha/boot/bootp.c b/trunk/arch/alpha/boot/bootp.c index 3c8d1b25c661..3af21c789339 100644 --- a/trunk/arch/alpha/boot/bootp.c +++ b/trunk/arch/alpha/boot/bootp.c @@ -9,7 +9,7 @@ */ #include #include -#include +#include #include #include diff --git a/trunk/arch/alpha/boot/bootpz.c b/trunk/arch/alpha/boot/bootpz.c index ade3f129dc27..1036b515e20c 100644 --- a/trunk/arch/alpha/boot/bootpz.c +++ b/trunk/arch/alpha/boot/bootpz.c @@ -11,7 +11,7 @@ */ #include #include -#include +#include #include #include diff --git a/trunk/arch/alpha/boot/main.c b/trunk/arch/alpha/boot/main.c index 644b7db55438..89f3be071ae5 100644 --- a/trunk/arch/alpha/boot/main.c +++ b/trunk/arch/alpha/boot/main.c @@ -7,7 +7,7 @@ */ #include #include -#include +#include #include #include diff --git a/trunk/arch/alpha/include/asm/asm-offsets.h b/trunk/arch/alpha/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/alpha/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/alpha/include/asm/fcntl.h b/trunk/arch/alpha/include/asm/fcntl.h index 70145cbb21cb..21b1117a0c61 100644 --- a/trunk/arch/alpha/include/asm/fcntl.h +++ b/trunk/arch/alpha/include/asm/fcntl.h @@ -16,7 +16,7 @@ #define O_NOATIME 04000000 #define O_CLOEXEC 010000000 /* set close_on_exec */ /* - * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using + * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using * the O_SYNC flag. We continue to use the existing numerical value * for O_DSYNC semantics now, but using the correct symbolic name for it. * This new value is used to request true Posix O_SYNC semantics. It is diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index e9da08483b3c..fa0cdab2e1d3 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -242,8 +242,15 @@ all: $(KBUILD_IMAGE) boot := arch/arm/boot -archprepare: - $(Q)$(MAKE) $(build)=arch/arm/tools include/generated/mach-types.h +# Update machine arch and proc symlinks if something which affects +# them changed. We use .arch to indicate when they were updated +# last, otherwise make uses the target directory mtime. + +archprepare: maketools + +PHONY += maketools FORCE +maketools: include/linux/version.h FORCE + $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h # Convert bzImage to zImage bzImage: zImage @@ -254,6 +261,9 @@ zImage Image xipImage bootpImage uImage: vmlinux zinstall install: vmlinux $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ +CLEAN_FILES += include/asm-arm/mach-types.h \ + include/asm-arm/arch include/asm-arm/.arch + # We use MRPROPER_FILES and CLEAN_FILES now archclean: $(Q)$(MAKE) $(clean)=$(boot) diff --git a/trunk/arch/arm/common/dmabounce.c b/trunk/arch/arm/common/dmabounce.c index bc90364a96c7..5a375e5fef21 100644 --- a/trunk/arch/arm/common/dmabounce.c +++ b/trunk/arch/arm/common/dmabounce.c @@ -308,11 +308,15 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr, memcpy(ptr, buf->safe, size); /* - * Since we may have written to a page cache page, - * we need to ensure that the data will be coherent - * with user mappings. + * DMA buffers must have the same cache properties + * as if they were really used for DMA - which means + * data must be written back to RAM. Note that + * we don't use dmac_flush_range() here for the + * bidirectional case because we know the cache + * lines will be coherent with the data written. */ - __cpuc_flush_kernel_dcache_area(ptr, size); + dmac_clean_range(ptr, ptr + size); + outer_clean_range(__pa(ptr), __pa(ptr) + size); } free_safe_buffer(dev->archdata.dmabounce, buf); } diff --git a/trunk/arch/arm/include/asm/asm-offsets.h b/trunk/arch/arm/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/arm/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/arm/include/asm/cacheflush.h b/trunk/arch/arm/include/asm/cacheflush.h index 730aefcfbee3..73eceb87e588 100644 --- a/trunk/arch/arm/include/asm/cacheflush.h +++ b/trunk/arch/arm/include/asm/cacheflush.h @@ -211,7 +211,7 @@ struct cpu_cache_fns { void (*coherent_kern_range)(unsigned long, unsigned long); void (*coherent_user_range)(unsigned long, unsigned long); - void (*flush_kern_dcache_area)(void *, size_t); + void (*flush_kern_dcache_page)(void *); void (*dma_inv_range)(const void *, const void *); void (*dma_clean_range)(const void *, const void *); @@ -236,7 +236,7 @@ extern struct cpu_cache_fns cpu_cache; #define __cpuc_flush_user_range cpu_cache.flush_user_range #define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range #define __cpuc_coherent_user_range cpu_cache.coherent_user_range -#define __cpuc_flush_dcache_area cpu_cache.flush_kern_dcache_area +#define __cpuc_flush_dcache_page cpu_cache.flush_kern_dcache_page /* * These are private to the dma-mapping API. Do not use directly. @@ -255,14 +255,14 @@ extern struct cpu_cache_fns cpu_cache; #define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range) #define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range) #define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range) -#define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area) +#define __cpuc_flush_dcache_page __glue(_CACHE,_flush_kern_dcache_page) extern void __cpuc_flush_kern_all(void); extern void __cpuc_flush_user_all(void); extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); extern void __cpuc_coherent_kern_range(unsigned long, unsigned long); extern void __cpuc_coherent_user_range(unsigned long, unsigned long); -extern void __cpuc_flush_dcache_area(void *, size_t); +extern void __cpuc_flush_dcache_page(void *); /* * These are private to the dma-mapping API. Do not use directly. @@ -448,7 +448,7 @@ static inline void flush_kernel_dcache_page(struct page *page) { /* highmem pages are always flushed upon kunmap already */ if ((cache_is_vivt() || cache_is_vipt_aliasing()) && !PageHighMem(page)) - __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); + __cpuc_flush_dcache_page(page_address(page)); } #define flush_dcache_mmap_lock(mapping) \ @@ -465,6 +465,13 @@ static inline void flush_kernel_dcache_page(struct page *page) */ #define flush_icache_page(vma,page) do { } while (0) +static inline void flush_ioremap_region(unsigned long phys, void __iomem *virt, + unsigned offset, size_t size) +{ + const void *start = (void __force *)virt + offset; + dmac_inv_range(start, start + size); +} + /* * flush_cache_vmap() is used when creating mappings (eg, via vmap, * vmalloc, ioremap etc) in kernel space for pages. On non-VIPT diff --git a/trunk/arch/arm/include/asm/mach-types.h b/trunk/arch/arm/include/asm/mach-types.h deleted file mode 100644 index 948178cc6ba8..000000000000 --- a/trunk/arch/arm/include/asm/mach-types.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/arm/mach-kirkwood/Kconfig b/trunk/arch/arm/mach-kirkwood/Kconfig index f6c6196a51fa..8bf09ae5b347 100644 --- a/trunk/arch/arm/mach-kirkwood/Kconfig +++ b/trunk/arch/arm/mach-kirkwood/Kconfig @@ -52,12 +52,6 @@ config MACH_OPENRD_BASE Say 'Y' here if you want your kernel to support the Marvell OpenRD Base Board. -config MACH_NETSPACE_V2 - bool "LaCie Network Space v2 NAS Board" - help - Say 'Y' here if you want your kernel to support the - LaCie Network Space v2 NAS. - endmenu endif diff --git a/trunk/arch/arm/mach-kirkwood/Makefile b/trunk/arch/arm/mach-kirkwood/Makefile index d4d7f53b0fb9..9f2f67b2b63d 100644 --- a/trunk/arch/arm/mach-kirkwood/Makefile +++ b/trunk/arch/arm/mach-kirkwood/Makefile @@ -8,6 +8,5 @@ obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o obj-$(CONFIG_MACH_OPENRD_BASE) += openrd_base-setup.o -obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o diff --git a/trunk/arch/arm/mach-kirkwood/netspace_v2-setup.c b/trunk/arch/arm/mach-kirkwood/netspace_v2-setup.c deleted file mode 100644 index 9a064065bebe..000000000000 --- a/trunk/arch/arm/mach-kirkwood/netspace_v2-setup.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * arch/arm/mach-kirkwood/netspace_v2-setup.c - * - * LaCie Network Space v2 board setup - * - * Copyright (C) 2009 Simon Guinot - * Copyright (C) 2009 Benoît Canet - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "mpp.h" - -/***************************************************************************** - * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005) - ****************************************************************************/ - -static struct mtd_partition netspace_v2_flash_parts[] = { - { - .name = "u-boot", - .size = MTDPART_SIZ_FULL, - .offset = 0, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, -}; - -static const struct flash_platform_data netspace_v2_flash = { - .type = "mx25l4005a", - .name = "spi_flash", - .parts = netspace_v2_flash_parts, - .nr_parts = ARRAY_SIZE(netspace_v2_flash_parts), -}; - -static struct spi_board_info __initdata netspace_v2_spi_slave_info[] = { - { - .modalias = "m25p80", - .platform_data = &netspace_v2_flash, - .irq = -1, - .max_speed_hz = 20000000, - .bus_num = 0, - .chip_select = 0, - }, -}; - -/***************************************************************************** - * Ethernet - ****************************************************************************/ - -static struct mv643xx_eth_platform_data netspace_v2_ge00_data = { - .phy_addr = MV643XX_ETH_PHY_ADDR(8), -}; - -/***************************************************************************** - * I2C devices - ****************************************************************************/ - -static struct at24_platform_data at24c04 = { - .byte_len = SZ_4K / 8, - .page_size = 16, -}; - -/* - * i2c addr | chip | description - * 0x50 | HT24LC04 | eeprom (512B) - */ - -static struct i2c_board_info __initdata netspace_v2_i2c_info[] = { - { - I2C_BOARD_INFO("24c04", 0x50), - .platform_data = &at24c04, - } -}; - -/***************************************************************************** - * SATA - ****************************************************************************/ - -static struct mv_sata_platform_data netspace_v2_sata_data = { - .n_ports = 2, -}; - -#define NETSPACE_V2_GPIO_SATA0_POWER 16 -#define NETSPACE_V2_GPIO_SATA1_POWER 17 - -static void __init netspace_v2_sata_power_init(void) -{ - int err; - - err = gpio_request(NETSPACE_V2_GPIO_SATA0_POWER, "SATA0 power"); - if (err == 0) { - err = gpio_direction_output(NETSPACE_V2_GPIO_SATA0_POWER, 1); - if (err) - gpio_free(NETSPACE_V2_GPIO_SATA0_POWER); - } - if (err) - pr_err("netspace_v2: failed to setup SATA0 power\n"); -} - -/***************************************************************************** - * GPIO keys - ****************************************************************************/ - -#define NETSPACE_V2_PUSH_BUTTON 32 - -static struct gpio_keys_button netspace_v2_buttons[] = { - [0] = { - .code = KEY_POWER, - .gpio = NETSPACE_V2_PUSH_BUTTON, - .desc = "Power push button", - .active_low = 0, - }, -}; - -static struct gpio_keys_platform_data netspace_v2_button_data = { - .buttons = netspace_v2_buttons, - .nbuttons = ARRAY_SIZE(netspace_v2_buttons), -}; - -static struct platform_device netspace_v2_gpio_buttons = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = &netspace_v2_button_data, - }, -}; - -/***************************************************************************** - * GPIO LEDs - ****************************************************************************/ - -/* - * The blue front LED is wired to a CPLD and can blink in relation with the - * SATA activity. - * - * The following array detail the different LED registers and the combination - * of their possible values: - * - * cmd_led | slow_led | /SATA active | LED state - * | | | - * 1 | 0 | x | off - * - | 1 | x | on - * 0 | 0 | 1 | on - * 0 | 0 | 0 | blink (rate 300ms) - */ - -#define NETSPACE_V2_GPIO_RED_LED 12 -#define NETSPACE_V2_GPIO_BLUE_LED_SLOW 29 -#define NETSPACE_V2_GPIO_BLUE_LED_CMD 30 - - -static struct gpio_led netspace_v2_gpio_led_pins[] = { - { - .name = "ns_v2:red:fail", - .gpio = NETSPACE_V2_GPIO_RED_LED, - }, -}; - -static struct gpio_led_platform_data netspace_v2_gpio_leds_data = { - .num_leds = ARRAY_SIZE(netspace_v2_gpio_led_pins), - .leds = netspace_v2_gpio_led_pins, -}; - -static struct platform_device netspace_v2_gpio_leds = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = &netspace_v2_gpio_leds_data, - }, -}; - -static void __init netspace_v2_gpio_leds_init(void) -{ - platform_device_register(&netspace_v2_gpio_leds); - - /* - * Configure the front blue LED to blink in relation with the SATA - * activity. - */ - if (gpio_request(NETSPACE_V2_GPIO_BLUE_LED_SLOW, - "SATA blue LED slow") != 0) - return; - if (gpio_direction_output(NETSPACE_V2_GPIO_BLUE_LED_SLOW, 0) != 0) - goto err_free_1; - if (gpio_request(NETSPACE_V2_GPIO_BLUE_LED_CMD, - "SATA blue LED command") != 0) - goto err_free_1; - if (gpio_direction_output(NETSPACE_V2_GPIO_BLUE_LED_CMD, 0) != 0) - goto err_free_2; - - return; - -err_free_2: - gpio_free(NETSPACE_V2_GPIO_BLUE_LED_CMD); -err_free_1: - gpio_free(NETSPACE_V2_GPIO_BLUE_LED_SLOW); - pr_err("netspace_v2: failed to configure SATA blue LED\n"); -} - -/***************************************************************************** - * Timer - ****************************************************************************/ - -static void netspace_v2_timer_init(void) -{ - kirkwood_tclk = 166666667; - orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); -} - -struct sys_timer netspace_v2_timer = { - .init = netspace_v2_timer_init, -}; - -/***************************************************************************** - * General Setup - ****************************************************************************/ - -static unsigned int netspace_v2_mpp_config[] __initdata = { - MPP0_SPI_SCn, - MPP1_SPI_MOSI, - MPP2_SPI_SCK, - MPP3_SPI_MISO, - MPP4_NF_IO6, - MPP5_NF_IO7, - MPP6_SYSRST_OUTn, - MPP8_TW_SDA, - MPP9_TW_SCK, - MPP10_UART0_TXD, - MPP11_UART0_RXD, - MPP12_GPO, /* Red led */ - MPP14_GPIO, /* USB fuse */ - MPP16_GPIO, /* SATA 0 power */ - MPP18_NF_IO0, - MPP19_NF_IO1, - MPP20_SATA1_ACTn, - MPP21_SATA0_ACTn, - MPP24_GPIO, /* USB mode select */ - MPP25_GPIO, /* Fan rotation fail */ - MPP26_GPIO, /* USB device vbus */ - MPP28_GPIO, /* USB enable host vbus */ - MPP29_GPIO, /* Blue led (slow register) */ - MPP30_GPIO, /* Blue led (command register) */ - MPP31_GPIO, /* Board power off */ - MPP32_GPIO, /* Power button (0 = Released, 1 = Pushed) */ - 0 -}; - -#define NETSPACE_V2_GPIO_POWER_OFF 31 - -static void netspace_v2_power_off(void) -{ - gpio_set_value(NETSPACE_V2_GPIO_POWER_OFF, 1); -} - -static void __init netspace_v2_init(void) -{ - /* - * Basic setup. Needs to be called early. - */ - kirkwood_init(); - kirkwood_mpp_conf(netspace_v2_mpp_config); - - netspace_v2_sata_power_init(); - - kirkwood_ehci_init(); - kirkwood_ge00_init(&netspace_v2_ge00_data); - kirkwood_sata_init(&netspace_v2_sata_data); - kirkwood_uart0_init(); - spi_register_board_info(netspace_v2_spi_slave_info, - ARRAY_SIZE(netspace_v2_spi_slave_info)); - kirkwood_spi_init(); - kirkwood_i2c_init(); - i2c_register_board_info(0, netspace_v2_i2c_info, - ARRAY_SIZE(netspace_v2_i2c_info)); - - netspace_v2_gpio_leds_init(); - platform_device_register(&netspace_v2_gpio_buttons); - - if (gpio_request(NETSPACE_V2_GPIO_POWER_OFF, "power-off") == 0 && - gpio_direction_output(NETSPACE_V2_GPIO_POWER_OFF, 0) == 0) - pm_power_off = netspace_v2_power_off; - else - pr_err("netspace_v2: failed to configure power-off GPIO\n"); -} - -MACHINE_START(NETSPACE_V2, "LaCie Network Space v2") - .phys_io = KIRKWOOD_REGS_PHYS_BASE, - .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, - .boot_params = 0x00000100, - .init_machine = netspace_v2_init, - .map_io = kirkwood_map_io, - .init_irq = kirkwood_init_irq, - .timer = &netspace_v2_timer, -MACHINE_END diff --git a/trunk/arch/arm/mach-pxa/Kconfig b/trunk/arch/arm/mach-pxa/Kconfig index 8a0837ea0294..e6d8e10ae5d1 100644 --- a/trunk/arch/arm/mach-pxa/Kconfig +++ b/trunk/arch/arm/mach-pxa/Kconfig @@ -110,8 +110,6 @@ config MACH_CM_X300 bool "CompuLab CM-X300 modules" select PXA3xx select CPU_PXA300 - select CPU_PXA310 - select HAVE_PWM config ARCH_GUMSTIX bool "Gumstix XScale 255 boards" @@ -242,6 +240,7 @@ config MACH_COLIBRI300 select PXA3xx select CPU_PXA300 select CPU_PXA310 + select HAVE_PWM config MACH_COLIBRI320 bool "Toradex Colibri PXA320" diff --git a/trunk/arch/arm/mach-pxa/devices.c b/trunk/arch/arm/mach-pxa/devices.c index 8e10db148f1b..3395463bb5a6 100644 --- a/trunk/arch/arm/mach-pxa/devices.c +++ b/trunk/arch/arm/mach-pxa/devices.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -13,7 +14,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-s3c2410/include/mach/spi.h b/trunk/arch/arm/mach-s3c2410/include/mach/spi.h index 4d9588373aa5..193b39d654ed 100644 --- a/trunk/arch/arm/mach-s3c2410/include/mach/spi.h +++ b/trunk/arch/arm/mach-s3c2410/include/mach/spi.h @@ -18,8 +18,6 @@ struct s3c2410_spi_info { unsigned int num_cs; /* total chipselects */ int bus_num; /* bus number to use. */ - unsigned int use_fiq:1; /* use fiq */ - void (*gpio_setup)(struct s3c2410_spi_info *spi, int enable); void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); }; diff --git a/trunk/arch/arm/mm/cache-fa.S b/trunk/arch/arm/mm/cache-fa.S index a89444a3c016..b63a8f7b95cf 100644 --- a/trunk/arch/arm/mm/cache-fa.S +++ b/trunk/arch/arm/mm/cache-fa.S @@ -127,16 +127,15 @@ ENTRY(fa_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(kaddr) * * Ensure that the data held in the page kaddr is written back * to the page in question. * - * - addr - kernel address - * - size - size of region + * - kaddr - kernel address (guaranteed to be page aligned) */ -ENTRY(fa_flush_kern_dcache_area) - add r1, r0, r1 +ENTRY(fa_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -214,7 +213,7 @@ ENTRY(fa_cache_fns) .long fa_flush_user_cache_range .long fa_coherent_kern_range .long fa_coherent_user_range - .long fa_flush_kern_dcache_area + .long fa_flush_kern_dcache_page .long fa_dma_inv_range .long fa_dma_clean_range .long fa_dma_flush_range diff --git a/trunk/arch/arm/mm/cache-l2x0.c b/trunk/arch/arm/mm/cache-l2x0.c index cb8fc6573b1b..747f9a9021bb 100644 --- a/trunk/arch/arm/mm/cache-l2x0.c +++ b/trunk/arch/arm/mm/cache-l2x0.c @@ -28,120 +28,69 @@ static void __iomem *l2x0_base; static DEFINE_SPINLOCK(l2x0_lock); -static inline void cache_wait(void __iomem *reg, unsigned long mask) +static inline void sync_writel(unsigned long val, unsigned long reg, + unsigned long complete_mask) { + unsigned long flags; + + spin_lock_irqsave(&l2x0_lock, flags); + writel(val, l2x0_base + reg); /* wait for the operation to complete */ - while (readl(reg) & mask) + while (readl(l2x0_base + reg) & complete_mask) ; + spin_unlock_irqrestore(&l2x0_lock, flags); } static inline void cache_sync(void) { - void __iomem *base = l2x0_base; - writel(0, base + L2X0_CACHE_SYNC); - cache_wait(base + L2X0_CACHE_SYNC, 1); + sync_writel(0, L2X0_CACHE_SYNC, 1); } static inline void l2x0_inv_all(void) { - unsigned long flags; - /* invalidate all ways */ - spin_lock_irqsave(&l2x0_lock, flags); - writel(0xff, l2x0_base + L2X0_INV_WAY); - cache_wait(l2x0_base + L2X0_INV_WAY, 0xff); + sync_writel(0xff, L2X0_INV_WAY, 0xff); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_inv_range(unsigned long start, unsigned long end) { - void __iomem *base = l2x0_base; - unsigned long flags; + unsigned long addr; - spin_lock_irqsave(&l2x0_lock, flags); if (start & (CACHE_LINE_SIZE - 1)) { start &= ~(CACHE_LINE_SIZE - 1); - cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); - writel(start, base + L2X0_CLEAN_INV_LINE_PA); + sync_writel(start, L2X0_CLEAN_INV_LINE_PA, 1); start += CACHE_LINE_SIZE; } if (end & (CACHE_LINE_SIZE - 1)) { end &= ~(CACHE_LINE_SIZE - 1); - cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); - writel(end, base + L2X0_CLEAN_INV_LINE_PA); + sync_writel(end, L2X0_CLEAN_INV_LINE_PA, 1); } - while (start < end) { - unsigned long blk_end = start + min(end - start, 4096UL); - - while (start < blk_end) { - cache_wait(base + L2X0_INV_LINE_PA, 1); - writel(start, base + L2X0_INV_LINE_PA); - start += CACHE_LINE_SIZE; - } - - if (blk_end < end) { - spin_unlock_irqrestore(&l2x0_lock, flags); - spin_lock_irqsave(&l2x0_lock, flags); - } - } - cache_wait(base + L2X0_INV_LINE_PA, 1); + for (addr = start; addr < end; addr += CACHE_LINE_SIZE) + sync_writel(addr, L2X0_INV_LINE_PA, 1); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_clean_range(unsigned long start, unsigned long end) { - void __iomem *base = l2x0_base; - unsigned long flags; + unsigned long addr; - spin_lock_irqsave(&l2x0_lock, flags); start &= ~(CACHE_LINE_SIZE - 1); - while (start < end) { - unsigned long blk_end = start + min(end - start, 4096UL); - - while (start < blk_end) { - cache_wait(base + L2X0_CLEAN_LINE_PA, 1); - writel(start, base + L2X0_CLEAN_LINE_PA); - start += CACHE_LINE_SIZE; - } - - if (blk_end < end) { - spin_unlock_irqrestore(&l2x0_lock, flags); - spin_lock_irqsave(&l2x0_lock, flags); - } - } - cache_wait(base + L2X0_CLEAN_LINE_PA, 1); + for (addr = start; addr < end; addr += CACHE_LINE_SIZE) + sync_writel(addr, L2X0_CLEAN_LINE_PA, 1); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); } static void l2x0_flush_range(unsigned long start, unsigned long end) { - void __iomem *base = l2x0_base; - unsigned long flags; + unsigned long addr; - spin_lock_irqsave(&l2x0_lock, flags); start &= ~(CACHE_LINE_SIZE - 1); - while (start < end) { - unsigned long blk_end = start + min(end - start, 4096UL); - - while (start < blk_end) { - cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); - writel(start, base + L2X0_CLEAN_INV_LINE_PA); - start += CACHE_LINE_SIZE; - } - - if (blk_end < end) { - spin_unlock_irqrestore(&l2x0_lock, flags); - spin_lock_irqsave(&l2x0_lock, flags); - } - } - cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); + for (addr = start; addr < end; addr += CACHE_LINE_SIZE) + sync_writel(addr, L2X0_CLEAN_INV_LINE_PA, 1); cache_sync(); - spin_unlock_irqrestore(&l2x0_lock, flags); } void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) diff --git a/trunk/arch/arm/mm/cache-v3.S b/trunk/arch/arm/mm/cache-v3.S index 2a482731ea36..8a4abebc478a 100644 --- a/trunk/arch/arm/mm/cache-v3.S +++ b/trunk/arch/arm/mm/cache-v3.S @@ -72,15 +72,14 @@ ENTRY(v3_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *page, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - addr - page aligned address */ -ENTRY(v3_flush_kern_dcache_area) +ENTRY(v3_flush_kern_dcache_page) /* FALLTHROUGH */ /* @@ -130,7 +129,7 @@ ENTRY(v3_cache_fns) .long v3_flush_user_cache_range .long v3_coherent_kern_range .long v3_coherent_user_range - .long v3_flush_kern_dcache_area + .long v3_flush_kern_dcache_page .long v3_dma_inv_range .long v3_dma_clean_range .long v3_dma_flush_range diff --git a/trunk/arch/arm/mm/cache-v4.S b/trunk/arch/arm/mm/cache-v4.S index 5c7da3e372e9..3668611cb400 100644 --- a/trunk/arch/arm/mm/cache-v4.S +++ b/trunk/arch/arm/mm/cache-v4.S @@ -82,15 +82,14 @@ ENTRY(v4_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - addr - page aligned address */ -ENTRY(v4_flush_kern_dcache_area) +ENTRY(v4_flush_kern_dcache_page) /* FALLTHROUGH */ /* @@ -142,7 +141,7 @@ ENTRY(v4_cache_fns) .long v4_flush_user_cache_range .long v4_coherent_kern_range .long v4_coherent_user_range - .long v4_flush_kern_dcache_area + .long v4_flush_kern_dcache_page .long v4_dma_inv_range .long v4_dma_clean_range .long v4_dma_flush_range diff --git a/trunk/arch/arm/mm/cache-v4wb.S b/trunk/arch/arm/mm/cache-v4wb.S index 3dbedf1ec0e7..2ebc1b3bf856 100644 --- a/trunk/arch/arm/mm/cache-v4wb.S +++ b/trunk/arch/arm/mm/cache-v4wb.S @@ -114,16 +114,15 @@ ENTRY(v4wb_flush_user_cache_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - addr - page aligned address */ -ENTRY(v4wb_flush_kern_dcache_area) - add r1, r0, r1 +ENTRY(v4wb_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ /* fall through */ /* @@ -225,7 +224,7 @@ ENTRY(v4wb_cache_fns) .long v4wb_flush_user_cache_range .long v4wb_coherent_kern_range .long v4wb_coherent_user_range - .long v4wb_flush_kern_dcache_area + .long v4wb_flush_kern_dcache_page .long v4wb_dma_inv_range .long v4wb_dma_clean_range .long v4wb_dma_flush_range diff --git a/trunk/arch/arm/mm/cache-v4wt.S b/trunk/arch/arm/mm/cache-v4wt.S index b3b7410270b4..c54fa2cc40e6 100644 --- a/trunk/arch/arm/mm/cache-v4wt.S +++ b/trunk/arch/arm/mm/cache-v4wt.S @@ -117,18 +117,17 @@ ENTRY(v4wt_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - addr - page aligned address */ -ENTRY(v4wt_flush_kern_dcache_area) +ENTRY(v4wt_flush_kern_dcache_page) mov r2, #0 mcr p15, 0, r2, c7, c5, 0 @ invalidate I cache - add r1, r0, r1 + add r1, r0, #PAGE_SZ /* fallthrough */ /* @@ -181,7 +180,7 @@ ENTRY(v4wt_cache_fns) .long v4wt_flush_user_cache_range .long v4wt_coherent_kern_range .long v4wt_coherent_user_range - .long v4wt_flush_kern_dcache_area + .long v4wt_flush_kern_dcache_page .long v4wt_dma_inv_range .long v4wt_dma_clean_range .long v4wt_dma_flush_range diff --git a/trunk/arch/arm/mm/cache-v6.S b/trunk/arch/arm/mm/cache-v6.S index 4ba0a24ce6f5..295e25dd6381 100644 --- a/trunk/arch/arm/mm/cache-v6.S +++ b/trunk/arch/arm/mm/cache-v6.S @@ -159,16 +159,15 @@ ENDPROC(v6_coherent_user_range) ENDPROC(v6_coherent_kern_range) /* - * v6_flush_kern_dcache_area(void *addr, size_t size) + * v6_flush_kern_dcache_page(kaddr) * * Ensure that the data held in the page kaddr is written back * to the page in question. * - * - addr - kernel address - * - size - region size + * - kaddr - kernel address (guaranteed to be page aligned) */ -ENTRY(v6_flush_kern_dcache_area) - add r1, r0, r1 +ENTRY(v6_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ 1: #ifdef HARVARD_CACHE mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line @@ -272,7 +271,7 @@ ENTRY(v6_cache_fns) .long v6_flush_user_cache_range .long v6_coherent_kern_range .long v6_coherent_user_range - .long v6_flush_kern_dcache_area + .long v6_flush_kern_dcache_page .long v6_dma_inv_range .long v6_dma_clean_range .long v6_dma_flush_range diff --git a/trunk/arch/arm/mm/cache-v7.S b/trunk/arch/arm/mm/cache-v7.S index 9073db849fb4..e1bd9759617f 100644 --- a/trunk/arch/arm/mm/cache-v7.S +++ b/trunk/arch/arm/mm/cache-v7.S @@ -186,17 +186,16 @@ ENDPROC(v7_coherent_kern_range) ENDPROC(v7_coherent_user_range) /* - * v7_flush_kern_dcache_area(void *addr, size_t size) + * v7_flush_kern_dcache_page(kaddr) * * Ensure that the data held in the page kaddr is written back * to the page in question. * - * - addr - kernel address - * - size - region size + * - kaddr - kernel address (guaranteed to be page aligned) */ -ENTRY(v7_flush_kern_dcache_area) +ENTRY(v7_flush_kern_dcache_page) dcache_line_size r2, r3 - add r1, r0, r1 + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line add r0, r0, r2 @@ -204,7 +203,7 @@ ENTRY(v7_flush_kern_dcache_area) blo 1b dsb mov pc, lr -ENDPROC(v7_flush_kern_dcache_area) +ENDPROC(v7_flush_kern_dcache_page) /* * v7_dma_inv_range(start,end) @@ -280,7 +279,7 @@ ENTRY(v7_cache_fns) .long v7_flush_user_cache_range .long v7_coherent_kern_range .long v7_coherent_user_range - .long v7_flush_kern_dcache_area + .long v7_flush_kern_dcache_page .long v7_dma_inv_range .long v7_dma_clean_range .long v7_dma_flush_range diff --git a/trunk/arch/arm/mm/flush.c b/trunk/arch/arm/mm/flush.c index 6f3a4b7a3b82..329594e760cd 100644 --- a/trunk/arch/arm/mm/flush.c +++ b/trunk/arch/arm/mm/flush.c @@ -131,7 +131,7 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page) */ if (addr) #endif - __cpuc_flush_dcache_area(addr, PAGE_SIZE); + __cpuc_flush_dcache_page(addr); /* * If this is a page cache page, and we have an aliasing VIPT cache, @@ -258,5 +258,5 @@ void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned l * in this mapping of the page. FIXME: this is overkill * since we actually ask for a write-back and invalidate. */ - __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); + __cpuc_flush_dcache_page(page_address(page)); } diff --git a/trunk/arch/arm/mm/highmem.c b/trunk/arch/arm/mm/highmem.c index 2be1ec7c1b41..30f82fb5918c 100644 --- a/trunk/arch/arm/mm/highmem.c +++ b/trunk/arch/arm/mm/highmem.c @@ -79,7 +79,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) unsigned int idx = type + KM_TYPE_NR * smp_processor_id(); if (kvaddr >= (void *)FIXADDR_START) { - __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); + __cpuc_flush_dcache_page((void *)vaddr); #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); set_pte_ext(TOP_PTE(vaddr), __pte(0), 0); diff --git a/trunk/arch/arm/mm/nommu.c b/trunk/arch/arm/mm/nommu.c index 374a8311bc84..900811cc9130 100644 --- a/trunk/arch/arm/mm/nommu.c +++ b/trunk/arch/arm/mm/nommu.c @@ -61,7 +61,7 @@ void setup_mm_for_reboot(char mode) void flush_dcache_page(struct page *page) { - __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); + __cpuc_flush_dcache_page(page_address(page)); } EXPORT_SYMBOL(flush_dcache_page); diff --git a/trunk/arch/arm/mm/proc-arm1020.S b/trunk/arch/arm/mm/proc-arm1020.S index 8012e24282b2..d9fb4b98c49f 100644 --- a/trunk/arch/arm/mm/proc-arm1020.S +++ b/trunk/arch/arm/mm/proc-arm1020.S @@ -231,18 +231,17 @@ ENTRY(arm1020_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - page - page aligned address */ -ENTRY(arm1020_flush_kern_dcache_area) +ENTRY(arm1020_flush_kern_dcache_page) mov ip, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE - add r1, r0, r1 + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry mcr p15, 0, ip, c7, c10, 4 @ drain WB add r0, r0, #CACHE_DLINESIZE @@ -336,7 +335,7 @@ ENTRY(arm1020_cache_fns) .long arm1020_flush_user_cache_range .long arm1020_coherent_kern_range .long arm1020_coherent_user_range - .long arm1020_flush_kern_dcache_area + .long arm1020_flush_kern_dcache_page .long arm1020_dma_inv_range .long arm1020_dma_clean_range .long arm1020_dma_flush_range diff --git a/trunk/arch/arm/mm/proc-arm1020e.S b/trunk/arch/arm/mm/proc-arm1020e.S index 41fe25d234f5..7453b75dcea5 100644 --- a/trunk/arch/arm/mm/proc-arm1020e.S +++ b/trunk/arch/arm/mm/proc-arm1020e.S @@ -225,18 +225,17 @@ ENTRY(arm1020e_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - page - page aligned address */ -ENTRY(arm1020e_flush_kern_dcache_area) +ENTRY(arm1020e_flush_kern_dcache_page) mov ip, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE - add r1, r0, r1 + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -322,7 +321,7 @@ ENTRY(arm1020e_cache_fns) .long arm1020e_flush_user_cache_range .long arm1020e_coherent_kern_range .long arm1020e_coherent_user_range - .long arm1020e_flush_kern_dcache_area + .long arm1020e_flush_kern_dcache_page .long arm1020e_dma_inv_range .long arm1020e_dma_clean_range .long arm1020e_dma_flush_range diff --git a/trunk/arch/arm/mm/proc-arm1022.S b/trunk/arch/arm/mm/proc-arm1022.S index 20a5b1b31a70..8eb72d75a8b6 100644 --- a/trunk/arch/arm/mm/proc-arm1022.S +++ b/trunk/arch/arm/mm/proc-arm1022.S @@ -214,18 +214,17 @@ ENTRY(arm1022_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - page - page aligned address */ -ENTRY(arm1022_flush_kern_dcache_area) +ENTRY(arm1022_flush_kern_dcache_page) mov ip, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE - add r1, r0, r1 + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -311,7 +310,7 @@ ENTRY(arm1022_cache_fns) .long arm1022_flush_user_cache_range .long arm1022_coherent_kern_range .long arm1022_coherent_user_range - .long arm1022_flush_kern_dcache_area + .long arm1022_flush_kern_dcache_page .long arm1022_dma_inv_range .long arm1022_dma_clean_range .long arm1022_dma_flush_range diff --git a/trunk/arch/arm/mm/proc-arm1026.S b/trunk/arch/arm/mm/proc-arm1026.S index 96aedb10fcc4..3b59f0d67139 100644 --- a/trunk/arch/arm/mm/proc-arm1026.S +++ b/trunk/arch/arm/mm/proc-arm1026.S @@ -208,18 +208,17 @@ ENTRY(arm1026_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - page - page aligned address */ -ENTRY(arm1026_flush_kern_dcache_area) +ENTRY(arm1026_flush_kern_dcache_page) mov ip, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE - add r1, r0, r1 + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -305,7 +304,7 @@ ENTRY(arm1026_cache_fns) .long arm1026_flush_user_cache_range .long arm1026_coherent_kern_range .long arm1026_coherent_user_range - .long arm1026_flush_kern_dcache_area + .long arm1026_flush_kern_dcache_page .long arm1026_dma_inv_range .long arm1026_dma_clean_range .long arm1026_dma_flush_range diff --git a/trunk/arch/arm/mm/proc-arm920.S b/trunk/arch/arm/mm/proc-arm920.S index 471669e2d7cb..2b7c197cc58d 100644 --- a/trunk/arch/arm/mm/proc-arm920.S +++ b/trunk/arch/arm/mm/proc-arm920.S @@ -207,16 +207,15 @@ ENTRY(arm920_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - addr - page aligned address */ -ENTRY(arm920_flush_kern_dcache_area) - add r1, r0, r1 +ENTRY(arm920_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -294,7 +293,7 @@ ENTRY(arm920_cache_fns) .long arm920_flush_user_cache_range .long arm920_coherent_kern_range .long arm920_coherent_user_range - .long arm920_flush_kern_dcache_area + .long arm920_flush_kern_dcache_page .long arm920_dma_inv_range .long arm920_dma_clean_range .long arm920_dma_flush_range diff --git a/trunk/arch/arm/mm/proc-arm922.S b/trunk/arch/arm/mm/proc-arm922.S index ee111b00fa41..06a1aa4e3398 100644 --- a/trunk/arch/arm/mm/proc-arm922.S +++ b/trunk/arch/arm/mm/proc-arm922.S @@ -209,16 +209,15 @@ ENTRY(arm922_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - addr - page aligned address */ -ENTRY(arm922_flush_kern_dcache_area) - add r1, r0, r1 +ENTRY(arm922_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -296,7 +295,7 @@ ENTRY(arm922_cache_fns) .long arm922_flush_user_cache_range .long arm922_coherent_kern_range .long arm922_coherent_user_range - .long arm922_flush_kern_dcache_area + .long arm922_flush_kern_dcache_page .long arm922_dma_inv_range .long arm922_dma_clean_range .long arm922_dma_flush_range diff --git a/trunk/arch/arm/mm/proc-arm925.S b/trunk/arch/arm/mm/proc-arm925.S index 8deb5bde58e4..cb53435a85ae 100644 --- a/trunk/arch/arm/mm/proc-arm925.S +++ b/trunk/arch/arm/mm/proc-arm925.S @@ -251,16 +251,15 @@ ENTRY(arm925_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - addr - page aligned address */ -ENTRY(arm925_flush_kern_dcache_area) - add r1, r0, r1 +ENTRY(arm925_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -347,7 +346,7 @@ ENTRY(arm925_cache_fns) .long arm925_flush_user_cache_range .long arm925_coherent_kern_range .long arm925_coherent_user_range - .long arm925_flush_kern_dcache_area + .long arm925_flush_kern_dcache_page .long arm925_dma_inv_range .long arm925_dma_clean_range .long arm925_dma_flush_range diff --git a/trunk/arch/arm/mm/proc-arm926.S b/trunk/arch/arm/mm/proc-arm926.S index 64db6e275a44..1c4848704bb3 100644 --- a/trunk/arch/arm/mm/proc-arm926.S +++ b/trunk/arch/arm/mm/proc-arm926.S @@ -214,16 +214,15 @@ ENTRY(arm926_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - addr - page aligned address */ -ENTRY(arm926_flush_kern_dcache_area) - add r1, r0, r1 +ENTRY(arm926_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -310,7 +309,7 @@ ENTRY(arm926_cache_fns) .long arm926_flush_user_cache_range .long arm926_coherent_kern_range .long arm926_coherent_user_range - .long arm926_flush_kern_dcache_area + .long arm926_flush_kern_dcache_page .long arm926_dma_inv_range .long arm926_dma_clean_range .long arm926_dma_flush_range diff --git a/trunk/arch/arm/mm/proc-arm940.S b/trunk/arch/arm/mm/proc-arm940.S index 8196b9f401fb..5b0f8464c8f2 100644 --- a/trunk/arch/arm/mm/proc-arm940.S +++ b/trunk/arch/arm/mm/proc-arm940.S @@ -141,15 +141,14 @@ ENTRY(arm940_coherent_user_range) /* FALLTHROUGH */ /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - addr - page aligned address */ -ENTRY(arm940_flush_kern_dcache_area) +ENTRY(arm940_flush_kern_dcache_page) mov ip, #0 mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments 1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries @@ -239,7 +238,7 @@ ENTRY(arm940_cache_fns) .long arm940_flush_user_cache_range .long arm940_coherent_kern_range .long arm940_coherent_user_range - .long arm940_flush_kern_dcache_area + .long arm940_flush_kern_dcache_page .long arm940_dma_inv_range .long arm940_dma_clean_range .long arm940_dma_flush_range diff --git a/trunk/arch/arm/mm/proc-arm946.S b/trunk/arch/arm/mm/proc-arm946.S index 9a951239c86c..40c0449a139b 100644 --- a/trunk/arch/arm/mm/proc-arm946.S +++ b/trunk/arch/arm/mm/proc-arm946.S @@ -183,17 +183,16 @@ ENTRY(arm946_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - addr - page aligned address * (same as arm926) */ -ENTRY(arm946_flush_kern_dcache_area) - add r1, r0, r1 +ENTRY(arm946_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -281,7 +280,7 @@ ENTRY(arm946_cache_fns) .long arm946_flush_user_cache_range .long arm946_coherent_kern_range .long arm946_coherent_user_range - .long arm946_flush_kern_dcache_area + .long arm946_flush_kern_dcache_page .long arm946_dma_inv_range .long arm946_dma_clean_range .long arm946_dma_flush_range diff --git a/trunk/arch/arm/mm/proc-feroceon.S b/trunk/arch/arm/mm/proc-feroceon.S index dbc39383e66a..d0d7795200fc 100644 --- a/trunk/arch/arm/mm/proc-feroceon.S +++ b/trunk/arch/arm/mm/proc-feroceon.S @@ -226,17 +226,16 @@ ENTRY(feroceon_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - addr - page aligned address */ .align 5 -ENTRY(feroceon_flush_kern_dcache_area) - add r1, r0, r1 +ENTRY(feroceon_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -247,7 +246,7 @@ ENTRY(feroceon_flush_kern_dcache_area) mov pc, lr .align 5 -ENTRY(feroceon_range_flush_kern_dcache_area) +ENTRY(feroceon_range_flush_kern_dcache_page) mrs r2, cpsr add r1, r0, #PAGE_SZ - CACHE_DLINESIZE @ top addr is inclusive orr r3, r2, #PSR_I_BIT @@ -373,7 +372,7 @@ ENTRY(feroceon_cache_fns) .long feroceon_flush_user_cache_range .long feroceon_coherent_kern_range .long feroceon_coherent_user_range - .long feroceon_flush_kern_dcache_area + .long feroceon_flush_kern_dcache_page .long feroceon_dma_inv_range .long feroceon_dma_clean_range .long feroceon_dma_flush_range @@ -384,7 +383,7 @@ ENTRY(feroceon_range_cache_fns) .long feroceon_flush_user_cache_range .long feroceon_coherent_kern_range .long feroceon_coherent_user_range - .long feroceon_range_flush_kern_dcache_area + .long feroceon_range_flush_kern_dcache_page .long feroceon_range_dma_inv_range .long feroceon_range_dma_clean_range .long feroceon_range_dma_flush_range diff --git a/trunk/arch/arm/mm/proc-mohawk.S b/trunk/arch/arm/mm/proc-mohawk.S index 9674d36cc97d..52b5fd74fbb3 100644 --- a/trunk/arch/arm/mm/proc-mohawk.S +++ b/trunk/arch/arm/mm/proc-mohawk.S @@ -186,16 +186,15 @@ ENTRY(mohawk_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - addr - page aligned address */ -ENTRY(mohawk_flush_kern_dcache_area) - add r1, r0, r1 +ENTRY(mohawk_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry add r0, r0, #CACHE_DLINESIZE cmp r0, r1 @@ -274,7 +273,7 @@ ENTRY(mohawk_cache_fns) .long mohawk_flush_user_cache_range .long mohawk_coherent_kern_range .long mohawk_coherent_user_range - .long mohawk_flush_kern_dcache_area + .long mohawk_flush_kern_dcache_page .long mohawk_dma_inv_range .long mohawk_dma_clean_range .long mohawk_dma_flush_range diff --git a/trunk/arch/arm/mm/proc-syms.c b/trunk/arch/arm/mm/proc-syms.c index 3e6210b4d6d4..ac5c80062b70 100644 --- a/trunk/arch/arm/mm/proc-syms.c +++ b/trunk/arch/arm/mm/proc-syms.c @@ -27,7 +27,8 @@ EXPORT_SYMBOL(__cpuc_flush_kern_all); EXPORT_SYMBOL(__cpuc_flush_user_all); EXPORT_SYMBOL(__cpuc_flush_user_range); EXPORT_SYMBOL(__cpuc_coherent_kern_range); -EXPORT_SYMBOL(__cpuc_flush_dcache_area); +EXPORT_SYMBOL(__cpuc_flush_dcache_page); +EXPORT_SYMBOL(dmac_inv_range); /* because of flush_ioremap_region() */ #else EXPORT_SYMBOL(cpu_cache); #endif diff --git a/trunk/arch/arm/mm/proc-v6.S b/trunk/arch/arm/mm/proc-v6.S index 395cc90c6613..5485c821101c 100644 --- a/trunk/arch/arm/mm/proc-v6.S +++ b/trunk/arch/arm/mm/proc-v6.S @@ -254,9 +254,10 @@ __pj4_v6_proc_info: .long 0x560f5810 .long 0xff0ffff0 .long PMD_TYPE_SECT | \ + PMD_SECT_BUFFERABLE | \ + PMD_SECT_CACHEABLE | \ PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ | \ - PMD_FLAGS + PMD_SECT_AP_READ .long PMD_TYPE_SECT | \ PMD_SECT_XN | \ PMD_SECT_AP_WRITE | \ diff --git a/trunk/arch/arm/mm/proc-xsc3.S b/trunk/arch/arm/mm/proc-xsc3.S index 96456f548798..fab134e29826 100644 --- a/trunk/arch/arm/mm/proc-xsc3.S +++ b/trunk/arch/arm/mm/proc-xsc3.S @@ -226,16 +226,15 @@ ENTRY(xsc3_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache. * - * - addr - kernel address - * - size - region size + * - addr - page aligned address */ -ENTRY(xsc3_flush_kern_dcache_area) - add r1, r0, r1 +ENTRY(xsc3_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line add r0, r0, #CACHELINESIZE cmp r0, r1 @@ -310,7 +309,7 @@ ENTRY(xsc3_cache_fns) .long xsc3_flush_user_cache_range .long xsc3_coherent_kern_range .long xsc3_coherent_user_range - .long xsc3_flush_kern_dcache_area + .long xsc3_flush_kern_dcache_page .long xsc3_dma_inv_range .long xsc3_dma_clean_range .long xsc3_dma_flush_range diff --git a/trunk/arch/arm/mm/proc-xscale.S b/trunk/arch/arm/mm/proc-xscale.S index 93df47265f2d..f056c283682d 100644 --- a/trunk/arch/arm/mm/proc-xscale.S +++ b/trunk/arch/arm/mm/proc-xscale.S @@ -284,16 +284,15 @@ ENTRY(xscale_coherent_user_range) mov pc, lr /* - * flush_kern_dcache_area(void *addr, size_t size) + * flush_kern_dcache_page(void *page) * * Ensure no D cache aliasing occurs, either with itself or * the I cache * - * - addr - kernel address - * - size - region size + * - addr - page aligned address */ -ENTRY(xscale_flush_kern_dcache_area) - add r1, r0, r1 +ENTRY(xscale_flush_kern_dcache_page) + add r1, r0, #PAGE_SZ 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry add r0, r0, #CACHELINESIZE @@ -369,7 +368,7 @@ ENTRY(xscale_cache_fns) .long xscale_flush_user_cache_range .long xscale_coherent_kern_range .long xscale_coherent_user_range - .long xscale_flush_kern_dcache_area + .long xscale_flush_kern_dcache_page .long xscale_dma_inv_range .long xscale_dma_clean_range .long xscale_dma_flush_range @@ -393,7 +392,7 @@ ENTRY(xscale_80200_A0_A1_cache_fns) .long xscale_flush_user_cache_range .long xscale_coherent_kern_range .long xscale_coherent_user_range - .long xscale_flush_kern_dcache_area + .long xscale_flush_kern_dcache_page .long xscale_dma_flush_range .long xscale_dma_clean_range .long xscale_dma_flush_range diff --git a/trunk/arch/arm/tools/Makefile b/trunk/arch/arm/tools/Makefile index 635cb1865e4d..1dbaa29ac4d7 100644 --- a/trunk/arch/arm/tools/Makefile +++ b/trunk/arch/arm/tools/Makefile @@ -4,7 +4,7 @@ # Copyright (C) 2001 Russell King # -include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types +include/asm-arm/mach-types.h: $(src)/gen-mach-types $(src)/mach-types @echo ' Generating $@' @mkdir -p $(dir $@) $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } diff --git a/trunk/arch/arm/tools/gen-mach-types b/trunk/arch/arm/tools/gen-mach-types index 04fef71d7be9..ce319ef64bc1 100644 --- a/trunk/arch/arm/tools/gen-mach-types +++ b/trunk/arch/arm/tools/gen-mach-types @@ -1,6 +1,6 @@ #!/bin/awk # -# Awk script to generate include/generated/mach-types.h +# Awk script to generate include/asm-arm/mach-types.h # BEGIN { nr = 0 } /^#/ { next } diff --git a/trunk/arch/arm/tools/mach-types b/trunk/arch/arm/tools/mach-types index c3a74ce24ef6..07b976da6174 100644 --- a/trunk/arch/arm/tools/mach-types +++ b/trunk/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Wed Dec 16 20:06:34 2009 +# Last update: Wed Nov 25 22:14:58 2009 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -1776,7 +1776,6 @@ cybook3 MACH_CYBOOK3 CYBOOK3 1784 wdg002 MACH_WDG002 WDG002 1785 sg560adsl MACH_SG560ADSL SG560ADSL 1786 nextio_n2800_ica MACH_NEXTIO_N2800_ICA NEXTIO_N2800_ICA 1787 -dove_db MACH_DOVE_DB DOVE_DB 1788 marvell_newdb MACH_MARVELL_NEWDB MARVELL_NEWDB 1789 vandihud MACH_VANDIHUD VANDIHUD 1790 magx_e8 MACH_MAGX_E8 MAGX_E8 1791 @@ -2537,44 +2536,3 @@ c3ax03 MACH_C3AX03 C3AX03 2549 mxt_td60 MACH_MXT_TD60 MXT_TD60 2550 esyx MACH_ESYX ESYX 2551 bulldog MACH_BULLDOG BULLDOG 2553 -derell_me2000 MACH_DERELL_ME2000 DERELL_ME2000 2554 -bcmring_base MACH_BCMRING_BASE BCMRING_BASE 2555 -bcmring_evm MACH_BCMRING_EVM BCMRING_EVM 2556 -bcmring_evm_jazz MACH_BCMRING_EVM_JAZZ BCMRING_EVM_JAZZ 2557 -bcmring_sp MACH_BCMRING_SP BCMRING_SP 2558 -bcmring_sv MACH_BCMRING_SV BCMRING_SV 2559 -bcmring_sv_jazz MACH_BCMRING_SV_JAZZ BCMRING_SV_JAZZ 2560 -bcmring_tablet MACH_BCMRING_TABLET BCMRING_TABLET 2561 -bcmring_vp MACH_BCMRING_VP BCMRING_VP 2562 -bcmring_evm_seikor MACH_BCMRING_EVM_SEIKOR BCMRING_EVM_SEIKOR 2563 -bcmring_sp_wqvga MACH_BCMRING_SP_WQVGA BCMRING_SP_WQVGA 2564 -bcmring_custom MACH_BCMRING_CUSTOM BCMRING_CUSTOM 2565 -acer_s200 MACH_ACER_S200 ACER_S200 2566 -bt270 MACH_BT270 BT270 2567 -iseo MACH_ISEO ISEO 2568 -cezanne MACH_CEZANNE CEZANNE 2569 -lucca MACH_LUCCA LUCCA 2570 -supersmart MACH_SUPERSMART SUPERSMART 2571 -magnolia2 MACH_MAGNOLIA2 MAGNOLIA2 2573 -emxx MACH_EMXX EMXX 2574 -outlaw MACH_OUTLAW OUTLAW 2575 -riot_bei2 MACH_RIOT_BEI2 RIOT_BEI2 2576 -riot_vox MACH_RIOT_VOX RIOT_VOX 2577 -riot_x37 MACH_RIOT_X37 RIOT_X37 2578 -mega25mx MACH_MEGA25MX MEGA25MX 2579 -benzina2 MACH_BENZINA2 BENZINA2 2580 -ignite MACH_IGNITE IGNITE 2581 -foggia MACH_FOGGIA FOGGIA 2582 -arezzo MACH_AREZZO AREZZO 2583 -leica_skywalker MACH_LEICA_SKYWALKER LEICA_SKYWALKER 2584 -jacinto2_jamr MACH_JACINTO2_JAMR JACINTO2_JAMR 2585 -gts_nova MACH_GTS_NOVA GTS_NOVA 2586 -p3600 MACH_P3600 P3600 2587 -dlt2 MACH_DLT2 DLT2 2588 -df3120 MACH_DF3120 DF3120 2589 -ecucore_9g20 MACH_ECUCORE_9G20 ECUCORE_9G20 2590 -nautel_lpc3240 MACH_NAUTEL_LPC3240 NAUTEL_LPC3240 2591 -glacier MACH_GLACIER GLACIER 2592 -phrazer_bulldog MACH_PHRAZER_BULLDOG PHRAZER_BULLDOG 2593 -omap3_bulldog MACH_OMAP3_BULLDOG OMAP3_BULLDOG 2594 -pca101 MACH_PCA101 PCA101 2595 diff --git a/trunk/arch/avr32/include/asm/asm-offsets.h b/trunk/arch/avr32/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/avr32/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/blackfin/include/asm/asm-offsets.h b/trunk/arch/blackfin/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/blackfin/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/cris/arch-v32/kernel/head.S b/trunk/arch/cris/arch-v32/kernel/head.S index 76266f80a5f1..3db478eb5155 100644 --- a/trunk/arch/cris/arch-v32/kernel/head.S +++ b/trunk/arch/cris/arch-v32/kernel/head.S @@ -10,6 +10,7 @@ * The macros found in mmu_defs_asm.h uses the ## concatenation operator, so * -traditional must not be used when assembling this file. */ +#include #include #include #include diff --git a/trunk/arch/cris/include/asm/asm-offsets.h b/trunk/arch/cris/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/cris/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/cris/kernel/asm-offsets.c b/trunk/arch/cris/kernel/asm-offsets.c index dd7b8e983221..ddd6fbbe75de 100644 --- a/trunk/arch/cris/kernel/asm-offsets.c +++ b/trunk/arch/cris/kernel/asm-offsets.c @@ -1,5 +1,6 @@ #include #include +#include /* * Generate definitions needed by assembly language modules. diff --git a/trunk/arch/cris/kernel/vmlinux.lds.S b/trunk/arch/cris/kernel/vmlinux.lds.S index d49d17d2a14f..bbfda67d2907 100644 --- a/trunk/arch/cris/kernel/vmlinux.lds.S +++ b/trunk/arch/cris/kernel/vmlinux.lds.S @@ -8,6 +8,7 @@ * the kernel has booted. */ +#include #include #include diff --git a/trunk/arch/frv/include/asm/asm-offsets.h b/trunk/arch/frv/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/frv/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/frv/kernel/setup.c b/trunk/arch/frv/kernel/setup.c index 75cf7f4b2fa8..55e4fab7c0bc 100644 --- a/trunk/arch/frv/kernel/setup.c +++ b/trunk/arch/frv/kernel/setup.c @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. */ -#include +#include #include #include #include diff --git a/trunk/arch/h8300/include/asm/asm-offsets.h b/trunk/arch/h8300/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/h8300/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/ia64/Makefile b/trunk/arch/ia64/Makefile index 475e2725fbde..e7cbaa02cd0b 100644 --- a/trunk/arch/ia64/Makefile +++ b/trunk/arch/ia64/Makefile @@ -103,4 +103,4 @@ archprepare: make_nr_irqs_h FORCE PHONY += make_nr_irqs_h FORCE make_nr_irqs_h: FORCE - $(Q)$(MAKE) $(build)=arch/ia64/kernel include/generated/nr-irqs.h + $(Q)$(MAKE) $(build)=arch/ia64/kernel include/asm-ia64/nr-irqs.h diff --git a/trunk/arch/ia64/include/asm/asm-offsets.h b/trunk/arch/ia64/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/ia64/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/ia64/include/asm/irq.h b/trunk/arch/ia64/include/asm/irq.h index 91b920fd7d53..5282546cdf82 100644 --- a/trunk/arch/ia64/include/asm/irq.h +++ b/trunk/arch/ia64/include/asm/irq.h @@ -13,7 +13,7 @@ #include #include -#include +#include static __inline__ int irq_canonicalize (int irq) diff --git a/trunk/arch/ia64/kernel/Makefile b/trunk/arch/ia64/kernel/Makefile index 2a75e937ae8d..6b7edcab0cb5 100644 --- a/trunk/arch/ia64/kernel/Makefile +++ b/trunk/arch/ia64/kernel/Makefile @@ -81,14 +81,17 @@ define cmd_nr_irqs endef # We use internal kbuild rules to avoid the "is up to date" message from make -arch/$(SRCARCH)/kernel/nr-irqs.s: arch/$(SRCARCH)/kernel/nr-irqs.c +arch/$(SRCARCH)/kernel/nr-irqs.s: $(srctree)/arch/$(SRCARCH)/kernel/nr-irqs.c \ + $(wildcard $(srctree)/include/asm-ia64/*/irq.h) $(Q)mkdir -p $(dir $@) $(call if_changed_dep,cc_s_c) -include/generated/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s +include/asm-ia64/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s $(Q)mkdir -p $(dir $@) $(call cmd,nr_irqs) +clean-files += $(objtree)/include/asm-ia64/nr-irqs.h + # # native ivt.S, entry.S and fsys.S # diff --git a/trunk/arch/ia64/kvm/asm-offsets.c b/trunk/arch/ia64/kvm/asm-offsets.c index 9324c875caf5..0c3564a7a033 100644 --- a/trunk/arch/ia64/kvm/asm-offsets.c +++ b/trunk/arch/ia64/kvm/asm-offsets.c @@ -22,6 +22,7 @@ * */ +#include #include #include diff --git a/trunk/arch/m68k/include/asm/asm-offsets.h b/trunk/arch/m68k/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/m68k/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/m68k/kernel/head.S b/trunk/arch/m68k/kernel/head.S index ef54128baa0b..86edb5fbcfc3 100644 --- a/trunk/arch/m68k/kernel/head.S +++ b/trunk/arch/m68k/kernel/head.S @@ -196,7 +196,7 @@ * for them and trying to understand what they mean. * * CONFIG_xxx: These are the obvious machine configuration defines created - * during configuration. These are defined in autoconf.h. + * during configuration. These are defined in include/linux/autoconf.h. * * CONSOLE: There is support for head.S console in this file. This * console can talk to a Mac frame buffer, but could easily be extrapolated diff --git a/trunk/arch/microblaze/include/asm/asm-offsets.h b/trunk/arch/microblaze/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/microblaze/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index fd7620f025fa..f6f3b990d837 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -22,6 +22,7 @@ choice config MACH_ALCHEMY bool "Alchemy processor based machines" + select SYS_SUPPORTS_ZBOOT config AR7 bool "Texas Instruments AR7" @@ -36,6 +37,7 @@ config AR7 select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_ZBOOT_UART16550 select GENERIC_GPIO select GCD select VLYNQ @@ -192,6 +194,7 @@ config LASAT config MACH_LOONGSON bool "Loongson family of machines" + select SYS_SUPPORTS_ZBOOT_UART16550 help This enables the support of Loongson family of machines. @@ -233,6 +236,7 @@ config MIPS_MALTA select SYS_SUPPORTS_MIPS_CMP select SYS_SUPPORTS_MULTITHREADING select SYS_SUPPORTS_SMARTMIPS + select SYS_SUPPORTS_ZBOOT help This enables support for the MIPS Technologies Malta evaluation board. @@ -1294,6 +1298,16 @@ config CPU_CAVIUM_OCTEON endchoice +config SYS_SUPPORTS_ZBOOT + bool + select HAVE_KERNEL_GZIP + select HAVE_KERNEL_BZIP2 + select HAVE_KERNEL_LZMA + +config SYS_SUPPORTS_ZBOOT_UART16550 + bool + select SYS_SUPPORTS_ZBOOT + config CPU_LOONGSON2 bool select CPU_SUPPORTS_32BIT_KERNEL diff --git a/trunk/arch/mips/Makefile b/trunk/arch/mips/Makefile index 77f5021218d3..ba04782c4b91 100644 --- a/trunk/arch/mips/Makefile +++ b/trunk/arch/mips/Makefile @@ -69,6 +69,7 @@ endif all-$(CONFIG_BOOT_ELF32) := $(vmlinux-32) all-$(CONFIG_BOOT_ELF64) := $(vmlinux-64) +all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlinuz # # GCC uses -G 0 -mabicalls -fpic as default. We don't want PIC in the kernel @@ -331,7 +332,7 @@ load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000 core-$(CONFIG_MIPS_MALTA) += arch/mips/mti-malta/ cflags-$(CONFIG_MIPS_MALTA) += -I$(srctree)/arch/mips/include/asm/mach-malta load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000 -all-$(CONFIG_MIPS_MALTA) := vmlinux.bin +all-$(CONFIG_MIPS_MALTA) := vmlinuz.bin # # MIPS SIM @@ -581,7 +582,7 @@ load-$(CONFIG_SNI_RM) += 0xffffffff80600000 else load-$(CONFIG_SNI_RM) += 0xffffffff80030000 endif -all-$(CONFIG_SNI_RM) := vmlinux.ecoff +all-$(CONFIG_SNI_RM) := vmlinuz.ecoff # # Common TXx9 @@ -699,9 +700,23 @@ vmlinux.64: vmlinux $(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@ makeboot =$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) $(1) +makezboot =$(Q)$(MAKE) $(build)=arch/mips/boot/compressed \ + VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $(1) all: $(all-y) +vmlinuz: vmlinux FORCE + +@$(call makezboot,$@) + +vmlinuz.bin: vmlinux + +@$(call makezboot,$@) + +vmlinuz.ecoff: vmlinux + +@$(call makezboot,$@) + +vmlinuz.srec: vmlinux + +@$(call makezboot,$@) + vmlinux.bin: $(vmlinux-32) +@$(call makeboot,$@) @@ -726,11 +741,13 @@ endif install: $(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE) + $(Q)install -D -m 755 vmlinuz $(INSTALL_PATH)/vmlinuz-$(KERNELRELEASE) $(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE) $(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE) archclean: @$(MAKE) $(clean)=arch/mips/boot + @$(MAKE) $(clean)=arch/mips/boot/compressed @$(MAKE) $(clean)=arch/mips/lasat define archhelp @@ -738,10 +755,18 @@ define archhelp echo ' vmlinux.ecoff - ECOFF boot image' echo ' vmlinux.bin - Raw binary boot image' echo ' vmlinux.srec - SREC boot image' + echo ' vmlinuz - Compressed boot(zboot) image' + echo ' vmlinuz.ecoff - ECOFF zboot image' + echo ' vmlinuz.bin - Raw binary zboot image' + echo ' vmlinuz.srec - SREC zboot image' echo echo ' These will be default as apropriate for a configured platform.' endef CLEAN_FILES += vmlinux.32 \ vmlinux.64 \ - vmlinux.ecoff + vmlinux.ecoff \ + vmlinuz \ + vmlinuz.ecoff \ + vmlinuz.bin \ + vmlinuz.srec diff --git a/trunk/arch/mips/boot/compressed/Makefile b/trunk/arch/mips/boot/compressed/Makefile new file mode 100644 index 000000000000..e27f40bbd4e5 --- /dev/null +++ b/trunk/arch/mips/boot/compressed/Makefile @@ -0,0 +1,100 @@ +# +# This file is subject to the terms and conditions of the GNU General Public +# License. +# +# Adapted for MIPS Pete Popov, Dan Malek +# +# Copyright (C) 1994 by Linus Torvalds +# Adapted for PowerPC by Gary Thomas +# modified by Cort (cort@cs.nmt.edu) +# +# Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University +# Author: Wu Zhangjin +# + +# compressed kernel load addr: VMLINUZ_LOAD_ADDRESS > VMLINUX_LOAD_ADDRESS + VMLINUX_SIZE +VMLINUX_SIZE := $(shell wc -c $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | cut -d' ' -f1) +VMLINUX_SIZE := $(shell [ -n "$(VMLINUX_SIZE)" ] && echo $$(($(VMLINUX_SIZE) + (65536 - $(VMLINUX_SIZE) % 65536)))) +VMLINUZ_LOAD_ADDRESS := 0x$(shell [ -n "$(VMLINUX_SIZE)" ] && printf %x $$(($(VMLINUX_LOAD_ADDRESS) + $(VMLINUX_SIZE)))) + +# set the default size of the mallocing area for decompressing +BOOT_HEAP_SIZE := 0x400000 + +# Disable Function Tracer +KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//") + +KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \ + -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" \ + +KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ + -DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ ) \ + -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) + +obj-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o + +obj-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o + +OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S +$(obj)/vmlinux.bin: $(KBUILD_IMAGE) + $(call if_changed,objcopy) + +suffix_$(CONFIG_KERNEL_GZIP) = gz +suffix_$(CONFIG_KERNEL_BZIP2) = bz2 +suffix_$(CONFIG_KERNEL_LZMA) = lzma +tool_$(CONFIG_KERNEL_GZIP) = gzip +tool_$(CONFIG_KERNEL_BZIP2) = bzip2 +tool_$(CONFIG_KERNEL_LZMA) = lzma +$(obj)/vmlinux.$(suffix_y): $(obj)/vmlinux.bin + $(call if_changed,$(tool_y)) + +$(obj)/piggy.o: $(obj)/vmlinux.$(suffix_y) $(obj)/dummy.o + $(Q)$(OBJCOPY) $(OBJCOPYFLAGS) \ + --add-section=.image=$< \ + --set-section-flags=.image=contents,alloc,load,readonly,data \ + $(obj)/dummy.o $@ + +LDFLAGS_vmlinuz := $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T +vmlinuz: $(src)/ld.script $(obj-y) $(obj)/piggy.o + $(call if_changed,ld) + $(Q)$(OBJCOPY) $(OBJCOPYFLAGS) -R .comment -R .stab -R .stabstr -R .initrd -R .sysmap $@ + +# +# Some DECstations need all possible sections of an ECOFF executable +# +ifdef CONFIG_MACH_DECSTATION + E2EFLAGS = -a +else + E2EFLAGS = +endif + +# elf2ecoff can only handle 32bit image + +ifdef CONFIG_32BIT + VMLINUZ = vmlinuz +else + VMLINUZ = vmlinuz.32 +endif + +vmlinuz.32: vmlinuz + $(Q)$(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@ + +vmlinuz.ecoff: $(obj)/../elf2ecoff $(VMLINUZ) + $(Q)$(obj)/../elf2ecoff $(VMLINUZ) vmlinuz.ecoff $(E2EFLAGS) + +$(obj)/../elf2ecoff: $(src)/../elf2ecoff.c + $(Q)$(HOSTCC) -o $@ $^ + +drop-sections = .reginfo .mdebug .comment .note .pdr .options .MIPS.options +strip-flags = $(addprefix --remove-section=,$(drop-sections)) + +OBJCOPYFLAGS_vmlinuz.bin := $(OBJCOPYFLAGS) -O binary $(strip-flags) +vmlinuz.bin: vmlinuz + $(call if_changed,objcopy) + +OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFLAGS) -S -O srec $(strip-flags) +vmlinuz.srec: vmlinuz + $(call if_changed,objcopy) + +clean: +clean-files += *.o \ + vmlinu* diff --git a/trunk/arch/mips/boot/compressed/dbg.c b/trunk/arch/mips/boot/compressed/dbg.c new file mode 100644 index 000000000000..ff4dc7a33a9f --- /dev/null +++ b/trunk/arch/mips/boot/compressed/dbg.c @@ -0,0 +1,37 @@ +/* + * MIPS-specific debug support for pre-boot environment + * + * NOTE: putc() is board specific, if your board have a 16550 compatible uart, + * please select SYS_SUPPORTS_ZBOOT_UART16550 for your machine. othewise, you + * need to implement your own putc(). + */ + +#include +#include + +void __attribute__ ((weak)) putc(char c) +{ +} + +void puts(const char *s) +{ + char c; + while ((c = *s++) != '\0') { + putc(c); + if (c == '\n') + putc('\r'); + } +} + +void puthex(unsigned long long val) +{ + + unsigned char buf[10]; + int i; + for (i = 7; i >= 0; i--) { + buf[i] = "0123456789ABCDEF"[val & 0x0F]; + val >>= 4; + } + buf[8] = '\0'; + puts(buf); +} diff --git a/trunk/arch/mips/boot/compressed/decompress.c b/trunk/arch/mips/boot/compressed/decompress.c new file mode 100644 index 000000000000..67330c2f7318 --- /dev/null +++ b/trunk/arch/mips/boot/compressed/decompress.c @@ -0,0 +1,126 @@ +/* + * Misc. bootloader code for many machines. + * + * Copyright 2001 MontaVista Software Inc. + * Author: Matt Porter Derived from + * arch/ppc/boot/prep/misc.c + * + * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology + * Author: Wu Zhangjin + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include + +#include + +/* These two variables specify the free mem region + * that can be used for temporary malloc area + */ +unsigned long free_mem_ptr; +unsigned long free_mem_end_ptr; +char *zimage_start; + +/* The linker tells us where the image is. */ +extern unsigned char __image_begin, __image_end; +extern unsigned char __ramdisk_begin, __ramdisk_end; +unsigned long initrd_size; + +/* debug interfaces */ +extern void puts(const char *s); +extern void puthex(unsigned long long val); + +void error(char *x) +{ + puts("\n\n"); + puts(x); + puts("\n\n -- System halted"); + + while (1) + ; /* Halt */ +} + +/* activate the code for pre-boot environment */ +#define STATIC static + +#ifdef CONFIG_KERNEL_GZIP +void *memcpy(void *dest, const void *src, size_t n) +{ + int i; + const char *s = src; + char *d = dest; + + for (i = 0; i < n; i++) + d[i] = s[i]; + return dest; +} +#include "../../../../lib/decompress_inflate.c" +#endif + +#ifdef CONFIG_KERNEL_BZIP2 +void *memset(void *s, int c, size_t n) +{ + int i; + char *ss = s; + + for (i = 0; i < n; i++) + ss[i] = c; + return s; +} +#include "../../../../lib/decompress_bunzip2.c" +#endif + +#ifdef CONFIG_KERNEL_LZMA +#include "../../../../lib/decompress_unlzma.c" +#endif + +void decompress_kernel(unsigned long boot_heap_start) +{ + int zimage_size; + + /* + * We link ourself to an arbitrary low address. When we run, we + * relocate outself to that address. __image_beign points to + * the part of the image where the zImage is. -- Tom + */ + zimage_start = (char *)(unsigned long)(&__image_begin); + zimage_size = (unsigned long)(&__image_end) - + (unsigned long)(&__image_begin); + + /* + * The zImage and initrd will be between start and _end, so they've + * already been moved once. We're good to go now. -- Tom + */ + puts("zimage at: "); + puthex((unsigned long)zimage_start); + puts(" "); + puthex((unsigned long)(zimage_size + zimage_start)); + puts("\n"); + + if (initrd_size) { + puts("initrd at: "); + puthex((unsigned long)(&__ramdisk_begin)); + puts(" "); + puthex((unsigned long)(&__ramdisk_end)); + puts("\n"); + } + + /* this area are prepared for mallocing when decompressing */ + free_mem_ptr = boot_heap_start; + free_mem_end_ptr = boot_heap_start + BOOT_HEAP_SIZE; + + /* Display standard Linux/MIPS boot prompt for kernel args */ + puts("Uncompressing Linux at load address "); + puthex(VMLINUX_LOAD_ADDRESS_ULL); + puts("\n"); + /* Decompress the kernel with according algorithm */ + decompress(zimage_start, zimage_size, 0, 0, + (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, error); + /* FIXME: is there a need to flush cache here? */ + puts("Now, booting the kernel...\n"); +} diff --git a/trunk/arch/mips/boot/compressed/dummy.c b/trunk/arch/mips/boot/compressed/dummy.c new file mode 100644 index 000000000000..31dbf45bf99c --- /dev/null +++ b/trunk/arch/mips/boot/compressed/dummy.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/trunk/arch/mips/boot/compressed/head.S b/trunk/arch/mips/boot/compressed/head.S new file mode 100644 index 000000000000..4e65a8420bee --- /dev/null +++ b/trunk/arch/mips/boot/compressed/head.S @@ -0,0 +1,56 @@ +/* + * 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 (C) 1994, 1995 Waldorf Electronics + * Written by Ralf Baechle and Andreas Busse + * Copyright (C) 1995 - 1999 Ralf Baechle + * Copyright (C) 1996 Paul M. Antoine + * Modified for DECStation and hence R3000 support by Paul M. Antoine + * Further modifications by David S. Miller and Harald Koerfgen + * Copyright (C) 1999 Silicon Graphics, Inc. + */ + +#include +#include + + .set noreorder + .cprestore + LEAF(start) +start: + /* Save boot rom start args */ + move s0, a0 + move s1, a1 + move s2, a2 + move s3, a3 + + /* Clear BSS */ + PTR_LA a0, _edata + PTR_LA a2, _end +1: sw zero, 0(a0) + bne a2, a0, 1b + addiu a0, a0, 4 + + PTR_LA a0, (.heap) /* heap address */ + PTR_LA sp, (.stack + 8192) /* stack address */ + + PTR_LA ra, 2f + PTR_LA k0, decompress_kernel + jr k0 + nop +2: + move a0, s0 + move a1, s1 + move a2, s2 + move a3, s3 + PTR_LI k0, KERNEL_ENTRY + jr k0 + nop +3: + b 3b + nop + END(start) + + .comm .heap,BOOT_HEAP_SIZE,4 + .comm .stack,4096*2,4 diff --git a/trunk/arch/mips/boot/compressed/ld.script b/trunk/arch/mips/boot/compressed/ld.script new file mode 100644 index 000000000000..29e9f4c0d5d8 --- /dev/null +++ b/trunk/arch/mips/boot/compressed/ld.script @@ -0,0 +1,150 @@ +OUTPUT_ARCH(mips) +ENTRY(start) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + .init : { *(.init) } =0 + .text : + { + _ftext = . ; + *(.text) + *(.rodata) + *(.rodata1) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + .kstrtab : { *(.kstrtab) } + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + __start___dbe_table = .; /* Exception table for data bus errors */ + __dbe_table : { *(__dbe_table) } + __stop___dbe_table = .; + + __start___ksymtab = .; /* Kernel symbol table */ + __ksymtab : { *(__ksymtab) } + __stop___ksymtab = .; + + _etext = .; + + . = ALIGN(8192); + .data.init_task : { *(.data.init_task) } + + /* Startup code */ + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(16); + __setup_start = .; + .setup.init : { *(.setup.init) } + __setup_end = .; + __initcall_start = .; + .initcall.init : { *(.initcall.init) } + __initcall_end = .; + . = ALIGN(4096); /* Align double page for init_task_union */ + __init_end = .; + + . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + .fini : { *(.fini) } =0 + .reginfo : { *(.reginfo) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. It would + be more correct to do this: + . = .; + The current expression does not correctly handle the case of a + text segment ending precisely at the end of a page; it causes the + data segment to skip a page. The above expression does not have + this problem, but it will currently (2/95) cause BFD to allocate + a single segment, combining both text and data, for this case. + This will prevent the text segment from being shared among + multiple executions of the program; I think that is more + important than losing a page of the virtual address space (note + that no actual memory is lost; the page which is skipped can not + be referenced). */ + . = .; + .data : + { + _fdata = . ; + *(.data) + + /* Put the compressed image here, so bss is on the end. */ + __image_begin = .; + *(.image) + __image_end = .; + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __ramdisk_begin = .; + *(.initrd) + __ramdisk_end = .; + . = ALIGN(4096); + + CONSTRUCTORS + } + .data1 : { *(.data1) } + _gp = . + 0x8000; + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + . = ALIGN(4); + _edata = .; + PROVIDE (edata = .); + + __bss_start = .; + _fbss = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + . = ALIGN(4); + _end = . ; + PROVIDE (end = .); + } + + /* Sections to be discarded */ + /DISCARD/ : + { + *(.text.exit) + *(.data.exit) + *(.exitcall.exit) + } + + /* This is the MIPS specific mdebug section. */ + .mdebug : { *(.mdebug) } + /* These are needed for ELF backends which have not yet been + converted to the new style linker. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the .debug DWARF section are relative to the beginning of the + section so we begin .debug at 0. It's not clear yet what needs to happen + for the others. */ + .debug 0 : { *(.debug) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .line 0 : { *(.line) } + /* These must appear regardless of . */ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } + .comment : { *(.comment) } + .note : { *(.note) } +} diff --git a/trunk/arch/mips/boot/compressed/uart-16550.c b/trunk/arch/mips/boot/compressed/uart-16550.c new file mode 100644 index 000000000000..c9caaf4fbf60 --- /dev/null +++ b/trunk/arch/mips/boot/compressed/uart-16550.c @@ -0,0 +1,43 @@ +/* + * 16550 compatible uart based serial debug support for zboot + */ + +#include +#include +#include + +#include + +#if defined(CONFIG_MACH_LOONGSON) || defined(CONFIG_MIPS_MALTA) +#define UART_BASE 0x1fd003f8 +#define PORT(offset) (CKSEG1ADDR(UART_BASE) + (offset)) +#endif + +#ifdef CONFIG_AR7 +#include +#define PORT(offset) (CKSEG1ADDR(AR7_REGS_UART0) + (4 * offset)) +#endif + +#ifndef PORT +#error please define the serial port address for your own machine +#endif + +static inline unsigned int serial_in(int offset) +{ + return *((char *)PORT(offset)); +} + +static inline void serial_out(int offset, int value) +{ + *((char *)PORT(offset)) = value; +} + +void putc(char c) +{ + int timeout = 1024; + + while (((serial_in(UART_LSR) & UART_LSR_THRE) == 0) && (timeout-- > 0)) + ; + + serial_out(UART_TX, c); +} diff --git a/trunk/arch/mips/include/asm/asm-offsets.h b/trunk/arch/mips/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/mips/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/mips/include/asm/fcntl.h b/trunk/arch/mips/include/asm/fcntl.h index e482fe90fe88..7c6681aa2ab8 100644 --- a/trunk/arch/mips/include/asm/fcntl.h +++ b/trunk/arch/mips/include/asm/fcntl.h @@ -19,7 +19,7 @@ #define FASYNC 0x1000 /* fcntl, for BSD compatibility */ #define O_LARGEFILE 0x2000 /* allow large file opens */ /* - * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using + * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using * the O_SYNC flag. We continue to use the existing numerical value * for O_DSYNC semantics now, but using the correct symbolic name for it. * This new value is used to request true Posix O_SYNC semantics. It is diff --git a/trunk/arch/mn10300/include/asm/asm-offsets.h b/trunk/arch/mn10300/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/mn10300/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/parisc/include/asm/asm-offsets.h b/trunk/arch/parisc/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/parisc/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/powerpc/include/asm/asm-offsets.h b/trunk/arch/powerpc/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/powerpc/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/powerpc/platforms/52xx/efika.c b/trunk/arch/powerpc/platforms/52xx/efika.c index 45c0cb9b67e6..bcc69e1f77c1 100644 --- a/trunk/arch/powerpc/platforms/52xx/efika.c +++ b/trunk/arch/powerpc/platforms/52xx/efika.c @@ -10,7 +10,7 @@ */ #include -#include +#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/amigaone/setup.c b/trunk/arch/powerpc/platforms/amigaone/setup.c index fb4eb0df054c..9290a7a442d0 100644 --- a/trunk/arch/powerpc/platforms/amigaone/setup.c +++ b/trunk/arch/powerpc/platforms/amigaone/setup.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include diff --git a/trunk/arch/powerpc/platforms/cell/spufs/Makefile b/trunk/arch/powerpc/platforms/cell/spufs/Makefile index b9d5d678aa44..b93f877ba504 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/Makefile +++ b/trunk/arch/powerpc/platforms/cell/spufs/Makefile @@ -13,8 +13,10 @@ SPU_CC := $(SPU_CROSS)gcc SPU_AS := $(SPU_CROSS)gcc SPU_LD := $(SPU_CROSS)ld SPU_OBJCOPY := $(SPU_CROSS)objcopy -SPU_CFLAGS := -O2 -Wall -I$(srctree)/include -D__KERNEL__ -SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include -D__KERNEL__ +SPU_CFLAGS := -O2 -Wall -I$(srctree)/include \ + -I$(objtree)/include2 -D__KERNEL__ +SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include \ + -I$(objtree)/include2 -D__KERNEL__ SPU_LDFLAGS := -N -Ttext=0x0 $(obj)/switch.o: $(obj)/spu_save_dump.h $(obj)/spu_restore_dump.h diff --git a/trunk/arch/powerpc/platforms/chrp/setup.c b/trunk/arch/powerpc/platforms/chrp/setup.c index 8f41685d8f42..52f3df3b4ca0 100644 --- a/trunk/arch/powerpc/platforms/chrp/setup.c +++ b/trunk/arch/powerpc/platforms/chrp/setup.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/powermac/bootx_init.c b/trunk/arch/powerpc/platforms/powermac/bootx_init.c index 9dd789a7370d..cf660916ae0b 100644 --- a/trunk/arch/powerpc/platforms/powermac/bootx_init.c +++ b/trunk/arch/powerpc/platforms/powermac/bootx_init.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/arch/s390/include/asm/asm-offsets.h b/trunk/arch/s390/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/s390/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/score/include/asm/asm-offsets.h b/trunk/arch/score/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/score/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/score/include/asm/cacheflush.h b/trunk/arch/score/include/asm/cacheflush.h index 1d545d0ce206..caaba24036e3 100644 --- a/trunk/arch/score/include/asm/cacheflush.h +++ b/trunk/arch/score/include/asm/cacheflush.h @@ -14,12 +14,10 @@ extern void flush_cache_sigtramp(unsigned long addr); extern void flush_icache_all(void); extern void flush_icache_range(unsigned long start, unsigned long end); extern void flush_dcache_range(unsigned long start, unsigned long end); -extern void flush_dcache_page(struct page *page); - -#define PG_dcache_dirty PG_arch_1 #define flush_cache_dup_mm(mm) do {} while (0) #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 +#define flush_dcache_page(page) do {} while (0) #define flush_dcache_mmap_lock(mapping) do {} while (0) #define flush_dcache_mmap_unlock(mapping) do {} while (0) #define flush_cache_vmap(start, end) do {} while (0) diff --git a/trunk/arch/score/include/asm/delay.h b/trunk/arch/score/include/asm/delay.h index 529e494712a5..6726ec199dc0 100644 --- a/trunk/arch/score/include/asm/delay.h +++ b/trunk/arch/score/include/asm/delay.h @@ -1,8 +1,6 @@ #ifndef _ASM_SCORE_DELAY_H #define _ASM_SCORE_DELAY_H -#include - static inline void __delay(unsigned long loops) { /* 3 cycles per loop. */ diff --git a/trunk/arch/score/include/asm/page.h b/trunk/arch/score/include/asm/page.h index 1e9ade8e77e6..d92a5a2d36d4 100644 --- a/trunk/arch/score/include/asm/page.h +++ b/trunk/arch/score/include/asm/page.h @@ -74,7 +74,7 @@ extern unsigned long max_pfn; #define page_to_bus(page) (page_to_phys(page)) #define phys_to_page(paddr) (pfn_to_page(phys_to_pfn(paddr))) -#define pfn_valid(pfn) (((pfn) >= min_low_pfn) && ((pfn) < max_low_pfn)) +#define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_mapnr) #define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT) diff --git a/trunk/arch/score/kernel/setup.c b/trunk/arch/score/kernel/setup.c index 6f898c057878..6a2503c75c4e 100644 --- a/trunk/arch/score/kernel/setup.c +++ b/trunk/arch/score/kernel/setup.c @@ -49,7 +49,6 @@ static void __init bootmem_init(void) min_low_pfn = PFN_UP(MEMORY_START); max_low_pfn = PFN_UP(MEMORY_START + MEMORY_SIZE); - max_mapnr = max_low_pfn - min_low_pfn; /* Initialize the boot-time allocator with low memory only. */ bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, diff --git a/trunk/arch/score/mm/cache.c b/trunk/arch/score/mm/cache.c index b25e95743600..dbac9d9dfddd 100644 --- a/trunk/arch/score/mm/cache.c +++ b/trunk/arch/score/mm/cache.c @@ -29,7 +29,6 @@ #include #include #include -#include #include @@ -52,27 +51,6 @@ static void flush_data_cache_page(unsigned long addr) } } -void flush_dcache_page(struct page *page) -{ - struct address_space *mapping = page_mapping(page); - unsigned long addr; - - if (PageHighMem(page)) - return; - if (mapping && !mapping_mapped(mapping)) { - set_bit(PG_dcache_dirty, &(page)->flags); - return; - } - - /* - * We could delay the flush for the !page_mapping case too. But that - * case is for exec env/arg pages and those are %99 certainly going to - * get faulted into the tlb (and thus flushed) anyways. - */ - addr = (unsigned long) page_address(page); - flush_data_cache_page(addr); -} - /* called by update_mmu_cache. */ void __update_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) @@ -85,11 +63,11 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address, if (unlikely(!pfn_valid(pfn))) return; page = pfn_to_page(pfn); - if (page_mapping(page) && test_bit(PG_dcache_dirty, &(page)->flags)) { + if (page_mapping(page) && test_bit(PG_arch_1, &page->flags)) { addr = (unsigned long) page_address(page); if (exec) flush_data_cache_page(addr); - clear_bit(PG_dcache_dirty, &(page)->flags); + clear_bit(PG_arch_1, &page->flags); } } diff --git a/trunk/arch/score/mm/init.c b/trunk/arch/score/mm/init.c index 8c15b2c85d5a..4e3dcd0c4716 100644 --- a/trunk/arch/score/mm/init.c +++ b/trunk/arch/score/mm/init.c @@ -83,6 +83,7 @@ void __init mem_init(void) unsigned long codesize, reservedpages, datasize, initsize; unsigned long tmp, ram = 0; + max_mapnr = max_low_pfn; high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); totalram_pages += free_all_bootmem(); totalram_pages -= setup_zero_page(); /* Setup zeroed pages. */ @@ -100,6 +101,10 @@ void __init mem_init(void) datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; + kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); + kclist_add(&kcore_vmalloc, (void *) VMALLOC_START, + VMALLOC_END - VMALLOC_START); + printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, " "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), diff --git a/trunk/arch/sh/Makefile b/trunk/arch/sh/Makefile index db91925c79d1..ac17c5ac550e 100644 --- a/trunk/arch/sh/Makefile +++ b/trunk/arch/sh/Makefile @@ -205,7 +205,10 @@ libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec uImage.bin \ zImage vmlinux.srec romImage -PHONY += $(BOOT_TARGETS) +PHONY += maketools $(BOOT_TARGETS) FORCE + +maketools: include/linux/version.h FORCE + $(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h all: $(KBUILD_IMAGE) @@ -214,8 +217,7 @@ $(BOOT_TARGETS): vmlinux compressed: zImage -archprepare: - $(Q)$(MAKE) $(build)=arch/sh/tools include/generated/machtypes.h +archprepare: maketools archclean: $(Q)$(MAKE) $(clean)=$(boot) @@ -232,3 +234,5 @@ define archhelp @echo ' uImage.bz2 - Kernel-only image for U-Boot (bzip2)' @echo ' uImage.lzma - Kernel-only image for U-Boot (lzma)' endef + +CLEAN_FILES += include/asm-sh/machtypes.h diff --git a/trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c b/trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c index 7898f14d6641..052b354236dc 100644 --- a/trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -15,7 +15,7 @@ #include #include #include "pci-sh4.h" -#include +#include #define PCIMCR_MRSET_OFF 0xBFFFFFFF #define PCIMCR_RFSH_OFF 0xFFFFFFFB diff --git a/trunk/arch/sh/include/asm/.gitignore b/trunk/arch/sh/include/asm/.gitignore new file mode 100644 index 000000000000..378db779fb6c --- /dev/null +++ b/trunk/arch/sh/include/asm/.gitignore @@ -0,0 +1 @@ +machtypes.h diff --git a/trunk/arch/sh/include/asm/asm-offsets.h b/trunk/arch/sh/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/sh/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/sh/include/asm/machvec.h b/trunk/arch/sh/include/asm/machvec.h index 9c30955630ff..84dd37761f56 100644 --- a/trunk/arch/sh/include/asm/machvec.h +++ b/trunk/arch/sh/include/asm/machvec.h @@ -12,7 +12,7 @@ #include #include -#include +#include struct sh_machine_vector { void (*mv_setup)(char **cmdline_p); diff --git a/trunk/arch/sh/tools/Makefile b/trunk/arch/sh/tools/Makefile index 558a56bcc7cf..567516b58acc 100644 --- a/trunk/arch/sh/tools/Makefile +++ b/trunk/arch/sh/tools/Makefile @@ -10,7 +10,7 @@ # Shamelessly cloned from ARM. # -include/generated/machtypes.h: $(src)/gen-mach-types $(src)/mach-types +include/asm-sh/machtypes.h: $(src)/gen-mach-types $(src)/mach-types @echo ' Generating $@' - $(Q)mkdir -p $(dir $@) + $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } diff --git a/trunk/arch/sh/tools/gen-mach-types b/trunk/arch/sh/tools/gen-mach-types index f5ff7c5d8913..65161e368353 100644 --- a/trunk/arch/sh/tools/gen-mach-types +++ b/trunk/arch/sh/tools/gen-mach-types @@ -1,6 +1,6 @@ #!/bin/awk # -# Awk script to generate include/generated/machtypes.h +# Awk script to generate include/asm-sh/machtypes.h # Heavily based on arch/arm/tools/gen-mach-types # BEGIN { nr = 0 } diff --git a/trunk/arch/sparc/include/asm/asm-offsets.h b/trunk/arch/sparc/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/sparc/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/sparc/include/asm/fcntl.h b/trunk/arch/sparc/include/asm/fcntl.h index 38f37b333cc7..3b9cfb39175e 100644 --- a/trunk/arch/sparc/include/asm/fcntl.h +++ b/trunk/arch/sparc/include/asm/fcntl.h @@ -19,7 +19,7 @@ #define O_NOATIME 0x200000 #define O_CLOEXEC 0x400000 /* - * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using + * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using * the O_SYNC flag. We continue to use the existing numerical value * for O_DSYNC semantics now, but using the correct symbolic name for it. * This new value is used to request true Posix O_SYNC semantics. It is diff --git a/trunk/arch/um/Makefile b/trunk/arch/um/Makefile index fab8121d2b32..fc633dbacf84 100644 --- a/trunk/arch/um/Makefile +++ b/trunk/arch/um/Makefile @@ -149,6 +149,6 @@ $(SHARED_HEADERS)/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s $(SHARED_HEADERS)/kern_constants.h: $(Q)mkdir -p $(dir $@) - $(Q)echo '#include "../../../../include/generated/asm-offsets.h"' >$@ + $(Q)echo '#include "../../../../include/asm/asm-offsets.h"' >$@ export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH DEV_NULL_PATH diff --git a/trunk/arch/um/include/asm/asm-offsets.h b/trunk/arch/um/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/um/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/x86/boot/header.S b/trunk/arch/x86/boot/header.S index 93e689f4bd86..b31cc54b4641 100644 --- a/trunk/arch/x86/boot/header.S +++ b/trunk/arch/x86/boot/header.S @@ -16,7 +16,7 @@ */ #include -#include +#include #include #include #include diff --git a/trunk/arch/x86/boot/version.c b/trunk/arch/x86/boot/version.c index 2b15aa488ffb..2723d9b5ce43 100644 --- a/trunk/arch/x86/boot/version.c +++ b/trunk/arch/x86/boot/version.c @@ -13,8 +13,8 @@ */ #include "boot.h" -#include -#include +#include +#include const char kernel_version[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") " diff --git a/trunk/arch/x86/include/asm/asm-offsets.h b/trunk/arch/x86/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/x86/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/arch/x86/kernel/ptrace.c b/trunk/arch/x86/kernel/ptrace.c index 017d937639fe..2779321046bd 100644 --- a/trunk/arch/x86/kernel/ptrace.c +++ b/trunk/arch/x86/kernel/ptrace.c @@ -509,14 +509,14 @@ static int genregs_get(struct task_struct *target, { if (kbuf) { unsigned long *k = kbuf; - while (count >= sizeof(*k)) { + while (count > 0) { *k++ = getreg(target, pos); count -= sizeof(*k); pos += sizeof(*k); } } else { unsigned long __user *u = ubuf; - while (count >= sizeof(*u)) { + while (count > 0) { if (__put_user(getreg(target, pos), u++)) return -EFAULT; count -= sizeof(*u); @@ -535,14 +535,14 @@ static int genregs_set(struct task_struct *target, int ret = 0; if (kbuf) { const unsigned long *k = kbuf; - while (count >= sizeof(*k) && !ret) { + while (count > 0 && !ret) { ret = putreg(target, pos, *k++); count -= sizeof(*k); pos += sizeof(*k); } } else { const unsigned long __user *u = ubuf; - while (count >= sizeof(*u) && !ret) { + while (count > 0 && !ret) { unsigned long word; ret = __get_user(word, u++); if (ret) @@ -1458,14 +1458,14 @@ static int genregs32_get(struct task_struct *target, { if (kbuf) { compat_ulong_t *k = kbuf; - while (count >= sizeof(*k)) { + while (count > 0) { getreg32(target, pos, k++); count -= sizeof(*k); pos += sizeof(*k); } } else { compat_ulong_t __user *u = ubuf; - while (count >= sizeof(*u)) { + while (count > 0) { compat_ulong_t word; getreg32(target, pos, &word); if (__put_user(word, u++)) @@ -1486,14 +1486,14 @@ static int genregs32_set(struct task_struct *target, int ret = 0; if (kbuf) { const compat_ulong_t *k = kbuf; - while (count >= sizeof(*k) && !ret) { + while (count > 0 && !ret) { ret = putreg32(target, pos, *k++); count -= sizeof(*k); pos += sizeof(*k); } } else { const compat_ulong_t __user *u = ubuf; - while (count >= sizeof(*u) && !ret) { + while (count > 0 && !ret) { compat_ulong_t word; ret = __get_user(word, u++); if (ret) diff --git a/trunk/arch/xtensa/include/asm/asm-offsets.h b/trunk/arch/xtensa/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/trunk/arch/xtensa/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/drivers/accessibility/braille/braille_console.c b/trunk/drivers/accessibility/braille/braille_console.c index cb423f5aef24..d672cfe7ca59 100644 --- a/trunk/drivers/accessibility/braille/braille_console.c +++ b/trunk/drivers/accessibility/braille/braille_console.c @@ -21,6 +21,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include diff --git a/trunk/drivers/hid/hid-lg.h b/trunk/drivers/hid/hid-lg.h index bf31592eaf79..27ae750ca878 100644 --- a/trunk/drivers/hid/hid-lg.h +++ b/trunk/drivers/hid/hid-lg.h @@ -1,6 +1,8 @@ #ifndef __HID_LG_H #define __HID_LG_H +#include + #ifdef CONFIG_LOGITECH_FF int lgff_init(struct hid_device *hdev); #else diff --git a/trunk/drivers/hwmon/Kconfig b/trunk/drivers/hwmon/Kconfig index bf28945c610d..95ccbe377f9c 100644 --- a/trunk/drivers/hwmon/Kconfig +++ b/trunk/drivers/hwmon/Kconfig @@ -998,23 +998,6 @@ config SENSORS_LIS3_SPI will be called lis3lv02d and a specific module for the SPI transport is called lis3lv02d_spi. -config SENSORS_LIS3_I2C - tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (I2C)" - depends on I2C && INPUT - select INPUT_POLLDEV - default n - help - This driver provides support for the LIS3LV02Dx accelerometer connected - via I2C. The accelerometer data is readable via - /sys/devices/platform/lis3lv02d. - - This driver also provides an absolute input class device, allowing - the device to act as a pinball machine-esque joystick. - - This driver can also be built as modules. If so, the core module - will be called lis3lv02d and a specific module for the I2C transport - is called lis3lv02d_i2c. - config SENSORS_APPLESMC tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" depends on INPUT && X86 diff --git a/trunk/drivers/hwmon/Makefile b/trunk/drivers/hwmon/Makefile index 4131e253f96a..33c2ee105284 100644 --- a/trunk/drivers/hwmon/Makefile +++ b/trunk/drivers/hwmon/Makefile @@ -55,7 +55,6 @@ obj-$(CONFIG_SENSORS_IT87) += it87.o obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d.o lis3lv02d_spi.o -obj-$(CONFIG_SENSORS_LIS3_I2C) += lis3lv02d.o lis3lv02d_i2c.o obj-$(CONFIG_SENSORS_LM63) += lm63.o obj-$(CONFIG_SENSORS_LM70) += lm70.o obj-$(CONFIG_SENSORS_LM73) += lm73.o diff --git a/trunk/drivers/hwmon/lis3lv02d_i2c.c b/trunk/drivers/hwmon/lis3lv02d_i2c.c deleted file mode 100644 index dc1f5402c1d7..000000000000 --- a/trunk/drivers/hwmon/lis3lv02d_i2c.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * drivers/hwmon/lis3lv02d_i2c.c - * - * Implements I2C interface for lis3lv02d (STMicroelectronics) accelerometer. - * Driver is based on corresponding SPI driver written by Daniel Mack - * (lis3lv02d_spi.c (C) 2009 Daniel Mack ). - * - * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - * - * Contact: Samu Onkalo - * - * 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. - * - * 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include "lis3lv02d.h" - -#define DRV_NAME "lis3lv02d_i2c" - -static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value) -{ - struct i2c_client *c = lis3->bus_priv; - return i2c_smbus_write_byte_data(c, reg, value); -} - -static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v) -{ - struct i2c_client *c = lis3->bus_priv; - *v = i2c_smbus_read_byte_data(c, reg); - return 0; -} - -static int lis3_i2c_init(struct lis3lv02d *lis3) -{ - u8 reg; - int ret; - - /* power up the device */ - ret = lis3->read(lis3, CTRL_REG1, ®); - if (ret < 0) - return ret; - - reg |= CTRL1_PD0; - return lis3->write(lis3, CTRL_REG1, reg); -} - -/* Default axis mapping but it can be overwritten by platform data */ -static struct axis_conversion lis3lv02d_axis_map = { LIS3_DEV_X, - LIS3_DEV_Y, - LIS3_DEV_Z }; - -static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int ret = 0; - struct lis3lv02d_platform_data *pdata = client->dev.platform_data; - - if (pdata) { - if (pdata->axis_x) - lis3lv02d_axis_map.x = pdata->axis_x; - - if (pdata->axis_y) - lis3lv02d_axis_map.y = pdata->axis_y; - - if (pdata->axis_z) - lis3lv02d_axis_map.z = pdata->axis_z; - - if (pdata->setup_resources) - ret = pdata->setup_resources(); - - if (ret) - goto fail; - } - - lis3_dev.pdata = pdata; - lis3_dev.bus_priv = client; - lis3_dev.init = lis3_i2c_init; - lis3_dev.read = lis3_i2c_read; - lis3_dev.write = lis3_i2c_write; - lis3_dev.irq = client->irq; - lis3_dev.ac = lis3lv02d_axis_map; - - i2c_set_clientdata(client, &lis3_dev); - ret = lis3lv02d_init_device(&lis3_dev); -fail: - return ret; -} - -static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client) -{ - struct lis3lv02d *lis3 = i2c_get_clientdata(client); - struct lis3lv02d_platform_data *pdata = client->dev.platform_data; - - if (pdata && pdata->release_resources) - pdata->release_resources(); - - lis3lv02d_joystick_disable(); - lis3lv02d_poweroff(lis3); - - return lis3lv02d_remove_fs(&lis3_dev); -} - -#ifdef CONFIG_PM -static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg) -{ - struct lis3lv02d *lis3 = i2c_get_clientdata(client); - - if (!lis3->pdata->wakeup_flags) - lis3lv02d_poweroff(lis3); - return 0; -} - -static int lis3lv02d_i2c_resume(struct i2c_client *client) -{ - struct lis3lv02d *lis3 = i2c_get_clientdata(client); - - if (!lis3->pdata->wakeup_flags) - lis3lv02d_poweron(lis3); - return 0; -} - -static void lis3lv02d_i2c_shutdown(struct i2c_client *client) -{ - lis3lv02d_i2c_suspend(client, PMSG_SUSPEND); -} -#else -#define lis3lv02d_i2c_suspend NULL -#define lis3lv02d_i2c_resume NULL -#define lis3lv02d_i2c_shutdown NULL -#endif - -static const struct i2c_device_id lis3lv02d_id[] = { - {"lis3lv02d", 0 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, lis3lv02d_id); - -static struct i2c_driver lis3lv02d_i2c_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .suspend = lis3lv02d_i2c_suspend, - .shutdown = lis3lv02d_i2c_shutdown, - .resume = lis3lv02d_i2c_resume, - .probe = lis3lv02d_i2c_probe, - .remove = __devexit_p(lis3lv02d_i2c_remove), - .id_table = lis3lv02d_id, -}; - -static int __init lis3lv02d_init(void) -{ - return i2c_add_driver(&lis3lv02d_i2c_driver); -} - -static void __exit lis3lv02d_exit(void) -{ - i2c_del_driver(&lis3lv02d_i2c_driver); -} - -MODULE_AUTHOR("Nokia Corporation"); -MODULE_DESCRIPTION("lis3lv02d I2C interface"); -MODULE_LICENSE("GPL"); - -module_init(lis3lv02d_init); -module_exit(lis3lv02d_exit); diff --git a/trunk/drivers/leds/Kconfig b/trunk/drivers/leds/Kconfig index 8a0e1ec95e4a..e4f599f20e38 100644 --- a/trunk/drivers/leds/Kconfig +++ b/trunk/drivers/leds/Kconfig @@ -229,12 +229,6 @@ config LEDS_PWM help This option enables support for pwm driven LEDs -config LEDS_REGULATOR - tristate "REGULATOR driven LED support" - depends on LEDS_CLASS && REGULATOR - help - This option enables support for regulator driven LEDs. - config LEDS_BD2802 tristate "LED driver for BD2802 RGB LED" depends on LEDS_CLASS && I2C @@ -242,33 +236,6 @@ config LEDS_BD2802 This option enables support for BD2802GU RGB LED driver chips accessed via the I2C bus. -config LEDS_INTEL_SS4200 - tristate "LED driver for Intel NAS SS4200 series" - depends on LEDS_CLASS && PCI && DMI - help - This option enables support for the Intel SS4200 series of - Network Attached Storage servers. You may control the hard - drive or power LEDs on the front panel. Using this driver - can stop the front LED from blinking after startup. - -config LEDS_LT3593 - tristate "LED driver for LT3593 controllers" - depends on LEDS_CLASS && GENERIC_GPIO - help - This option enables support for LEDs driven by a Linear Technology - LT3593 controller. This controller uses a special one-wire pulse - coding protocol to set the brightness. - -config LEDS_ADP5520 - tristate "LED Support for ADP5520/ADP5501 PMIC" - depends on LEDS_CLASS && PMIC_ADP5520 - help - This option enables support for on-chip LED drivers found - on Analog Devices ADP5520/ADP5501 PMICs. - - To compile this driver as a module, choose M here: the module will - be called leds-adp5520. - comment "LED Triggers" config LEDS_TRIGGERS diff --git a/trunk/drivers/leds/Makefile b/trunk/drivers/leds/Makefile index 9e63869d7c0d..46d72704d606 100644 --- a/trunk/drivers/leds/Makefile +++ b/trunk/drivers/leds/Makefile @@ -29,10 +29,6 @@ obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o obj-$(CONFIG_LEDS_PWM) += leds-pwm.o -obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o -obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o -obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o -obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o # LED SPI Drivers obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o diff --git a/trunk/drivers/leds/leds-adp5520.c b/trunk/drivers/leds/leds-adp5520.c deleted file mode 100644 index a8f315902131..000000000000 --- a/trunk/drivers/leds/leds-adp5520.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * LEDs driver for Analog Devices ADP5520/ADP5501 MFD PMICs - * - * Copyright 2009 Analog Devices Inc. - * - * Loosely derived from leds-da903x: - * Copyright (C) 2008 Compulab, Ltd. - * Mike Rapoport - * - * Copyright (C) 2006-2008 Marvell International Ltd. - * Eric Miao - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include - -struct adp5520_led { - struct led_classdev cdev; - struct work_struct work; - struct device *master; - enum led_brightness new_brightness; - int id; - int flags; -}; - -static void adp5520_led_work(struct work_struct *work) -{ - struct adp5520_led *led = container_of(work, struct adp5520_led, work); - adp5520_write(led->master, ADP5520_LED1_CURRENT + led->id - 1, - led->new_brightness >> 2); -} - -static void adp5520_led_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct adp5520_led *led; - - led = container_of(led_cdev, struct adp5520_led, cdev); - led->new_brightness = value; - schedule_work(&led->work); -} - -static int adp5520_led_setup(struct adp5520_led *led) -{ - struct device *dev = led->master; - int flags = led->flags; - int ret = 0; - - switch (led->id) { - case FLAG_ID_ADP5520_LED1_ADP5501_LED0: - ret |= adp5520_set_bits(dev, ADP5520_LED_TIME, - (flags >> ADP5520_FLAG_OFFT_SHIFT) & - ADP5520_FLAG_OFFT_MASK); - ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL, - ADP5520_LED1_EN); - break; - case FLAG_ID_ADP5520_LED2_ADP5501_LED1: - ret |= adp5520_set_bits(dev, ADP5520_LED_TIME, - ((flags >> ADP5520_FLAG_OFFT_SHIFT) & - ADP5520_FLAG_OFFT_MASK) << 2); - ret |= adp5520_clr_bits(dev, ADP5520_LED_CONTROL, - ADP5520_R3_MODE); - ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL, - ADP5520_LED2_EN); - break; - case FLAG_ID_ADP5520_LED3_ADP5501_LED2: - ret |= adp5520_set_bits(dev, ADP5520_LED_TIME, - ((flags >> ADP5520_FLAG_OFFT_SHIFT) & - ADP5520_FLAG_OFFT_MASK) << 4); - ret |= adp5520_clr_bits(dev, ADP5520_LED_CONTROL, - ADP5520_C3_MODE); - ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL, - ADP5520_LED3_EN); - break; - } - - return ret; -} - -static int __devinit adp5520_led_prepare(struct platform_device *pdev) -{ - struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; - struct device *dev = pdev->dev.parent; - int ret = 0; - - ret |= adp5520_write(dev, ADP5520_LED1_CURRENT, 0); - ret |= adp5520_write(dev, ADP5520_LED2_CURRENT, 0); - ret |= adp5520_write(dev, ADP5520_LED3_CURRENT, 0); - ret |= adp5520_write(dev, ADP5520_LED_TIME, pdata->led_on_time << 6); - ret |= adp5520_write(dev, ADP5520_LED_FADE, FADE_VAL(pdata->fade_in, - pdata->fade_out)); - - return ret; -} - -static int __devinit adp5520_led_probe(struct platform_device *pdev) -{ - struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; - struct adp5520_led *led, *led_dat; - struct led_info *cur_led; - int ret, i; - - if (pdata == NULL) { - dev_err(&pdev->dev, "missing platform data\n"); - return -ENODEV; - } - - if (pdata->num_leds > ADP5520_01_MAXLEDS) { - dev_err(&pdev->dev, "can't handle more than %d LEDS\n", - ADP5520_01_MAXLEDS); - return -EFAULT; - } - - led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL); - if (led == NULL) { - dev_err(&pdev->dev, "failed to alloc memory\n"); - return -ENOMEM; - } - - ret = adp5520_led_prepare(pdev); - - if (ret) { - dev_err(&pdev->dev, "failed to write\n"); - goto err_free; - } - - for (i = 0; i < pdata->num_leds; ++i) { - cur_led = &pdata->leds[i]; - led_dat = &led[i]; - - led_dat->cdev.name = cur_led->name; - led_dat->cdev.default_trigger = cur_led->default_trigger; - led_dat->cdev.brightness_set = adp5520_led_set; - led_dat->cdev.brightness = LED_OFF; - - if (cur_led->flags & ADP5520_FLAG_LED_MASK) - led_dat->flags = cur_led->flags; - else - led_dat->flags = i + 1; - - led_dat->id = led_dat->flags & ADP5520_FLAG_LED_MASK; - - led_dat->master = pdev->dev.parent; - led_dat->new_brightness = LED_OFF; - - INIT_WORK(&led_dat->work, adp5520_led_work); - - ret = led_classdev_register(led_dat->master, &led_dat->cdev); - if (ret) { - dev_err(&pdev->dev, "failed to register LED %d\n", - led_dat->id); - goto err; - } - - ret = adp5520_led_setup(led_dat); - if (ret) { - dev_err(&pdev->dev, "failed to write\n"); - i++; - goto err; - } - } - - platform_set_drvdata(pdev, led); - return 0; - -err: - if (i > 0) { - for (i = i - 1; i >= 0; i--) { - led_classdev_unregister(&led[i].cdev); - cancel_work_sync(&led[i].work); - } - } - -err_free: - kfree(led); - return ret; -} - -static int __devexit adp5520_led_remove(struct platform_device *pdev) -{ - struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; - struct adp5520_led *led; - int i; - - led = platform_get_drvdata(pdev); - - adp5520_clr_bits(led->master, ADP5520_LED_CONTROL, - ADP5520_LED1_EN | ADP5520_LED2_EN | ADP5520_LED3_EN); - - for (i = 0; i < pdata->num_leds; i++) { - led_classdev_unregister(&led[i].cdev); - cancel_work_sync(&led[i].work); - } - - kfree(led); - return 0; -} - -static struct platform_driver adp5520_led_driver = { - .driver = { - .name = "adp5520-led", - .owner = THIS_MODULE, - }, - .probe = adp5520_led_probe, - .remove = __devexit_p(adp5520_led_remove), -}; - -static int __init adp5520_led_init(void) -{ - return platform_driver_register(&adp5520_led_driver); -} -module_init(adp5520_led_init); - -static void __exit adp5520_led_exit(void) -{ - platform_driver_unregister(&adp5520_led_driver); -} -module_exit(adp5520_led_exit); - -MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("LEDS ADP5520(01) Driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:adp5520-led"); diff --git a/trunk/drivers/leds/leds-alix2.c b/trunk/drivers/leds/leds-alix2.c index f59ffadf5125..731d4eef3425 100644 --- a/trunk/drivers/leds/leds-alix2.c +++ b/trunk/drivers/leds/leds-alix2.c @@ -11,24 +11,11 @@ #include #include #include -#include static int force = 0; module_param(force, bool, 0444); MODULE_PARM_DESC(force, "Assume system has ALIX.2/ALIX.3 style LEDs"); -#define MSR_LBAR_GPIO 0x5140000C -#define CS5535_GPIO_SIZE 256 - -static u32 gpio_base; - -static struct pci_device_id divil_pci[] = { - { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, - { } /* NULL entry */ -}; -MODULE_DEVICE_TABLE(pci, divil_pci); - struct alix_led { struct led_classdev cdev; unsigned short port; @@ -43,9 +30,9 @@ static void alix_led_set(struct led_classdev *led_cdev, container_of(led_cdev, struct alix_led, cdev); if (brightness) - outl(led_dev->on_value, gpio_base + led_dev->port); + outl(led_dev->on_value, led_dev->port); else - outl(led_dev->off_value, gpio_base + led_dev->port); + outl(led_dev->off_value, led_dev->port); } static struct alix_led alix_leds[] = { @@ -54,7 +41,7 @@ static struct alix_led alix_leds[] = { .name = "alix:1", .brightness_set = alix_led_set, }, - .port = 0x00, + .port = 0x6100, .on_value = 1 << 22, .off_value = 1 << 6, }, @@ -63,7 +50,7 @@ static struct alix_led alix_leds[] = { .name = "alix:2", .brightness_set = alix_led_set, }, - .port = 0x80, + .port = 0x6180, .on_value = 1 << 25, .off_value = 1 << 9, }, @@ -72,7 +59,7 @@ static struct alix_led alix_leds[] = { .name = "alix:3", .brightness_set = alix_led_set, }, - .port = 0x80, + .port = 0x6180, .on_value = 1 << 27, .off_value = 1 << 11, }, @@ -114,104 +101,64 @@ static struct platform_driver alix_led_driver = { }, }; -static int __init alix_present(unsigned long bios_phys, - const char *alix_sig, - size_t alix_sig_len) +static int __init alix_present(void) { + const unsigned long bios_phys = 0x000f0000; const size_t bios_len = 0x00010000; + const char alix_sig[] = "PC Engines ALIX."; + const size_t alix_sig_len = sizeof(alix_sig) - 1; + const char *bios_virt; const char *scan_end; const char *p; - char name[64]; + int ret = 0; if (force) { printk(KERN_NOTICE "%s: forced to skip BIOS test, " "assume system has ALIX.2 style LEDs\n", KBUILD_MODNAME); - return 1; + ret = 1; + goto out; } bios_virt = phys_to_virt(bios_phys); scan_end = bios_virt + bios_len - (alix_sig_len + 2); for (p = bios_virt; p < scan_end; p++) { const char *tail; - char *a; - if (memcmp(p, alix_sig, alix_sig_len) != 0) + if (memcmp(p, alix_sig, alix_sig_len) != 0) { continue; - - memcpy(name, p, sizeof(name)); - - /* remove the first \0 character from string */ - a = strchr(name, '\0'); - if (a) - *a = ' '; - - /* cut the string at a newline */ - a = strchr(name, '\r'); - if (a) - *a = '\0'; + } tail = p + alix_sig_len; - if ((tail[0] == '2' || tail[0] == '3')) { + if ((tail[0] == '2' || tail[0] == '3') && tail[1] == '\0') { printk(KERN_INFO "%s: system is recognized as \"%s\"\n", - KBUILD_MODNAME, name); - return 1; + KBUILD_MODNAME, p); + ret = 1; + break; } } - return 0; +out: + return ret; } static struct platform_device *pdev; -static int __init alix_pci_led_init(void) -{ - u32 low, hi; - - if (pci_dev_present(divil_pci) == 0) { - printk(KERN_WARNING KBUILD_MODNAME": DIVIL not found\n"); - return -ENODEV; - } - - /* Grab the GPIO I/O range */ - rdmsr(MSR_LBAR_GPIO, low, hi); - - /* Check the mask and whether GPIO is enabled (sanity check) */ - if (hi != 0x0000f001) { - printk(KERN_WARNING KBUILD_MODNAME": GPIO not enabled\n"); - return -ENODEV; - } - - /* Mask off the IO base address */ - gpio_base = low & 0x0000ff00; - - if (!request_region(gpio_base, CS5535_GPIO_SIZE, KBUILD_MODNAME)) { - printk(KERN_ERR KBUILD_MODNAME": can't allocate I/O for GPIO\n"); - return -ENODEV; - } - - /* Set GPIO function to output */ - outl(1 << 6, gpio_base + 0x04); - outl(1 << 9, gpio_base + 0x84); - outl(1 << 11, gpio_base + 0x84); - - return 0; -} - static int __init alix_led_init(void) { - int ret = -ENODEV; - const char tinybios_sig[] = "PC Engines ALIX."; - const char coreboot_sig[] = "PC Engines\0ALIX."; + int ret; - if (alix_present(0xf0000, tinybios_sig, sizeof(tinybios_sig) - 1) || - alix_present(0x500, coreboot_sig, sizeof(coreboot_sig) - 1)) - ret = alix_pci_led_init(); + if (!alix_present()) { + ret = -ENODEV; + goto out; + } - if (ret < 0) - return ret; + /* enable output on GPIO for LED 1,2,3 */ + outl(1 << 6, 0x6104); + outl(1 << 9, 0x6184); + outl(1 << 11, 0x6184); pdev = platform_device_register_simple(KBUILD_MODNAME, -1, NULL, 0); if (!IS_ERR(pdev)) { @@ -221,6 +168,7 @@ static int __init alix_led_init(void) } else ret = PTR_ERR(pdev); +out: return ret; } @@ -228,7 +176,6 @@ static void __exit alix_led_exit(void) { platform_device_unregister(pdev); platform_driver_unregister(&alix_led_driver); - release_region(gpio_base, CS5535_GPIO_SIZE); } module_init(alix_led_init); diff --git a/trunk/drivers/leds/leds-cobalt-qube.c b/trunk/drivers/leds/leds-cobalt-qube.c index da5fb016b1a5..8816806accd2 100644 --- a/trunk/drivers/leds/leds-cobalt-qube.c +++ b/trunk/drivers/leds/leds-cobalt-qube.c @@ -31,7 +31,7 @@ static struct led_classdev qube_front_led = { .name = "qube::front", .brightness = LED_FULL, .brightness_set = qube_front_led_set, - .default_trigger = "default-on", + .default_trigger = "ide-disk", }; static int __devinit cobalt_qube_led_probe(struct platform_device *pdev) @@ -43,7 +43,7 @@ static int __devinit cobalt_qube_led_probe(struct platform_device *pdev) if (!res) return -EBUSY; - led_port = ioremap(res->start, resource_size(res)); + led_port = ioremap(res->start, res->end - res->start + 1); if (!led_port) return -ENOMEM; diff --git a/trunk/drivers/leds/leds-cobalt-raq.c b/trunk/drivers/leds/leds-cobalt-raq.c index 438d48384636..defc212105f3 100644 --- a/trunk/drivers/leds/leds-cobalt-raq.c +++ b/trunk/drivers/leds/leds-cobalt-raq.c @@ -84,7 +84,7 @@ static int __devinit cobalt_raq_led_probe(struct platform_device *pdev) if (!res) return -EBUSY; - led_port = ioremap(res->start, resource_size(res)); + led_port = ioremap(res->start, res->end - res->start + 1); if (!led_port) return -ENOMEM; diff --git a/trunk/drivers/leds/leds-lt3593.c b/trunk/drivers/leds/leds-lt3593.c deleted file mode 100644 index fee40a841959..000000000000 --- a/trunk/drivers/leds/leds-lt3593.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * LEDs driver for LT3593 controllers - * - * See the datasheet at http://cds.linear.com/docs/Datasheet/3593f.pdf - * - * Copyright (c) 2009 Daniel Mack - * - * Based on leds-gpio.c, - * - * Copyright (C) 2007 8D Technologies inc. - * Raphael Assenat - * Copyright (C) 2008 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 -#include -#include -#include -#include -#include -#include - -struct lt3593_led_data { - struct led_classdev cdev; - unsigned gpio; - struct work_struct work; - u8 new_level; -}; - -static void lt3593_led_work(struct work_struct *work) -{ - int pulses; - struct lt3593_led_data *led_dat = - container_of(work, struct lt3593_led_data, work); - - /* - * The LT3593 resets its internal current level register to the maximum - * level on the first falling edge on the control pin. Each following - * falling edge decreases the current level by 625uA. Up to 32 pulses - * can be sent, so the maximum power reduction is 20mA. - * After a timeout of 128us, the value is taken from the register and - * applied is to the output driver. - */ - - if (led_dat->new_level == 0) { - gpio_set_value_cansleep(led_dat->gpio, 0); - return; - } - - pulses = 32 - (led_dat->new_level * 32) / 255; - - if (pulses == 0) { - gpio_set_value_cansleep(led_dat->gpio, 0); - mdelay(1); - gpio_set_value_cansleep(led_dat->gpio, 1); - return; - } - - gpio_set_value_cansleep(led_dat->gpio, 1); - - while (pulses--) { - gpio_set_value_cansleep(led_dat->gpio, 0); - udelay(1); - gpio_set_value_cansleep(led_dat->gpio, 1); - udelay(1); - } -} - -static void lt3593_led_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct lt3593_led_data *led_dat = - container_of(led_cdev, struct lt3593_led_data, cdev); - - led_dat->new_level = value; - schedule_work(&led_dat->work); -} - -static int __devinit create_lt3593_led(const struct gpio_led *template, - struct lt3593_led_data *led_dat, struct device *parent) -{ - int ret, state; - - /* skip leds on GPIOs that aren't available */ - if (!gpio_is_valid(template->gpio)) { - printk(KERN_INFO "%s: skipping unavailable LT3593 LED at gpio %d (%s)\n", - KBUILD_MODNAME, template->gpio, template->name); - return 0; - } - - ret = gpio_request(template->gpio, template->name); - if (ret < 0) - return ret; - - led_dat->cdev.name = template->name; - led_dat->cdev.default_trigger = template->default_trigger; - led_dat->gpio = template->gpio; - - led_dat->cdev.brightness_set = lt3593_led_set; - - state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); - led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; - - if (!template->retain_state_suspended) - led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; - - ret = gpio_direction_output(led_dat->gpio, state); - if (ret < 0) - goto err; - - INIT_WORK(&led_dat->work, lt3593_led_work); - - ret = led_classdev_register(parent, &led_dat->cdev); - if (ret < 0) - goto err; - - printk(KERN_INFO "%s: registered LT3593 LED '%s' at GPIO %d\n", - KBUILD_MODNAME, template->name, template->gpio); - - return 0; - -err: - gpio_free(led_dat->gpio); - return ret; -} - -static void delete_lt3593_led(struct lt3593_led_data *led) -{ - if (!gpio_is_valid(led->gpio)) - return; - - led_classdev_unregister(&led->cdev); - cancel_work_sync(&led->work); - gpio_free(led->gpio); -} - -static int __devinit lt3593_led_probe(struct platform_device *pdev) -{ - struct gpio_led_platform_data *pdata = pdev->dev.platform_data; - struct lt3593_led_data *leds_data; - int i, ret = 0; - - if (!pdata) - return -EBUSY; - - leds_data = kzalloc(sizeof(struct lt3593_led_data) * pdata->num_leds, - GFP_KERNEL); - if (!leds_data) - return -ENOMEM; - - for (i = 0; i < pdata->num_leds; i++) { - ret = create_lt3593_led(&pdata->leds[i], &leds_data[i], - &pdev->dev); - if (ret < 0) - goto err; - } - - platform_set_drvdata(pdev, leds_data); - - return 0; - -err: - for (i = i - 1; i >= 0; i--) - delete_lt3593_led(&leds_data[i]); - - kfree(leds_data); - - return ret; -} - -static int __devexit lt3593_led_remove(struct platform_device *pdev) -{ - int i; - struct gpio_led_platform_data *pdata = pdev->dev.platform_data; - struct lt3593_led_data *leds_data; - - leds_data = platform_get_drvdata(pdev); - - for (i = 0; i < pdata->num_leds; i++) - delete_lt3593_led(&leds_data[i]); - - kfree(leds_data); - - return 0; -} - -static struct platform_driver lt3593_led_driver = { - .probe = lt3593_led_probe, - .remove = __devexit_p(lt3593_led_remove), - .driver = { - .name = "leds-lt3593", - .owner = THIS_MODULE, - }, -}; - -MODULE_ALIAS("platform:leds-lt3593"); - -static int __init lt3593_led_init(void) -{ - return platform_driver_register(<3593_led_driver); -} - -static void __exit lt3593_led_exit(void) -{ - platform_driver_unregister(<3593_led_driver); -} - -module_init(lt3593_led_init); -module_exit(lt3593_led_exit); - -MODULE_AUTHOR("Daniel Mack "); -MODULE_DESCRIPTION("LED driver for LT3593 controllers"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/leds/leds-pwm.c b/trunk/drivers/leds/leds-pwm.c index 88b1dd091cfb..cdfdc8714e10 100644 --- a/trunk/drivers/leds/leds-pwm.c +++ b/trunk/drivers/leds/leds-pwm.c @@ -27,6 +27,7 @@ struct led_pwm_data { struct pwm_device *pwm; unsigned int active_low; unsigned int period; + unsigned int max_brightness; }; static void led_pwm_set(struct led_classdev *led_cdev, @@ -34,7 +35,7 @@ static void led_pwm_set(struct led_classdev *led_cdev, { struct led_pwm_data *led_dat = container_of(led_cdev, struct led_pwm_data, cdev); - unsigned int max = led_dat->cdev.max_brightness; + unsigned int max = led_dat->max_brightness; unsigned int period = led_dat->period; if (brightness == 0) { @@ -76,10 +77,10 @@ static int led_pwm_probe(struct platform_device *pdev) led_dat->cdev.name = cur_led->name; led_dat->cdev.default_trigger = cur_led->default_trigger; led_dat->active_low = cur_led->active_low; + led_dat->max_brightness = cur_led->max_brightness; led_dat->period = cur_led->pwm_period_ns; led_dat->cdev.brightness_set = led_pwm_set; led_dat->cdev.brightness = LED_OFF; - led_dat->cdev.max_brightness = cur_led->max_brightness; led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; ret = led_classdev_register(&pdev->dev, &led_dat->cdev); diff --git a/trunk/drivers/leds/leds-regulator.c b/trunk/drivers/leds/leds-regulator.c deleted file mode 100644 index 7f00de3ef922..000000000000 --- a/trunk/drivers/leds/leds-regulator.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * leds-regulator.c - LED class driver for regulator driven LEDs. - * - * Copyright (C) 2009 Antonio Ospite - * - * Inspired by leds-wm8350 driver. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#define to_regulator_led(led_cdev) \ - container_of(led_cdev, struct regulator_led, cdev) - -struct regulator_led { - struct led_classdev cdev; - enum led_brightness value; - int enabled; - struct mutex mutex; - struct work_struct work; - - struct regulator *vcc; -}; - -static inline int led_regulator_get_max_brightness(struct regulator *supply) -{ - int ret; - int voltage = regulator_list_voltage(supply, 0); - - if (voltage <= 0) - return 1; - - /* even if regulator can't change voltages, - * we still assume it can change status - * and the LED can be turned on and off. - */ - ret = regulator_set_voltage(supply, voltage, voltage); - if (ret < 0) - return 1; - - return regulator_count_voltages(supply); -} - -static int led_regulator_get_voltage(struct regulator *supply, - enum led_brightness brightness) -{ - if (brightness == 0) - return -EINVAL; - - return regulator_list_voltage(supply, brightness - 1); -} - - -static void regulator_led_enable(struct regulator_led *led) -{ - int ret; - - if (led->enabled) - return; - - ret = regulator_enable(led->vcc); - if (ret != 0) { - dev_err(led->cdev.dev, "Failed to enable vcc: %d\n", ret); - return; - } - - led->enabled = 1; -} - -static void regulator_led_disable(struct regulator_led *led) -{ - int ret; - - if (!led->enabled) - return; - - ret = regulator_disable(led->vcc); - if (ret != 0) { - dev_err(led->cdev.dev, "Failed to disable vcc: %d\n", ret); - return; - } - - led->enabled = 0; -} - -static void regulator_led_set_value(struct regulator_led *led) -{ - int voltage; - int ret; - - mutex_lock(&led->mutex); - - if (led->value == LED_OFF) { - regulator_led_disable(led); - goto out; - } - - if (led->cdev.max_brightness > 1) { - voltage = led_regulator_get_voltage(led->vcc, led->value); - dev_dbg(led->cdev.dev, "brightness: %d voltage: %d\n", - led->value, voltage); - - ret = regulator_set_voltage(led->vcc, voltage, voltage); - if (ret != 0) - dev_err(led->cdev.dev, "Failed to set voltage %d: %d\n", - voltage, ret); - } - - regulator_led_enable(led); - -out: - mutex_unlock(&led->mutex); -} - -static void led_work(struct work_struct *work) -{ - struct regulator_led *led; - - led = container_of(work, struct regulator_led, work); - regulator_led_set_value(led); -} - -static void regulator_led_brightness_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct regulator_led *led = to_regulator_led(led_cdev); - - led->value = value; - schedule_work(&led->work); -} - -static int __devinit regulator_led_probe(struct platform_device *pdev) -{ - struct led_regulator_platform_data *pdata = pdev->dev.platform_data; - struct regulator_led *led; - struct regulator *vcc; - int ret = 0; - - if (pdata == NULL) { - dev_err(&pdev->dev, "no platform data\n"); - return -ENODEV; - } - - vcc = regulator_get_exclusive(&pdev->dev, "vled"); - if (IS_ERR(vcc)) { - dev_err(&pdev->dev, "Cannot get vcc for %s\n", pdata->name); - return PTR_ERR(vcc); - } - - led = kzalloc(sizeof(*led), GFP_KERNEL); - if (led == NULL) { - ret = -ENOMEM; - goto err_vcc; - } - - led->cdev.max_brightness = led_regulator_get_max_brightness(vcc); - if (pdata->brightness > led->cdev.max_brightness) { - dev_err(&pdev->dev, "Invalid default brightness %d\n", - pdata->brightness); - ret = -EINVAL; - goto err_led; - } - led->value = pdata->brightness; - - led->cdev.brightness_set = regulator_led_brightness_set; - led->cdev.name = pdata->name; - led->cdev.flags |= LED_CORE_SUSPENDRESUME; - led->vcc = vcc; - - mutex_init(&led->mutex); - INIT_WORK(&led->work, led_work); - - platform_set_drvdata(pdev, led); - - ret = led_classdev_register(&pdev->dev, &led->cdev); - if (ret < 0) { - cancel_work_sync(&led->work); - goto err_led; - } - - /* to expose the default value to userspace */ - led->cdev.brightness = led->value; - - /* Set the default led status */ - regulator_led_set_value(led); - - return 0; - -err_led: - kfree(led); -err_vcc: - regulator_put(vcc); - return ret; -} - -static int __devexit regulator_led_remove(struct platform_device *pdev) -{ - struct regulator_led *led = platform_get_drvdata(pdev); - - led_classdev_unregister(&led->cdev); - cancel_work_sync(&led->work); - regulator_led_disable(led); - regulator_put(led->vcc); - kfree(led); - return 0; -} - -static struct platform_driver regulator_led_driver = { - .driver = { - .name = "leds-regulator", - .owner = THIS_MODULE, - }, - .probe = regulator_led_probe, - .remove = __devexit_p(regulator_led_remove), -}; - -static int __init regulator_led_init(void) -{ - return platform_driver_register(®ulator_led_driver); -} -module_init(regulator_led_init); - -static void __exit regulator_led_exit(void) -{ - platform_driver_unregister(®ulator_led_driver); -} -module_exit(regulator_led_exit); - -MODULE_AUTHOR("Antonio Ospite "); -MODULE_DESCRIPTION("Regulator driven LED driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:leds-regulator"); diff --git a/trunk/drivers/leds/leds-ss4200.c b/trunk/drivers/leds/leds-ss4200.c deleted file mode 100644 index 97f04984c1ca..000000000000 --- a/trunk/drivers/leds/leds-ss4200.c +++ /dev/null @@ -1,556 +0,0 @@ -/* - * SS4200-E Hardware API - * Copyright (c) 2009, Intel Corporation. - * Copyright IBM Corporation, 2009 - * - * 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., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Author: Dave Hansen - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Rodney Girod , Dave Hansen "); -MODULE_DESCRIPTION("Intel NAS/Home Server ICH7 GPIO Driver"); -MODULE_LICENSE("GPL"); - -/* - * ICH7 LPC/GPIO PCI Config register offsets - */ -#define PMBASE 0x040 -#define GPIO_BASE 0x048 -#define GPIO_CTRL 0x04c -#define GPIO_EN 0x010 - -/* - * The ICH7 GPIO register block is 64 bytes in size. - */ -#define ICH7_GPIO_SIZE 64 - -/* - * Define register offsets within the ICH7 register block. - */ -#define GPIO_USE_SEL 0x000 -#define GP_IO_SEL 0x004 -#define GP_LVL 0x00c -#define GPO_BLINK 0x018 -#define GPI_INV 0x030 -#define GPIO_USE_SEL2 0x034 -#define GP_IO_SEL2 0x038 -#define GP_LVL2 0x03c - -/* - * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives. - */ -static struct pci_device_id ich7_lpc_pci_id[] = -{ - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_30) }, - { } /* NULL entry */ -}; - -MODULE_DEVICE_TABLE(pci, ich7_lpc_pci_id); - -static int __init ss4200_led_dmi_callback(const struct dmi_system_id *id) -{ - pr_info("detected '%s'\n", id->ident); - return 1; -} - -static unsigned int __initdata nodetect; -module_param_named(nodetect, nodetect, bool, 0); -MODULE_PARM_DESC(nodetect, "Skip DMI-based hardware detection"); - -/* - * struct nas_led_whitelist - List of known good models - * - * Contains the known good models this driver is compatible with. - * When adding a new model try to be as strict as possible. This - * makes it possible to keep the false positives (the model is - * detected as working, but in reality it is not) as low as - * possible. - */ -static struct dmi_system_id __initdata nas_led_whitelist[] = { - { - .callback = ss4200_led_dmi_callback, - .ident = "Intel SS4200-E", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Intel"), - DMI_MATCH(DMI_PRODUCT_NAME, "SS4200-E"), - DMI_MATCH(DMI_PRODUCT_VERSION, "1.00.00") - } - }, -}; - -/* - * Base I/O address assigned to the Power Management register block - */ -static u32 g_pm_io_base; - -/* - * Base I/O address assigned to the ICH7 GPIO register block - */ -static u32 nas_gpio_io_base; - -/* - * When we successfully register a region, we are returned a resource. - * We use these to identify which regions we need to release on our way - * back out. - */ -static struct resource *gp_gpio_resource; - -struct nasgpio_led { - char *name; - u32 gpio_bit; - struct led_classdev led_cdev; -}; - -/* - * gpio_bit(s) are the ICH7 GPIO bit assignments - */ -static struct nasgpio_led nasgpio_leds[] = { - { .name = "hdd1:blue:sata", .gpio_bit = 0 }, - { .name = "hdd1:amber:sata", .gpio_bit = 1 }, - { .name = "hdd2:blue:sata", .gpio_bit = 2 }, - { .name = "hdd2:amber:sata", .gpio_bit = 3 }, - { .name = "hdd3:blue:sata", .gpio_bit = 4 }, - { .name = "hdd3:amber:sata", .gpio_bit = 5 }, - { .name = "hdd4:blue:sata", .gpio_bit = 6 }, - { .name = "hdd4:amber:sata", .gpio_bit = 7 }, - { .name = "power:blue:power", .gpio_bit = 27}, - { .name = "power:amber:power", .gpio_bit = 28}, -}; - -#define NAS_RECOVERY 0x00000400 /* GPIO10 */ - -static struct nasgpio_led * -led_classdev_to_nasgpio_led(struct led_classdev *led_cdev) -{ - return container_of(led_cdev, struct nasgpio_led, led_cdev); -} - -static struct nasgpio_led *get_led_named(char *name) -{ - int i; - for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) { - if (strcmp(nasgpio_leds[i].name, name)) - continue; - return &nasgpio_leds[i]; - } - return NULL; -} - -/* - * This protects access to the gpio ports. - */ -static DEFINE_SPINLOCK(nasgpio_gpio_lock); - -/* - * There are two gpio ports, one for blinking and the other - * for power. @port tells us if we're doing blinking or - * power control. - * - * Caller must hold nasgpio_gpio_lock - */ -static void __nasgpio_led_set_attr(struct led_classdev *led_cdev, - u32 port, u32 value) -{ - struct nasgpio_led *led = led_classdev_to_nasgpio_led(led_cdev); - u32 gpio_out; - - gpio_out = inl(nas_gpio_io_base + port); - if (value) - gpio_out |= (1<gpio_bit); - else - gpio_out &= ~(1<gpio_bit); - - outl(gpio_out, nas_gpio_io_base + port); -} - -static void nasgpio_led_set_attr(struct led_classdev *led_cdev, - u32 port, u32 value) -{ - spin_lock(&nasgpio_gpio_lock); - __nasgpio_led_set_attr(led_cdev, port, value); - spin_unlock(&nasgpio_gpio_lock); -} - -u32 nasgpio_led_get_attr(struct led_classdev *led_cdev, u32 port) -{ - struct nasgpio_led *led = led_classdev_to_nasgpio_led(led_cdev); - u32 gpio_in; - - spin_lock(&nasgpio_gpio_lock); - gpio_in = inl(nas_gpio_io_base + port); - spin_unlock(&nasgpio_gpio_lock); - if (gpio_in & (1<gpio_bit)) - return 1; - return 0; -} - -/* - * There is actual brightness control in the hardware, - * but it is via smbus commands and not implemented - * in this driver. - */ -static void nasgpio_led_set_brightness(struct led_classdev *led_cdev, - enum led_brightness brightness) -{ - u32 setting = 0; - if (brightness >= LED_HALF) - setting = 1; - /* - * Hold the lock across both operations. This ensures - * consistency so that both the "turn off blinking" - * and "turn light off" operations complete as a set. - */ - spin_lock(&nasgpio_gpio_lock); - /* - * LED class documentation asks that past blink state - * be disabled when brightness is turned to zero. - */ - if (brightness == 0) - __nasgpio_led_set_attr(led_cdev, GPO_BLINK, 0); - __nasgpio_led_set_attr(led_cdev, GP_LVL, setting); - spin_unlock(&nasgpio_gpio_lock); -} - -static int nasgpio_led_set_blink(struct led_classdev *led_cdev, - unsigned long *delay_on, - unsigned long *delay_off) -{ - u32 setting = 1; - if (!(*delay_on == 0 && *delay_off == 0) && - !(*delay_on == 500 && *delay_off == 500)) - return -EINVAL; - /* - * These are very approximate. - */ - *delay_on = 500; - *delay_off = 500; - - nasgpio_led_set_attr(led_cdev, GPO_BLINK, setting); - - return 0; -} - - -/* - * Initialize the ICH7 GPIO registers for NAS usage. The BIOS should have - * already taken care of this, but we will do so in a non destructive manner - * so that we have what we need whether the BIOS did it or not. - */ -static int __devinit ich7_gpio_init(struct device *dev) -{ - int i; - u32 config_data = 0; - u32 all_nas_led = 0; - - for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) - all_nas_led |= (1<dev, "pci_enable_device failed\n"); - return -EIO; - } - - nas_gpio_pci_dev = dev; - status = pci_read_config_dword(dev, PMBASE, &g_pm_io_base); - if (status) - goto out; - g_pm_io_base &= 0x00000ff80; - - status = pci_read_config_dword(dev, GPIO_CTRL, &gc); - if (!(GPIO_EN & gc)) { - status = -EEXIST; - dev_info(&dev->dev, - "ERROR: The LPC GPIO Block has not been enabled.\n"); - goto out; - } - - status = pci_read_config_dword(dev, GPIO_BASE, &nas_gpio_io_base); - if (0 > status) { - dev_info(&dev->dev, "Unable to read GPIOBASE.\n"); - goto out; - } - dev_dbg(&dev->dev, ": GPIOBASE = 0x%08x\n", nas_gpio_io_base); - nas_gpio_io_base &= 0x00000ffc0; - - /* - * Insure that we have exclusive access to the GPIO I/O address range. - */ - gp_gpio_resource = request_region(nas_gpio_io_base, ICH7_GPIO_SIZE, - KBUILD_MODNAME); - if (NULL == gp_gpio_resource) { - dev_info(&dev->dev, - "ERROR Unable to register GPIO I/O addresses.\n"); - status = -1; - goto out; - } - - /* - * Initialize the GPIO for NAS/Home Server Use - */ - ich7_gpio_init(&dev->dev); - -out: - if (status) { - ich7_lpc_cleanup(&dev->dev); - pci_disable_device(dev); - } - return status; -} - -static void ich7_lpc_remove(struct pci_dev *dev) -{ - ich7_lpc_cleanup(&dev->dev); - pci_disable_device(dev); -} - -/* - * pci_driver structure passed to the PCI modules - */ -static struct pci_driver nas_gpio_pci_driver = { - .name = KBUILD_MODNAME, - .id_table = ich7_lpc_pci_id, - .probe = ich7_lpc_probe, - .remove = ich7_lpc_remove, -}; - -static struct led_classdev *get_classdev_for_led_nr(int nr) -{ - struct nasgpio_led *nas_led = &nasgpio_leds[nr]; - struct led_classdev *led = &nas_led->led_cdev; - return led; -} - - -static void set_power_light_amber_noblink(void) -{ - struct nasgpio_led *amber = get_led_named("power:amber:power"); - struct nasgpio_led *blue = get_led_named("power:blue:power"); - - if (!amber || !blue) - return; - /* - * LED_OFF implies disabling future blinking - */ - pr_debug("setting blue off and amber on\n"); - - nasgpio_led_set_brightness(&blue->led_cdev, LED_OFF); - nasgpio_led_set_brightness(&amber->led_cdev, LED_FULL); -} - -static ssize_t nas_led_blink_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct led_classdev *led = dev_get_drvdata(dev); - int blinking = 0; - if (nasgpio_led_get_attr(led, GPO_BLINK)) - blinking = 1; - return sprintf(buf, "%u\n", blinking); -} - -static ssize_t nas_led_blink_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t size) -{ - int ret; - struct led_classdev *led = dev_get_drvdata(dev); - unsigned long blink_state; - - ret = strict_strtoul(buf, 10, &blink_state); - if (ret) - return ret; - - nasgpio_led_set_attr(led, GPO_BLINK, blink_state); - - return size; -} - -static DEVICE_ATTR(blink, 0644, nas_led_blink_show, nas_led_blink_store); - -static int register_nasgpio_led(int led_nr) -{ - int ret; - struct nasgpio_led *nas_led = &nasgpio_leds[led_nr]; - struct led_classdev *led = get_classdev_for_led_nr(led_nr); - - led->name = nas_led->name; - led->brightness = LED_OFF; - if (nasgpio_led_get_attr(led, GP_LVL)) - led->brightness = LED_FULL; - led->brightness_set = nasgpio_led_set_brightness; - led->blink_set = nasgpio_led_set_blink; - ret = led_classdev_register(&nas_gpio_pci_dev->dev, led); - if (ret) - return ret; - ret = device_create_file(led->dev, &dev_attr_blink); - if (ret) - led_classdev_unregister(led); - return ret; -} - -static void unregister_nasgpio_led(int led_nr) -{ - struct led_classdev *led = get_classdev_for_led_nr(led_nr); - led_classdev_unregister(led); - device_remove_file(led->dev, &dev_attr_blink); -} -/* - * module load/initialization - */ -static int __init nas_gpio_init(void) -{ - int i; - int ret = 0; - int nr_devices = 0; - - nr_devices = dmi_check_system(nas_led_whitelist); - if (nodetect) { - pr_info("skipping hardware autodetection\n"); - pr_info("Please send 'dmidecode' output to dave@sr71.net\n"); - nr_devices++; - } - - if (nr_devices <= 0) { - pr_info("no LED devices found\n"); - return -ENODEV; - } - - pr_info("registering PCI driver\n"); - ret = pci_register_driver(&nas_gpio_pci_driver); - if (ret) - return ret; - for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) { - ret = register_nasgpio_led(i); - if (ret) - goto out_err; - } - /* - * When the system powers on, the BIOS leaves the power - * light blue and blinking. This will turn it solid - * amber once the driver is loaded. - */ - set_power_light_amber_noblink(); - return 0; -out_err: - for (; i >= 0; i--) - unregister_nasgpio_led(i); - pci_unregister_driver(&nas_gpio_pci_driver); - return ret; -} - -/* - * module unload - */ -static void __exit nas_gpio_exit(void) -{ - int i; - pr_info("Unregistering driver\n"); - for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) - unregister_nasgpio_led(i); - pci_unregister_driver(&nas_gpio_pci_driver); -} - -module_init(nas_gpio_init); -module_exit(nas_gpio_exit); diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index e3551d20464f..1a7a9fc50ea1 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -203,7 +203,6 @@ config CS5535_MFGPT config CS5535_MFGPT_DEFAULT_IRQ int - depends on CS5535_MFGPT default 7 help MFGPTs on the CS5535 require an interrupt. The selected IRQ diff --git a/trunk/drivers/mmc/core/sdio.c b/trunk/drivers/mmc/core/sdio.c index 06b64085a355..cdb845b68ab5 100644 --- a/trunk/drivers/mmc/core/sdio.c +++ b/trunk/drivers/mmc/core/sdio.c @@ -516,8 +516,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) * The number of functions on the card is encoded inside * the ocr. */ - funcs = (ocr & 0x70000000) >> 28; - card->sdio_funcs = 0; + card->sdio_funcs = funcs = (ocr & 0x70000000) >> 28; /* * If needed, disconnect card detection pull-up resistor. @@ -529,7 +528,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) /* * Initialize (but don't add) all present functions. */ - for (i = 0; i < funcs; i++, card->sdio_funcs++) { + for (i = 0;i < funcs;i++) { err = sdio_init_func(host->card, i + 1); if (err) goto remove; diff --git a/trunk/drivers/mmc/core/sdio_bus.c b/trunk/drivers/mmc/core/sdio_bus.c index 9e060c87e64d..d37464e296a5 100644 --- a/trunk/drivers/mmc/core/sdio_bus.c +++ b/trunk/drivers/mmc/core/sdio_bus.c @@ -248,15 +248,12 @@ int sdio_add_func(struct sdio_func *func) /* * Unregister a SDIO function with the driver model, and * (eventually) free it. - * This function can be called through error paths where sdio_add_func() was - * never executed (because a failure occurred at an earlier point). */ void sdio_remove_func(struct sdio_func *func) { - if (!sdio_func_present(func)) - return; + if (sdio_func_present(func)) + device_del(&func->dev); - device_del(&func->dev); put_device(&func->dev); } diff --git a/trunk/drivers/mmc/host/Kconfig b/trunk/drivers/mmc/host/Kconfig index ce1d28884e29..9d405b181781 100644 --- a/trunk/drivers/mmc/host/Kconfig +++ b/trunk/drivers/mmc/host/Kconfig @@ -44,19 +44,6 @@ config MMC_SDHCI_IO_ACCESSORS This is silent Kconfig symbol that is selected by the drivers that need to overwrite SDHCI IO memory accessors. -config MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER - bool - select MMC_SDHCI_IO_ACCESSORS - help - This option is selected by drivers running on big endian hosts - and performing I/O to a SDHCI controller through a bus that - implements a hardware byte swapper using a 32-bit datum. - This endian mapping mode is called "data invariance" and - has the effect of scrambling the addresses and formats of data - accessed in sizes other than the datum size. - - This is the case for the Freescale eSDHC and Nintendo Wii SDHCI. - config MMC_SDHCI_PCI tristate "SDHCI support on PCI bus" depends on MMC_SDHCI && PCI @@ -88,29 +75,11 @@ config MMC_RICOH_MMC config MMC_SDHCI_OF tristate "SDHCI support on OpenFirmware platforms" depends on MMC_SDHCI && PPC_OF + select MMC_SDHCI_IO_ACCESSORS help This selects the OF support for Secure Digital Host Controller - Interfaces. - - If unsure, say N. - -config MMC_SDHCI_OF_ESDHC - bool "SDHCI OF support for the Freescale eSDHC controller" - depends on MMC_SDHCI_OF - select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER - help - This selects the Freescale eSDHC controller support. - - If unsure, say N. - -config MMC_SDHCI_OF_HLWD - bool "SDHCI OF support for the Nintendo Wii SDHCI controllers" - depends on MMC_SDHCI_OF - select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER - help - This selects the Secure Digital Host Controller Interface (SDHCI) - found in the "Hollywood" chipset of the Nintendo Wii video game - console. + Interfaces. So far, only the Freescale eSDHC controller is known + to exist on OF platforms. If unsure, say N. diff --git a/trunk/drivers/mmc/host/Makefile b/trunk/drivers/mmc/host/Makefile index 3d253dd4240f..ded4d8cdd9d7 100644 --- a/trunk/drivers/mmc/host/Makefile +++ b/trunk/drivers/mmc/host/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o +obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o obj-$(CONFIG_MMC_WBSD) += wbsd.o @@ -36,11 +37,6 @@ obj-$(CONFIG_MMC_CB710) += cb710-mmc.o obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o -obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o -sdhci-of-y := sdhci-of-core.o -sdhci-of-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o -sdhci-of-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o - ifeq ($(CONFIG_CB710_DEBUG),y) CFLAGS-cb710-mmc += -DDEBUG endif diff --git a/trunk/drivers/mmc/host/sdhci-of-esdhc.c b/trunk/drivers/mmc/host/sdhci-of-esdhc.c deleted file mode 100644 index d5b11a17e648..000000000000 --- a/trunk/drivers/mmc/host/sdhci-of-esdhc.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Freescale eSDHC controller driver. - * - * Copyright (c) 2007 Freescale Semiconductor, Inc. - * Copyright (c) 2009 MontaVista Software, Inc. - * - * Authors: Xiaobo Xie - * Anton Vorontsov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - */ - -#include -#include -#include -#include "sdhci-of.h" -#include "sdhci.h" - -/* - * Ops and quirks for the Freescale eSDHC controller. - */ - -#define ESDHC_DMA_SYSCTL 0x40c -#define ESDHC_DMA_SNOOP 0x00000040 - -#define ESDHC_SYSTEM_CONTROL 0x2c -#define ESDHC_CLOCK_MASK 0x0000fff0 -#define ESDHC_PREDIV_SHIFT 8 -#define ESDHC_DIVIDER_SHIFT 4 -#define ESDHC_CLOCK_PEREN 0x00000004 -#define ESDHC_CLOCK_HCKEN 0x00000002 -#define ESDHC_CLOCK_IPGEN 0x00000001 - -#define ESDHC_HOST_CONTROL_RES 0x05 - -static u16 esdhc_readw(struct sdhci_host *host, int reg) -{ - u16 ret; - - if (unlikely(reg == SDHCI_HOST_VERSION)) - ret = in_be16(host->ioaddr + reg); - else - ret = sdhci_be32bs_readw(host, reg); - return ret; -} - -static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) -{ - if (reg == SDHCI_BLOCK_SIZE) { - /* - * Two last DMA bits are reserved, and first one is used for - * non-standard blksz of 4096 bytes that we don't support - * yet. So clear the DMA boundary bits. - */ - val &= ~SDHCI_MAKE_BLKSZ(0x7, 0); - } - sdhci_be32bs_writew(host, val, reg); -} - -static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) -{ - /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ - if (reg == SDHCI_HOST_CONTROL) - val &= ~ESDHC_HOST_CONTROL_RES; - sdhci_be32bs_writeb(host, val, reg); -} - -static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) -{ - int pre_div = 2; - int div = 1; - - clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | - ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK); - - if (clock == 0) - goto out; - - while (host->max_clk / pre_div / 16 > clock && pre_div < 256) - pre_div *= 2; - - while (host->max_clk / pre_div / div > clock && div < 16) - div++; - - dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", - clock, host->max_clk / pre_div / div); - - pre_div >>= 1; - div--; - - setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | - ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | - div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT); - mdelay(100); -out: - host->clock = clock; -} - -static int esdhc_enable_dma(struct sdhci_host *host) -{ - setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP); - return 0; -} - -static unsigned int esdhc_get_max_clock(struct sdhci_host *host) -{ - struct sdhci_of_host *of_host = sdhci_priv(host); - - return of_host->clock; -} - -static unsigned int esdhc_get_min_clock(struct sdhci_host *host) -{ - struct sdhci_of_host *of_host = sdhci_priv(host); - - return of_host->clock / 256 / 16; -} - -struct sdhci_of_data sdhci_esdhc = { - .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 | - SDHCI_QUIRK_BROKEN_CARD_DETECTION | - SDHCI_QUIRK_NO_BUSY_IRQ | - SDHCI_QUIRK_NONSTANDARD_CLOCK | - SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | - SDHCI_QUIRK_PIO_NEEDS_DELAY | - SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | - SDHCI_QUIRK_NO_CARD_NO_RESET, - .ops = { - .readl = sdhci_be32bs_readl, - .readw = esdhc_readw, - .readb = sdhci_be32bs_readb, - .writel = sdhci_be32bs_writel, - .writew = esdhc_writew, - .writeb = esdhc_writeb, - .set_clock = esdhc_set_clock, - .enable_dma = esdhc_enable_dma, - .get_max_clock = esdhc_get_max_clock, - .get_min_clock = esdhc_get_min_clock, - }, -}; diff --git a/trunk/drivers/mmc/host/sdhci-of-hlwd.c b/trunk/drivers/mmc/host/sdhci-of-hlwd.c deleted file mode 100644 index 35117f3ed757..000000000000 --- a/trunk/drivers/mmc/host/sdhci-of-hlwd.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * drivers/mmc/host/sdhci-of-hlwd.c - * - * Nintendo Wii Secure Digital Host Controller Interface. - * Copyright (C) 2009 The GameCube Linux Team - * Copyright (C) 2009 Albert Herranz - * - * Based on sdhci-of-esdhc.c - * - * Copyright (c) 2007 Freescale Semiconductor, Inc. - * Copyright (c) 2009 MontaVista Software, Inc. - * - * Authors: Xiaobo Xie - * Anton Vorontsov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - */ - -#include -#include -#include "sdhci-of.h" -#include "sdhci.h" - -/* - * Ops and quirks for the Nintendo Wii SDHCI controllers. - */ - -/* - * We need a small delay after each write, or things go horribly wrong. - */ -#define SDHCI_HLWD_WRITE_DELAY 5 /* usecs */ - -static void sdhci_hlwd_writel(struct sdhci_host *host, u32 val, int reg) -{ - sdhci_be32bs_writel(host, val, reg); - udelay(SDHCI_HLWD_WRITE_DELAY); -} - -static void sdhci_hlwd_writew(struct sdhci_host *host, u16 val, int reg) -{ - sdhci_be32bs_writew(host, val, reg); - udelay(SDHCI_HLWD_WRITE_DELAY); -} - -static void sdhci_hlwd_writeb(struct sdhci_host *host, u8 val, int reg) -{ - sdhci_be32bs_writeb(host, val, reg); - udelay(SDHCI_HLWD_WRITE_DELAY); -} - -struct sdhci_of_data sdhci_hlwd = { - .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | - SDHCI_QUIRK_32BIT_DMA_SIZE, - .ops = { - .readl = sdhci_be32bs_readl, - .readw = sdhci_be32bs_readw, - .readb = sdhci_be32bs_readb, - .writel = sdhci_hlwd_writel, - .writew = sdhci_hlwd_writew, - .writeb = sdhci_hlwd_writeb, - }, -}; diff --git a/trunk/drivers/mmc/host/sdhci-of-core.c b/trunk/drivers/mmc/host/sdhci-of.c similarity index 58% rename from trunk/drivers/mmc/host/sdhci-of-core.c rename to trunk/drivers/mmc/host/sdhci-of.c index 55e33135edb4..01ab916c2802 100644 --- a/trunk/drivers/mmc/host/sdhci-of-core.c +++ b/trunk/drivers/mmc/host/sdhci-of.c @@ -22,37 +22,62 @@ #include #include #include -#include "sdhci-of.h" #include "sdhci.h" -#ifdef CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER +struct sdhci_of_data { + unsigned int quirks; + struct sdhci_ops ops; +}; + +struct sdhci_of_host { + unsigned int clock; + u16 xfer_mode_shadow; +}; /* - * These accessors are designed for big endian hosts doing I/O to - * little endian controllers incorporating a 32-bit hardware byte swapper. + * Ops and quirks for the Freescale eSDHC controller. */ -u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg) +#define ESDHC_DMA_SYSCTL 0x40c +#define ESDHC_DMA_SNOOP 0x00000040 + +#define ESDHC_SYSTEM_CONTROL 0x2c +#define ESDHC_CLOCK_MASK 0x0000fff0 +#define ESDHC_PREDIV_SHIFT 8 +#define ESDHC_DIVIDER_SHIFT 4 +#define ESDHC_CLOCK_PEREN 0x00000004 +#define ESDHC_CLOCK_HCKEN 0x00000002 +#define ESDHC_CLOCK_IPGEN 0x00000001 + +#define ESDHC_HOST_CONTROL_RES 0x05 + +static u32 esdhc_readl(struct sdhci_host *host, int reg) { return in_be32(host->ioaddr + reg); } -u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg) +static u16 esdhc_readw(struct sdhci_host *host, int reg) { - return in_be16(host->ioaddr + (reg ^ 0x2)); + u16 ret; + + if (unlikely(reg == SDHCI_HOST_VERSION)) + ret = in_be16(host->ioaddr + reg); + else + ret = in_be16(host->ioaddr + (reg ^ 0x2)); + return ret; } -u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg) +static u8 esdhc_readb(struct sdhci_host *host, int reg) { return in_8(host->ioaddr + (reg ^ 0x3)); } -void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg) +static void esdhc_writel(struct sdhci_host *host, u32 val, int reg) { out_be32(host->ioaddr + reg, val); } -void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg) +static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) { struct sdhci_of_host *of_host = sdhci_priv(host); int base = reg & ~0x3; @@ -67,21 +92,106 @@ void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg) of_host->xfer_mode_shadow = val; return; case SDHCI_COMMAND: - sdhci_be32bs_writel(host, val << 16 | of_host->xfer_mode_shadow, - SDHCI_TRANSFER_MODE); + esdhc_writel(host, val << 16 | of_host->xfer_mode_shadow, + SDHCI_TRANSFER_MODE); return; + case SDHCI_BLOCK_SIZE: + /* + * Two last DMA bits are reserved, and first one is used for + * non-standard blksz of 4096 bytes that we don't support + * yet. So clear the DMA boundary bits. + */ + val &= ~SDHCI_MAKE_BLKSZ(0x7, 0); + /* fall through */ } clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift); } -void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg) +static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) { int base = reg & ~0x3; int shift = (reg & 0x3) * 8; + /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ + if (reg == SDHCI_HOST_CONTROL) + val &= ~ESDHC_HOST_CONTROL_RES; + clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift); } -#endif /* CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER */ + +static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) +{ + int pre_div = 2; + int div = 1; + + clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | + ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK); + + if (clock == 0) + goto out; + + while (host->max_clk / pre_div / 16 > clock && pre_div < 256) + pre_div *= 2; + + while (host->max_clk / pre_div / div > clock && div < 16) + div++; + + dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n", + clock, host->max_clk / pre_div / div); + + pre_div >>= 1; + div--; + + setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN | + ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | + div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT); + mdelay(100); +out: + host->clock = clock; +} + +static int esdhc_enable_dma(struct sdhci_host *host) +{ + setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP); + return 0; +} + +static unsigned int esdhc_get_max_clock(struct sdhci_host *host) +{ + struct sdhci_of_host *of_host = sdhci_priv(host); + + return of_host->clock; +} + +static unsigned int esdhc_get_min_clock(struct sdhci_host *host) +{ + struct sdhci_of_host *of_host = sdhci_priv(host); + + return of_host->clock / 256 / 16; +} + +static struct sdhci_of_data sdhci_esdhc = { + .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 | + SDHCI_QUIRK_BROKEN_CARD_DETECTION | + SDHCI_QUIRK_NO_BUSY_IRQ | + SDHCI_QUIRK_NONSTANDARD_CLOCK | + SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | + SDHCI_QUIRK_PIO_NEEDS_DELAY | + SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | + SDHCI_QUIRK_NO_CARD_NO_RESET, + .ops = { + .readl = esdhc_readl, + .readw = esdhc_readw, + .readb = esdhc_readb, + .writel = esdhc_writel, + .writew = esdhc_writew, + .writeb = esdhc_writeb, + .set_clock = esdhc_set_clock, + .enable_dma = esdhc_enable_dma, + .get_max_clock = esdhc_get_max_clock, + .get_min_clock = esdhc_get_min_clock, + }, +}; #ifdef CONFIG_PM @@ -191,14 +301,9 @@ static int __devexit sdhci_of_remove(struct of_device *ofdev) } static const struct of_device_id sdhci_of_match[] = { -#ifdef CONFIG_MMC_SDHCI_OF_ESDHC { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, }, { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, }, { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, }, -#endif -#ifdef CONFIG_MMC_SDHCI_OF_HLWD - { .compatible = "nintendo,hollywood-sdhci", .data = &sdhci_hlwd, }, -#endif { .compatible = "generic-sdhci", }, {}, }; diff --git a/trunk/drivers/mmc/host/sdhci-of.h b/trunk/drivers/mmc/host/sdhci-of.h deleted file mode 100644 index ad09ad9915d8..000000000000 --- a/trunk/drivers/mmc/host/sdhci-of.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * OpenFirmware bindings for Secure Digital Host Controller Interface. - * - * Copyright (c) 2007 Freescale Semiconductor, Inc. - * Copyright (c) 2009 MontaVista Software, Inc. - * - * Authors: Xiaobo Xie - * Anton Vorontsov - * - * 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 __SDHCI_OF_H -#define __SDHCI_OF_H - -#include -#include "sdhci.h" - -struct sdhci_of_data { - unsigned int quirks; - struct sdhci_ops ops; -}; - -struct sdhci_of_host { - unsigned int clock; - u16 xfer_mode_shadow; -}; - -extern u32 sdhci_be32bs_readl(struct sdhci_host *host, int reg); -extern u16 sdhci_be32bs_readw(struct sdhci_host *host, int reg); -extern u8 sdhci_be32bs_readb(struct sdhci_host *host, int reg); -extern void sdhci_be32bs_writel(struct sdhci_host *host, u32 val, int reg); -extern void sdhci_be32bs_writew(struct sdhci_host *host, u16 val, int reg); -extern void sdhci_be32bs_writeb(struct sdhci_host *host, u8 val, int reg); - -extern struct sdhci_of_data sdhci_esdhc; -extern struct sdhci_of_data sdhci_hlwd; - -#endif /* __SDHCI_OF_H */ diff --git a/trunk/drivers/mmc/host/sdhci.h b/trunk/drivers/mmc/host/sdhci.h index 842f46f94284..ce5f1d73dc04 100644 --- a/trunk/drivers/mmc/host/sdhci.h +++ b/trunk/drivers/mmc/host/sdhci.h @@ -8,8 +8,6 @@ * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. */ -#ifndef __SDHCI_H -#define __SDHCI_H #include #include @@ -410,5 +408,3 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead); extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); extern int sdhci_resume_host(struct sdhci_host *host); #endif - -#endif /* __SDHCI_H */ diff --git a/trunk/drivers/mtd/maps/pxa2xx-flash.c b/trunk/drivers/mtd/maps/pxa2xx-flash.c index b13f6417b5b2..74fa075c838a 100644 --- a/trunk/drivers/mtd/maps/pxa2xx-flash.c +++ b/trunk/drivers/mtd/maps/pxa2xx-flash.c @@ -20,23 +20,14 @@ #include #include +#include #include -#define CACHELINESIZE 32 - static void pxa2xx_map_inval_cache(struct map_info *map, unsigned long from, ssize_t len) { - unsigned long start = (unsigned long)map->cached + from; - unsigned long end = start + len; - - start &= ~(CACHELINESIZE - 1); - while (start < end) { - /* invalidate D cache line */ - asm volatile ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)); - start += CACHELINESIZE; - } + flush_ioremap_region(map->phys, map->cached, from, len); } struct pxa2xx_flash_info { diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h index 27ca859e7453..675b7df632fc 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h @@ -63,7 +63,7 @@ #ifndef __iwl_core_h__ #define __iwl_core_h__ -#include +#include /************************ * forward declarations * diff --git a/trunk/drivers/pcmcia/pxa2xx_base.c b/trunk/drivers/pcmcia/pxa2xx_base.c index 76e640bccde8..3aabf1e37988 100644 --- a/trunk/drivers/pcmcia/pxa2xx_base.c +++ b/trunk/drivers/pcmcia/pxa2xx_base.c @@ -291,7 +291,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) skt->nr = ops->first + i; skt->ops = ops; skt->socket.owner = ops->owner; - skt->socket.dev.parent = &dev->dev; + skt->socket.dev.parent = dev; skt->socket.pci_irq = NO_IRQ; ret = pxa2xx_drv_pcmcia_add_one(skt); @@ -304,8 +304,8 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) soc_pcmcia_remove_one(&sinfo->skt[i]); kfree(sinfo); } else { - pxa2xx_configure_sockets(&dev->dev); - dev_set_drvdata(&dev->dev, sinfo); + pxa2xx_configure_sockets(dev); + dev_set_drvdata(dev, sinfo); } return ret; diff --git a/trunk/drivers/platform/x86/compal-laptop.c b/trunk/drivers/platform/x86/compal-laptop.c index 1a387e79f719..11003bba10d3 100644 --- a/trunk/drivers/platform/x86/compal-laptop.c +++ b/trunk/drivers/platform/x86/compal-laptop.c @@ -51,6 +51,7 @@ #include #include #include +#include #define COMPAL_DRIVER_VERSION "0.2.6" diff --git a/trunk/drivers/regulator/88pm8607.c b/trunk/drivers/regulator/88pm8607.c deleted file mode 100644 index 04719551381b..000000000000 --- a/trunk/drivers/regulator/88pm8607.c +++ /dev/null @@ -1,685 +0,0 @@ -/* - * Regulators driver for Marvell 88PM8607 - * - * Copyright (C) 2009 Marvell International Ltd. - * Haojian Zhuang - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include - -struct pm8607_regulator_info { - struct regulator_desc desc; - struct pm8607_chip *chip; - struct regulator_dev *regulator; - - int min_uV; - int max_uV; - int step_uV; - int vol_reg; - int vol_shift; - int vol_nbits; - int update_reg; - int update_bit; - int enable_reg; - int enable_bit; - int slope_double; -}; - -static inline int check_range(struct pm8607_regulator_info *info, - int min_uV, int max_uV) -{ - if (max_uV < info->min_uV || min_uV > info->max_uV || min_uV > max_uV) - return -EINVAL; - - return 0; -} - -static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) -{ - struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - uint8_t chip_id = info->chip->chip_id; - int ret = -EINVAL; - - switch (info->desc.id) { - case PM8607_ID_BUCK1: - ret = (index < 0x1d) ? (index * 25000 + 800000) : - ((index < 0x20) ? 1500000 : - ((index < 0x40) ? ((index - 0x20) * 25000) : - -EINVAL)); - break; - case PM8607_ID_BUCK3: - ret = (index < 0x3d) ? (index * 25000) : - ((index < 0x40) ? 1500000 : -EINVAL); - if (ret < 0) - break; - if (info->slope_double) - ret <<= 1; - break; - case PM8607_ID_LDO1: - ret = (index == 0) ? 1800000 : - ((index == 1) ? 1200000 : - ((index == 2) ? 2800000 : -EINVAL)); - break; - case PM8607_ID_LDO5: - ret = (index == 0) ? 2900000 : - ((index == 1) ? 3000000 : - ((index == 2) ? 3100000 : 3300000)); - break; - case PM8607_ID_LDO7: - case PM8607_ID_LDO8: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 8) ? (index * 50000 + 2550000) : - -EINVAL); - break; - case PM8607_ID_LDO12: - ret = (index < 2) ? (index * 100000 + 1800000) : - ((index < 7) ? (index * 100000 + 2500000) : - ((index == 7) ? 3300000 : 1200000)); - break; - case PM8607_ID_LDO2: - case PM8607_ID_LDO3: - case PM8607_ID_LDO9: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 8) ? (index * 50000 + 2550000) : - -EINVAL); - break; - case PM8607_CHIP_B0: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 7) ? (index * 50000 + 2550000) : - 3300000); - break; - } - break; - case PM8607_ID_LDO4: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 8) ? (index * 50000 + 2550000) : - -EINVAL); - break; - case PM8607_CHIP_B0: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 6) ? (index * 50000 + 2550000) : - ((index == 6) ? 2900000 : 3300000)); - break; - } - break; - case PM8607_ID_LDO6: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 8) ? (index * 50000 + 2450000) : - -EINVAL); - break; - case PM8607_CHIP_B0: - ret = (index < 2) ? (index * 50000 + 1800000) : - ((index < 7) ? (index * 50000 + 2500000) : - 3300000); - break; - } - break; - case PM8607_ID_LDO10: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 8) ? (index * 50000 + 2550000) : - 1200000); - break; - case PM8607_CHIP_B0: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 7) ? (index * 50000 + 2550000) : - ((index == 7) ? 3300000 : 1200000)); - break; - } - break; - case PM8607_ID_LDO14: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - ret = (index < 3) ? (index * 50000 + 1800000) : - ((index < 8) ? (index * 50000 + 2550000) : - -EINVAL); - break; - case PM8607_CHIP_B0: - ret = (index < 2) ? (index * 50000 + 1800000) : - ((index < 7) ? (index * 50000 + 2600000) : - 3300000); - break; - } - break; - } - return ret; -} - -static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) -{ - struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - uint8_t chip_id = info->chip->chip_id; - int val = -ENOENT; - int ret; - - switch (info->desc.id) { - case PM8607_ID_BUCK1: - if (min_uV >= 800000) /* 800mV ~ 1500mV / 25mV */ - val = (min_uV - 775001) / 25000; - else { /* 25mV ~ 775mV / 25mV */ - val = (min_uV + 249999) / 25000; - val += 32; - } - break; - case PM8607_ID_BUCK3: - if (info->slope_double) - min_uV = min_uV >> 1; - val = (min_uV + 249999) / 25000; /* 0mV ~ 1500mV / 25mV */ - - break; - case PM8607_ID_LDO1: - if (min_uV > 1800000) - val = 2; - else if (min_uV > 1200000) - val = 0; - else - val = 1; - break; - case PM8607_ID_LDO5: - if (min_uV > 3100000) - val = 3; - else /* 2900mV ~ 3100mV / 100mV */ - val = (min_uV - 2800001) / 100000; - break; - case PM8607_ID_LDO7: - case PM8607_ID_LDO8: - if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; /* 1800mv */ - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2700mV */ - } else { /* 2700mV ~ 2900mV / 50mV */ - if (min_uV <= 2900000) { - val = (min_uV - 2650001) / 50000; - val += 3; - } else - val = -EINVAL; - } - break; - case PM8607_ID_LDO10: - if (min_uV > 2850000) - val = 7; - else if (min_uV <= 1200000) - val = 8; - else if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ - val = (min_uV - 1750001) / 50000; - else { /* 2700mV ~ 2850mV / 50mV */ - val = (min_uV - 2650001) / 50000; - val += 3; - } - break; - case PM8607_ID_LDO12: - if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 100mV */ - if (min_uV <= 1200000) - val = 8; /* 1200mV */ - else if (min_uV <= 1800000) - val = 0; /* 1800mV */ - else if (min_uV <= 1900000) - val = (min_uV - 1700001) / 100000; - else - val = 2; /* 2700mV */ - } else { /* 2700mV ~ 3100mV / 100mV */ - if (min_uV <= 3100000) { - val = (min_uV - 2600001) / 100000; - val += 2; - } else if (min_uV <= 3300000) - val = 7; - else - val = -EINVAL; - } - break; - case PM8607_ID_LDO2: - case PM8607_ID_LDO3: - case PM8607_ID_LDO9: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2700mV */ - else { /* 2700mV ~ 2900mV / 50mV */ - if (min_uV <= 2900000) { - val = (min_uV - 2650001) / 50000; - val += 3; - } else - val = -EINVAL; - } - break; - case PM8607_CHIP_B0: - if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2700mV */ - } else { /* 2700mV ~ 2850mV / 50mV */ - if (min_uV <= 2850000) { - val = (min_uV - 2650001) / 50000; - val += 3; - } else if (min_uV <= 3300000) - val = 7; - else - val = -EINVAL; - } - break; - } - break; - case PM8607_ID_LDO4: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2700mV */ - else { /* 2700mV ~ 2900mV / 50mV */ - if (min_uV <= 2900000) { - val = (min_uV - 2650001) / 50000; - val += 3; - } else - val = -EINVAL; - } - break; - case PM8607_CHIP_B0: - if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2700mV */ - } else { /* 2700mV ~ 2800mV / 50mV */ - if (min_uV <= 2850000) { - val = (min_uV - 2650001) / 50000; - val += 3; - } else if (min_uV <= 2900000) - val = 6; - else if (min_uV <= 3300000) - val = 7; - else - val = -EINVAL; - } - break; - } - break; - case PM8607_ID_LDO6: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - if (min_uV < 2600000) { /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2600mV */ - } else { /* 2600mV ~ 2800mV / 50mV */ - if (min_uV <= 2800000) { - val = (min_uV - 2550001) / 50000; - val += 3; - } else - val = -EINVAL; - } - break; - case PM8607_CHIP_B0: - if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1850000) - val = (min_uV - 1750001) / 50000; - else - val = 2; /* 2600mV */ - } else { /* 2600mV ~ 2800mV / 50mV */ - if (min_uV <= 2800000) { - val = (min_uV - 2550001) / 50000; - val += 2; - } else if (min_uV <= 3300000) - val = 7; - else - val = -EINVAL; - } - break; - } - break; - case PM8607_ID_LDO14: - switch (chip_id) { - case PM8607_CHIP_A0: - case PM8607_CHIP_A1: - if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1900000) - val = (min_uV - 1750001) / 50000; - else - val = 3; /* 2700mV */ - } else { /* 2700mV ~ 2900mV / 50mV */ - if (min_uV <= 2900000) { - val = (min_uV - 2650001) / 50000; - val += 3; - } else - val = -EINVAL; - } - break; - case PM8607_CHIP_B0: - if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */ - if (min_uV <= 1800000) - val = 0; - else if (min_uV <= 1850000) - val = (min_uV - 1750001) / 50000; - else - val = 2; /* 2700mV */ - } else { /* 2700mV ~ 2900mV / 50mV */ - if (min_uV <= 2900000) { - val = (min_uV - 2650001) / 50000; - val += 2; - } else if (min_uV <= 3300000) - val = 7; - else - val = -EINVAL; - } - break; - } - break; - } - if (val >= 0) { - ret = pm8607_list_voltage(rdev, val); - if (ret > max_uV) { - pr_err("exceed voltage range (%d %d) uV", - min_uV, max_uV); - return -EINVAL; - } - } else - pr_err("invalid voltage range (%d %d) uV", min_uV, max_uV); - return val; -} - -static int pm8607_set_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - struct pm8607_chip *chip = info->chip; - uint8_t val, mask; - int ret; - - if (check_range(info, min_uV, max_uV)) { - pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV); - return -EINVAL; - } - - ret = choose_voltage(rdev, min_uV, max_uV); - if (ret < 0) - return -EINVAL; - val = (uint8_t)(ret << info->vol_shift); - mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; - - ret = pm8607_set_bits(chip, info->vol_reg, mask, val); - if (ret) - return ret; - switch (info->desc.id) { - case PM8607_ID_BUCK1: - case PM8607_ID_BUCK3: - ret = pm8607_set_bits(chip, info->update_reg, - 1 << info->update_bit, - 1 << info->update_bit); - break; - } - return ret; -} - -static int pm8607_get_voltage(struct regulator_dev *rdev) -{ - struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - struct pm8607_chip *chip = info->chip; - uint8_t val, mask; - int ret; - - ret = pm8607_reg_read(chip, info->vol_reg); - if (ret < 0) - return ret; - - mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; - val = ((unsigned char)ret & mask) >> info->vol_shift; - - return pm8607_list_voltage(rdev, val); -} - -static int pm8607_enable(struct regulator_dev *rdev) -{ - struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - struct pm8607_chip *chip = info->chip; - - return pm8607_set_bits(chip, info->enable_reg, - 1 << info->enable_bit, - 1 << info->enable_bit); -} - -static int pm8607_disable(struct regulator_dev *rdev) -{ - struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - struct pm8607_chip *chip = info->chip; - - return pm8607_set_bits(chip, info->enable_reg, - 1 << info->enable_bit, 0); -} - -static int pm8607_is_enabled(struct regulator_dev *rdev) -{ - struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); - struct pm8607_chip *chip = info->chip; - int ret; - - ret = pm8607_reg_read(chip, info->enable_reg); - if (ret < 0) - return ret; - - return !!((unsigned char)ret & (1 << info->enable_bit)); -} - -static struct regulator_ops pm8607_regulator_ops = { - .set_voltage = pm8607_set_voltage, - .get_voltage = pm8607_get_voltage, - .enable = pm8607_enable, - .disable = pm8607_disable, - .is_enabled = pm8607_is_enabled, -}; - -#define PM8607_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \ -{ \ - .desc = { \ - .name = "BUCK" #_id, \ - .ops = &pm8607_regulator_ops, \ - .type = REGULATOR_VOLTAGE, \ - .id = PM8607_ID_BUCK##_id, \ - .owner = THIS_MODULE, \ - }, \ - .min_uV = (min) * 1000, \ - .max_uV = (max) * 1000, \ - .step_uV = (step) * 1000, \ - .vol_reg = PM8607_##vreg, \ - .vol_shift = (0), \ - .vol_nbits = (nbits), \ - .update_reg = PM8607_##ureg, \ - .update_bit = (ubit), \ - .enable_reg = PM8607_##ereg, \ - .enable_bit = (ebit), \ - .slope_double = (0), \ -} - -#define PM8607_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \ -{ \ - .desc = { \ - .name = "LDO" #_id, \ - .ops = &pm8607_regulator_ops, \ - .type = REGULATOR_VOLTAGE, \ - .id = PM8607_ID_LDO##_id, \ - .owner = THIS_MODULE, \ - }, \ - .min_uV = (min) * 1000, \ - .max_uV = (max) * 1000, \ - .step_uV = (step) * 1000, \ - .vol_reg = PM8607_##vreg, \ - .vol_shift = (shift), \ - .vol_nbits = (nbits), \ - .enable_reg = PM8607_##ereg, \ - .enable_bit = (ebit), \ - .slope_double = (0), \ -} - -static struct pm8607_regulator_info pm8607_regulator_info[] = { - PM8607_DVC(1, 0, 1500, 25, BUCK1, 6, GO, 0, SUPPLIES_EN11, 0), - PM8607_DVC(3, 0, 1500, 25, BUCK3, 6, GO, 2, SUPPLIES_EN11, 2), - - PM8607_LDO(1 , 1200, 2800, 0, LDO1 , 0, 2, SUPPLIES_EN11, 3), - PM8607_LDO(2 , 1800, 3300, 0, LDO2 , 0, 3, SUPPLIES_EN11, 4), - PM8607_LDO(3 , 1800, 3300, 0, LDO3 , 0, 3, SUPPLIES_EN11, 5), - PM8607_LDO(4 , 1800, 3300, 0, LDO4 , 0, 3, SUPPLIES_EN11, 6), - PM8607_LDO(5 , 2900, 3300, 0, LDO5 , 0, 2, SUPPLIES_EN11, 7), - PM8607_LDO(6 , 1800, 3300, 0, LDO6 , 0, 3, SUPPLIES_EN12, 0), - PM8607_LDO(7 , 1800, 2900, 0, LDO7 , 0, 3, SUPPLIES_EN12, 1), - PM8607_LDO(8 , 1800, 2900, 0, LDO8 , 0, 3, SUPPLIES_EN12, 2), - PM8607_LDO(9 , 1800, 3300, 0, LDO9 , 0, 3, SUPPLIES_EN12, 3), - PM8607_LDO(10, 1200, 3300, 0, LDO10, 0, 4, SUPPLIES_EN11, 4), - PM8607_LDO(12, 1200, 3300, 0, LDO12, 0, 4, SUPPLIES_EN11, 5), - PM8607_LDO(14, 1800, 3300, 0, LDO14, 0, 3, SUPPLIES_EN11, 6), -}; - -static inline struct pm8607_regulator_info *find_regulator_info(int id) -{ - struct pm8607_regulator_info *info; - int i; - - for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) { - info = &pm8607_regulator_info[i]; - if (info->desc.id == id) - return info; - } - return NULL; -} - -static int __devinit pm8607_regulator_probe(struct platform_device *pdev) -{ - struct pm8607_chip *chip = dev_get_drvdata(pdev->dev.parent); - struct pm8607_platform_data *pdata = chip->dev->platform_data; - struct pm8607_regulator_info *info = NULL; - - info = find_regulator_info(pdev->id); - if (info == NULL) { - dev_err(&pdev->dev, "invalid regulator ID specified\n"); - return -EINVAL; - } - - info->chip = chip; - - info->regulator = regulator_register(&info->desc, &pdev->dev, - pdata->regulator[pdev->id], info); - if (IS_ERR(info->regulator)) { - dev_err(&pdev->dev, "failed to register regulator %s\n", - info->desc.name); - return PTR_ERR(info->regulator); - } - - /* check DVC ramp slope double */ - if (info->desc.id == PM8607_ID_BUCK3) - if (info->chip->buck3_double) - info->slope_double = 1; - - platform_set_drvdata(pdev, info); - return 0; -} - -static int __devexit pm8607_regulator_remove(struct platform_device *pdev) -{ - struct pm8607_regulator_info *info = platform_get_drvdata(pdev); - - regulator_unregister(info->regulator); - return 0; -} - -#define PM8607_REGULATOR_DRIVER(_name) \ -{ \ - .driver = { \ - .name = "88pm8607-" #_name, \ - .owner = THIS_MODULE, \ - }, \ - .probe = pm8607_regulator_probe, \ - .remove = __devexit_p(pm8607_regulator_remove), \ -} - -static struct platform_driver pm8607_regulator_driver[] = { - PM8607_REGULATOR_DRIVER(buck1), - PM8607_REGULATOR_DRIVER(buck2), - PM8607_REGULATOR_DRIVER(buck3), - PM8607_REGULATOR_DRIVER(ldo1), - PM8607_REGULATOR_DRIVER(ldo2), - PM8607_REGULATOR_DRIVER(ldo3), - PM8607_REGULATOR_DRIVER(ldo4), - PM8607_REGULATOR_DRIVER(ldo5), - PM8607_REGULATOR_DRIVER(ldo6), - PM8607_REGULATOR_DRIVER(ldo7), - PM8607_REGULATOR_DRIVER(ldo8), - PM8607_REGULATOR_DRIVER(ldo9), - PM8607_REGULATOR_DRIVER(ldo10), - PM8607_REGULATOR_DRIVER(ldo12), - PM8607_REGULATOR_DRIVER(ldo14), -}; - -static int __init pm8607_regulator_init(void) -{ - int i, count, ret; - - count = ARRAY_SIZE(pm8607_regulator_driver); - for (i = 0; i < count; i++) { - ret = platform_driver_register(&pm8607_regulator_driver[i]); - if (ret != 0) - pr_err("Failed to register regulator driver: %d\n", - ret); - } - return 0; -} -subsys_initcall(pm8607_regulator_init); - -static void __exit pm8607_regulator_exit(void) -{ - int i, count; - - count = ARRAY_SIZE(pm8607_regulator_driver); - for (i = 0; i < count; i++) - platform_driver_unregister(&pm8607_regulator_driver[i]); -} -module_exit(pm8607_regulator_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Haojian Zhuang "); -MODULE_DESCRIPTION("Regulator Driver for Marvell 88PM8607 PMIC"); -MODULE_ALIAS("platform:88pm8607-regulator"); diff --git a/trunk/drivers/regulator/Kconfig b/trunk/drivers/regulator/Kconfig index 262f62eec837..7cfdd65bebb4 100644 --- a/trunk/drivers/regulator/Kconfig +++ b/trunk/drivers/regulator/Kconfig @@ -69,13 +69,6 @@ config REGULATOR_MAX1586 regulator via I2C bus. The provided regulator is suitable for PXA27x chips to control VCC_CORE and VCC_USIM voltages. -config REGULATOR_MAX8660 - tristate "Maxim 8660/8661 voltage regulator" - depends on I2C - help - This driver controls a Maxim 8660/8661 voltage output - regulator via I2C bus. - config REGULATOR_TWL4030 bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC" depends on TWL4030_CORE @@ -164,11 +157,5 @@ config REGULATOR_TPS6507X three step-down converters and two general-purpose LDO voltage regulators. It supports TI's software based Class-2 SmartReflex implementation. -config REGULATOR_88PM8607 - bool "Marvell 88PM8607 Power regulators" - depends on MFD_88PM8607=y - help - This driver supports 88PM8607 voltage regulator chips. - endif diff --git a/trunk/drivers/regulator/Makefile b/trunk/drivers/regulator/Makefile index b3c806c79415..9ae3cc44e668 100644 --- a/trunk/drivers/regulator/Makefile +++ b/trunk/drivers/regulator/Makefile @@ -12,7 +12,6 @@ obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o -obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o @@ -21,11 +20,10 @@ obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o -obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o +obj-$(CONFIG_REGULATOR_MC13783) += mc13783.o obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o -obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG diff --git a/trunk/drivers/regulator/ab3100.c b/trunk/drivers/regulator/ab3100.c index b349db4504b7..49aeee823a25 100644 --- a/trunk/drivers/regulator/ab3100.c +++ b/trunk/drivers/regulator/ab3100.c @@ -81,7 +81,7 @@ static const u8 ab3100_reg_init_order[AB3100_NUM_REGULATORS+2] = { #define LDO_C_VOLTAGE 2650000 #define LDO_D_VOLTAGE 2650000 -static const int ldo_e_buck_typ_voltages[] = { +static const int const ldo_e_buck_typ_voltages[] = { 1800000, 1400000, 1300000, @@ -91,7 +91,7 @@ static const int ldo_e_buck_typ_voltages[] = { 900000, }; -static const int ldo_f_typ_voltages[] = { +static const int const ldo_f_typ_voltages[] = { 1800000, 1400000, 1300000, @@ -102,21 +102,21 @@ static const int ldo_f_typ_voltages[] = { 2650000, }; -static const int ldo_g_typ_voltages[] = { +static const int const ldo_g_typ_voltages[] = { 2850000, 2750000, 1800000, 1500000, }; -static const int ldo_h_typ_voltages[] = { +static const int const ldo_h_typ_voltages[] = { 2750000, 1800000, 1500000, 1200000, }; -static const int ldo_k_typ_voltages[] = { +static const int const ldo_k_typ_voltages[] = { 2750000, 1800000, }; @@ -241,12 +241,24 @@ static int ab3100_disable_regulator(struct regulator_dev *reg) * LDO D is a special regulator. When it is disabled, the entire * system is shut down. So this is handled specially. */ - pr_info("Called ab3100_disable_regulator\n"); if (abreg->regreg == AB3100_LDO_D) { + int i; + dev_info(®->dev, "disabling LDO D - shut down system\n"); + /* + * Set regulators to default values, ignore any errors, + * we're going DOWN + */ + for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) { + (void) ab3100_set_register_interruptible(abreg->ab3100, + ab3100_reg_init_order[i], + abreg->plfdata->reg_initvals[i]); + } + /* Setting LDO D to 0x00 cuts the power to the SoC */ return ab3100_set_register_interruptible(abreg->ab3100, AB3100_LDO_D, 0x00U); + } /* @@ -595,6 +607,13 @@ static int __init ab3100_regulators_probe(struct platform_device *pdev) } } + if (err) { + dev_err(&pdev->dev, + "LDO D regulator initialization failed with error %d\n", + err); + return err; + } + /* Register the regulators */ for (i = 0; i < AB3100_NUM_REGULATORS; i++) { struct ab3100_regulator *reg = &ab3100_regulators[i]; @@ -669,7 +688,7 @@ static __init int ab3100_regulators_init(void) static __exit void ab3100_regulators_exit(void) { - platform_driver_unregister(&ab3100_regulators_driver); + platform_driver_register(&ab3100_regulators_driver); } subsys_initcall(ab3100_regulators_init); diff --git a/trunk/drivers/regulator/core.c b/trunk/drivers/regulator/core.c index 686ef270ecf7..efe568deda12 100644 --- a/trunk/drivers/regulator/core.c +++ b/trunk/drivers/regulator/core.c @@ -66,16 +66,6 @@ static unsigned int _regulator_get_mode(struct regulator_dev *rdev); static void _notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data); -static const char *rdev_get_name(struct regulator_dev *rdev) -{ - if (rdev->constraints && rdev->constraints->name) - return rdev->constraints->name; - else if (rdev->desc->name) - return rdev->desc->name; - else - return ""; -} - /* gets the regulator for a given consumer device */ static struct regulator *get_device_regulator(struct device *dev) { @@ -106,12 +96,12 @@ static int regulator_check_voltage(struct regulator_dev *rdev, if (!rdev->constraints) { printk(KERN_ERR "%s: no constraints for %s\n", __func__, - rdev_get_name(rdev)); + rdev->desc->name); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { printk(KERN_ERR "%s: operation not allowed for %s\n", - __func__, rdev_get_name(rdev)); + __func__, rdev->desc->name); return -EPERM; } @@ -134,12 +124,12 @@ static int regulator_check_current_limit(struct regulator_dev *rdev, if (!rdev->constraints) { printk(KERN_ERR "%s: no constraints for %s\n", __func__, - rdev_get_name(rdev)); + rdev->desc->name); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) { printk(KERN_ERR "%s: operation not allowed for %s\n", - __func__, rdev_get_name(rdev)); + __func__, rdev->desc->name); return -EPERM; } @@ -169,17 +159,17 @@ static int regulator_check_mode(struct regulator_dev *rdev, int mode) if (!rdev->constraints) { printk(KERN_ERR "%s: no constraints for %s\n", __func__, - rdev_get_name(rdev)); + rdev->desc->name); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) { printk(KERN_ERR "%s: operation not allowed for %s\n", - __func__, rdev_get_name(rdev)); + __func__, rdev->desc->name); return -EPERM; } if (!(rdev->constraints->valid_modes_mask & mode)) { printk(KERN_ERR "%s: invalid mode %x for %s\n", - __func__, mode, rdev_get_name(rdev)); + __func__, mode, rdev->desc->name); return -EINVAL; } return 0; @@ -190,12 +180,12 @@ static int regulator_check_drms(struct regulator_dev *rdev) { if (!rdev->constraints) { printk(KERN_ERR "%s: no constraints for %s\n", __func__, - rdev_get_name(rdev)); + rdev->desc->name); return -ENODEV; } if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) { printk(KERN_ERR "%s: operation not allowed for %s\n", - __func__, rdev_get_name(rdev)); + __func__, rdev->desc->name); return -EPERM; } return 0; @@ -240,8 +230,16 @@ static ssize_t regulator_name_show(struct device *dev, struct device_attribute *attr, char *buf) { struct regulator_dev *rdev = dev_get_drvdata(dev); + const char *name; - return sprintf(buf, "%s\n", rdev_get_name(rdev)); + if (rdev->constraints && rdev->constraints->name) + name = rdev->constraints->name; + else if (rdev->desc->name) + name = rdev->desc->name; + else + name = ""; + + return sprintf(buf, "%s\n", name); } static ssize_t regulator_print_opmode(char *buf, int mode) @@ -390,7 +388,7 @@ static ssize_t regulator_total_uA_show(struct device *dev, mutex_lock(&rdev->mutex); list_for_each_entry(regulator, &rdev->consumer_list, list) - uA += regulator->uA_load; + uA += regulator->uA_load; mutex_unlock(&rdev->mutex); return sprintf(buf, "%d\n", uA); } @@ -565,7 +563,7 @@ static void drms_uA_update(struct regulator_dev *rdev) /* calc total requested load */ list_for_each_entry(sibling, &rdev->consumer_list, list) - current_uA += sibling->uA_load; + current_uA += sibling->uA_load; /* now get the optimum mode for our new total regulator load */ mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV, @@ -581,29 +579,10 @@ static int suspend_set_state(struct regulator_dev *rdev, struct regulator_state *rstate) { int ret = 0; - bool can_set_state; - can_set_state = rdev->desc->ops->set_suspend_enable && - rdev->desc->ops->set_suspend_disable; - - /* If we have no suspend mode configration don't set anything; - * only warn if the driver actually makes the suspend mode - * configurable. - */ - if (!rstate->enabled && !rstate->disabled) { - if (can_set_state) - printk(KERN_WARNING "%s: No configuration for %s\n", - __func__, rdev_get_name(rdev)); - return 0; - } - - if (rstate->enabled && rstate->disabled) { - printk(KERN_ERR "%s: invalid configuration for %s\n", - __func__, rdev_get_name(rdev)); - return -EINVAL; - } - - if (!can_set_state) { + /* enable & disable are mandatory for suspend control */ + if (!rdev->desc->ops->set_suspend_enable || + !rdev->desc->ops->set_suspend_disable) { printk(KERN_ERR "%s: no way to set suspend state\n", __func__); return -EINVAL; @@ -662,43 +641,25 @@ static void print_constraints(struct regulator_dev *rdev) { struct regulation_constraints *constraints = rdev->constraints; char buf[80]; - int count = 0; - int ret; + int count; - if (constraints->min_uV && constraints->max_uV) { + if (rdev->desc->type == REGULATOR_VOLTAGE) { if (constraints->min_uV == constraints->max_uV) - count += sprintf(buf + count, "%d mV ", - constraints->min_uV / 1000); + count = sprintf(buf, "%d mV ", + constraints->min_uV / 1000); else - count += sprintf(buf + count, "%d <--> %d mV ", - constraints->min_uV / 1000, - constraints->max_uV / 1000); - } - - if (!constraints->min_uV || - constraints->min_uV != constraints->max_uV) { - ret = _regulator_get_voltage(rdev); - if (ret > 0) - count += sprintf(buf + count, "at %d mV ", ret / 1000); - } - - if (constraints->min_uA && constraints->max_uA) { + count = sprintf(buf, "%d <--> %d mV ", + constraints->min_uV / 1000, + constraints->max_uV / 1000); + } else { if (constraints->min_uA == constraints->max_uA) - count += sprintf(buf + count, "%d mA ", - constraints->min_uA / 1000); + count = sprintf(buf, "%d mA ", + constraints->min_uA / 1000); else - count += sprintf(buf + count, "%d <--> %d mA ", - constraints->min_uA / 1000, - constraints->max_uA / 1000); + count = sprintf(buf, "%d <--> %d mA ", + constraints->min_uA / 1000, + constraints->max_uA / 1000); } - - if (!constraints->min_uA || - constraints->min_uA != constraints->max_uA) { - ret = _regulator_get_current_limit(rdev); - if (ret > 0) - count += sprintf(buf + count, "at %d uA ", ret / 1000); - } - if (constraints->valid_modes_mask & REGULATOR_MODE_FAST) count += sprintf(buf + count, "fast "); if (constraints->valid_modes_mask & REGULATOR_MODE_NORMAL) @@ -708,30 +669,33 @@ static void print_constraints(struct regulator_dev *rdev) if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY) count += sprintf(buf + count, "standby"); - printk(KERN_INFO "regulator: %s: %s\n", rdev_get_name(rdev), buf); + printk(KERN_INFO "regulator: %s: %s\n", rdev->desc->name, buf); } -static int machine_constraints_voltage(struct regulator_dev *rdev, +/** + * set_machine_constraints - sets regulator constraints + * @rdev: regulator source + * @constraints: constraints to apply + * + * Allows platform initialisation code to define and constrain + * regulator circuits e.g. valid voltage/current ranges, etc. NOTE: + * Constraints *must* be set by platform code in order for some + * regulator operations to proceed i.e. set_voltage, set_current_limit, + * set_mode. + */ +static int set_machine_constraints(struct regulator_dev *rdev, struct regulation_constraints *constraints) { + int ret = 0; + const char *name; struct regulator_ops *ops = rdev->desc->ops; - const char *name = rdev_get_name(rdev); - int ret; - /* do we need to apply the constraint voltage */ - if (rdev->constraints->apply_uV && - rdev->constraints->min_uV == rdev->constraints->max_uV && - ops->set_voltage) { - ret = ops->set_voltage(rdev, - rdev->constraints->min_uV, rdev->constraints->max_uV); - if (ret < 0) { - printk(KERN_ERR "%s: failed to apply %duV constraint to %s\n", - __func__, - rdev->constraints->min_uV, name); - rdev->constraints = NULL; - return ret; - } - } + if (constraints->name) + name = constraints->name; + else if (rdev->desc->name) + name = rdev->desc->name; + else + name = "regulator"; /* constrain machine-level voltage specs to fit * the actual range supported by this regulator. @@ -755,13 +719,14 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, /* voltage constraints are optional */ if ((cmin == 0) && (cmax == 0)) - return 0; + goto out; /* else require explicit machine-level constraints */ if (cmin <= 0 || cmax <= 0 || cmax < cmin) { pr_err("%s: %s '%s' voltage constraints\n", __func__, "invalid", name); - return -EINVAL; + ret = -EINVAL; + goto out; } /* initial: [cmin..cmax] valid, [min_uV..max_uV] not */ @@ -783,7 +748,8 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, if (max_uV < min_uV) { pr_err("%s: %s '%s' voltage constraints\n", __func__, "unsupportable", name); - return -EINVAL; + ret = -EINVAL; + goto out; } /* use regulator's subset of machine constraints */ @@ -801,34 +767,22 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, } } - return 0; -} - -/** - * set_machine_constraints - sets regulator constraints - * @rdev: regulator source - * @constraints: constraints to apply - * - * Allows platform initialisation code to define and constrain - * regulator circuits e.g. valid voltage/current ranges, etc. NOTE: - * Constraints *must* be set by platform code in order for some - * regulator operations to proceed i.e. set_voltage, set_current_limit, - * set_mode. - */ -static int set_machine_constraints(struct regulator_dev *rdev, - struct regulation_constraints *constraints) -{ - int ret = 0; - const char *name; - struct regulator_ops *ops = rdev->desc->ops; - rdev->constraints = constraints; - name = rdev_get_name(rdev); - - ret = machine_constraints_voltage(rdev, constraints); - if (ret != 0) - goto out; + /* do we need to apply the constraint voltage */ + if (rdev->constraints->apply_uV && + rdev->constraints->min_uV == rdev->constraints->max_uV && + ops->set_voltage) { + ret = ops->set_voltage(rdev, + rdev->constraints->min_uV, rdev->constraints->max_uV); + if (ret < 0) { + printk(KERN_ERR "%s: failed to apply %duV constraint to %s\n", + __func__, + rdev->constraints->min_uV, name); + rdev->constraints = NULL; + goto out; + } + } /* do we need to setup our suspend state */ if (constraints->initial_state) { @@ -949,7 +903,7 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, dev_name(&node->regulator->dev), node->regulator->desc->name, supply, - dev_name(&rdev->dev), rdev_get_name(rdev)); + dev_name(&rdev->dev), rdev->desc->name); return -EBUSY; } @@ -1258,7 +1212,7 @@ static int _regulator_enable(struct regulator_dev *rdev) ret = _regulator_enable(rdev->supply); if (ret < 0) { printk(KERN_ERR "%s: failed to enable %s: %d\n", - __func__, rdev_get_name(rdev), ret); + __func__, rdev->desc->name, ret); return ret; } } @@ -1284,7 +1238,7 @@ static int _regulator_enable(struct regulator_dev *rdev) } } else if (ret < 0) { printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n", - __func__, rdev_get_name(rdev), ret); + __func__, rdev->desc->name, ret); return ret; } /* Fallthrough on positive return values - already enabled */ @@ -1325,7 +1279,7 @@ static int _regulator_disable(struct regulator_dev *rdev) if (WARN(rdev->use_count <= 0, "unbalanced disables for %s\n", - rdev_get_name(rdev))) + rdev->desc->name)) return -EIO; /* are we the last user and permitted to disable ? */ @@ -1338,7 +1292,7 @@ static int _regulator_disable(struct regulator_dev *rdev) ret = rdev->desc->ops->disable(rdev); if (ret < 0) { printk(KERN_ERR "%s: failed to disable %s\n", - __func__, rdev_get_name(rdev)); + __func__, rdev->desc->name); return ret; } } @@ -1395,7 +1349,7 @@ static int _regulator_force_disable(struct regulator_dev *rdev) ret = rdev->desc->ops->disable(rdev); if (ret < 0) { printk(KERN_ERR "%s: failed to force disable %s\n", - __func__, rdev_get_name(rdev)); + __func__, rdev->desc->name); return ret; } /* notify other consumers that power has been forced off */ @@ -1812,7 +1766,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) output_uV = rdev->desc->ops->get_voltage(rdev); if (output_uV <= 0) { printk(KERN_ERR "%s: invalid output voltage found for %s\n", - __func__, rdev_get_name(rdev)); + __func__, rdev->desc->name); goto out; } @@ -1823,13 +1777,13 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) input_uV = rdev->constraints->input_uV; if (input_uV <= 0) { printk(KERN_ERR "%s: invalid input voltage found for %s\n", - __func__, rdev_get_name(rdev)); + __func__, rdev->desc->name); goto out; } /* calc total requested load for this regulator */ list_for_each_entry(consumer, &rdev->consumer_list, list) - total_uA_load += consumer->uA_load; + total_uA_load += consumer->uA_load; mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV, output_uV, @@ -1837,7 +1791,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) ret = regulator_check_mode(rdev, mode); if (ret < 0) { printk(KERN_ERR "%s: failed to get optimum mode for %s @" - " %d uA %d -> %d uV\n", __func__, rdev_get_name(rdev), + " %d uA %d -> %d uV\n", __func__, rdev->desc->name, total_uA_load, input_uV, output_uV); goto out; } @@ -1845,7 +1799,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) ret = rdev->desc->ops->set_mode(rdev, mode); if (ret < 0) { printk(KERN_ERR "%s: failed to set optimum mode %x for %s\n", - __func__, mode, rdev_get_name(rdev)); + __func__, mode, rdev->desc->name); goto out; } ret = mode; @@ -1898,9 +1852,9 @@ static void _notifier_call_chain(struct regulator_dev *rdev, /* now notify regulator we supply */ list_for_each_entry(_rdev, &rdev->supply_list, slist) { - mutex_lock(&_rdev->mutex); - _notifier_call_chain(_rdev, event, data); - mutex_unlock(&_rdev->mutex); + mutex_lock(&_rdev->mutex); + _notifier_call_chain(_rdev, event, data); + mutex_unlock(&_rdev->mutex); } } @@ -1931,9 +1885,9 @@ int regulator_bulk_get(struct device *dev, int num_consumers, consumers[i].consumer = regulator_get(dev, consumers[i].supply); if (IS_ERR(consumers[i].consumer)) { + dev_err(dev, "Failed to get supply '%s'\n", + consumers[i].supply); ret = PTR_ERR(consumers[i].consumer); - dev_err(dev, "Failed to get supply '%s': %d\n", - consumers[i].supply, ret); consumers[i].consumer = NULL; goto err; } @@ -1976,8 +1930,8 @@ int regulator_bulk_enable(int num_consumers, return 0; err: - printk(KERN_ERR "Failed to enable %s: %d\n", consumers[i].supply, ret); - for (--i; i >= 0; --i) + printk(KERN_ERR "Failed to enable %s\n", consumers[i].supply); + for (i = 0; i < num_consumers; i++) regulator_disable(consumers[i].consumer); return ret; @@ -2011,9 +1965,8 @@ int regulator_bulk_disable(int num_consumers, return 0; err: - printk(KERN_ERR "Failed to disable %s: %d\n", consumers[i].supply, - ret); - for (--i; i >= 0; --i) + printk(KERN_ERR "Failed to disable %s\n", consumers[i].supply); + for (i = 0; i < num_consumers; i++) regulator_enable(consumers[i].consumer); return ret; @@ -2363,7 +2316,7 @@ int regulator_suspend_prepare(suspend_state_t state) if (ret < 0) { printk(KERN_ERR "%s: failed to prepare %s\n", - __func__, rdev_get_name(rdev)); + __func__, rdev->desc->name); goto out; } } @@ -2476,7 +2429,12 @@ static int __init regulator_init_complete(void) ops = rdev->desc->ops; c = rdev->constraints; - name = rdev_get_name(rdev); + if (c && c->name) + name = c->name; + else if (rdev->desc->name) + name = rdev->desc->name; + else + name = "regulator"; if (!ops->disable || (c && c->always_on)) continue; diff --git a/trunk/drivers/regulator/da903x.c b/trunk/drivers/regulator/da903x.c index f8c4661a7a81..aa224d936e0d 100644 --- a/trunk/drivers/regulator/da903x.c +++ b/trunk/drivers/regulator/da903x.c @@ -331,7 +331,7 @@ static int da9034_get_ldo12_voltage(struct regulator_dev *rdev) static int da9034_list_ldo12_voltage(struct regulator_dev *rdev, unsigned selector) { - if (selector >= ARRAY_SIZE(da9034_ldo12_data)) + if (selector > ARRAY_SIZE(da9034_ldo12_data)) return -EINVAL; return da9034_ldo12_data[selector] * 1000; } diff --git a/trunk/drivers/regulator/lp3971.c b/trunk/drivers/regulator/lp3971.c index 76d08c282f9c..7803a320543b 100644 --- a/trunk/drivers/regulator/lp3971.c +++ b/trunk/drivers/regulator/lp3971.c @@ -446,8 +446,8 @@ static int setup_regulators(struct lp3971 *lp3971, lp3971->rdev[i] = regulator_register(®ulators[id], lp3971->dev, pdata->regulators[i].initdata, lp3971); - if (IS_ERR(lp3971->rdev[i])) { - err = PTR_ERR(lp3971->rdev[i]); + err = IS_ERR(lp3971->rdev[i]); + if (err) { dev_err(lp3971->dev, "regulator init failed: %d\n", err); goto error; diff --git a/trunk/drivers/regulator/max8660.c b/trunk/drivers/regulator/max8660.c deleted file mode 100644 index acc2fb7b6087..000000000000 --- a/trunk/drivers/regulator/max8660.c +++ /dev/null @@ -1,510 +0,0 @@ -/* - * max8660.c -- Voltage regulation for the Maxim 8660/8661 - * - * based on max1586.c and wm8400-regulator.c - * - * Copyright (C) 2009 Wolfram Sang, Pengutronix e.K. - * - * 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., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - * - * Some info: - * - * Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX8660-MAX8661.pdf - * - * This chip is a bit nasty because it is a write-only device. Thus, the driver - * uses shadow registers to keep track of its values. The main problem appears - * to be the initialization: When Linux boots up, we cannot know if the chip is - * in the default state or not, so we would have to pass such information in - * platform_data. As this adds a bit of complexity to the driver, this is left - * out for now until it is really needed. - * - * [A|S|M]DTV1 registers are currently not used, but [A|S|M]DTV2. - * - * If the driver is feature complete, it might be worth to check if one set of - * functions for V3-V7 is sufficient. For maximum flexibility during - * development, they are separated for now. - * - */ - -#include -#include -#include -#include -#include -#include - -#define MAX8660_DCDC_MIN_UV 725000 -#define MAX8660_DCDC_MAX_UV 1800000 -#define MAX8660_DCDC_STEP 25000 -#define MAX8660_DCDC_MAX_SEL 0x2b - -#define MAX8660_LDO5_MIN_UV 1700000 -#define MAX8660_LDO5_MAX_UV 2000000 -#define MAX8660_LDO5_STEP 25000 -#define MAX8660_LDO5_MAX_SEL 0x0c - -#define MAX8660_LDO67_MIN_UV 1800000 -#define MAX8660_LDO67_MAX_UV 3300000 -#define MAX8660_LDO67_STEP 100000 -#define MAX8660_LDO67_MAX_SEL 0x0f - -enum { - MAX8660_OVER1, - MAX8660_OVER2, - MAX8660_VCC1, - MAX8660_ADTV1, - MAX8660_ADTV2, - MAX8660_SDTV1, - MAX8660_SDTV2, - MAX8660_MDTV1, - MAX8660_MDTV2, - MAX8660_L12VCR, - MAX8660_FPWM, - MAX8660_N_REGS, /* not a real register */ -}; - -struct max8660 { - struct i2c_client *client; - u8 shadow_regs[MAX8660_N_REGS]; /* as chip is write only */ - struct regulator_dev *rdev[]; -}; - -static int max8660_write(struct max8660 *max8660, u8 reg, u8 mask, u8 val) -{ - static const u8 max8660_addresses[MAX8660_N_REGS] = - { 0x10, 0x12, 0x20, 0x23, 0x24, 0x29, 0x2a, 0x32, 0x33, 0x39, 0x80 }; - - int ret; - u8 reg_val = (max8660->shadow_regs[reg] & mask) | val; - dev_vdbg(&max8660->client->dev, "Writing reg %02x with %02x\n", - max8660_addresses[reg], reg_val); - - ret = i2c_smbus_write_byte_data(max8660->client, - max8660_addresses[reg], reg_val); - if (ret == 0) - max8660->shadow_regs[reg] = reg_val; - - return ret; -} - - -/* - * DCDC functions - */ - -static int max8660_dcdc_is_enabled(struct regulator_dev *rdev) -{ - struct max8660 *max8660 = rdev_get_drvdata(rdev); - u8 val = max8660->shadow_regs[MAX8660_OVER1]; - u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; - return !!(val & mask); -} - -static int max8660_dcdc_enable(struct regulator_dev *rdev) -{ - struct max8660 *max8660 = rdev_get_drvdata(rdev); - u8 bit = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4; - return max8660_write(max8660, MAX8660_OVER1, 0xff, bit); -} - -static int max8660_dcdc_disable(struct regulator_dev *rdev) -{ - struct max8660 *max8660 = rdev_get_drvdata(rdev); - u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? ~1 : ~4; - return max8660_write(max8660, MAX8660_OVER1, mask, 0); -} - -static int max8660_dcdc_list(struct regulator_dev *rdev, unsigned selector) -{ - if (selector > MAX8660_DCDC_MAX_SEL) - return -EINVAL; - return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP; -} - -static int max8660_dcdc_get(struct regulator_dev *rdev) -{ - struct max8660 *max8660 = rdev_get_drvdata(rdev); - u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; - u8 selector = max8660->shadow_regs[reg]; - return MAX8660_DCDC_MIN_UV + selector * MAX8660_DCDC_STEP; -} - -static int max8660_dcdc_set(struct regulator_dev *rdev, int min_uV, int max_uV) -{ - struct max8660 *max8660 = rdev_get_drvdata(rdev); - u8 reg, selector, bits; - int ret; - - if (min_uV < MAX8660_DCDC_MIN_UV || min_uV > MAX8660_DCDC_MAX_UV) - return -EINVAL; - if (max_uV < MAX8660_DCDC_MIN_UV || max_uV > MAX8660_DCDC_MAX_UV) - return -EINVAL; - - selector = (min_uV - (MAX8660_DCDC_MIN_UV - MAX8660_DCDC_STEP + 1)) - / MAX8660_DCDC_STEP; - - ret = max8660_dcdc_list(rdev, selector); - if (ret < 0 || ret > max_uV) - return -EINVAL; - - reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2; - ret = max8660_write(max8660, reg, 0, selector); - if (ret) - return ret; - - /* Select target voltage register and activate regulation */ - bits = (rdev_get_id(rdev) == MAX8660_V3) ? 0x03 : 0x30; - return max8660_write(max8660, MAX8660_VCC1, 0xff, bits); -} - -static struct regulator_ops max8660_dcdc_ops = { - .is_enabled = max8660_dcdc_is_enabled, - .list_voltage = max8660_dcdc_list, - .set_voltage = max8660_dcdc_set, - .get_voltage = max8660_dcdc_get, -}; - - -/* - * LDO5 functions - */ - -static int max8660_ldo5_list(struct regulator_dev *rdev, unsigned selector) -{ - if (selector > MAX8660_LDO5_MAX_SEL) - return -EINVAL; - return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP; -} - -static int max8660_ldo5_get(struct regulator_dev *rdev) -{ - struct max8660 *max8660 = rdev_get_drvdata(rdev); - u8 selector = max8660->shadow_regs[MAX8660_MDTV2]; - - return MAX8660_LDO5_MIN_UV + selector * MAX8660_LDO5_STEP; -} - -static int max8660_ldo5_set(struct regulator_dev *rdev, int min_uV, int max_uV) -{ - struct max8660 *max8660 = rdev_get_drvdata(rdev); - u8 selector; - int ret; - - if (min_uV < MAX8660_LDO5_MIN_UV || min_uV > MAX8660_LDO5_MAX_UV) - return -EINVAL; - if (max_uV < MAX8660_LDO5_MIN_UV || max_uV > MAX8660_LDO5_MAX_UV) - return -EINVAL; - - selector = (min_uV - (MAX8660_LDO5_MIN_UV - MAX8660_LDO5_STEP + 1)) - / MAX8660_LDO5_STEP; - ret = max8660_ldo5_list(rdev, selector); - if (ret < 0 || ret > max_uV) - return -EINVAL; - - ret = max8660_write(max8660, MAX8660_MDTV2, 0, selector); - if (ret) - return ret; - - /* Select target voltage register and activate regulation */ - return max8660_write(max8660, MAX8660_VCC1, 0xff, 0xc0); -} - -static struct regulator_ops max8660_ldo5_ops = { - .list_voltage = max8660_ldo5_list, - .set_voltage = max8660_ldo5_set, - .get_voltage = max8660_ldo5_get, -}; - - -/* - * LDO67 functions - */ - -static int max8660_ldo67_is_enabled(struct regulator_dev *rdev) -{ - struct max8660 *max8660 = rdev_get_drvdata(rdev); - u8 val = max8660->shadow_regs[MAX8660_OVER2]; - u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; - return !!(val & mask); -} - -static int max8660_ldo67_enable(struct regulator_dev *rdev) -{ - struct max8660 *max8660 = rdev_get_drvdata(rdev); - u8 bit = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4; - return max8660_write(max8660, MAX8660_OVER2, 0xff, bit); -} - -static int max8660_ldo67_disable(struct regulator_dev *rdev) -{ - struct max8660 *max8660 = rdev_get_drvdata(rdev); - u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? ~2 : ~4; - return max8660_write(max8660, MAX8660_OVER2, mask, 0); -} - -static int max8660_ldo67_list(struct regulator_dev *rdev, unsigned selector) -{ - if (selector > MAX8660_LDO67_MAX_SEL) - return -EINVAL; - return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP; -} - -static int max8660_ldo67_get(struct regulator_dev *rdev) -{ - struct max8660 *max8660 = rdev_get_drvdata(rdev); - u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4; - u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf; - - return MAX8660_LDO67_MIN_UV + selector * MAX8660_LDO67_STEP; -} - -static int max8660_ldo67_set(struct regulator_dev *rdev, int min_uV, int max_uV) -{ - struct max8660 *max8660 = rdev_get_drvdata(rdev); - u8 selector; - int ret; - - if (min_uV < MAX8660_LDO67_MIN_UV || min_uV > MAX8660_LDO67_MAX_UV) - return -EINVAL; - if (max_uV < MAX8660_LDO67_MIN_UV || max_uV > MAX8660_LDO67_MAX_UV) - return -EINVAL; - - selector = (min_uV - (MAX8660_LDO67_MIN_UV - MAX8660_LDO67_STEP + 1)) - / MAX8660_LDO67_STEP; - - ret = max8660_ldo67_list(rdev, selector); - if (ret < 0 || ret > max_uV) - return -EINVAL; - - if (rdev_get_id(rdev) == MAX8660_V6) - return max8660_write(max8660, MAX8660_L12VCR, 0xf0, selector); - else - return max8660_write(max8660, MAX8660_L12VCR, 0x0f, selector << 4); -} - -static struct regulator_ops max8660_ldo67_ops = { - .is_enabled = max8660_ldo67_is_enabled, - .enable = max8660_ldo67_enable, - .disable = max8660_ldo67_disable, - .list_voltage = max8660_ldo67_list, - .get_voltage = max8660_ldo67_get, - .set_voltage = max8660_ldo67_set, -}; - -static struct regulator_desc max8660_reg[] = { - { - .name = "V3(DCDC)", - .id = MAX8660_V3, - .ops = &max8660_dcdc_ops, - .type = REGULATOR_VOLTAGE, - .n_voltages = MAX8660_DCDC_MAX_SEL + 1, - .owner = THIS_MODULE, - }, - { - .name = "V4(DCDC)", - .id = MAX8660_V4, - .ops = &max8660_dcdc_ops, - .type = REGULATOR_VOLTAGE, - .n_voltages = MAX8660_DCDC_MAX_SEL + 1, - .owner = THIS_MODULE, - }, - { - .name = "V5(LDO)", - .id = MAX8660_V5, - .ops = &max8660_ldo5_ops, - .type = REGULATOR_VOLTAGE, - .n_voltages = MAX8660_LDO5_MAX_SEL + 1, - .owner = THIS_MODULE, - }, - { - .name = "V6(LDO)", - .id = MAX8660_V6, - .ops = &max8660_ldo67_ops, - .type = REGULATOR_VOLTAGE, - .n_voltages = MAX8660_LDO67_MAX_SEL + 1, - .owner = THIS_MODULE, - }, - { - .name = "V7(LDO)", - .id = MAX8660_V7, - .ops = &max8660_ldo67_ops, - .type = REGULATOR_VOLTAGE, - .n_voltages = MAX8660_LDO67_MAX_SEL + 1, - .owner = THIS_MODULE, - }, -}; - -static int max8660_probe(struct i2c_client *client, - const struct i2c_device_id *i2c_id) -{ - struct regulator_dev **rdev; - struct max8660_platform_data *pdata = client->dev.platform_data; - struct max8660 *max8660; - int boot_on, i, id, ret = -EINVAL; - - if (pdata->num_subdevs > MAX8660_V_END) { - dev_err(&client->dev, "Too much regulators found!\n"); - goto out; - } - - max8660 = kzalloc(sizeof(struct max8660) + - sizeof(struct regulator_dev *) * MAX8660_V_END, - GFP_KERNEL); - if (!max8660) { - ret = -ENOMEM; - goto out; - } - - max8660->client = client; - rdev = max8660->rdev; - - if (pdata->en34_is_high) { - /* Simulate always on */ - max8660->shadow_regs[MAX8660_OVER1] = 5; - } else { - /* Otherwise devices can be toggled via software */ - max8660_dcdc_ops.enable = max8660_dcdc_enable; - max8660_dcdc_ops.disable = max8660_dcdc_disable; - } - - /* - * First, set up shadow registers to prevent glitches. As some - * registers are shared between regulators, everything must be properly - * set up for all regulators in advance. - */ - max8660->shadow_regs[MAX8660_ADTV1] = - max8660->shadow_regs[MAX8660_ADTV2] = - max8660->shadow_regs[MAX8660_SDTV1] = - max8660->shadow_regs[MAX8660_SDTV2] = 0x1b; - max8660->shadow_regs[MAX8660_MDTV1] = - max8660->shadow_regs[MAX8660_MDTV2] = 0x04; - - for (i = 0; i < pdata->num_subdevs; i++) { - - if (!pdata->subdevs[i].platform_data) - goto err_free; - - boot_on = pdata->subdevs[i].platform_data->constraints.boot_on; - - switch (pdata->subdevs[i].id) { - case MAX8660_V3: - if (boot_on) - max8660->shadow_regs[MAX8660_OVER1] |= 1; - break; - - case MAX8660_V4: - if (boot_on) - max8660->shadow_regs[MAX8660_OVER1] |= 4; - break; - - case MAX8660_V5: - break; - - case MAX8660_V6: - if (boot_on) - max8660->shadow_regs[MAX8660_OVER2] |= 2; - break; - - case MAX8660_V7: - if (!strcmp(i2c_id->name, "max8661")) { - dev_err(&client->dev, "Regulator not on this chip!\n"); - goto err_free; - } - - if (boot_on) - max8660->shadow_regs[MAX8660_OVER2] |= 4; - break; - - default: - dev_err(&client->dev, "invalid regulator %s\n", - pdata->subdevs[i].name); - goto err_free; - } - } - - /* Finally register devices */ - for (i = 0; i < pdata->num_subdevs; i++) { - - id = pdata->subdevs[i].id; - - rdev[i] = regulator_register(&max8660_reg[id], &client->dev, - pdata->subdevs[i].platform_data, - max8660); - if (IS_ERR(rdev[i])) { - ret = PTR_ERR(rdev[i]); - dev_err(&client->dev, "failed to register %s\n", - max8660_reg[id].name); - goto err_unregister; - } - } - - i2c_set_clientdata(client, rdev); - dev_info(&client->dev, "Maxim 8660/8661 regulator driver loaded\n"); - return 0; - -err_unregister: - while (--i >= 0) - regulator_unregister(rdev[i]); -err_free: - kfree(max8660); -out: - return ret; -} - -static int max8660_remove(struct i2c_client *client) -{ - struct regulator_dev **rdev = i2c_get_clientdata(client); - int i; - - for (i = 0; i < MAX8660_V_END; i++) - if (rdev[i]) - regulator_unregister(rdev[i]); - kfree(rdev); - i2c_set_clientdata(client, NULL); - - return 0; -} - -static const struct i2c_device_id max8660_id[] = { - { "max8660", 0 }, - { "max8661", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, max8660_id); - -static struct i2c_driver max8660_driver = { - .probe = max8660_probe, - .remove = max8660_remove, - .driver = { - .name = "max8660", - }, - .id_table = max8660_id, -}; - -static int __init max8660_init(void) -{ - return i2c_add_driver(&max8660_driver); -} -subsys_initcall(max8660_init); - -static void __exit max8660_exit(void) -{ - i2c_del_driver(&max8660_driver); -} -module_exit(max8660_exit); - -/* Module information */ -MODULE_DESCRIPTION("MAXIM 8660/8661 voltage regulator driver"); -MODULE_AUTHOR("Wolfram Sang"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/regulator/mc13783-regulator.c b/trunk/drivers/regulator/mc13783-regulator.c deleted file mode 100644 index 39c495300045..000000000000 --- a/trunk/drivers/regulator/mc13783-regulator.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Regulator Driver for Freescale MC13783 PMIC - * - * Copyright (C) 2008 Sascha Hauer, Pengutronix - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define MC13783_REG_SWITCHERS4 28 -#define MC13783_REG_SWITCHERS4_PLLEN (1 << 18) - -#define MC13783_REG_SWITCHERS5 29 -#define MC13783_REG_SWITCHERS5_SW3EN (1 << 20) - -#define MC13783_REG_REGULATORMODE0 32 -#define MC13783_REG_REGULATORMODE0_VAUDIOEN (1 << 0) -#define MC13783_REG_REGULATORMODE0_VIOHIEN (1 << 3) -#define MC13783_REG_REGULATORMODE0_VIOLOEN (1 << 6) -#define MC13783_REG_REGULATORMODE0_VDIGEN (1 << 9) -#define MC13783_REG_REGULATORMODE0_VGENEN (1 << 12) -#define MC13783_REG_REGULATORMODE0_VRFDIGEN (1 << 15) -#define MC13783_REG_REGULATORMODE0_VRFREFEN (1 << 18) -#define MC13783_REG_REGULATORMODE0_VRFCPEN (1 << 21) - -#define MC13783_REG_REGULATORMODE1 33 -#define MC13783_REG_REGULATORMODE1_VSIMEN (1 << 0) -#define MC13783_REG_REGULATORMODE1_VESIMEN (1 << 3) -#define MC13783_REG_REGULATORMODE1_VCAMEN (1 << 6) -#define MC13783_REG_REGULATORMODE1_VRFBGEN (1 << 9) -#define MC13783_REG_REGULATORMODE1_VVIBEN (1 << 11) -#define MC13783_REG_REGULATORMODE1_VRF1EN (1 << 12) -#define MC13783_REG_REGULATORMODE1_VRF2EN (1 << 15) -#define MC13783_REG_REGULATORMODE1_VMMC1EN (1 << 18) -#define MC13783_REG_REGULATORMODE1_VMMC2EN (1 << 21) - -#define MC13783_REG_POWERMISC 34 -#define MC13783_REG_POWERMISC_GPO1EN (1 << 6) -#define MC13783_REG_POWERMISC_GPO2EN (1 << 8) -#define MC13783_REG_POWERMISC_GPO3EN (1 << 10) -#define MC13783_REG_POWERMISC_GPO4EN (1 << 12) - -struct mc13783_regulator { - struct regulator_desc desc; - int reg; - int enable_bit; -}; - -static struct regulator_ops mc13783_regulator_ops; - -#define MC13783_DEFINE(prefix, _name, _reg) \ - [MC13783_ ## prefix ## _ ## _name] = { \ - .desc = { \ - .name = #prefix "_" #_name, \ - .ops = &mc13783_regulator_ops, \ - .type = REGULATOR_VOLTAGE, \ - .id = MC13783_ ## prefix ## _ ## _name, \ - .owner = THIS_MODULE, \ - }, \ - .reg = MC13783_REG_ ## _reg, \ - .enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN, \ - } - -#define MC13783_DEFINE_SW(_name, _reg) MC13783_DEFINE(SW, _name, _reg) -#define MC13783_DEFINE_REGU(_name, _reg) MC13783_DEFINE(REGU, _name, _reg) - -static struct mc13783_regulator mc13783_regulators[] = { - MC13783_DEFINE_SW(SW3, SWITCHERS5), - MC13783_DEFINE_SW(PLL, SWITCHERS4), - - MC13783_DEFINE_REGU(VAUDIO, REGULATORMODE0), - MC13783_DEFINE_REGU(VIOHI, REGULATORMODE0), - MC13783_DEFINE_REGU(VIOLO, REGULATORMODE0), - MC13783_DEFINE_REGU(VDIG, REGULATORMODE0), - MC13783_DEFINE_REGU(VGEN, REGULATORMODE0), - MC13783_DEFINE_REGU(VRFDIG, REGULATORMODE0), - MC13783_DEFINE_REGU(VRFREF, REGULATORMODE0), - MC13783_DEFINE_REGU(VRFCP, REGULATORMODE0), - MC13783_DEFINE_REGU(VSIM, REGULATORMODE1), - MC13783_DEFINE_REGU(VESIM, REGULATORMODE1), - MC13783_DEFINE_REGU(VCAM, REGULATORMODE1), - MC13783_DEFINE_REGU(VRFBG, REGULATORMODE1), - MC13783_DEFINE_REGU(VVIB, REGULATORMODE1), - MC13783_DEFINE_REGU(VRF1, REGULATORMODE1), - MC13783_DEFINE_REGU(VRF2, REGULATORMODE1), - MC13783_DEFINE_REGU(VMMC1, REGULATORMODE1), - MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1), - MC13783_DEFINE_REGU(GPO1, POWERMISC), - MC13783_DEFINE_REGU(GPO2, POWERMISC), - MC13783_DEFINE_REGU(GPO3, POWERMISC), - MC13783_DEFINE_REGU(GPO4, POWERMISC), -}; - -struct mc13783_regulator_priv { - struct mc13783 *mc13783; - struct regulator_dev *regulators[]; -}; - -static int mc13783_regulator_enable(struct regulator_dev *rdev) -{ - struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); - int ret; - - dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); - - mc13783_lock(priv->mc13783); - ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].reg, - mc13783_regulators[id].enable_bit, - mc13783_regulators[id].enable_bit); - mc13783_unlock(priv->mc13783); - - return ret; -} - -static int mc13783_regulator_disable(struct regulator_dev *rdev) -{ - struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); - int ret; - - dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); - - mc13783_lock(priv->mc13783); - ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].reg, - mc13783_regulators[id].enable_bit, 0); - mc13783_unlock(priv->mc13783); - - return ret; -} - -static int mc13783_regulator_is_enabled(struct regulator_dev *rdev) -{ - struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); - int ret, id = rdev_get_id(rdev); - unsigned int val; - - mc13783_lock(priv->mc13783); - ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val); - mc13783_unlock(priv->mc13783); - - if (ret) - return ret; - - return (val & mc13783_regulators[id].enable_bit) != 0; -} - -static struct regulator_ops mc13783_regulator_ops = { - .enable = mc13783_regulator_enable, - .disable = mc13783_regulator_disable, - .is_enabled = mc13783_regulator_is_enabled, -}; - -static int __devinit mc13783_regulator_probe(struct platform_device *pdev) -{ - struct mc13783_regulator_priv *priv; - struct mc13783 *mc13783 = dev_get_drvdata(pdev->dev.parent); - struct mc13783_regulator_platform_data *pdata = - dev_get_platdata(&pdev->dev); - struct mc13783_regulator_init_data *init_data; - int i, ret; - - dev_dbg(&pdev->dev, "mc13783_regulator_probe id %d\n", pdev->id); - - priv = kzalloc(sizeof(*priv) + - pdata->num_regulators * sizeof(priv->regulators[0]), - GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->mc13783 = mc13783; - - for (i = 0; i < pdata->num_regulators; i++) { - init_data = &pdata->regulators[i]; - priv->regulators[i] = regulator_register( - &mc13783_regulators[init_data->id].desc, - &pdev->dev, init_data->init_data, priv); - - if (IS_ERR(priv->regulators[i])) { - dev_err(&pdev->dev, "failed to register regulator %s\n", - mc13783_regulators[i].desc.name); - ret = PTR_ERR(priv->regulators[i]); - goto err; - } - } - - platform_set_drvdata(pdev, priv); - - return 0; -err: - while (--i >= 0) - regulator_unregister(priv->regulators[i]); - - kfree(priv); - - return ret; -} - -static int __devexit mc13783_regulator_remove(struct platform_device *pdev) -{ - struct mc13783_regulator_priv *priv = platform_get_drvdata(pdev); - struct mc13783_regulator_platform_data *pdata = - dev_get_platdata(&pdev->dev); - int i; - - for (i = 0; i < pdata->num_regulators; i++) - regulator_unregister(priv->regulators[i]); - - return 0; -} - -static struct platform_driver mc13783_regulator_driver = { - .driver = { - .name = "mc13783-regulator", - .owner = THIS_MODULE, - }, - .remove = __devexit_p(mc13783_regulator_remove), - .probe = mc13783_regulator_probe, -}; - -static int __init mc13783_regulator_init(void) -{ - return platform_driver_register(&mc13783_regulator_driver); -} -subsys_initcall(mc13783_regulator_init); - -static void __exit mc13783_regulator_exit(void) -{ - platform_driver_unregister(&mc13783_regulator_driver); -} -module_exit(mc13783_regulator_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Sascha Hauer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct mc13783_regulator { + struct regulator_desc desc; + int reg; + int enable_bit; +}; + +static struct regulator_ops mc13783_regulator_ops; + +static struct mc13783_regulator mc13783_regulators[] = { + [MC13783_SW_SW3] = { + .desc = { + .name = "SW_SW3", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_SW_SW3, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_SWITCHERS_5, + .enable_bit = MC13783_SWCTRL_SW3_EN, + }, + [MC13783_SW_PLL] = { + .desc = { + .name = "SW_PLL", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_SW_PLL, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_SWITCHERS_4, + .enable_bit = MC13783_SWCTRL_PLL_EN, + }, + [MC13783_REGU_VAUDIO] = { + .desc = { + .name = "REGU_VAUDIO", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VAUDIO, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VAUDIO_EN, + }, + [MC13783_REGU_VIOHI] = { + .desc = { + .name = "REGU_VIOHI", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VIOHI, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VIOHI_EN, + }, + [MC13783_REGU_VIOLO] = { + .desc = { + .name = "REGU_VIOLO", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VIOLO, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VIOLO_EN, + }, + [MC13783_REGU_VDIG] = { + .desc = { + .name = "REGU_VDIG", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VDIG, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VDIG_EN, + }, + [MC13783_REGU_VGEN] = { + .desc = { + .name = "REGU_VGEN", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VGEN, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VGEN_EN, + }, + [MC13783_REGU_VRFDIG] = { + .desc = { + .name = "REGU_VRFDIG", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VRFDIG, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VRFDIG_EN, + }, + [MC13783_REGU_VRFREF] = { + .desc = { + .name = "REGU_VRFREF", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VRFREF, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VRFREF_EN, + }, + [MC13783_REGU_VRFCP] = { + .desc = { + .name = "REGU_VRFCP", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VRFCP, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_0, + .enable_bit = MC13783_REGCTRL_VRFCP_EN, + }, + [MC13783_REGU_VSIM] = { + .desc = { + .name = "REGU_VSIM", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VSIM, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VSIM_EN, + }, + [MC13783_REGU_VESIM] = { + .desc = { + .name = "REGU_VESIM", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VESIM, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VESIM_EN, + }, + [MC13783_REGU_VCAM] = { + .desc = { + .name = "REGU_VCAM", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VCAM, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VCAM_EN, + }, + [MC13783_REGU_VRFBG] = { + .desc = { + .name = "REGU_VRFBG", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VRFBG, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VRFBG_EN, + }, + [MC13783_REGU_VVIB] = { + .desc = { + .name = "REGU_VVIB", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VVIB, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VVIB_EN, + }, + [MC13783_REGU_VRF1] = { + .desc = { + .name = "REGU_VRF1", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VRF1, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VRF1_EN, + }, + [MC13783_REGU_VRF2] = { + .desc = { + .name = "REGU_VRF2", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VRF2, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VRF2_EN, + }, + [MC13783_REGU_VMMC1] = { + .desc = { + .name = "REGU_VMMC1", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VMMC1, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VMMC1_EN, + }, + [MC13783_REGU_VMMC2] = { + .desc = { + .name = "REGU_VMMC2", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_VMMC2, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_REGULATOR_MODE_1, + .enable_bit = MC13783_REGCTRL_VMMC2_EN, + }, + [MC13783_REGU_GPO1] = { + .desc = { + .name = "REGU_GPO1", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_GPO1, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_POWER_MISCELLANEOUS, + .enable_bit = MC13783_REGCTRL_GPO1_EN, + }, + [MC13783_REGU_GPO2] = { + .desc = { + .name = "REGU_GPO2", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_GPO2, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_POWER_MISCELLANEOUS, + .enable_bit = MC13783_REGCTRL_GPO2_EN, + }, + [MC13783_REGU_GPO3] = { + .desc = { + .name = "REGU_GPO3", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_GPO3, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_POWER_MISCELLANEOUS, + .enable_bit = MC13783_REGCTRL_GPO3_EN, + }, + [MC13783_REGU_GPO4] = { + .desc = { + .name = "REGU_GPO4", + .ops = &mc13783_regulator_ops, + .type = REGULATOR_VOLTAGE, + .id = MC13783_REGU_GPO4, + .owner = THIS_MODULE, + }, + .reg = MC13783_REG_POWER_MISCELLANEOUS, + .enable_bit = MC13783_REGCTRL_GPO4_EN, + }, +}; + +struct mc13783_priv { + struct regulator_desc desc[ARRAY_SIZE(mc13783_regulators)]; + struct mc13783 *mc13783; + struct regulator_dev *regulators[0]; +}; + +static int mc13783_enable(struct regulator_dev *rdev) +{ + struct mc13783_priv *priv = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + + dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); + + return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg, + mc13783_regulators[id].enable_bit, + mc13783_regulators[id].enable_bit); +} + +static int mc13783_disable(struct regulator_dev *rdev) +{ + struct mc13783_priv *priv = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + + dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); + + return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg, + mc13783_regulators[id].enable_bit, 0); +} + +static int mc13783_is_enabled(struct regulator_dev *rdev) +{ + struct mc13783_priv *priv = rdev_get_drvdata(rdev); + int ret, id = rdev_get_id(rdev); + unsigned int val; + + ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val); + if (ret) + return ret; + + return (val & mc13783_regulators[id].enable_bit) != 0; +} + +static struct regulator_ops mc13783_regulator_ops = { + .enable = mc13783_enable, + .disable = mc13783_disable, + .is_enabled = mc13783_is_enabled, +}; + +static int __devinit mc13783_regulator_probe(struct platform_device *pdev) +{ + struct mc13783_priv *priv; + struct mc13783 *mc13783 = dev_get_drvdata(pdev->dev.parent); + struct mc13783_regulator_init_data *init_data; + int i, ret; + + dev_dbg(&pdev->dev, "mc13783_regulator_probe id %d\n", pdev->id); + + priv = kzalloc(sizeof(*priv) + mc13783->num_regulators * sizeof(void *), + GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->mc13783 = mc13783; + + for (i = 0; i < mc13783->num_regulators; i++) { + init_data = &mc13783->regulators[i]; + priv->regulators[i] = regulator_register( + &mc13783_regulators[init_data->id].desc, + &pdev->dev, init_data->init_data, priv); + + if (IS_ERR(priv->regulators[i])) { + dev_err(&pdev->dev, "failed to register regulator %s\n", + mc13783_regulators[i].desc.name); + ret = PTR_ERR(priv->regulators[i]); + goto err; + } + } + + platform_set_drvdata(pdev, priv); + + return 0; +err: + while (--i >= 0) + regulator_unregister(priv->regulators[i]); + + kfree(priv); + + return ret; +} + +static int __devexit mc13783_regulator_remove(struct platform_device *pdev) +{ + struct mc13783_priv *priv = platform_get_drvdata(pdev); + struct mc13783 *mc13783 = priv->mc13783; + int i; + + for (i = 0; i < mc13783->num_regulators; i++) + regulator_unregister(priv->regulators[i]); + + return 0; +} + +static struct platform_driver mc13783_regulator_driver = { + .driver = { + .name = "mc13783-regulator", + .owner = THIS_MODULE, + }, + .remove = __devexit_p(mc13783_regulator_remove), +}; + +static int __init mc13783_regulator_init(void) +{ + return platform_driver_probe(&mc13783_regulator_driver, + mc13783_regulator_probe); +} +subsys_initcall(mc13783_regulator_init); + +static void __exit mc13783_regulator_exit(void) +{ + platform_driver_unregister(&mc13783_regulator_driver); +} +module_exit(mc13783_regulator_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Sascha Hauer #include #include -#include #include #include #include @@ -41,12 +40,6 @@ struct twlreg_info { u8 table_len; const u16 *table; - /* regulator specific turn-on delay */ - u16 delay; - - /* State REMAP default configuration */ - u8 remap; - /* chip constraints on regulator behavior */ u16 min_mV; @@ -135,7 +128,6 @@ static int twlreg_enable(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); int grp; - int ret; grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); if (grp < 0) @@ -146,11 +138,7 @@ static int twlreg_enable(struct regulator_dev *rdev) else grp |= P1_GRP_6030; - ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); - - udelay(info->delay); - - return ret; + return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); } static int twlreg_disable(struct regulator_dev *rdev) @@ -163,9 +151,9 @@ static int twlreg_disable(struct regulator_dev *rdev) return grp; if (twl_class_is_4030()) - grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030); + grp &= ~P1_GRP_4030; else - grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030); + grp &= ~P1_GRP_6030; return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); } @@ -306,18 +294,6 @@ static const u16 VSIM_VSEL_table[] = { static const u16 VDAC_VSEL_table[] = { 1200, 1300, 1800, 1800, }; -static const u16 VDD1_VSEL_table[] = { - 800, 1450, -}; -static const u16 VDD2_VSEL_table[] = { - 800, 1450, 1500, -}; -static const u16 VIO_VSEL_table[] = { - 1800, 1850, -}; -static const u16 VINTANA2_VSEL_table[] = { - 2500, 2750, -}; static const u16 VAUX1_6030_VSEL_table[] = { 1000, 1300, 1800, 2500, 2800, 2900, 3000, 3000, @@ -438,30 +414,20 @@ static struct regulator_ops twlfixed_ops = { /*----------------------------------------------------------------------*/ -#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \ - TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ - remap_conf, TWL4030) -#define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ - remap_conf) \ - TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ - remap_conf, TWL4030) -#define TWL6030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ - remap_conf) \ - TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, \ - remap_conf, TWL6030) -#define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ - remap_conf) \ - TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ - remap_conf, TWL6030) - -#define TWL_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf, \ - family) { \ +#define TWL4030_ADJUSTABLE_LDO(label, offset, num) \ + TWL_ADJUSTABLE_LDO(label, offset, num, TWL4030) +#define TWL4030_FIXED_LDO(label, offset, mVolts, num) \ + TWL_FIXED_LDO(label, offset, mVolts, num, TWL4030) +#define TWL6030_ADJUSTABLE_LDO(label, offset, num) \ + TWL_ADJUSTABLE_LDO(label, offset, num, TWL6030) +#define TWL6030_FIXED_LDO(label, offset, mVolts, num) \ + TWL_FIXED_LDO(label, offset, mVolts, num, TWL6030) + +#define TWL_ADJUSTABLE_LDO(label, offset, num, family) { \ .base = offset, \ .id = num, \ .table_len = ARRAY_SIZE(label##_VSEL_table), \ .table = label##_VSEL_table, \ - .delay = turnon_delay, \ - .remap = remap_conf, \ .desc = { \ .name = #label, \ .id = family##_REG_##label, \ @@ -472,13 +438,10 @@ static struct regulator_ops twlfixed_ops = { }, \ } -#define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ - family) { \ +#define TWL_FIXED_LDO(label, offset, mVolts, num, family) { \ .base = offset, \ .id = num, \ .min_mV = mVolts, \ - .delay = turnon_delay, \ - .remap = remap_conf, \ .desc = { \ .name = #label, \ .id = family##_REG_##label, \ @@ -494,41 +457,43 @@ static struct regulator_ops twlfixed_ops = { * software control over them after boot. */ static struct twlreg_info twl_regs[] = { - TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1, 100, 0x08), - TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2, 100, 0x08), - TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2, 100, 0x08), - TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3, 100, 0x08), - TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4, 100, 0x08), - TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5, 100, 0x08), - TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6, 100, 0x08), - TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7, 100, 0x00), - TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8, 100, 0x08), - TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9, 100, 0x00), - TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10, 100, 0x08), - TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08), - TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08), - TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08), - TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08), - TWL4030_ADJUSTABLE_LDO(VDD1, 0x55, 15, 1000, 0x08), - TWL4030_ADJUSTABLE_LDO(VDD2, 0x63, 16, 1000, 0x08), - TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08), - TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08), - TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19, 150, 0x08), + TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1), + TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2), + TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2), + TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3), + TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4), + TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5), + TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6), + /* + TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7), + */ + TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8), + TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9), + TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10), + /* + TWL4030_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11), + TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12), + TWL4030_ADJUSTABLE_LDO(VINTDIG, 0x47, 13), + TWL4030_SMPS(VIO, 0x4b, 14), + TWL4030_SMPS(VDD1, 0x55, 15), + TWL4030_SMPS(VDD2, 0x63, 16), + */ + TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17), + TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18), + TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19), /* VUSBCP is managed *only* by the USB subchip */ /* 6030 REG with base as PMC Slave Misc : 0x0030 */ - /* Turnon-delay and remap configuration values for 6030 are not - verified since the specification is not public */ - TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1, 0, 0x08), - TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 2, 0, 0x08), - TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 3, 0, 0x08), - TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 4, 0, 0x08), - TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 5, 0, 0x08), - TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 7, 0, 0x08), - TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x08), - TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x08), - TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x08), - TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x08) + TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1), + TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 2), + TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 3), + TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 4), + TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 5), + TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 7), + TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15), + TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16), + TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17), + TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18) }; static int twlreg_probe(struct platform_device *pdev) @@ -560,19 +525,6 @@ static int twlreg_probe(struct platform_device *pdev) c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS; - switch (pdev->id) { - case TWL4030_REG_VIO: - case TWL4030_REG_VDD1: - case TWL4030_REG_VDD2: - case TWL4030_REG_VPLL1: - case TWL4030_REG_VINTANA1: - case TWL4030_REG_VINTANA2: - case TWL4030_REG_VINTDIG: - c->always_on = true; - break; - default: - break; - } rdev = regulator_register(&info->desc, &pdev->dev, initdata, info); if (IS_ERR(rdev)) { @@ -582,9 +534,6 @@ static int twlreg_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, rdev); - twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP, - info->remap); - /* NOTE: many regulators support short-circuit IRQs (presentable * as REGULATOR_OVER_CURRENT notifications?) configured via: * - SC_CONFIG diff --git a/trunk/drivers/regulator/wm831x-dcdc.c b/trunk/drivers/regulator/wm831x-dcdc.c index 0a6577577e8d..2eefc1a0cf08 100644 --- a/trunk/drivers/regulator/wm831x-dcdc.c +++ b/trunk/drivers/regulator/wm831x-dcdc.c @@ -19,8 +19,6 @@ #include #include #include -#include -#include #include #include @@ -41,7 +39,6 @@ #define WM831X_DCDC_CONTROL_2 1 #define WM831X_DCDC_ON_CONFIG 2 #define WM831X_DCDC_SLEEP_CONTROL 3 -#define WM831X_DCDC_DVS_CONTROL 4 /* * Shared @@ -53,10 +50,6 @@ struct wm831x_dcdc { int base; struct wm831x *wm831x; struct regulator_dev *regulator; - int dvs_gpio; - int dvs_gpio_state; - int on_vsel; - int dvs_vsel; }; static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev) @@ -247,9 +240,11 @@ static int wm831x_buckv_list_voltage(struct regulator_dev *rdev, return -EINVAL; } -static int wm831x_buckv_select_min_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) +static int wm831x_buckv_set_voltage_int(struct regulator_dev *rdev, int reg, + int min_uV, int max_uV) { + struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); + struct wm831x *wm831x = dcdc->wm831x; u16 vsel; if (min_uV < 600000) @@ -262,126 +257,39 @@ static int wm831x_buckv_select_min_voltage(struct regulator_dev *rdev, if (wm831x_buckv_list_voltage(rdev, vsel) > max_uV) return -EINVAL; - return vsel; -} - -static int wm831x_buckv_select_max_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - u16 vsel; - - if (max_uV < 600000 || max_uV > 1800000) - return -EINVAL; - - vsel = ((max_uV - 600000) / 12500) + 8; - - if (wm831x_buckv_list_voltage(rdev, vsel) < min_uV || - wm831x_buckv_list_voltage(rdev, vsel) < max_uV) - return -EINVAL; - - return vsel; -} - -static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state) -{ - struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); - - if (state == dcdc->dvs_gpio_state) - return 0; - - dcdc->dvs_gpio_state = state; - gpio_set_value(dcdc->dvs_gpio, state); - - /* Should wait for DVS state change to be asserted if we have - * a GPIO for it, for now assume the device is configured - * for the fastest possible transition. - */ - - return 0; + return wm831x_set_bits(wm831x, reg, WM831X_DC1_ON_VSEL_MASK, vsel); } static int wm831x_buckv_set_voltage(struct regulator_dev *rdev, - int min_uV, int max_uV) + int min_uV, int max_uV) { struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); - struct wm831x *wm831x = dcdc->wm831x; - int on_reg = dcdc->base + WM831X_DCDC_ON_CONFIG; - int dvs_reg = dcdc->base + WM831X_DCDC_DVS_CONTROL; - int vsel, ret; - - vsel = wm831x_buckv_select_min_voltage(rdev, min_uV, max_uV); - if (vsel < 0) - return vsel; - - /* If this value is already set then do a GPIO update if we can */ - if (dcdc->dvs_gpio && dcdc->on_vsel == vsel) - return wm831x_buckv_set_dvs(rdev, 0); - - if (dcdc->dvs_gpio && dcdc->dvs_vsel == vsel) - return wm831x_buckv_set_dvs(rdev, 1); - - /* Always set the ON status to the minimum voltage */ - ret = wm831x_set_bits(wm831x, on_reg, WM831X_DC1_ON_VSEL_MASK, vsel); - if (ret < 0) - return ret; - dcdc->on_vsel = vsel; - - if (!dcdc->dvs_gpio) - return ret; - - /* Kick the voltage transition now */ - ret = wm831x_buckv_set_dvs(rdev, 0); - if (ret < 0) - return ret; - - /* Set the high voltage as the DVS voltage. This is optimised - * for CPUfreq usage, most processors will keep the maximum - * voltage constant and lower the minimum with the frequency. */ - vsel = wm831x_buckv_select_max_voltage(rdev, min_uV, max_uV); - if (vsel < 0) { - /* This should never happen - at worst the same vsel - * should be chosen */ - WARN_ON(vsel < 0); - return 0; - } - - /* Don't bother if it's the same VSEL we're already using */ - if (vsel == dcdc->on_vsel) - return 0; - - ret = wm831x_set_bits(wm831x, dvs_reg, WM831X_DC1_DVS_VSEL_MASK, vsel); - if (ret == 0) - dcdc->dvs_vsel = vsel; - else - dev_warn(wm831x->dev, "Failed to set DCDC DVS VSEL: %d\n", - ret); + u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG; - return 0; + return wm831x_buckv_set_voltage_int(rdev, reg, min_uV, max_uV); } static int wm831x_buckv_set_suspend_voltage(struct regulator_dev *rdev, - int uV) + int uV) { struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); - struct wm831x *wm831x = dcdc->wm831x; u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL; - int vsel; - - vsel = wm831x_buckv_select_min_voltage(rdev, uV, uV); - if (vsel < 0) - return vsel; - return wm831x_set_bits(wm831x, reg, WM831X_DC1_SLP_VSEL_MASK, vsel); + return wm831x_buckv_set_voltage_int(rdev, reg, uV, uV); } static int wm831x_buckv_get_voltage(struct regulator_dev *rdev) { struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev); + struct wm831x *wm831x = dcdc->wm831x; + u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG; + int val; - if (dcdc->dvs_gpio && dcdc->dvs_gpio_state) - return wm831x_buckv_list_voltage(rdev, dcdc->dvs_vsel); - else - return wm831x_buckv_list_voltage(rdev, dcdc->on_vsel); + val = wm831x_reg_read(wm831x, reg); + if (val < 0) + return val; + + return wm831x_buckv_list_voltage(rdev, val & WM831X_DC1_ON_VSEL_MASK); } /* Current limit options */ @@ -438,64 +346,6 @@ static struct regulator_ops wm831x_buckv_ops = { .set_suspend_mode = wm831x_dcdc_set_suspend_mode, }; -/* - * Set up DVS control. We just log errors since we can still run - * (with reduced performance) if we fail. - */ -static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc, - struct wm831x_buckv_pdata *pdata) -{ - struct wm831x *wm831x = dcdc->wm831x; - int ret; - u16 ctrl; - - if (!pdata || !pdata->dvs_gpio) - return; - - switch (pdata->dvs_control_src) { - case 1: - ctrl = 2 << WM831X_DC1_DVS_SRC_SHIFT; - break; - case 2: - ctrl = 3 << WM831X_DC1_DVS_SRC_SHIFT; - break; - default: - dev_err(wm831x->dev, "Invalid DVS control source %d for %s\n", - pdata->dvs_control_src, dcdc->name); - return; - } - - ret = wm831x_set_bits(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL, - WM831X_DC1_DVS_SRC_MASK, ctrl); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to set %s DVS source: %d\n", - dcdc->name, ret); - return; - } - - ret = gpio_request(pdata->dvs_gpio, "DCDC DVS"); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n", - dcdc->name, ret); - return; - } - - /* gpiolib won't let us read the GPIO status so pick the higher - * of the two existing voltages so we take it as platform data. - */ - dcdc->dvs_gpio_state = pdata->dvs_init_state; - - ret = gpio_direction_output(pdata->dvs_gpio, dcdc->dvs_gpio_state); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to enable %s DVS GPIO: %d\n", - dcdc->name, ret); - gpio_free(pdata->dvs_gpio); - return; - } - - dcdc->dvs_gpio = pdata->dvs_gpio; -} - static __devinit int wm831x_buckv_probe(struct platform_device *pdev) { struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); @@ -534,23 +384,6 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) dcdc->desc.ops = &wm831x_buckv_ops; dcdc->desc.owner = THIS_MODULE; - ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to read ON VSEL: %d\n", ret); - goto err; - } - dcdc->on_vsel = ret & WM831X_DC1_ON_VSEL_MASK; - - ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG); - if (ret < 0) { - dev_err(wm831x->dev, "Failed to read DVS VSEL: %d\n", ret); - goto err; - } - dcdc->dvs_vsel = ret & WM831X_DC1_DVS_VSEL_MASK; - - if (pdata->dcdc[id]) - wm831x_buckv_dvs_init(dcdc, pdata->dcdc[id]->driver_data); - dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev, pdata->dcdc[id], dcdc); if (IS_ERR(dcdc->regulator)) { @@ -589,8 +422,6 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) err_regulator: regulator_unregister(dcdc->regulator); err: - if (dcdc->dvs_gpio) - gpio_free(dcdc->dvs_gpio); kfree(dcdc); return ret; } @@ -603,8 +434,6 @@ static __devexit int wm831x_buckv_remove(struct platform_device *pdev) wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "HC"), dcdc); wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc); regulator_unregister(dcdc->regulator); - if (dcdc->dvs_gpio) - gpio_free(dcdc->dvs_gpio); kfree(dcdc); return 0; diff --git a/trunk/drivers/regulator/wm831x-ldo.c b/trunk/drivers/regulator/wm831x-ldo.c index 61e02ac2fda3..902db56ce099 100644 --- a/trunk/drivers/regulator/wm831x-ldo.c +++ b/trunk/drivers/regulator/wm831x-ldo.c @@ -470,7 +470,7 @@ static unsigned int wm831x_aldo_get_mode(struct regulator_dev *rdev) struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); struct wm831x *wm831x = ldo->wm831x; int on_reg = ldo->base + WM831X_LDO_ON_CONTROL; - int ret; + unsigned int ret; ret = wm831x_reg_read(wm831x, on_reg); if (ret < 0) diff --git a/trunk/drivers/rtc/rtc-ds1305.c b/trunk/drivers/rtc/rtc-ds1305.c index 9630e7d3314e..259db7f3535b 100644 --- a/trunk/drivers/rtc/rtc-ds1305.c +++ b/trunk/drivers/rtc/rtc-ds1305.c @@ -778,8 +778,6 @@ static int __devinit ds1305_probe(struct spi_device *spi) spi->irq, status); goto fail1; } - - device_set_wakeup_capable(&spi->dev, 1); } /* export NVRAM */ diff --git a/trunk/drivers/rtc/rtc-ds1307.c b/trunk/drivers/rtc/rtc-ds1307.c index c4ec5c158aa1..8a99da6f2f24 100644 --- a/trunk/drivers/rtc/rtc-ds1307.c +++ b/trunk/drivers/rtc/rtc-ds1307.c @@ -881,8 +881,6 @@ static int __devinit ds1307_probe(struct i2c_client *client, "unable to request IRQ!\n"); goto exit_irq; } - - device_set_wakeup_capable(&client->dev, 1); set_bit(HAS_ALARM, &ds1307->flags); dev_dbg(&client->dev, "got IRQ %d\n", client->irq); } diff --git a/trunk/drivers/rtc/rtc-ds1374.c b/trunk/drivers/rtc/rtc-ds1374.c index 5317bbcbc7a0..713f7bf5afb3 100644 --- a/trunk/drivers/rtc/rtc-ds1374.c +++ b/trunk/drivers/rtc/rtc-ds1374.c @@ -383,8 +383,6 @@ static int ds1374_probe(struct i2c_client *client, dev_err(&client->dev, "unable to request IRQ\n"); goto out_free; } - - device_set_wakeup_capable(&client->dev, 1); } ds1374->rtc = rtc_device_register(client->name, &client->dev, diff --git a/trunk/drivers/spi/Kconfig b/trunk/drivers/spi/Kconfig index f55eb0107336..2d9d70359360 100644 --- a/trunk/drivers/spi/Kconfig +++ b/trunk/drivers/spi/Kconfig @@ -216,17 +216,6 @@ config SPI_S3C24XX help SPI driver for Samsung S3C24XX series ARM SoCs -config SPI_S3C24XX_FIQ - bool "S3C24XX driver with FIQ pseudo-DMA" - depends on SPI_S3C24XX - select FIQ - help - Enable FIQ support for the S3C24XX SPI driver to provide pseudo - DMA by using the fast-interrupt request framework, This allows - the driver to get DMA-like performance when there are either - no free DMA channels, or when doing transfers that required both - TX and RX data paths. - config SPI_S3C24XX_GPIO tristate "Samsung S3C24XX series SPI by GPIO" depends on ARCH_S3C2410 && EXPERIMENTAL @@ -237,13 +226,6 @@ config SPI_S3C24XX_GPIO the inbuilt hardware cannot provide the transfer mode, or where the board is using non hardware connected pins. -config SPI_S3C64XX - tristate "Samsung S3C64XX series type SPI" - depends on ARCH_S3C64XX && EXPERIMENTAL - select S3C64XX_DMA - help - SPI driver for Samsung S3C64XX and newer SoCs. - config SPI_SH_MSIOF tristate "SuperH MSIOF SPI controller" depends on SUPERH && HAVE_CLK @@ -307,16 +289,6 @@ config SPI_NUC900 # Add new SPI master controllers in alphabetical order above this line # -config SPI_DESIGNWARE - bool "DesignWare SPI controller core support" - depends on SPI_MASTER - help - general driver for SPI controller core from DesignWare - -config SPI_DW_PCI - tristate "PCI interface driver for DW SPI core" - depends on SPI_DESIGNWARE && PCI - # # There are lots of SPI device types, with sensors and memory # being probably the most widely used ones. diff --git a/trunk/drivers/spi/Makefile b/trunk/drivers/spi/Makefile index f3d2810ba11c..ed8c1675b52f 100644 --- a/trunk/drivers/spi/Makefile +++ b/trunk/drivers/spi/Makefile @@ -16,8 +16,6 @@ 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_DESIGNWARE) += dw_spi.o -obj-$(CONFIG_SPI_DW_PCI) += dw_spi_pci.o obj-$(CONFIG_SPI_GPIO) += spi_gpio.o obj-$(CONFIG_SPI_IMX) += spi_imx.o obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o @@ -32,8 +30,7 @@ obj-$(CONFIG_SPI_MPC52xx) += mpc52xx_spi.o obj-$(CONFIG_SPI_MPC8xxx) += spi_mpc8xxx.o obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o -obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o -obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o +obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o obj-$(CONFIG_SPI_TXX9) += spi_txx9.o obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o @@ -42,11 +39,6 @@ obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o - -# special build for s3c24xx spi driver with fiq support -spi_s3c24xx_hw-y := spi_s3c24xx.o -spi_s3c24xx_hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi_s3c24xx_fiq.o - # ... add above this line ... # SPI protocol drivers (device/link on bus) diff --git a/trunk/drivers/spi/atmel_spi.c b/trunk/drivers/spi/atmel_spi.c index d21c24eaf0a9..f5b3fdbb1e27 100644 --- a/trunk/drivers/spi/atmel_spi.c +++ b/trunk/drivers/spi/atmel_spi.c @@ -189,14 +189,14 @@ static void atmel_spi_next_xfer_data(struct spi_master *master, /* use scratch buffer only when rx or tx data is unspecified */ if (xfer->rx_buf) - *rx_dma = xfer->rx_dma + xfer->len - *plen; + *rx_dma = xfer->rx_dma + xfer->len - len; else { *rx_dma = as->buffer_dma; if (len > BUFFER_SIZE) len = BUFFER_SIZE; } if (xfer->tx_buf) - *tx_dma = xfer->tx_dma + xfer->len - *plen; + *tx_dma = xfer->tx_dma + xfer->len - len; else { *tx_dma = as->buffer_dma; if (len > BUFFER_SIZE) @@ -788,7 +788,7 @@ static int __init atmel_spi_probe(struct platform_device *pdev) spin_lock_init(&as->lock); INIT_LIST_HEAD(&as->queue); as->pdev = pdev; - as->regs = ioremap(regs->start, resource_size(regs)); + as->regs = ioremap(regs->start, (regs->end - regs->start) + 1); if (!as->regs) goto out_free_buffer; as->irq = irq; diff --git a/trunk/drivers/spi/dw_spi.c b/trunk/drivers/spi/dw_spi.c deleted file mode 100644 index 31620fae77be..000000000000 --- a/trunk/drivers/spi/dw_spi.c +++ /dev/null @@ -1,944 +0,0 @@ -/* - * dw_spi.c - Designware SPI core controller driver (refer pxa2xx_spi.c) - * - * Copyright (c) 2009, 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., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include - -#include -#include - -#ifdef CONFIG_DEBUG_FS -#include -#endif - -#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 - -#define MRST_SPI_DEASSERT 0 -#define MRST_SPI_ASSERT 1 - -/* Slave spi_dev related */ -struct chip_data { - u16 cr0; - u8 cs; /* chip select pin */ - u8 n_bytes; /* current is a 1/2/4 byte op */ - u8 tmode; /* TR/TO/RO/EEPROM */ - u8 type; /* SPI/SSP/MicroWire */ - - u8 poll_mode; /* 1 means use poll mode */ - - u32 dma_width; - u32 rx_threshold; - u32 tx_threshold; - u8 enable_dma; - u8 bits_per_word; - u16 clk_div; /* baud rate divider */ - u32 speed_hz; /* baud rate */ - int (*write)(struct dw_spi *dws); - int (*read)(struct dw_spi *dws); - void (*cs_control)(u32 command); -}; - -#ifdef CONFIG_DEBUG_FS -static int spi_show_regs_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -#define SPI_REGS_BUFSIZE 1024 -static ssize_t spi_show_regs(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct dw_spi *dws; - char *buf; - u32 len = 0; - ssize_t ret; - - dws = file->private_data; - - buf = kzalloc(SPI_REGS_BUFSIZE, GFP_KERNEL); - if (!buf) - return 0; - - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "MRST SPI0 registers:\n"); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "=================================\n"); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "CTRL0: \t\t0x%08x\n", dw_readl(dws, ctrl0)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "CTRL1: \t\t0x%08x\n", dw_readl(dws, ctrl1)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "SSIENR: \t0x%08x\n", dw_readl(dws, ssienr)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "SER: \t\t0x%08x\n", dw_readl(dws, ser)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "BAUDR: \t\t0x%08x\n", dw_readl(dws, baudr)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "TXFTLR: \t0x%08x\n", dw_readl(dws, txfltr)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "RXFTLR: \t0x%08x\n", dw_readl(dws, rxfltr)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "TXFLR: \t\t0x%08x\n", dw_readl(dws, txflr)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "RXFLR: \t\t0x%08x\n", dw_readl(dws, rxflr)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "SR: \t\t0x%08x\n", dw_readl(dws, sr)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "IMR: \t\t0x%08x\n", dw_readl(dws, imr)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "ISR: \t\t0x%08x\n", dw_readl(dws, isr)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "DMACR: \t\t0x%08x\n", dw_readl(dws, dmacr)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "DMATDLR: \t0x%08x\n", dw_readl(dws, dmatdlr)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "DMARDLR: \t0x%08x\n", dw_readl(dws, dmardlr)); - len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, - "=================================\n"); - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - return ret; -} - -static const struct file_operations mrst_spi_regs_ops = { - .owner = THIS_MODULE, - .open = spi_show_regs_open, - .read = spi_show_regs, -}; - -static int mrst_spi_debugfs_init(struct dw_spi *dws) -{ - dws->debugfs = debugfs_create_dir("mrst_spi", NULL); - if (!dws->debugfs) - return -ENOMEM; - - debugfs_create_file("registers", S_IFREG | S_IRUGO, - dws->debugfs, (void *)dws, &mrst_spi_regs_ops); - return 0; -} - -static void mrst_spi_debugfs_remove(struct dw_spi *dws) -{ - if (dws->debugfs) - debugfs_remove_recursive(dws->debugfs); -} - -#else -static inline int mrst_spi_debugfs_init(struct dw_spi *dws) -{ -} - -static inline void mrst_spi_debugfs_remove(struct dw_spi *dws) -{ -} -#endif /* CONFIG_DEBUG_FS */ - -static void wait_till_not_busy(struct dw_spi *dws) -{ - unsigned long end = jiffies + usecs_to_jiffies(1000); - - while (time_before(jiffies, end)) { - if (!(dw_readw(dws, sr) & SR_BUSY)) - return; - } - dev_err(&dws->master->dev, - "DW SPI: Stutus keeps busy for 1000us after a read/write!\n"); -} - -static void flush(struct dw_spi *dws) -{ - while (dw_readw(dws, sr) & SR_RF_NOT_EMPT) - dw_readw(dws, dr); - - wait_till_not_busy(dws); -} - -static void null_cs_control(u32 command) -{ -} - -static int null_writer(struct dw_spi *dws) -{ - u8 n_bytes = dws->n_bytes; - - if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL) - || (dws->tx == dws->tx_end)) - return 0; - dw_writew(dws, dr, 0); - dws->tx += n_bytes; - - wait_till_not_busy(dws); - return 1; -} - -static int null_reader(struct dw_spi *dws) -{ - u8 n_bytes = dws->n_bytes; - - while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT) - && (dws->rx < dws->rx_end)) { - dw_readw(dws, dr); - dws->rx += n_bytes; - } - wait_till_not_busy(dws); - return dws->rx == dws->rx_end; -} - -static int u8_writer(struct dw_spi *dws) -{ - if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL) - || (dws->tx == dws->tx_end)) - return 0; - - dw_writew(dws, dr, *(u8 *)(dws->tx)); - ++dws->tx; - - wait_till_not_busy(dws); - return 1; -} - -static int u8_reader(struct dw_spi *dws) -{ - while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT) - && (dws->rx < dws->rx_end)) { - *(u8 *)(dws->rx) = dw_readw(dws, dr); - ++dws->rx; - } - - wait_till_not_busy(dws); - return dws->rx == dws->rx_end; -} - -static int u16_writer(struct dw_spi *dws) -{ - if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL) - || (dws->tx == dws->tx_end)) - return 0; - - dw_writew(dws, dr, *(u16 *)(dws->tx)); - dws->tx += 2; - - wait_till_not_busy(dws); - return 1; -} - -static int u16_reader(struct dw_spi *dws) -{ - u16 temp; - - while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT) - && (dws->rx < dws->rx_end)) { - temp = dw_readw(dws, dr); - *(u16 *)(dws->rx) = temp; - dws->rx += 2; - } - - wait_till_not_busy(dws); - return dws->rx == dws->rx_end; -} - -static void *next_transfer(struct dw_spi *dws) -{ - struct spi_message *msg = dws->cur_msg; - struct spi_transfer *trans = dws->cur_transfer; - - /* Move to next transfer */ - if (trans->transfer_list.next != &msg->transfers) { - dws->cur_transfer = - list_entry(trans->transfer_list.next, - struct spi_transfer, - transfer_list); - return RUNNING_STATE; - } else - return DONE_STATE; -} - -/* - * Note: first step is the protocol driver prepares - * a dma-capable memory, and this func just need translate - * the virt addr to physical - */ -static int map_dma_buffers(struct dw_spi *dws) -{ - if (!dws->cur_msg->is_dma_mapped || !dws->dma_inited - || !dws->cur_chip->enable_dma) - return 0; - - if (dws->cur_transfer->tx_dma) - dws->tx_dma = dws->cur_transfer->tx_dma; - - if (dws->cur_transfer->rx_dma) - dws->rx_dma = dws->cur_transfer->rx_dma; - - return 1; -} - -/* Caller already set message->status; dma and pio irqs are blocked */ -static void giveback(struct dw_spi *dws) -{ - struct spi_transfer *last_transfer; - unsigned long flags; - struct spi_message *msg; - - spin_lock_irqsave(&dws->lock, flags); - msg = dws->cur_msg; - dws->cur_msg = NULL; - dws->cur_transfer = NULL; - dws->prev_chip = dws->cur_chip; - dws->cur_chip = NULL; - dws->dma_mapped = 0; - queue_work(dws->workqueue, &dws->pump_messages); - spin_unlock_irqrestore(&dws->lock, flags); - - last_transfer = list_entry(msg->transfers.prev, - struct spi_transfer, - transfer_list); - - if (!last_transfer->cs_change) - dws->cs_control(MRST_SPI_DEASSERT); - - msg->state = NULL; - if (msg->complete) - msg->complete(msg->context); -} - -static void int_error_stop(struct dw_spi *dws, const char *msg) -{ - /* Stop and reset hw */ - flush(dws); - spi_enable_chip(dws, 0); - - dev_err(&dws->master->dev, "%s\n", msg); - dws->cur_msg->state = ERROR_STATE; - tasklet_schedule(&dws->pump_transfers); -} - -static void transfer_complete(struct dw_spi *dws) -{ - /* Update total byte transfered return count actual bytes read */ - dws->cur_msg->actual_length += dws->len; - - /* Move to next transfer */ - dws->cur_msg->state = next_transfer(dws); - - /* Handle end of message */ - if (dws->cur_msg->state == DONE_STATE) { - dws->cur_msg->status = 0; - giveback(dws); - } else - tasklet_schedule(&dws->pump_transfers); -} - -static irqreturn_t interrupt_transfer(struct dw_spi *dws) -{ - u16 irq_status, irq_mask = 0x3f; - - irq_status = dw_readw(dws, isr) & irq_mask; - /* Error handling */ - if (irq_status & (SPI_INT_TXOI | SPI_INT_RXOI | SPI_INT_RXUI)) { - dw_readw(dws, txoicr); - dw_readw(dws, rxoicr); - dw_readw(dws, rxuicr); - int_error_stop(dws, "interrupt_transfer: fifo overrun"); - return IRQ_HANDLED; - } - - /* INT comes from tx */ - if (dws->tx && (irq_status & SPI_INT_TXEI)) { - while (dws->tx < dws->tx_end) - dws->write(dws); - - if (dws->tx == dws->tx_end) { - spi_mask_intr(dws, SPI_INT_TXEI); - transfer_complete(dws); - } - } - - /* INT comes from rx */ - if (dws->rx && (irq_status & SPI_INT_RXFI)) { - if (dws->read(dws)) - transfer_complete(dws); - } - return IRQ_HANDLED; -} - -static irqreturn_t dw_spi_irq(int irq, void *dev_id) -{ - struct dw_spi *dws = dev_id; - - if (!dws->cur_msg) { - spi_mask_intr(dws, SPI_INT_TXEI); - /* Never fail */ - return IRQ_HANDLED; - } - - return dws->transfer_handler(dws); -} - -/* Must be called inside pump_transfers() */ -static void poll_transfer(struct dw_spi *dws) -{ - if (dws->tx) { - while (dws->write(dws)) - dws->read(dws); - } - - dws->read(dws); - transfer_complete(dws); -} - -static void dma_transfer(struct dw_spi *dws, int cs_change) -{ -} - -static void pump_transfers(unsigned long data) -{ - struct dw_spi *dws = (struct dw_spi *)data; - struct spi_message *message = NULL; - struct spi_transfer *transfer = NULL; - struct spi_transfer *previous = NULL; - struct spi_device *spi = NULL; - struct chip_data *chip = NULL; - u8 bits = 0; - u8 imask = 0; - u8 cs_change = 0; - u16 clk_div = 0; - u32 speed = 0; - u32 cr0 = 0; - - /* Get current state information */ - message = dws->cur_msg; - transfer = dws->cur_transfer; - chip = dws->cur_chip; - spi = message->spi; - - if (message->state == ERROR_STATE) { - message->status = -EIO; - goto early_exit; - } - - /* Handle end of message */ - if (message->state == DONE_STATE) { - message->status = 0; - goto early_exit; - } - - /* 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); - } - - dws->n_bytes = chip->n_bytes; - dws->dma_width = chip->dma_width; - dws->cs_control = chip->cs_control; - - dws->rx_dma = transfer->rx_dma; - dws->tx_dma = transfer->tx_dma; - dws->tx = (void *)transfer->tx_buf; - dws->tx_end = dws->tx + transfer->len; - dws->rx = transfer->rx_buf; - dws->rx_end = dws->rx + transfer->len; - dws->write = dws->tx ? chip->write : null_writer; - dws->read = dws->rx ? chip->read : null_reader; - dws->cs_change = transfer->cs_change; - dws->len = dws->cur_transfer->len; - if (chip != dws->prev_chip) - cs_change = 1; - - cr0 = chip->cr0; - - /* Handle per transfer options for bpw and speed */ - if (transfer->speed_hz) { - speed = chip->speed_hz; - - if (transfer->speed_hz != speed) { - speed = transfer->speed_hz; - if (speed > dws->max_freq) { - printk(KERN_ERR "MRST SPI0: unsupported" - "freq: %dHz\n", speed); - message->status = -EIO; - goto early_exit; - } - - /* clk_div doesn't support odd number */ - clk_div = dws->max_freq / speed; - clk_div = (clk_div >> 1) << 1; - - chip->speed_hz = speed; - chip->clk_div = clk_div; - } - } - if (transfer->bits_per_word) { - bits = transfer->bits_per_word; - - switch (bits) { - case 8: - dws->n_bytes = 1; - dws->dma_width = 1; - dws->read = (dws->read != null_reader) ? - u8_reader : null_reader; - dws->write = (dws->write != null_writer) ? - u8_writer : null_writer; - break; - case 16: - dws->n_bytes = 2; - dws->dma_width = 2; - dws->read = (dws->read != null_reader) ? - u16_reader : null_reader; - dws->write = (dws->write != null_writer) ? - u16_writer : null_writer; - break; - default: - printk(KERN_ERR "MRST SPI0: unsupported bits:" - "%db\n", bits); - message->status = -EIO; - goto early_exit; - } - - cr0 = (bits - 1) - | (chip->type << SPI_FRF_OFFSET) - | (spi->mode << SPI_MODE_OFFSET) - | (chip->tmode << SPI_TMOD_OFFSET); - } - message->state = RUNNING_STATE; - - /* Check if current transfer is a DMA transaction */ - dws->dma_mapped = map_dma_buffers(dws); - - if (!dws->dma_mapped && !chip->poll_mode) { - if (dws->rx) - imask |= SPI_INT_RXFI; - if (dws->tx) - imask |= SPI_INT_TXEI; - dws->transfer_handler = interrupt_transfer; - } - - /* - * Reprogram registers only if - * 1. chip select changes - * 2. clk_div is changed - * 3. control value changes - */ - if (dw_readw(dws, ctrl0) != cr0 || cs_change || clk_div) { - spi_enable_chip(dws, 0); - - if (dw_readw(dws, ctrl0) != cr0) - dw_writew(dws, ctrl0, cr0); - - /* Set the interrupt mask, for poll mode just diable all int */ - spi_mask_intr(dws, 0xff); - if (!chip->poll_mode) - spi_umask_intr(dws, imask); - - spi_set_clk(dws, clk_div ? clk_div : chip->clk_div); - spi_chip_sel(dws, spi->chip_select); - spi_enable_chip(dws, 1); - - if (cs_change) - dws->prev_chip = chip; - } - - if (dws->dma_mapped) - dma_transfer(dws, cs_change); - - if (chip->poll_mode) - poll_transfer(dws); - - return; - -early_exit: - giveback(dws); - return; -} - -static void pump_messages(struct work_struct *work) -{ - struct dw_spi *dws = - container_of(work, struct dw_spi, pump_messages); - unsigned long flags; - - /* Lock queue and check for queue work */ - spin_lock_irqsave(&dws->lock, flags); - if (list_empty(&dws->queue) || dws->run == QUEUE_STOPPED) { - dws->busy = 0; - spin_unlock_irqrestore(&dws->lock, flags); - return; - } - - /* Make sure we are not already running a message */ - if (dws->cur_msg) { - spin_unlock_irqrestore(&dws->lock, flags); - return; - } - - /* Extract head of queue */ - dws->cur_msg = list_entry(dws->queue.next, struct spi_message, queue); - list_del_init(&dws->cur_msg->queue); - - /* Initial message state*/ - dws->cur_msg->state = START_STATE; - dws->cur_transfer = list_entry(dws->cur_msg->transfers.next, - struct spi_transfer, - transfer_list); - dws->cur_chip = spi_get_ctldata(dws->cur_msg->spi); - - /* Mark as busy and launch transfers */ - tasklet_schedule(&dws->pump_transfers); - - dws->busy = 1; - spin_unlock_irqrestore(&dws->lock, flags); -} - -/* spi_device use this to queue in their spi_msg */ -static int dw_spi_transfer(struct spi_device *spi, struct spi_message *msg) -{ - struct dw_spi *dws = spi_master_get_devdata(spi->master); - unsigned long flags; - - spin_lock_irqsave(&dws->lock, flags); - - if (dws->run == QUEUE_STOPPED) { - spin_unlock_irqrestore(&dws->lock, flags); - return -ESHUTDOWN; - } - - msg->actual_length = 0; - msg->status = -EINPROGRESS; - msg->state = START_STATE; - - list_add_tail(&msg->queue, &dws->queue); - - if (dws->run == QUEUE_RUNNING && !dws->busy) { - - if (dws->cur_transfer || dws->cur_msg) - queue_work(dws->workqueue, - &dws->pump_messages); - else { - /* If no other data transaction in air, just go */ - spin_unlock_irqrestore(&dws->lock, flags); - pump_messages(&dws->pump_messages); - return 0; - } - } - - spin_unlock_irqrestore(&dws->lock, flags); - return 0; -} - -/* This may be called twice for each spi dev */ -static int dw_spi_setup(struct spi_device *spi) -{ - struct dw_spi_chip *chip_info = NULL; - struct chip_data *chip; - - if (spi->bits_per_word != 8 && spi->bits_per_word != 16) - return -EINVAL; - - /* Only alloc on first setup */ - chip = spi_get_ctldata(spi); - if (!chip) { - chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - chip->cs_control = null_cs_control; - chip->enable_dma = 0; - } - - /* - * Protocol drivers may change the chip settings, so... - * if chip_info exists, use it - */ - chip_info = spi->controller_data; - - /* chip_info doesn't always exist */ - if (chip_info) { - if (chip_info->cs_control) - chip->cs_control = chip_info->cs_control; - - chip->poll_mode = chip_info->poll_mode; - chip->type = chip_info->type; - - chip->rx_threshold = 0; - chip->tx_threshold = 0; - - chip->enable_dma = chip_info->enable_dma; - } - - if (spi->bits_per_word <= 8) { - chip->n_bytes = 1; - chip->dma_width = 1; - chip->read = u8_reader; - chip->write = u8_writer; - } else if (spi->bits_per_word <= 16) { - chip->n_bytes = 2; - chip->dma_width = 2; - chip->read = u16_reader; - chip->write = u16_writer; - } else { - /* Never take >16b case for MRST SPIC */ - dev_err(&spi->dev, "invalid wordsize\n"); - return -EINVAL; - } - chip->bits_per_word = spi->bits_per_word; - - chip->speed_hz = spi->max_speed_hz; - if (chip->speed_hz) - chip->clk_div = 25000000 / chip->speed_hz; - else - chip->clk_div = 8; /* default value */ - - chip->tmode = 0; /* Tx & Rx */ - /* Default SPI mode is SCPOL = 0, SCPH = 0 */ - chip->cr0 = (chip->bits_per_word - 1) - | (chip->type << SPI_FRF_OFFSET) - | (spi->mode << SPI_MODE_OFFSET) - | (chip->tmode << SPI_TMOD_OFFSET); - - spi_set_ctldata(spi, chip); - return 0; -} - -static void dw_spi_cleanup(struct spi_device *spi) -{ - struct chip_data *chip = spi_get_ctldata(spi); - kfree(chip); -} - -static int __init init_queue(struct dw_spi *dws) -{ - INIT_LIST_HEAD(&dws->queue); - spin_lock_init(&dws->lock); - - dws->run = QUEUE_STOPPED; - dws->busy = 0; - - tasklet_init(&dws->pump_transfers, - pump_transfers, (unsigned long)dws); - - INIT_WORK(&dws->pump_messages, pump_messages); - dws->workqueue = create_singlethread_workqueue( - dev_name(dws->master->dev.parent)); - if (dws->workqueue == NULL) - return -EBUSY; - - return 0; -} - -static int start_queue(struct dw_spi *dws) -{ - unsigned long flags; - - spin_lock_irqsave(&dws->lock, flags); - - if (dws->run == QUEUE_RUNNING || dws->busy) { - spin_unlock_irqrestore(&dws->lock, flags); - return -EBUSY; - } - - dws->run = QUEUE_RUNNING; - dws->cur_msg = NULL; - dws->cur_transfer = NULL; - dws->cur_chip = NULL; - dws->prev_chip = NULL; - spin_unlock_irqrestore(&dws->lock, flags); - - queue_work(dws->workqueue, &dws->pump_messages); - - return 0; -} - -static int stop_queue(struct dw_spi *dws) -{ - unsigned long flags; - unsigned limit = 50; - int status = 0; - - spin_lock_irqsave(&dws->lock, flags); - dws->run = QUEUE_STOPPED; - while (!list_empty(&dws->queue) && dws->busy && limit--) { - spin_unlock_irqrestore(&dws->lock, flags); - msleep(10); - spin_lock_irqsave(&dws->lock, flags); - } - - if (!list_empty(&dws->queue) || dws->busy) - status = -EBUSY; - spin_unlock_irqrestore(&dws->lock, flags); - - return status; -} - -static int destroy_queue(struct dw_spi *dws) -{ - int status; - - status = stop_queue(dws); - if (status != 0) - return status; - destroy_workqueue(dws->workqueue); - return 0; -} - -/* Restart the controller, disable all interrupts, clean rx fifo */ -static void spi_hw_init(struct dw_spi *dws) -{ - spi_enable_chip(dws, 0); - spi_mask_intr(dws, 0xff); - spi_enable_chip(dws, 1); - flush(dws); -} - -int __devinit dw_spi_add_host(struct dw_spi *dws) -{ - struct spi_master *master; - int ret; - - BUG_ON(dws == NULL); - - master = spi_alloc_master(dws->parent_dev, 0); - if (!master) { - ret = -ENOMEM; - goto exit; - } - - dws->master = master; - dws->type = SSI_MOTO_SPI; - dws->prev_chip = NULL; - dws->dma_inited = 0; - dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60); - - ret = request_irq(dws->irq, dw_spi_irq, 0, - "dw_spi", dws); - if (ret < 0) { - dev_err(&master->dev, "can not get IRQ\n"); - goto err_free_master; - } - - master->mode_bits = SPI_CPOL | SPI_CPHA; - master->bus_num = dws->bus_num; - master->num_chipselect = dws->num_cs; - master->cleanup = dw_spi_cleanup; - master->setup = dw_spi_setup; - master->transfer = dw_spi_transfer; - - dws->dma_inited = 0; - - /* Basic HW init */ - spi_hw_init(dws); - - /* Initial and start queue */ - ret = init_queue(dws); - if (ret) { - dev_err(&master->dev, "problem initializing queue\n"); - goto err_diable_hw; - } - ret = start_queue(dws); - if (ret) { - dev_err(&master->dev, "problem starting queue\n"); - goto err_diable_hw; - } - - spi_master_set_devdata(master, dws); - ret = spi_register_master(master); - if (ret) { - dev_err(&master->dev, "problem registering spi master\n"); - goto err_queue_alloc; - } - - mrst_spi_debugfs_init(dws); - return 0; - -err_queue_alloc: - destroy_queue(dws); -err_diable_hw: - spi_enable_chip(dws, 0); - free_irq(dws->irq, dws); -err_free_master: - spi_master_put(master); -exit: - return ret; -} -EXPORT_SYMBOL(dw_spi_add_host); - -void __devexit dw_spi_remove_host(struct dw_spi *dws) -{ - int status = 0; - - if (!dws) - return; - mrst_spi_debugfs_remove(dws); - - /* Remove the queue */ - status = destroy_queue(dws); - if (status != 0) - dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not " - "complete, message memory not freed\n"); - - spi_enable_chip(dws, 0); - /* Disable clk */ - spi_set_clk(dws, 0); - free_irq(dws->irq, dws); - - /* Disconnect from the SPI framework */ - spi_unregister_master(dws->master); -} - -int dw_spi_suspend_host(struct dw_spi *dws) -{ - int ret = 0; - - ret = stop_queue(dws); - if (ret) - return ret; - spi_enable_chip(dws, 0); - spi_set_clk(dws, 0); - return ret; -} -EXPORT_SYMBOL(dw_spi_suspend_host); - -int dw_spi_resume_host(struct dw_spi *dws) -{ - int ret; - - spi_hw_init(dws); - ret = start_queue(dws); - if (ret) - dev_err(&dws->master->dev, "fail to start queue (%d)\n", ret); - return ret; -} -EXPORT_SYMBOL(dw_spi_resume_host); - -MODULE_AUTHOR("Feng Tang "); -MODULE_DESCRIPTION("Driver for DesignWare SPI controller core"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/spi/dw_spi_pci.c b/trunk/drivers/spi/dw_spi_pci.c deleted file mode 100644 index 34ba69161734..000000000000 --- a/trunk/drivers/spi/dw_spi_pci.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * mrst_spi_pci.c - PCI interface driver for DW SPI Core - * - * Copyright (c) 2009, 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., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include - -#define DRIVER_NAME "dw_spi_pci" - -struct dw_spi_pci { - struct pci_dev *pdev; - struct dw_spi dws; -}; - -static int __devinit spi_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct dw_spi_pci *dwpci; - struct dw_spi *dws; - int pci_bar = 0; - int ret; - - printk(KERN_INFO "DW: found PCI SPI controller(ID: %04x:%04x)\n", - pdev->vendor, pdev->device); - - ret = pci_enable_device(pdev); - if (ret) - return ret; - - dwpci = kzalloc(sizeof(struct dw_spi_pci), GFP_KERNEL); - if (!dwpci) { - ret = -ENOMEM; - goto err_disable; - } - - dwpci->pdev = pdev; - dws = &dwpci->dws; - - /* Get basic io resource and map it */ - dws->paddr = pci_resource_start(pdev, pci_bar); - dws->iolen = pci_resource_len(pdev, pci_bar); - - ret = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev)); - if (ret) - goto err_kfree; - - dws->regs = ioremap_nocache((unsigned long)dws->paddr, - pci_resource_len(pdev, pci_bar)); - if (!dws->regs) { - ret = -ENOMEM; - goto err_release_reg; - } - - dws->parent_dev = &pdev->dev; - dws->bus_num = 0; - dws->num_cs = 4; - dws->max_freq = 25000000; /* for Moorestwon */ - dws->irq = pdev->irq; - - ret = dw_spi_add_host(dws); - if (ret) - goto err_unmap; - - /* PCI hook and SPI hook use the same drv data */ - pci_set_drvdata(pdev, dwpci); - return 0; - -err_unmap: - iounmap(dws->regs); -err_release_reg: - pci_release_region(pdev, pci_bar); -err_kfree: - kfree(dwpci); -err_disable: - pci_disable_device(pdev); - return ret; -} - -static void __devexit spi_pci_remove(struct pci_dev *pdev) -{ - struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); - - pci_set_drvdata(pdev, NULL); - iounmap(dwpci->dws.regs); - pci_release_region(pdev, 0); - kfree(dwpci); - pci_disable_device(pdev); -} - -#ifdef CONFIG_PM -static int spi_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); - int ret; - - ret = dw_spi_suspend_host(&dwpci->dws); - if (ret) - return ret; - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return ret; -} - -static int spi_resume(struct pci_dev *pdev) -{ - struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); - int ret; - - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - ret = pci_enable_device(pdev); - if (ret) - return ret; - return dw_spi_resume_host(&dwpci->dws); -} -#else -#define spi_suspend NULL -#define spi_resume NULL -#endif - -static const struct pci_device_id pci_ids[] __devinitdata = { - /* Intel Moorestown platform SPI controller 0 */ - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0800) }, - {}, -}; - -static struct pci_driver dw_spi_driver = { - .name = DRIVER_NAME, - .id_table = pci_ids, - .probe = spi_pci_probe, - .remove = __devexit_p(spi_pci_remove), - .suspend = spi_suspend, - .resume = spi_resume, -}; - -static int __init mrst_spi_init(void) -{ - return pci_register_driver(&dw_spi_driver); -} - -static void __exit mrst_spi_exit(void) -{ - pci_unregister_driver(&dw_spi_driver); -} - -module_init(mrst_spi_init); -module_exit(mrst_spi_exit); - -MODULE_AUTHOR("Feng Tang "); -MODULE_DESCRIPTION("PCI interface driver for DW SPI Core"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/spi/spi_bfin5xx.c b/trunk/drivers/spi/spi_bfin5xx.c index 1d41058bbab2..73e24ef5a2f9 100644 --- a/trunk/drivers/spi/spi_bfin5xx.c +++ b/trunk/drivers/spi/spi_bfin5xx.c @@ -1294,7 +1294,7 @@ static int __init bfin_spi_probe(struct platform_device *pdev) goto out_error_get_res; } - drv_data->regs_base = ioremap(res->start, resource_size(res)); + drv_data->regs_base = ioremap(res->start, (res->end - res->start + 1)); if (drv_data->regs_base == NULL) { dev_err(dev, "Cannot map IO\n"); status = -ENXIO; diff --git a/trunk/drivers/spi/spi_mpc8xxx.c b/trunk/drivers/spi/spi_mpc8xxx.c index 1fb2a6ea328c..e9390d747bfc 100644 --- a/trunk/drivers/spi/spi_mpc8xxx.c +++ b/trunk/drivers/spi/spi_mpc8xxx.c @@ -1013,7 +1013,7 @@ mpc8xxx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq) init_completion(&mpc8xxx_spi->done); - mpc8xxx_spi->base = ioremap(mem->start, resource_size(mem)); + mpc8xxx_spi->base = ioremap(mem->start, mem->end - mem->start + 1); if (mpc8xxx_spi->base == NULL) { ret = -ENOMEM; goto err_ioremap; diff --git a/trunk/drivers/spi/spi_s3c24xx.c b/trunk/drivers/spi/spi_s3c24xx.c index c010733877ae..276591569c8b 100644 --- a/trunk/drivers/spi/spi_s3c24xx.c +++ b/trunk/drivers/spi/spi_s3c24xx.c @@ -1,7 +1,7 @@ /* linux/drivers/spi/spi_s3c24xx.c * * Copyright (c) 2006 Ben Dooks - * Copyright 2006-2009 Simtec Electronics + * Copyright (c) 2006 Simtec Electronics * Ben Dooks * * This program is free software; you can redistribute it and/or modify @@ -28,11 +28,6 @@ #include #include -#include -#include - -#include "spi_s3c24xx_fiq.h" - /** * s3c24xx_spi_devstate - per device data * @hz: Last frequency calculated for @sppre field. @@ -47,13 +42,6 @@ struct s3c24xx_spi_devstate { u8 sppre; }; -enum spi_fiq_mode { - FIQ_MODE_NONE = 0, - FIQ_MODE_TX = 1, - FIQ_MODE_RX = 2, - FIQ_MODE_TXRX = 3, -}; - struct s3c24xx_spi { /* bitbang has to be first */ struct spi_bitbang bitbang; @@ -64,11 +52,6 @@ struct s3c24xx_spi { int len; int count; - struct fiq_handler fiq_handler; - enum spi_fiq_mode fiq_mode; - unsigned char fiq_inuse; - unsigned char fiq_claimed; - void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); @@ -84,7 +67,6 @@ struct s3c24xx_spi { struct s3c2410_spi_info *pdata; }; - #define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT) #define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP) @@ -145,7 +127,7 @@ static int s3c24xx_spi_update_state(struct spi_device *spi, } if (spi->mode != cs->mode) { - u8 spcon = SPCON_DEFAULT | S3C2410_SPCON_ENSCK; + u8 spcon = SPCON_DEFAULT; if (spi->mode & SPI_CPHA) spcon |= S3C2410_SPCON_CPHA_FMTB; @@ -232,196 +214,13 @@ static inline unsigned int hw_txbyte(struct s3c24xx_spi *hw, int count) return hw->tx ? hw->tx[count] : 0; } -#ifdef CONFIG_SPI_S3C24XX_FIQ -/* Support for FIQ based pseudo-DMA to improve the transfer speed. - * - * This code uses the assembly helper in spi_s3c24xx_spi.S which is - * used by the FIQ core to move data between main memory and the peripheral - * block. Since this is code running on the processor, there is no problem - * with cache coherency of the buffers, so we can use any buffer we like. - */ - -/** - * struct spi_fiq_code - FIQ code and header - * @length: The length of the code fragment, excluding this header. - * @ack_offset: The offset from @data to the word to place the IRQ ACK bit at. - * @data: The code itself to install as a FIQ handler. - */ -struct spi_fiq_code { - u32 length; - u32 ack_offset; - u8 data[0]; -}; - -extern struct spi_fiq_code s3c24xx_spi_fiq_txrx; -extern struct spi_fiq_code s3c24xx_spi_fiq_tx; -extern struct spi_fiq_code s3c24xx_spi_fiq_rx; - -/** - * ack_bit - turn IRQ into IRQ acknowledgement bit - * @irq: The interrupt number - * - * Returns the bit to write to the interrupt acknowledge register. - */ -static inline u32 ack_bit(unsigned int irq) -{ - return 1 << (irq - IRQ_EINT0); -} - -/** - * s3c24xx_spi_tryfiq - attempt to claim and setup FIQ for transfer - * @hw: The hardware state. - * - * Claim the FIQ handler (only one can be active at any one time) and - * then setup the correct transfer code for this transfer. - * - * This call updates all the necessary state information if sucessful, - * so the caller does not need to do anything more than start the transfer - * as normal, since the IRQ will have been re-routed to the FIQ handler. -*/ -void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw) -{ - struct pt_regs regs; - enum spi_fiq_mode mode; - struct spi_fiq_code *code; - int ret; - - if (!hw->fiq_claimed) { - /* try and claim fiq if we haven't got it, and if not - * then return and simply use another transfer method */ - - ret = claim_fiq(&hw->fiq_handler); - if (ret) - return; - } - - if (hw->tx && !hw->rx) - mode = FIQ_MODE_TX; - else if (hw->rx && !hw->tx) - mode = FIQ_MODE_RX; - else - mode = FIQ_MODE_TXRX; - - regs.uregs[fiq_rspi] = (long)hw->regs; - regs.uregs[fiq_rrx] = (long)hw->rx; - regs.uregs[fiq_rtx] = (long)hw->tx + 1; - regs.uregs[fiq_rcount] = hw->len - 1; - regs.uregs[fiq_rirq] = (long)S3C24XX_VA_IRQ; - - set_fiq_regs(®s); - - if (hw->fiq_mode != mode) { - u32 *ack_ptr; - - hw->fiq_mode = mode; - - switch (mode) { - case FIQ_MODE_TX: - code = &s3c24xx_spi_fiq_tx; - break; - case FIQ_MODE_RX: - code = &s3c24xx_spi_fiq_rx; - break; - case FIQ_MODE_TXRX: - code = &s3c24xx_spi_fiq_txrx; - break; - default: - code = NULL; - } - - BUG_ON(!code); - - ack_ptr = (u32 *)&code->data[code->ack_offset]; - *ack_ptr = ack_bit(hw->irq); - - set_fiq_handler(&code->data, code->length); - } - - s3c24xx_set_fiq(hw->irq, true); - - hw->fiq_mode = mode; - hw->fiq_inuse = 1; -} - -/** - * s3c24xx_spi_fiqop - FIQ core code callback - * @pw: Data registered with the handler - * @release: Whether this is a release or a return. - * - * Called by the FIQ code when another module wants to use the FIQ, so - * return whether we are currently using this or not and then update our - * internal state. - */ -static int s3c24xx_spi_fiqop(void *pw, int release) -{ - struct s3c24xx_spi *hw = pw; - int ret = 0; - - if (release) { - if (hw->fiq_inuse) - ret = -EBUSY; - - /* note, we do not need to unroute the FIQ, as the FIQ - * vector code de-routes it to signal the end of transfer */ - - hw->fiq_mode = FIQ_MODE_NONE; - hw->fiq_claimed = 0; - } else { - hw->fiq_claimed = 1; - } - - return ret; -} - -/** - * s3c24xx_spi_initfiq - setup the information for the FIQ core - * @hw: The hardware state. - * - * Setup the fiq_handler block to pass to the FIQ core. - */ -static inline void s3c24xx_spi_initfiq(struct s3c24xx_spi *hw) -{ - hw->fiq_handler.dev_id = hw; - hw->fiq_handler.name = dev_name(hw->dev); - hw->fiq_handler.fiq_op = s3c24xx_spi_fiqop; -} - -/** - * s3c24xx_spi_usefiq - return if we should be using FIQ. - * @hw: The hardware state. - * - * Return true if the platform data specifies whether this channel is - * allowed to use the FIQ. - */ -static inline bool s3c24xx_spi_usefiq(struct s3c24xx_spi *hw) -{ - return hw->pdata->use_fiq; -} - -/** - * s3c24xx_spi_usingfiq - return if channel is using FIQ - * @spi: The hardware state. - * - * Return whether the channel is currently using the FIQ (separate from - * whether the FIQ is claimed). - */ -static inline bool s3c24xx_spi_usingfiq(struct s3c24xx_spi *spi) -{ - return spi->fiq_inuse; -} -#else - -static inline void s3c24xx_spi_initfiq(struct s3c24xx_spi *s) { } -static inline void s3c24xx_spi_tryfiq(struct s3c24xx_spi *s) { } -static inline bool s3c24xx_spi_usefiq(struct s3c24xx_spi *s) { return false; } -static inline bool s3c24xx_spi_usingfiq(struct s3c24xx_spi *s) { return false; } - -#endif /* CONFIG_SPI_S3C24XX_FIQ */ - static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t) { struct s3c24xx_spi *hw = to_hw(spi); + dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", + t->tx_buf, t->rx_buf, t->len); + hw->tx = t->tx_buf; hw->rx = t->rx_buf; hw->len = t->len; @@ -429,14 +228,11 @@ static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t) init_completion(&hw->done); - hw->fiq_inuse = 0; - if (s3c24xx_spi_usefiq(hw) && t->len >= 3) - s3c24xx_spi_tryfiq(hw); - /* send the first byte */ writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT); wait_for_completion(&hw->done); + return hw->count; } @@ -458,27 +254,17 @@ static irqreturn_t s3c24xx_spi_irq(int irq, void *dev) goto irq_done; } - if (!s3c24xx_spi_usingfiq(hw)) { - hw->count++; - - if (hw->rx) - hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT); + hw->count++; - count++; + if (hw->rx) + hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT); - if (count < hw->len) - writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT); - else - complete(&hw->done); - } else { - hw->count = hw->len; - hw->fiq_inuse = 0; - - if (hw->rx) - hw->rx[hw->len-1] = readb(hw->regs + S3C2410_SPRDAT); + count++; + if (count < hw->len) + writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT); + else complete(&hw->done); - } irq_done: return IRQ_HANDLED; @@ -536,10 +322,6 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, hw); init_completion(&hw->done); - /* initialise fiq handler */ - - s3c24xx_spi_initfiq(hw); - /* setup the master state. */ /* the spi->mode bits understood by this driver: */ diff --git a/trunk/drivers/spi/spi_s3c24xx_fiq.S b/trunk/drivers/spi/spi_s3c24xx_fiq.S deleted file mode 100644 index 3793cae361db..000000000000 --- a/trunk/drivers/spi/spi_s3c24xx_fiq.S +++ /dev/null @@ -1,116 +0,0 @@ -/* linux/drivers/spi/spi_s3c24xx_fiq.S - * - * Copyright 2009 Simtec Electronics - * Ben Dooks - * - * S3C24XX SPI - FIQ pseudo-DMA transfer code - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include - -#include -#include -#include - -#include "spi_s3c24xx_fiq.h" - - .text - - @ entry to these routines is as follows, with the register names - @ defined in fiq.h so that they can be shared with the C files which - @ setup the calling registers. - @ - @ fiq_rirq The base of the IRQ registers to find S3C2410_SRCPND - @ fiq_rtmp Temporary register to hold tx/rx data - @ fiq_rspi The base of the SPI register block - @ fiq_rtx The tx buffer pointer - @ fiq_rrx The rx buffer pointer - @ fiq_rcount The number of bytes to move - - @ each entry starts with a word entry of how long it is - @ and an offset to the irq acknowledgment word - -ENTRY(s3c24xx_spi_fiq_rx) -s3c24xx_spi_fix_rx: - .word fiq_rx_end - fiq_rx_start - .word fiq_rx_irq_ack - fiq_rx_start -fiq_rx_start: - ldr fiq_rtmp, fiq_rx_irq_ack - str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] - - ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] - strb fiq_rtmp, [ fiq_rrx ], #1 - - mov fiq_rtmp, #0xff - strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] - - subs fiq_rcount, fiq_rcount, #1 - subnes pc, lr, #4 @@ return, still have work to do - - @@ set IRQ controller so that next op will trigger IRQ - mov fiq_rtmp, #0 - str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] - subs pc, lr, #4 - -fiq_rx_irq_ack: - .word 0 -fiq_rx_end: - -ENTRY(s3c24xx_spi_fiq_txrx) -s3c24xx_spi_fiq_txrx: - .word fiq_txrx_end - fiq_txrx_start - .word fiq_txrx_irq_ack - fiq_txrx_start -fiq_txrx_start: - - ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] - strb fiq_rtmp, [ fiq_rrx ], #1 - - ldr fiq_rtmp, fiq_txrx_irq_ack - str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] - - ldrb fiq_rtmp, [ fiq_rtx ], #1 - strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] - - subs fiq_rcount, fiq_rcount, #1 - subnes pc, lr, #4 @@ return, still have work to do - - mov fiq_rtmp, #0 - str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] - subs pc, lr, #4 - -fiq_txrx_irq_ack: - .word 0 - -fiq_txrx_end: - -ENTRY(s3c24xx_spi_fiq_tx) -s3c24xx_spi_fix_tx: - .word fiq_tx_end - fiq_tx_start - .word fiq_tx_irq_ack - fiq_tx_start -fiq_tx_start: - ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] - - ldr fiq_rtmp, fiq_tx_irq_ack - str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] - - ldrb fiq_rtmp, [ fiq_rtx ], #1 - strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] - - subs fiq_rcount, fiq_rcount, #1 - subnes pc, lr, #4 @@ return, still have work to do - - mov fiq_rtmp, #0 - str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] - subs pc, lr, #4 - -fiq_tx_irq_ack: - .word 0 - -fiq_tx_end: - - .end diff --git a/trunk/drivers/spi/spi_s3c24xx_fiq.h b/trunk/drivers/spi/spi_s3c24xx_fiq.h deleted file mode 100644 index a5950bb25b51..000000000000 --- a/trunk/drivers/spi/spi_s3c24xx_fiq.h +++ /dev/null @@ -1,26 +0,0 @@ -/* linux/drivers/spi/spi_s3c24xx_fiq.h - * - * Copyright 2009 Simtec Electronics - * Ben Dooks - * - * S3C24XX SPI - FIQ pseudo-DMA transfer support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -/* We have R8 through R13 to play with */ - -#ifdef __ASSEMBLY__ -#define __REG_NR(x) r##x -#else -#define __REG_NR(x) (x) -#endif - -#define fiq_rspi __REG_NR(8) -#define fiq_rtmp __REG_NR(9) -#define fiq_rrx __REG_NR(10) -#define fiq_rtx __REG_NR(11) -#define fiq_rcount __REG_NR(12) -#define fiq_rirq __REG_NR(13) diff --git a/trunk/drivers/spi/spi_s3c64xx.c b/trunk/drivers/spi/spi_s3c64xx.c deleted file mode 100644 index 88a456dba967..000000000000 --- a/trunk/drivers/spi/spi_s3c64xx.c +++ /dev/null @@ -1,1196 +0,0 @@ -/* linux/drivers/spi/spi_s3c64xx.c - * - * Copyright (C) 2009 Samsung Electronics Ltd. - * Jaswinder Singh - * - * 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* Registers and bit-fields */ - -#define S3C64XX_SPI_CH_CFG 0x00 -#define S3C64XX_SPI_CLK_CFG 0x04 -#define S3C64XX_SPI_MODE_CFG 0x08 -#define S3C64XX_SPI_SLAVE_SEL 0x0C -#define S3C64XX_SPI_INT_EN 0x10 -#define S3C64XX_SPI_STATUS 0x14 -#define S3C64XX_SPI_TX_DATA 0x18 -#define S3C64XX_SPI_RX_DATA 0x1C -#define S3C64XX_SPI_PACKET_CNT 0x20 -#define S3C64XX_SPI_PENDING_CLR 0x24 -#define S3C64XX_SPI_SWAP_CFG 0x28 -#define S3C64XX_SPI_FB_CLK 0x2C - -#define S3C64XX_SPI_CH_HS_EN (1<<6) /* High Speed Enable */ -#define S3C64XX_SPI_CH_SW_RST (1<<5) -#define S3C64XX_SPI_CH_SLAVE (1<<4) -#define S3C64XX_SPI_CPOL_L (1<<3) -#define S3C64XX_SPI_CPHA_B (1<<2) -#define S3C64XX_SPI_CH_RXCH_ON (1<<1) -#define S3C64XX_SPI_CH_TXCH_ON (1<<0) - -#define S3C64XX_SPI_CLKSEL_SRCMSK (3<<9) -#define S3C64XX_SPI_CLKSEL_SRCSHFT 9 -#define S3C64XX_SPI_ENCLK_ENABLE (1<<8) -#define S3C64XX_SPI_PSR_MASK 0xff - -#define S3C64XX_SPI_MODE_CH_TSZ_BYTE (0<<29) -#define S3C64XX_SPI_MODE_CH_TSZ_HALFWORD (1<<29) -#define S3C64XX_SPI_MODE_CH_TSZ_WORD (2<<29) -#define S3C64XX_SPI_MODE_CH_TSZ_MASK (3<<29) -#define S3C64XX_SPI_MODE_BUS_TSZ_BYTE (0<<17) -#define S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD (1<<17) -#define S3C64XX_SPI_MODE_BUS_TSZ_WORD (2<<17) -#define S3C64XX_SPI_MODE_BUS_TSZ_MASK (3<<17) -#define S3C64XX_SPI_MODE_RXDMA_ON (1<<2) -#define S3C64XX_SPI_MODE_TXDMA_ON (1<<1) -#define S3C64XX_SPI_MODE_4BURST (1<<0) - -#define S3C64XX_SPI_SLAVE_AUTO (1<<1) -#define S3C64XX_SPI_SLAVE_SIG_INACT (1<<0) - -#define S3C64XX_SPI_ACT(c) writel(0, (c)->regs + S3C64XX_SPI_SLAVE_SEL) - -#define S3C64XX_SPI_DEACT(c) writel(S3C64XX_SPI_SLAVE_SIG_INACT, \ - (c)->regs + S3C64XX_SPI_SLAVE_SEL) - -#define S3C64XX_SPI_INT_TRAILING_EN (1<<6) -#define S3C64XX_SPI_INT_RX_OVERRUN_EN (1<<5) -#define S3C64XX_SPI_INT_RX_UNDERRUN_EN (1<<4) -#define S3C64XX_SPI_INT_TX_OVERRUN_EN (1<<3) -#define S3C64XX_SPI_INT_TX_UNDERRUN_EN (1<<2) -#define S3C64XX_SPI_INT_RX_FIFORDY_EN (1<<1) -#define S3C64XX_SPI_INT_TX_FIFORDY_EN (1<<0) - -#define S3C64XX_SPI_ST_RX_OVERRUN_ERR (1<<5) -#define S3C64XX_SPI_ST_RX_UNDERRUN_ERR (1<<4) -#define S3C64XX_SPI_ST_TX_OVERRUN_ERR (1<<3) -#define S3C64XX_SPI_ST_TX_UNDERRUN_ERR (1<<2) -#define S3C64XX_SPI_ST_RX_FIFORDY (1<<1) -#define S3C64XX_SPI_ST_TX_FIFORDY (1<<0) - -#define S3C64XX_SPI_PACKET_CNT_EN (1<<16) - -#define S3C64XX_SPI_PND_TX_UNDERRUN_CLR (1<<4) -#define S3C64XX_SPI_PND_TX_OVERRUN_CLR (1<<3) -#define S3C64XX_SPI_PND_RX_UNDERRUN_CLR (1<<2) -#define S3C64XX_SPI_PND_RX_OVERRUN_CLR (1<<1) -#define S3C64XX_SPI_PND_TRAILING_CLR (1<<0) - -#define S3C64XX_SPI_SWAP_RX_HALF_WORD (1<<7) -#define S3C64XX_SPI_SWAP_RX_BYTE (1<<6) -#define S3C64XX_SPI_SWAP_RX_BIT (1<<5) -#define S3C64XX_SPI_SWAP_RX_EN (1<<4) -#define S3C64XX_SPI_SWAP_TX_HALF_WORD (1<<3) -#define S3C64XX_SPI_SWAP_TX_BYTE (1<<2) -#define S3C64XX_SPI_SWAP_TX_BIT (1<<1) -#define S3C64XX_SPI_SWAP_TX_EN (1<<0) - -#define S3C64XX_SPI_FBCLK_MSK (3<<0) - -#define S3C64XX_SPI_ST_TRLCNTZ(v, i) ((((v) >> (i)->rx_lvl_offset) & \ - (((i)->fifo_lvl_mask + 1))) \ - ? 1 : 0) - -#define S3C64XX_SPI_ST_TX_DONE(v, i) ((((v) >> (i)->rx_lvl_offset) & \ - (((i)->fifo_lvl_mask + 1) << 1)) \ - ? 1 : 0) -#define TX_FIFO_LVL(v, i) (((v) >> 6) & (i)->fifo_lvl_mask) -#define RX_FIFO_LVL(v, i) (((v) >> (i)->rx_lvl_offset) & (i)->fifo_lvl_mask) - -#define S3C64XX_SPI_MAX_TRAILCNT 0x3ff -#define S3C64XX_SPI_TRAILCNT_OFF 19 - -#define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT - -#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) - -#define SUSPND (1<<0) -#define SPIBUSY (1<<1) -#define RXBUSY (1<<2) -#define TXBUSY (1<<3) - -/** - * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver. - * @clk: Pointer to the spi clock. - * @master: Pointer to the SPI Protocol master. - * @workqueue: Work queue for the SPI xfer requests. - * @cntrlr_info: Platform specific data for the controller this driver manages. - * @tgl_spi: Pointer to the last CS left untoggled by the cs_change hint. - * @work: Work - * @queue: To log SPI xfer requests. - * @lock: Controller specific lock. - * @state: Set of FLAGS to indicate status. - * @rx_dmach: Controller's DMA channel for Rx. - * @tx_dmach: Controller's DMA channel for Tx. - * @sfr_start: BUS address of SPI controller regs. - * @regs: Pointer to ioremap'ed controller registers. - * @xfer_completion: To indicate completion of xfer task. - * @cur_mode: Stores the active configuration of the controller. - * @cur_bpw: Stores the active bits per word settings. - * @cur_speed: Stores the active xfer clock speed. - */ -struct s3c64xx_spi_driver_data { - void __iomem *regs; - struct clk *clk; - struct platform_device *pdev; - struct spi_master *master; - struct workqueue_struct *workqueue; - struct s3c64xx_spi_cntrlr_info *cntrlr_info; - struct spi_device *tgl_spi; - struct work_struct work; - struct list_head queue; - spinlock_t lock; - enum dma_ch rx_dmach; - enum dma_ch tx_dmach; - unsigned long sfr_start; - struct completion xfer_completion; - unsigned state; - unsigned cur_mode, cur_bpw; - unsigned cur_speed; -}; - -static struct s3c2410_dma_client s3c64xx_spi_dma_client = { - .name = "samsung-spi-dma", -}; - -static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) -{ - struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; - void __iomem *regs = sdd->regs; - unsigned long loops; - u32 val; - - writel(0, regs + S3C64XX_SPI_PACKET_CNT); - - val = readl(regs + S3C64XX_SPI_CH_CFG); - val |= S3C64XX_SPI_CH_SW_RST; - val &= ~S3C64XX_SPI_CH_HS_EN; - writel(val, regs + S3C64XX_SPI_CH_CFG); - - /* Flush TxFIFO*/ - loops = msecs_to_loops(1); - do { - val = readl(regs + S3C64XX_SPI_STATUS); - } while (TX_FIFO_LVL(val, sci) && loops--); - - /* Flush RxFIFO*/ - loops = msecs_to_loops(1); - do { - val = readl(regs + S3C64XX_SPI_STATUS); - if (RX_FIFO_LVL(val, sci)) - readl(regs + S3C64XX_SPI_RX_DATA); - else - break; - } while (loops--); - - val = readl(regs + S3C64XX_SPI_CH_CFG); - val &= ~S3C64XX_SPI_CH_SW_RST; - writel(val, regs + S3C64XX_SPI_CH_CFG); - - val = readl(regs + S3C64XX_SPI_MODE_CFG); - val &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON); - writel(val, regs + S3C64XX_SPI_MODE_CFG); - - val = readl(regs + S3C64XX_SPI_CH_CFG); - val &= ~(S3C64XX_SPI_CH_RXCH_ON | S3C64XX_SPI_CH_TXCH_ON); - writel(val, regs + S3C64XX_SPI_CH_CFG); -} - -static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, - struct spi_device *spi, - struct spi_transfer *xfer, int dma_mode) -{ - struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; - void __iomem *regs = sdd->regs; - u32 modecfg, chcfg; - - modecfg = readl(regs + S3C64XX_SPI_MODE_CFG); - modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON); - - chcfg = readl(regs + S3C64XX_SPI_CH_CFG); - chcfg &= ~S3C64XX_SPI_CH_TXCH_ON; - - if (dma_mode) { - chcfg &= ~S3C64XX_SPI_CH_RXCH_ON; - } else { - /* Always shift in data in FIFO, even if xfer is Tx only, - * this helps setting PCKT_CNT value for generating clocks - * as exactly needed. - */ - chcfg |= S3C64XX_SPI_CH_RXCH_ON; - writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) - | S3C64XX_SPI_PACKET_CNT_EN, - regs + S3C64XX_SPI_PACKET_CNT); - } - - if (xfer->tx_buf != NULL) { - sdd->state |= TXBUSY; - chcfg |= S3C64XX_SPI_CH_TXCH_ON; - if (dma_mode) { - modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; - s3c2410_dma_config(sdd->tx_dmach, 1); - s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd, - xfer->tx_dma, xfer->len); - s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START); - } else { - unsigned char *buf = (unsigned char *) xfer->tx_buf; - int i = 0; - while (i < xfer->len) - writeb(buf[i++], regs + S3C64XX_SPI_TX_DATA); - } - } - - if (xfer->rx_buf != NULL) { - sdd->state |= RXBUSY; - - if (sci->high_speed && sdd->cur_speed >= 30000000UL - && !(sdd->cur_mode & SPI_CPHA)) - chcfg |= S3C64XX_SPI_CH_HS_EN; - - if (dma_mode) { - modecfg |= S3C64XX_SPI_MODE_RXDMA_ON; - chcfg |= S3C64XX_SPI_CH_RXCH_ON; - writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) - | S3C64XX_SPI_PACKET_CNT_EN, - regs + S3C64XX_SPI_PACKET_CNT); - s3c2410_dma_config(sdd->rx_dmach, 1); - s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd, - xfer->rx_dma, xfer->len); - s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START); - } - } - - writel(modecfg, regs + S3C64XX_SPI_MODE_CFG); - writel(chcfg, regs + S3C64XX_SPI_CH_CFG); -} - -static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd, - struct spi_device *spi) -{ - struct s3c64xx_spi_csinfo *cs; - - if (sdd->tgl_spi != NULL) { /* If last device toggled after mssg */ - if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ - /* Deselect the last toggled device */ - cs = sdd->tgl_spi->controller_data; - cs->set_level(spi->mode & SPI_CS_HIGH ? 0 : 1); - } - sdd->tgl_spi = NULL; - } - - cs = spi->controller_data; - cs->set_level(spi->mode & SPI_CS_HIGH ? 1 : 0); -} - -static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd, - struct spi_transfer *xfer, int dma_mode) -{ - struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; - void __iomem *regs = sdd->regs; - unsigned long val; - int ms; - - /* millisecs to xfer 'len' bytes @ 'cur_speed' */ - ms = xfer->len * 8 * 1000 / sdd->cur_speed; - ms += 5; /* some tolerance */ - - if (dma_mode) { - val = msecs_to_jiffies(ms) + 10; - val = wait_for_completion_timeout(&sdd->xfer_completion, val); - } else { - val = msecs_to_loops(ms); - do { - val = readl(regs + S3C64XX_SPI_STATUS); - } while (RX_FIFO_LVL(val, sci) < xfer->len && --val); - } - - if (!val) - return -EIO; - - if (dma_mode) { - u32 status; - - /* - * DmaTx returns after simply writing data in the FIFO, - * w/o waiting for real transmission on the bus to finish. - * DmaRx returns only after Dma read data from FIFO which - * needs bus transmission to finish, so we don't worry if - * Xfer involved Rx(with or without Tx). - */ - if (xfer->rx_buf == NULL) { - val = msecs_to_loops(10); - status = readl(regs + S3C64XX_SPI_STATUS); - while ((TX_FIFO_LVL(status, sci) - || !S3C64XX_SPI_ST_TX_DONE(status, sci)) - && --val) { - cpu_relax(); - status = readl(regs + S3C64XX_SPI_STATUS); - } - - if (!val) - return -EIO; - } - } else { - unsigned char *buf; - int i; - - /* If it was only Tx */ - if (xfer->rx_buf == NULL) { - sdd->state &= ~TXBUSY; - return 0; - } - - i = 0; - buf = xfer->rx_buf; - while (i < xfer->len) - buf[i++] = readb(regs + S3C64XX_SPI_RX_DATA); - - sdd->state &= ~RXBUSY; - } - - return 0; -} - -static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd, - struct spi_device *spi) -{ - struct s3c64xx_spi_csinfo *cs = spi->controller_data; - - if (sdd->tgl_spi == spi) - sdd->tgl_spi = NULL; - - cs->set_level(spi->mode & SPI_CS_HIGH ? 0 : 1); -} - -static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) -{ - struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; - void __iomem *regs = sdd->regs; - u32 val; - - /* Disable Clock */ - val = readl(regs + S3C64XX_SPI_CLK_CFG); - val &= ~S3C64XX_SPI_ENCLK_ENABLE; - writel(val, regs + S3C64XX_SPI_CLK_CFG); - - /* Set Polarity and Phase */ - val = readl(regs + S3C64XX_SPI_CH_CFG); - val &= ~(S3C64XX_SPI_CH_SLAVE | - S3C64XX_SPI_CPOL_L | - S3C64XX_SPI_CPHA_B); - - if (sdd->cur_mode & SPI_CPOL) - val |= S3C64XX_SPI_CPOL_L; - - if (sdd->cur_mode & SPI_CPHA) - val |= S3C64XX_SPI_CPHA_B; - - writel(val, regs + S3C64XX_SPI_CH_CFG); - - /* Set Channel & DMA Mode */ - val = readl(regs + S3C64XX_SPI_MODE_CFG); - val &= ~(S3C64XX_SPI_MODE_BUS_TSZ_MASK - | S3C64XX_SPI_MODE_CH_TSZ_MASK); - - switch (sdd->cur_bpw) { - case 32: - val |= S3C64XX_SPI_MODE_BUS_TSZ_WORD; - break; - case 16: - val |= S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD; - break; - default: - val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE; - break; - } - val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; /* Always 8bits wide */ - - writel(val, regs + S3C64XX_SPI_MODE_CFG); - - /* Configure Clock */ - val = readl(regs + S3C64XX_SPI_CLK_CFG); - val &= ~S3C64XX_SPI_PSR_MASK; - val |= ((clk_get_rate(sci->src_clk) / sdd->cur_speed / 2 - 1) - & S3C64XX_SPI_PSR_MASK); - writel(val, regs + S3C64XX_SPI_CLK_CFG); - - /* Enable Clock */ - val = readl(regs + S3C64XX_SPI_CLK_CFG); - val |= S3C64XX_SPI_ENCLK_ENABLE; - writel(val, regs + S3C64XX_SPI_CLK_CFG); -} - -void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id, - int size, enum s3c2410_dma_buffresult res) -{ - struct s3c64xx_spi_driver_data *sdd = buf_id; - unsigned long flags; - - spin_lock_irqsave(&sdd->lock, flags); - - if (res == S3C2410_RES_OK) - sdd->state &= ~RXBUSY; - else - dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size); - - /* If the other done */ - if (!(sdd->state & TXBUSY)) - complete(&sdd->xfer_completion); - - spin_unlock_irqrestore(&sdd->lock, flags); -} - -void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id, - int size, enum s3c2410_dma_buffresult res) -{ - struct s3c64xx_spi_driver_data *sdd = buf_id; - unsigned long flags; - - spin_lock_irqsave(&sdd->lock, flags); - - if (res == S3C2410_RES_OK) - sdd->state &= ~TXBUSY; - else - dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size); - - /* If the other done */ - if (!(sdd->state & RXBUSY)) - complete(&sdd->xfer_completion); - - spin_unlock_irqrestore(&sdd->lock, flags); -} - -#define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) - -static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd, - struct spi_message *msg) -{ - struct device *dev = &sdd->pdev->dev; - struct spi_transfer *xfer; - - if (msg->is_dma_mapped) - return 0; - - /* First mark all xfer unmapped */ - list_for_each_entry(xfer, &msg->transfers, transfer_list) { - xfer->rx_dma = XFER_DMAADDR_INVALID; - xfer->tx_dma = XFER_DMAADDR_INVALID; - } - - /* Map until end or first fail */ - list_for_each_entry(xfer, &msg->transfers, transfer_list) { - - if (xfer->tx_buf != NULL) { - xfer->tx_dma = dma_map_single(dev, xfer->tx_buf, - xfer->len, DMA_TO_DEVICE); - if (dma_mapping_error(dev, xfer->tx_dma)) { - dev_err(dev, "dma_map_single Tx failed\n"); - xfer->tx_dma = XFER_DMAADDR_INVALID; - return -ENOMEM; - } - } - - if (xfer->rx_buf != NULL) { - xfer->rx_dma = dma_map_single(dev, xfer->rx_buf, - xfer->len, DMA_FROM_DEVICE); - if (dma_mapping_error(dev, xfer->rx_dma)) { - dev_err(dev, "dma_map_single Rx failed\n"); - dma_unmap_single(dev, xfer->tx_dma, - xfer->len, DMA_TO_DEVICE); - xfer->tx_dma = XFER_DMAADDR_INVALID; - xfer->rx_dma = XFER_DMAADDR_INVALID; - return -ENOMEM; - } - } - } - - return 0; -} - -static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd, - struct spi_message *msg) -{ - struct device *dev = &sdd->pdev->dev; - struct spi_transfer *xfer; - - if (msg->is_dma_mapped) - return; - - list_for_each_entry(xfer, &msg->transfers, transfer_list) { - - if (xfer->rx_buf != NULL - && xfer->rx_dma != XFER_DMAADDR_INVALID) - dma_unmap_single(dev, xfer->rx_dma, - xfer->len, DMA_FROM_DEVICE); - - if (xfer->tx_buf != NULL - && xfer->tx_dma != XFER_DMAADDR_INVALID) - dma_unmap_single(dev, xfer->tx_dma, - xfer->len, DMA_TO_DEVICE); - } -} - -static void handle_msg(struct s3c64xx_spi_driver_data *sdd, - struct spi_message *msg) -{ - struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; - struct spi_device *spi = msg->spi; - struct s3c64xx_spi_csinfo *cs = spi->controller_data; - struct spi_transfer *xfer; - int status = 0, cs_toggle = 0; - u32 speed; - u8 bpw; - - /* If Master's(controller) state differs from that needed by Slave */ - if (sdd->cur_speed != spi->max_speed_hz - || sdd->cur_mode != spi->mode - || sdd->cur_bpw != spi->bits_per_word) { - sdd->cur_bpw = spi->bits_per_word; - sdd->cur_speed = spi->max_speed_hz; - sdd->cur_mode = spi->mode; - s3c64xx_spi_config(sdd); - } - - /* Map all the transfers if needed */ - if (s3c64xx_spi_map_mssg(sdd, msg)) { - dev_err(&spi->dev, - "Xfer: Unable to map message buffers!\n"); - status = -ENOMEM; - goto out; - } - - /* Configure feedback delay */ - writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK); - - list_for_each_entry(xfer, &msg->transfers, transfer_list) { - - unsigned long flags; - int use_dma; - - INIT_COMPLETION(sdd->xfer_completion); - - /* Only BPW and Speed may change across transfers */ - bpw = xfer->bits_per_word ? : spi->bits_per_word; - speed = xfer->speed_hz ? : spi->max_speed_hz; - - if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) { - sdd->cur_bpw = bpw; - sdd->cur_speed = speed; - s3c64xx_spi_config(sdd); - } - - /* Polling method for xfers not bigger than FIFO capacity */ - if (xfer->len <= ((sci->fifo_lvl_mask >> 1) + 1)) - use_dma = 0; - else - use_dma = 1; - - spin_lock_irqsave(&sdd->lock, flags); - - /* Pending only which is to be done */ - sdd->state &= ~RXBUSY; - sdd->state &= ~TXBUSY; - - enable_datapath(sdd, spi, xfer, use_dma); - - /* Slave Select */ - enable_cs(sdd, spi); - - /* Start the signals */ - S3C64XX_SPI_ACT(sdd); - - spin_unlock_irqrestore(&sdd->lock, flags); - - status = wait_for_xfer(sdd, xfer, use_dma); - - /* Quiese the signals */ - S3C64XX_SPI_DEACT(sdd); - - if (status) { - dev_err(&spi->dev, "I/O Error: \ - rx-%d tx-%d res:rx-%c tx-%c len-%d\n", - xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0, - (sdd->state & RXBUSY) ? 'f' : 'p', - (sdd->state & TXBUSY) ? 'f' : 'p', - xfer->len); - - if (use_dma) { - if (xfer->tx_buf != NULL - && (sdd->state & TXBUSY)) - s3c2410_dma_ctrl(sdd->tx_dmach, - S3C2410_DMAOP_FLUSH); - if (xfer->rx_buf != NULL - && (sdd->state & RXBUSY)) - s3c2410_dma_ctrl(sdd->rx_dmach, - S3C2410_DMAOP_FLUSH); - } - - goto out; - } - - if (xfer->delay_usecs) - udelay(xfer->delay_usecs); - - if (xfer->cs_change) { - /* Hint that the next mssg is gonna be - for the same device */ - if (list_is_last(&xfer->transfer_list, - &msg->transfers)) - cs_toggle = 1; - else - disable_cs(sdd, spi); - } - - msg->actual_length += xfer->len; - - flush_fifo(sdd); - } - -out: - if (!cs_toggle || status) - disable_cs(sdd, spi); - else - sdd->tgl_spi = spi; - - s3c64xx_spi_unmap_mssg(sdd, msg); - - msg->status = status; - - if (msg->complete) - msg->complete(msg->context); -} - -static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) -{ - if (s3c2410_dma_request(sdd->rx_dmach, - &s3c64xx_spi_dma_client, NULL) < 0) { - dev_err(&sdd->pdev->dev, "cannot get RxDMA\n"); - return 0; - } - s3c2410_dma_set_buffdone_fn(sdd->rx_dmach, s3c64xx_spi_dma_rxcb); - s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW, - sdd->sfr_start + S3C64XX_SPI_RX_DATA); - - if (s3c2410_dma_request(sdd->tx_dmach, - &s3c64xx_spi_dma_client, NULL) < 0) { - dev_err(&sdd->pdev->dev, "cannot get TxDMA\n"); - s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client); - return 0; - } - s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb); - s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM, - sdd->sfr_start + S3C64XX_SPI_TX_DATA); - - return 1; -} - -static void s3c64xx_spi_work(struct work_struct *work) -{ - struct s3c64xx_spi_driver_data *sdd = container_of(work, - struct s3c64xx_spi_driver_data, work); - unsigned long flags; - - /* Acquire DMA channels */ - while (!acquire_dma(sdd)) - msleep(10); - - spin_lock_irqsave(&sdd->lock, flags); - - while (!list_empty(&sdd->queue) - && !(sdd->state & SUSPND)) { - - struct spi_message *msg; - - msg = container_of(sdd->queue.next, struct spi_message, queue); - - list_del_init(&msg->queue); - - /* Set Xfer busy flag */ - sdd->state |= SPIBUSY; - - spin_unlock_irqrestore(&sdd->lock, flags); - - handle_msg(sdd, msg); - - spin_lock_irqsave(&sdd->lock, flags); - - sdd->state &= ~SPIBUSY; - } - - spin_unlock_irqrestore(&sdd->lock, flags); - - /* Free DMA channels */ - s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client); - s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client); -} - -static int s3c64xx_spi_transfer(struct spi_device *spi, - struct spi_message *msg) -{ - struct s3c64xx_spi_driver_data *sdd; - unsigned long flags; - - sdd = spi_master_get_devdata(spi->master); - - spin_lock_irqsave(&sdd->lock, flags); - - if (sdd->state & SUSPND) { - spin_unlock_irqrestore(&sdd->lock, flags); - return -ESHUTDOWN; - } - - msg->status = -EINPROGRESS; - msg->actual_length = 0; - - list_add_tail(&msg->queue, &sdd->queue); - - queue_work(sdd->workqueue, &sdd->work); - - spin_unlock_irqrestore(&sdd->lock, flags); - - return 0; -} - -/* - * Here we only check the validity of requested configuration - * and save the configuration in a local data-structure. - * The controller is actually configured only just before we - * get a message to transfer. - */ -static int s3c64xx_spi_setup(struct spi_device *spi) -{ - struct s3c64xx_spi_csinfo *cs = spi->controller_data; - struct s3c64xx_spi_driver_data *sdd; - struct s3c64xx_spi_cntrlr_info *sci; - struct spi_message *msg; - u32 psr, speed; - unsigned long flags; - int err = 0; - - if (cs == NULL || cs->set_level == NULL) { - dev_err(&spi->dev, "No CS for SPI(%d)\n", spi->chip_select); - return -ENODEV; - } - - sdd = spi_master_get_devdata(spi->master); - sci = sdd->cntrlr_info; - - spin_lock_irqsave(&sdd->lock, flags); - - list_for_each_entry(msg, &sdd->queue, queue) { - /* Is some mssg is already queued for this device */ - if (msg->spi == spi) { - dev_err(&spi->dev, - "setup: attempt while mssg in queue!\n"); - spin_unlock_irqrestore(&sdd->lock, flags); - return -EBUSY; - } - } - - if (sdd->state & SUSPND) { - spin_unlock_irqrestore(&sdd->lock, flags); - dev_err(&spi->dev, - "setup: SPI-%d not active!\n", spi->master->bus_num); - return -ESHUTDOWN; - } - - spin_unlock_irqrestore(&sdd->lock, flags); - - if (spi->bits_per_word != 8 - && spi->bits_per_word != 16 - && spi->bits_per_word != 32) { - dev_err(&spi->dev, "setup: %dbits/wrd not supported!\n", - spi->bits_per_word); - err = -EINVAL; - goto setup_exit; - } - - /* Check if we can provide the requested rate */ - speed = clk_get_rate(sci->src_clk) / 2 / (0 + 1); /* Max possible */ - - if (spi->max_speed_hz > speed) - spi->max_speed_hz = speed; - - psr = clk_get_rate(sci->src_clk) / 2 / spi->max_speed_hz - 1; - psr &= S3C64XX_SPI_PSR_MASK; - if (psr == S3C64XX_SPI_PSR_MASK) - psr--; - - speed = clk_get_rate(sci->src_clk) / 2 / (psr + 1); - if (spi->max_speed_hz < speed) { - if (psr+1 < S3C64XX_SPI_PSR_MASK) { - psr++; - } else { - err = -EINVAL; - goto setup_exit; - } - } - - speed = clk_get_rate(sci->src_clk) / 2 / (psr + 1); - if (spi->max_speed_hz >= speed) - spi->max_speed_hz = speed; - else - err = -EINVAL; - -setup_exit: - - /* setup() returns with device de-selected */ - disable_cs(sdd, spi); - - return err; -} - -static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel) -{ - struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; - void __iomem *regs = sdd->regs; - unsigned int val; - - sdd->cur_speed = 0; - - S3C64XX_SPI_DEACT(sdd); - - /* Disable Interrupts - we use Polling if not DMA mode */ - writel(0, regs + S3C64XX_SPI_INT_EN); - - writel(sci->src_clk_nr << S3C64XX_SPI_CLKSEL_SRCSHFT, - regs + S3C64XX_SPI_CLK_CFG); - writel(0, regs + S3C64XX_SPI_MODE_CFG); - writel(0, regs + S3C64XX_SPI_PACKET_CNT); - - /* Clear any irq pending bits */ - writel(readl(regs + S3C64XX_SPI_PENDING_CLR), - regs + S3C64XX_SPI_PENDING_CLR); - - writel(0, regs + S3C64XX_SPI_SWAP_CFG); - - val = readl(regs + S3C64XX_SPI_MODE_CFG); - val &= ~S3C64XX_SPI_MODE_4BURST; - val &= ~(S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF); - val |= (S3C64XX_SPI_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF); - writel(val, regs + S3C64XX_SPI_MODE_CFG); - - flush_fifo(sdd); -} - -static int __init s3c64xx_spi_probe(struct platform_device *pdev) -{ - struct resource *mem_res, *dmatx_res, *dmarx_res; - struct s3c64xx_spi_driver_data *sdd; - struct s3c64xx_spi_cntrlr_info *sci; - struct spi_master *master; - int ret; - - if (pdev->id < 0) { - dev_err(&pdev->dev, - "Invalid platform device id-%d\n", pdev->id); - return -ENODEV; - } - - if (pdev->dev.platform_data == NULL) { - dev_err(&pdev->dev, "platform_data missing!\n"); - return -ENODEV; - } - - /* Check for availability of necessary resource */ - - dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (dmatx_res == NULL) { - dev_err(&pdev->dev, "Unable to get SPI-Tx dma resource\n"); - return -ENXIO; - } - - dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (dmarx_res == NULL) { - dev_err(&pdev->dev, "Unable to get SPI-Rx dma resource\n"); - return -ENXIO; - } - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (mem_res == NULL) { - dev_err(&pdev->dev, "Unable to get SPI MEM resource\n"); - return -ENXIO; - } - - master = spi_alloc_master(&pdev->dev, - sizeof(struct s3c64xx_spi_driver_data)); - if (master == NULL) { - dev_err(&pdev->dev, "Unable to allocate SPI Master\n"); - return -ENOMEM; - } - - sci = pdev->dev.platform_data; - - platform_set_drvdata(pdev, master); - - sdd = spi_master_get_devdata(master); - sdd->master = master; - sdd->cntrlr_info = sci; - sdd->pdev = pdev; - sdd->sfr_start = mem_res->start; - sdd->tx_dmach = dmatx_res->start; - sdd->rx_dmach = dmarx_res->start; - - sdd->cur_bpw = 8; - - master->bus_num = pdev->id; - master->setup = s3c64xx_spi_setup; - master->transfer = s3c64xx_spi_transfer; - master->num_chipselect = sci->num_cs; - master->dma_alignment = 8; - /* the spi->mode bits understood by this driver: */ - master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; - - if (request_mem_region(mem_res->start, - resource_size(mem_res), pdev->name) == NULL) { - dev_err(&pdev->dev, "Req mem region failed\n"); - ret = -ENXIO; - goto err0; - } - - sdd->regs = ioremap(mem_res->start, resource_size(mem_res)); - if (sdd->regs == NULL) { - dev_err(&pdev->dev, "Unable to remap IO\n"); - ret = -ENXIO; - goto err1; - } - - if (sci->cfg_gpio == NULL || sci->cfg_gpio(pdev)) { - dev_err(&pdev->dev, "Unable to config gpio\n"); - ret = -EBUSY; - goto err2; - } - - /* Setup clocks */ - sdd->clk = clk_get(&pdev->dev, "spi"); - if (IS_ERR(sdd->clk)) { - dev_err(&pdev->dev, "Unable to acquire clock 'spi'\n"); - ret = PTR_ERR(sdd->clk); - goto err3; - } - - if (clk_enable(sdd->clk)) { - dev_err(&pdev->dev, "Couldn't enable clock 'spi'\n"); - ret = -EBUSY; - goto err4; - } - - if (sci->src_clk_nr == S3C64XX_SPI_SRCCLK_PCLK) - sci->src_clk = sdd->clk; - else - sci->src_clk = clk_get(&pdev->dev, sci->src_clk_name); - if (IS_ERR(sci->src_clk)) { - dev_err(&pdev->dev, - "Unable to acquire clock '%s'\n", sci->src_clk_name); - ret = PTR_ERR(sci->src_clk); - goto err5; - } - - if (sci->src_clk != sdd->clk && clk_enable(sci->src_clk)) { - dev_err(&pdev->dev, "Couldn't enable clock '%s'\n", - sci->src_clk_name); - ret = -EBUSY; - goto err6; - } - - sdd->workqueue = create_singlethread_workqueue( - dev_name(master->dev.parent)); - if (sdd->workqueue == NULL) { - dev_err(&pdev->dev, "Unable to create workqueue\n"); - ret = -ENOMEM; - goto err7; - } - - /* Setup Deufult Mode */ - s3c64xx_spi_hwinit(sdd, pdev->id); - - spin_lock_init(&sdd->lock); - init_completion(&sdd->xfer_completion); - INIT_WORK(&sdd->work, s3c64xx_spi_work); - INIT_LIST_HEAD(&sdd->queue); - - if (spi_register_master(master)) { - dev_err(&pdev->dev, "cannot register SPI master\n"); - ret = -EBUSY; - goto err8; - } - - dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d \ - with %d Slaves attached\n", - pdev->id, master->num_chipselect); - dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\ - \tDMA=[Rx-%d, Tx-%d]\n", - mem_res->end, mem_res->start, - sdd->rx_dmach, sdd->tx_dmach); - - return 0; - -err8: - destroy_workqueue(sdd->workqueue); -err7: - if (sci->src_clk != sdd->clk) - clk_disable(sci->src_clk); -err6: - if (sci->src_clk != sdd->clk) - clk_put(sci->src_clk); -err5: - clk_disable(sdd->clk); -err4: - clk_put(sdd->clk); -err3: -err2: - iounmap((void *) sdd->regs); -err1: - release_mem_region(mem_res->start, resource_size(mem_res)); -err0: - platform_set_drvdata(pdev, NULL); - spi_master_put(master); - - return ret; -} - -static int s3c64xx_spi_remove(struct platform_device *pdev) -{ - struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); - struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); - struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; - struct resource *mem_res; - unsigned long flags; - - spin_lock_irqsave(&sdd->lock, flags); - sdd->state |= SUSPND; - spin_unlock_irqrestore(&sdd->lock, flags); - - while (sdd->state & SPIBUSY) - msleep(10); - - spi_unregister_master(master); - - destroy_workqueue(sdd->workqueue); - - if (sci->src_clk != sdd->clk) - clk_disable(sci->src_clk); - - if (sci->src_clk != sdd->clk) - clk_put(sci->src_clk); - - clk_disable(sdd->clk); - clk_put(sdd->clk); - - iounmap((void *) sdd->regs); - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(mem_res->start, resource_size(mem_res)); - - platform_set_drvdata(pdev, NULL); - spi_master_put(master); - - return 0; -} - -#ifdef CONFIG_PM -static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); - struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); - struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; - struct s3c64xx_spi_csinfo *cs; - unsigned long flags; - - spin_lock_irqsave(&sdd->lock, flags); - sdd->state |= SUSPND; - spin_unlock_irqrestore(&sdd->lock, flags); - - while (sdd->state & SPIBUSY) - msleep(10); - - /* Disable the clock */ - if (sci->src_clk != sdd->clk) - clk_disable(sci->src_clk); - - clk_disable(sdd->clk); - - sdd->cur_speed = 0; /* Output Clock is stopped */ - - return 0; -} - -static int s3c64xx_spi_resume(struct platform_device *pdev) -{ - struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); - struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); - struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; - unsigned long flags; - - sci->cfg_gpio(pdev); - - /* Enable the clock */ - if (sci->src_clk != sdd->clk) - clk_enable(sci->src_clk); - - clk_enable(sdd->clk); - - s3c64xx_spi_hwinit(sdd, pdev->id); - - spin_lock_irqsave(&sdd->lock, flags); - sdd->state &= ~SUSPND; - spin_unlock_irqrestore(&sdd->lock, flags); - - return 0; -} -#else -#define s3c64xx_spi_suspend NULL -#define s3c64xx_spi_resume NULL -#endif /* CONFIG_PM */ - -static struct platform_driver s3c64xx_spi_driver = { - .driver = { - .name = "s3c64xx-spi", - .owner = THIS_MODULE, - }, - .remove = s3c64xx_spi_remove, - .suspend = s3c64xx_spi_suspend, - .resume = s3c64xx_spi_resume, -}; -MODULE_ALIAS("platform:s3c64xx-spi"); - -static int __init s3c64xx_spi_init(void) -{ - return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe); -} -module_init(s3c64xx_spi_init); - -static void __exit s3c64xx_spi_exit(void) -{ - platform_driver_unregister(&s3c64xx_spi_driver); -} -module_exit(s3c64xx_spi_exit); - -MODULE_AUTHOR("Jaswinder Singh "); -MODULE_DESCRIPTION("S3C64XX SPI Controller Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/spi/spi_sh_sci.c b/trunk/drivers/spi/spi_sh_sci.c index a65c12ffa733..7d36720eb982 100644 --- a/trunk/drivers/spi/spi_sh_sci.c +++ b/trunk/drivers/spi/spi_sh_sci.c @@ -148,7 +148,7 @@ static int sh_sci_spi_probe(struct platform_device *dev) ret = -ENOENT; goto err1; } - sp->membase = ioremap(r->start, resource_size(r)); + sp->membase = ioremap(r->start, r->end - r->start + 1); if (!sp->membase) { ret = -ENXIO; goto err1; diff --git a/trunk/drivers/spi/spi_txx9.c b/trunk/drivers/spi/spi_txx9.c index dfa024b633e1..19f75627c3de 100644 --- a/trunk/drivers/spi/spi_txx9.c +++ b/trunk/drivers/spi/spi_txx9.c @@ -375,10 +375,12 @@ static int __init txx9spi_probe(struct platform_device *dev) res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res) goto exit_busy; - if (!devm_request_mem_region(&dev->dev, res->start, resource_size(res), + if (!devm_request_mem_region(&dev->dev, + res->start, res->end - res->start + 1, "spi_txx9")) goto exit_busy; - c->membase = devm_ioremap(&dev->dev, res->start, resource_size(res)); + c->membase = devm_ioremap(&dev->dev, + res->start, res->end - res->start + 1); if (!c->membase) goto exit_busy; diff --git a/trunk/drivers/spi/spidev.c b/trunk/drivers/spi/spidev.c index ea1bec3c9a13..9c446e6003d5 100644 --- a/trunk/drivers/spi/spidev.c +++ b/trunk/drivers/spi/spidev.c @@ -53,7 +53,7 @@ #define SPIDEV_MAJOR 153 /* assigned */ #define N_SPI_MINORS 32 /* ... up to 256 */ -static DECLARE_BITMAP(minors, N_SPI_MINORS); +static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG]; /* Bit masks for spi_device.mode management. Note that incorrect @@ -558,7 +558,7 @@ static struct class *spidev_class; /*-------------------------------------------------------------------------*/ -static int __devinit spidev_probe(struct spi_device *spi) +static int spidev_probe(struct spi_device *spi) { struct spidev_data *spidev; int status; @@ -607,7 +607,7 @@ static int __devinit spidev_probe(struct spi_device *spi) return status; } -static int __devexit spidev_remove(struct spi_device *spi) +static int spidev_remove(struct spi_device *spi) { struct spidev_data *spidev = spi_get_drvdata(spi); @@ -629,7 +629,7 @@ static int __devexit spidev_remove(struct spi_device *spi) return 0; } -static struct spi_driver spidev_spi_driver = { +static struct spi_driver spidev_spi = { .driver = { .name = "spidev", .owner = THIS_MODULE, @@ -661,14 +661,14 @@ static int __init spidev_init(void) spidev_class = class_create(THIS_MODULE, "spidev"); if (IS_ERR(spidev_class)) { - unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); + unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); return PTR_ERR(spidev_class); } - status = spi_register_driver(&spidev_spi_driver); + status = spi_register_driver(&spidev_spi); if (status < 0) { class_destroy(spidev_class); - unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); + unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); } return status; } @@ -676,9 +676,9 @@ module_init(spidev_init); static void __exit spidev_exit(void) { - spi_unregister_driver(&spidev_spi_driver); + spi_unregister_driver(&spidev_spi); class_destroy(spidev_class); - unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); + unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); } module_exit(spidev_exit); diff --git a/trunk/drivers/staging/iio/ring_sw.h b/trunk/drivers/staging/iio/ring_sw.h index fd677f008365..f0b86f02cd80 100644 --- a/trunk/drivers/staging/iio/ring_sw.h +++ b/trunk/drivers/staging/iio/ring_sw.h @@ -29,6 +29,7 @@ * driver requests - some may support multiple options */ +#include #include "iio.h" #include "ring_generic.h" diff --git a/trunk/drivers/staging/panel/panel.c b/trunk/drivers/staging/panel/panel.c index f98a52448eae..4ce399b6d237 100644 --- a/trunk/drivers/staging/panel/panel.c +++ b/trunk/drivers/staging/panel/panel.c @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/drivers/video/atafb.c b/trunk/drivers/video/atafb.c index b7687c55fe16..2051c9dc813b 100644 --- a/trunk/drivers/video/atafb.c +++ b/trunk/drivers/video/atafb.c @@ -2245,6 +2245,9 @@ static int ext_setcolreg(unsigned int regno, unsigned int red, if (regno > 255) return 1; + if (regno > 255) + return 1; + switch (external_card_type) { case IS_VGA: OUTB(0x3c8, regno); diff --git a/trunk/drivers/video/backlight/adp5520_bl.c b/trunk/drivers/video/backlight/adp5520_bl.c index 86d95c228adb..4c10edecfb66 100644 --- a/trunk/drivers/video/backlight/adp5520_bl.c +++ b/trunk/drivers/video/backlight/adp5520_bl.c @@ -85,7 +85,7 @@ static int adp5520_bl_get_brightness(struct backlight_device *bl) return error ? data->current_brightness : reg_val; } -static const struct backlight_ops adp5520_bl_ops = { +static struct backlight_ops adp5520_bl_ops = { .update_status = adp5520_bl_update_status, .get_brightness = adp5520_bl_get_brightness, }; diff --git a/trunk/drivers/video/backlight/adx_bl.c b/trunk/drivers/video/backlight/adx_bl.c index d769b0bab21a..2c3bdfc620b7 100644 --- a/trunk/drivers/video/backlight/adx_bl.c +++ b/trunk/drivers/video/backlight/adx_bl.c @@ -61,7 +61,7 @@ static int adx_backlight_check_fb(struct fb_info *fb) return 1; } -static const struct backlight_ops adx_backlight_ops = { +static struct backlight_ops adx_backlight_ops = { .options = 0, .update_status = adx_backlight_update_status, .get_brightness = adx_backlight_get_brightness, diff --git a/trunk/drivers/video/backlight/atmel-pwm-bl.c b/trunk/drivers/video/backlight/atmel-pwm-bl.c index f625ffc69ad3..2cf7ba52f67c 100644 --- a/trunk/drivers/video/backlight/atmel-pwm-bl.c +++ b/trunk/drivers/video/backlight/atmel-pwm-bl.c @@ -113,7 +113,7 @@ static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl) return pwm_channel_enable(&pwmbl->pwmc); } -static const struct backlight_ops atmel_pwm_bl_ops = { +static struct backlight_ops atmel_pwm_bl_ops = { .get_brightness = atmel_pwm_bl_get_intensity, .update_status = atmel_pwm_bl_set_intensity, }; diff --git a/trunk/drivers/video/backlight/backlight.c b/trunk/drivers/video/backlight/backlight.c index 18829cf68b1b..6615ac7fa60a 100644 --- a/trunk/drivers/video/backlight/backlight.c +++ b/trunk/drivers/video/backlight/backlight.c @@ -269,7 +269,7 @@ EXPORT_SYMBOL(backlight_force_update); * ERR_PTR() or a pointer to the newly allocated device. */ struct backlight_device *backlight_device_register(const char *name, - struct device *parent, void *devdata, const struct backlight_ops *ops) + struct device *parent, void *devdata, struct backlight_ops *ops) { struct backlight_device *new_bd; int rc; diff --git a/trunk/drivers/video/backlight/corgi_lcd.c b/trunk/drivers/video/backlight/corgi_lcd.c index b4bcf8043797..96774949cd30 100644 --- a/trunk/drivers/video/backlight/corgi_lcd.c +++ b/trunk/drivers/video/backlight/corgi_lcd.c @@ -451,7 +451,7 @@ void corgi_lcd_limit_intensity(int limit) } EXPORT_SYMBOL(corgi_lcd_limit_intensity); -static const struct backlight_ops corgi_bl_ops = { +static struct backlight_ops corgi_bl_ops = { .get_brightness = corgi_bl_get_intensity, .update_status = corgi_bl_update_status, }; diff --git a/trunk/drivers/video/backlight/cr_bllcd.c b/trunk/drivers/video/backlight/cr_bllcd.c index da86db4374a0..b9fe62b475c6 100644 --- a/trunk/drivers/video/backlight/cr_bllcd.c +++ b/trunk/drivers/video/backlight/cr_bllcd.c @@ -108,7 +108,7 @@ static int cr_backlight_get_intensity(struct backlight_device *bd) return intensity; } -static const struct backlight_ops cr_backlight_ops = { +static struct backlight_ops cr_backlight_ops = { .get_brightness = cr_backlight_get_intensity, .update_status = cr_backlight_set_intensity, }; @@ -201,7 +201,7 @@ static int cr_backlight_probe(struct platform_device *pdev) if (IS_ERR(ldp)) { backlight_device_unregister(bdp); pci_dev_put(lpc_dev); - return PTR_ERR(ldp); + return PTR_ERR(bdp); } pci_read_config_dword(lpc_dev, CRVML_REG_GPIOBAR, diff --git a/trunk/drivers/video/backlight/da903x_bl.c b/trunk/drivers/video/backlight/da903x_bl.c index 74cdc640173d..f2d76dae1eb3 100644 --- a/trunk/drivers/video/backlight/da903x_bl.c +++ b/trunk/drivers/video/backlight/da903x_bl.c @@ -95,7 +95,7 @@ static int da903x_backlight_get_brightness(struct backlight_device *bl) return data->current_brightness; } -static const struct backlight_ops da903x_backlight_ops = { +static struct backlight_ops da903x_backlight_ops = { .update_status = da903x_backlight_update_status, .get_brightness = da903x_backlight_get_brightness, }; diff --git a/trunk/drivers/video/backlight/generic_bl.c b/trunk/drivers/video/backlight/generic_bl.c index e6d348e63596..6d27f62fdcd0 100644 --- a/trunk/drivers/video/backlight/generic_bl.c +++ b/trunk/drivers/video/backlight/generic_bl.c @@ -70,7 +70,7 @@ void corgibl_limit_intensity(int limit) } EXPORT_SYMBOL(corgibl_limit_intensity); -static const struct backlight_ops genericbl_ops = { +static struct backlight_ops genericbl_ops = { .options = BL_CORE_SUSPENDRESUME, .get_brightness = genericbl_get_intensity, .update_status = genericbl_send_intensity, diff --git a/trunk/drivers/video/backlight/hp680_bl.c b/trunk/drivers/video/backlight/hp680_bl.c index f7cc528d5be7..7fb4eefff80d 100644 --- a/trunk/drivers/video/backlight/hp680_bl.c +++ b/trunk/drivers/video/backlight/hp680_bl.c @@ -98,7 +98,7 @@ static int hp680bl_get_intensity(struct backlight_device *bd) return current_intensity; } -static const struct backlight_ops hp680bl_ops = { +static struct backlight_ops hp680bl_ops = { .get_brightness = hp680bl_get_intensity, .update_status = hp680bl_set_intensity, }; diff --git a/trunk/drivers/video/backlight/jornada720_bl.c b/trunk/drivers/video/backlight/jornada720_bl.c index db9071fc5665..7aed2565c1bd 100644 --- a/trunk/drivers/video/backlight/jornada720_bl.c +++ b/trunk/drivers/video/backlight/jornada720_bl.c @@ -93,7 +93,7 @@ static int jornada_bl_update_status(struct backlight_device *bd) return ret; } -static const struct backlight_ops jornada_bl_ops = { +static struct backlight_ops jornada_bl_ops = { .get_brightness = jornada_bl_get_brightness, .update_status = jornada_bl_update_status, .options = BL_CORE_SUSPENDRESUME, diff --git a/trunk/drivers/video/backlight/kb3886_bl.c b/trunk/drivers/video/backlight/kb3886_bl.c index 939e7b830cf3..a38fda1742dd 100644 --- a/trunk/drivers/video/backlight/kb3886_bl.c +++ b/trunk/drivers/video/backlight/kb3886_bl.c @@ -134,7 +134,7 @@ static int kb3886bl_get_intensity(struct backlight_device *bd) return kb3886bl_intensity; } -static const struct backlight_ops kb3886bl_ops = { +static struct backlight_ops kb3886bl_ops = { .get_brightness = kb3886bl_get_intensity, .update_status = kb3886bl_send_intensity, }; diff --git a/trunk/drivers/video/backlight/locomolcd.c b/trunk/drivers/video/backlight/locomolcd.c index 00a9591b0003..6b488b8a7eee 100644 --- a/trunk/drivers/video/backlight/locomolcd.c +++ b/trunk/drivers/video/backlight/locomolcd.c @@ -141,7 +141,7 @@ static int locomolcd_get_intensity(struct backlight_device *bd) return current_intensity; } -static const struct backlight_ops locomobl_data = { +static struct backlight_ops locomobl_data = { .get_brightness = locomolcd_get_intensity, .update_status = locomolcd_set_intensity, }; diff --git a/trunk/drivers/video/backlight/mbp_nvidia_bl.c b/trunk/drivers/video/backlight/mbp_nvidia_bl.c index 2e78b0784bdc..9edb8d7c295f 100644 --- a/trunk/drivers/video/backlight/mbp_nvidia_bl.c +++ b/trunk/drivers/video/backlight/mbp_nvidia_bl.c @@ -33,7 +33,7 @@ struct dmi_match_data { unsigned long iostart; unsigned long iolen; /* Backlight operations structure. */ - const struct backlight_ops backlight_ops; + struct backlight_ops backlight_ops; }; /* Module parameters. */ @@ -218,24 +218,6 @@ static const struct dmi_system_id __initdata mbp_device_table[] = { }, .driver_data = (void *)&nvidia_chipset_data, }, - { - .callback = mbp_dmi_match, - .ident = "MacBookPro 5,3", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,3"), - }, - .driver_data = (void *)&nvidia_chipset_data, - }, - { - .callback = mbp_dmi_match, - .ident = "MacBookPro 5,4", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,4"), - }, - .driver_data = (void *)&nvidia_chipset_data, - }, { .callback = mbp_dmi_match, .ident = "MacBookPro 5,5", diff --git a/trunk/drivers/video/backlight/omap1_bl.c b/trunk/drivers/video/backlight/omap1_bl.c index 409ca9643528..8693e5fcd2eb 100644 --- a/trunk/drivers/video/backlight/omap1_bl.c +++ b/trunk/drivers/video/backlight/omap1_bl.c @@ -125,7 +125,7 @@ static int omapbl_get_intensity(struct backlight_device *dev) return bl->current_intensity; } -static const struct backlight_ops omapbl_ops = { +static struct backlight_ops omapbl_ops = { .get_brightness = omapbl_get_intensity, .update_status = omapbl_update_status, }; diff --git a/trunk/drivers/video/backlight/progear_bl.c b/trunk/drivers/video/backlight/progear_bl.c index 075786e05034..9edaf24fd82d 100644 --- a/trunk/drivers/video/backlight/progear_bl.c +++ b/trunk/drivers/video/backlight/progear_bl.c @@ -54,7 +54,7 @@ static int progearbl_get_intensity(struct backlight_device *bd) return intensity - HW_LEVEL_MIN; } -static const struct backlight_ops progearbl_ops = { +static struct backlight_ops progearbl_ops = { .get_brightness = progearbl_get_intensity, .update_status = progearbl_set_intensity, }; diff --git a/trunk/drivers/video/backlight/pwm_bl.c b/trunk/drivers/video/backlight/pwm_bl.c index 9d2ec2a1cce8..887166267443 100644 --- a/trunk/drivers/video/backlight/pwm_bl.c +++ b/trunk/drivers/video/backlight/pwm_bl.c @@ -22,10 +22,8 @@ struct pwm_bl_data { struct pwm_device *pwm; - struct device *dev; unsigned int period; - int (*notify)(struct device *, - int brightness); + int (*notify)(int brightness); }; static int pwm_backlight_update_status(struct backlight_device *bl) @@ -41,7 +39,7 @@ static int pwm_backlight_update_status(struct backlight_device *bl) brightness = 0; if (pb->notify) - brightness = pb->notify(pb->dev, brightness); + brightness = pb->notify(brightness); if (brightness == 0) { pwm_config(pb->pwm, 0, pb->period); @@ -58,7 +56,7 @@ static int pwm_backlight_get_brightness(struct backlight_device *bl) return bl->props.brightness; } -static const struct backlight_ops pwm_backlight_ops = { +static struct backlight_ops pwm_backlight_ops = { .update_status = pwm_backlight_update_status, .get_brightness = pwm_backlight_get_brightness, }; @@ -90,7 +88,6 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->period = data->pwm_period_ns; pb->notify = data->notify; - pb->dev = &pdev->dev; pb->pwm = pwm_request(data->pwm_id, "backlight"); if (IS_ERR(pb->pwm)) { @@ -149,7 +146,7 @@ static int pwm_backlight_suspend(struct platform_device *pdev, struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); if (pb->notify) - pb->notify(pb->dev, 0); + pb->notify(0); pwm_config(pb->pwm, 0, pb->period); pwm_disable(pb->pwm); return 0; diff --git a/trunk/drivers/video/backlight/tosa_bl.c b/trunk/drivers/video/backlight/tosa_bl.c index e14ce4d469f5..43edbada12d1 100644 --- a/trunk/drivers/video/backlight/tosa_bl.c +++ b/trunk/drivers/video/backlight/tosa_bl.c @@ -72,7 +72,7 @@ static int tosa_bl_get_brightness(struct backlight_device *dev) return props->brightness; } -static const struct backlight_ops bl_ops = { +static struct backlight_ops bl_ops = { .get_brightness = tosa_bl_get_brightness, .update_status = tosa_bl_update_status, }; diff --git a/trunk/drivers/video/backlight/wm831x_bl.c b/trunk/drivers/video/backlight/wm831x_bl.c index e32add37a203..467bdb7efb23 100644 --- a/trunk/drivers/video/backlight/wm831x_bl.c +++ b/trunk/drivers/video/backlight/wm831x_bl.c @@ -112,7 +112,7 @@ static int wm831x_backlight_get_brightness(struct backlight_device *bl) return data->current_brightness; } -static const struct backlight_ops wm831x_backlight_ops = { +static struct backlight_ops wm831x_backlight_ops = { .options = BL_CORE_SUSPENDRESUME, .update_status = wm831x_backlight_update_status, .get_brightness = wm831x_backlight_get_brightness, diff --git a/trunk/drivers/video/via/viafbdev.c b/trunk/drivers/video/via/viafbdev.c index d8df17a7d5fc..10d8c4b4baeb 100644 --- a/trunk/drivers/video/via/viafbdev.c +++ b/trunk/drivers/video/via/viafbdev.c @@ -680,7 +680,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) if (!viafb_gamma_table) return -ENOMEM; if (copy_from_user(viafb_gamma_table, argp, - 256 * sizeof(u32))) { + sizeof(viafb_gamma_table))) { kfree(viafb_gamma_table); return -EFAULT; } @@ -694,7 +694,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) return -ENOMEM; viafb_get_gamma_table(viafb_gamma_table); if (copy_to_user(argp, viafb_gamma_table, - 256 * sizeof(u32))) { + sizeof(viafb_gamma_table))) { kfree(viafb_gamma_table); return -EFAULT; } diff --git a/trunk/fs/Kconfig b/trunk/fs/Kconfig index 64d44efad7a5..f8fccaaad628 100644 --- a/trunk/fs/Kconfig +++ b/trunk/fs/Kconfig @@ -6,6 +6,10 @@ menu "File systems" if BLOCK +config FS_JOURNAL_INFO + bool + default n + source "fs/ext2/Kconfig" source "fs/ext3/Kconfig" source "fs/ext4/Kconfig" diff --git a/trunk/fs/anon_inodes.c b/trunk/fs/anon_inodes.c index 2c994591f4d7..94f5110c4655 100644 --- a/trunk/fs/anon_inodes.c +++ b/trunk/fs/anon_inodes.c @@ -35,13 +35,14 @@ static int anon_inodefs_get_sb(struct file_system_type *fs_type, int flags, mnt); } -/* - * anon_inodefs_dname() is called from d_path(). - */ -static char *anon_inodefs_dname(struct dentry *dentry, char *buffer, int buflen) +static int anon_inodefs_delete_dentry(struct dentry *dentry) { - return dynamic_dname(dentry, buffer, buflen, "anon_inode:%s", - dentry->d_name.name); + /* + * We faked vfs to believe the dentry was hashed when we created it. + * Now we restore the flag so that dput() will work correctly. + */ + dentry->d_flags |= DCACHE_UNHASHED; + return 1; } static struct file_system_type anon_inode_fs_type = { @@ -50,7 +51,7 @@ static struct file_system_type anon_inode_fs_type = { .kill_sb = kill_anon_super, }; static const struct dentry_operations anon_inodefs_dentry_operations = { - .d_dname = anon_inodefs_dname, + .d_delete = anon_inodefs_delete_dentry, }; /* @@ -118,6 +119,8 @@ struct file *anon_inode_getfile(const char *name, atomic_inc(&anon_inode_inode->i_count); path.dentry->d_op = &anon_inodefs_dentry_operations; + /* Do not publish this dentry inside the global dentry hash table */ + path.dentry->d_flags &= ~DCACHE_UNHASHED; d_instantiate(path.dentry, anon_inode_inode); error = -ENFILE; diff --git a/trunk/fs/binfmt_aout.c b/trunk/fs/binfmt_aout.c index 346b69405363..b639dcf7c778 100644 --- a/trunk/fs/binfmt_aout.c +++ b/trunk/fs/binfmt_aout.c @@ -32,7 +32,7 @@ static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); static int load_aout_library(struct file*); -static int aout_core_dump(struct coredump_params *cprm); +static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); static struct linux_binfmt aout_format = { .module = THIS_MODULE, @@ -89,9 +89,8 @@ if (file->f_op->llseek) { \ * dumping of the process results in another error.. */ -static int aout_core_dump(struct coredump_params *cprm) +static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) { - struct file *file = cprm->file; mm_segment_t fs; int has_dumped = 0; unsigned long dump_start, dump_size; @@ -109,16 +108,16 @@ static int aout_core_dump(struct coredump_params *cprm) current->flags |= PF_DUMPCORE; strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); dump.u_ar0 = offsetof(struct user, regs); - dump.signal = cprm->signr; - aout_dump_thread(cprm->regs, &dump); + dump.signal = signr; + aout_dump_thread(regs, &dump); /* If the size of the dump file exceeds the rlimit, then see what would happen if we wrote the stack, but not the data area. */ - if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > cprm->limit) + if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit) dump.u_dsize = 0; /* Make sure we have enough room to write the stack and data areas. */ - if ((dump.u_ssize + 1) * PAGE_SIZE > cprm->limit) + if ((dump.u_ssize + 1) * PAGE_SIZE > limit) dump.u_ssize = 0; /* make sure we actually have a data and stack area to dump */ diff --git a/trunk/fs/binfmt_elf.c b/trunk/fs/binfmt_elf.c index edd90c49003c..97b6e9efeb7f 100644 --- a/trunk/fs/binfmt_elf.c +++ b/trunk/fs/binfmt_elf.c @@ -45,7 +45,7 @@ static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *, * don't even try. */ #ifdef CONFIG_ELF_CORE -static int elf_core_dump(struct coredump_params *cprm); +static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); #else #define elf_core_dump NULL #endif @@ -1272,9 +1272,8 @@ static int writenote(struct memelfnote *men, struct file *file, } #undef DUMP_WRITE -#define DUMP_WRITE(addr, nr) \ - if ((size += (nr)) > cprm->limit || \ - !dump_write(cprm->file, (addr), (nr))) \ +#define DUMP_WRITE(addr, nr) \ + if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ goto end_coredump; static void fill_elf_header(struct elfhdr *elf, int segs, @@ -1902,7 +1901,7 @@ static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma, * and then they are actually written out. If we run out of core limit * we just truncate. */ -static int elf_core_dump(struct coredump_params *cprm) +static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) { int has_dumped = 0; mm_segment_t fs; @@ -1948,7 +1947,7 @@ static int elf_core_dump(struct coredump_params *cprm) * notes. This also sets up the file header. */ if (!fill_note_info(elf, segs + 1, /* including notes section */ - &info, cprm->signr, cprm->regs)) + &info, signr, regs)) goto cleanup; has_dumped = 1; @@ -2010,14 +2009,14 @@ static int elf_core_dump(struct coredump_params *cprm) #endif /* write out the notes section */ - if (!write_note_info(&info, cprm->file, &foffset)) + if (!write_note_info(&info, file, &foffset)) goto end_coredump; - if (elf_coredump_extra_notes_write(cprm->file, &foffset)) + if (elf_coredump_extra_notes_write(file, &foffset)) goto end_coredump; /* Align to page */ - if (!dump_seek(cprm->file, dataoff - foffset)) + if (!dump_seek(file, dataoff - foffset)) goto end_coredump; for (vma = first_vma(current, gate_vma); vma != NULL; @@ -2034,13 +2033,12 @@ static int elf_core_dump(struct coredump_params *cprm) page = get_dump_page(addr); if (page) { void *kaddr = kmap(page); - stop = ((size += PAGE_SIZE) > cprm->limit) || - !dump_write(cprm->file, kaddr, - PAGE_SIZE); + stop = ((size += PAGE_SIZE) > limit) || + !dump_write(file, kaddr, PAGE_SIZE); kunmap(page); page_cache_release(page); } else - stop = !dump_seek(cprm->file, PAGE_SIZE); + stop = !dump_seek(file, PAGE_SIZE); if (stop) goto end_coredump; } diff --git a/trunk/fs/binfmt_elf_fdpic.c b/trunk/fs/binfmt_elf_fdpic.c index c25256a5c5b0..7b055385db8e 100644 --- a/trunk/fs/binfmt_elf_fdpic.c +++ b/trunk/fs/binfmt_elf_fdpic.c @@ -76,7 +76,7 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *, struct file *, struct mm_struct *); #ifdef CONFIG_ELF_CORE -static int elf_fdpic_core_dump(struct coredump_params *cprm); +static int elf_fdpic_core_dump(long, struct pt_regs *, struct file *, unsigned long limit); #endif static struct linux_binfmt elf_fdpic_format = { @@ -1326,9 +1326,8 @@ static int writenote(struct memelfnote *men, struct file *file) #undef DUMP_WRITE #undef DUMP_SEEK -#define DUMP_WRITE(addr, nr) \ - if ((size += (nr)) > cprm->limit || \ - !dump_write(cprm->file, (addr), (nr))) \ +#define DUMP_WRITE(addr, nr) \ + if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ goto end_coredump; static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs) @@ -1583,7 +1582,8 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size, * and then they are actually written out. If we run out of core limit * we just truncate. */ -static int elf_fdpic_core_dump(struct coredump_params *cprm) +static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, + struct file *file, unsigned long limit) { #define NUM_NOTES 6 int has_dumped = 0; @@ -1642,7 +1642,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) goto cleanup; #endif - if (cprm->signr) { + if (signr) { struct core_thread *ct; struct elf_thread_status *tmp; @@ -1661,14 +1661,14 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) int sz; tmp = list_entry(t, struct elf_thread_status, list); - sz = elf_dump_thread_status(cprm->signr, tmp); + sz = elf_dump_thread_status(signr, tmp); thread_status_size += sz; } } /* now collect the dump for the current */ - fill_prstatus(prstatus, current, cprm->signr); - elf_core_copy_regs(&prstatus->pr_reg, cprm->regs); + fill_prstatus(prstatus, current, signr); + elf_core_copy_regs(&prstatus->pr_reg, regs); segs = current->mm->map_count; #ifdef ELF_CORE_EXTRA_PHDRS @@ -1703,7 +1703,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) /* Try to dump the FPU. */ if ((prstatus->pr_fpvalid = - elf_core_copy_task_fpregs(current, cprm->regs, fpu))) + elf_core_copy_task_fpregs(current, regs, fpu))) fill_note(notes + numnote++, "CORE", NT_PRFPREG, sizeof(*fpu), fpu); #ifdef ELF_CORE_COPY_XFPREGS @@ -1774,7 +1774,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) /* write out the notes section */ for (i = 0; i < numnote; i++) - if (!writenote(notes + i, cprm->file)) + if (!writenote(notes + i, file)) goto end_coredump; /* write out the thread status notes section */ @@ -1783,15 +1783,14 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) list_entry(t, struct elf_thread_status, list); for (i = 0; i < tmp->num_notes; i++) - if (!writenote(&tmp->notes[i], cprm->file)) + if (!writenote(&tmp->notes[i], file)) goto end_coredump; } - if (!dump_seek(cprm->file, dataoff)) + if (!dump_seek(file, dataoff)) goto end_coredump; - if (elf_fdpic_dump_segments(cprm->file, &size, &cprm->limit, - mm_flags) < 0) + if (elf_fdpic_dump_segments(file, &size, &limit, mm_flags) < 0) goto end_coredump; #ifdef ELF_CORE_WRITE_EXTRA_DATA diff --git a/trunk/fs/binfmt_flat.c b/trunk/fs/binfmt_flat.c index d4a00ea1054c..a2796651e756 100644 --- a/trunk/fs/binfmt_flat.c +++ b/trunk/fs/binfmt_flat.c @@ -87,7 +87,7 @@ static int load_flat_shared_library(int id, struct lib_info *p); #endif static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs); -static int flat_core_dump(struct coredump_params *cprm); +static int flat_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); static struct linux_binfmt flat_format = { .module = THIS_MODULE, @@ -102,10 +102,10 @@ static struct linux_binfmt flat_format = { * Currently only a stub-function. */ -static int flat_core_dump(struct coredump_params *cprm) +static int flat_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) { printk("Process %s:%d received signr %d and should have core dumped\n", - current->comm, current->pid, (int) cprm->signr); + current->comm, current->pid, (int) signr); return(1); } diff --git a/trunk/fs/binfmt_som.c b/trunk/fs/binfmt_som.c index 2a9b5330cc5e..eff74b9c9e77 100644 --- a/trunk/fs/binfmt_som.c +++ b/trunk/fs/binfmt_som.c @@ -43,7 +43,7 @@ static int load_som_library(struct file *); * don't even try. */ #if 0 -static int som_core_dump(struct coredump_params *cprm); +static int som_core_dump(long signr, struct pt_regs *regs, unsigned long limit); #else #define som_core_dump NULL #endif diff --git a/trunk/fs/btrfs/Kconfig b/trunk/fs/btrfs/Kconfig index 7bb3c020e570..402afe0a0bfb 100644 --- a/trunk/fs/btrfs/Kconfig +++ b/trunk/fs/btrfs/Kconfig @@ -4,6 +4,7 @@ config BTRFS_FS select LIBCRC32C select ZLIB_INFLATE select ZLIB_DEFLATE + select FS_JOURNAL_INFO help Btrfs is a new filesystem with extents, writable snapshotting, support for multiple devices and many more features. diff --git a/trunk/fs/btrfs/acl.c b/trunk/fs/btrfs/acl.c index 2e9e69987a82..52cbe47022bf 100644 --- a/trunk/fs/btrfs/acl.c +++ b/trunk/fs/btrfs/acl.c @@ -94,8 +94,7 @@ static int btrfs_xattr_acl_get(struct dentry *dentry, const char *name, /* * Needs to be called with fs_mutex held */ -static int btrfs_set_acl(struct btrfs_trans_handle *trans, - struct inode *inode, struct posix_acl *acl, int type) +static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) { int ret, size = 0; const char *name; @@ -141,7 +140,8 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans, goto out; } - ret = __btrfs_setxattr(trans, inode, name, value, size, 0); + ret = __btrfs_setxattr(inode, name, value, size, 0); + out: kfree(value); @@ -154,7 +154,7 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans, static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) { - int ret; + int ret = 0; struct posix_acl *acl = NULL; if (value) { @@ -167,7 +167,7 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, } } - ret = btrfs_set_acl(NULL, dentry->d_inode, acl, type); + ret = btrfs_set_acl(dentry->d_inode, acl, type); posix_acl_release(acl); @@ -196,8 +196,7 @@ int btrfs_check_acl(struct inode *inode, int mask) * stuff has been fixed to work with that. If the locking stuff changes, we * need to re-evaluate the acl locking stuff. */ -int btrfs_init_acl(struct btrfs_trans_handle *trans, - struct inode *inode, struct inode *dir) +int btrfs_init_acl(struct inode *inode, struct inode *dir) { struct posix_acl *acl = NULL; int ret = 0; @@ -222,8 +221,7 @@ int btrfs_init_acl(struct btrfs_trans_handle *trans, mode_t mode; if (S_ISDIR(inode->i_mode)) { - ret = btrfs_set_acl(trans, inode, acl, - ACL_TYPE_DEFAULT); + ret = btrfs_set_acl(inode, acl, ACL_TYPE_DEFAULT); if (ret) goto failed; } @@ -238,7 +236,7 @@ int btrfs_init_acl(struct btrfs_trans_handle *trans, inode->i_mode = mode; if (ret > 0) { /* we need an acl */ - ret = btrfs_set_acl(trans, inode, clone, + ret = btrfs_set_acl(inode, clone, ACL_TYPE_ACCESS); } } @@ -271,7 +269,7 @@ int btrfs_acl_chmod(struct inode *inode) ret = posix_acl_chmod_masq(clone, inode->i_mode); if (!ret) - ret = btrfs_set_acl(NULL, inode, clone, ACL_TYPE_ACCESS); + ret = btrfs_set_acl(inode, clone, ACL_TYPE_ACCESS); posix_acl_release(clone); @@ -299,8 +297,7 @@ int btrfs_acl_chmod(struct inode *inode) return 0; } -int btrfs_init_acl(struct btrfs_trans_handle *trans, - struct inode *inode, struct inode *dir) +int btrfs_init_acl(struct inode *inode, struct inode *dir) { return 0; } diff --git a/trunk/fs/btrfs/btrfs_inode.h b/trunk/fs/btrfs/btrfs_inode.h index 3f1f50d9d916..f6783a42f010 100644 --- a/trunk/fs/btrfs/btrfs_inode.h +++ b/trunk/fs/btrfs/btrfs_inode.h @@ -44,6 +44,9 @@ struct btrfs_inode { */ struct extent_io_tree io_failure_tree; + /* held while inesrting or deleting extents from files */ + struct mutex extent_mutex; + /* held while logging the inode in tree-log.c */ struct mutex log_mutex; @@ -163,7 +166,7 @@ static inline struct btrfs_inode *BTRFS_I(struct inode *inode) static inline void btrfs_i_size_write(struct inode *inode, u64 size) { - i_size_write(inode, size); + inode->i_size = size; BTRFS_I(inode)->disk_i_size = size; } diff --git a/trunk/fs/btrfs/ctree.c b/trunk/fs/btrfs/ctree.c index c4bc570a396e..ec96f3a6d536 100644 --- a/trunk/fs/btrfs/ctree.c +++ b/trunk/fs/btrfs/ctree.c @@ -37,11 +37,6 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct extent_buffer *src_buf); static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int level, int slot); -static int setup_items_for_insert(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_key *cpu_key, u32 *data_size, - u32 total_data, u32 total_size, int nr); - struct btrfs_path *btrfs_alloc_path(void) { @@ -456,8 +451,9 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, extent_buffer_get(cow); spin_unlock(&root->node_lock); - btrfs_free_tree_block(trans, root, buf->start, buf->len, - parent_start, root->root_key.objectid, level); + btrfs_free_extent(trans, root, buf->start, buf->len, + parent_start, root->root_key.objectid, + level, 0); free_extent_buffer(buf); add_root_to_dirty_list(root); } else { @@ -472,8 +468,9 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, btrfs_set_node_ptr_generation(parent, parent_slot, trans->transid); btrfs_mark_buffer_dirty(parent); - btrfs_free_tree_block(trans, root, buf->start, buf->len, - parent_start, root->root_key.objectid, level); + btrfs_free_extent(trans, root, buf->start, buf->len, + parent_start, root->root_key.objectid, + level, 0); } if (unlock_orig) btrfs_tree_unlock(buf); @@ -1033,8 +1030,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, btrfs_tree_unlock(mid); /* once for the path */ free_extent_buffer(mid); - ret = btrfs_free_tree_block(trans, root, mid->start, mid->len, - 0, root->root_key.objectid, level); + ret = btrfs_free_extent(trans, root, mid->start, mid->len, + 0, root->root_key.objectid, level, 1); /* once for the root ptr */ free_extent_buffer(mid); return ret; @@ -1098,10 +1095,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, 1); if (wret) ret = wret; - wret = btrfs_free_tree_block(trans, root, - bytenr, blocksize, 0, - root->root_key.objectid, - level); + wret = btrfs_free_extent(trans, root, bytenr, + blocksize, 0, + root->root_key.objectid, + level, 0); if (wret) ret = wret; } else { @@ -1146,8 +1143,9 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, wret = del_ptr(trans, root, path, level + 1, pslot); if (wret) ret = wret; - wret = btrfs_free_tree_block(trans, root, bytenr, blocksize, - 0, root->root_key.objectid, level); + wret = btrfs_free_extent(trans, root, bytenr, blocksize, + 0, root->root_key.objectid, + level, 0); if (wret) ret = wret; } else { @@ -2999,85 +2997,75 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, return ret; } -static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, int ins_len) +/* + * This function splits a single item into two items, + * giving 'new_key' to the new item and splitting the + * old one at split_offset (from the start of the item). + * + * The path may be released by this operation. After + * the split, the path is pointing to the old item. The + * new item is going to be in the same node as the old one. + * + * Note, the item being split must be smaller enough to live alone on + * a tree block with room for one extra struct btrfs_item + * + * This allows us to split the item in place, keeping a lock on the + * leaf the entire time. + */ +int btrfs_split_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + struct btrfs_key *new_key, + unsigned long split_offset) { - struct btrfs_key key; - struct extent_buffer *leaf; - struct btrfs_file_extent_item *fi; - u64 extent_len = 0; u32 item_size; - int ret; + struct extent_buffer *leaf; + struct btrfs_key orig_key; + struct btrfs_item *item; + struct btrfs_item *new_item; + int ret = 0; + int slot; + u32 nritems; + u32 orig_offset; + struct btrfs_disk_key disk_key; + char *buf; leaf = path->nodes[0]; - btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); - - BUG_ON(key.type != BTRFS_EXTENT_DATA_KEY && - key.type != BTRFS_EXTENT_CSUM_KEY); - - if (btrfs_leaf_free_space(root, leaf) >= ins_len) - return 0; + btrfs_item_key_to_cpu(leaf, &orig_key, path->slots[0]); + if (btrfs_leaf_free_space(root, leaf) >= sizeof(struct btrfs_item)) + goto split; item_size = btrfs_item_size_nr(leaf, path->slots[0]); - if (key.type == BTRFS_EXTENT_DATA_KEY) { - fi = btrfs_item_ptr(leaf, path->slots[0], - struct btrfs_file_extent_item); - extent_len = btrfs_file_extent_num_bytes(leaf, fi); - } btrfs_release_path(root, path); - path->keep_locks = 1; path->search_for_split = 1; - ret = btrfs_search_slot(trans, root, &key, path, 0, 1); + path->keep_locks = 1; + + ret = btrfs_search_slot(trans, root, &orig_key, path, 0, 1); path->search_for_split = 0; - if (ret < 0) - goto err; - ret = -EAGAIN; - leaf = path->nodes[0]; /* if our item isn't there or got smaller, return now */ - if (ret > 0 || item_size != btrfs_item_size_nr(leaf, path->slots[0])) - goto err; - - if (key.type == BTRFS_EXTENT_DATA_KEY) { - fi = btrfs_item_ptr(leaf, path->slots[0], - struct btrfs_file_extent_item); - if (extent_len != btrfs_file_extent_num_bytes(leaf, fi)) - goto err; + if (ret != 0 || item_size != btrfs_item_size_nr(path->nodes[0], + path->slots[0])) { + path->keep_locks = 0; + return -EAGAIN; } btrfs_set_path_blocking(path); - ret = split_leaf(trans, root, &key, path, ins_len, 1); + ret = split_leaf(trans, root, &orig_key, path, + sizeof(struct btrfs_item), 1); + path->keep_locks = 0; BUG_ON(ret); - path->keep_locks = 0; btrfs_unlock_up_safe(path, 1); - return 0; -err: - path->keep_locks = 0; - return ret; -} - -static noinline int split_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - struct btrfs_key *new_key, - unsigned long split_offset) -{ - struct extent_buffer *leaf; - struct btrfs_item *item; - struct btrfs_item *new_item; - int slot; - char *buf; - u32 nritems; - u32 item_size; - u32 orig_offset; - struct btrfs_disk_key disk_key; - leaf = path->nodes[0]; BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); +split: + /* + * make sure any changes to the path from split_leaf leave it + * in a blocking state + */ btrfs_set_path_blocking(path); item = btrfs_item_nr(leaf, path->slots[0]); @@ -3085,19 +3073,19 @@ static noinline int split_item(struct btrfs_trans_handle *trans, item_size = btrfs_item_size(leaf, item); buf = kmalloc(item_size, GFP_NOFS); - if (!buf) - return -ENOMEM; - read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf, path->slots[0]), item_size); - slot = path->slots[0] + 1; + leaf = path->nodes[0]; + nritems = btrfs_header_nritems(leaf); + if (slot != nritems) { /* shift the items */ memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1), - btrfs_item_nr_offset(slot), - (nritems - slot) * sizeof(struct btrfs_item)); + btrfs_item_nr_offset(slot), + (nritems - slot) * sizeof(struct btrfs_item)); + } btrfs_cpu_key_to_disk(&disk_key, new_key); @@ -3125,80 +3113,15 @@ static noinline int split_item(struct btrfs_trans_handle *trans, item_size - split_offset); btrfs_mark_buffer_dirty(leaf); - BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); + ret = 0; + if (btrfs_leaf_free_space(root, leaf) < 0) { + btrfs_print_leaf(root, leaf); + BUG(); + } kfree(buf); - return 0; -} - -/* - * This function splits a single item into two items, - * giving 'new_key' to the new item and splitting the - * old one at split_offset (from the start of the item). - * - * The path may be released by this operation. After - * the split, the path is pointing to the old item. The - * new item is going to be in the same node as the old one. - * - * Note, the item being split must be smaller enough to live alone on - * a tree block with room for one extra struct btrfs_item - * - * This allows us to split the item in place, keeping a lock on the - * leaf the entire time. - */ -int btrfs_split_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - struct btrfs_key *new_key, - unsigned long split_offset) -{ - int ret; - ret = setup_leaf_for_split(trans, root, path, - sizeof(struct btrfs_item)); - if (ret) - return ret; - - ret = split_item(trans, root, path, new_key, split_offset); return ret; } -/* - * This function duplicate a item, giving 'new_key' to the new item. - * It guarantees both items live in the same tree leaf and the new item - * is contiguous with the original item. - * - * This allows us to split file extent in place, keeping a lock on the - * leaf the entire time. - */ -int btrfs_duplicate_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - struct btrfs_key *new_key) -{ - struct extent_buffer *leaf; - int ret; - u32 item_size; - - leaf = path->nodes[0]; - item_size = btrfs_item_size_nr(leaf, path->slots[0]); - ret = setup_leaf_for_split(trans, root, path, - item_size + sizeof(struct btrfs_item)); - if (ret) - return ret; - - path->slots[0]++; - ret = setup_items_for_insert(trans, root, path, new_key, &item_size, - item_size, item_size + - sizeof(struct btrfs_item), 1); - BUG_ON(ret); - - leaf = path->nodes[0]; - memcpy_extent_buffer(leaf, - btrfs_item_ptr_offset(leaf, path->slots[0]), - btrfs_item_ptr_offset(leaf, path->slots[0] - 1), - item_size); - return 0; -} - /* * make the item pointed to by the path smaller. new_size indicates * how small to make it, and from_end tells us if we just chop bytes @@ -3791,8 +3714,8 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, */ btrfs_unlock_up_safe(path, 0); - ret = btrfs_free_tree_block(trans, root, leaf->start, leaf->len, - 0, root->root_key.objectid, 0); + ret = btrfs_free_extent(trans, root, leaf->start, leaf->len, + 0, root->root_key.objectid, 0, 0); return ret; } /* diff --git a/trunk/fs/btrfs/ctree.h b/trunk/fs/btrfs/ctree.h index 9f806dd04c27..444b3e9b92a4 100644 --- a/trunk/fs/btrfs/ctree.h +++ b/trunk/fs/btrfs/ctree.h @@ -310,9 +310,6 @@ struct btrfs_header { #define BTRFS_MAX_INLINE_DATA_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ sizeof(struct btrfs_item) - \ sizeof(struct btrfs_file_extent_item)) -#define BTRFS_MAX_XATTR_SIZE(r) (BTRFS_LEAF_DATA_SIZE(r) - \ - sizeof(struct btrfs_item) -\ - sizeof(struct btrfs_dir_item)) /* @@ -862,9 +859,8 @@ struct btrfs_fs_info { struct mutex ordered_operations_mutex; struct rw_semaphore extent_commit_sem; - struct rw_semaphore cleanup_work_sem; - struct rw_semaphore subvol_sem; + struct srcu_struct subvol_srcu; struct list_head trans_list; @@ -872,9 +868,6 @@ struct btrfs_fs_info { struct list_head dead_roots; struct list_head caching_block_groups; - spinlock_t delayed_iput_lock; - struct list_head delayed_iputs; - atomic_t nr_async_submits; atomic_t async_submit_draining; atomic_t nr_async_bios; @@ -1041,12 +1034,12 @@ struct btrfs_root { int ref_cows; int track_dirty; int in_radix; - int clean_orphans; u64 defrag_trans_start; struct btrfs_key defrag_progress; struct btrfs_key defrag_max; int defrag_running; + int defrag_level; char *name; int in_sysfs; @@ -1982,10 +1975,6 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, u64 parent, u64 root_objectid, struct btrfs_disk_key *key, int level, u64 hint, u64 empty_size); -int btrfs_free_tree_block(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - u64 bytenr, u32 blocksize, - u64 parent, u64 root_objectid, int level); struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u32 blocksize, @@ -2100,10 +2089,6 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, struct btrfs_path *path, struct btrfs_key *new_key, unsigned long split_offset); -int btrfs_duplicate_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - struct btrfs_key *new_key); int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *key, struct btrfs_path *p, int ins_len, int cow); @@ -2211,10 +2196,9 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, struct btrfs_path *path, struct btrfs_dir_item *di); int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, u64 objectid, - const char *name, u16 name_len, - const void *data, u16 data_len); + struct btrfs_root *root, const char *name, + u16 name_len, const void *data, u16 data_len, + u64 dir); struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, u64 dir, @@ -2308,7 +2292,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, struct inode *inode, u64 new_size, u32 min_type); -int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput); +int btrfs_start_delalloc_inodes(struct btrfs_root *root); int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); int btrfs_writepages(struct address_space *mapping, struct writeback_control *wbc); @@ -2348,8 +2332,6 @@ int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode); void btrfs_orphan_cleanup(struct btrfs_root *root); int btrfs_cont_expand(struct inode *inode, loff_t size); int btrfs_invalidate_inodes(struct btrfs_root *root); -void btrfs_add_delayed_iput(struct inode *inode); -void btrfs_run_delayed_iputs(struct btrfs_root *root); extern const struct dentry_operations btrfs_dentry_operations; /* ioctl.c */ @@ -2363,9 +2345,12 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, int skip_pinned); int btrfs_check_file(struct btrfs_root *root, struct inode *inode); extern const struct file_operations btrfs_file_operations; -int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, - u64 start, u64 end, u64 *hint_byte, int drop_cache); +int btrfs_drop_extents(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct inode *inode, + u64 start, u64 end, u64 locked_end, + u64 inline_limit, u64 *hint_block, int drop_cache); int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct inode *inode, u64 start, u64 end); int btrfs_release_file(struct inode *inode, struct file *file); @@ -2395,8 +2380,7 @@ int btrfs_check_acl(struct inode *inode, int mask); #else #define btrfs_check_acl NULL #endif -int btrfs_init_acl(struct btrfs_trans_handle *trans, - struct inode *inode, struct inode *dir); +int btrfs_init_acl(struct inode *inode, struct inode *dir); int btrfs_acl_chmod(struct inode *inode); /* relocation.c */ diff --git a/trunk/fs/btrfs/dir-item.c b/trunk/fs/btrfs/dir-item.c index e9103b3baa49..f3a6075519cc 100644 --- a/trunk/fs/btrfs/dir-item.c +++ b/trunk/fs/btrfs/dir-item.c @@ -68,12 +68,12 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle * into the tree */ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, u64 objectid, - const char *name, u16 name_len, - const void *data, u16 data_len) + struct btrfs_root *root, const char *name, + u16 name_len, const void *data, u16 data_len, + u64 dir) { int ret = 0; + struct btrfs_path *path; struct btrfs_dir_item *dir_item; unsigned long name_ptr, data_ptr; struct btrfs_key key, location; @@ -81,11 +81,15 @@ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, struct extent_buffer *leaf; u32 data_size; - BUG_ON(name_len + data_len > BTRFS_MAX_XATTR_SIZE(root)); - - key.objectid = objectid; + key.objectid = dir; btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY); key.offset = btrfs_name_hash(name, name_len); + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + if (name_len + data_len + sizeof(struct btrfs_dir_item) > + BTRFS_LEAF_DATA_SIZE(root) - sizeof(struct btrfs_item)) + return -ENOSPC; data_size = sizeof(*dir_item) + name_len + data_len; dir_item = insert_with_overflow(trans, root, path, &key, data_size, @@ -113,6 +117,7 @@ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, write_extent_buffer(leaf, data, data_ptr, data_len); btrfs_mark_buffer_dirty(path->nodes[0]); + btrfs_free_path(path); return ret; } diff --git a/trunk/fs/btrfs/disk-io.c b/trunk/fs/btrfs/disk-io.c index 009e3bd18f23..02b6afbd7450 100644 --- a/trunk/fs/btrfs/disk-io.c +++ b/trunk/fs/btrfs/disk-io.c @@ -892,8 +892,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, root->stripesize = stripesize; root->ref_cows = 0; root->track_dirty = 0; - root->in_radix = 0; - root->clean_orphans = 0; root->fs_info = fs_info; root->objectid = objectid; @@ -930,6 +928,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, root->defrag_trans_start = fs_info->generation; init_completion(&root->kobj_unregister); root->defrag_running = 0; + root->defrag_level = 0; root->root_key.objectid = objectid; root->anon_super.s_root = NULL; root->anon_super.s_dev = 0; @@ -981,12 +980,12 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans, while (1) { ret = find_first_extent_bit(&log_root_tree->dirty_log_pages, - 0, &start, &end, EXTENT_DIRTY | EXTENT_NEW); + 0, &start, &end, EXTENT_DIRTY); if (ret) break; - clear_extent_bits(&log_root_tree->dirty_log_pages, start, end, - EXTENT_DIRTY | EXTENT_NEW, GFP_NOFS); + clear_extent_dirty(&log_root_tree->dirty_log_pages, + start, end, GFP_NOFS); } eb = fs_info->log_root_tree->node; @@ -1211,10 +1210,8 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, ret = radix_tree_insert(&fs_info->fs_roots_radix, (unsigned long)root->root_key.objectid, root); - if (ret == 0) { + if (ret == 0) root->in_radix = 1; - root->clean_orphans = 1; - } spin_unlock(&fs_info->fs_roots_radix_lock); radix_tree_preload_end(); if (ret) { @@ -1228,6 +1225,10 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, ret = btrfs_find_dead_roots(fs_info->tree_root, root->root_key.objectid); WARN_ON(ret); + + if (!(fs_info->sb->s_flags & MS_RDONLY)) + btrfs_orphan_cleanup(root); + return root; fail: free_fs_root(root); @@ -1476,7 +1477,6 @@ static int cleaner_kthread(void *arg) if (!(root->fs_info->sb->s_flags & MS_RDONLY) && mutex_trylock(&root->fs_info->cleaner_mutex)) { - btrfs_run_delayed_iputs(root); btrfs_clean_old_snapshots(root); mutex_unlock(&root->fs_info->cleaner_mutex); } @@ -1606,7 +1606,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC); INIT_LIST_HEAD(&fs_info->trans_list); INIT_LIST_HEAD(&fs_info->dead_roots); - INIT_LIST_HEAD(&fs_info->delayed_iputs); INIT_LIST_HEAD(&fs_info->hashers); INIT_LIST_HEAD(&fs_info->delalloc_inodes); INIT_LIST_HEAD(&fs_info->ordered_operations); @@ -1615,7 +1614,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, spin_lock_init(&fs_info->new_trans_lock); spin_lock_init(&fs_info->ref_cache_lock); spin_lock_init(&fs_info->fs_roots_radix_lock); - spin_lock_init(&fs_info->delayed_iput_lock); init_completion(&fs_info->kobj_unregister); fs_info->tree_root = tree_root; @@ -1691,7 +1689,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, mutex_init(&fs_info->cleaner_mutex); mutex_init(&fs_info->volume_mutex); init_rwsem(&fs_info->extent_commit_sem); - init_rwsem(&fs_info->cleanup_work_sem); init_rwsem(&fs_info->subvol_sem); btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); @@ -2389,14 +2386,8 @@ int btrfs_commit_super(struct btrfs_root *root) int ret; mutex_lock(&root->fs_info->cleaner_mutex); - btrfs_run_delayed_iputs(root); btrfs_clean_old_snapshots(root); mutex_unlock(&root->fs_info->cleaner_mutex); - - /* wait until ongoing cleanup work done */ - down_write(&root->fs_info->cleanup_work_sem); - up_write(&root->fs_info->cleanup_work_sem); - trans = btrfs_start_transaction(root, 1); ret = btrfs_commit_transaction(trans, root); BUG_ON(ret); diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index 56e50137d0e6..94627c4cc193 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -195,14 +195,6 @@ static int exclude_super_stripes(struct btrfs_root *root, int stripe_len; int i, nr, ret; - if (cache->key.objectid < BTRFS_SUPER_INFO_OFFSET) { - stripe_len = BTRFS_SUPER_INFO_OFFSET - cache->key.objectid; - cache->bytes_super += stripe_len; - ret = add_excluded_extent(root, cache->key.objectid, - stripe_len); - BUG_ON(ret); - } - for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { bytenr = btrfs_sb_offset(i); ret = btrfs_rmap_block(&root->fs_info->mapping_tree, @@ -263,7 +255,7 @@ static u64 add_new_free_space(struct btrfs_block_group_cache *block_group, if (ret) break; - if (extent_start <= start) { + if (extent_start == start) { start = extent_end + 1; } else if (extent_start > start && extent_start < end) { size = extent_start - start; @@ -2888,9 +2880,9 @@ static noinline void flush_delalloc_async(struct btrfs_work *work) root = async->root; info = async->info; - btrfs_start_delalloc_inodes(root, 0); + btrfs_start_delalloc_inodes(root); wake_up(&info->flush_wait); - btrfs_wait_ordered_extents(root, 0, 0); + btrfs_wait_ordered_extents(root, 0); spin_lock(&info->lock); info->flushing = 0; @@ -2964,8 +2956,8 @@ static void flush_delalloc(struct btrfs_root *root, return; flush: - btrfs_start_delalloc_inodes(root, 0); - btrfs_wait_ordered_extents(root, 0, 0); + btrfs_start_delalloc_inodes(root); + btrfs_wait_ordered_extents(root, 0); spin_lock(&info->lock); info->flushing = 0; @@ -3462,6 +3454,14 @@ static int update_block_group(struct btrfs_trans_handle *trans, else old_val -= num_bytes; btrfs_set_super_bytes_used(&info->super_copy, old_val); + + /* block accounting for root item */ + old_val = btrfs_root_used(&root->root_item); + if (alloc) + old_val += num_bytes; + else + old_val -= num_bytes; + btrfs_set_root_used(&root->root_item, old_val); spin_unlock(&info->delalloc_lock); while (total) { @@ -4049,21 +4049,6 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, return ret; } -int btrfs_free_tree_block(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - u64 bytenr, u32 blocksize, - u64 parent, u64 root_objectid, int level) -{ - u64 used; - spin_lock(&root->node_lock); - used = btrfs_root_used(&root->root_item) - blocksize; - btrfs_set_root_used(&root->root_item, used); - spin_unlock(&root->node_lock); - - return btrfs_free_extent(trans, root, bytenr, blocksize, - parent, root_objectid, level, 0); -} - static u64 stripe_align(struct btrfs_root *root, u64 val) { u64 mask = ((u64)root->stripesize - 1); @@ -4593,6 +4578,7 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, { int ret; u64 search_start = 0; + struct btrfs_fs_info *info = root->fs_info; data = btrfs_get_alloc_profile(root, data); again: @@ -4600,9 +4586,17 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, * the only place that sets empty_size is btrfs_realloc_node, which * is not called recursively on allocations */ - if (empty_size || root->ref_cows) + if (empty_size || root->ref_cows) { + if (!(data & BTRFS_BLOCK_GROUP_METADATA)) { + ret = do_chunk_alloc(trans, root->fs_info->extent_root, + 2 * 1024 * 1024, + BTRFS_BLOCK_GROUP_METADATA | + (info->metadata_alloc_profile & + info->avail_metadata_alloc_bits), 0); + } ret = do_chunk_alloc(trans, root->fs_info->extent_root, num_bytes + 2 * 1024 * 1024, data, 0); + } WARN_ON(num_bytes < root->sectorsize); ret = find_free_extent(trans, root, num_bytes, empty_size, @@ -4903,14 +4897,6 @@ static int alloc_tree_block(struct btrfs_trans_handle *trans, extent_op); BUG_ON(ret); } - - if (root_objectid == root->root_key.objectid) { - u64 used; - spin_lock(&root->node_lock); - used = btrfs_root_used(&root->root_item) + num_bytes; - btrfs_set_root_used(&root->root_item, used); - spin_unlock(&root->node_lock); - } return ret; } @@ -4933,16 +4919,8 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, btrfs_set_buffer_uptodate(buf); if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) { - /* - * we allow two log transactions at a time, use different - * EXENT bit to differentiate dirty pages. - */ - if (root->log_transid % 2 == 0) - set_extent_dirty(&root->dirty_log_pages, buf->start, - buf->start + buf->len - 1, GFP_NOFS); - else - set_extent_new(&root->dirty_log_pages, buf->start, - buf->start + buf->len - 1, GFP_NOFS); + set_extent_dirty(&root->dirty_log_pages, buf->start, + buf->start + buf->len - 1, GFP_NOFS); } else { set_extent_dirty(&trans->transaction->dirty_pages, buf->start, buf->start + buf->len - 1, GFP_NOFS); diff --git a/trunk/fs/btrfs/file.c b/trunk/fs/btrfs/file.c index feaa13b105d9..77f759302e12 100644 --- a/trunk/fs/btrfs/file.c +++ b/trunk/fs/btrfs/file.c @@ -179,14 +179,18 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, } flags = em->flags; if (skip_pinned && test_bit(EXTENT_FLAG_PINNED, &em->flags)) { - if (testend && em->start + em->len >= start + len) { + if (em->start <= start && + (!testend || em->start + em->len >= start + len)) { free_extent_map(em); write_unlock(&em_tree->lock); break; } - start = em->start + em->len; - if (testend) + if (start < em->start) { + len = em->start - start; + } else { len = start + len - (em->start + em->len); + start = em->start + em->len; + } free_extent_map(em); write_unlock(&em_tree->lock); continue; @@ -261,247 +265,319 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, * If an extent intersects the range but is not entirely inside the range * it is either truncated or split. Anything entirely inside the range * is deleted from the tree. + * + * inline_limit is used to tell this code which offsets in the file to keep + * if they contain inline extents. */ -int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, - u64 start, u64 end, u64 *hint_byte, int drop_cache) +noinline int btrfs_drop_extents(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct inode *inode, + u64 start, u64 end, u64 locked_end, + u64 inline_limit, u64 *hint_byte, int drop_cache) { - struct btrfs_root *root = BTRFS_I(inode)->root; + u64 extent_end = 0; + u64 search_start = start; + u64 ram_bytes = 0; + u64 disk_bytenr = 0; + u64 orig_locked_end = locked_end; + u8 compression; + u8 encryption; + u16 other_encoding = 0; struct extent_buffer *leaf; - struct btrfs_file_extent_item *fi; + struct btrfs_file_extent_item *extent; struct btrfs_path *path; struct btrfs_key key; - struct btrfs_key new_key; - u64 search_start = start; - u64 disk_bytenr = 0; - u64 num_bytes = 0; - u64 extent_offset = 0; - u64 extent_end = 0; - int del_nr = 0; - int del_slot = 0; - int extent_type; + struct btrfs_file_extent_item old; + int keep; + int slot; + int bookend; + int found_type = 0; + int found_extent; + int found_inline; int recow; int ret; + inline_limit = 0; if (drop_cache) btrfs_drop_extent_cache(inode, start, end - 1, 0); path = btrfs_alloc_path(); if (!path) return -ENOMEM; - while (1) { recow = 0; + btrfs_release_path(root, path); ret = btrfs_lookup_file_extent(trans, root, path, inode->i_ino, search_start, -1); if (ret < 0) - break; - if (ret > 0 && path->slots[0] > 0 && search_start == start) { - leaf = path->nodes[0]; - btrfs_item_key_to_cpu(leaf, &key, path->slots[0] - 1); - if (key.objectid == inode->i_ino && - key.type == BTRFS_EXTENT_DATA_KEY) - path->slots[0]--; - } - ret = 0; -next_slot: - leaf = path->nodes[0]; - if (path->slots[0] >= btrfs_header_nritems(leaf)) { - BUG_ON(del_nr > 0); - ret = btrfs_next_leaf(root, path); - if (ret < 0) - break; - if (ret > 0) { + goto out; + if (ret > 0) { + if (path->slots[0] == 0) { ret = 0; - break; + goto out; } - leaf = path->nodes[0]; - recow = 1; + path->slots[0]--; } - - btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); - if (key.objectid > inode->i_ino || - key.type > BTRFS_EXTENT_DATA_KEY || key.offset >= end) - break; - - fi = btrfs_item_ptr(leaf, path->slots[0], - struct btrfs_file_extent_item); - extent_type = btrfs_file_extent_type(leaf, fi); - - if (extent_type == BTRFS_FILE_EXTENT_REG || - extent_type == BTRFS_FILE_EXTENT_PREALLOC) { - disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); - num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi); - extent_offset = btrfs_file_extent_offset(leaf, fi); - extent_end = key.offset + - btrfs_file_extent_num_bytes(leaf, fi); - } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { - extent_end = key.offset + - btrfs_file_extent_inline_len(leaf, fi); - } else { - WARN_ON(1); - extent_end = search_start; +next_slot: + keep = 0; + bookend = 0; + found_extent = 0; + found_inline = 0; + compression = 0; + encryption = 0; + extent = NULL; + leaf = path->nodes[0]; + slot = path->slots[0]; + ret = 0; + btrfs_item_key_to_cpu(leaf, &key, slot); + if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY && + key.offset >= end) { + goto out; } - - if (extent_end <= search_start) { - path->slots[0]++; - goto next_slot; + if (btrfs_key_type(&key) > BTRFS_EXTENT_DATA_KEY || + key.objectid != inode->i_ino) { + goto out; } - - search_start = max(key.offset, start); if (recow) { - btrfs_release_path(root, path); + search_start = max(key.offset, start); continue; } + if (btrfs_key_type(&key) == BTRFS_EXTENT_DATA_KEY) { + extent = btrfs_item_ptr(leaf, slot, + struct btrfs_file_extent_item); + found_type = btrfs_file_extent_type(leaf, extent); + compression = btrfs_file_extent_compression(leaf, + extent); + encryption = btrfs_file_extent_encryption(leaf, + extent); + other_encoding = btrfs_file_extent_other_encoding(leaf, + extent); + if (found_type == BTRFS_FILE_EXTENT_REG || + found_type == BTRFS_FILE_EXTENT_PREALLOC) { + extent_end = + btrfs_file_extent_disk_bytenr(leaf, + extent); + if (extent_end) + *hint_byte = extent_end; + + extent_end = key.offset + + btrfs_file_extent_num_bytes(leaf, extent); + ram_bytes = btrfs_file_extent_ram_bytes(leaf, + extent); + found_extent = 1; + } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { + found_inline = 1; + extent_end = key.offset + + btrfs_file_extent_inline_len(leaf, extent); + } + } else { + extent_end = search_start; + } - /* - * | - range to drop - | - * | -------- extent -------- | - */ - if (start > key.offset && end < extent_end) { - BUG_ON(del_nr > 0); - BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE); - - memcpy(&new_key, &key, sizeof(new_key)); - new_key.offset = start; - ret = btrfs_duplicate_item(trans, root, path, - &new_key); - if (ret == -EAGAIN) { - btrfs_release_path(root, path); - continue; + /* we found nothing we can drop */ + if ((!found_extent && !found_inline) || + search_start >= extent_end) { + int nextret; + u32 nritems; + nritems = btrfs_header_nritems(leaf); + if (slot >= nritems - 1) { + nextret = btrfs_next_leaf(root, path); + if (nextret) + goto out; + recow = 1; + } else { + path->slots[0]++; } - if (ret < 0) - break; + goto next_slot; + } - leaf = path->nodes[0]; - fi = btrfs_item_ptr(leaf, path->slots[0] - 1, - struct btrfs_file_extent_item); - btrfs_set_file_extent_num_bytes(leaf, fi, - start - key.offset); + if (end <= extent_end && start >= key.offset && found_inline) + *hint_byte = EXTENT_MAP_INLINE; - fi = btrfs_item_ptr(leaf, path->slots[0], - struct btrfs_file_extent_item); + if (found_extent) { + read_extent_buffer(leaf, &old, (unsigned long)extent, + sizeof(old)); + } - extent_offset += start - key.offset; - btrfs_set_file_extent_offset(leaf, fi, extent_offset); - btrfs_set_file_extent_num_bytes(leaf, fi, - extent_end - start); - btrfs_mark_buffer_dirty(leaf); + if (end < extent_end && end >= key.offset) { + bookend = 1; + if (found_inline && start <= key.offset) + keep = 1; + } - if (disk_bytenr > 0) { + if (bookend && found_extent) { + if (locked_end < extent_end) { + ret = try_lock_extent(&BTRFS_I(inode)->io_tree, + locked_end, extent_end - 1, + GFP_NOFS); + if (!ret) { + btrfs_release_path(root, path); + lock_extent(&BTRFS_I(inode)->io_tree, + locked_end, extent_end - 1, + GFP_NOFS); + locked_end = extent_end; + continue; + } + locked_end = extent_end; + } + disk_bytenr = le64_to_cpu(old.disk_bytenr); + if (disk_bytenr != 0) { ret = btrfs_inc_extent_ref(trans, root, - disk_bytenr, num_bytes, 0, - root->root_key.objectid, - new_key.objectid, - start - extent_offset); + disk_bytenr, + le64_to_cpu(old.disk_num_bytes), 0, + root->root_key.objectid, + key.objectid, key.offset - + le64_to_cpu(old.offset)); BUG_ON(ret); - *hint_byte = disk_bytenr; } - key.offset = start; } - /* - * | ---- range to drop ----- | - * | -------- extent -------- | - */ - if (start <= key.offset && end < extent_end) { - BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE); - memcpy(&new_key, &key, sizeof(new_key)); - new_key.offset = end; - btrfs_set_item_key_safe(trans, root, path, &new_key); - - extent_offset += end - key.offset; - btrfs_set_file_extent_offset(leaf, fi, extent_offset); - btrfs_set_file_extent_num_bytes(leaf, fi, - extent_end - end); - btrfs_mark_buffer_dirty(leaf); - if (disk_bytenr > 0) { - inode_sub_bytes(inode, end - key.offset); - *hint_byte = disk_bytenr; + if (found_inline) { + u64 mask = root->sectorsize - 1; + search_start = (extent_end + mask) & ~mask; + } else + search_start = extent_end; + + /* truncate existing extent */ + if (start > key.offset) { + u64 new_num; + u64 old_num; + keep = 1; + WARN_ON(start & (root->sectorsize - 1)); + if (found_extent) { + new_num = start - key.offset; + old_num = btrfs_file_extent_num_bytes(leaf, + extent); + *hint_byte = + btrfs_file_extent_disk_bytenr(leaf, + extent); + if (btrfs_file_extent_disk_bytenr(leaf, + extent)) { + inode_sub_bytes(inode, old_num - + new_num); + } + btrfs_set_file_extent_num_bytes(leaf, + extent, new_num); + btrfs_mark_buffer_dirty(leaf); + } else if (key.offset < inline_limit && + (end > extent_end) && + (inline_limit < extent_end)) { + u32 new_size; + new_size = btrfs_file_extent_calc_inline_size( + inline_limit - key.offset); + inode_sub_bytes(inode, extent_end - + inline_limit); + btrfs_set_file_extent_ram_bytes(leaf, extent, + new_size); + if (!compression && !encryption) { + btrfs_truncate_item(trans, root, path, + new_size, 1); + } } - break; } + /* delete the entire extent */ + if (!keep) { + if (found_inline) + inode_sub_bytes(inode, extent_end - + key.offset); + ret = btrfs_del_item(trans, root, path); + /* TODO update progress marker and return */ + BUG_ON(ret); + extent = NULL; + btrfs_release_path(root, path); + /* the extent will be freed later */ + } + if (bookend && found_inline && start <= key.offset) { + u32 new_size; + new_size = btrfs_file_extent_calc_inline_size( + extent_end - end); + inode_sub_bytes(inode, end - key.offset); + btrfs_set_file_extent_ram_bytes(leaf, extent, + new_size); + if (!compression && !encryption) + ret = btrfs_truncate_item(trans, root, path, + new_size, 0); + BUG_ON(ret); + } + /* create bookend, splitting the extent in two */ + if (bookend && found_extent) { + struct btrfs_key ins; + ins.objectid = inode->i_ino; + ins.offset = end; + btrfs_set_key_type(&ins, BTRFS_EXTENT_DATA_KEY); - search_start = extent_end; - /* - * | ---- range to drop ----- | - * | -------- extent -------- | - */ - if (start > key.offset && end >= extent_end) { - BUG_ON(del_nr > 0); - BUG_ON(extent_type == BTRFS_FILE_EXTENT_INLINE); + btrfs_release_path(root, path); + path->leave_spinning = 1; + ret = btrfs_insert_empty_item(trans, root, path, &ins, + sizeof(*extent)); + BUG_ON(ret); - btrfs_set_file_extent_num_bytes(leaf, fi, - start - key.offset); - btrfs_mark_buffer_dirty(leaf); - if (disk_bytenr > 0) { - inode_sub_bytes(inode, extent_end - start); - *hint_byte = disk_bytenr; - } - if (end == extent_end) - break; + leaf = path->nodes[0]; + extent = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); + write_extent_buffer(leaf, &old, + (unsigned long)extent, sizeof(old)); + + btrfs_set_file_extent_compression(leaf, extent, + compression); + btrfs_set_file_extent_encryption(leaf, extent, + encryption); + btrfs_set_file_extent_other_encoding(leaf, extent, + other_encoding); + btrfs_set_file_extent_offset(leaf, extent, + le64_to_cpu(old.offset) + end - key.offset); + WARN_ON(le64_to_cpu(old.num_bytes) < + (extent_end - end)); + btrfs_set_file_extent_num_bytes(leaf, extent, + extent_end - end); - path->slots[0]++; - goto next_slot; + /* + * set the ram bytes to the size of the full extent + * before splitting. This is a worst case flag, + * but its the best we can do because we don't know + * how splitting affects compression + */ + btrfs_set_file_extent_ram_bytes(leaf, extent, + ram_bytes); + btrfs_set_file_extent_type(leaf, extent, found_type); + + btrfs_unlock_up_safe(path, 1); + btrfs_mark_buffer_dirty(path->nodes[0]); + btrfs_set_lock_blocking(path->nodes[0]); + + path->leave_spinning = 0; + btrfs_release_path(root, path); + if (disk_bytenr != 0) + inode_add_bytes(inode, extent_end - end); } - /* - * | ---- range to drop ----- | - * | ------ extent ------ | - */ - if (start <= key.offset && end >= extent_end) { - if (del_nr == 0) { - del_slot = path->slots[0]; - del_nr = 1; - } else { - BUG_ON(del_slot + del_nr != path->slots[0]); - del_nr++; - } + if (found_extent && !keep) { + u64 old_disk_bytenr = le64_to_cpu(old.disk_bytenr); - if (extent_type == BTRFS_FILE_EXTENT_INLINE) { + if (old_disk_bytenr != 0) { inode_sub_bytes(inode, - extent_end - key.offset); - extent_end = ALIGN(extent_end, - root->sectorsize); - } else if (disk_bytenr > 0) { + le64_to_cpu(old.num_bytes)); ret = btrfs_free_extent(trans, root, - disk_bytenr, num_bytes, 0, - root->root_key.objectid, + old_disk_bytenr, + le64_to_cpu(old.disk_num_bytes), + 0, root->root_key.objectid, key.objectid, key.offset - - extent_offset); + le64_to_cpu(old.offset)); BUG_ON(ret); - inode_sub_bytes(inode, - extent_end - key.offset); - *hint_byte = disk_bytenr; - } - - if (end == extent_end) - break; - - if (path->slots[0] + 1 < btrfs_header_nritems(leaf)) { - path->slots[0]++; - goto next_slot; + *hint_byte = old_disk_bytenr; } - - ret = btrfs_del_items(trans, root, path, del_slot, - del_nr); - BUG_ON(ret); - - del_nr = 0; - del_slot = 0; - - btrfs_release_path(root, path); - continue; } - BUG_ON(1); - } - - if (del_nr > 0) { - ret = btrfs_del_items(trans, root, path, del_slot, del_nr); - BUG_ON(ret); + if (search_start >= end) { + ret = 0; + goto out; + } } - +out: btrfs_free_path(path); + if (locked_end > orig_locked_end) { + unlock_extent(&BTRFS_I(inode)->io_tree, orig_locked_end, + locked_end - 1, GFP_NOFS); + } return ret; } @@ -544,23 +620,23 @@ static int extent_mergeable(struct extent_buffer *leaf, int slot, * two or three. */ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct inode *inode, u64 start, u64 end) { - struct btrfs_root *root = BTRFS_I(inode)->root; struct extent_buffer *leaf; struct btrfs_path *path; struct btrfs_file_extent_item *fi; struct btrfs_key key; - struct btrfs_key new_key; u64 bytenr; u64 num_bytes; u64 extent_end; u64 orig_offset; u64 other_start; u64 other_end; - u64 split; - int del_nr = 0; - int del_slot = 0; + u64 split = start; + u64 locked_end = end; + int extent_type; + int split_end = 1; int ret; btrfs_drop_extent_cache(inode, start, end - 1, 0); @@ -568,10 +644,12 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, path = btrfs_alloc_path(); BUG_ON(!path); again: - split = start; key.objectid = inode->i_ino; key.type = BTRFS_EXTENT_DATA_KEY; - key.offset = split; + if (split == start) + key.offset = split; + else + key.offset = split - 1; ret = btrfs_search_slot(trans, root, &key, path, -1, 1); if (ret > 0 && path->slots[0] > 0) @@ -583,8 +661,8 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, key.type != BTRFS_EXTENT_DATA_KEY); fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); - BUG_ON(btrfs_file_extent_type(leaf, fi) != - BTRFS_FILE_EXTENT_PREALLOC); + extent_type = btrfs_file_extent_type(leaf, fi); + BUG_ON(extent_type != BTRFS_FILE_EXTENT_PREALLOC); extent_end = key.offset + btrfs_file_extent_num_bytes(leaf, fi); BUG_ON(key.offset > start || extent_end < end); @@ -592,91 +670,150 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi); orig_offset = key.offset - btrfs_file_extent_offset(leaf, fi); - while (start > key.offset || end < extent_end) { - if (key.offset == start) - split = end; - - memcpy(&new_key, &key, sizeof(new_key)); - new_key.offset = split; - ret = btrfs_duplicate_item(trans, root, path, &new_key); - if (ret == -EAGAIN) { - btrfs_release_path(root, path); - goto again; + if (key.offset == start) + split = end; + + if (key.offset == start && extent_end == end) { + int del_nr = 0; + int del_slot = 0; + other_start = end; + other_end = 0; + if (extent_mergeable(leaf, path->slots[0] + 1, inode->i_ino, + bytenr, &other_start, &other_end)) { + extent_end = other_end; + del_slot = path->slots[0] + 1; + del_nr++; + ret = btrfs_free_extent(trans, root, bytenr, num_bytes, + 0, root->root_key.objectid, + inode->i_ino, orig_offset); + BUG_ON(ret); + } + other_start = 0; + other_end = start; + if (extent_mergeable(leaf, path->slots[0] - 1, inode->i_ino, + bytenr, &other_start, &other_end)) { + key.offset = other_start; + del_slot = path->slots[0]; + del_nr++; + ret = btrfs_free_extent(trans, root, bytenr, num_bytes, + 0, root->root_key.objectid, + inode->i_ino, orig_offset); + BUG_ON(ret); + } + split_end = 0; + if (del_nr == 0) { + btrfs_set_file_extent_type(leaf, fi, + BTRFS_FILE_EXTENT_REG); + goto done; } - BUG_ON(ret < 0); - - leaf = path->nodes[0]; - fi = btrfs_item_ptr(leaf, path->slots[0] - 1, - struct btrfs_file_extent_item); - btrfs_set_file_extent_num_bytes(leaf, fi, - split - key.offset); - fi = btrfs_item_ptr(leaf, path->slots[0], + fi = btrfs_item_ptr(leaf, del_slot - 1, struct btrfs_file_extent_item); - - btrfs_set_file_extent_offset(leaf, fi, split - orig_offset); + btrfs_set_file_extent_type(leaf, fi, BTRFS_FILE_EXTENT_REG); btrfs_set_file_extent_num_bytes(leaf, fi, - extent_end - split); + extent_end - key.offset); btrfs_mark_buffer_dirty(leaf); - ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0, - root->root_key.objectid, - inode->i_ino, orig_offset); + ret = btrfs_del_items(trans, root, path, del_slot, del_nr); BUG_ON(ret); - - if (split == start) { - key.offset = start; - } else { - BUG_ON(start != key.offset); - path->slots[0]--; - extent_end = end; + goto release; + } else if (split == start) { + if (locked_end < extent_end) { + ret = try_lock_extent(&BTRFS_I(inode)->io_tree, + locked_end, extent_end - 1, GFP_NOFS); + if (!ret) { + btrfs_release_path(root, path); + lock_extent(&BTRFS_I(inode)->io_tree, + locked_end, extent_end - 1, GFP_NOFS); + locked_end = extent_end; + goto again; + } + locked_end = extent_end; } + btrfs_set_file_extent_num_bytes(leaf, fi, split - key.offset); + } else { + BUG_ON(key.offset != start); + key.offset = split; + btrfs_set_file_extent_offset(leaf, fi, key.offset - + orig_offset); + btrfs_set_file_extent_num_bytes(leaf, fi, extent_end - split); + btrfs_set_item_key_safe(trans, root, path, &key); + extent_end = split; } - fi = btrfs_item_ptr(leaf, path->slots[0], - struct btrfs_file_extent_item); - - other_start = end; - other_end = 0; - if (extent_mergeable(leaf, path->slots[0] + 1, inode->i_ino, - bytenr, &other_start, &other_end)) { - extent_end = other_end; - del_slot = path->slots[0] + 1; - del_nr++; - ret = btrfs_free_extent(trans, root, bytenr, num_bytes, - 0, root->root_key.objectid, - inode->i_ino, orig_offset); - BUG_ON(ret); + if (extent_end == end) { + split_end = 0; + extent_type = BTRFS_FILE_EXTENT_REG; } - other_start = 0; - other_end = start; - if (extent_mergeable(leaf, path->slots[0] - 1, inode->i_ino, - bytenr, &other_start, &other_end)) { - key.offset = other_start; - del_slot = path->slots[0]; - del_nr++; - ret = btrfs_free_extent(trans, root, bytenr, num_bytes, - 0, root->root_key.objectid, - inode->i_ino, orig_offset); - BUG_ON(ret); + if (extent_end == end && split == start) { + other_start = end; + other_end = 0; + if (extent_mergeable(leaf, path->slots[0] + 1, inode->i_ino, + bytenr, &other_start, &other_end)) { + path->slots[0]++; + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); + key.offset = split; + btrfs_set_item_key_safe(trans, root, path, &key); + btrfs_set_file_extent_offset(leaf, fi, key.offset - + orig_offset); + btrfs_set_file_extent_num_bytes(leaf, fi, + other_end - split); + goto done; + } } - if (del_nr == 0) { - btrfs_set_file_extent_type(leaf, fi, - BTRFS_FILE_EXTENT_REG); - btrfs_mark_buffer_dirty(leaf); - goto out; + if (extent_end == end && split == end) { + other_start = 0; + other_end = start; + if (extent_mergeable(leaf, path->slots[0] - 1 , inode->i_ino, + bytenr, &other_start, &other_end)) { + path->slots[0]--; + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); + btrfs_set_file_extent_num_bytes(leaf, fi, extent_end - + other_start); + goto done; + } } - fi = btrfs_item_ptr(leaf, del_slot - 1, - struct btrfs_file_extent_item); - btrfs_set_file_extent_type(leaf, fi, BTRFS_FILE_EXTENT_REG); - btrfs_set_file_extent_num_bytes(leaf, fi, - extent_end - key.offset); btrfs_mark_buffer_dirty(leaf); - ret = btrfs_del_items(trans, root, path, del_slot, del_nr); + ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0, + root->root_key.objectid, + inode->i_ino, orig_offset); BUG_ON(ret); -out: + btrfs_release_path(root, path); + + key.offset = start; + ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(*fi)); + BUG_ON(ret); + + leaf = path->nodes[0]; + fi = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_file_extent_item); + btrfs_set_file_extent_generation(leaf, fi, trans->transid); + btrfs_set_file_extent_type(leaf, fi, extent_type); + btrfs_set_file_extent_disk_bytenr(leaf, fi, bytenr); + btrfs_set_file_extent_disk_num_bytes(leaf, fi, num_bytes); + btrfs_set_file_extent_offset(leaf, fi, key.offset - orig_offset); + btrfs_set_file_extent_num_bytes(leaf, fi, extent_end - key.offset); + btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes); + btrfs_set_file_extent_compression(leaf, fi, 0); + btrfs_set_file_extent_encryption(leaf, fi, 0); + btrfs_set_file_extent_other_encoding(leaf, fi, 0); +done: + btrfs_mark_buffer_dirty(leaf); + +release: + btrfs_release_path(root, path); + if (split_end && split == start) { + split = end; + goto again; + } + if (locked_end > end) { + unlock_extent(&BTRFS_I(inode)->io_tree, end, locked_end - 1, + GFP_NOFS); + } btrfs_free_path(path); return 0; } diff --git a/trunk/fs/btrfs/inode.c b/trunk/fs/btrfs/inode.c index 5440bab23635..b3ad168a0bfc 100644 --- a/trunk/fs/btrfs/inode.c +++ b/trunk/fs/btrfs/inode.c @@ -88,14 +88,13 @@ static noinline int cow_file_range(struct inode *inode, u64 start, u64 end, int *page_started, unsigned long *nr_written, int unlock); -static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, - struct inode *inode, struct inode *dir) +static int btrfs_init_inode_security(struct inode *inode, struct inode *dir) { int err; - err = btrfs_init_acl(trans, inode, dir); + err = btrfs_init_acl(inode, dir); if (!err) - err = btrfs_xattr_security_init(trans, inode, dir); + err = btrfs_xattr_security_init(inode, dir); return err; } @@ -189,18 +188,8 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(leaf); btrfs_free_path(path); - /* - * we're an inline extent, so nobody can - * extend the file past i_size without locking - * a page we already have locked. - * - * We must do any isize and inode updates - * before we unlock the pages. Otherwise we - * could end up racing with unlink. - */ BTRFS_I(inode)->disk_i_size = inode->i_size; btrfs_update_inode(trans, root, inode); - return 0; fail: btrfs_free_path(path); @@ -241,7 +230,8 @@ static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans, return 1; } - ret = btrfs_drop_extents(trans, inode, start, aligned_end, + ret = btrfs_drop_extents(trans, root, inode, start, + aligned_end, aligned_end, start, &hint_byte, 1); BUG_ON(ret); @@ -426,6 +416,7 @@ static noinline int compress_file_range(struct inode *inode, start, end, total_compressed, pages); } + btrfs_end_transaction(trans, root); if (ret == 0) { /* * inline extent creation worked, we don't need @@ -439,11 +430,9 @@ static noinline int compress_file_range(struct inode *inode, EXTENT_CLEAR_DELALLOC | EXTENT_CLEAR_ACCOUNTING | EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK); - - btrfs_end_transaction(trans, root); + ret = 0; goto free_pages_out; } - btrfs_end_transaction(trans, root); } if (will_compress) { @@ -554,6 +543,7 @@ static noinline int submit_compressed_extents(struct inode *inode, if (list_empty(&async_cow->extents)) return 0; + trans = btrfs_join_transaction(root, 1); while (!list_empty(&async_cow->extents)) { async_extent = list_entry(async_cow->extents.next, @@ -600,15 +590,19 @@ static noinline int submit_compressed_extents(struct inode *inode, lock_extent(io_tree, async_extent->start, async_extent->start + async_extent->ram_size - 1, GFP_NOFS); + /* + * here we're doing allocation and writeback of the + * compressed pages + */ + btrfs_drop_extent_cache(inode, async_extent->start, + async_extent->start + + async_extent->ram_size - 1, 0); - trans = btrfs_join_transaction(root, 1); ret = btrfs_reserve_extent(trans, root, async_extent->compressed_size, async_extent->compressed_size, 0, alloc_hint, (u64)-1, &ins, 1); - btrfs_end_transaction(trans, root); - if (ret) { int i; for (i = 0; i < async_extent->nr_pages; i++) { @@ -624,14 +618,6 @@ static noinline int submit_compressed_extents(struct inode *inode, goto retry; } - /* - * here we're doing allocation and writeback of the - * compressed pages - */ - btrfs_drop_extent_cache(inode, async_extent->start, - async_extent->start + - async_extent->ram_size - 1, 0); - em = alloc_extent_map(GFP_NOFS); em->start = async_extent->start; em->len = async_extent->ram_size; @@ -663,6 +649,8 @@ static noinline int submit_compressed_extents(struct inode *inode, BTRFS_ORDERED_COMPRESSED); BUG_ON(ret); + btrfs_end_transaction(trans, root); + /* * clear dirty, set writeback and unlock the pages. */ @@ -684,11 +672,13 @@ static noinline int submit_compressed_extents(struct inode *inode, async_extent->nr_pages); BUG_ON(ret); + trans = btrfs_join_transaction(root, 1); alloc_hint = ins.objectid + ins.offset; kfree(async_extent); cond_resched(); } + btrfs_end_transaction(trans, root); return 0; } @@ -752,7 +742,6 @@ static noinline int cow_file_range(struct inode *inode, EXTENT_CLEAR_DIRTY | EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK); - *nr_written = *nr_written + (end - start + PAGE_CACHE_SIZE) / PAGE_CACHE_SIZE; *page_started = 1; @@ -1607,6 +1596,7 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, struct inode *inode, u64 file_pos, u64 disk_bytenr, u64 disk_num_bytes, u64 num_bytes, u64 ram_bytes, + u64 locked_end, u8 compression, u8 encryption, u16 other_encoding, int extent_type) { @@ -1632,8 +1622,9 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, * the caller is expected to unpin it and allow it to be merged * with the others. */ - ret = btrfs_drop_extents(trans, inode, file_pos, file_pos + num_bytes, - &hint, 0); + ret = btrfs_drop_extents(trans, root, inode, file_pos, + file_pos + num_bytes, locked_end, + file_pos, &hint, 0); BUG_ON(ret); ins.objectid = inode->i_ino; @@ -1739,32 +1730,23 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) } } + trans = btrfs_join_transaction(root, 1); + if (!ordered_extent) ordered_extent = btrfs_lookup_ordered_extent(inode, start); BUG_ON(!ordered_extent); - if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { - BUG_ON(!list_empty(&ordered_extent->list)); - ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); - if (!ret) { - trans = btrfs_join_transaction(root, 1); - ret = btrfs_update_inode(trans, root, inode); - BUG_ON(ret); - btrfs_end_transaction(trans, root); - } - goto out; - } + if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) + goto nocow; lock_extent(io_tree, ordered_extent->file_offset, ordered_extent->file_offset + ordered_extent->len - 1, GFP_NOFS); - trans = btrfs_join_transaction(root, 1); - if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered_extent->flags)) compressed = 1; if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { BUG_ON(compressed); - ret = btrfs_mark_extent_written(trans, inode, + ret = btrfs_mark_extent_written(trans, root, inode, ordered_extent->file_offset, ordered_extent->file_offset + ordered_extent->len); @@ -1776,6 +1758,8 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) ordered_extent->disk_len, ordered_extent->len, ordered_extent->len, + ordered_extent->file_offset + + ordered_extent->len, compressed, 0, 0, BTRFS_FILE_EXTENT_REG); unpin_extent_cache(&BTRFS_I(inode)->extent_tree, @@ -1786,20 +1770,22 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) unlock_extent(io_tree, ordered_extent->file_offset, ordered_extent->file_offset + ordered_extent->len - 1, GFP_NOFS); +nocow: add_pending_csums(trans, inode, ordered_extent->file_offset, &ordered_extent->list); - /* this also removes the ordered extent from the tree */ - btrfs_ordered_update_i_size(inode, 0, ordered_extent); - ret = btrfs_update_inode(trans, root, inode); - BUG_ON(ret); - btrfs_end_transaction(trans, root); -out: + mutex_lock(&BTRFS_I(inode)->extent_mutex); + btrfs_ordered_update_i_size(inode, ordered_extent); + btrfs_update_inode(trans, root, inode); + btrfs_remove_ordered_extent(inode, ordered_extent); + mutex_unlock(&BTRFS_I(inode)->extent_mutex); + /* once for us */ btrfs_put_ordered_extent(ordered_extent); /* once for the tree */ btrfs_put_ordered_extent(ordered_extent); + btrfs_end_transaction(trans, root); return 0; } @@ -2022,54 +2008,6 @@ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end, return -EIO; } -struct delayed_iput { - struct list_head list; - struct inode *inode; -}; - -void btrfs_add_delayed_iput(struct inode *inode) -{ - struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info; - struct delayed_iput *delayed; - - if (atomic_add_unless(&inode->i_count, -1, 1)) - return; - - delayed = kmalloc(sizeof(*delayed), GFP_NOFS | __GFP_NOFAIL); - delayed->inode = inode; - - spin_lock(&fs_info->delayed_iput_lock); - list_add_tail(&delayed->list, &fs_info->delayed_iputs); - spin_unlock(&fs_info->delayed_iput_lock); -} - -void btrfs_run_delayed_iputs(struct btrfs_root *root) -{ - LIST_HEAD(list); - struct btrfs_fs_info *fs_info = root->fs_info; - struct delayed_iput *delayed; - int empty; - - spin_lock(&fs_info->delayed_iput_lock); - empty = list_empty(&fs_info->delayed_iputs); - spin_unlock(&fs_info->delayed_iput_lock); - if (empty) - return; - - down_read(&root->fs_info->cleanup_work_sem); - spin_lock(&fs_info->delayed_iput_lock); - list_splice_init(&fs_info->delayed_iputs, &list); - spin_unlock(&fs_info->delayed_iput_lock); - - while (!list_empty(&list)) { - delayed = list_entry(list.next, struct delayed_iput, list); - list_del(&delayed->list); - iput(delayed->inode); - kfree(delayed); - } - up_read(&root->fs_info->cleanup_work_sem); -} - /* * This creates an orphan entry for the given inode in case something goes * wrong in the middle of an unlink/truncate. @@ -2142,17 +2080,16 @@ void btrfs_orphan_cleanup(struct btrfs_root *root) struct inode *inode; int ret = 0, nr_unlink = 0, nr_truncate = 0; - if (!xchg(&root->clean_orphans, 0)) - return; - path = btrfs_alloc_path(); - BUG_ON(!path); + if (!path) + return; path->reada = -1; key.objectid = BTRFS_ORPHAN_OBJECTID; btrfs_set_key_type(&key, BTRFS_ORPHAN_ITEM_KEY); key.offset = (u64)-1; + while (1) { ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); if (ret < 0) { @@ -2897,40 +2834,37 @@ static noinline int drop_csum_leaves(struct btrfs_trans_handle *trans, * min_type is the minimum key type to truncate down to. If set to 0, this * will kill all the items on this inode, including the INODE_ITEM_KEY. */ -int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct inode *inode, - u64 new_size, u32 min_type) +noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct inode *inode, + u64 new_size, u32 min_type) { + int ret; struct btrfs_path *path; - struct extent_buffer *leaf; - struct btrfs_file_extent_item *fi; struct btrfs_key key; struct btrfs_key found_key; + u32 found_type = (u8)-1; + struct extent_buffer *leaf; + struct btrfs_file_extent_item *fi; u64 extent_start = 0; u64 extent_num_bytes = 0; u64 extent_offset = 0; u64 item_end = 0; - u64 mask = root->sectorsize - 1; - u32 found_type = (u8)-1; int found_extent; int del_item; int pending_del_nr = 0; int pending_del_slot = 0; int extent_type = -1; int encoding; - int ret; - int err = 0; - - BUG_ON(new_size > 0 && min_type != BTRFS_EXTENT_DATA_KEY); + u64 mask = root->sectorsize - 1; if (root->ref_cows) btrfs_drop_extent_cache(inode, new_size & (~mask), (u64)-1, 0); - path = btrfs_alloc_path(); BUG_ON(!path); path->reada = -1; + /* FIXME, add redo link to tree so we don't leak on crash */ key.objectid = inode->i_ino; key.offset = (u64)-1; key.type = (u8)-1; @@ -2938,17 +2872,17 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, search_again: path->leave_spinning = 1; ret = btrfs_search_slot(trans, root, &key, path, -1, 1); - if (ret < 0) { - err = ret; - goto out; - } + if (ret < 0) + goto error; if (ret > 0) { /* there are no items in the tree for us to truncate, we're * done */ - if (path->slots[0] == 0) - goto out; + if (path->slots[0] == 0) { + ret = 0; + goto error; + } path->slots[0]--; } @@ -2983,17 +2917,28 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, } item_end--; } - if (found_type > min_type) { - del_item = 1; - } else { - if (item_end < new_size) - break; - if (found_key.offset >= new_size) - del_item = 1; + if (item_end < new_size) { + if (found_type == BTRFS_DIR_ITEM_KEY) + found_type = BTRFS_INODE_ITEM_KEY; + else if (found_type == BTRFS_EXTENT_ITEM_KEY) + found_type = BTRFS_EXTENT_DATA_KEY; + else if (found_type == BTRFS_EXTENT_DATA_KEY) + found_type = BTRFS_XATTR_ITEM_KEY; + else if (found_type == BTRFS_XATTR_ITEM_KEY) + found_type = BTRFS_INODE_REF_KEY; + else if (found_type) + found_type--; else - del_item = 0; + break; + btrfs_set_key_type(&key, found_type); + goto next; } + if (found_key.offset >= new_size) + del_item = 1; + else + del_item = 0; found_extent = 0; + /* FIXME, shrink the extent if the ref count is only 1 */ if (found_type != BTRFS_EXTENT_DATA_KEY) goto delete; @@ -3080,36 +3025,42 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, inode->i_ino, extent_offset); BUG_ON(ret); } +next: + if (path->slots[0] == 0) { + if (pending_del_nr) + goto del_pending; + btrfs_release_path(root, path); + if (found_type == BTRFS_INODE_ITEM_KEY) + break; + goto search_again; + } - if (found_type == BTRFS_INODE_ITEM_KEY) - break; - - if (path->slots[0] == 0 || - path->slots[0] != pending_del_slot) { - if (root->ref_cows) { - err = -EAGAIN; - goto out; - } - if (pending_del_nr) { - ret = btrfs_del_items(trans, root, path, - pending_del_slot, - pending_del_nr); - BUG_ON(ret); - pending_del_nr = 0; - } + path->slots[0]--; + if (pending_del_nr && + path->slots[0] + 1 != pending_del_slot) { + struct btrfs_key debug; +del_pending: + btrfs_item_key_to_cpu(path->nodes[0], &debug, + pending_del_slot); + ret = btrfs_del_items(trans, root, path, + pending_del_slot, + pending_del_nr); + BUG_ON(ret); + pending_del_nr = 0; btrfs_release_path(root, path); + if (found_type == BTRFS_INODE_ITEM_KEY) + break; goto search_again; - } else { - path->slots[0]--; } } -out: + ret = 0; +error: if (pending_del_nr) { ret = btrfs_del_items(trans, root, path, pending_del_slot, pending_del_nr); } btrfs_free_path(path); - return err; + return ret; } /* @@ -3229,6 +3180,10 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) if (size <= hole_start) return 0; + err = btrfs_truncate_page(inode->i_mapping, inode->i_size); + if (err) + return err; + while (1) { struct btrfs_ordered_extent *ordered; btrfs_wait_ordered_range(inode, hole_start, @@ -3241,6 +3196,9 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) btrfs_put_ordered_extent(ordered); } + trans = btrfs_start_transaction(root, 1); + btrfs_set_trans_block_group(trans, inode); + cur_offset = hole_start; while (1) { em = btrfs_get_extent(inode, NULL, 0, cur_offset, @@ -3248,120 +3206,40 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) BUG_ON(IS_ERR(em) || !em); last_byte = min(extent_map_end(em), block_end); last_byte = (last_byte + mask) & ~mask; - if (!test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) { + if (test_bit(EXTENT_FLAG_VACANCY, &em->flags)) { u64 hint_byte = 0; hole_size = last_byte - cur_offset; - - err = btrfs_reserve_metadata_space(root, 2); + err = btrfs_drop_extents(trans, root, inode, + cur_offset, + cur_offset + hole_size, + block_end, + cur_offset, &hint_byte, 1); if (err) break; - trans = btrfs_start_transaction(root, 1); - btrfs_set_trans_block_group(trans, inode); - - err = btrfs_drop_extents(trans, inode, cur_offset, - cur_offset + hole_size, - &hint_byte, 1); - BUG_ON(err); + err = btrfs_reserve_metadata_space(root, 1); + if (err) + break; err = btrfs_insert_file_extent(trans, root, inode->i_ino, cur_offset, 0, 0, hole_size, 0, hole_size, 0, 0, 0); - BUG_ON(err); - btrfs_drop_extent_cache(inode, hole_start, last_byte - 1, 0); - - btrfs_end_transaction(trans, root); - btrfs_unreserve_metadata_space(root, 2); + btrfs_unreserve_metadata_space(root, 1); } free_extent_map(em); cur_offset = last_byte; - if (cur_offset >= block_end) + if (err || cur_offset >= block_end) break; } + btrfs_end_transaction(trans, root); unlock_extent(io_tree, hole_start, block_end - 1, GFP_NOFS); return err; } -static int btrfs_setattr_size(struct inode *inode, struct iattr *attr) -{ - struct btrfs_root *root = BTRFS_I(inode)->root; - struct btrfs_trans_handle *trans; - unsigned long nr; - int ret; - - if (attr->ia_size == inode->i_size) - return 0; - - if (attr->ia_size > inode->i_size) { - unsigned long limit; - limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; - if (attr->ia_size > inode->i_sb->s_maxbytes) - return -EFBIG; - if (limit != RLIM_INFINITY && attr->ia_size > limit) { - send_sig(SIGXFSZ, current, 0); - return -EFBIG; - } - } - - ret = btrfs_reserve_metadata_space(root, 1); - if (ret) - return ret; - - trans = btrfs_start_transaction(root, 1); - btrfs_set_trans_block_group(trans, inode); - - ret = btrfs_orphan_add(trans, inode); - BUG_ON(ret); - - nr = trans->blocks_used; - btrfs_end_transaction(trans, root); - btrfs_unreserve_metadata_space(root, 1); - btrfs_btree_balance_dirty(root, nr); - - if (attr->ia_size > inode->i_size) { - ret = btrfs_cont_expand(inode, attr->ia_size); - if (ret) { - btrfs_truncate(inode); - return ret; - } - - i_size_write(inode, attr->ia_size); - btrfs_ordered_update_i_size(inode, inode->i_size, NULL); - - trans = btrfs_start_transaction(root, 1); - btrfs_set_trans_block_group(trans, inode); - - ret = btrfs_update_inode(trans, root, inode); - BUG_ON(ret); - if (inode->i_nlink > 0) { - ret = btrfs_orphan_del(trans, inode); - BUG_ON(ret); - } - nr = trans->blocks_used; - btrfs_end_transaction(trans, root); - btrfs_btree_balance_dirty(root, nr); - return 0; - } - - /* - * We're truncating a file that used to have good data down to - * zero. Make sure it gets into the ordered flush list so that - * any new writes get down to disk quickly. - */ - if (attr->ia_size == 0) - BTRFS_I(inode)->ordered_data_close = 1; - - /* we don't support swapfiles, so vmtruncate shouldn't fail */ - ret = vmtruncate(inode, attr->ia_size); - BUG_ON(ret); - - return 0; -} - static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) { struct inode *inode = dentry->d_inode; @@ -3372,14 +3250,23 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) return err; if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { - err = btrfs_setattr_size(inode, attr); - if (err) - return err; + if (attr->ia_size > inode->i_size) { + err = btrfs_cont_expand(inode, attr->ia_size); + if (err) + return err; + } else if (inode->i_size > 0 && + attr->ia_size == 0) { + + /* we're truncating a file that used to have good + * data down to zero. Make sure it gets into + * the ordered flush list so that any new writes + * get down to disk quickly. + */ + BTRFS_I(inode)->ordered_data_close = 1; + } } - attr->ia_valid &= ~ATTR_SIZE; - if (attr->ia_valid) - err = inode_setattr(inode, attr); + err = inode_setattr(inode, attr); if (!err && ((attr->ia_valid & ATTR_MODE))) err = btrfs_acl_chmod(inode); @@ -3400,43 +3287,36 @@ void btrfs_delete_inode(struct inode *inode) } btrfs_wait_ordered_range(inode, 0, (u64)-1); - if (root->fs_info->log_root_recovering) { - BUG_ON(!list_empty(&BTRFS_I(inode)->i_orphan)); - goto no_delete; - } - if (inode->i_nlink > 0) { BUG_ON(btrfs_root_refs(&root->root_item) != 0); goto no_delete; } btrfs_i_size_write(inode, 0); + trans = btrfs_join_transaction(root, 1); - while (1) { - trans = btrfs_start_transaction(root, 1); - btrfs_set_trans_block_group(trans, inode); - ret = btrfs_truncate_inode_items(trans, root, inode, 0, 0); + btrfs_set_trans_block_group(trans, inode); + ret = btrfs_truncate_inode_items(trans, root, inode, inode->i_size, 0); + if (ret) { + btrfs_orphan_del(NULL, inode); + goto no_delete_lock; + } - if (ret != -EAGAIN) - break; + btrfs_orphan_del(trans, inode); - nr = trans->blocks_used; - btrfs_end_transaction(trans, root); - trans = NULL; - btrfs_btree_balance_dirty(root, nr); - } + nr = trans->blocks_used; + clear_inode(inode); - if (ret == 0) { - ret = btrfs_orphan_del(trans, inode); - BUG_ON(ret); - } + btrfs_end_transaction(trans, root); + btrfs_btree_balance_dirty(root, nr); + return; +no_delete_lock: nr = trans->blocks_used; btrfs_end_transaction(trans, root); btrfs_btree_balance_dirty(root, nr); no_delete: clear_inode(inode); - return; } /* @@ -3689,6 +3569,7 @@ static noinline void init_btrfs_i(struct inode *inode) INIT_LIST_HEAD(&BTRFS_I(inode)->ordered_operations); RB_CLEAR_NODE(&BTRFS_I(inode)->rb_node); btrfs_ordered_inode_tree_init(&BTRFS_I(inode)->ordered_tree); + mutex_init(&BTRFS_I(inode)->extent_mutex); mutex_init(&BTRFS_I(inode)->log_mutex); } @@ -3814,13 +3695,6 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) } srcu_read_unlock(&root->fs_info->subvol_srcu, index); - if (root != sub_root) { - down_read(&root->fs_info->cleanup_work_sem); - if (!(inode->i_sb->s_flags & MS_RDONLY)) - btrfs_orphan_cleanup(sub_root); - up_read(&root->fs_info->cleanup_work_sem); - } - return inode; } @@ -4345,7 +4219,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, if (IS_ERR(inode)) goto out_unlock; - err = btrfs_init_inode_security(trans, inode, dir); + err = btrfs_init_inode_security(inode, dir); if (err) { drop_inode = 1; goto out_unlock; @@ -4416,7 +4290,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, if (IS_ERR(inode)) goto out_unlock; - err = btrfs_init_inode_security(trans, inode, dir); + err = btrfs_init_inode_security(inode, dir); if (err) { drop_inode = 1; goto out_unlock; @@ -4462,10 +4336,6 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, if (inode->i_nlink == 0) return -ENOENT; - /* do not allow sys_link's with other subvols of the same device */ - if (root->objectid != BTRFS_I(inode)->root->objectid) - return -EPERM; - /* * 1 item for inode ref * 2 items for dir items @@ -4553,7 +4423,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) drop_on_err = 1; - err = btrfs_init_inode_security(trans, inode, dir); + err = btrfs_init_inode_security(inode, dir); if (err) goto out_fail; @@ -5204,20 +5074,17 @@ static void btrfs_truncate(struct inode *inode) unsigned long nr; u64 mask = root->sectorsize - 1; - if (!S_ISREG(inode->i_mode)) { - WARN_ON(1); + if (!S_ISREG(inode->i_mode)) + return; + if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) return; - } ret = btrfs_truncate_page(inode->i_mapping, inode->i_size); if (ret) return; - btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1); - btrfs_ordered_update_i_size(inode, inode->i_size, NULL); trans = btrfs_start_transaction(root, 1); - btrfs_set_trans_block_group(trans, inode); /* * setattr is responsible for setting the ordered_data_close flag, @@ -5239,32 +5106,21 @@ static void btrfs_truncate(struct inode *inode) if (inode->i_size == 0 && BTRFS_I(inode)->ordered_data_close) btrfs_add_ordered_operation(trans, root, inode); - while (1) { - ret = btrfs_truncate_inode_items(trans, root, inode, - inode->i_size, - BTRFS_EXTENT_DATA_KEY); - if (ret != -EAGAIN) - break; - - ret = btrfs_update_inode(trans, root, inode); - BUG_ON(ret); - - nr = trans->blocks_used; - btrfs_end_transaction(trans, root); - btrfs_btree_balance_dirty(root, nr); - - trans = btrfs_start_transaction(root, 1); - btrfs_set_trans_block_group(trans, inode); - } + btrfs_set_trans_block_group(trans, inode); + btrfs_i_size_write(inode, inode->i_size); - if (ret == 0 && inode->i_nlink > 0) { - ret = btrfs_orphan_del(trans, inode); - BUG_ON(ret); - } + ret = btrfs_orphan_add(trans, inode); + if (ret) + goto out; + /* FIXME, add redo link to tree so we don't leak on crash */ + ret = btrfs_truncate_inode_items(trans, root, inode, inode->i_size, + BTRFS_EXTENT_DATA_KEY); + btrfs_update_inode(trans, root, inode); - ret = btrfs_update_inode(trans, root, inode); + ret = btrfs_orphan_del(trans, inode); BUG_ON(ret); +out: nr = trans->blocks_used; ret = btrfs_end_transaction_throttle(trans, root); BUG_ON(ret); @@ -5361,9 +5217,9 @@ void btrfs_destroy_inode(struct inode *inode) spin_lock(&root->list_lock); if (!list_empty(&BTRFS_I(inode)->i_orphan)) { - printk(KERN_INFO "BTRFS: inode %lu still on the orphan list\n", - inode->i_ino); - list_del_init(&BTRFS_I(inode)->i_orphan); + printk(KERN_ERR "BTRFS: inode %lu: inode still on the orphan" + " list\n", inode->i_ino); + dump_stack(); } spin_unlock(&root->list_lock); @@ -5620,7 +5476,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, * some fairly slow code that needs optimization. This walks the list * of all the inodes with pending delalloc and forces them to disk. */ -int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput) +int btrfs_start_delalloc_inodes(struct btrfs_root *root) { struct list_head *head = &root->fs_info->delalloc_inodes; struct btrfs_inode *binode; @@ -5639,10 +5495,7 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput) spin_unlock(&root->fs_info->delalloc_lock); if (inode) { filemap_flush(inode->i_mapping); - if (delay_iput) - btrfs_add_delayed_iput(inode); - else - iput(inode); + iput(inode); } cond_resched(); spin_lock(&root->fs_info->delalloc_lock); @@ -5716,7 +5569,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, if (IS_ERR(inode)) goto out_unlock; - err = btrfs_init_inode_security(trans, inode, dir); + err = btrfs_init_inode_security(inode, dir); if (err) { drop_inode = 1; goto out_unlock; @@ -5788,10 +5641,10 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, return err; } -static int prealloc_file_range(struct inode *inode, u64 start, u64 end, - u64 alloc_hint, int mode) +static int prealloc_file_range(struct btrfs_trans_handle *trans, + struct inode *inode, u64 start, u64 end, + u64 locked_end, u64 alloc_hint, int mode) { - struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_key ins; u64 alloc_size; @@ -5802,56 +5655,43 @@ static int prealloc_file_range(struct inode *inode, u64 start, u64 end, while (num_bytes > 0) { alloc_size = min(num_bytes, root->fs_info->max_extent); - trans = btrfs_start_transaction(root, 1); + ret = btrfs_reserve_metadata_space(root, 1); + if (ret) + goto out; ret = btrfs_reserve_extent(trans, root, alloc_size, root->sectorsize, 0, alloc_hint, (u64)-1, &ins, 1); if (ret) { WARN_ON(1); - goto stop_trans; - } - - ret = btrfs_reserve_metadata_space(root, 3); - if (ret) { - btrfs_free_reserved_extent(root, ins.objectid, - ins.offset); - goto stop_trans; + goto out; } - ret = insert_reserved_file_extent(trans, inode, cur_offset, ins.objectid, ins.offset, ins.offset, - ins.offset, 0, 0, 0, + ins.offset, locked_end, + 0, 0, 0, BTRFS_FILE_EXTENT_PREALLOC); BUG_ON(ret); btrfs_drop_extent_cache(inode, cur_offset, cur_offset + ins.offset -1, 0); - num_bytes -= ins.offset; cur_offset += ins.offset; alloc_hint = ins.objectid + ins.offset; - + btrfs_unreserve_metadata_space(root, 1); + } +out: + if (cur_offset > start) { inode->i_ctime = CURRENT_TIME; BTRFS_I(inode)->flags |= BTRFS_INODE_PREALLOC; if (!(mode & FALLOC_FL_KEEP_SIZE) && - cur_offset > inode->i_size) { - i_size_write(inode, cur_offset); - btrfs_ordered_update_i_size(inode, cur_offset, NULL); - } - + cur_offset > i_size_read(inode)) + btrfs_i_size_write(inode, cur_offset); ret = btrfs_update_inode(trans, root, inode); BUG_ON(ret); - - btrfs_end_transaction(trans, root); - btrfs_unreserve_metadata_space(root, 3); } - return ret; -stop_trans: - btrfs_end_transaction(trans, root); return ret; - } static long btrfs_fallocate(struct inode *inode, int mode, @@ -5865,6 +5705,8 @@ static long btrfs_fallocate(struct inode *inode, int mode, u64 locked_end; u64 mask = BTRFS_I(inode)->root->sectorsize - 1; struct extent_map *em; + struct btrfs_trans_handle *trans; + struct btrfs_root *root; int ret; alloc_start = offset & ~mask; @@ -5883,7 +5725,9 @@ static long btrfs_fallocate(struct inode *inode, int mode, goto out; } - ret = btrfs_check_data_free_space(BTRFS_I(inode)->root, inode, + root = BTRFS_I(inode)->root; + + ret = btrfs_check_data_free_space(root, inode, alloc_end - alloc_start); if (ret) goto out; @@ -5892,6 +5736,12 @@ static long btrfs_fallocate(struct inode *inode, int mode, while (1) { struct btrfs_ordered_extent *ordered; + trans = btrfs_start_transaction(BTRFS_I(inode)->root, 1); + if (!trans) { + ret = -EIO; + goto out_free; + } + /* the extent lock is ordered inside the running * transaction */ @@ -5905,6 +5755,8 @@ static long btrfs_fallocate(struct inode *inode, int mode, btrfs_put_ordered_extent(ordered); unlock_extent(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, GFP_NOFS); + btrfs_end_transaction(trans, BTRFS_I(inode)->root); + /* * we can't wait on the range with the transaction * running or with the extent lock held @@ -5925,12 +5777,10 @@ static long btrfs_fallocate(struct inode *inode, int mode, BUG_ON(IS_ERR(em) || !em); last_byte = min(extent_map_end(em), alloc_end); last_byte = (last_byte + mask) & ~mask; - if (em->block_start == EXTENT_MAP_HOLE || - (cur_offset >= inode->i_size && - !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { - ret = prealloc_file_range(inode, - cur_offset, last_byte, - alloc_hint, mode); + if (em->block_start == EXTENT_MAP_HOLE) { + ret = prealloc_file_range(trans, inode, cur_offset, + last_byte, locked_end + 1, + alloc_hint, mode); if (ret < 0) { free_extent_map(em); break; @@ -5949,8 +5799,9 @@ static long btrfs_fallocate(struct inode *inode, int mode, unlock_extent(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, GFP_NOFS); - btrfs_free_reserved_data_space(BTRFS_I(inode)->root, inode, - alloc_end - alloc_start); + btrfs_end_transaction(trans, BTRFS_I(inode)->root); +out_free: + btrfs_free_reserved_data_space(root, inode, alloc_end - alloc_start); out: mutex_unlock(&inode->i_mutex); return ret; diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index 645a17927a8f..cdbb054102b9 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -237,6 +237,7 @@ static noinline int create_subvol(struct btrfs_root *root, u64 objectid; u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; u64 index = 0; + unsigned long nr = 1; /* * 1 - inode item @@ -289,7 +290,7 @@ static noinline int create_subvol(struct btrfs_root *root, btrfs_set_root_generation(&root_item, trans->transid); btrfs_set_root_level(&root_item, 0); btrfs_set_root_refs(&root_item, 1); - btrfs_set_root_used(&root_item, leaf->len); + btrfs_set_root_used(&root_item, 0); btrfs_set_root_last_snapshot(&root_item, 0); memset(&root_item.drop_progress, 0, sizeof(root_item.drop_progress)); @@ -341,21 +342,24 @@ static noinline int create_subvol(struct btrfs_root *root, d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); fail: + nr = trans->blocks_used; err = btrfs_commit_transaction(trans, root); if (err && !ret) ret = err; btrfs_unreserve_metadata_space(root, 6); + btrfs_btree_balance_dirty(root, nr); return ret; } static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, char *name, int namelen) { - struct inode *inode; struct btrfs_pending_snapshot *pending_snapshot; struct btrfs_trans_handle *trans; - int ret; + int ret = 0; + int err; + unsigned long nr = 0; if (!root->ref_cows) return -EINVAL; @@ -368,20 +372,20 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, */ ret = btrfs_reserve_metadata_space(root, 6); if (ret) - goto fail; + goto fail_unlock; pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); if (!pending_snapshot) { ret = -ENOMEM; btrfs_unreserve_metadata_space(root, 6); - goto fail; + goto fail_unlock; } pending_snapshot->name = kmalloc(namelen + 1, GFP_NOFS); if (!pending_snapshot->name) { ret = -ENOMEM; kfree(pending_snapshot); btrfs_unreserve_metadata_space(root, 6); - goto fail; + goto fail_unlock; } memcpy(pending_snapshot->name, name, namelen); pending_snapshot->name[namelen] = '\0'; @@ -391,19 +395,10 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, pending_snapshot->root = root; list_add(&pending_snapshot->list, &trans->transaction->pending_snapshots); - ret = btrfs_commit_transaction(trans, root); - BUG_ON(ret); - btrfs_unreserve_metadata_space(root, 6); + err = btrfs_commit_transaction(trans, root); - inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry); - if (IS_ERR(inode)) { - ret = PTR_ERR(inode); - goto fail; - } - BUG_ON(!inode); - d_instantiate(dentry, inode); - ret = 0; -fail: +fail_unlock: + btrfs_btree_balance_dirty(root, nr); return ret; } @@ -1032,7 +1027,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, BUG_ON(!trans); /* punch hole in destination first */ - btrfs_drop_extents(trans, inode, off, off + len, &hint_byte, 1); + btrfs_drop_extents(trans, root, inode, off, off + len, + off + len, 0, &hint_byte, 1); /* clone data */ key.objectid = src->i_ino; diff --git a/trunk/fs/btrfs/ordered-data.c b/trunk/fs/btrfs/ordered-data.c index b10a49d4bc6a..5799bc46a309 100644 --- a/trunk/fs/btrfs/ordered-data.c +++ b/trunk/fs/btrfs/ordered-data.c @@ -291,16 +291,16 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry) /* * remove an ordered extent from the tree. No references are dropped - * and you must wake_up entry->wait. You must hold the tree mutex - * while you call this function. + * but, anyone waiting on this extent is woken up. */ -static int __btrfs_remove_ordered_extent(struct inode *inode, +int btrfs_remove_ordered_extent(struct inode *inode, struct btrfs_ordered_extent *entry) { struct btrfs_ordered_inode_tree *tree; struct rb_node *node; tree = &BTRFS_I(inode)->ordered_tree; + mutex_lock(&tree->mutex); node = &entry->rb_node; rb_erase(node, &tree->tree); tree->last = NULL; @@ -326,34 +326,16 @@ static int __btrfs_remove_ordered_extent(struct inode *inode, } spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); - return 0; -} - -/* - * remove an ordered extent from the tree. No references are dropped - * but any waiters are woken. - */ -int btrfs_remove_ordered_extent(struct inode *inode, - struct btrfs_ordered_extent *entry) -{ - struct btrfs_ordered_inode_tree *tree; - int ret; - - tree = &BTRFS_I(inode)->ordered_tree; - mutex_lock(&tree->mutex); - ret = __btrfs_remove_ordered_extent(inode, entry); mutex_unlock(&tree->mutex); wake_up(&entry->wait); - - return ret; + return 0; } /* * wait for all the ordered extents in a root. This is done when balancing * space between drives. */ -int btrfs_wait_ordered_extents(struct btrfs_root *root, - int nocow_only, int delay_iput) +int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only) { struct list_head splice; struct list_head *cur; @@ -390,10 +372,7 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, if (inode) { btrfs_start_ordered_extent(inode, ordered, 1); btrfs_put_ordered_extent(ordered); - if (delay_iput) - btrfs_add_delayed_iput(inode); - else - iput(inode); + iput(inode); } else { btrfs_put_ordered_extent(ordered); } @@ -451,7 +430,7 @@ int btrfs_run_ordered_operations(struct btrfs_root *root, int wait) btrfs_wait_ordered_range(inode, 0, (u64)-1); else filemap_flush(inode->i_mapping); - btrfs_add_delayed_iput(inode); + iput(inode); } cond_resched(); @@ -610,7 +589,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset) * After an extent is done, call this to conditionally update the on disk * i_size. i_size is updated to cover any fully written part of the file. */ -int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, +int btrfs_ordered_update_i_size(struct inode *inode, struct btrfs_ordered_extent *ordered) { struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree; @@ -618,30 +597,18 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, u64 disk_i_size; u64 new_i_size; u64 i_size_test; - u64 i_size = i_size_read(inode); struct rb_node *node; - struct rb_node *prev = NULL; struct btrfs_ordered_extent *test; - int ret = 1; - - if (ordered) - offset = entry_end(ordered); mutex_lock(&tree->mutex); disk_i_size = BTRFS_I(inode)->disk_i_size; - /* truncate file */ - if (disk_i_size > i_size) { - BTRFS_I(inode)->disk_i_size = i_size; - ret = 0; - goto out; - } - /* * if the disk i_size is already at the inode->i_size, or * this ordered extent is inside the disk i_size, we're done */ - if (disk_i_size == i_size || offset <= disk_i_size) { + if (disk_i_size >= inode->i_size || + ordered->file_offset + ordered->len <= disk_i_size) { goto out; } @@ -649,7 +616,8 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, * we can't update the disk_isize if there are delalloc bytes * between disk_i_size and this ordered extent */ - if (test_range_bit(io_tree, disk_i_size, offset - 1, + if (test_range_bit(io_tree, disk_i_size, + ordered->file_offset + ordered->len - 1, EXTENT_DELALLOC, 0, NULL)) { goto out; } @@ -658,32 +626,20 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, * if we find an ordered extent then we can't update disk i_size * yet */ - if (ordered) { - node = rb_prev(&ordered->rb_node); - } else { - prev = tree_search(tree, offset); - /* - * we insert file extents without involving ordered struct, - * so there should be no ordered struct cover this offset - */ - if (prev) { - test = rb_entry(prev, struct btrfs_ordered_extent, - rb_node); - BUG_ON(offset_in_entry(test, offset)); - } - node = prev; - } - while (node) { + node = &ordered->rb_node; + while (1) { + node = rb_prev(node); + if (!node) + break; test = rb_entry(node, struct btrfs_ordered_extent, rb_node); if (test->file_offset + test->len <= disk_i_size) break; - if (test->file_offset >= i_size) + if (test->file_offset >= inode->i_size) break; if (test->file_offset >= disk_i_size) goto out; - node = rb_prev(node); } - new_i_size = min_t(u64, offset, i_size); + new_i_size = min_t(u64, entry_end(ordered), i_size_read(inode)); /* * at this point, we know we can safely update i_size to at least @@ -691,14 +647,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, * walk forward and see if ios from higher up in the file have * finished. */ - if (ordered) { - node = rb_next(&ordered->rb_node); - } else { - if (prev) - node = rb_next(prev); - else - node = rb_first(&tree->tree); - } + node = rb_next(&ordered->rb_node); i_size_test = 0; if (node) { /* @@ -706,10 +655,10 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, * between our ordered extent and the next one. */ test = rb_entry(node, struct btrfs_ordered_extent, rb_node); - if (test->file_offset > offset) + if (test->file_offset > entry_end(ordered)) i_size_test = test->file_offset; } else { - i_size_test = i_size; + i_size_test = i_size_read(inode); } /* @@ -718,25 +667,15 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, * are no delalloc bytes in this area, it is safe to update * disk_i_size to the end of the region. */ - if (i_size_test > offset && - !test_range_bit(io_tree, offset, i_size_test - 1, - EXTENT_DELALLOC, 0, NULL)) { - new_i_size = min_t(u64, i_size_test, i_size); + if (i_size_test > entry_end(ordered) && + !test_range_bit(io_tree, entry_end(ordered), i_size_test - 1, + EXTENT_DELALLOC, 0, NULL)) { + new_i_size = min_t(u64, i_size_test, i_size_read(inode)); } BTRFS_I(inode)->disk_i_size = new_i_size; - ret = 0; out: - /* - * we need to remove the ordered extent with the tree lock held - * so that other people calling this function don't find our fully - * processed ordered entry and skip updating the i_size - */ - if (ordered) - __btrfs_remove_ordered_extent(inode, ordered); mutex_unlock(&tree->mutex); - if (ordered) - wake_up(&ordered->wait); - return ret; + return 0; } /* diff --git a/trunk/fs/btrfs/ordered-data.h b/trunk/fs/btrfs/ordered-data.h index 1fe1282ef47c..f82e87488ca8 100644 --- a/trunk/fs/btrfs/ordered-data.h +++ b/trunk/fs/btrfs/ordered-data.h @@ -150,13 +150,12 @@ void btrfs_start_ordered_extent(struct inode *inode, int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len); struct btrfs_ordered_extent * btrfs_lookup_first_ordered_extent(struct inode * inode, u64 file_offset); -int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, +int btrfs_ordered_update_i_size(struct inode *inode, struct btrfs_ordered_extent *ordered); int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, u32 *sum); +int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only); int btrfs_run_ordered_operations(struct btrfs_root *root, int wait); int btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *inode); -int btrfs_wait_ordered_extents(struct btrfs_root *root, - int nocow_only, int delay_iput); #endif diff --git a/trunk/fs/btrfs/relocation.c b/trunk/fs/btrfs/relocation.c index a9728680eca8..cfcc93c93a7b 100644 --- a/trunk/fs/btrfs/relocation.c +++ b/trunk/fs/btrfs/relocation.c @@ -1561,20 +1561,6 @@ static int invalidate_extent_cache(struct btrfs_root *root, return 0; } -static void put_inodes(struct list_head *list) -{ - struct inodevec *ivec; - while (!list_empty(list)) { - ivec = list_entry(list->next, struct inodevec, list); - list_del(&ivec->list); - while (ivec->nr > 0) { - ivec->nr--; - iput(ivec->inode[ivec->nr]); - } - kfree(ivec); - } -} - static int find_next_key(struct btrfs_path *path, int level, struct btrfs_key *key) @@ -1737,11 +1723,6 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc, btrfs_btree_balance_dirty(root, nr); - /* - * put inodes outside transaction, otherwise we may deadlock. - */ - put_inodes(&inode_list); - if (replaced && rc->stage == UPDATE_DATA_PTRS) invalidate_extent_cache(root, &key, &next_key); } @@ -1771,7 +1752,19 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc, btrfs_btree_balance_dirty(root, nr); - put_inodes(&inode_list); + /* + * put inodes while we aren't holding the tree locks + */ + while (!list_empty(&inode_list)) { + struct inodevec *ivec; + ivec = list_entry(inode_list.next, struct inodevec, list); + list_del(&ivec->list); + while (ivec->nr > 0) { + ivec->nr--; + iput(ivec->inode[ivec->nr]); + } + kfree(ivec); + } if (replaced && rc->stage == UPDATE_DATA_PTRS) invalidate_extent_cache(root, &key, &next_key); @@ -3541,8 +3534,8 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start) (unsigned long long)rc->block_group->key.objectid, (unsigned long long)rc->block_group->flags); - btrfs_start_delalloc_inodes(fs_info->tree_root, 0); - btrfs_wait_ordered_extents(fs_info->tree_root, 0, 0); + btrfs_start_delalloc_inodes(fs_info->tree_root); + btrfs_wait_ordered_extents(fs_info->tree_root, 0); while (1) { rc->extents_found = 0; @@ -3762,7 +3755,6 @@ int btrfs_recover_relocation(struct btrfs_root *root) BTRFS_DATA_RELOC_TREE_OBJECTID); if (IS_ERR(fs_root)) err = PTR_ERR(fs_root); - btrfs_orphan_cleanup(fs_root); } return err; } diff --git a/trunk/fs/btrfs/super.c b/trunk/fs/btrfs/super.c index 3f9b45704fcd..752a5463bf53 100644 --- a/trunk/fs/btrfs/super.c +++ b/trunk/fs/btrfs/super.c @@ -128,7 +128,6 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) substring_t args[MAX_OPT_ARGS]; char *p, *num; int intarg; - int ret = 0; if (!options) return 0; @@ -263,18 +262,12 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) case Opt_discard: btrfs_set_opt(info->mount_opt, DISCARD); break; - case Opt_err: - printk(KERN_INFO "btrfs: unrecognized mount option " - "'%s'\n", p); - ret = -EINVAL; - goto out; default: break; } } -out: kfree(options); - return ret; + return 0; } /* @@ -412,8 +405,8 @@ int btrfs_sync_fs(struct super_block *sb, int wait) return 0; } - btrfs_start_delalloc_inodes(root, 0); - btrfs_wait_ordered_extents(root, 0, 0); + btrfs_start_delalloc_inodes(root); + btrfs_wait_ordered_extents(root, 0); trans = btrfs_start_transaction(root, 1); ret = btrfs_commit_transaction(trans, root); @@ -457,8 +450,6 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) seq_puts(seq, ",notreelog"); if (btrfs_test_opt(root, FLUSHONCOMMIT)) seq_puts(seq, ",flushoncommit"); - if (btrfs_test_opt(root, DISCARD)) - seq_puts(seq, ",discard"); if (!(root->fs_info->sb->s_flags & MS_POSIXACL)) seq_puts(seq, ",noacl"); return 0; diff --git a/trunk/fs/btrfs/transaction.c b/trunk/fs/btrfs/transaction.c index b2acc79f1b34..c207e8c32c9b 100644 --- a/trunk/fs/btrfs/transaction.c +++ b/trunk/fs/btrfs/transaction.c @@ -333,9 +333,6 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, memset(trans, 0, sizeof(*trans)); kmem_cache_free(btrfs_trans_handle_cachep, trans); - if (throttle) - btrfs_run_delayed_iputs(root); - return 0; } @@ -357,7 +354,7 @@ int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans, * those extents are sent to disk but does not wait on them */ int btrfs_write_marked_extents(struct btrfs_root *root, - struct extent_io_tree *dirty_pages, int mark) + struct extent_io_tree *dirty_pages) { int ret; int err = 0; @@ -370,7 +367,7 @@ int btrfs_write_marked_extents(struct btrfs_root *root, while (1) { ret = find_first_extent_bit(dirty_pages, start, &start, &end, - mark); + EXTENT_DIRTY); if (ret) break; while (start <= end) { @@ -416,7 +413,7 @@ int btrfs_write_marked_extents(struct btrfs_root *root, * on all the pages and clear them from the dirty pages state tree */ int btrfs_wait_marked_extents(struct btrfs_root *root, - struct extent_io_tree *dirty_pages, int mark) + struct extent_io_tree *dirty_pages) { int ret; int err = 0; @@ -428,12 +425,12 @@ int btrfs_wait_marked_extents(struct btrfs_root *root, unsigned long index; while (1) { - ret = find_first_extent_bit(dirty_pages, start, &start, &end, - mark); + ret = find_first_extent_bit(dirty_pages, 0, &start, &end, + EXTENT_DIRTY); if (ret) break; - clear_extent_bits(dirty_pages, start, end, mark, GFP_NOFS); + clear_extent_dirty(dirty_pages, start, end, GFP_NOFS); while (start <= end) { index = start >> PAGE_CACHE_SHIFT; start = (u64)(index + 1) << PAGE_CACHE_SHIFT; @@ -463,13 +460,13 @@ int btrfs_wait_marked_extents(struct btrfs_root *root, * those extents are on disk for transaction or log commit */ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, - struct extent_io_tree *dirty_pages, int mark) + struct extent_io_tree *dirty_pages) { int ret; int ret2; - ret = btrfs_write_marked_extents(root, dirty_pages, mark); - ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark); + ret = btrfs_write_marked_extents(root, dirty_pages); + ret2 = btrfs_wait_marked_extents(root, dirty_pages); return ret || ret2; } @@ -482,8 +479,7 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, return filemap_write_and_wait(btree_inode->i_mapping); } return btrfs_write_and_wait_marked_extents(root, - &trans->transaction->dirty_pages, - EXTENT_DIRTY); + &trans->transaction->dirty_pages); } /* @@ -501,16 +497,13 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, { int ret; u64 old_root_bytenr; - u64 old_root_used; struct btrfs_root *tree_root = root->fs_info->tree_root; - old_root_used = btrfs_root_used(&root->root_item); btrfs_write_dirty_block_groups(trans, root); while (1) { old_root_bytenr = btrfs_root_bytenr(&root->root_item); - if (old_root_bytenr == root->node->start && - old_root_used == btrfs_root_used(&root->root_item)) + if (old_root_bytenr == root->node->start) break; btrfs_set_root_node(&root->root_item, root->node); @@ -519,7 +512,6 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, &root->root_item); BUG_ON(ret); - old_root_used = btrfs_root_used(&root->root_item); ret = btrfs_write_dirty_block_groups(trans, root); BUG_ON(ret); } @@ -803,6 +795,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, memcpy(&pending->root_key, &key, sizeof(key)); fail: kfree(new_root_item); + btrfs_unreserve_metadata_space(root, 6); return ret; } @@ -814,6 +807,7 @@ static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info, u64 index = 0; struct btrfs_trans_handle *trans; struct inode *parent_inode; + struct inode *inode; struct btrfs_root *parent_root; parent_inode = pending->dentry->d_parent->d_inode; @@ -845,6 +839,8 @@ static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info, BUG_ON(ret); + inode = btrfs_lookup_dentry(parent_inode, pending->dentry); + d_instantiate(pending->dentry, inode); fail: btrfs_end_transaction(trans, fs_info->fs_root); return ret; @@ -998,11 +994,11 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, mutex_unlock(&root->fs_info->trans_mutex); if (flush_on_commit) { - btrfs_start_delalloc_inodes(root, 1); - ret = btrfs_wait_ordered_extents(root, 0, 1); + btrfs_start_delalloc_inodes(root); + ret = btrfs_wait_ordered_extents(root, 0); BUG_ON(ret); } else if (snap_pending) { - ret = btrfs_wait_ordered_extents(root, 0, 1); + ret = btrfs_wait_ordered_extents(root, 1); BUG_ON(ret); } @@ -1120,10 +1116,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, current->journal_info = NULL; kmem_cache_free(btrfs_trans_handle_cachep, trans); - - if (current != root->fs_info->transaction_kthread) - btrfs_run_delayed_iputs(root); - return ret; } diff --git a/trunk/fs/btrfs/transaction.h b/trunk/fs/btrfs/transaction.h index 93c7ccb33118..d4e3e7a6938c 100644 --- a/trunk/fs/btrfs/transaction.h +++ b/trunk/fs/btrfs/transaction.h @@ -107,10 +107,10 @@ void btrfs_throttle(struct btrfs_root *root); int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans, struct btrfs_root *root); int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, - struct extent_io_tree *dirty_pages, int mark); + struct extent_io_tree *dirty_pages); int btrfs_write_marked_extents(struct btrfs_root *root, - struct extent_io_tree *dirty_pages, int mark); + struct extent_io_tree *dirty_pages); int btrfs_wait_marked_extents(struct btrfs_root *root, - struct extent_io_tree *dirty_pages, int mark); + struct extent_io_tree *dirty_pages); int btrfs_transaction_in_commit(struct btrfs_fs_info *info); #endif diff --git a/trunk/fs/btrfs/tree-log.c b/trunk/fs/btrfs/tree-log.c index 4a9434b622ec..741666a7676a 100644 --- a/trunk/fs/btrfs/tree-log.c +++ b/trunk/fs/btrfs/tree-log.c @@ -542,8 +542,8 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, saved_nbytes = inode_get_bytes(inode); /* drop any overlapping extents */ - ret = btrfs_drop_extents(trans, inode, start, extent_end, - &alloc_hint, 1); + ret = btrfs_drop_extents(trans, root, inode, + start, extent_end, extent_end, start, &alloc_hint, 1); BUG_ON(ret); if (found_type == BTRFS_FILE_EXTENT_REG || @@ -930,17 +930,6 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, return 0; } -static int insert_orphan_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 offset) -{ - int ret; - ret = btrfs_find_orphan_item(root, offset); - if (ret > 0) - ret = btrfs_insert_orphan_item(trans, root, offset); - return ret; -} - - /* * There are a few corners where the link count of the file can't * be properly maintained during replay. So, instead of adding @@ -1008,13 +997,9 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans, } BTRFS_I(inode)->index_cnt = (u64)-1; - if (inode->i_nlink == 0) { - if (S_ISDIR(inode->i_mode)) { - ret = replay_dir_deletes(trans, root, NULL, path, - inode->i_ino, 1); - BUG_ON(ret); - } - ret = insert_orphan_item(trans, root, inode->i_ino); + if (inode->i_nlink == 0 && S_ISDIR(inode->i_mode)) { + ret = replay_dir_deletes(trans, root, NULL, path, + inode->i_ino, 1); BUG_ON(ret); } btrfs_free_path(path); @@ -1602,6 +1587,7 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb, /* inode keys are done during the first stage */ if (key.type == BTRFS_INODE_ITEM_KEY && wc->stage == LOG_WALK_REPLAY_INODES) { + struct inode *inode; struct btrfs_inode_item *inode_item; u32 mode; @@ -1617,16 +1603,31 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb, eb, i, &key); BUG_ON(ret); - /* for regular files, make sure corresponding - * orhpan item exist. extents past the new EOF - * will be truncated later by orphan cleanup. + /* for regular files, truncate away + * extents past the new EOF */ if (S_ISREG(mode)) { - ret = insert_orphan_item(wc->trans, root, - key.objectid); + inode = read_one_inode(root, + key.objectid); + BUG_ON(!inode); + + ret = btrfs_truncate_inode_items(wc->trans, + root, inode, inode->i_size, + BTRFS_EXTENT_DATA_KEY); BUG_ON(ret); - } + /* if the nlink count is zero here, the iput + * will free the inode. We bump it to make + * sure it doesn't get freed until the link + * count fixup is done + */ + if (inode->i_nlink == 0) { + btrfs_inc_nlink(inode); + btrfs_update_inode(wc->trans, + root, inode); + } + iput(inode); + } ret = link_to_fixup_dir(wc->trans, root, path, key.objectid); BUG_ON(ret); @@ -1976,11 +1977,10 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, { int index1; int index2; - int mark; int ret; struct btrfs_root *log = root->log_root; struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; - unsigned long log_transid = 0; + u64 log_transid = 0; mutex_lock(&root->log_mutex); index1 = root->log_transid % 2; @@ -2014,29 +2014,24 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, goto out; } - log_transid = root->log_transid; - if (log_transid % 2 == 0) - mark = EXTENT_DIRTY; - else - mark = EXTENT_NEW; - /* we start IO on all the marked extents here, but we don't actually * wait for them until later. */ - ret = btrfs_write_marked_extents(log, &log->dirty_log_pages, mark); + ret = btrfs_write_marked_extents(log, &log->dirty_log_pages); BUG_ON(ret); btrfs_set_root_node(&log->root_item, log->node); root->log_batch = 0; + log_transid = root->log_transid; root->log_transid++; log->log_transid = root->log_transid; root->log_start_pid = 0; smp_mb(); /* - * IO has been started, blocks of the log tree have WRITTEN flag set - * in their headers. new modifications of the log will be written to - * new positions. so it's safe to allow log writers to go in. + * log tree has been flushed to disk, new modifications of + * the log will be written to new positions. so it's safe to + * allow log writers to go in. */ mutex_unlock(&root->log_mutex); @@ -2057,7 +2052,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, index2 = log_root_tree->log_transid % 2; if (atomic_read(&log_root_tree->log_commit[index2])) { - btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); + btrfs_wait_marked_extents(log, &log->dirty_log_pages); wait_log_commit(trans, log_root_tree, log_root_tree->log_transid); mutex_unlock(&log_root_tree->log_mutex); @@ -2077,17 +2072,16 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, * check the full commit flag again */ if (root->fs_info->last_trans_log_full_commit == trans->transid) { - btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); + btrfs_wait_marked_extents(log, &log->dirty_log_pages); mutex_unlock(&log_root_tree->log_mutex); ret = -EAGAIN; goto out_wake_log_root; } ret = btrfs_write_and_wait_marked_extents(log_root_tree, - &log_root_tree->dirty_log_pages, - EXTENT_DIRTY | EXTENT_NEW); + &log_root_tree->dirty_log_pages); BUG_ON(ret); - btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); + btrfs_wait_marked_extents(log, &log->dirty_log_pages); btrfs_set_super_log_root(&root->fs_info->super_for_commit, log_root_tree->node->start); @@ -2153,12 +2147,12 @@ int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root) while (1) { ret = find_first_extent_bit(&log->dirty_log_pages, - 0, &start, &end, EXTENT_DIRTY | EXTENT_NEW); + 0, &start, &end, EXTENT_DIRTY); if (ret) break; - clear_extent_bits(&log->dirty_log_pages, start, end, - EXTENT_DIRTY | EXTENT_NEW, GFP_NOFS); + clear_extent_dirty(&log->dirty_log_pages, + start, end, GFP_NOFS); } if (log->log_transid > 0) { diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index 198cff28766d..7eda483d7b5a 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -2209,7 +2209,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, max_chunk_size = 10 * calc_size; min_stripe_size = 64 * 1024 * 1024; } else if (type & BTRFS_BLOCK_GROUP_METADATA) { - max_chunk_size = 256 * 1024 * 1024; + max_chunk_size = 4 * calc_size; min_stripe_size = 32 * 1024 * 1024; } else if (type & BTRFS_BLOCK_GROUP_SYSTEM) { calc_size = 8 * 1024 * 1024; diff --git a/trunk/fs/btrfs/xattr.c b/trunk/fs/btrfs/xattr.c index 193b58f7d3f3..b6dd5967c48a 100644 --- a/trunk/fs/btrfs/xattr.c +++ b/trunk/fs/btrfs/xattr.c @@ -85,23 +85,22 @@ ssize_t __btrfs_getxattr(struct inode *inode, const char *name, return ret; } -static int do_setxattr(struct btrfs_trans_handle *trans, - struct inode *inode, const char *name, - const void *value, size_t size, int flags) +int __btrfs_setxattr(struct inode *inode, const char *name, + const void *value, size_t size, int flags) { struct btrfs_dir_item *di; struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_trans_handle *trans; struct btrfs_path *path; - size_t name_len = strlen(name); - int ret = 0; - - if (name_len + size > BTRFS_MAX_XATTR_SIZE(root)) - return -ENOSPC; + int ret = 0, mod = 0; path = btrfs_alloc_path(); if (!path) return -ENOMEM; + trans = btrfs_join_transaction(root, 1); + btrfs_set_trans_block_group(trans, inode); + /* first lets see if we already have this xattr */ di = btrfs_lookup_xattr(trans, root, path, inode->i_ino, name, strlen(name), -1); @@ -119,12 +118,15 @@ static int do_setxattr(struct btrfs_trans_handle *trans, } ret = btrfs_delete_one_dir_name(trans, root, path, di); - BUG_ON(ret); + if (ret) + goto out; btrfs_release_path(root, path); /* if we don't have a value then we are removing the xattr */ - if (!value) + if (!value) { + mod = 1; goto out; + } } else { btrfs_release_path(root, path); @@ -136,45 +138,20 @@ static int do_setxattr(struct btrfs_trans_handle *trans, } /* ok we have to create a completely new xattr */ - ret = btrfs_insert_xattr_item(trans, root, path, inode->i_ino, - name, name_len, value, size); - BUG_ON(ret); -out: - btrfs_free_path(path); - return ret; -} - -int __btrfs_setxattr(struct btrfs_trans_handle *trans, - struct inode *inode, const char *name, - const void *value, size_t size, int flags) -{ - struct btrfs_root *root = BTRFS_I(inode)->root; - int ret; - - if (trans) - return do_setxattr(trans, inode, name, value, size, flags); - - ret = btrfs_reserve_metadata_space(root, 2); + ret = btrfs_insert_xattr_item(trans, root, name, strlen(name), + value, size, inode->i_ino); if (ret) - return ret; - - trans = btrfs_start_transaction(root, 1); - if (!trans) { - ret = -ENOMEM; goto out; - } - btrfs_set_trans_block_group(trans, inode); + mod = 1; - ret = do_setxattr(trans, inode, name, value, size, flags); - if (ret) - goto out; - - inode->i_ctime = CURRENT_TIME; - ret = btrfs_update_inode(trans, root, inode); - BUG_ON(ret); out: - btrfs_end_transaction_throttle(trans, root); - btrfs_unreserve_metadata_space(root, 2); + if (mod) { + inode->i_ctime = CURRENT_TIME; + ret = btrfs_update_inode(trans, root, inode); + } + + btrfs_end_transaction(trans, root); + btrfs_free_path(path); return ret; } @@ -337,9 +314,7 @@ int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value, if (size == 0) value = ""; /* empty EA, do not remove */ - - return __btrfs_setxattr(NULL, dentry->d_inode, name, value, size, - flags); + return __btrfs_setxattr(dentry->d_inode, name, value, size, flags); } int btrfs_removexattr(struct dentry *dentry, const char *name) @@ -354,13 +329,10 @@ int btrfs_removexattr(struct dentry *dentry, const char *name) if (!btrfs_is_valid_xattr(name)) return -EOPNOTSUPP; - - return __btrfs_setxattr(NULL, dentry->d_inode, name, NULL, 0, - XATTR_REPLACE); + return __btrfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE); } -int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, - struct inode *inode, struct inode *dir) +int btrfs_xattr_security_init(struct inode *inode, struct inode *dir) { int err; size_t len; @@ -382,7 +354,7 @@ int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, } else { strcpy(name, XATTR_SECURITY_PREFIX); strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); - err = __btrfs_setxattr(trans, inode, name, value, len, 0); + err = __btrfs_setxattr(inode, name, value, len, 0); kfree(name); } diff --git a/trunk/fs/btrfs/xattr.h b/trunk/fs/btrfs/xattr.h index 721efa0346e0..c71e9c3cf3f7 100644 --- a/trunk/fs/btrfs/xattr.h +++ b/trunk/fs/btrfs/xattr.h @@ -27,16 +27,15 @@ extern struct xattr_handler *btrfs_xattr_handlers[]; extern ssize_t __btrfs_getxattr(struct inode *inode, const char *name, void *buffer, size_t size); -extern int __btrfs_setxattr(struct btrfs_trans_handle *trans, - struct inode *inode, const char *name, - const void *value, size_t size, int flags); +extern int __btrfs_setxattr(struct inode *inode, const char *name, + const void *value, size_t size, int flags); + extern ssize_t btrfs_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size); extern int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags); extern int btrfs_removexattr(struct dentry *dentry, const char *name); -extern int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, - struct inode *inode, struct inode *dir); +extern int btrfs_xattr_security_init(struct inode *inode, struct inode *dir); #endif /* __XATTR__ */ diff --git a/trunk/fs/direct-io.c b/trunk/fs/direct-io.c index e82adc2debb7..4012885d027f 100644 --- a/trunk/fs/direct-io.c +++ b/trunk/fs/direct-io.c @@ -1206,7 +1206,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, * NOTE: filesystems with their own locking have to handle this * on their own. */ - if (flags & DIO_LOCKING) { + if (dio->flags & DIO_LOCKING) { if (unlikely((rw & WRITE) && retval < 0)) { loff_t isize = i_size_read(inode); if (end > isize) diff --git a/trunk/fs/ecryptfs/dentry.c b/trunk/fs/ecryptfs/dentry.c index 8f006a0d6076..2dda5ade75bc 100644 --- a/trunk/fs/ecryptfs/dentry.c +++ b/trunk/fs/ecryptfs/dentry.c @@ -62,7 +62,7 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) struct inode *lower_inode = ecryptfs_inode_to_lower(dentry->d_inode); - fsstack_copy_attr_all(dentry->d_inode, lower_inode); + fsstack_copy_attr_all(dentry->d_inode, lower_inode, NULL); } out: return rc; diff --git a/trunk/fs/ecryptfs/inode.c b/trunk/fs/ecryptfs/inode.c index 429ca0b3ba08..056fed62d0de 100644 --- a/trunk/fs/ecryptfs/inode.c +++ b/trunk/fs/ecryptfs/inode.c @@ -626,9 +626,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, lower_new_dir_dentry->d_inode, lower_new_dentry); if (rc) goto out_lock; - fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode); + fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL); if (new_dir != old_dir) - fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); + fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode, NULL); out_lock: unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); dput(lower_new_dentry->d_parent); @@ -967,7 +967,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) rc = notify_change(lower_dentry, ia); mutex_unlock(&lower_dentry->d_inode->i_mutex); out: - fsstack_copy_attr_all(inode, lower_inode); + fsstack_copy_attr_all(inode, lower_inode, NULL); return rc; } diff --git a/trunk/fs/ecryptfs/main.c b/trunk/fs/ecryptfs/main.c index 567bc4b9f70a..101fe4c7b1ee 100644 --- a/trunk/fs/ecryptfs/main.c +++ b/trunk/fs/ecryptfs/main.c @@ -189,7 +189,7 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, init_special_inode(inode, lower_inode->i_mode, lower_inode->i_rdev); dentry->d_op = &ecryptfs_dops; - fsstack_copy_attr_all(inode, lower_inode); + fsstack_copy_attr_all(inode, lower_inode, NULL); /* This size will be overwritten for real files w/ headers and * other metadata */ fsstack_copy_inode_size(inode, lower_inode); diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 632b02e34ec7..623a5cc3076a 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -826,9 +826,7 @@ static int de_thread(struct task_struct *tsk) attach_pid(tsk, PIDTYPE_PID, task_pid(leader)); transfer_pid(leader, tsk, PIDTYPE_PGID); transfer_pid(leader, tsk, PIDTYPE_SID); - list_replace_rcu(&leader->tasks, &tsk->tasks); - list_replace_init(&leader->sibling, &tsk->sibling); tsk->group_leader = tsk; leader->group_leader = tsk; @@ -1763,20 +1761,17 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) struct mm_struct *mm = current->mm; struct linux_binfmt * binfmt; struct inode * inode; + struct file * file; const struct cred *old_cred; struct cred *cred; int retval = 0; int flag = 0; int ispipe = 0; + unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; char **helper_argv = NULL; int helper_argc = 0; int dump_count = 0; static atomic_t core_dump_count = ATOMIC_INIT(0); - struct coredump_params cprm = { - .signr = signr, - .regs = regs, - .limit = current->signal->rlim[RLIMIT_CORE].rlim_cur, - }; audit_core_dumps(signr); @@ -1832,15 +1827,15 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) ispipe = format_corename(corename, signr); unlock_kernel(); - if ((!ispipe) && (cprm.limit < binfmt->min_coredump)) + if ((!ispipe) && (core_limit < binfmt->min_coredump)) goto fail_unlock; if (ispipe) { - if (cprm.limit == 0) { + if (core_limit == 0) { /* * Normally core limits are irrelevant to pipes, since * we're not writing to the file system, but we use - * cprm.limit of 0 here as a speacial value. Any + * core_limit of 0 here as a speacial value. Any * non-zero limit gets set to RLIM_INFINITY below, but * a limit of 0 skips the dump. This is a consistent * way to catch recursive crashes. We can still crash @@ -1873,25 +1868,25 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) goto fail_dropcount; } - cprm.limit = RLIM_INFINITY; + core_limit = RLIM_INFINITY; /* SIGPIPE can happen, but it's just never processed */ if (call_usermodehelper_pipe(helper_argv[0], helper_argv, NULL, - &cprm.file)) { + &file)) { printk(KERN_INFO "Core dump to %s pipe failed\n", corename); goto fail_dropcount; } } else - cprm.file = filp_open(corename, + file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, 0600); - if (IS_ERR(cprm.file)) + if (IS_ERR(file)) goto fail_dropcount; - inode = cprm.file->f_path.dentry->d_inode; + inode = file->f_path.dentry->d_inode; if (inode->i_nlink > 1) goto close_fail; /* multiple links - don't dump */ - if (!ispipe && d_unhashed(cprm.file->f_path.dentry)) + if (!ispipe && d_unhashed(file->f_path.dentry)) goto close_fail; /* AK: actually i see no reason to not allow this for named pipes etc., @@ -1904,22 +1899,21 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) */ if (inode->i_uid != current_fsuid()) goto close_fail; - if (!cprm.file->f_op) + if (!file->f_op) goto close_fail; - if (!cprm.file->f_op->write) + if (!file->f_op->write) goto close_fail; - if (!ispipe && - do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file) != 0) + if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0) goto close_fail; - retval = binfmt->core_dump(&cprm); + retval = binfmt->core_dump(signr, regs, file, core_limit); if (retval) current->signal->group_exit_code |= 0x80; close_fail: if (ispipe && core_pipe_limit) - wait_for_dump_helpers(cprm.file); - filp_close(cprm.file, NULL); + wait_for_dump_helpers(file); + filp_close(file, NULL); fail_dropcount: if (dump_count) atomic_dec(&core_dump_count); diff --git a/trunk/fs/ext4/Kconfig b/trunk/fs/ext4/Kconfig index 9acf7e808139..e5f6774846e4 100644 --- a/trunk/fs/ext4/Kconfig +++ b/trunk/fs/ext4/Kconfig @@ -2,6 +2,7 @@ config EXT4_FS tristate "The Extended 4 (ext4) filesystem" select JBD2 select CRC16 + select FS_JOURNAL_INFO help This is the next generation of the ext3 filesystem. diff --git a/trunk/fs/gfs2/Kconfig b/trunk/fs/gfs2/Kconfig index 4dcddf83326f..b192c661caa6 100644 --- a/trunk/fs/gfs2/Kconfig +++ b/trunk/fs/gfs2/Kconfig @@ -10,6 +10,7 @@ config GFS2_FS select SLOW_WORK select QUOTA select QUOTACTL + select FS_JOURNAL_INFO help A cluster filesystem. diff --git a/trunk/fs/gfs2/inode.c b/trunk/fs/gfs2/inode.c index 6e220f4eee7d..3ff32fa793da 100644 --- a/trunk/fs/gfs2/inode.c +++ b/trunk/fs/gfs2/inode.c @@ -125,7 +125,7 @@ static struct inode *gfs2_iget_skip(struct super_block *sb, * directory entry when gfs2_inode_lookup() is invoked. Part of the code * segment inside gfs2_inode_lookup code needs to get moved around. * - * Clears I_NEW as well. + * Clean up I_LOCK and I_NEW as well. **/ void gfs2_set_iop(struct inode *inode) diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index 03dfeb2e3928..06c1f02de611 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -113,7 +113,7 @@ static void wake_up_inode(struct inode *inode) * Prevent speculative execution through spin_unlock(&inode_lock); */ smp_mb(); - wake_up_bit(&inode->i_state, __I_NEW); + wake_up_bit(&inode->i_state, __I_LOCK); } /** @@ -690,17 +690,17 @@ void unlock_new_inode(struct inode *inode) } #endif /* - * This is special! We do not need the spinlock when clearing I_NEW, + * This is special! We do not need the spinlock when clearing I_LOCK, * because we're guaranteed that nobody else tries to do anything about * the state of the inode when it is locked, as we just created it (so - * there can be no old holders that haven't tested I_NEW). + * there can be no old holders that haven't tested I_LOCK). * However we must emit the memory barrier so that other CPUs reliably - * see the clearing of I_NEW after the other inode initialisation has + * see the clearing of I_LOCK after the other inode initialisation has * completed. */ smp_mb(); - WARN_ON(!(inode->i_state & I_NEW)); - inode->i_state &= ~I_NEW; + WARN_ON((inode->i_state & (I_LOCK|I_NEW)) != (I_LOCK|I_NEW)); + inode->i_state &= ~(I_LOCK|I_NEW); wake_up_inode(inode); } EXPORT_SYMBOL(unlock_new_inode); @@ -731,7 +731,7 @@ static struct inode *get_new_inode(struct super_block *sb, goto set_failed; __inode_add_to_lists(sb, head, inode); - inode->i_state = I_NEW; + inode->i_state = I_LOCK|I_NEW; spin_unlock(&inode_lock); /* Return the locked inode with I_NEW set, the @@ -778,7 +778,7 @@ static struct inode *get_new_inode_fast(struct super_block *sb, if (!old) { inode->i_ino = ino; __inode_add_to_lists(sb, head, inode); - inode->i_state = I_NEW; + inode->i_state = I_LOCK|I_NEW; spin_unlock(&inode_lock); /* Return the locked inode with I_NEW set, the @@ -1083,7 +1083,7 @@ int insert_inode_locked(struct inode *inode) ino_t ino = inode->i_ino; struct hlist_head *head = inode_hashtable + hash(sb, ino); - inode->i_state |= I_NEW; + inode->i_state |= I_LOCK|I_NEW; while (1) { struct hlist_node *node; struct inode *old = NULL; @@ -1120,7 +1120,7 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval, struct super_block *sb = inode->i_sb; struct hlist_head *head = inode_hashtable + hash(sb, hashval); - inode->i_state |= I_NEW; + inode->i_state |= I_LOCK|I_NEW; while (1) { struct hlist_node *node; @@ -1510,7 +1510,7 @@ EXPORT_SYMBOL(inode_wait); * until the deletion _might_ have completed. Callers are responsible * to recheck inode state. * - * It doesn't matter if I_NEW is not set initially, a call to + * It doesn't matter if I_LOCK is not set initially, a call to * wake_up_inode() after removing from the hash list will DTRT. * * This is called with inode_lock held. @@ -1518,8 +1518,8 @@ EXPORT_SYMBOL(inode_wait); static void __wait_on_freeing_inode(struct inode *inode) { wait_queue_head_t *wq; - DEFINE_WAIT_BIT(wait, &inode->i_state, __I_NEW); - wq = bit_waitqueue(&inode->i_state, __I_NEW); + DEFINE_WAIT_BIT(wait, &inode->i_state, __I_LOCK); + wq = bit_waitqueue(&inode->i_state, __I_LOCK); prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE); spin_unlock(&inode_lock); schedule(); diff --git a/trunk/fs/jbd/Kconfig b/trunk/fs/jbd/Kconfig index 4e28beeed157..a8408983abd4 100644 --- a/trunk/fs/jbd/Kconfig +++ b/trunk/fs/jbd/Kconfig @@ -1,5 +1,6 @@ config JBD tristate + select FS_JOURNAL_INFO help This is a generic journalling layer for block devices. It is currently used by the ext3 file system, but it could also be diff --git a/trunk/fs/jbd2/Kconfig b/trunk/fs/jbd2/Kconfig index f32f346f4b0a..0f7d1ceafdfd 100644 --- a/trunk/fs/jbd2/Kconfig +++ b/trunk/fs/jbd2/Kconfig @@ -1,6 +1,7 @@ config JBD2 tristate select CRC32 + select FS_JOURNAL_INFO help This is a generic journaling layer for block devices that support both 32-bit and 64-bit block numbers. It is currently used by diff --git a/trunk/fs/jfs/jfs_txnmgr.c b/trunk/fs/jfs/jfs_txnmgr.c index d945ea76b445..f26e4d03ada5 100644 --- a/trunk/fs/jfs/jfs_txnmgr.c +++ b/trunk/fs/jfs/jfs_txnmgr.c @@ -1292,7 +1292,7 @@ int txCommit(tid_t tid, /* transaction identifier */ */ /* * I believe this code is no longer needed. Splitting I_LOCK - * into two bits, I_NEW and I_SYNC should prevent this + * into two bits, I_LOCK and I_SYNC should prevent this * deadlock as well. But since I don't have a JFS testload * to verify this, only a trivial s/I_LOCK/I_SYNC/ was done. * Joern diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index dad4b80257db..d2783c8a770b 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -1764,7 +1764,7 @@ struct file *do_filp_open(int dfd, const char *pathname, path_to_nameidata(&path, &nd); error = -EISDIR; - if (S_ISDIR(path.dentry->d_inode->i_mode)) + if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) goto exit; ok: /* diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index 7d70d63ceb29..faab1273281e 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -2068,7 +2068,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, * create_mnt_ns - creates a private namespace and adds a root filesystem * @mnt: pointer to the new root filesystem mountpoint */ -struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt) +static struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt) { struct mnt_namespace *new_ns; @@ -2080,7 +2080,6 @@ struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt) } return new_ns; } -EXPORT_SYMBOL(create_mnt_ns); SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, char __user *, type, unsigned long, flags, void __user *, data) diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index ce907efc5508..d5b112bcf3de 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -2648,21 +2648,13 @@ static void nfs_fix_devname(const struct path *path, struct vfsmount *mnt) static int nfs_follow_remote_path(struct vfsmount *root_mnt, const char *export_path, struct vfsmount *mnt_target) { - struct mnt_namespace *ns_private; struct nameidata nd; struct super_block *s; int ret; - ns_private = create_mnt_ns(root_mnt); - ret = PTR_ERR(ns_private); - if (IS_ERR(ns_private)) - goto out_mntput; - ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt, export_path, LOOKUP_FOLLOW, &nd); - put_mnt_ns(ns_private); - if (ret != 0) goto out_err; diff --git a/trunk/fs/nilfs2/Kconfig b/trunk/fs/nilfs2/Kconfig index 251da07b2a1d..1225af7b2166 100644 --- a/trunk/fs/nilfs2/Kconfig +++ b/trunk/fs/nilfs2/Kconfig @@ -2,6 +2,7 @@ config NILFS2_FS tristate "NILFS2 file system support (EXPERIMENTAL)" depends on EXPERIMENTAL select CRC32 + select FS_JOURNAL_INFO help NILFS2 is a log-structured file system (LFS) supporting continuous snapshotting. In addition to versioning capability of the entire diff --git a/trunk/fs/ntfs/inode.c b/trunk/fs/ntfs/inode.c index dc2505abb6d7..9938034762cc 100644 --- a/trunk/fs/ntfs/inode.c +++ b/trunk/fs/ntfs/inode.c @@ -530,7 +530,7 @@ static int ntfs_is_extended_system_file(ntfs_attr_search_ctx *ctx) * the ntfs inode. * * Q: What locks are held when the function is called? - * A: i_state has I_NEW set, hence the inode is locked, also + * A: i_state has I_LOCK set, hence the inode is locked, also * i_count is set to 1, so it is not going to go away * i_flags is set to 0 and we have no business touching it. Only an ioctl() * is allowed to write to them. We should of course be honouring them but @@ -1207,7 +1207,7 @@ static int ntfs_read_locked_inode(struct inode *vi) * necessary fields in @vi as well as initializing the ntfs inode. * * Q: What locks are held when the function is called? - * A: i_state has I_NEW set, hence the inode is locked, also + * A: i_state has I_LOCK set, hence the inode is locked, also * i_count is set to 1, so it is not going to go away * * Return 0 on success and -errno on error. In the error case, the inode will @@ -1474,7 +1474,7 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) * normal directory inodes. * * Q: What locks are held when the function is called? - * A: i_state has I_NEW set, hence the inode is locked, also + * A: i_state has I_LOCK set, hence the inode is locked, also * i_count is set to 1, so it is not going to go away * * Return 0 on success and -errno on error. In the error case, the inode will diff --git a/trunk/fs/pipe.c b/trunk/fs/pipe.c index 37ba29ff3158..43d79da5c57e 100644 --- a/trunk/fs/pipe.c +++ b/trunk/fs/pipe.c @@ -906,6 +906,17 @@ void free_pipe_info(struct inode *inode) } static struct vfsmount *pipe_mnt __read_mostly; +static int pipefs_delete_dentry(struct dentry *dentry) +{ + /* + * At creation time, we pretended this dentry was hashed + * (by clearing DCACHE_UNHASHED bit in d_flags) + * At delete time, we restore the truth : not hashed. + * (so that dput() can proceed correctly) + */ + dentry->d_flags |= DCACHE_UNHASHED; + return 0; +} /* * pipefs_dname() is called from d_path(). @@ -917,6 +928,7 @@ static char *pipefs_dname(struct dentry *dentry, char *buffer, int buflen) } static const struct dentry_operations pipefs_dentry_operations = { + .d_delete = pipefs_delete_dentry, .d_dname = pipefs_dname, }; @@ -977,6 +989,12 @@ struct file *create_write_pipe(int flags) path.mnt = mntget(pipe_mnt); path.dentry->d_op = &pipefs_dentry_operations; + /* + * We dont want to publish this dentry into global dentry hash table. + * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED + * This permits a working /proc/$pid/fd/XXX on pipes + */ + path.dentry->d_flags &= ~DCACHE_UNHASHED; d_instantiate(path.dentry, inode); err = -ENFILE; diff --git a/trunk/fs/ramfs/file-nommu.c b/trunk/fs/ramfs/file-nommu.c index 2efc57173fd7..32fae4040ebf 100644 --- a/trunk/fs/ramfs/file-nommu.c +++ b/trunk/fs/ramfs/file-nommu.c @@ -60,7 +60,7 @@ const struct inode_operations ramfs_file_inode_operations = { */ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) { - unsigned long npages, xpages, loop; + unsigned long npages, xpages, loop, limit; struct page *pages; unsigned order; void *data; diff --git a/trunk/fs/reiserfs/Kconfig b/trunk/fs/reiserfs/Kconfig index 513f431038f9..ac7cd75c86f8 100644 --- a/trunk/fs/reiserfs/Kconfig +++ b/trunk/fs/reiserfs/Kconfig @@ -1,6 +1,7 @@ config REISERFS_FS tristate "Reiserfs support" select CRC32 + select FS_JOURNAL_INFO help Stores not just filenames but the files themselves in a balanced tree. Uses journalling. diff --git a/trunk/fs/reiserfs/inode.c b/trunk/fs/reiserfs/inode.c index 290ae38fca8a..3a28e7751b3c 100644 --- a/trunk/fs/reiserfs/inode.c +++ b/trunk/fs/reiserfs/inode.c @@ -2538,12 +2538,6 @@ static int reiserfs_writepage(struct page *page, struct writeback_control *wbc) return reiserfs_write_full_page(page, wbc); } -static void reiserfs_truncate_failed_write(struct inode *inode) -{ - truncate_inode_pages(inode->i_mapping, inode->i_size); - reiserfs_truncate_file(inode, 0); -} - static int reiserfs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, @@ -2610,8 +2604,6 @@ static int reiserfs_write_begin(struct file *file, if (ret) { unlock_page(page); page_cache_release(page); - /* Truncate allocated blocks */ - reiserfs_truncate_failed_write(inode); } return ret; } @@ -2709,7 +2701,9 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, ** transaction tracking stuff when the size changes. So, we have ** to do the i_size updates here. */ - if (pos + copied > inode->i_size) { + pos += copied; + + if (pos > inode->i_size) { struct reiserfs_transaction_handle myth; lock_depth = reiserfs_write_lock_once(inode->i_sb); locked = true; @@ -2727,7 +2721,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, goto journal_error; reiserfs_update_inode_transaction(inode); - inode->i_size = pos + copied; + inode->i_size = pos; /* * this will just nest into our transaction. It's important * to use mark_inode_dirty so the inode gets pushed around on the @@ -2757,10 +2751,6 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, reiserfs_write_unlock_once(inode->i_sb, lock_depth); unlock_page(page); page_cache_release(page); - - if (pos + len > inode->i_size) - reiserfs_truncate_failed_write(inode); - return ret == 0 ? copied : ret; journal_error: diff --git a/trunk/fs/stack.c b/trunk/fs/stack.c index 4a6f7f440658..67716f6a1a4a 100644 --- a/trunk/fs/stack.c +++ b/trunk/fs/stack.c @@ -7,63 +7,18 @@ * This function cannot be inlined since i_size_{read,write} is rather * heavy-weight on 32-bit systems */ -void fsstack_copy_inode_size(struct inode *dst, struct inode *src) +void fsstack_copy_inode_size(struct inode *dst, const struct inode *src) { - loff_t i_size; - blkcnt_t i_blocks; - - /* - * i_size_read() includes its own seqlocking and protection from - * preemption (see include/linux/fs.h): we need nothing extra for - * that here, and prefer to avoid nesting locks than attempt to keep - * i_size and i_blocks in sync together. - */ - i_size = i_size_read(src); - - /* - * But if CONFIG_LBDAF (on 32-bit), we ought to make an effort to - * keep the two halves of i_blocks in sync despite SMP or PREEMPT - - * though stat's generic_fillattr() doesn't bother, and we won't be - * applying quotas (where i_blocks does become important) at the - * upper level. - * - * We don't actually know what locking is used at the lower level; - * but if it's a filesystem that supports quotas, it will be using - * i_lock as in inode_add_bytes(). tmpfs uses other locking, and - * its 32-bit is (just) able to exceed 2TB i_size with the aid of - * holes; but its i_blocks cannot carry into the upper long without - * almost 2TB swap - let's ignore that case. - */ - if (sizeof(i_blocks) > sizeof(long)) - spin_lock(&src->i_lock); - i_blocks = src->i_blocks; - if (sizeof(i_blocks) > sizeof(long)) - spin_unlock(&src->i_lock); - - /* - * If CONFIG_SMP or CONFIG_PREEMPT on 32-bit, it's vital for - * fsstack_copy_inode_size() to hold some lock around - * i_size_write(), otherwise i_size_read() may spin forever (see - * include/linux/fs.h). We don't necessarily hold i_mutex when this - * is called, so take i_lock for that case. - * - * And if CONFIG_LBADF (on 32-bit), continue our effort to keep the - * two halves of i_blocks in sync despite SMP or PREEMPT: use i_lock - * for that case too, and do both at once by combining the tests. - * - * There is none of this locking overhead in the 64-bit case. - */ - if (sizeof(i_size) > sizeof(long) || sizeof(i_blocks) > sizeof(long)) - spin_lock(&dst->i_lock); - i_size_write(dst, i_size); - dst->i_blocks = i_blocks; - if (sizeof(i_size) > sizeof(long) || sizeof(i_blocks) > sizeof(long)) - spin_unlock(&dst->i_lock); + i_size_write(dst, i_size_read((struct inode *)src)); + dst->i_blocks = src->i_blocks; } EXPORT_SYMBOL_GPL(fsstack_copy_inode_size); -/* copy all attributes */ -void fsstack_copy_attr_all(struct inode *dest, const struct inode *src) +/* copy all attributes; get_nlinks is optional way to override the i_nlink + * copying + */ +void fsstack_copy_attr_all(struct inode *dest, const struct inode *src, + int (*get_nlinks)(struct inode *)) { dest->i_mode = src->i_mode; dest->i_uid = src->i_uid; @@ -74,6 +29,14 @@ void fsstack_copy_attr_all(struct inode *dest, const struct inode *src) dest->i_ctime = src->i_ctime; dest->i_blkbits = src->i_blkbits; dest->i_flags = src->i_flags; - dest->i_nlink = src->i_nlink; + + /* + * Update the nlinks AFTER updating the above fields, because the + * get_links callback may depend on them. + */ + if (!get_nlinks) + dest->i_nlink = src->i_nlink; + else + dest->i_nlink = (*get_nlinks)(dest); } EXPORT_SYMBOL_GPL(fsstack_copy_attr_all); diff --git a/trunk/fs/sync.c b/trunk/fs/sync.c index 418727a2a239..36752a683481 100644 --- a/trunk/fs/sync.c +++ b/trunk/fs/sync.c @@ -355,7 +355,6 @@ SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes, { int ret; struct file *file; - struct address_space *mapping; loff_t endbyte; /* inclusive */ int fput_needed; umode_t i_mode; @@ -406,28 +405,7 @@ SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes, !S_ISLNK(i_mode)) goto out_put; - mapping = file->f_mapping; - if (!mapping) { - ret = -EINVAL; - goto out_put; - } - - ret = 0; - if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) { - ret = filemap_fdatawait_range(mapping, offset, endbyte); - if (ret < 0) - goto out_put; - } - - if (flags & SYNC_FILE_RANGE_WRITE) { - ret = filemap_fdatawrite_range(mapping, offset, endbyte); - if (ret < 0) - goto out_put; - } - - if (flags & SYNC_FILE_RANGE_WAIT_AFTER) - ret = filemap_fdatawait_range(mapping, offset, endbyte); - + ret = do_sync_mapping_range(file->f_mapping, offset, endbyte, flags); out_put: fput_light(file, fput_needed); out: @@ -459,3 +437,38 @@ asmlinkage long SyS_sync_file_range2(long fd, long flags, } SYSCALL_ALIAS(sys_sync_file_range2, SyS_sync_file_range2); #endif + +/* + * `endbyte' is inclusive + */ +int do_sync_mapping_range(struct address_space *mapping, loff_t offset, + loff_t endbyte, unsigned int flags) +{ + int ret; + + if (!mapping) { + ret = -EINVAL; + goto out; + } + + ret = 0; + if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) { + ret = filemap_fdatawait_range(mapping, offset, endbyte); + if (ret < 0) + goto out; + } + + if (flags & SYNC_FILE_RANGE_WRITE) { + ret = __filemap_fdatawrite_range(mapping, offset, endbyte, + WB_SYNC_ALL); + if (ret < 0) + goto out; + } + + if (flags & SYNC_FILE_RANGE_WAIT_AFTER) { + ret = filemap_fdatawait_range(mapping, offset, endbyte); + } +out: + return ret; +} +EXPORT_SYMBOL_GPL(do_sync_mapping_range); diff --git a/trunk/fs/ubifs/file.c b/trunk/fs/ubifs/file.c index 16a6444330ec..39849f887e72 100644 --- a/trunk/fs/ubifs/file.c +++ b/trunk/fs/ubifs/file.c @@ -45,7 +45,7 @@ * * Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the * read-ahead path does not lock it ("sys_read -> generic_file_aio_read -> - * ondemand_readahead -> readpage"). In case of readahead, @I_SYNC flag is not + * ondemand_readahead -> readpage"). In case of readahead, @I_LOCK flag is not * set as well. However, UBIFS disables readahead. */ diff --git a/trunk/fs/xfs/linux-2.6/xfs_iops.c b/trunk/fs/xfs/linux-2.6/xfs_iops.c index 225946012d0b..1d5b298ba8b2 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_iops.c +++ b/trunk/fs/xfs/linux-2.6/xfs_iops.c @@ -794,7 +794,7 @@ xfs_setup_inode( struct inode *inode = &ip->i_vnode; inode->i_ino = ip->i_ino; - inode->i_state = I_NEW; + inode->i_state = I_NEW|I_LOCK; inode_add_to_lists(ip->i_mount->m_super, inode); inode->i_mode = ip->i_d.di_mode; diff --git a/trunk/fs/xfs/xfs_iget.c b/trunk/fs/xfs/xfs_iget.c index fa402a6bbbcf..0de36c2a46f1 100644 --- a/trunk/fs/xfs/xfs_iget.c +++ b/trunk/fs/xfs/xfs_iget.c @@ -91,7 +91,7 @@ xfs_inode_alloc( ip->i_new_size = 0; /* prevent anyone from using this yet */ - VFS_I(ip)->i_state = I_NEW; + VFS_I(ip)->i_state = I_NEW|I_LOCK; return ip; } @@ -217,7 +217,7 @@ xfs_iget_cache_hit( trace_xfs_iget_reclaim(ip); goto out_error; } - inode->i_state = I_NEW; + inode->i_state = I_LOCK|I_NEW; } else { /* If the VFS inode is being torn down, pause and try again. */ if (!igrab(inode)) { diff --git a/trunk/include/asm-generic/fcntl.h b/trunk/include/asm-generic/fcntl.h index fcd268ce0674..681ddf3e844c 100644 --- a/trunk/include/asm-generic/fcntl.h +++ b/trunk/include/asm-generic/fcntl.h @@ -51,7 +51,7 @@ #endif /* - * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using + * Before Linux 2.6.32 only O_DSYNC semantics were implemented, but using * the O_SYNC flag. We continue to use the existing numerical value * for O_DSYNC semantics now, but using the correct symbolic name for it. * This new value is used to request true Posix O_SYNC semantics. It is diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index 756f831cbdd5..f72914db2a11 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -118,7 +118,6 @@ header-y += mtio.h header-y += ncp_no.h header-y += neighbour.h header-y += net_dropmon.h -header-y += net_tstamp.h header-y += netfilter_arp.h header-y += netrom.h header-y += nfs2.h diff --git a/trunk/include/linux/backlight.h b/trunk/include/linux/backlight.h index 8c4f884db6b4..0f5f57858a23 100644 --- a/trunk/include/linux/backlight.h +++ b/trunk/include/linux/backlight.h @@ -36,18 +36,18 @@ struct backlight_device; struct fb_info; struct backlight_ops { - const unsigned int options; + unsigned int options; #define BL_CORE_SUSPENDRESUME (1 << 0) /* Notify the backlight driver some property has changed */ - int (* const update_status)(struct backlight_device *); + int (*update_status)(struct backlight_device *); /* Return the current backlight brightness (accounting for power, fb_blank etc.) */ - int (* const get_brightness)(struct backlight_device *); + int (*get_brightness)(struct backlight_device *); /* Check if given framebuffer device is the one bound to this backlight; return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */ - int (* const check_fb)(struct fb_info *); + int (*check_fb)(struct fb_info *); }; /* This structure defines all the properties of a backlight */ @@ -86,7 +86,7 @@ struct backlight_device { registered this device has been unloaded, and if class_get_devdata() points to something in the body of that driver, it is also invalid. */ struct mutex ops_lock; - const struct backlight_ops *ops; + struct backlight_ops *ops; /* The framebuffer notifier block */ struct notifier_block fb_notif; @@ -103,7 +103,7 @@ static inline void backlight_update_status(struct backlight_device *bd) } extern struct backlight_device *backlight_device_register(const char *name, - struct device *dev, void *devdata, const struct backlight_ops *ops); + struct device *dev, void *devdata, struct backlight_ops *ops); extern void backlight_device_unregister(struct backlight_device *bd); extern void backlight_force_update(struct backlight_device *bd, enum backlight_update_reason reason); diff --git a/trunk/include/linux/binfmts.h b/trunk/include/linux/binfmts.h index cd4349bdc34e..aece486ac734 100644 --- a/trunk/include/linux/binfmts.h +++ b/trunk/include/linux/binfmts.h @@ -68,14 +68,6 @@ struct linux_binprm{ #define BINPRM_MAX_RECURSION 4 -/* Function parameter for binfmt->coredump */ -struct coredump_params { - long signr; - struct pt_regs *regs; - struct file *file; - unsigned long limit; -}; - /* * This structure defines the functions that are used to load the binary formats that * linux accepts. @@ -85,7 +77,7 @@ struct linux_binfmt { struct module *module; int (*load_binary)(struct linux_binprm *, struct pt_regs * regs); int (*load_shlib)(struct file *); - int (*core_dump)(struct coredump_params *cprm); + int (*core_dump)(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); unsigned long min_coredump; /* minimal dump size */ int hasvdso; }; diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index cca191933ff6..66bc0a54b284 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -1095,6 +1095,10 @@ struct file_lock { extern void send_sigio(struct fown_struct *fown, int fd, int band); +/* fs/sync.c */ +extern int do_sync_mapping_range(struct address_space *mapping, loff_t offset, + loff_t endbyte, unsigned int flags); + #ifdef CONFIG_FILE_LOCKING extern int fcntl_getlk(struct file *, struct flock __user *); extern int fcntl_setlk(unsigned int, struct file *, unsigned int, @@ -1587,7 +1591,7 @@ struct super_operations { * until that flag is cleared. I_WILL_FREE, I_FREEING and I_CLEAR are set at * various stages of removing an inode. * - * Two bits are used for locking and completion notification, I_NEW and I_SYNC. + * Two bits are used for locking and completion notification, I_LOCK and I_SYNC. * * I_DIRTY_SYNC Inode is dirty, but doesn't have to be written on * fdatasync(). i_atime is the usual cause. @@ -1596,14 +1600,8 @@ struct super_operations { * don't have to write inode on fdatasync() when only * mtime has changed in it. * I_DIRTY_PAGES Inode has dirty pages. Inode itself may be clean. - * I_NEW Serves as both a mutex and completion notification. - * New inodes set I_NEW. If two processes both create - * the same inode, one of them will release its inode and - * wait for I_NEW to be released before returning. - * Inodes in I_WILL_FREE, I_FREEING or I_CLEAR state can - * also cause waiting on I_NEW, without I_NEW actually - * being set. find_inode() uses this to prevent returning - * nearly-dead inodes. + * I_NEW get_new_inode() sets i_state to I_LOCK|I_NEW. Both + * are cleared by unlock_new_inode(), called from iget(). * I_WILL_FREE Must be set when calling write_inode_now() if i_count * is zero. I_FREEING must be set when I_WILL_FREE is * cleared. @@ -1617,11 +1615,20 @@ struct super_operations { * prohibited for many purposes. iget() must wait for * the inode to be completely released, then create it * anew. Other functions will just ignore such inodes, - * if appropriate. I_NEW is used for waiting. + * if appropriate. I_LOCK is used for waiting. * - * I_SYNC Synchonized write of dirty inode data. The bits is - * set during data writeback, and cleared with a wakeup - * on the bit address once it is done. + * I_LOCK Serves as both a mutex and completion notification. + * New inodes set I_LOCK. If two processes both create + * the same inode, one of them will release its inode and + * wait for I_LOCK to be released before returning. + * Inodes in I_WILL_FREE, I_FREEING or I_CLEAR state can + * also cause waiting on I_LOCK, without I_LOCK actually + * being set. find_inode() uses this to prevent returning + * nearly-dead inodes. + * I_SYNC Similar to I_LOCK, but limited in scope to writeback + * of inode dirty data. Having a separate lock for this + * purpose reduces latency and prevents some filesystem- + * specific deadlocks. * * Q: What is the difference between I_WILL_FREE and I_FREEING? * Q: igrab() only checks on (I_FREEING|I_WILL_FREE). Should it also check on @@ -1630,12 +1637,13 @@ struct super_operations { #define I_DIRTY_SYNC 1 #define I_DIRTY_DATASYNC 2 #define I_DIRTY_PAGES 4 -#define __I_NEW 3 -#define I_NEW (1 << __I_NEW) +#define I_NEW 8 #define I_WILL_FREE 16 #define I_FREEING 32 #define I_CLEAR 64 -#define __I_SYNC 7 +#define __I_LOCK 7 +#define I_LOCK (1 << __I_LOCK) +#define __I_SYNC 8 #define I_SYNC (1 << __I_SYNC) #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) diff --git a/trunk/include/linux/fs_stack.h b/trunk/include/linux/fs_stack.h index da317c7163ab..bb516ceeefc9 100644 --- a/trunk/include/linux/fs_stack.h +++ b/trunk/include/linux/fs_stack.h @@ -8,8 +8,10 @@ #include /* externs for fs/stack.c */ -extern void fsstack_copy_attr_all(struct inode *dest, const struct inode *src); -extern void fsstack_copy_inode_size(struct inode *dst, struct inode *src); +extern void fsstack_copy_attr_all(struct inode *dest, const struct inode *src, + int (*get_nlinks)(struct inode *)); + +extern void fsstack_copy_inode_size(struct inode *dst, const struct inode *src); /* inlines */ static inline void fsstack_copy_attr_atime(struct inode *dest, diff --git a/trunk/include/linux/init_task.h b/trunk/include/linux/init_task.h index abec69b63d7e..5ed8b9c50355 100644 --- a/trunk/include/linux/init_task.h +++ b/trunk/include/linux/init_task.h @@ -111,6 +111,12 @@ extern struct cred init_cred; # define INIT_PERF_EVENTS(tsk) #endif +#ifdef CONFIG_FS_JOURNAL_INFO +#define INIT_JOURNAL_INFO .journal_info = NULL, +#else +#define INIT_JOURNAL_INFO +#endif + /* * INIT_TASK is used to set up the first task table, touch at * your own risk!. Base=0, limit=0x1fffff (=2MB) @@ -162,7 +168,6 @@ extern struct cred init_cred; .signal = {{0}}}, \ .blocked = {{0}}, \ .alloc_lock = __SPIN_LOCK_UNLOCKED(tsk.alloc_lock), \ - .journal_info = NULL, \ .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ .fs_excl = ATOMIC_INIT(0), \ .pi_lock = __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock), \ @@ -173,6 +178,7 @@ extern struct cred init_cred; [PIDTYPE_SID] = INIT_PID_LINK(PIDTYPE_SID), \ }, \ .dirties = INIT_PROP_LOCAL_SINGLE(dirties), \ + INIT_JOURNAL_INFO \ INIT_IDS \ INIT_PERF_EVENTS(tsk) \ INIT_TRACE_IRQFLAGS \ diff --git a/trunk/include/linux/kmemleak.h b/trunk/include/linux/kmemleak.h index 99d9a6766f7e..3c7497d46ee9 100644 --- a/trunk/include/linux/kmemleak.h +++ b/trunk/include/linux/kmemleak.h @@ -32,7 +32,8 @@ extern void kmemleak_padding(const void *ptr, unsigned long offset, size_t size) __ref; extern void kmemleak_not_leak(const void *ptr) __ref; extern void kmemleak_ignore(const void *ptr) __ref; -extern void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) __ref; +extern void kmemleak_scan_area(const void *ptr, unsigned long offset, + size_t length, gfp_t gfp) __ref; extern void kmemleak_no_scan(const void *ptr) __ref; static inline void kmemleak_alloc_recursive(const void *ptr, size_t size, @@ -83,7 +84,8 @@ static inline void kmemleak_not_leak(const void *ptr) static inline void kmemleak_ignore(const void *ptr) { } -static inline void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) +static inline void kmemleak_scan_area(const void *ptr, unsigned long offset, + size_t length, gfp_t gfp) { } static inline void kmemleak_erase(void **ptr) diff --git a/trunk/include/linux/leds-lp3944.h b/trunk/include/linux/leds-lp3944.h index 2618aa9063bc..afc9f9fd70f5 100644 --- a/trunk/include/linux/leds-lp3944.h +++ b/trunk/include/linux/leds-lp3944.h @@ -12,6 +12,9 @@ #ifndef __LINUX_LEDS_LP3944_H #define __LINUX_LEDS_LP3944_H +#include +#include + #define LP3944_LED0 0 #define LP3944_LED1 1 #define LP3944_LED2 2 diff --git a/trunk/include/linux/leds-pca9532.h b/trunk/include/linux/leds-pca9532.h index f158eb1149aa..96eea90f01a8 100644 --- a/trunk/include/linux/leds-pca9532.h +++ b/trunk/include/linux/leds-pca9532.h @@ -32,7 +32,7 @@ struct pca9532_led { struct i2c_client *client; char *name; struct led_classdev ldev; - struct work_struct work; + struct work_struct work; enum pca9532_type type; enum pca9532_state state; }; diff --git a/trunk/include/linux/leds-regulator.h b/trunk/include/linux/leds-regulator.h deleted file mode 100644 index 5a8eb389aab8..000000000000 --- a/trunk/include/linux/leds-regulator.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * leds-regulator.h - platform data structure for regulator driven LEDs. - * - * Copyright (C) 2009 Antonio Ospite - * - * 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 __LINUX_LEDS_REGULATOR_H -#define __LINUX_LEDS_REGULATOR_H - -/* - * Use "vled" as supply id when declaring the regulator consumer: - * - * static struct regulator_consumer_supply pcap_regulator_VVIB_consumers [] = { - * { .dev_name = "leds-regulator.0", supply = "vled" }, - * }; - * - * If you have several regulator driven LEDs, you can append a numerical id to - * .dev_name as done above, and use the same id when declaring the platform - * device: - * - * static struct led_regulator_platform_data a780_vibrator_data = { - * .name = "a780::vibrator", - * }; - * - * static struct platform_device a780_vibrator = { - * .name = "leds-regulator", - * .id = 0, - * .dev = { - * .platform_data = &a780_vibrator_data, - * }, - * }; - */ - -#include - -struct led_regulator_platform_data { - char *name; /* LED name as expected by LED class */ - enum led_brightness brightness; /* initial brightness value */ -}; - -#endif /* __LINUX_LEDS_REGULATOR_H */ diff --git a/trunk/include/linux/mfd/wm831x/pdata.h b/trunk/include/linux/mfd/wm831x/pdata.h index fd322aca33ba..415c228743d5 100644 --- a/trunk/include/linux/mfd/wm831x/pdata.h +++ b/trunk/include/linux/mfd/wm831x/pdata.h @@ -41,23 +41,6 @@ struct wm831x_battery_pdata { int timeout; /** Charge cycle timeout, in minutes */ }; -/** - * Configuration for the WM831x DC-DC BuckWise convertors. This - * should be passed as driver_data in the regulator_init_data. - * - * Currently all the configuration is for the fast DVS switching - * support of the devices. This allows MFPs on the device to be - * configured as an input to switch between two output voltages, - * allowing voltage transitions without the expense of an access over - * I2C or SPI buses. - */ -struct wm831x_buckv_pdata { - int dvs_gpio; /** CPU GPIO to use for DVS switching */ - int dvs_control_src; /** Hardware DVS source to use (1 or 2) */ - int dvs_init_state; /** DVS state to expect on startup */ - int dvs_state_gpio; /** CPU GPIO to use for monitoring status */ -}; - /* Sources for status LED configuration. Values are register values * plus 1 to allow for a zero default for preserve. */ diff --git a/trunk/include/linux/mmdebug.h b/trunk/include/linux/mmdebug.h index ee24ef8ab616..8a5509877192 100644 --- a/trunk/include/linux/mmdebug.h +++ b/trunk/include/linux/mmdebug.h @@ -1,6 +1,8 @@ #ifndef LINUX_MM_DEBUG_H #define LINUX_MM_DEBUG_H 1 +#include + #ifdef CONFIG_DEBUG_VM #define VM_BUG_ON(cond) BUG_ON(cond) #else diff --git a/trunk/include/linux/mmzone.h b/trunk/include/linux/mmzone.h index 30fe668c2542..6f7561730d88 100644 --- a/trunk/include/linux/mmzone.h +++ b/trunk/include/linux/mmzone.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/include/linux/mnt_namespace.h b/trunk/include/linux/mnt_namespace.h index d74785c2393a..d9ebf1037dfa 100644 --- a/trunk/include/linux/mnt_namespace.h +++ b/trunk/include/linux/mnt_namespace.h @@ -23,7 +23,6 @@ struct proc_mounts { struct fs_struct; -extern struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt); extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *, struct fs_struct *); extern void put_mnt_ns(struct mnt_namespace *ns); diff --git a/trunk/include/linux/page-flags.h b/trunk/include/linux/page-flags.h index 5b59f35dcb8f..feee2ba8d06a 100644 --- a/trunk/include/linux/page-flags.h +++ b/trunk/include/linux/page-flags.h @@ -8,7 +8,7 @@ #include #ifndef __GENERATING_BOUNDS_H #include -#include +#include #endif /* !__GENERATING_BOUNDS_H */ /* diff --git a/trunk/include/linux/pwm_backlight.h b/trunk/include/linux/pwm_backlight.h index 01b3d759f1fc..7a9754c96775 100644 --- a/trunk/include/linux/pwm_backlight.h +++ b/trunk/include/linux/pwm_backlight.h @@ -10,7 +10,7 @@ struct platform_pwm_backlight_data { unsigned int dft_brightness; unsigned int pwm_period_ns; int (*init)(struct device *dev); - int (*notify)(struct device *dev, int brightness); + int (*notify)(int brightness); void (*exit)(struct device *dev); }; diff --git a/trunk/include/linux/regulator/consumer.h b/trunk/include/linux/regulator/consumer.h index 030d92255c7a..490c5b37b6d7 100644 --- a/trunk/include/linux/regulator/consumer.h +++ b/trunk/include/linux/regulator/consumer.h @@ -35,8 +35,6 @@ #ifndef __LINUX_REGULATOR_CONSUMER_H_ #define __LINUX_REGULATOR_CONSUMER_H_ -#include - /* * Regulator operating modes. * diff --git a/trunk/include/linux/regulator/machine.h b/trunk/include/linux/regulator/machine.h index 234a8476cba8..87f5f176d4ef 100644 --- a/trunk/include/linux/regulator/machine.h +++ b/trunk/include/linux/regulator/machine.h @@ -43,20 +43,16 @@ struct regulator; /** * struct regulator_state - regulator state during low power system states * - * This describes a regulators state during a system wide low power - * state. One of enabled or disabled must be set for the - * configuration to be applied. + * This describes a regulators state during a system wide low power state. * * @uV: Operating voltage during suspend. * @mode: Operating mode during suspend. * @enabled: Enabled during suspend. - * @disabled: Disabled during suspend. */ struct regulator_state { int uV; /* suspend voltage */ unsigned int mode; /* suspend regulator operating mode */ int enabled; /* is regulator enabled in this suspend state */ - int disabled; /* is the regulator disbled in this suspend state */ }; /** diff --git a/trunk/include/linux/regulator/max8660.h b/trunk/include/linux/regulator/max8660.h deleted file mode 100644 index 9936763621c7..000000000000 --- a/trunk/include/linux/regulator/max8660.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * max8660.h -- Voltage regulation for the Maxim 8660/8661 - * - * Copyright (C) 2009 Wolfram Sang, Pengutronix e.K. - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __LINUX_REGULATOR_MAX8660_H -#define __LINUX_REGULATOR_MAX8660_H - -#include - -enum { - MAX8660_V3, - MAX8660_V4, - MAX8660_V5, - MAX8660_V6, - MAX8660_V7, - MAX8660_V_END, -}; - -/** - * max8660_subdev_data - regulator subdev data - * @id: regulator id - * @name: regulator name - * @platform_data: regulator init data - */ -struct max8660_subdev_data { - int id; - char *name; - struct regulator_init_data *platform_data; -}; - -/** - * max8660_platform_data - platform data for max8660 - * @num_subdevs: number of regulators used - * @subdevs: pointer to regulators used - * @en34_is_high: if EN34 is driven high, regulators cannot be en-/disabled. - */ -struct max8660_platform_data { - int num_subdevs; - struct max8660_subdev_data *subdevs; - unsigned en34_is_high:1; -}; -#endif diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 211ed32befbd..244c287a5ac1 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -1446,8 +1446,10 @@ struct task_struct { gfp_t lockdep_reclaim_gfp; #endif +#ifdef CONFIG_FS_JOURNAL_INFO /* journalling filesystem info */ void *journal_info; +#endif /* stacked block device info */ struct bio *bio_list, **bio_tail; diff --git a/trunk/include/linux/spi/dw_spi.h b/trunk/include/linux/spi/dw_spi.h deleted file mode 100644 index 51b3e771a9a3..000000000000 --- a/trunk/include/linux/spi/dw_spi.h +++ /dev/null @@ -1,212 +0,0 @@ -#ifndef DW_SPI_HEADER_H -#define DW_SPI_HEADER_H -#include - -/* Bit fields in CTRLR0 */ -#define SPI_DFS_OFFSET 0 - -#define SPI_FRF_OFFSET 4 -#define SPI_FRF_SPI 0x0 -#define SPI_FRF_SSP 0x1 -#define SPI_FRF_MICROWIRE 0x2 -#define SPI_FRF_RESV 0x3 - -#define SPI_MODE_OFFSET 6 -#define SPI_SCPH_OFFSET 6 -#define SPI_SCOL_OFFSET 7 -#define SPI_TMOD_OFFSET 8 -#define SPI_TMOD_TR 0x0 /* xmit & recv */ -#define SPI_TMOD_TO 0x1 /* xmit only */ -#define SPI_TMOD_RO 0x2 /* recv only */ -#define SPI_TMOD_EPROMREAD 0x3 /* eeprom read mode */ - -#define SPI_SLVOE_OFFSET 10 -#define SPI_SRL_OFFSET 11 -#define SPI_CFS_OFFSET 12 - -/* Bit fields in SR, 7 bits */ -#define SR_MASK 0x7f /* cover 7 bits */ -#define SR_BUSY (1 << 0) -#define SR_TF_NOT_FULL (1 << 1) -#define SR_TF_EMPT (1 << 2) -#define SR_RF_NOT_EMPT (1 << 3) -#define SR_RF_FULL (1 << 4) -#define SR_TX_ERR (1 << 5) -#define SR_DCOL (1 << 6) - -/* Bit fields in ISR, IMR, RISR, 7 bits */ -#define SPI_INT_TXEI (1 << 0) -#define SPI_INT_TXOI (1 << 1) -#define SPI_INT_RXUI (1 << 2) -#define SPI_INT_RXOI (1 << 3) -#define SPI_INT_RXFI (1 << 4) -#define SPI_INT_MSTI (1 << 5) - -/* TX RX interrupt level threshhold, max can be 256 */ -#define SPI_INT_THRESHOLD 32 - -enum dw_ssi_type { - SSI_MOTO_SPI = 0, - SSI_TI_SSP, - SSI_NS_MICROWIRE, -}; - -struct dw_spi_reg { - u32 ctrl0; - u32 ctrl1; - u32 ssienr; - u32 mwcr; - u32 ser; - u32 baudr; - u32 txfltr; - u32 rxfltr; - u32 txflr; - u32 rxflr; - u32 sr; - u32 imr; - u32 isr; - u32 risr; - u32 txoicr; - u32 rxoicr; - u32 rxuicr; - u32 msticr; - u32 icr; - u32 dmacr; - u32 dmatdlr; - u32 dmardlr; - u32 idr; - u32 version; - u32 dr; /* Currently oper as 32 bits, - though only low 16 bits matters */ -} __packed; - -struct dw_spi { - struct spi_master *master; - struct spi_device *cur_dev; - struct device *parent_dev; - enum dw_ssi_type type; - - void __iomem *regs; - unsigned long paddr; - u32 iolen; - int irq; - u32 max_freq; /* max bus freq supported */ - - u16 bus_num; - u16 num_cs; /* supported slave numbers */ - - /* 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; - struct chip_data *prev_chip; - 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; /* current is a 1/2 bytes op */ - u8 max_bits_per_word; /* maxim is 16b */ - u32 dma_width; - int cs_change; - int (*write)(struct dw_spi *dws); - int (*read)(struct dw_spi *dws); - irqreturn_t (*transfer_handler)(struct dw_spi *dws); - void (*cs_control)(u32 command); - - /* Dma info */ - int dma_inited; - struct dma_chan *txchan; - struct dma_chan *rxchan; - int txdma_done; - int rxdma_done; - u64 tx_param; - u64 rx_param; - struct device *dma_dev; - dma_addr_t dma_addr; - - /* Bus interface info */ - void *priv; -#ifdef CONFIG_DEBUG_FS - struct dentry *debugfs; -#endif -}; - -#define dw_readl(dw, name) \ - __raw_readl(&(((struct dw_spi_reg *)dw->regs)->name)) -#define dw_writel(dw, name, val) \ - __raw_writel((val), &(((struct dw_spi_reg *)dw->regs)->name)) -#define dw_readw(dw, name) \ - __raw_readw(&(((struct dw_spi_reg *)dw->regs)->name)) -#define dw_writew(dw, name, val) \ - __raw_writew((val), &(((struct dw_spi_reg *)dw->regs)->name)) - -static inline void spi_enable_chip(struct dw_spi *dws, int enable) -{ - dw_writel(dws, ssienr, (enable ? 1 : 0)); -} - -static inline void spi_set_clk(struct dw_spi *dws, u16 div) -{ - dw_writel(dws, baudr, div); -} - -static inline void spi_chip_sel(struct dw_spi *dws, u16 cs) -{ - if (cs > dws->num_cs) - return; - dw_writel(dws, ser, 1 << cs); -} - -/* Disable IRQ bits */ -static inline void spi_mask_intr(struct dw_spi *dws, u32 mask) -{ - u32 new_mask; - - new_mask = dw_readl(dws, imr) & ~mask; - dw_writel(dws, imr, new_mask); -} - -/* Enable IRQ bits */ -static inline void spi_umask_intr(struct dw_spi *dws, u32 mask) -{ - u32 new_mask; - - new_mask = dw_readl(dws, imr) | mask; - dw_writel(dws, imr, new_mask); -} - -/* - * Each SPI slave device to work with dw_api controller should - * has such a structure claiming its working mode (PIO/DMA etc), - * which can be save in the "controller_data" member of the - * struct spi_device - */ -struct dw_spi_chip { - u8 poll_mode; /* 0 for contoller polling mode */ - u8 type; /* SPI/SSP/Micrwire */ - u8 enable_dma; - void (*cs_control)(u32 command); -}; - -extern int dw_spi_add_host(struct dw_spi *dws); -extern void dw_spi_remove_host(struct dw_spi *dws); -extern int dw_spi_suspend_host(struct dw_spi *dws); -extern int dw_spi_resume_host(struct dw_spi *dws); -#endif /* DW_SPI_HEADER_H */ diff --git a/trunk/include/linux/vermagic.h b/trunk/include/linux/vermagic.h index cf97b5b9d1fe..79b9837d9ca0 100644 --- a/trunk/include/linux/vermagic.h +++ b/trunk/include/linux/vermagic.h @@ -1,4 +1,4 @@ -#include +#include #include /* Simply sanity version stamp for modules. */ diff --git a/trunk/include/linux/vt.h b/trunk/include/linux/vt.h index d5dd0bc408fd..3fb9944e50a6 100644 --- a/trunk/include/linux/vt.h +++ b/trunk/include/linux/vt.h @@ -84,8 +84,6 @@ struct vt_setactivate { #define VT_SETACTIVATE 0x560F /* Activate and set the mode of a console */ -#ifdef __KERNEL__ - #ifdef CONFIG_VT_CONSOLE extern int vt_kmsg_redirect(int new); @@ -99,8 +97,6 @@ static inline int vt_kmsg_redirect(int new) #endif -#endif /* __KERNEL__ */ - #define vt_get_kmsg_redirect() vt_kmsg_redirect(-1) #endif /* _LINUX_VT_H */ diff --git a/trunk/include/linux/writeback.h b/trunk/include/linux/writeback.h index c18c008f4bbf..705f01fe413a 100644 --- a/trunk/include/linux/writeback.h +++ b/trunk/include/linux/writeback.h @@ -79,7 +79,8 @@ void wakeup_flusher_threads(long nr_pages); static inline void wait_on_inode(struct inode *inode) { might_sleep(); - wait_on_bit(&inode->i_state, __I_NEW, inode_wait, TASK_UNINTERRUPTIBLE); + wait_on_bit(&inode->i_state, __I_LOCK, inode_wait, + TASK_UNINTERRUPTIBLE); } static inline void inode_sync_wait(struct inode *inode) { diff --git a/trunk/init/Makefile b/trunk/init/Makefile index 0bf677aa0872..4a243df426f7 100644 --- a/trunk/init/Makefile +++ b/trunk/init/Makefile @@ -15,8 +15,12 @@ mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o +# files to be removed upon make clean +clean-files := ../include/linux/compile.h + # dependencies on generated files need to be listed explicitly -$(obj)/version.o: include/generated/compile.h + +$(obj)/version.o: include/linux/compile.h # compile.h changes depending on hostname, generation number, etc, # so we regenerate it always. @@ -26,7 +30,7 @@ $(obj)/version.o: include/generated/compile.h chk_compile.h = : quiet_chk_compile.h = echo ' CHK $@' silent_chk_compile.h = : -include/generated/compile.h: FORCE +include/linux/compile.h: FORCE @$($(quiet)chk_compile.h) $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(KBUILD_CFLAGS)" diff --git a/trunk/init/version.c b/trunk/init/version.c index adff586401a5..52a8b98642b8 100644 --- a/trunk/init/version.c +++ b/trunk/init/version.c @@ -6,11 +6,11 @@ * May be freely distributed as part of Linux. */ -#include +#include #include #include #include -#include +#include #include #ifndef CONFIG_KALLSYMS diff --git a/trunk/kernel/bounds.c b/trunk/kernel/bounds.c index 98a51f26c136..3c5301381837 100644 --- a/trunk/kernel/bounds.c +++ b/trunk/kernel/bounds.c @@ -12,7 +12,7 @@ void foo(void) { - /* The enum constants to put into include/generated/bounds.h */ + /* The enum constants to put into include/linux/bounds.h */ DEFINE(NR_PAGEFLAGS, __NR_PAGEFLAGS); DEFINE(MAX_NR_ZONES, __MAX_NR_ZONES); /* End of constants */ diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 546774a31a66..5962d7ccf243 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -68,10 +68,10 @@ static void __unhash_process(struct task_struct *p) detach_pid(p, PIDTYPE_SID); list_del_rcu(&p->tasks); - list_del_init(&p->sibling); __get_cpu_var(process_counts)--; } list_del_rcu(&p->thread_group); + list_del_init(&p->sibling); } /* @@ -736,9 +736,12 @@ static struct task_struct *find_new_reaper(struct task_struct *father) /* * Any that need to be release_task'd are put on the @dead list. */ -static void reparent_leader(struct task_struct *father, struct task_struct *p, +static void reparent_thread(struct task_struct *father, struct task_struct *p, struct list_head *dead) { + if (p->pdeath_signal) + group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p); + list_move_tail(&p->sibling, &p->real_parent->children); if (task_detached(p)) @@ -777,18 +780,12 @@ static void forget_original_parent(struct task_struct *father) reaper = find_new_reaper(father); list_for_each_entry_safe(p, n, &father->children, sibling) { - struct task_struct *t = p; - do { - t->real_parent = reaper; - if (t->parent == father) { - BUG_ON(task_ptrace(t)); - t->parent = t->real_parent; - } - if (t->pdeath_signal) - group_send_sig_info(t->pdeath_signal, - SEND_SIG_NOINFO, t); - } while_each_thread(p, t); - reparent_leader(father, p, &dead_children); + p->real_parent = reaper; + if (p->parent == father) { + BUG_ON(task_ptrace(p)); + p->parent = p->real_parent; + } + reparent_thread(father, p, &dead_children); } write_unlock_irq(&tasklist_lock); @@ -1554,9 +1551,14 @@ static int do_wait_thread(struct wait_opts *wo, struct task_struct *tsk) struct task_struct *p; list_for_each_entry(p, &tsk->children, sibling) { - int ret = wait_consider_task(wo, 0, p); - if (ret) - return ret; + /* + * Do not consider detached threads. + */ + if (!task_detached(p)) { + int ret = wait_consider_task(wo, 0, p); + if (ret) + return ret; + } } return 0; diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index 5b2959b3ffc2..202a0ba63d3c 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -1291,6 +1291,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, } if (likely(p->pid)) { + list_add_tail(&p->sibling, &p->real_parent->children); tracehook_finish_clone(p, clone_flags, trace); if (thread_group_leader(p)) { @@ -1302,7 +1303,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->signal->tty = tty_kref_get(current->signal->tty); attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); attach_pid(p, PIDTYPE_SID, task_session(current)); - list_add_tail(&p->sibling, &p->real_parent->children); list_add_tail_rcu(&p->tasks, &init_task.tasks); __get_cpu_var(process_counts)++; } diff --git a/trunk/kernel/kexec.c b/trunk/kernel/kexec.c index a9a93d9ee7a7..433e9fcc1fc5 100644 --- a/trunk/kernel/kexec.c +++ b/trunk/kernel/kexec.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index e96b8ed1cb6a..a65dc787a27b 100644 --- a/trunk/kernel/module.c +++ b/trunk/kernel/module.c @@ -1910,7 +1910,9 @@ static void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr, unsigned int i; /* only scan the sections containing data */ - kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL); + kmemleak_scan_area(mod->module_core, (unsigned long)mod - + (unsigned long)mod->module_core, + sizeof(struct module), GFP_KERNEL); for (i = 1; i < hdr->e_shnum; i++) { if (!(sechdrs[i].sh_flags & SHF_ALLOC)) @@ -1919,7 +1921,8 @@ static void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr, && strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) != 0) continue; - kmemleak_scan_area((void *)sechdrs[i].sh_addr, + kmemleak_scan_area(mod->module_core, sechdrs[i].sh_addr - + (unsigned long)mod->module_core, sechdrs[i].sh_size, GFP_KERNEL); } } @@ -2247,12 +2250,6 @@ static noinline struct module *load_module(void __user *umod, "_ftrace_events", sizeof(*mod->trace_events), &mod->num_trace_events); - /* - * This section contains pointers to allocated objects in the trace - * code and not scanning it leads to false positives. - */ - kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) * - mod->num_trace_events, GFP_KERNEL); #endif #ifdef CONFIG_FTRACE_MCOUNT_RECORD /* sechdrs[0].sh_size is always zero */ diff --git a/trunk/kernel/printk.c b/trunk/kernel/printk.c index 17463ca2e229..1ded8e7dd19b 100644 --- a/trunk/kernel/printk.c +++ b/trunk/kernel/printk.c @@ -1412,7 +1412,7 @@ static LIST_HEAD(dump_list); /** * kmsg_dump_register - register a kernel log dumper. - * @dumper: pointer to the kmsg_dumper structure + * @dump: pointer to the kmsg_dumper structure * * Adds a kernel log dumper to the system. The dump callback in the * structure will be called when the kernel oopses or panics and must be @@ -1442,7 +1442,7 @@ EXPORT_SYMBOL_GPL(kmsg_dump_register); /** * kmsg_dump_unregister - unregister a kmsg dumper. - * @dumper: pointer to the kmsg_dumper structure + * @dump: pointer to the kmsg_dumper structure * * Removes a dump device from the system. Returns zero on success and * %-EINVAL otherwise. diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index 6665761c006d..45e4bef0012a 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -1131,7 +1131,7 @@ static struct ctl_table vm_table[] = { .data = &sysctl_max_map_count, .maxlen = sizeof(sysctl_max_map_count), .mode = 0644, - .proc_handler = proc_dointvec_minmax, + .proc_handler = proc_dointvec, .extra1 = &zero, }, #else diff --git a/trunk/kernel/trace/trace.c b/trunk/kernel/trace/trace.c index 8b9f20ab8eed..06ba26747d7e 100644 --- a/trunk/kernel/trace/trace.c +++ b/trunk/kernel/trace/trace.c @@ -12,7 +12,7 @@ * Copyright (C) 2004 William Lee Irwin III */ #include -#include +#include #include #include #include diff --git a/trunk/lib/Kconfig.debug b/trunk/lib/Kconfig.debug index 25c3ed594c54..8cf9938dd147 100644 --- a/trunk/lib/Kconfig.debug +++ b/trunk/lib/Kconfig.debug @@ -360,7 +360,6 @@ config DEBUG_KMEMLEAK select DEBUG_FS if SYSFS select STACKTRACE if STACKTRACE_SUPPORT select KALLSYMS - select CRC32 help Say Y here if you want to enable the memory leak detector. The memory allocation/freeing is traced in a way diff --git a/trunk/lib/vsprintf.c b/trunk/lib/vsprintf.c index d4996cf46eb6..735343fc857a 100644 --- a/trunk/lib/vsprintf.c +++ b/trunk/lib/vsprintf.c @@ -1179,18 +1179,7 @@ static int format_decode(const char *fmt, struct printf_spec *spec) * %ps output the name of a text symbol without offset * %pF output the name of a function pointer with its offset * %pf output the name of a function pointer without its offset - * %pR output the address range in a struct resource with decoded flags - * %pr output the address range in a struct resource with raw flags - * %pM output a 6-byte MAC address with colons - * %pm output a 6-byte MAC address without colons - * %pI4 print an IPv4 address without leading zeros - * %pi4 print an IPv4 address with leading zeros - * %pI6 print an IPv6 address with colons - * %pi6 print an IPv6 address without colons - * %pI6c print an IPv6 address as specified by - * http://www.ietf.org/id/draft-kawamura-ipv6-text-representation-03.txt - * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper - * case. + * %pR output the address range in a struct resource * %n is ignored * * The return value is the number of characters which would diff --git a/trunk/mm/kmemleak.c b/trunk/mm/kmemleak.c index 5b069e4f5e48..13f33b3081ec 100644 --- a/trunk/mm/kmemleak.c +++ b/trunk/mm/kmemleak.c @@ -93,7 +93,6 @@ #include #include #include -#include #include #include @@ -109,6 +108,7 @@ #define MSECS_MIN_AGE 5000 /* minimum object age for reporting */ #define SECS_FIRST_SCAN 60 /* delay before the first scan */ #define SECS_SCAN_WAIT 600 /* subsequent auto scanning delay */ +#define GRAY_LIST_PASSES 25 /* maximum number of gray list scans */ #define MAX_SCAN_SIZE 4096 /* maximum size of a scanned block */ #define BYTES_PER_POINTER sizeof(void *) @@ -119,8 +119,8 @@ /* scanning area inside a memory block */ struct kmemleak_scan_area { struct hlist_node node; - unsigned long start; - size_t size; + unsigned long offset; + size_t length; }; #define KMEMLEAK_GREY 0 @@ -149,8 +149,6 @@ struct kmemleak_object { int min_count; /* the total number of pointers found pointing to this object */ int count; - /* checksum for detecting modified objects */ - u32 checksum; /* memory ranges to be scanned inside an object (empty for all) */ struct hlist_head area_list; unsigned long trace[MAX_TRACE]; @@ -166,6 +164,8 @@ struct kmemleak_object { #define OBJECT_REPORTED (1 << 1) /* flag set to not scan the object */ #define OBJECT_NO_SCAN (1 << 2) +/* flag set on newly allocated objects */ +#define OBJECT_NEW (1 << 3) /* number of bytes to print per line; must be 16 or 32 */ #define HEX_ROW_SIZE 16 @@ -241,6 +241,8 @@ struct early_log { const void *ptr; /* allocated/freed memory block */ size_t size; /* memory block size */ int min_count; /* minimum reference count */ + unsigned long offset; /* scan area offset */ + size_t length; /* scan area length */ unsigned long trace[MAX_TRACE]; /* stack trace */ unsigned int trace_len; /* stack trace length */ }; @@ -321,6 +323,11 @@ static bool color_gray(const struct kmemleak_object *object) object->count >= object->min_count; } +static bool color_black(const struct kmemleak_object *object) +{ + return object->min_count == KMEMLEAK_BLACK; +} + /* * Objects are considered unreferenced only if their color is white, they have * not be deleted and have a minimum age to avoid false positives caused by @@ -328,7 +335,7 @@ static bool color_gray(const struct kmemleak_object *object) */ static bool unreferenced_object(struct kmemleak_object *object) { - return (color_white(object) && object->flags & OBJECT_ALLOCATED) && + return (object->flags & OBJECT_ALLOCATED) && color_white(object) && time_before_eq(object->jiffies + jiffies_min_age, jiffies_last_scan); } @@ -341,13 +348,11 @@ static void print_unreferenced(struct seq_file *seq, struct kmemleak_object *object) { int i; - unsigned int msecs_age = jiffies_to_msecs(jiffies - object->jiffies); seq_printf(seq, "unreferenced object 0x%08lx (size %zu):\n", object->pointer, object->size); - seq_printf(seq, " comm \"%s\", pid %d, jiffies %lu (age %d.%03ds)\n", - object->comm, object->pid, object->jiffies, - msecs_age / 1000, msecs_age % 1000); + seq_printf(seq, " comm \"%s\", pid %d, jiffies %lu\n", + object->comm, object->pid, object->jiffies); hex_dump_object(seq, object); seq_printf(seq, " backtrace:\n"); @@ -376,7 +381,6 @@ static void dump_object_info(struct kmemleak_object *object) pr_notice(" min_count = %d\n", object->min_count); pr_notice(" count = %d\n", object->count); pr_notice(" flags = 0x%lx\n", object->flags); - pr_notice(" checksum = %d\n", object->checksum); pr_notice(" backtrace:\n"); print_stack_trace(&trace, 4); } @@ -518,13 +522,12 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, INIT_HLIST_HEAD(&object->area_list); spin_lock_init(&object->lock); atomic_set(&object->use_count, 1); - object->flags = OBJECT_ALLOCATED; + object->flags = OBJECT_ALLOCATED | OBJECT_NEW; object->pointer = ptr; object->size = size; object->min_count = min_count; - object->count = 0; /* white color initially */ + object->count = -1; /* no color initially */ object->jiffies = jiffies; - object->checksum = 0; /* task information */ if (in_irq()) { @@ -717,13 +720,14 @@ static void make_black_object(unsigned long ptr) * Add a scanning area to the object. If at least one such area is added, * kmemleak will only scan these ranges rather than the whole memory block. */ -static void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp) +static void add_scan_area(unsigned long ptr, unsigned long offset, + size_t length, gfp_t gfp) { unsigned long flags; struct kmemleak_object *object; struct kmemleak_scan_area *area; - object = find_and_get_object(ptr, 1); + object = find_and_get_object(ptr, 0); if (!object) { kmemleak_warn("Adding scan area to unknown object at 0x%08lx\n", ptr); @@ -737,7 +741,7 @@ static void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp) } spin_lock_irqsave(&object->lock, flags); - if (ptr + size > object->pointer + object->size) { + if (offset + length > object->size) { kmemleak_warn("Scan area larger than object 0x%08lx\n", ptr); dump_object_info(object); kmem_cache_free(scan_area_cache, area); @@ -745,8 +749,8 @@ static void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp) } INIT_HLIST_NODE(&area->node); - area->start = ptr; - area->size = size; + area->offset = offset; + area->length = length; hlist_add_head(&area->node, &object->area_list); out_unlock: @@ -782,7 +786,7 @@ static void object_no_scan(unsigned long ptr) * processed later once kmemleak is fully initialized. */ static void __init log_early(int op_type, const void *ptr, size_t size, - int min_count) + int min_count, unsigned long offset, size_t length) { unsigned long flags; struct early_log *log; @@ -804,6 +808,8 @@ static void __init log_early(int op_type, const void *ptr, size_t size, log->ptr = ptr; log->size = size; log->min_count = min_count; + log->offset = offset; + log->length = length; if (op_type == KMEMLEAK_ALLOC) log->trace_len = __save_stack_trace(log->trace); crt_early_log++; @@ -852,7 +858,7 @@ void __ref kmemleak_alloc(const void *ptr, size_t size, int min_count, if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) create_object((unsigned long)ptr, size, min_count, gfp); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_ALLOC, ptr, size, min_count); + log_early(KMEMLEAK_ALLOC, ptr, size, min_count, 0, 0); } EXPORT_SYMBOL_GPL(kmemleak_alloc); @@ -867,7 +873,7 @@ void __ref kmemleak_free(const void *ptr) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) delete_object_full((unsigned long)ptr); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_FREE, ptr, 0, 0); + log_early(KMEMLEAK_FREE, ptr, 0, 0, 0, 0); } EXPORT_SYMBOL_GPL(kmemleak_free); @@ -882,7 +888,7 @@ void __ref kmemleak_free_part(const void *ptr, size_t size) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) delete_object_part((unsigned long)ptr, size); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_FREE_PART, ptr, size, 0); + log_early(KMEMLEAK_FREE_PART, ptr, size, 0, 0, 0); } EXPORT_SYMBOL_GPL(kmemleak_free_part); @@ -897,7 +903,7 @@ void __ref kmemleak_not_leak(const void *ptr) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) make_gray_object((unsigned long)ptr); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_NOT_LEAK, ptr, 0, 0); + log_early(KMEMLEAK_NOT_LEAK, ptr, 0, 0, 0, 0); } EXPORT_SYMBOL(kmemleak_not_leak); @@ -913,21 +919,22 @@ void __ref kmemleak_ignore(const void *ptr) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) make_black_object((unsigned long)ptr); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_IGNORE, ptr, 0, 0); + log_early(KMEMLEAK_IGNORE, ptr, 0, 0, 0, 0); } EXPORT_SYMBOL(kmemleak_ignore); /* * Limit the range to be scanned in an allocated memory block. */ -void __ref kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) +void __ref kmemleak_scan_area(const void *ptr, unsigned long offset, + size_t length, gfp_t gfp) { pr_debug("%s(0x%p)\n", __func__, ptr); if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) - add_scan_area((unsigned long)ptr, size, gfp); + add_scan_area((unsigned long)ptr, offset, length, gfp); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_SCAN_AREA, ptr, size, 0); + log_early(KMEMLEAK_SCAN_AREA, ptr, 0, 0, offset, length); } EXPORT_SYMBOL(kmemleak_scan_area); @@ -941,24 +948,10 @@ void __ref kmemleak_no_scan(const void *ptr) if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) object_no_scan((unsigned long)ptr); else if (atomic_read(&kmemleak_early_log)) - log_early(KMEMLEAK_NO_SCAN, ptr, 0, 0); + log_early(KMEMLEAK_NO_SCAN, ptr, 0, 0, 0, 0); } EXPORT_SYMBOL(kmemleak_no_scan); -/* - * Update an object's checksum and return true if it was modified. - */ -static bool update_checksum(struct kmemleak_object *object) -{ - u32 old_csum = object->checksum; - - if (!kmemcheck_is_obj_initialized(object->pointer, object->size)) - return false; - - object->checksum = crc32(0, (void *)object->pointer, object->size); - return object->checksum != old_csum; -} - /* * Memory scanning is a long process and it needs to be interruptable. This * function checks whether such interrupt condition occured. @@ -1038,14 +1031,11 @@ static void scan_block(void *_start, void *_end, * added to the gray_list. */ object->count++; - if (color_gray(object)) { + if (color_gray(object)) list_add_tail(&object->gray_list, &gray_list); - spin_unlock_irqrestore(&object->lock, flags); - continue; - } - + else + put_object(object); spin_unlock_irqrestore(&object->lock, flags); - put_object(object); } } @@ -1085,46 +1075,13 @@ static void scan_object(struct kmemleak_object *object) } } else hlist_for_each_entry(area, elem, &object->area_list, node) - scan_block((void *)area->start, - (void *)(area->start + area->size), - object, 0); + scan_block((void *)(object->pointer + area->offset), + (void *)(object->pointer + area->offset + + area->length), object, 0); out: spin_unlock_irqrestore(&object->lock, flags); } -/* - * Scan the objects already referenced (gray objects). More objects will be - * referenced and, if there are no memory leaks, all the objects are scanned. - */ -static void scan_gray_list(void) -{ - struct kmemleak_object *object, *tmp; - - /* - * The list traversal is safe for both tail additions and removals - * from inside the loop. The kmemleak objects cannot be freed from - * outside the loop because their use_count was incremented. - */ - object = list_entry(gray_list.next, typeof(*object), gray_list); - while (&object->gray_list != &gray_list) { - cond_resched(); - - /* may add new objects to the list */ - if (!scan_should_stop()) - scan_object(object); - - tmp = list_entry(object->gray_list.next, typeof(*object), - gray_list); - - /* remove the object from the list and release it */ - list_del(&object->gray_list); - put_object(object); - - object = tmp; - } - WARN_ON(!list_empty(&gray_list)); -} - /* * Scan data sections and all the referenced memory blocks allocated via the * kernel's standard allocators. This function must be called with the @@ -1133,9 +1090,10 @@ static void scan_gray_list(void) static void kmemleak_scan(void) { unsigned long flags; - struct kmemleak_object *object; + struct kmemleak_object *object, *tmp; int i; int new_leaks = 0; + int gray_list_pass = 0; jiffies_last_scan = jiffies; @@ -1156,6 +1114,7 @@ static void kmemleak_scan(void) #endif /* reset the reference count (whiten the object) */ object->count = 0; + object->flags &= ~OBJECT_NEW; if (color_gray(object) && get_object(object)) list_add_tail(&object->gray_list, &gray_list); @@ -1213,36 +1172,62 @@ static void kmemleak_scan(void) /* * Scan the objects already referenced from the sections scanned - * above. + * above. More objects will be referenced and, if there are no memory + * leaks, all the objects will be scanned. The list traversal is safe + * for both tail additions and removals from inside the loop. The + * kmemleak objects cannot be freed from outside the loop because their + * use_count was increased. */ - scan_gray_list(); +repeat: + object = list_entry(gray_list.next, typeof(*object), gray_list); + while (&object->gray_list != &gray_list) { + cond_resched(); + + /* may add new objects to the list */ + if (!scan_should_stop()) + scan_object(object); + + tmp = list_entry(object->gray_list.next, typeof(*object), + gray_list); + + /* remove the object from the list and release it */ + list_del(&object->gray_list); + put_object(object); + + object = tmp; + } + + if (scan_should_stop() || ++gray_list_pass >= GRAY_LIST_PASSES) + goto scan_end; /* - * Check for new or unreferenced objects modified since the previous - * scan and color them gray until the next scan. + * Check for new objects allocated during this scanning and add them + * to the gray list. */ rcu_read_lock(); list_for_each_entry_rcu(object, &object_list, object_list) { spin_lock_irqsave(&object->lock, flags); - if (color_white(object) && (object->flags & OBJECT_ALLOCATED) - && update_checksum(object) && get_object(object)) { - /* color it gray temporarily */ - object->count = object->min_count; + if ((object->flags & OBJECT_NEW) && !color_black(object) && + get_object(object)) { + object->flags &= ~OBJECT_NEW; list_add_tail(&object->gray_list, &gray_list); } spin_unlock_irqrestore(&object->lock, flags); } rcu_read_unlock(); - /* - * Re-scan the gray list for modified unreferenced objects. - */ - scan_gray_list(); + if (!list_empty(&gray_list)) + goto repeat; + +scan_end: + WARN_ON(!list_empty(&gray_list)); /* - * If scanning was stopped do not report any new unreferenced objects. + * If scanning was stopped or new objects were being allocated at a + * higher rate than gray list scanning, do not report any new + * unreferenced objects. */ - if (scan_should_stop()) + if (scan_should_stop() || gray_list_pass >= GRAY_LIST_PASSES) return; /* @@ -1657,7 +1642,8 @@ void __init kmemleak_init(void) kmemleak_ignore(log->ptr); break; case KMEMLEAK_SCAN_AREA: - kmemleak_scan_area(log->ptr, log->size, GFP_KERNEL); + kmemleak_scan_area(log->ptr, log->offset, log->length, + GFP_KERNEL); break; case KMEMLEAK_NO_SCAN: kmemleak_no_scan(log->ptr); diff --git a/trunk/mm/readahead.c b/trunk/mm/readahead.c index 033bc135a41f..aa1aa2345235 100644 --- a/trunk/mm/readahead.c +++ b/trunk/mm/readahead.c @@ -547,17 +547,5 @@ page_cache_async_readahead(struct address_space *mapping, /* do read-ahead */ ondemand_readahead(mapping, ra, filp, true, offset, req_size); - -#ifdef CONFIG_BLOCK - /* - * Normally the current page is !uptodate and lock_page() will be - * immediately called to implicitly unplug the device. However this - * is not always true for RAID conifgurations, where data arrives - * not strictly in their submission order. In this case we need to - * explicitly kick off the IO. - */ - if (PageUptodate(page)) - blk_run_backing_dev(mapping->backing_dev_info, NULL); -#endif } EXPORT_SYMBOL_GPL(page_cache_async_readahead); diff --git a/trunk/mm/shmem.c b/trunk/mm/shmem.c index eef4ebea5158..f8485062f3ba 100644 --- a/trunk/mm/shmem.c +++ b/trunk/mm/shmem.c @@ -1830,8 +1830,6 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) iput(inode); return error; } -#else - error = 0; #endif if (dir->i_mode & S_ISGID) { inode->i_gid = dir->i_gid; diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index e17cc2c337b8..3f4822938f46 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -2275,11 +2275,9 @@ kmem_cache_create (const char *name, size_t size, size_t align, /* * Determine if the slab management is 'on' or 'off' slab. * (bootstrapping cannot cope with offslab caches so don't do - * it too early on. Always use on-slab management when - * SLAB_NOLEAKTRACE to avoid recursive calls into kmemleak) + * it too early on.) */ - if ((size >= (PAGE_SIZE >> 3)) && !slab_early_init && - !(flags & SLAB_NOLEAKTRACE)) + if ((size >= (PAGE_SIZE >> 3)) && !slab_early_init) /* * Size is large, assume best to place the slab management obj * off-slab (should allow better packing of objs). @@ -2598,8 +2596,8 @@ static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp, * kmemleak does not treat the ->s_mem pointer as a reference * to the object. Otherwise we will not report the leak. */ - kmemleak_scan_area(&slabp->list, sizeof(struct list_head), - local_flags); + kmemleak_scan_area(slabp, offsetof(struct slab, list), + sizeof(struct list_head), local_flags); if (!slabp) return NULL; } else { diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 769c386bd428..dbfdfa96d29b 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -312,6 +312,18 @@ static struct file_system_type sock_fs_type = { .kill_sb = kill_anon_super, }; +static int sockfs_delete_dentry(struct dentry *dentry) +{ + /* + * At creation time, we pretended this dentry was hashed + * (by clearing DCACHE_UNHASHED bit in d_flags) + * At delete time, we restore the truth : not hashed. + * (so that dput() can proceed correctly) + */ + dentry->d_flags |= DCACHE_UNHASHED; + return 0; +} + /* * sockfs_dname() is called from d_path(). */ @@ -322,6 +334,7 @@ static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen) } static const struct dentry_operations sockfs_dentry_operations = { + .d_delete = sockfs_delete_dentry, .d_dname = sockfs_dname, }; @@ -361,6 +374,12 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags) path.mnt = mntget(sock_mnt); path.dentry->d_op = &sockfs_dentry_operations; + /* + * We dont want to push this dentry into global dentry hash table. + * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED + * This permits a working /proc/$pid/fd/XXX on sockets + */ + path.dentry->d_flags &= ~DCACHE_UNHASHED; d_instantiate(path.dentry, SOCK_INODE(sock)); SOCK_INODE(sock)->i_fop = &socket_file_ops; diff --git a/trunk/scripts/Kbuild.include b/trunk/scripts/Kbuild.include index ed2773edfe71..c67e73ecd5be 100644 --- a/trunk/scripts/Kbuild.include +++ b/trunk/scripts/Kbuild.include @@ -149,12 +149,6 @@ ld-option = $(call try-run,\ # $(Q)$(MAKE) $(build)=dir build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj -### -# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.modbuiltin obj= -# Usage: -# $(Q)$(MAKE) $(modbuiltin)=dir -modbuiltin := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.modbuiltin obj - # Prefix -I with $(srctree) if it is not an absolute path. # skip if -I has no parameter addtree = $(if $(patsubst -I%,%,$(1)), \ diff --git a/trunk/scripts/Makefile.lib b/trunk/scripts/Makefile.lib index cd815ac2a50b..224d85e72ef1 100644 --- a/trunk/scripts/Makefile.lib +++ b/trunk/scripts/Makefile.lib @@ -213,7 +213,7 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \ # Bzip2 and LZMA do not include size in file... so we have to fake that; # append the size as a 32-bit littleendian number as gzip does. -size_append = printf $(shell \ +size_append = /bin/echo -ne $(shell \ dec_size=0; \ for F in $1; do \ fsize=$$(stat -c "%s" $$F); \ diff --git a/trunk/scripts/Makefile.modbuiltin b/trunk/scripts/Makefile.modbuiltin deleted file mode 100644 index 102a276f6eea..000000000000 --- a/trunk/scripts/Makefile.modbuiltin +++ /dev/null @@ -1,55 +0,0 @@ -# ========================================================================== -# Generating modules.builtin -# ========================================================================== - -src := $(obj) - -PHONY := __modbuiltin -__modbuiltin: - --include include/config/auto.conf -# tristate.conf sets tristate variables to uppercase 'Y' or 'M' -# That way, we get the list of built-in modules in obj-Y --include include/config/tristate.conf - -include scripts/Kbuild.include - -# The filename Kbuild has precedence over Makefile -kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) -kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile) -include $(kbuild-file) - -include scripts/Makefile.lib -__subdir-Y := $(patsubst %/,%,$(filter %/, $(obj-Y))) -subdir-Y += $(__subdir-Y) -subdir-ym := $(sort $(subdir-y) $(subdir-Y) $(subdir-m)) -subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) -obj-Y := $(addprefix $(obj)/,$(obj-Y)) - -modbuiltin-subdirs := $(patsubst %,%/modules.builtin, $(subdir-ym)) -modbuiltin-mods := $(filter %.ko, $(obj-Y:.o=.ko)) -modbuiltin-target := $(obj)/modules.builtin - -__modbuiltin: $(modbuiltin-target) $(subdir-ym) - @: - -$(modbuiltin-target): $(subdir-ym) FORCE - $(Q)(for m in $(modbuiltin-mods); do echo kernel/$$m; done; \ - cat /dev/null $(modbuiltin-subdirs)) > $@ - -PHONY += FORCE - -FORCE: - -# Descending -# --------------------------------------------------------------------------- - -PHONY += $(subdir-ym) -$(subdir-ym): - $(Q)$(MAKE) $(modbuiltin)=$@ - - -# 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. - -.PHONY: $(PHONY) diff --git a/trunk/scripts/basic/fixdep.c b/trunk/scripts/basic/fixdep.c index ea26b23de082..6bf21f83837d 100644 --- a/trunk/scripts/basic/fixdep.c +++ b/trunk/scripts/basic/fixdep.c @@ -16,15 +16,15 @@ * tells make when to remake a file. * * To use this list as-is however has the drawback that virtually - * every file in the kernel includes autoconf.h. + * every file in the kernel includes . * - * If the user re-runs make *config, autoconf.h will be + * If the user re-runs make *config, linux/autoconf.h will be * regenerated. make notices that and will rebuild every file which * includes autoconf.h, i.e. basically all files. This is extremely * annoying if the user just changed CONFIG_HIS_DRIVER from n to m. * * So we play the same trick that "mkdep" played before. We replace - * the dependency on autoconf.h by a dependency on every config + * the dependency on linux/autoconf.h by a dependency on every config * option which is mentioned in any of the listed prequisites. * * kconfig populates a tree in include/config/ with an empty file @@ -73,7 +73,7 @@ * cmd_ = * * and then basically copies the ..d file to stdout, in the - * process filtering out the dependency on autoconf.h and adding + * process filtering out the dependency on linux/autoconf.h and adding * dependencies on include/config/my/option.h for every * CONFIG_MY_OPTION encountered in any of the prequisites. * @@ -324,7 +324,7 @@ static void parse_dep_file(void *map, size_t len) p++; } memcpy(s, m, p-m); s[p-m] = 0; - if (strrcmp(s, "include/generated/autoconf.h") && + if (strrcmp(s, "include/linux/autoconf.h") && strrcmp(s, "arch/um/include/uml-config.h") && strrcmp(s, ".ver")) { printf(" %s \\\n", s); diff --git a/trunk/scripts/genksyms/keywords.c_shipped b/trunk/scripts/genksyms/keywords.c_shipped index 8060e06798b3..287467a2e8c7 100644 --- a/trunk/scripts/genksyms/keywords.c_shipped +++ b/trunk/scripts/genksyms/keywords.c_shipped @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.4 */ +/* ANSI-C code produced by gperf version 3.0.3 */ /* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -34,7 +34,7 @@ struct resword; static const struct resword *is_reserved_word(register const char *str, register unsigned int len); #line 5 "scripts/genksyms/keywords.gperf" struct resword { const char *name; int token; }; -/* maximum key range = 64, duplicates = 0 */ +/* maximum key range = 62, duplicates = 0 */ #ifdef __GNUC__ __inline @@ -48,39 +48,39 @@ is_reserved_hash (register const char *str, register unsigned int len) { static const unsigned char asso_values[] = { - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 0, - 67, 67, 67, 67, 67, 67, 15, 67, 67, 67, - 0, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 0, 67, 0, 67, 5, - 25, 20, 15, 30, 67, 15, 67, 67, 10, 0, - 10, 40, 20, 67, 10, 5, 0, 10, 15, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67 + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 5, + 65, 65, 65, 65, 65, 65, 35, 65, 65, 65, + 0, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 0, 65, 0, 65, 5, + 20, 15, 10, 30, 65, 15, 65, 65, 20, 0, + 10, 35, 20, 65, 10, 5, 0, 10, 5, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65 }; return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]]; } #ifdef __GNUC__ __inline -#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ +#ifdef __GNUC_STDC_INLINE__ __attribute__ ((__gnu_inline__)) #endif #endif @@ -89,119 +89,116 @@ is_reserved_word (register const char *str, register unsigned int len) { enum { - TOTAL_KEYWORDS = 45, + TOTAL_KEYWORDS = 43, MIN_WORD_LENGTH = 3, MAX_WORD_LENGTH = 24, MIN_HASH_VALUE = 3, - MAX_HASH_VALUE = 66 + MAX_HASH_VALUE = 64 }; static const struct resword wordlist[] = { {""}, {""}, {""}, -#line 30 "scripts/genksyms/keywords.gperf" +#line 28 "scripts/genksyms/keywords.gperf" {"asm", ASM_KEYW}, {""}, -#line 12 "scripts/genksyms/keywords.gperf" +#line 10 "scripts/genksyms/keywords.gperf" {"__asm", ASM_KEYW}, {""}, -#line 13 "scripts/genksyms/keywords.gperf" +#line 11 "scripts/genksyms/keywords.gperf" {"__asm__", ASM_KEYW}, {""}, {""}, -#line 56 "scripts/genksyms/keywords.gperf" +#line 54 "scripts/genksyms/keywords.gperf" {"__typeof__", TYPEOF_KEYW}, {""}, -#line 16 "scripts/genksyms/keywords.gperf" +#line 14 "scripts/genksyms/keywords.gperf" {"__const", CONST_KEYW}, -#line 15 "scripts/genksyms/keywords.gperf" +#line 13 "scripts/genksyms/keywords.gperf" {"__attribute__", ATTRIBUTE_KEYW}, -#line 17 "scripts/genksyms/keywords.gperf" +#line 15 "scripts/genksyms/keywords.gperf" {"__const__", CONST_KEYW}, -#line 22 "scripts/genksyms/keywords.gperf" +#line 20 "scripts/genksyms/keywords.gperf" {"__signed__", SIGNED_KEYW}, -#line 48 "scripts/genksyms/keywords.gperf" +#line 46 "scripts/genksyms/keywords.gperf" {"static", STATIC_KEYW}, - {""}, -#line 43 "scripts/genksyms/keywords.gperf" +#line 22 "scripts/genksyms/keywords.gperf" + {"__volatile__", VOLATILE_KEYW}, +#line 41 "scripts/genksyms/keywords.gperf" {"int", INT_KEYW}, -#line 36 "scripts/genksyms/keywords.gperf" +#line 34 "scripts/genksyms/keywords.gperf" {"char", CHAR_KEYW}, -#line 37 "scripts/genksyms/keywords.gperf" +#line 35 "scripts/genksyms/keywords.gperf" {"const", CONST_KEYW}, -#line 49 "scripts/genksyms/keywords.gperf" +#line 47 "scripts/genksyms/keywords.gperf" {"struct", STRUCT_KEYW}, -#line 28 "scripts/genksyms/keywords.gperf" +#line 26 "scripts/genksyms/keywords.gperf" {"__restrict__", RESTRICT_KEYW}, -#line 29 "scripts/genksyms/keywords.gperf" - {"restrict", RESTRICT_KEYW}, -#line 9 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, -#line 20 "scripts/genksyms/keywords.gperf" - {"__inline__", INLINE_KEYW}, - {""}, -#line 24 "scripts/genksyms/keywords.gperf" - {"__volatile__", VOLATILE_KEYW}, -#line 7 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, #line 27 "scripts/genksyms/keywords.gperf" + {"restrict", RESTRICT_KEYW}, +#line 25 "scripts/genksyms/keywords.gperf" {"_restrict", RESTRICT_KEYW}, - {""}, -#line 14 "scripts/genksyms/keywords.gperf" - {"__attribute", ATTRIBUTE_KEYW}, -#line 8 "scripts/genksyms/keywords.gperf" - {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, #line 18 "scripts/genksyms/keywords.gperf" + {"__inline__", INLINE_KEYW}, +#line 12 "scripts/genksyms/keywords.gperf" + {"__attribute", ATTRIBUTE_KEYW}, + {""}, +#line 16 "scripts/genksyms/keywords.gperf" {"__extension__", EXTENSION_KEYW}, -#line 39 "scripts/genksyms/keywords.gperf" +#line 37 "scripts/genksyms/keywords.gperf" {"enum", ENUM_KEYW}, -#line 10 "scripts/genksyms/keywords.gperf" - {"EXPORT_UNUSED_SYMBOL", EXPORT_SYMBOL_KEYW}, -#line 40 "scripts/genksyms/keywords.gperf" +#line 21 "scripts/genksyms/keywords.gperf" + {"__volatile", VOLATILE_KEYW}, +#line 38 "scripts/genksyms/keywords.gperf" {"extern", EXTERN_KEYW}, {""}, -#line 21 "scripts/genksyms/keywords.gperf" +#line 19 "scripts/genksyms/keywords.gperf" {"__signed", SIGNED_KEYW}, -#line 11 "scripts/genksyms/keywords.gperf" - {"EXPORT_UNUSED_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, -#line 51 "scripts/genksyms/keywords.gperf" - {"union", UNION_KEYW}, -#line 55 "scripts/genksyms/keywords.gperf" +#line 9 "scripts/genksyms/keywords.gperf" + {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW}, + {""}, +#line 53 "scripts/genksyms/keywords.gperf" {"typeof", TYPEOF_KEYW}, -#line 50 "scripts/genksyms/keywords.gperf" +#line 48 "scripts/genksyms/keywords.gperf" {"typedef", TYPEDEF_KEYW}, -#line 19 "scripts/genksyms/keywords.gperf" +#line 17 "scripts/genksyms/keywords.gperf" {"__inline", INLINE_KEYW}, -#line 35 "scripts/genksyms/keywords.gperf" +#line 33 "scripts/genksyms/keywords.gperf" {"auto", AUTO_KEYW}, -#line 23 "scripts/genksyms/keywords.gperf" - {"__volatile", VOLATILE_KEYW}, +#line 49 "scripts/genksyms/keywords.gperf" + {"union", UNION_KEYW}, {""}, {""}, -#line 52 "scripts/genksyms/keywords.gperf" +#line 50 "scripts/genksyms/keywords.gperf" {"unsigned", UNSIGNED_KEYW}, - {""}, -#line 46 "scripts/genksyms/keywords.gperf" +#line 51 "scripts/genksyms/keywords.gperf" + {"void", VOID_KEYW}, +#line 44 "scripts/genksyms/keywords.gperf" {"short", SHORT_KEYW}, -#line 42 "scripts/genksyms/keywords.gperf" + {""}, {""}, +#line 52 "scripts/genksyms/keywords.gperf" + {"volatile", VOLATILE_KEYW}, + {""}, +#line 39 "scripts/genksyms/keywords.gperf" + {"float", FLOAT_KEYW}, +#line 36 "scripts/genksyms/keywords.gperf" + {"double", DOUBLE_KEYW}, + {""}, +#line 7 "scripts/genksyms/keywords.gperf" + {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, + {""}, {""}, +#line 40 "scripts/genksyms/keywords.gperf" {"inline", INLINE_KEYW}, +#line 8 "scripts/genksyms/keywords.gperf" + {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, +#line 43 "scripts/genksyms/keywords.gperf" + {"register", REGISTER_KEYW}, {""}, -#line 54 "scripts/genksyms/keywords.gperf" - {"volatile", VOLATILE_KEYW}, -#line 44 "scripts/genksyms/keywords.gperf" - {"long", LONG_KEYW}, -#line 26 "scripts/genksyms/keywords.gperf" +#line 24 "scripts/genksyms/keywords.gperf" {"_Bool", BOOL_KEYW}, - {""}, {""}, #line 45 "scripts/genksyms/keywords.gperf" - {"register", REGISTER_KEYW}, -#line 53 "scripts/genksyms/keywords.gperf" - {"void", VOID_KEYW}, -#line 41 "scripts/genksyms/keywords.gperf" - {"float", FLOAT_KEYW}, -#line 38 "scripts/genksyms/keywords.gperf" - {"double", DOUBLE_KEYW}, - {""}, {""}, {""}, {""}, -#line 47 "scripts/genksyms/keywords.gperf" - {"signed", SIGNED_KEYW} + {"signed", SIGNED_KEYW}, + {""}, {""}, +#line 42 "scripts/genksyms/keywords.gperf" + {"long", LONG_KEYW} }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) diff --git a/trunk/scripts/genksyms/keywords.gperf b/trunk/scripts/genksyms/keywords.gperf index e6349acb6f2f..8fe977a4d57b 100644 --- a/trunk/scripts/genksyms/keywords.gperf +++ b/trunk/scripts/genksyms/keywords.gperf @@ -7,8 +7,6 @@ struct resword { const char *name; int token; } EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW -EXPORT_UNUSED_SYMBOL, EXPORT_SYMBOL_KEYW -EXPORT_UNUSED_SYMBOL_GPL, EXPORT_SYMBOL_KEYW __asm, ASM_KEYW __asm__, ASM_KEYW __attribute, ATTRIBUTE_KEYW diff --git a/trunk/scripts/headers.sh b/trunk/scripts/headers.sh index 1ddcdd38d97f..0308ecc10d5b 100755 --- a/trunk/scripts/headers.sh +++ b/trunk/scripts/headers.sh @@ -8,6 +8,8 @@ do_command() { if [ -f ${srctree}/arch/$2/include/asm/Kbuild ]; then make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 + elif [ -f ${srctree}/include/asm-$2/Kbuild ]; then + make ARCH=$2 KBUILD_HEADERS=$1 headers_$1 else printf "Ignoring arch: %s\n" ${arch} fi diff --git a/trunk/scripts/kconfig/Makefile b/trunk/scripts/kconfig/Makefile index 999e8a7d5bf7..80599e3a7994 100644 --- a/trunk/scripts/kconfig/Makefile +++ b/trunk/scripts/kconfig/Makefile @@ -27,7 +27,6 @@ oldconfig: $(obj)/conf $< -o $(Kconfig) silentoldconfig: $(obj)/conf - $(Q)mkdir -p include/generated $< -s $(Kconfig) localmodconfig: $(obj)/streamline_config.pl $(obj)/conf diff --git a/trunk/scripts/kconfig/confdata.c b/trunk/scripts/kconfig/confdata.c index c4dec80cfd8e..b55e72ff2fc6 100644 --- a/trunk/scripts/kconfig/confdata.c +++ b/trunk/scripts/kconfig/confdata.c @@ -677,7 +677,7 @@ int conf_write_autoconf(void) struct symbol *sym; const char *str; const char *name; - FILE *out, *tristate, *out_h; + FILE *out, *out_h; time_t now; int i, l; @@ -692,16 +692,9 @@ int conf_write_autoconf(void) if (!out) return 1; - tristate = fopen(".tmpconfig_tristate", "w"); - if (!tristate) { - fclose(out); - return 1; - } - out_h = fopen(".tmpconfig.h", "w"); if (!out_h) { fclose(out); - fclose(tristate); return 1; } @@ -714,9 +707,6 @@ int conf_write_autoconf(void) "# %s" "#\n", sym_get_string_value(sym), ctime(&now)); - fprintf(tristate, "#\n" - "# Automatically generated - do not edit\n" - "\n"); fprintf(out_h, "/*\n" " * Automatically generated C config: don't edit\n" " * Linux kernel version: %s\n" @@ -737,14 +727,10 @@ int conf_write_autoconf(void) break; case mod: fprintf(out, "CONFIG_%s=m\n", sym->name); - fprintf(tristate, "CONFIG_%s=M\n", sym->name); fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); break; case yes: fprintf(out, "CONFIG_%s=y\n", sym->name); - if (sym->type == S_TRISTATE) - fprintf(tristate, "CONFIG_%s=Y\n", - sym->name); fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); break; } @@ -786,19 +772,13 @@ int conf_write_autoconf(void) } } fclose(out); - fclose(tristate); fclose(out_h); name = getenv("KCONFIG_AUTOHEADER"); if (!name) - name = "include/generated/autoconf.h"; + name = "include/linux/autoconf.h"; if (rename(".tmpconfig.h", name)) return 1; - name = getenv("KCONFIG_TRISTATE"); - if (!name) - name = "include/config/tristate.conf"; - if (rename(".tmpconfig_tristate", name)) - return 1; name = conf_get_autoconfig_name(); /* * This must be the last step, kbuild has a dependency on auto.conf diff --git a/trunk/scripts/mkcompile_h b/trunk/scripts/mkcompile_h index 23dbad80cce9..bce3d0fe6fbd 100755 --- a/trunk/scripts/mkcompile_h +++ b/trunk/scripts/mkcompile_h @@ -14,7 +14,7 @@ vecho() { [ "${quiet}" = "silent_" ] || echo "$@" ; } # So "sudo make install" won't change the "compiled by " # do "compiled by root" -if [ -r $TARGET -a ! -O include/generated/autoconf.h ]; then +if [ -r $TARGET -a ! -O include/linux/autoconf.h ]; then vecho " SKIPPED $TARGET" exit 0 fi diff --git a/trunk/scripts/mod/modpost.c b/trunk/scripts/mod/modpost.c index 20923613467c..6c4ffc767b91 100644 --- a/trunk/scripts/mod/modpost.c +++ b/trunk/scripts/mod/modpost.c @@ -15,7 +15,7 @@ #include #include #include "modpost.h" -#include "../../include/generated/autoconf.h" +#include "../../include/linux/autoconf.h" #include "../../include/linux/license.h" /* Some toolchains use a `_' prefix for all user symbols. */ diff --git a/trunk/scripts/package/Makefile b/trunk/scripts/package/Makefile index 62fcc3a7f4d3..f67cc885c807 100644 --- a/trunk/scripts/package/Makefile +++ b/trunk/scripts/package/Makefile @@ -77,27 +77,9 @@ clean-files += $(objtree)/binkernel.spec # Deb target # --------------------------------------------------------------------------- -quiet_cmd_builddeb = BUILDDEB - cmd_builddeb = set -e; \ - test `id -u` = 0 || \ - test -n "$(KBUILD_PKG_ROOTCMD)" || { \ - which fakeroot >/dev/null 2>&1 && \ - KBUILD_PKG_ROOTCMD="fakeroot -u"; \ - } || { \ - echo; \ - echo "builddeb must be run as root (or using fakeroot)."; \ - echo "KBUILD_PKG_ROOTCMD is unset and fakeroot not found."; \ - echo "Try setting KBUILD_PKG_ROOTCMD to a command to acquire"; \ - echo "root privileges (e.g., 'fakeroot -u' or 'sudo')."; \ - false; \ - } && \ - \ - $$KBUILD_PKG_ROOTCMD $(CONFIG_SHELL) \ - $(srctree)/scripts/package/builddeb - deb-pkg: FORCE $(MAKE) KBUILD_SRC= - $(call cmd,builddeb) + $(CONFIG_SHELL) $(srctree)/scripts/package/builddeb clean-dirs += $(objtree)/debian/ diff --git a/trunk/scripts/package/buildtar b/trunk/scripts/package/buildtar index 51b2aa0acb82..b1fd48db1640 100644 --- a/trunk/scripts/package/buildtar +++ b/trunk/scripts/package/buildtar @@ -101,11 +101,7 @@ esac # ( cd "${tmpdir}" - opts= - if tar --owner=root --group=root --help >/dev/null 2>&1; then - opts="--owner=root --group=root" - fi - tar cf - . $opts | ${compress} > "${tarball}${file_ext}" + tar cf - . | ${compress} > "${tarball}${file_ext}" ) echo "Tarball successfully created in ${tarball}${file_ext}" diff --git a/trunk/scripts/tags.sh b/trunk/scripts/tags.sh index 1a0c44d7c4a7..d52f7a01557c 100755 --- a/trunk/scripts/tags.sh +++ b/trunk/scripts/tags.sh @@ -89,13 +89,7 @@ all_defconfigs() docscope() { - # always use absolute paths for cscope, as recommended by cscope - # upstream - case "$tree" in - /*) ;; - *) tree=$PWD/$tree ;; - esac - (cd /; echo \-k; echo \-q; all_sources) > cscope.files + (echo \-k; echo \-q; all_sources) > cscope.files cscope -b -f cscope.out } diff --git a/trunk/scripts/unifdef.c b/trunk/scripts/unifdef.c index 44d39785e50d..30d459fb0709 100644 --- a/trunk/scripts/unifdef.c +++ b/trunk/scripts/unifdef.c @@ -1,5 +1,13 @@ /* - * Copyright (c) 2002 - 2009 Tony Finch + * Copyright (c) 2002 - 2005 Tony Finch . All rights reserved. + * + * This code is derived from software contributed to Berkeley by Dave Yost. + * It was rewritten to support ANSI C by Tony Finch. The original version of + * unifdef carried the following copyright notice. None of its code remains + * in this version (though some of the names remain). + * + * Copyright (c) 1985, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,20 +31,23 @@ * SUCH DAMAGE. */ -/* - * This code was derived from software contributed to Berkeley by Dave Yost. - * It was rewritten to support ANSI C by Tony Finch. The original version - * of unifdef carried the 4-clause BSD copyright licence. None of its code - * remains in this version (though some of the names remain) so it now - * carries a more liberal licence. - * - * The latest version is available from http://dotat.at/prog/unifdef - */ +#include -static const char * const copyright[] = { - "@(#) Copyright (c) 2002 - 2009 Tony Finch \n", - "$dotat: unifdef/unifdef.c,v 1.190 2009/11/27 17:21:26 fanf2 Exp $", -}; +#ifndef lint +#if 0 +static const char copyright[] = +"@(#) Copyright (c) 1985, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif +#ifdef __IDSTRING +__IDSTRING(Berkeley, "@(#)unifdef.c 8.1 (Berkeley) 6/6/93"); +__IDSTRING(NetBSD, "$NetBSD: unifdef.c,v 1.8 2000/07/03 02:51:36 matt Exp $"); +__IDSTRING(dotat, "$dotat: things/unifdef.c,v 1.171 2005/03/08 12:38:48 fanf2 Exp $"); +#endif +#endif /* not lint */ +#ifdef __FBSDID +__FBSDID("$FreeBSD: /repoman/r/ncvs/src/usr.bin/unifdef/unifdef.c,v 1.20 2005/05/21 09:55:09 ru Exp $"); +#endif /* * unifdef - remove ifdef'ed lines @@ -61,6 +72,8 @@ static const char * const copyright[] = { #include #include +size_t strlcpy(char *dst, const char *src, size_t siz); + /* types of input lines: */ typedef enum { LT_TRUEI, /* a true #if with ignore flag */ @@ -77,7 +90,6 @@ typedef enum { LT_DODGY_LAST = LT_DODGY + LT_ENDIF, LT_PLAIN, /* ordinary line */ LT_EOF, /* end of file */ - LT_ERROR, /* unevaluable #if */ LT_COUNT } Linetype; @@ -88,7 +100,7 @@ static char const * const linetype_name[] = { "DODGY IF", "DODGY TRUE", "DODGY FALSE", "DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE", "DODGY ELSE", "DODGY ENDIF", - "PLAIN", "EOF", "ERROR" + "PLAIN", "EOF" }; /* state of #if processing */ @@ -156,13 +168,11 @@ static char const * const linestate_name[] = { * Globals. */ -static bool compblank; /* -B: compress blank lines */ -static bool lnblank; /* -b: blank deleted lines */ static bool complement; /* -c: do the complement */ static bool debugging; /* -d: debugging reports */ static bool iocccok; /* -e: fewer IOCCC errors */ -static bool strictlogic; /* -K: keep ambiguous #ifs */ static bool killconsts; /* -k: eval constant #ifs */ +static bool lnblank; /* -l: blank deleted lines */ static bool lnnum; /* -n: add #line directives */ static bool symlist; /* -s: output symbol list */ static bool text; /* -t: this is a text file */ @@ -186,9 +196,7 @@ static bool ignoring[MAXDEPTH]; /* ignore comments state */ static int stifline[MAXDEPTH]; /* start of current #if */ static int depth; /* current #if nesting */ static int delcount; /* count of deleted lines */ -static unsigned blankcount; /* count of blank lines */ -static unsigned blankmax; /* maximum recent blankcount */ -static bool constexpr; /* constant #if expression */ +static bool keepthis; /* don't delete constant #if */ static int exitstat; /* program exit status */ @@ -198,14 +206,13 @@ static void done(void); static void error(const char *); static int findsym(const char *); static void flushline(bool); -static Linetype parseline(void); +static Linetype get_line(void); static Linetype ifeval(const char **); static void ignoreoff(void); static void ignoreon(void); static void keywordedit(const char *); static void nest(void); static void process(void); -static const char *skipargs(const char *); static const char *skipcomment(const char *); static const char *skipsym(const char *); static void state(Ifstate); @@ -213,7 +220,7 @@ static int strlcmp(const char *, const char *, size_t); static void unnest(void); static void usage(void); -#define endsym(c) (!isalnum((unsigned char)c) && c != '_') +#define endsym(c) (!isalpha((unsigned char)c) && !isdigit((unsigned char)c) && c != '_') /* * The main program. @@ -223,7 +230,7 @@ main(int argc, char *argv[]) { int opt; - while ((opt = getopt(argc, argv, "i:D:U:I:BbcdeKklnst")) != -1) + while ((opt = getopt(argc, argv, "i:D:U:I:cdeklnst")) != -1) switch (opt) { case 'i': /* treat stuff controlled by these symbols as text */ /* @@ -248,13 +255,6 @@ main(int argc, char *argv[]) case 'I': /* no-op for compatibility with cpp */ break; - case 'B': /* compress blank lines around removed section */ - compblank = true; - break; - case 'b': /* blank deleted lines instead of omitting them */ - case 'l': /* backwards compatibility */ - lnblank = true; - break; case 'c': /* treat -D as -U and vice versa */ complement = true; break; @@ -264,12 +264,12 @@ main(int argc, char *argv[]) case 'e': /* fewer errors from dodgy lines */ iocccok = true; break; - case 'K': /* keep ambiguous #ifs */ - strictlogic = true; - break; case 'k': /* process constant #ifs */ killconsts = true; break; + case 'l': /* blank deleted lines instead of omitting them */ + lnblank = true; + break; case 'n': /* add #line directive after deleted lines */ lnnum = true; break; @@ -284,8 +284,6 @@ main(int argc, char *argv[]) } argc -= optind; argv += optind; - if (compblank && lnblank) - errx(2, "-B and -b are mutually exclusive"); if (argc > 1) { errx(2, "can only do one file"); } else if (argc == 1 && strcmp(*argv, "-") != 0) { @@ -304,7 +302,7 @@ main(int argc, char *argv[]) static void usage(void) { - fprintf(stderr, "usage: unifdef [-BbcdeKknst] [-Ipath]" + fprintf(stderr, "usage: unifdef [-cdeklnst] [-Ipath]" " [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n"); exit(2); } @@ -385,46 +383,46 @@ static state_fn * const trans_table[IS_COUNT][LT_COUNT] = { /* IS_OUTSIDE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eendif, - print, done, abort }, + print, done }, /* IS_FALSE_PREFIX */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc, - drop, Eeof, abort }, + drop, Eeof }, /* IS_TRUE_PREFIX */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc, - print, Eeof, abort }, + print, Eeof }, /* IS_PASS_MIDDLE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif, Oiffy, Oiffy, Fpass, Oif, Oif, Pelif, Oelif, Oelif, Pelse, Pendif, - print, Eeof, abort }, + print, Eeof }, /* IS_FALSE_MIDDLE */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc, - drop, Eeof, abort }, + drop, Eeof }, /* IS_TRUE_MIDDLE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Pendif, - print, Eeof, abort }, + print, Eeof }, /* IS_PASS_ELSE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Pendif, - print, Eeof, abort }, + print, Eeof }, /* IS_FALSE_ELSE */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc, - drop, Eeof, abort }, + drop, Eeof }, /* IS_TRUE_ELSE */ { Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif, Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eioccc, - print, Eeof, abort }, + print, Eeof }, /* IS_FALSE_TRAILER */ { Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif, Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc, - drop, Eeof, abort } + drop, Eeof } /*TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF (DODGY) - PLAIN EOF ERROR */ + PLAIN EOF */ }; /* @@ -465,11 +463,9 @@ keywordedit(const char *replacement) static void nest(void) { - if (depth > MAXDEPTH-1) - abort(); /* bug */ - if (depth == MAXDEPTH-1) - error("Too many levels of nesting"); depth += 1; + if (depth >= MAXDEPTH) + error("Too many levels of nesting"); stifline[depth] = linenum; } static void @@ -494,23 +490,15 @@ flushline(bool keep) if (symlist) return; if (keep ^ complement) { - bool blankline = tline[strspn(tline, " \t\n")] == '\0'; - if (blankline && compblank && blankcount != blankmax) { - delcount += 1; - blankcount += 1; - } else { - if (lnnum && delcount > 0) - printf("#line %d\n", linenum); - fputs(tline, stdout); - delcount = 0; - blankmax = blankcount = blankline ? blankcount + 1 : 0; - } + if (lnnum && delcount > 0) + printf("#line %d\n", linenum); + fputs(tline, stdout); + delcount = 0; } else { if (lnblank) putc('\n', stdout); exitstat = 1; delcount += 1; - blankcount = 0; } } @@ -522,12 +510,9 @@ process(void) { Linetype lineval; - /* When compressing blank lines, act as if the file - is preceded by a large number of blank lines. */ - blankmax = blankcount = 1000; for (;;) { linenum++; - lineval = parseline(); + lineval = get_line(); trans_table[ifstate[depth]][lineval](); debug("process %s -> %s depth %d", linetype_name[lineval], @@ -541,7 +526,7 @@ process(void) * help from skipcomment(). */ static Linetype -parseline(void) +get_line(void) { const char *cp; int cursym; @@ -610,21 +595,9 @@ parseline(void) if (incomment) linestate = LS_DIRTY; } - /* skipcomment normally changes the state, except - if the last line of the file lacks a newline, or - if there is too much whitespace in a directive */ - if (linestate == LS_HASH) { - size_t len = cp - tline; - if (fgets(tline + len, MAXLINE - len, input) == NULL) { - /* append the missing newline */ - tline[len+0] = '\n'; - tline[len+1] = '\0'; - cp++; - linestate = LS_START; - } else { - linestate = LS_DIRTY; - } - } + /* skipcomment should have changed the state */ + if (linestate == LS_HASH) + abort(); /* bug */ } if (linestate == LS_DIRTY) { while (*cp != '\0') @@ -637,40 +610,17 @@ parseline(void) /* * These are the binary operators that are supported by the expression - * evaluator. + * evaluator. Note that if support for division is added then we also + * need short-circuiting booleans because of divide-by-zero. */ -static Linetype op_strict(int *p, int v, Linetype at, Linetype bt) { - if(at == LT_IF || bt == LT_IF) return (LT_IF); - return (*p = v, v ? LT_TRUE : LT_FALSE); -} -static Linetype op_lt(int *p, Linetype at, int a, Linetype bt, int b) { - return op_strict(p, a < b, at, bt); -} -static Linetype op_gt(int *p, Linetype at, int a, Linetype bt, int b) { - return op_strict(p, a > b, at, bt); -} -static Linetype op_le(int *p, Linetype at, int a, Linetype bt, int b) { - return op_strict(p, a <= b, at, bt); -} -static Linetype op_ge(int *p, Linetype at, int a, Linetype bt, int b) { - return op_strict(p, a >= b, at, bt); -} -static Linetype op_eq(int *p, Linetype at, int a, Linetype bt, int b) { - return op_strict(p, a == b, at, bt); -} -static Linetype op_ne(int *p, Linetype at, int a, Linetype bt, int b) { - return op_strict(p, a != b, at, bt); -} -static Linetype op_or(int *p, Linetype at, int a, Linetype bt, int b) { - if (!strictlogic && (at == LT_TRUE || bt == LT_TRUE)) - return (*p = 1, LT_TRUE); - return op_strict(p, a || b, at, bt); -} -static Linetype op_and(int *p, Linetype at, int a, Linetype bt, int b) { - if (!strictlogic && (at == LT_FALSE || bt == LT_FALSE)) - return (*p = 0, LT_FALSE); - return op_strict(p, a && b, at, bt); -} +static int op_lt(int a, int b) { return (a < b); } +static int op_gt(int a, int b) { return (a > b); } +static int op_le(int a, int b) { return (a <= b); } +static int op_ge(int a, int b) { return (a >= b); } +static int op_eq(int a, int b) { return (a == b); } +static int op_ne(int a, int b) { return (a != b); } +static int op_or(int a, int b) { return (a || b); } +static int op_and(int a, int b) { return (a && b); } /* * An evaluation function takes three arguments, as follows: (1) a pointer to @@ -679,8 +629,8 @@ static Linetype op_and(int *p, Linetype at, int a, Linetype bt, int b) { * value of the expression; and (3) a pointer to a char* that points to the * expression to be evaluated and that is updated to the end of the expression * when evaluation is complete. The function returns LT_FALSE if the value of - * the expression is zero, LT_TRUE if it is non-zero, LT_IF if the expression - * depends on an unknown symbol, or LT_ERROR if there is a parse failure. + * the expression is zero, LT_TRUE if it is non-zero, or LT_IF if the + * expression could not be evaluated. */ struct ops; @@ -699,7 +649,7 @@ static const struct ops { eval_fn *inner; struct op { const char *str; - Linetype (*fn)(int *, Linetype, int, Linetype, int); + int (*fn)(int, int); } op[5]; } eval_ops[] = { { eval_table, { { "||", op_or } } }, @@ -714,8 +664,8 @@ static const struct ops { /* * Function for evaluating the innermost parts of expressions, - * viz. !expr (expr) number defined(symbol) symbol - * We reset the constexpr flag in the last two cases. + * viz. !expr (expr) defined(symbol) symbol number + * We reset the keepthis flag when we find a non-constant subexpression. */ static Linetype eval_unary(const struct ops *ops, int *valp, const char **cpp) @@ -723,83 +673,68 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp) const char *cp; char *ep; int sym; - bool defparen; - Linetype lt; cp = skipcomment(*cpp); if (*cp == '!') { debug("eval%d !", ops - eval_ops); cp++; - lt = eval_unary(ops, valp, &cp); - if (lt == LT_ERROR) - return (LT_ERROR); - if (lt != LT_IF) { - *valp = !*valp; - lt = *valp ? LT_TRUE : LT_FALSE; + if (eval_unary(ops, valp, &cp) == LT_IF) { + *cpp = cp; + return (LT_IF); } + *valp = !*valp; } else if (*cp == '(') { cp++; debug("eval%d (", ops - eval_ops); - lt = eval_table(eval_ops, valp, &cp); - if (lt == LT_ERROR) - return (LT_ERROR); + if (eval_table(eval_ops, valp, &cp) == LT_IF) + return (LT_IF); cp = skipcomment(cp); if (*cp++ != ')') - return (LT_ERROR); + return (LT_IF); } else if (isdigit((unsigned char)*cp)) { debug("eval%d number", ops - eval_ops); *valp = strtol(cp, &ep, 0); - if (ep == cp) - return (LT_ERROR); - lt = *valp ? LT_TRUE : LT_FALSE; cp = skipsym(cp); } else if (strncmp(cp, "defined", 7) == 0 && endsym(cp[7])) { cp = skipcomment(cp+7); debug("eval%d defined", ops - eval_ops); - if (*cp == '(') { - cp = skipcomment(cp+1); - defparen = true; - } else { - defparen = false; - } + if (*cp++ != '(') + return (LT_IF); + cp = skipcomment(cp); sym = findsym(cp); - if (sym < 0) { - lt = LT_IF; - } else { - *valp = (value[sym] != NULL); - lt = *valp ? LT_TRUE : LT_FALSE; - } cp = skipsym(cp); cp = skipcomment(cp); - if (defparen && *cp++ != ')') - return (LT_ERROR); - constexpr = false; + if (*cp++ != ')') + return (LT_IF); + if (sym >= 0) + *valp = (value[sym] != NULL); + else { + *cpp = cp; + return (LT_IF); + } + keepthis = false; } else if (!endsym(*cp)) { debug("eval%d symbol", ops - eval_ops); sym = findsym(cp); - cp = skipsym(cp); - if (sym < 0) { - lt = LT_IF; - cp = skipargs(cp); - } else if (value[sym] == NULL) { + if (sym < 0) + return (LT_IF); + if (value[sym] == NULL) *valp = 0; - lt = LT_FALSE; - } else { + else { *valp = strtol(value[sym], &ep, 0); if (*ep != '\0' || ep == value[sym]) - return (LT_ERROR); - lt = *valp ? LT_TRUE : LT_FALSE; - cp = skipargs(cp); + return (LT_IF); } - constexpr = false; + cp = skipsym(cp); + keepthis = false; } else { debug("eval%d bad expr", ops - eval_ops); - return (LT_ERROR); + return (LT_IF); } *cpp = cp; debug("eval%d = %d", ops - eval_ops, *valp); - return (lt); + return (*valp ? LT_TRUE : LT_FALSE); } /* @@ -811,13 +746,11 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) const struct op *op; const char *cp; int val; - Linetype lt, rt; + Linetype lhs, rhs; debug("eval%d", ops - eval_ops); cp = *cpp; - lt = ops->inner(ops+1, valp, &cp); - if (lt == LT_ERROR) - return (LT_ERROR); + lhs = ops->inner(ops+1, valp, &cp); for (;;) { cp = skipcomment(cp); for (op = ops->op; op->str != NULL; op++) @@ -827,16 +760,32 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) break; cp += strlen(op->str); debug("eval%d %s", ops - eval_ops, op->str); - rt = ops->inner(ops+1, &val, &cp); - if (rt == LT_ERROR) - return (LT_ERROR); - lt = op->fn(valp, lt, *valp, rt, val); + rhs = ops->inner(ops+1, &val, &cp); + if (op->fn == op_and && (lhs == LT_FALSE || rhs == LT_FALSE)) { + debug("eval%d: and always false", ops - eval_ops); + if (lhs == LT_IF) + *valp = val; + lhs = LT_FALSE; + continue; + } + if (op->fn == op_or && (lhs == LT_TRUE || rhs == LT_TRUE)) { + debug("eval%d: or always true", ops - eval_ops); + if (lhs == LT_IF) + *valp = val; + lhs = LT_TRUE; + continue; + } + if (rhs == LT_IF) + lhs = LT_IF; + if (lhs != LT_IF) + *valp = op->fn(*valp, val); } *cpp = cp; debug("eval%d = %d", ops - eval_ops, *valp); - debug("eval%d lt = %s", ops - eval_ops, linetype_name[lt]); - return (lt); + if (lhs != LT_IF) + lhs = (*valp ? LT_TRUE : LT_FALSE); + return lhs; } /* @@ -847,14 +796,17 @@ eval_table(const struct ops *ops, int *valp, const char **cpp) static Linetype ifeval(const char **cpp) { + const char *cp = *cpp; int ret; - int val = 0; + int val; debug("eval %s", *cpp); - constexpr = killconsts ? false : true; - ret = eval_table(eval_ops, &val, cpp); + keepthis = killconsts ? false : true; + ret = eval_table(eval_ops, &val, &cp); + if (ret != LT_IF) + *cpp = cp; debug("eval = %d", val); - return (constexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret); + return (keepthis ? LT_IF : ret); } /* @@ -965,31 +917,6 @@ skipcomment(const char *cp) return (cp); } -/* - * Skip macro arguments. - */ -static const char * -skipargs(const char *cp) -{ - const char *ocp = cp; - int level = 0; - cp = skipcomment(cp); - if (*cp != '(') - return (cp); - do { - if (*cp == '(') - level++; - if (*cp == ')') - level--; - cp = skipcomment(cp+1); - } while (level != 0 && *cp != '\0'); - if (level == 0) - return (cp); - else - /* Rewind and re-detect the syntax error later. */ - return (ocp); -} - /* * Skip over an identifier. */ @@ -1002,7 +929,7 @@ skipsym(const char *cp) } /* - * Look for the symbol in the symbol table. If it is found, we return + * Look for the symbol in the symbol table. If is is found, we return * the symbol table index, else we return -1. */ static int diff --git a/trunk/usr/gen_init_cpio.c b/trunk/usr/gen_init_cpio.c index b2b3c2d1cf8b..83b3dde1a83b 100644 --- a/trunk/usr/gen_init_cpio.c +++ b/trunk/usr/gen_init_cpio.c @@ -354,10 +354,7 @@ static int cpio_mkfile(const char *name, const char *location, push_pad(); if (size) { - if (fwrite(filebuf, size, 1, stdout) != 1) { - fprintf(stderr, "writing filebuf failed\n"); - goto error; - } + fwrite(filebuf, size, 1, stdout); offset += size; push_pad(); }