Merge branch 'akpm' (Andrew's patch-bomb)
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 23 Mar 2012 23:59:10 +0000 (16:59 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 23 Mar 2012 23:59:10 +0000 (16:59 -0700)
Merge second batch of patches from Andrew Morton:
 - various misc things
 - core kernel changes to prctl, exit, exec, init, etc.
 - kernel/watchdog.c updates
 - get_maintainer
 - MAINTAINERS
 - the backlight driver queue
 - core bitops code cleanups
 - the led driver queue
 - some core prio_tree work
 - checkpatch udpates
 - largeish crc32 update
 - a new poll() feature for the v4l guys
 - the rtc driver queue
 - fatfs
 - ptrace
 - signals
 - kmod/usermodehelper updates
 - coredump
 - procfs updates

* emailed from Andrew Morton <akpm@linux-foundation.org>: (141 commits)
  seq_file: add seq_set_overflow(), seq_overflow()
  proc-ns: use d_set_d_op() API to set dentry ops in proc_ns_instantiate().
  procfs: speed up /proc/pid/stat, statm
  procfs: add num_to_str() to speed up /proc/stat
  proc: speed up /proc/stat handling
  fs/proc/kcore.c: make get_sparsemem_vmemmap_info() static
  coredump: add VM_NODUMP, MADV_NODUMP, MADV_CLEAR_NODUMP
  coredump: remove VM_ALWAYSDUMP flag
  kmod: make __request_module() killable
  kmod: introduce call_modprobe() helper
  usermodehelper: ____call_usermodehelper() doesn't need do_exit()
  usermodehelper: kill umh_wait, renumber UMH_* constants
  usermodehelper: implement UMH_KILLABLE
  usermodehelper: introduce umh_complete(sub_info)
  usermodehelper: use UMH_WAIT_PROC consistently
  signal: zap_pid_ns_processes: s/SEND_SIG_NOINFO/SEND_SIG_FORCED/
  signal: oom_kill_task: use SEND_SIG_FORCED instead of force_sig()
  signal: cosmetic, s/from_ancestor_ns/force/ in prepare_signal() paths
  signal: give SEND_SIG_FORCED more power to beat SIGNAL_UNKILLABLE
  Hexagon: use set_current_blocked() and block_sigmask()
  ...

213 files changed:
Documentation/00-INDEX
Documentation/backlight/lp855x-driver.txt [new file with mode: 0644]
Documentation/crc32.txt [new file with mode: 0644]
Documentation/leds/leds-lp5521.txt
MAINTAINERS
arch/Kconfig
arch/alpha/include/asm/mman.h
arch/arm/include/asm/pgtable-nommu.h
arch/arm/kernel/process.c
arch/blackfin/Kconfig
arch/blackfin/include/asm/irq.h
arch/c6x/include/asm/pgtable.h
arch/hexagon/kernel/signal.c
arch/hexagon/kernel/vdso.c
arch/microblaze/include/asm/pgtable.h
arch/mips/include/asm/mman.h
arch/mips/kernel/vdso.c
arch/mn10300/Kconfig
arch/mn10300/include/asm/reset-regs.h
arch/openrisc/include/asm/pgtable.h
arch/parisc/include/asm/mman.h
arch/powerpc/kernel/vdso.c
arch/s390/kernel/vdso.c
arch/sh/kernel/vsyscall/vsyscall.c
arch/sparc/Kconfig
arch/sparc/include/asm/irq_64.h
arch/tile/mm/elf.c
arch/um/kernel/signal.c
arch/unicore32/kernel/process.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/irqinit.c
arch/x86/um/mem_32.c
arch/x86/um/vdso/vma.c
arch/x86/vdso/vdso32-setup.c
arch/x86/vdso/vma.c
arch/xtensa/include/asm/mman.h
crypto/Kconfig
crypto/crc32c.c
drivers/base/regmap/regcache-lzo.c
drivers/block/drbd/drbd_nl.c
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/led-class.c
drivers/leds/led-core.c
drivers/leds/leds-gpio.c
drivers/leds/leds-lm3530.c
drivers/leds/leds-lp5521.c
drivers/leds/leds-lp5523.c
drivers/leds/leds-pca9633.c [new file with mode: 0644]
drivers/leds/leds-tca6507.c
drivers/mtd/chips/cfi_cmdset_0001.c
drivers/mtd/mtdchar.c
drivers/rtc/Kconfig
drivers/rtc/Makefile
drivers/rtc/rtc-at91sam9.c
drivers/rtc/rtc-bq32k.c
drivers/rtc/rtc-cmos.c
drivers/rtc/rtc-coh901331.c
drivers/rtc/rtc-da9052.c [new file with mode: 0644]
drivers/rtc/rtc-davinci.c
drivers/rtc/rtc-ds1305.c
drivers/rtc/rtc-ds1307.c
drivers/rtc/rtc-ds1374.c
drivers/rtc/rtc-ds1390.c
drivers/rtc/rtc-ds1511.c
drivers/rtc/rtc-ds1553.c
drivers/rtc/rtc-ds1672.c
drivers/rtc/rtc-ds3232.c
drivers/rtc/rtc-ds3234.c
drivers/rtc/rtc-em3027.c
drivers/rtc/rtc-fm3130.c
drivers/rtc/rtc-isl12022.c
drivers/rtc/rtc-isl1208.c
drivers/rtc/rtc-lpc32xx.c
drivers/rtc/rtc-ls1x.c [new file with mode: 0644]
drivers/rtc/rtc-m41t80.c
drivers/rtc/rtc-m41t93.c
drivers/rtc/rtc-m41t94.c
drivers/rtc/rtc-max6900.c
drivers/rtc/rtc-max6902.c
drivers/rtc/rtc-max8925.c
drivers/rtc/rtc-mpc5121.c
drivers/rtc/rtc-mrst.c
drivers/rtc/rtc-mv.c
drivers/rtc/rtc-nuc900.c
drivers/rtc/rtc-omap.c
drivers/rtc/rtc-pcf2123.c
drivers/rtc/rtc-pcf8563.c
drivers/rtc/rtc-pcf8583.c
drivers/rtc/rtc-pl030.c
drivers/rtc/rtc-pl031.c
drivers/rtc/rtc-pm8xxx.c
drivers/rtc/rtc-pxa.c
drivers/rtc/rtc-r9701.c
drivers/rtc/rtc-rs5c348.c
drivers/rtc/rtc-rs5c372.c
drivers/rtc/rtc-rv3029c2.c
drivers/rtc/rtc-rx8025.c
drivers/rtc/rtc-rx8581.c
drivers/rtc/rtc-s35390a.c
drivers/rtc/rtc-s3c.c
drivers/rtc/rtc-sa1100.c
drivers/rtc/rtc-sh.c
drivers/rtc/rtc-spear.c
drivers/rtc/rtc-stk17ta8.c
drivers/rtc/rtc-twl.c
drivers/rtc/rtc-tx4939.c
drivers/rtc/rtc-vr41xx.c
drivers/rtc/rtc-x1205.c
drivers/s390/char/sclp_cmd.c
drivers/staging/rtl8187se/r8180_core.c
drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
drivers/staging/telephony/ixj.c
drivers/uwb/allocator.c
drivers/video/backlight/88pm860x_bl.c
drivers/video/backlight/Kconfig
drivers/video/backlight/Makefile
drivers/video/backlight/aat2870_bl.c
drivers/video/backlight/adp5520_bl.c
drivers/video/backlight/adp8860_bl.c
drivers/video/backlight/adp8870_bl.c
drivers/video/backlight/ams369fg06.c
drivers/video/backlight/corgi_lcd.c
drivers/video/backlight/cr_bllcd.c
drivers/video/backlight/da903x_bl.c
drivers/video/backlight/l4f00242t03.c
drivers/video/backlight/ld9040.c
drivers/video/backlight/lms283gf05.c
drivers/video/backlight/lp855x_bl.c [new file with mode: 0644]
drivers/video/backlight/ltv350qv.c
drivers/video/backlight/max8925_bl.c
drivers/video/backlight/omap1_bl.c
drivers/video/backlight/ot200_bl.c [new file with mode: 0644]
drivers/video/backlight/pandora_bl.c [new file with mode: 0644]
drivers/video/backlight/pcf50633-backlight.c
drivers/video/backlight/platform_lcd.c
drivers/video/backlight/pwm_bl.c
drivers/video/backlight/s6e63m0.c
drivers/video/backlight/tdo24m.c
drivers/video/backlight/tosa_bl.c
drivers/video/backlight/tosa_lcd.c
drivers/video/backlight/vgg2432a4.c
drivers/video/backlight/wm831x_bl.c
drivers/video/uvesafb.c
fs/binfmt_elf.c
fs/binfmt_misc.c
fs/block_dev.c
fs/eventpoll.c
fs/fat/namei_vfat.c
fs/notify/notification.c
fs/pipe.c
fs/proc/array.c
fs/proc/kcore.c
fs/proc/namespaces.c
fs/proc/stat.c
fs/select.c
fs/seq_file.c
include/asm-generic/bug.h
include/asm-generic/mman-common.h
include/asm-generic/vmlinux.lds.h
include/drm/drm_mode.h
include/linux/bitops.h
include/linux/compiler-gcc.h
include/linux/crc32.h
include/linux/kernel.h
include/linux/kmod.h
include/linux/led-lm3530.h
include/linux/leds-lp5521.h
include/linux/lp855x.h [new file with mode: 0644]
include/linux/magic.h
include/linux/mm.h
include/linux/mmc/ioctl.h
include/linux/nmi.h
include/linux/pipe_fs_i.h
include/linux/poll.h
include/linux/prctl.h
include/linux/ptrace.h
include/linux/rcupdate.h
include/linux/sched.h
include/linux/seq_file.h
include/linux/tracehook.h
include/net/sock.h
include/scsi/scsi_netlink.h
include/sound/compress_params.h
include/xen/xenbus.h
init/calibrate.c
init/do_mounts.c
kernel/exit.c
kernel/fork.c
kernel/kmod.c
kernel/pid_namespace.c
kernel/ptrace.c
kernel/signal.c
kernel/sys.c
kernel/watchdog.c
lib/Kconfig
lib/Kconfig.debug
lib/crc32.c
lib/crc32defs.h
lib/gen_crc32table.c
lib/prio_tree.c
lib/string.c
lib/vsprintf.c
mm/hugetlb.c
mm/madvise.c
mm/memory.c
mm/oom_kill.c
net/unix/af_unix.c
scripts/checkpatch.pl
scripts/get_maintainer.pl
security/keys/request_key.c
security/tomoyo/load_policy.c
tools/perf/util/include/linux/bitops.h

index a1a6432..2214f12 100644 (file)
@@ -104,6 +104,8 @@ cpuidle/
        - info on CPU_IDLE, CPU idle state management subsystem.
 cputopology.txt
        - documentation on how CPU topology info is exported via sysfs.
+crc32.txt
+       - brief tutorial on CRC computation
 cris/
        - directory with info about Linux on CRIS architecture.
 crypto/
diff --git a/Documentation/backlight/lp855x-driver.txt b/Documentation/backlight/lp855x-driver.txt
new file mode 100644 (file)
index 0000000..f5e4caa
--- /dev/null
@@ -0,0 +1,78 @@
+Kernel driver lp855x
+====================
+
+Backlight driver for LP855x ICs
+
+Supported chips:
+       Texas Instruments LP8550, LP8551, LP8552, LP8553 and LP8556
+
+Author: Milo(Woogyom) Kim <milo.kim@ti.com>
+
+Description
+-----------
+
+* Brightness control
+
+Brightness can be controlled by the pwm input or the i2c command.
+The lp855x driver supports both cases.
+
+* Device attributes
+
+1) bl_ctl_mode
+Backlight control mode.
+Value : pwm based or register based
+
+2) chip_id
+The lp855x chip id.
+Value : lp8550/lp8551/lp8552/lp8553/lp8556
+
+Platform data for lp855x
+------------------------
+
+For supporting platform specific data, the lp855x platform data can be used.
+
+* name : Backlight driver name. If it is not defined, default name is set.
+* mode : Brightness control mode. PWM or register based.
+* device_control : Value of DEVICE CONTROL register.
+* initial_brightness : Initial value of backlight brightness.
+* pwm_data : Platform specific pwm generation functions.
+            Only valid when brightness is pwm input mode.
+            Functions should be implemented by PWM driver.
+            - pwm_set_intensity() : set duty of PWM
+            - pwm_get_intensity() : get current duty of PWM
+* load_new_rom_data :
+       0 : use default configuration data
+       1 : update values of eeprom or eprom registers on loading driver
+* size_program : Total size of lp855x_rom_data.
+* rom_data : List of new eeprom/eprom registers.
+
+example 1) lp8552 platform data : i2c register mode with new eeprom data
+
+#define EEPROM_A5_ADDR 0xA5
+#define EEPROM_A5_VAL  0x4f    /* EN_VSYNC=0 */
+
+static struct lp855x_rom_data lp8552_eeprom_arr[] = {
+       {EEPROM_A5_ADDR, EEPROM_A5_VAL},
+};
+
+static struct lp855x_platform_data lp8552_pdata = {
+       .name = "lcd-bl",
+       .mode = REGISTER_BASED,
+       .device_control = I2C_CONFIG(LP8552),
+       .initial_brightness = INITIAL_BRT,
+       .load_new_rom_data = 1,
+       .size_program = ARRAY_SIZE(lp8552_eeprom_arr),
+       .rom_data = lp8552_eeprom_arr,
+};
+
+example 2) lp8556 platform data : pwm input mode with default rom data
+
+static struct lp855x_platform_data lp8556_pdata = {
+       .mode = PWM_BASED,
+       .device_control = PWM_CONFIG(LP8556),
+       .initial_brightness = INITIAL_BRT,
+       .pwm_data = {
+                    .pwm_set_intensity = platform_pwm_set_intensity,
+                    .pwm_get_intensity = platform_pwm_get_intensity,
+                    },
+};
diff --git a/Documentation/crc32.txt b/Documentation/crc32.txt
new file mode 100644 (file)
index 0000000..a08a7dd
--- /dev/null
@@ -0,0 +1,182 @@
+A brief CRC tutorial.
+
+A CRC is a long-division remainder.  You add the CRC to the message,
+and the whole thing (message+CRC) is a multiple of the given
+CRC polynomial.  To check the CRC, you can either check that the
+CRC matches the recomputed value, *or* you can check that the
+remainder computed on the message+CRC is 0.  This latter approach
+is used by a lot of hardware implementations, and is why so many
+protocols put the end-of-frame flag after the CRC.
+
+It's actually the same long division you learned in school, except that
+- We're working in binary, so the digits are only 0 and 1, and
+- When dividing polynomials, there are no carries.  Rather than add and
+  subtract, we just xor.  Thus, we tend to get a bit sloppy about
+  the difference between adding and subtracting.
+
+Like all division, the remainder is always smaller than the divisor.
+To produce a 32-bit CRC, the divisor is actually a 33-bit CRC polynomial.
+Since it's 33 bits long, bit 32 is always going to be set, so usually the
+CRC is written in hex with the most significant bit omitted.  (If you're
+familiar with the IEEE 754 floating-point format, it's the same idea.)
+
+Note that a CRC is computed over a string of *bits*, so you have
+to decide on the endianness of the bits within each byte.  To get
+the best error-detecting properties, this should correspond to the
+order they're actually sent.  For example, standard RS-232 serial is
+little-endian; the most significant bit (sometimes used for parity)
+is sent last.  And when appending a CRC word to a message, you should
+do it in the right order, matching the endianness.
+
+Just like with ordinary division, you proceed one digit (bit) at a time.
+Each step of the division you take one more digit (bit) of the dividend
+and append it to the current remainder.  Then you figure out the
+appropriate multiple of the divisor to subtract to being the remainder
+back into range.  In binary, this is easy - it has to be either 0 or 1,
+and to make the XOR cancel, it's just a copy of bit 32 of the remainder.
+
+When computing a CRC, we don't care about the quotient, so we can
+throw the quotient bit away, but subtract the appropriate multiple of
+the polynomial from the remainder and we're back to where we started,
+ready to process the next bit.
+
+A big-endian CRC written this way would be coded like:
+for (i = 0; i < input_bits; i++) {
+       multiple = remainder & 0x80000000 ? CRCPOLY : 0;
+       remainder = (remainder << 1 | next_input_bit()) ^ multiple;
+}
+
+Notice how, to get at bit 32 of the shifted remainder, we look
+at bit 31 of the remainder *before* shifting it.
+
+But also notice how the next_input_bit() bits we're shifting into
+the remainder don't actually affect any decision-making until
+32 bits later.  Thus, the first 32 cycles of this are pretty boring.
+Also, to add the CRC to a message, we need a 32-bit-long hole for it at
+the end, so we have to add 32 extra cycles shifting in zeros at the
+end of every message,
+
+These details lead to a standard trick: rearrange merging in the
+next_input_bit() until the moment it's needed.  Then the first 32 cycles
+can be precomputed, and merging in the final 32 zero bits to make room
+for the CRC can be skipped entirely.  This changes the code to:
+
+for (i = 0; i < input_bits; i++) {
+       remainder ^= next_input_bit() << 31;
+       multiple = (remainder & 0x80000000) ? CRCPOLY : 0;
+       remainder = (remainder << 1) ^ multiple;
+}
+
+With this optimization, the little-endian code is particularly simple:
+for (i = 0; i < input_bits; i++) {
+       remainder ^= next_input_bit();
+       multiple = (remainder & 1) ? CRCPOLY : 0;
+       remainder = (remainder >> 1) ^ multiple;
+}
+
+The most significant coefficient of the remainder polynomial is stored
+in the least significant bit of the binary "remainder" variable.
+The other details of endianness have been hidden in CRCPOLY (which must
+be bit-reversed) and next_input_bit().
+
+As long as next_input_bit is returning the bits in a sensible order, we don't
+*have* to wait until the last possible moment to merge in additional bits.
+We can do it 8 bits at a time rather than 1 bit at a time:
+for (i = 0; i < input_bytes; i++) {
+       remainder ^= next_input_byte() << 24;
+       for (j = 0; j < 8; j++) {
+               multiple = (remainder & 0x80000000) ? CRCPOLY : 0;
+               remainder = (remainder << 1) ^ multiple;
+       }
+}
+
+Or in little-endian:
+for (i = 0; i < input_bytes; i++) {
+       remainder ^= next_input_byte();
+       for (j = 0; j < 8; j++) {
+               multiple = (remainder & 1) ? CRCPOLY : 0;
+               remainder = (remainder >> 1) ^ multiple;
+       }
+}
+
+If the input is a multiple of 32 bits, you can even XOR in a 32-bit
+word at a time and increase the inner loop count to 32.
+
+You can also mix and match the two loop styles, for example doing the
+bulk of a message byte-at-a-time and adding bit-at-a-time processing
+for any fractional bytes at the end.
+
+To reduce the number of conditional branches, software commonly uses
+the byte-at-a-time table method, popularized by Dilip V. Sarwate,
+"Computation of Cyclic Redundancy Checks via Table Look-Up", Comm. ACM
+v.31 no.8 (August 1998) p. 1008-1013.
+
+Here, rather than just shifting one bit of the remainder to decide
+in the correct multiple to subtract, we can shift a byte at a time.
+This produces a 40-bit (rather than a 33-bit) intermediate remainder,
+and the correct multiple of the polynomial to subtract is found using
+a 256-entry lookup table indexed by the high 8 bits.
+
+(The table entries are simply the CRC-32 of the given one-byte messages.)
+
+When space is more constrained, smaller tables can be used, e.g. two
+4-bit shifts followed by a lookup in a 16-entry table.
+
+It is not practical to process much more than 8 bits at a time using this
+technique, because tables larger than 256 entries use too much memory and,
+more importantly, too much of the L1 cache.
+
+To get higher software performance, a "slicing" technique can be used.
+See "High Octane CRC Generation with the Intel Slicing-by-8 Algorithm",
+ftp://download.intel.com/technology/comms/perfnet/download/slicing-by-8.pdf
+
+This does not change the number of table lookups, but does increase
+the parallelism.  With the classic Sarwate algorithm, each table lookup
+must be completed before the index of the next can be computed.
+
+A "slicing by 2" technique would shift the remainder 16 bits at a time,
+producing a 48-bit intermediate remainder.  Rather than doing a single
+lookup in a 65536-entry table, the two high bytes are looked up in
+two different 256-entry tables.  Each contains the remainder required
+to cancel out the corresponding byte.  The tables are different because the
+polynomials to cancel are different.  One has non-zero coefficients from
+x^32 to x^39, while the other goes from x^40 to x^47.
+
+Since modern processors can handle many parallel memory operations, this
+takes barely longer than a single table look-up and thus performs almost
+twice as fast as the basic Sarwate algorithm.
+
+This can be extended to "slicing by 4" using 4 256-entry tables.
+Each step, 32 bits of data is fetched, XORed with the CRC, and the result
+broken into bytes and looked up in the tables.  Because the 32-bit shift
+leaves the low-order bits of the intermediate remainder zero, the
+final CRC is simply the XOR of the 4 table look-ups.
+
+But this still enforces sequential execution: a second group of table
+look-ups cannot begin until the previous groups 4 table look-ups have all
+been completed.  Thus, the processor's load/store unit is sometimes idle.
+
+To make maximum use of the processor, "slicing by 8" performs 8 look-ups
+in parallel.  Each step, the 32-bit CRC is shifted 64 bits and XORed
+with 64 bits of input data.  What is important to note is that 4 of
+those 8 bytes are simply copies of the input data; they do not depend
+on the previous CRC at all.  Thus, those 4 table look-ups may commence
+immediately, without waiting for the previous loop iteration.
+
+By always having 4 loads in flight, a modern superscalar processor can
+be kept busy and make full use of its L1 cache.
+
+Two more details about CRC implementation in the real world:
+
+Normally, appending zero bits to a message which is already a multiple
+of a polynomial produces a larger multiple of that polynomial.  Thus,
+a basic CRC will not detect appended zero bits (or bytes).  To enable
+a CRC to detect this condition, it's common to invert the CRC before
+appending it.  This makes the remainder of the message+crc come out not
+as zero, but some fixed non-zero value.  (The CRC of the inversion
+pattern, 0xffffffff.)
+
+The same problem applies to zero bits prepended to the message, and a
+similar solution is used.  Instead of starting the CRC computation with
+a remainder of 0, an initial remainder of all ones is used.  As long as
+you start the same way on decoding, it doesn't make a difference.
index c4d8d15..0e542ab 100644 (file)
@@ -43,17 +43,23 @@ Format: 10x mA i.e 10 means 1.0 mA
 example platform data:
 
 Note: chan_nr can have values between 0 and 2.
+The name of each channel can be configurable.
+If the name field is not defined, the default name will be set to 'xxxx:channelN'
+(XXXX : pdata->label or i2c client name, N : channel number)
 
 static struct lp5521_led_config lp5521_led_config[] = {
         {
+               .name = "red",
                 .chan_nr        = 0,
                 .led_current    = 50,
                .max_current    = 130,
         }, {
+               .name = "green",
                 .chan_nr        = 1,
                 .led_current    = 0,
                .max_current    = 130,
         }, {
+               .name = "blue",
                 .chan_nr        = 2,
                 .led_current    = 0,
                .max_current    = 130,
@@ -86,3 +92,60 @@ static struct lp5521_platform_data lp5521_platform_data = {
 
 If the current is set to 0 in the platform data, that channel is
 disabled and it is not visible in the sysfs.
+
+The 'update_config' : CONFIG register (ADDR 08h)
+This value is platform-specific data.
+If update_config is not defined, the CONFIG register is set with
+'LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT'.
+(Enable auto-powersave, set charge pump to auto, red to battery)
+
+example of update_config :
+
+#define LP5521_CONFIGS (LP5521_PWM_HF | LP5521_PWRSAVE_EN | \
+                       LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT | \
+                       LP5521_CLK_INT)
+
+static struct lp5521_platform_data lp5521_pdata = {
+       .led_config = lp5521_led_config,
+       .num_channels = ARRAY_SIZE(lp5521_led_config),
+       .clock_mode = LP5521_CLOCK_INT,
+       .update_config = LP5521_CONFIGS,
+};
+
+LED patterns : LP5521 has autonomous operation without external control.
+Pattern data can be defined in the platform data.
+
+example of led pattern data :
+
+/* RGB(50,5,0) 500ms on, 500ms off, infinite loop */
+static u8 pattern_red[] = {
+               0x40, 0x32, 0x60, 0x00, 0x40, 0x00, 0x60, 0x00,
+               };
+
+static u8 pattern_green[] = {
+               0x40, 0x05, 0x60, 0x00, 0x40, 0x00, 0x60, 0x00,
+               };
+
+static struct lp5521_led_pattern board_led_patterns[] = {
+       {
+               .r = pattern_red,
+               .g = pattern_green,
+               .size_r = ARRAY_SIZE(pattern_red),
+               .size_g = ARRAY_SIZE(pattern_green),
+       },
+};
+
+static struct lp5521_platform_data lp5521_platform_data = {
+        .led_config     = lp5521_led_config,
+        .num_channels   = ARRAY_SIZE(lp5521_led_config),
+        .clock_mode     = LP5521_CLOCK_EXT,
+       .patterns = board_led_patterns,
+       .num_patterns = ARRAY_SIZE(board_led_patterns),
+};
+
+Then predefined led pattern(s) can be executed via the sysfs.
+To start the pattern #1,
+# echo 1 > /sys/bus/i2c/devices/xxxx/led_pattern
+(xxxx : i2c bus & slave address)
+To end the pattern,
+# echo 0 > /sys/bus/i2c/devices/xxxx/led_pattern
index ec9bcb1..f47091a 100644 (file)
@@ -163,7 +163,7 @@ M:  Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 L:     linux-serial@vger.kernel.org
 W:     http://serial.sourceforge.net
 S:     Maintained
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git
 F:     drivers/tty/serial/8250*
 F:     include/linux/serial_8250.h
 
@@ -464,6 +464,7 @@ ALPHA PORT
 M:     Richard Henderson <rth@twiddle.net>
 M:     Ivan Kokshaysky <ink@jurassic.park.msu.ru>
 M:     Matt Turner <mattst88@gmail.com>
+S:     Odd Fixes
 L:     linux-alpha@vger.kernel.org
 F:     arch/alpha/
 
@@ -715,6 +716,7 @@ S:  Maintained
 ARM/CLKDEV SUPPORT
 M:     Russell King <linux@arm.linux.org.uk>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
 F:     arch/arm/include/asm/clkdev.h
 F:     drivers/clk/clkdev.c
 
@@ -1502,7 +1504,7 @@ F:        drivers/i2c/busses/i2c-bfin-twi.c
 
 BLOCK LAYER
 M:     Jens Axboe <axboe@kernel.dk>
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 S:     Maintained
 F:     block/
 
@@ -1640,7 +1642,7 @@ BTTV VIDEO4LINUX DRIVER
 M:     Mauro Carvalho Chehab <mchehab@infradead.org>
 L:     linux-media@vger.kernel.org
 W:     http://linuxtv.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:     Maintained
 F:     Documentation/video4linux/bttv/
 F:     drivers/media/video/bt8xx/bttv*
@@ -1670,7 +1672,7 @@ F:        fs/cachefiles/
 CAFE CMOS INTEGRATED CAMERA CONTROLLER DRIVER
 M:     Jonathan Corbet <corbet@lwn.net>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:     Maintained
 F:     Documentation/video4linux/cafe_ccic
 F:     drivers/media/video/marvell-ccic/
@@ -1841,6 +1843,7 @@ F:        include/linux/cleancache.h
 
 CLK API
 M:     Russell King <linux@arm.linux.org.uk>
+S:     Maintained
 F:     include/linux/clk.h
 
 CISCO FCOE HBA DRIVER
@@ -2036,7 +2039,7 @@ CX18 VIDEO4LINUX DRIVER
 M:     Andy Walls <awalls@md.metrocast.net>
 L:     ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:     http://linuxtv.org
 W:     http://www.ivtvdriver.org/index.php/Cx18
 S:     Maintained
@@ -2350,7 +2353,7 @@ F:        Documentation/blockdev/drbd/
 
 DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
 M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git
 S:     Supported
 F:     Documentation/kobject.txt
 F:     drivers/base/
@@ -2372,7 +2375,7 @@ INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
 M:     Keith Packard <keithp@keithp.com>
 L:     intel-gfx@lists.freedesktop.org (subscribers-only)
 L:     dri-devel@lists.freedesktop.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/keithp/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/keithp/linux.git
 S:     Supported
 F:     drivers/gpu/drm/i915
 F:     include/drm/i915*
@@ -2966,8 +2969,8 @@ GFS2 FILE SYSTEM
 M:     Steven Whitehouse <swhiteho@redhat.com>
 L:     cluster-devel@redhat.com
 W:     http://sources.redhat.com/cluster/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes.git
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-nmw.git
 S:     Supported
 F:     Documentation/filesystems/gfs2*.txt
 F:     fs/gfs2/
@@ -3008,42 +3011,42 @@ F:      drivers/net/ethernet/aeroflex/
 GSPCA FINEPIX SUBDRIVER
 M:     Frank Zago <frank@zago.net>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:     Maintained
 F:     drivers/media/video/gspca/finepix.c
 
 GSPCA GL860 SUBDRIVER
 M:     Olivier Lorin <o.lorin@laposte.net>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:     Maintained
 F:     drivers/media/video/gspca/gl860/
 
 GSPCA M5602 SUBDRIVER
 M:     Erik Andren <erik.andren@gmail.com>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:     Maintained
 F:     drivers/media/video/gspca/m5602/
 
 GSPCA PAC207 SONIXB SUBDRIVER
 M:     Hans de Goede <hdegoede@redhat.com>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:     Maintained
 F:     drivers/media/video/gspca/pac207.c
 
 GSPCA SN9C20X SUBDRIVER
 M:     Brian Johnson <brijohn@gmail.com>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:     Maintained
 F:     drivers/media/video/gspca/sn9c20x.c
 
 GSPCA T613 SUBDRIVER
 M:     Leandro Costantino <lcostantino@gmail.com>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:     Maintained
 F:     drivers/media/video/gspca/t613.c
 
@@ -3051,7 +3054,7 @@ GSPCA USB WEBCAM DRIVER
 M:     Jean-Francois Moine <moinejf@free.fr>
 W:     http://moinejf.free.fr
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:     Maintained
 F:     drivers/media/video/gspca/
 
@@ -3337,7 +3340,7 @@ IDE SUBSYSTEM
 M:     "David S. Miller" <davem@davemloft.net>
 L:     linux-ide@vger.kernel.org
 Q:     http://patchwork.ozlabs.org/project/linux-ide/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide.git
 S:     Maintained
 F:     Documentation/ide/
 F:     drivers/ide/
@@ -3449,7 +3452,7 @@ F:        firmware/isci/
 INTEL IDLE DRIVER
 M:     Len Brown <lenb@kernel.org>
 L:     linux-pm@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-idle-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git
 S:     Supported
 F:     drivers/idle/intel_idle.c
 
@@ -3756,7 +3759,7 @@ IVTV VIDEO4LINUX DRIVER
 M:     Andy Walls <awalls@md.metrocast.net>
 L:     ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:     http://www.ivtvdriver.org
 S:     Maintained
 F:     Documentation/video4linux/*.ivtv
@@ -3852,8 +3855,8 @@ F:        fs/autofs4/
 
 KERNEL BUILD + files below scripts/ (unless maintained elsewhere)
 M:     Michal Marek <mmarek@suse.cz>
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6.git for-next
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6.git rc-fixes
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild.git for-next
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild.git rc-fixes
 L:     linux-kbuild@vger.kernel.org
 S:     Maintained
 F:     Documentation/kbuild/
@@ -4233,12 +4236,14 @@ F:      Documentation/hwmon/ltc4261
 F:     drivers/hwmon/ltc4261.c
 
 LTP (Linux Test Project)
-M:     Rishikesh K Rajak <risrajak@linux.vnet.ibm.com>
-M:     Garrett Cooper <yanegomi@gmail.com>
+M:     Shubham Goyal <shubham@linux.vnet.ibm.com>
 M:     Mike Frysinger <vapier@gentoo.org>
-M:     Subrata Modak <subrata@linux.vnet.ibm.com>
+M:     Cyril Hrubis <chrubis@suse.cz>
+M:     Caspar Zhang <caspar@casparzhang.com>
+M:     Wanlong Gao <gaowanlong@cn.fujitsu.com>
 L:     ltp-list@lists.sourceforge.net (subscribers-only)
 W:     http://ltp.sourceforge.net/
+T:     git git://github.com/linux-test-project/ltp.git
 T:     git git://ltp.git.sourceforge.net/gitroot/ltp/ltp-dev
 S:     Maintained
 
@@ -4276,7 +4281,7 @@ MAC80211
 M:     Johannes Berg <johannes@sipsolutions.net>
 L:     linux-wireless@vger.kernel.org
 W:     http://linuxwireless.org/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git
 S:     Maintained
 F:     Documentation/networking/mac80211-injection.txt
 F:     include/net/mac80211.h
@@ -4287,7 +4292,7 @@ M:        Stefano Brivio <stefano.brivio@polimi.it>
 M:     Mattias Nissler <mattias.nissler@gmx.de>
 L:     linux-wireless@vger.kernel.org
 W:     http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/PID
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git
 S:     Maintained
 F:     net/mac80211/rc80211_pid*
 
@@ -4359,7 +4364,7 @@ P:        LinuxTV.org Project
 L:     linux-media@vger.kernel.org
 W:     http://linuxtv.org
 Q:     http://patchwork.kernel.org/project/linux-media/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:     Maintained
 F:     Documentation/dvb/
 F:     Documentation/video4linux/
@@ -4416,6 +4421,13 @@ T:       git git://git.monstr.eu/linux-2.6-microblaze.git
 S:     Supported
 F:     arch/microblaze/
 
+MICROCHANNEL ARCHITECTURE (MCA)
+M:     James Bottomley <James.Bottomley@HansenPartnership.com>
+S:     Maintained
+F:     Documentation/mca.txt
+F:     drivers/mca/
+F:     include/linux/mca*
+
 MICROTEK X6 SCANNER
 M:     Oliver Neukum <oliver@neukum.name>
 S:     Maintained
@@ -4431,14 +4443,6 @@ S:       Supported
 F:     Documentation/mips/
 F:     arch/mips/
 
-MISCELLANEOUS MCA-SUPPORT
-M:     James Bottomley <James.Bottomley@HansenPartnership.com>
-S:     Maintained
-F:     Documentation/ia64/mca.txt
-F:     Documentation/mca.txt
-F:     drivers/mca/
-F:     include/linux/mca*
-
 MODULE SUPPORT
 M:     Rusty Russell <rusty@rustcorp.com.au>
 S:     Maintained
@@ -4646,7 +4650,7 @@ M:        James Morris <jmorris@namei.org>
 M:     Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
 M:     Patrick McHardy <kaber@trash.net>
 L:     netdev@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
 S:     Maintained
 F:     net/ipv4/
 F:     net/ipv6/
@@ -4662,7 +4666,7 @@ NETWORKING [WIRELESS]
 M:     "John W. Linville" <linville@tuxdriver.com>
 L:     linux-wireless@vger.kernel.org
 Q:     http://patchwork.kernel.org/project/linux-wireless/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git
 S:     Maintained
 F:     net/mac80211/
 F:     net/rfkill/
@@ -4675,8 +4679,8 @@ F:        drivers/net/wireless/
 NETWORKING DRIVERS
 L:     netdev@vger.kernel.org
 W:     http://www.linuxfoundation.org/en/Net
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
 S:     Odd Fixes
 F:     drivers/net/
 F:     include/linux/if_*
@@ -4892,7 +4896,7 @@ F:        drivers/char/pcmcia/cm4040_cs.*
 OMNIVISION OV7670 SENSOR DRIVER
 M:     Jonathan Corbet <corbet@lwn.net>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:     Maintained
 F:     drivers/media/video/ov7670.c
 
@@ -5067,7 +5071,7 @@ M:        Helge Deller <deller@gmx.de>
 L:     linux-parisc@vger.kernel.org
 W:     http://www.parisc-linux.org/
 Q:     http://patchwork.kernel.org/project/linux-parisc/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/parisc-2.6.git
 S:     Maintained
 F:     arch/parisc/
 F:     drivers/parisc/
@@ -5123,7 +5127,7 @@ PCI SUBSYSTEM
 M:     Bjorn Helgaas <bhelgaas@google.com>
 L:     linux-pci@vger.kernel.org
 Q:     http://patchwork.kernel.org/project/linux-pci/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci.git
 S:     Supported
 F:     Documentation/PCI/
 F:     drivers/pci/
@@ -5408,7 +5412,7 @@ M:        Mike Isely <isely@pobox.com>
 L:     pvrusb2@isely.net       (subscribers-only)
 L:     linux-media@vger.kernel.org
 W:     http://www.isely.net/pvrusb2/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:     Maintained
 F:     Documentation/video4linux/README.pvrusb2
 F:     drivers/media/video/pvrusb2/
@@ -5574,7 +5578,7 @@ RCUTORTURE MODULE
 M:     Josh Triplett <josh@freedesktop.org>
 M:     "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
 S:     Supported
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-2.6-rcu.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
 F:     Documentation/RCU/torture.txt
 F:     kernel/rcutorture.c
 
@@ -5599,7 +5603,7 @@ M:        Dipankar Sarma <dipankar@in.ibm.com>
 M:     "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
 W:     http://www.rdrop.com/users/paulmck/rclock/
 S:     Supported
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-2.6-rcu.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
 F:     Documentation/RCU/
 F:     include/linux/rcu*
 F:     include/linux/srcu*
@@ -5753,7 +5757,7 @@ F:        drivers/mmc/host/s3cmci.*
 SAA7146 VIDEO4LINUX-2 DRIVER
 M:     Michael Hunold <michael@mihu.de>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:     http://www.mihu.de/linux/saa7146
 S:     Maintained
 F:     drivers/media/common/saa7146*
@@ -6176,7 +6180,7 @@ F:        arch/ia64/sn/
 SOC-CAMERA V4L2 SUBSYSTEM
 M:     Guennadi Liakhovetski <g.liakhovetski@gmx.de>
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:     Maintained
 F:     include/media/v4l2*
 F:     drivers/media/video/v4l2*
@@ -6248,8 +6252,8 @@ SPARC + UltraSPARC (sparc/sparc64)
 M:     "David S. Miller" <davem@davemloft.net>
 L:     sparclinux@vger.kernel.org
 Q:     http://patchwork.ozlabs.org/project/sparclinux/list/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next.git
 S:     Maintained
 F:     arch/sparc/
 F:     drivers/sbus/
@@ -6257,8 +6261,8 @@ F:        drivers/sbus/
 SPARC SERIAL DRIVERS
 M:     "David S. Miller" <davem@davemloft.net>
 L:     sparclinux@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next.git
 S:     Maintained
 F:     include/linux/sunserialcore.h
 F:     drivers/tty/serial/suncore.c
@@ -6563,7 +6567,7 @@ L:        linux-scsi@vger.kernel.org
 L:     target-devel@vger.kernel.org
 L:     http://groups.google.com/group/linux-iscsi-target-dev
 W:     http://www.linux-iscsi.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/nab/lio-core-2.6.git master
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/nab/lio-core.git master
 S:     Supported
 F:     drivers/target/
 F:     include/target/
@@ -6754,7 +6758,7 @@ K:        ^Subject:.*(?i)trivial
 TTY LAYER
 M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 S:     Supported
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git
 F:     drivers/tty/
 F:     drivers/tty/serial/serial_core.c
 F:     include/linux/serial_core.h
@@ -6922,7 +6926,7 @@ USB ET61X[12]51 DRIVER
 M:     Luca Risolia <luca.risolia@studio.unibo.it>
 L:     linux-usb@vger.kernel.org
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:     http://www.linux-projects.org
 S:     Maintained
 F:     drivers/media/video/et61x251/
@@ -7078,7 +7082,7 @@ USB SN9C1xx DRIVER
 M:     Luca Risolia <luca.risolia@studio.unibo.it>
 L:     linux-usb@vger.kernel.org
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:     http://www.linux-projects.org
 S:     Maintained
 F:     Documentation/video4linux/sn9c102.txt
@@ -7088,7 +7092,7 @@ USB SUBSYSTEM
 M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 L:     linux-usb@vger.kernel.org
 W:     http://www.linux-usb.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
 S:     Supported
 F:     Documentation/usb/
 F:     drivers/net/usb/
@@ -7114,7 +7118,7 @@ USB VIDEO CLASS
 M:     Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 L:     linux-uvc-devel@lists.berlios.de (subscribers-only)
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:     http://www.ideasonboard.org/uvc/
 S:     Maintained
 F:     drivers/media/video/uvc/
@@ -7123,7 +7127,7 @@ USB W996[87]CF DRIVER
 M:     Luca Risolia <luca.risolia@studio.unibo.it>
 L:     linux-usb@vger.kernel.org
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:     http://www.linux-projects.org
 S:     Maintained
 F:     Documentation/video4linux/w9968cf.txt
@@ -7152,7 +7156,7 @@ USB ZR364XX DRIVER
 M:     Antoine Jacquet <royale@zerezo.com>
 L:     linux-usb@vger.kernel.org
 L:     linux-media@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:     http://royale.zerezo.com/zr364xx/
 S:     Maintained
 F:     Documentation/video4linux/zr364xx.txt
@@ -7302,7 +7306,7 @@ M:        Liam Girdwood <lrg@ti.com>
 M:     Mark Brown <broonie@opensource.wolfsonmicro.com>
 W:     http://opensource.wolfsonmicro.com/node/15
 W:     http://www.slimlogic.co.uk/?p=48
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lrg/regulator.git
 S:     Supported
 F:     drivers/regulator/
 F:     include/linux/regulator/
index 5b448a7..a6f14f6 100644 (file)
@@ -120,6 +120,9 @@ config HAVE_KRETPROBES
 
 config HAVE_OPTPROBES
        bool
+
+config HAVE_NMI_WATCHDOG
+       bool
 #
 # An arch should select this if it provides all these things:
 #
index 72db984..cbeb361 100644 (file)
 #define MADV_HUGEPAGE  14              /* Worth backing with hugepages */
 #define MADV_NOHUGEPAGE        15              /* Not worth backing with hugepages */
 
+#define MADV_DONTDUMP   16             /* Explicity exclude from the core dump,
+                                          overrides the coredump filter bits */
+#define MADV_DODUMP    17              /* Clear the MADV_NODUMP flag */
+
 /* compatibility flags */
 #define MAP_FILE       0
 
index ffc0e85..7ec60d6 100644 (file)
@@ -79,7 +79,6 @@ extern unsigned int kobjsize(const void *objp);
  * No page table caches to initialise.
  */
 #define pgtable_cache_init()   do { } while (0)
-#define io_remap_page_range    remap_page_range
 #define io_remap_pfn_range     remap_pfn_range
 
 
index c2ae3cd..219e4ef 100644 (file)
@@ -533,8 +533,7 @@ int vectors_user_mapping(void)
        struct mm_struct *mm = current->mm;
        return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
                                       VM_READ | VM_EXEC |
-                                      VM_MAYREAD | VM_MAYEXEC |
-                                      VM_ALWAYSDUMP | VM_RESERVED,
+                                      VM_MAYREAD | VM_MAYEXEC | VM_RESERVED,
                                       NULL);
 }
 
index abe5a9e..c1269a1 100644 (file)
@@ -36,6 +36,7 @@ config BLACKFIN
        select GENERIC_ATOMIC64
        select GENERIC_IRQ_PROBE
        select IRQ_PER_CPU if SMP
+       select HAVE_NMI_WATCHDOG if NMI_WATCHDOG
 
 config GENERIC_CSUM
        def_bool y
index 12f4060..89de539 100644 (file)
@@ -38,8 +38,4 @@
 
 #include <asm-generic/irq.h>
 
-#ifdef CONFIG_NMI_WATCHDOG
-# define ARCH_HAS_NMI_WATCHDOG
-#endif
-
 #endif                         /* _BFIN_IRQ_H_ */
index 68c8af4..38a4312 100644 (file)
@@ -73,9 +73,6 @@ extern unsigned long empty_zero_page;
 #define pgtable_cache_init()   do { } while (0)
 #define io_remap_pfn_range      remap_pfn_range
 
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)             \
-               remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
 #include <asm-generic/pgtable.h>
 
 #endif /* _ASM_C6X_PGTABLE_H */
index b45be31..ecbab34 100644 (file)
@@ -192,12 +192,7 @@ static int handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
        if (rc)
                return rc;
 
-       spin_lock_irq(&current->sighand->siglock);
-       sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
-       if (!(ka->sa.sa_flags & SA_NODEFER))
-               sigaddset(&current->blocked, sig);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       block_sigmask(ka, sig);
 
        return 0;
 }
@@ -305,10 +300,7 @@ asmlinkage int sys_rt_sigreturn(void)
                goto badframe;
 
        sigdelsetmask(&blocked, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       current->blocked = blocked;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&blocked);
 
        if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
                goto badframe;
index 16277c3..f212a45 100644 (file)
@@ -78,8 +78,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
        /* MAYWRITE to allow gdb to COW and set breakpoints. */
        ret = install_special_mapping(mm, vdso_base, PAGE_SIZE,
                                      VM_READ|VM_EXEC|
-                                     VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
-                                     VM_ALWAYSDUMP,
+                                     VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
                                      &vdso_page);
 
        if (ret)
index b2af423..44dc67a 100644 (file)
@@ -543,8 +543,6 @@ extern unsigned long iopa(unsigned long addr);
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 #define kern_addr_valid(addr)  (1)
 
-#define io_remap_page_range remap_page_range
-
 /*
  * No page table caches to initialise
  */
index 785b4ea..46d3da0 100644 (file)
 #define MADV_HUGEPAGE  14              /* Worth backing with hugepages */
 #define MADV_NOHUGEPAGE        15              /* Not worth backing with hugepages */
 
+#define MADV_DONTDUMP   16             /* Explicity exclude from the core dump,
+                                          overrides the coredump filter bits */
+#define MADV_DODUMP    17              /* Clear the MADV_NODUMP flag */
+
 /* compatibility flags */
 #define MAP_FILE       0
 
index e5cdfd6..0f1af58 100644 (file)
@@ -88,8 +88,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 
        ret = install_special_mapping(mm, addr, PAGE_SIZE,
                                      VM_READ|VM_EXEC|
-                                     VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
-                                     VM_ALWAYSDUMP,
+                                     VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
                                      &vdso_page);
 
        if (ret)
index 8f1c40d..3aa3de0 100644 (file)
@@ -5,6 +5,7 @@ config MN10300
        select GENERIC_IRQ_SHOW
        select HAVE_ARCH_TRACEHOOK
        select HAVE_ARCH_KGDB
+       select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER
 
 config AM33_2
        def_bool n
index 10c7502..8ca2a42 100644 (file)
 
 #ifdef __KERNEL__
 
-#ifdef CONFIG_MN10300_WD_TIMER
-#define ARCH_HAS_NMI_WATCHDOG          /* See include/linux/nmi.h */
-#endif
-
 /*
  * watchdog timer registers
  */
index 043505d..14c900c 100644 (file)
@@ -455,7 +455,6 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
  * No page table caches to initialise
  */
 #define pgtable_cache_init()           do { } while (0)
-#define io_remap_page_range            remap_page_range
 
 typedef pte_t *pte_addr_t;
 
index f5b7bf5..12219eb 100644 (file)
 #define MADV_HUGEPAGE  67              /* Worth backing with hugepages */
 #define MADV_NOHUGEPAGE        68              /* Not worth backing with hugepages */
 
+#define MADV_DONTDUMP   69             /* Explicity exclude from the core dump,
+                                          overrides the coredump filter bits */
+#define MADV_DODUMP    70              /* Clear the MADV_NODUMP flag */
+
 /* compatibility flags */
 #define MAP_FILE       0
 #define MAP_VARIABLE   0
index 7d14bb6..d36ee10 100644 (file)
@@ -263,17 +263,11 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
         * the "data" page of the vDSO or you'll stop getting kernel updates
         * and your nice userland gettimeofday will be totally dead.
         * It's fine to use that for setting breakpoints in the vDSO code
-        * pages though
-        *
-        * Make sure the vDSO gets into every core dump.
-        * Dumping its contents makes post-mortem fully interpretable later
-        * without matching up the same kernel and hardware config to see
-        * what PC values meant.
+        * pages though.
         */
        rc = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
                                     VM_READ|VM_EXEC|
-                                    VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
-                                    VM_ALWAYSDUMP,
+                                    VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
                                     vdso_pagelist);
        if (rc) {
                current->mm->context.vdso_base = 0;
index e704a99..9c80138 100644 (file)
@@ -241,17 +241,11 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
         * on the "data" page of the vDSO or you'll stop getting kernel
         * updates and your nice userland gettimeofday will be totally dead.
         * It's fine to use that for setting breakpoints in the vDSO code
-        * pages though
-        *
-        * Make sure the vDSO gets into every core dump.
-        * Dumping its contents makes post-mortem fully interpretable later
-        * without matching up the same kernel and hardware config to see
-        * what PC values meant.
+        * pages though.
         */
        rc = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
                                     VM_READ|VM_EXEC|
-                                    VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
-                                    VM_ALWAYSDUMP,
+                                    VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
                                     vdso_pagelist);
        if (rc)
                current->mm->context.vdso_base = 0;
index 1d6d51a..5ca5797 100644 (file)
@@ -73,8 +73,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 
        ret = install_special_mapping(mm, addr, PAGE_SIZE,
                                      VM_READ | VM_EXEC |
-                                     VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC |
-                                     VM_ALWAYSDUMP,
+                                     VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
                                      syscall_pages);
        if (unlikely(ret))
                goto up_fail;
index ca5580e..1666de8 100644 (file)
@@ -29,6 +29,7 @@ config SPARC
        select GENERIC_IRQ_SHOW
        select USE_GENERIC_SMP_HELPERS if SMP
        select GENERIC_PCI_IOMAP
+       select HAVE_NMI_WATCHDOG if SPARC64
 
 config SPARC32
        def_bool !64BIT
index 16dcae6..abf6afe 100644 (file)
@@ -95,7 +95,6 @@ void arch_trigger_all_cpu_backtrace(void);
 extern void *hardirq_stack[NR_CPUS];
 extern void *softirq_stack[NR_CPUS];
 #define __ARCH_HAS_DO_SOFTIRQ
-#define ARCH_HAS_NMI_WATCHDOG
 
 #define NO_IRQ         0xffffffff
 
index 55e58e9..1a00fb6 100644 (file)
@@ -117,17 +117,11 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 
        /*
         * MAYWRITE to allow gdb to COW and set breakpoints
-        *
-        * Make sure the vDSO gets into every core dump.  Dumping its
-        * contents makes post-mortem fully interpretable later
-        * without matching up the same kernel and hardware config to
-        * see what PC values meant.
         */
        vdso_base = VDSO_BASE;
        retval = install_special_mapping(mm, vdso_base, PAGE_SIZE,
                                         VM_READ|VM_EXEC|
-                                        VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
-                                        VM_ALWAYSDUMP,
+                                        VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
                                         vdso_pages);
 
 #ifndef __tilegx__
index e8b889d..fb12f4c 100644 (file)
@@ -65,21 +65,10 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
 #endif
                err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
 
-       if (err) {
-               spin_lock_irq(&current->sighand->siglock);
-               current->blocked = *oldset;
-               recalc_sigpending();
-               spin_unlock_irq(&current->sighand->siglock);
+       if (err)
                force_sigsegv(signr, current);
-       } else {
-               spin_lock_irq(&current->sighand->siglock);
-               sigorsets(&current->blocked, &current->blocked,
-                         &ka->sa.sa_mask);
-               if (!(ka->sa.sa_flags & SA_NODEFER))
-                       sigaddset(&current->blocked, signr);
-               recalc_sigpending();
-               spin_unlock_irq(&current->sighand->siglock);
-       }
+       else
+               block_sigmask(ka, signr);
 
        return err;
 }
@@ -162,12 +151,11 @@ int do_signal(void)
  */
 long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 {
+       sigset_t blocked;
+
        mask &= _BLOCKABLE;
-       spin_lock_irq(&current->sighand->siglock);
-       current->saved_sigmask = current->blocked;
-       siginitset(&current->blocked, mask);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       siginitset(&blocked, mask);
+       set_current_blocked(&blocked);
 
        current->state = TASK_INTERRUPTIBLE;
        schedule();
index 52edc2b..432b429 100644 (file)
@@ -381,7 +381,7 @@ int vectors_user_mapping(void)
        return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
                                       VM_READ | VM_EXEC |
                                       VM_MAYREAD | VM_MAYEXEC |
-                                      VM_ALWAYSDUMP | VM_RESERVED,
+                                      VM_RESERVED,
                                       NULL);
 }
 
index 0a18d16..fa2900c 100644 (file)
@@ -643,14 +643,14 @@ static bool __perf_sched_find_counter(struct perf_sched *sched)
        /* Prefer fixed purpose counters */
        if (x86_pmu.num_counters_fixed) {
                idx = X86_PMC_IDX_FIXED;
-               for_each_set_bit_cont(idx, c->idxmsk, X86_PMC_IDX_MAX) {
+               for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) {
                        if (!__test_and_set_bit(idx, sched->state.used))
                                goto done;
                }
        }
        /* Grab the first unused counter starting with idx */
        idx = sched->state.counter;
-       for_each_set_bit_cont(idx, c->idxmsk, X86_PMC_IDX_FIXED) {
+       for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_FIXED) {
                if (!__test_and_set_bit(idx, sched->state.used))
                        goto done;
        }
index 313fb5c..43e2b1c 100644 (file)
@@ -306,10 +306,10 @@ void __init native_init_IRQ(void)
         * us. (some of these will be overridden and become
         * 'special' SMP interrupts)
         */
-       for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
+       i = FIRST_EXTERNAL_VECTOR;
+       for_each_clear_bit_from(i, used_vectors, NR_VECTORS) {
                /* IA32_SYSCALL_VECTOR could be used in trap_init already. */
-               if (!test_bit(i, used_vectors))
-                       set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]);
+               set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
        }
 
        if (!acpi_ioapic && !of_ioapic)
index 639900a..f40281e 100644 (file)
@@ -23,14 +23,6 @@ static int __init gate_vma_init(void)
        gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
        gate_vma.vm_page_prot = __P101;
 
-       /*
-        * Make sure the vDSO gets into every core dump.
-        * Dumping its contents makes post-mortem fully interpretable later
-        * without matching up the same kernel and hardware config to see
-        * what PC values meant.
-        */
-       gate_vma.vm_flags |= VM_ALWAYSDUMP;
-
        return 0;
 }
 __initcall(gate_vma_init);
index 91f4ec9..af91901 100644 (file)
@@ -64,8 +64,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 
        err = install_special_mapping(mm, um_vdso_addr, PAGE_SIZE,
                VM_READ|VM_EXEC|
-               VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
-               VM_ALWAYSDUMP,
+               VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
                vdsop);
 
        up_write(&mm->mmap_sem);
index 468d591..a944020 100644 (file)
@@ -250,13 +250,7 @@ static int __init gate_vma_init(void)
        gate_vma.vm_end = FIXADDR_USER_END;
        gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
        gate_vma.vm_page_prot = __P101;
-       /*
-        * Make sure the vDSO gets into every core dump.
-        * Dumping its contents makes post-mortem fully interpretable later
-        * without matching up the same kernel and hardware config to see
-        * what PC values meant.
-        */
-       gate_vma.vm_flags |= VM_ALWAYSDUMP;
+
        return 0;
 }
 
@@ -343,17 +337,10 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
        if (compat_uses_vma || !compat) {
                /*
                 * MAYWRITE to allow gdb to COW and set breakpoints
-                *
-                * Make sure the vDSO gets into every core dump.
-                * Dumping its contents makes post-mortem fully
-                * interpretable later without matching up the same
-                * kernel and hardware config to see what PC values
-                * meant.
                 */
                ret = install_special_mapping(mm, addr, PAGE_SIZE,
                                              VM_READ|VM_EXEC|
-                                             VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
-                                             VM_ALWAYSDUMP,
+                                             VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
                                              vdso32_pages);
 
                if (ret)
index 153407c..17e1827 100644 (file)
@@ -124,8 +124,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 
        ret = install_special_mapping(mm, addr, vdso_size,
                                      VM_READ|VM_EXEC|
-                                     VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
-                                     VM_ALWAYSDUMP,
+                                     VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
                                      vdso_pages);
        if (ret) {
                current->mm->context.vdso = NULL;
index 3078901..25bc6c1 100644 (file)
 #define MADV_HUGEPAGE  14              /* Worth backing with hugepages */
 #define MADV_NOHUGEPAGE        15              /* Not worth backing with hugepages */
 
+#define MADV_DONTDUMP   16             /* Explicity exclude from the core dump,
+                                          overrides the coredump filter bits */
+#define MADV_DODUMP    17              /* Clear the MADV_NODUMP flag */
+
 /* compatibility flags */
 #define MAP_FILE       0
 
index 6318edd..21ff9d0 100644 (file)
@@ -308,6 +308,7 @@ comment "Digest"
 config CRYPTO_CRC32C
        tristate "CRC32c CRC algorithm"
        select CRYPTO_HASH
+       select CRC32
        help
          Castagnoli, et al Cyclic Redundancy-Check Algorithm.  Used
          by iSCSI for header and data digests and by others.
index 3f9ad28..06f7018 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/crc32.h>
 
 #define CHKSUM_BLOCK_SIZE      1
 #define CHKSUM_DIGEST_SIZE     4
@@ -53,95 +54,6 @@ struct chksum_desc_ctx {
 };
 
 /*
- * This is the CRC-32C table
- * Generated with:
- * width = 32 bits
- * poly = 0x1EDC6F41
- * reflect input bytes = true
- * reflect output bytes = true
- */
-
-static const u32 crc32c_table[256] = {
-       0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
-       0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
-       0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
-       0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
-       0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
-       0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
-       0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
-       0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
-       0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
-       0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
-       0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
-       0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
-       0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
-       0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
-       0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
-       0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
-       0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
-       0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
-       0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
-       0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
-       0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
-       0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
-       0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
-       0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
-       0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
-       0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
-       0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
-       0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
-       0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
-       0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
-       0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
-       0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
-       0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
-       0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
-       0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
-       0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
-       0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
-       0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
-       0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
-       0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
-       0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
-       0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
-       0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
-       0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
-       0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
-       0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
-       0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
-       0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
-       0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
-       0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
-       0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
-       0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
-       0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
-       0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
-       0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
-       0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
-       0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
-       0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
-       0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
-       0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
-       0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
-       0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
-       0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
-       0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
-};
-
-/*
- * Steps through buffer one byte at at time, calculates reflected
- * crc using table.
- */
-
-static u32 crc32c(u32 crc, const u8 *data, unsigned int length)
-{
-       while (length--)
-               crc = crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
-
-       return crc;
-}
-
-/*
  * Steps through buffer one byte at at time, calculates reflected
  * crc using table.
  */
@@ -179,7 +91,7 @@ static int chksum_update(struct shash_desc *desc, const u8 *data,
 {
        struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
 
-       ctx->crc = crc32c(ctx->crc, data, length);
+       ctx->crc = __crc32c_le(ctx->crc, data, length);
        return 0;
 }
 
@@ -193,7 +105,7 @@ static int chksum_final(struct shash_desc *desc, u8 *out)
 
 static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out)
 {
-       *(__le32 *)out = ~cpu_to_le32(crc32c(*crcp, data, len));
+       *(__le32 *)out = ~cpu_to_le32(__crc32c_le(*crcp, data, len));
        return 0;
 }
 
index 8d00615..77dc532 100644 (file)
@@ -341,7 +341,7 @@ static int regcache_lzo_sync(struct regmap *map, unsigned int min,
 
        lzo_blocks = map->cache;
        i = min;
-       for_each_set_bit_cont(i, lzo_blocks[0]->sync_bmp,
+       for_each_set_bit_from(i, lzo_blocks[0]->sync_bmp,
                              lzo_blocks[0]->sync_bmp_nbits) {
                if (i > max)
                        continue;
index e09f9ce..abfaaca 100644 (file)
@@ -179,7 +179,7 @@ int drbd_khelper(struct drbd_conf *mdev, char *cmd)
        dev_info(DEV, "helper command: %s %s %s\n", usermode_helper, cmd, mb);
 
        drbd_bcast_ev_helper(mdev, cmd);
-       ret = call_usermodehelper(usermode_helper, argv, envp, 1);
+       ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
        if (ret)
                dev_warn(DEV, "helper command: %s %s %s exit code %u (0x%x)\n",
                                usermode_helper, cmd, mb,
index 8c7a75d..589ba02 100644 (file)
@@ -17,7 +17,7 @@ menuconfig NEW_LEDS
 if NEW_LEDS
 
 config LEDS_CLASS
-       bool "LED Class Support"
+       tristate "LED Class Support"
        help
          This option enables the led sysfs class in /sys/class/leds.  You'll
          need this to do anything useful with LEDs.  If unsure, say N.
@@ -234,6 +234,14 @@ config LEDS_PCA955X
          LED driver chips accessed via the I2C bus.  Supported
          devices include PCA9550, PCA9551, PCA9552, and PCA9553.
 
+config LEDS_PCA9633
+       tristate "LED support for PCA9633 I2C chip"
+       depends on LEDS_CLASS
+       depends on I2C
+       help
+         This option enables support for LEDs connected to the PCA9633
+         LED driver chip accessed via the I2C bus.
+
 config LEDS_WM831X_STATUS
        tristate "LED support for status LEDs on WM831x PMICs"
        depends on LEDS_CLASS
index 6bcf4f6..fa0f428 100644 (file)
@@ -30,6 +30,7 @@ obj-$(CONFIG_LEDS_HP6XX)              += leds-hp6xx.o
 obj-$(CONFIG_LEDS_OT200)               += leds-ot200.o
 obj-$(CONFIG_LEDS_FSG)                 += leds-fsg.o
 obj-$(CONFIG_LEDS_PCA955X)             += leds-pca955x.o
+obj-$(CONFIG_LEDS_PCA9633)             += leds-pca9633.o
 obj-$(CONFIG_LEDS_DA903X)              += leds-da903x.o
 obj-$(CONFIG_LEDS_WM831X_STATUS)       += leds-wm831x-status.o
 obj-$(CONFIG_LEDS_WM8350)              += leds-wm8350.o
index 0c8739c..5bff843 100644 (file)
@@ -110,50 +110,6 @@ static void led_timer_function(unsigned long data)
        mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
 }
 
-static void led_stop_software_blink(struct led_classdev *led_cdev)
-{
-       /* deactivate previous settings */
-       del_timer_sync(&led_cdev->blink_timer);
-       led_cdev->blink_delay_on = 0;
-       led_cdev->blink_delay_off = 0;
-}
-
-static void led_set_software_blink(struct led_classdev *led_cdev,
-                                  unsigned long delay_on,
-                                  unsigned long delay_off)
-{
-       int current_brightness;
-
-       current_brightness = led_get_brightness(led_cdev);
-       if (current_brightness)
-               led_cdev->blink_brightness = current_brightness;
-       if (!led_cdev->blink_brightness)
-               led_cdev->blink_brightness = led_cdev->max_brightness;
-
-       if (led_get_trigger_data(led_cdev) &&
-           delay_on == led_cdev->blink_delay_on &&
-           delay_off == led_cdev->blink_delay_off)
-               return;
-
-       led_stop_software_blink(led_cdev);
-
-       led_cdev->blink_delay_on = delay_on;
-       led_cdev->blink_delay_off = delay_off;
-
-       /* never on - don't blink */
-       if (!delay_on)
-               return;
-
-       /* never off - just set to brightness */
-       if (!delay_off) {
-               led_set_brightness(led_cdev, led_cdev->blink_brightness);
-               return;
-       }
-
-       mod_timer(&led_cdev->blink_timer, jiffies + 1);
-}
-
-
 /**
  * led_classdev_suspend - suspend an led_classdev.
  * @led_cdev: the led_classdev to suspend.
@@ -262,32 +218,6 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
 }
 EXPORT_SYMBOL_GPL(led_classdev_unregister);
 
-void led_blink_set(struct led_classdev *led_cdev,
-                  unsigned long *delay_on,
-                  unsigned long *delay_off)
-{
-       del_timer_sync(&led_cdev->blink_timer);
-
-       if (led_cdev->blink_set &&
-           !led_cdev->blink_set(led_cdev, delay_on, delay_off))
-               return;
-
-       /* blink with 1 Hz as default if nothing specified */
-       if (!*delay_on && !*delay_off)
-               *delay_on = *delay_off = 500;
-
-       led_set_software_blink(led_cdev, *delay_on, *delay_off);
-}
-EXPORT_SYMBOL(led_blink_set);
-
-void led_brightness_set(struct led_classdev *led_cdev,
-                       enum led_brightness brightness)
-{
-       led_stop_software_blink(led_cdev);
-       led_cdev->brightness_set(led_cdev, brightness);
-}
-EXPORT_SYMBOL(led_brightness_set);
-
 static int __init leds_init(void)
 {
        leds_class = class_create(THIS_MODULE, "leds");
index 016d19f..d686004 100644 (file)
@@ -23,3 +23,73 @@ EXPORT_SYMBOL_GPL(leds_list_lock);
 
 LIST_HEAD(leds_list);
 EXPORT_SYMBOL_GPL(leds_list);
+
+static void led_stop_software_blink(struct led_classdev *led_cdev)
+{
+       /* deactivate previous settings */
+       del_timer_sync(&led_cdev->blink_timer);
+       led_cdev->blink_delay_on = 0;
+       led_cdev->blink_delay_off = 0;
+}
+
+static void led_set_software_blink(struct led_classdev *led_cdev,
+                                  unsigned long delay_on,
+                                  unsigned long delay_off)
+{
+       int current_brightness;
+
+       current_brightness = led_get_brightness(led_cdev);
+       if (current_brightness)
+               led_cdev->blink_brightness = current_brightness;
+       if (!led_cdev->blink_brightness)
+               led_cdev->blink_brightness = led_cdev->max_brightness;
+
+       if (led_get_trigger_data(led_cdev) &&
+           delay_on == led_cdev->blink_delay_on &&
+           delay_off == led_cdev->blink_delay_off)
+               return;
+
+       led_stop_software_blink(led_cdev);
+
+       led_cdev->blink_delay_on = delay_on;
+       led_cdev->blink_delay_off = delay_off;
+
+       /* never on - don't blink */
+       if (!delay_on)
+               return;
+
+       /* never off - just set to brightness */
+       if (!delay_off) {
+               led_set_brightness(led_cdev, led_cdev->blink_brightness);
+               return;
+       }
+
+       mod_timer(&led_cdev->blink_timer, jiffies + 1);
+}
+
+
+void led_blink_set(struct led_classdev *led_cdev,
+                  unsigned long *delay_on,
+                  unsigned long *delay_off)
+{
+       del_timer_sync(&led_cdev->blink_timer);
+
+       if (led_cdev->blink_set &&
+           !led_cdev->blink_set(led_cdev, delay_on, delay_off))
+               return;
+
+       /* blink with 1 Hz as default if nothing specified */
+       if (!*delay_on && !*delay_off)
+               *delay_on = *delay_off = 500;
+
+       led_set_software_blink(led_cdev, *delay_on, *delay_off);
+}
+EXPORT_SYMBOL(led_blink_set);
+
+void led_brightness_set(struct led_classdev *led_cdev,
+                       enum led_brightness brightness)
+{
+       led_stop_software_blink(led_cdev);
+       led_cdev->brightness_set(led_cdev, brightness);
+}
+EXPORT_SYMBOL(led_brightness_set);
index 7df74cb..f4c470a 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
 #include <linux/leds.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
@@ -20,8 +21,6 @@
 #include <linux/workqueue.h>
 #include <linux/module.h>
 
-#include <asm/gpio.h>
-
 struct gpio_led_data {
        struct led_classdev cdev;
        unsigned gpio;
index e59c166..968fd5f 100644 (file)
@@ -26,7 +26,6 @@
 #define LM3530_GEN_CONFIG              0x10
 #define LM3530_ALS_CONFIG              0x20
 #define LM3530_BRT_RAMP_RATE           0x30
-#define LM3530_ALS_ZONE_REG            0x40
 #define LM3530_ALS_IMP_SELECT          0x41
 #define LM3530_BRT_CTRL_REG            0xA0
 #define LM3530_ALS_ZB0_REG             0x60
@@ -38,7 +37,7 @@
 #define LM3530_ALS_Z2T_REG             0x72
 #define LM3530_ALS_Z3T_REG             0x73
 #define LM3530_ALS_Z4T_REG             0x74
-#define LM3530_REG_MAX                 15
+#define LM3530_REG_MAX                 14
 
 /* General Control Register */
 #define LM3530_EN_I2C_SHIFT            (0)
@@ -80,6 +79,9 @@
 #define LM3530_DEF_ZT_3                        (0x33)
 #define LM3530_DEF_ZT_4                        (0x19)
 
+/* 7 bits are used for the brightness : LM3530_BRT_CTRL_REG */
+#define MAX_BRIGHTNESS                 (127)
+
 struct lm3530_mode_map {
        const char *mode;
        enum lm3530_mode mode_val;
@@ -115,7 +117,6 @@ static const u8 lm3530_reg[LM3530_REG_MAX] = {
        LM3530_GEN_CONFIG,
        LM3530_ALS_CONFIG,
        LM3530_BRT_RAMP_RATE,
-       LM3530_ALS_ZONE_REG,
        LM3530_ALS_IMP_SELECT,
        LM3530_BRT_CTRL_REG,
        LM3530_ALS_ZB0_REG,
@@ -152,27 +153,35 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
        u8 reg_val[LM3530_REG_MAX];
        u8 zones[LM3530_ALS_ZB_MAX];
        u32 als_vmin, als_vmax, als_vstep;
-       struct lm3530_platform_data *pltfm = drvdata->pdata;
+       struct lm3530_platform_data *pdata = drvdata->pdata;
        struct i2c_client *client = drvdata->client;
+       struct lm3530_pwm_data *pwm = &pdata->pwm_data;
 
-       gen_config = (pltfm->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) |
-                       ((pltfm->max_current & 7) << LM3530_MAX_CURR_SHIFT);
+       gen_config = (pdata->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) |
+                       ((pdata->max_current & 7) << LM3530_MAX_CURR_SHIFT);
 
-       if (drvdata->mode == LM3530_BL_MODE_MANUAL ||
-           drvdata->mode == LM3530_BL_MODE_ALS)
-               gen_config |= (LM3530_ENABLE_I2C);
+       switch (drvdata->mode) {
+       case LM3530_BL_MODE_MANUAL:
+       case LM3530_BL_MODE_ALS:
+               gen_config |= LM3530_ENABLE_I2C;
+               break;
+       case LM3530_BL_MODE_PWM:
+               gen_config |= LM3530_ENABLE_PWM | LM3530_ENABLE_PWM_SIMPLE |
+                             (pdata->pwm_pol_hi << LM3530_PWM_POL_SHIFT);
+               break;
+       }
 
        if (drvdata->mode == LM3530_BL_MODE_ALS) {
-               if (pltfm->als_vmax == 0) {
-                       pltfm->als_vmin = 0;
-                       pltfm->als_vmax = LM3530_ALS_WINDOW_mV;
+               if (pdata->als_vmax == 0) {
+                       pdata->als_vmin = 0;
+                       pdata->als_vmax = LM3530_ALS_WINDOW_mV;
                }
 
-               als_vmin = pltfm->als_vmin;
-               als_vmax = pltfm->als_vmax;
+               als_vmin = pdata->als_vmin;
+               als_vmax = pdata->als_vmax;
 
                if ((als_vmax - als_vmin) > LM3530_ALS_WINDOW_mV)
-                       pltfm->als_vmax = als_vmax =
+                       pdata->als_vmax = als_vmax =
                                als_vmin + LM3530_ALS_WINDOW_mV;
 
                /* n zone boundary makes n+1 zones */
@@ -184,44 +193,41 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
                                        / 1000;
 
                als_config =
-                       (pltfm->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) |
+                       (pdata->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) |
                        (LM3530_ENABLE_ALS) |
-                       (pltfm->als_input_mode << LM3530_ALS_SEL_SHIFT);
+                       (pdata->als_input_mode << LM3530_ALS_SEL_SHIFT);
 
                als_imp_sel =
-                       (pltfm->als1_resistor_sel << LM3530_ALS1_IMP_SHIFT) |
-                       (pltfm->als2_resistor_sel << LM3530_ALS2_IMP_SHIFT);
+                       (pdata->als1_resistor_sel << LM3530_ALS1_IMP_SHIFT) |
+                       (pdata->als2_resistor_sel << LM3530_ALS2_IMP_SHIFT);
 
        }
 
-       if (drvdata->mode == LM3530_BL_MODE_PWM)
-               gen_config |= (LM3530_ENABLE_PWM) |
-                               (pltfm->pwm_pol_hi << LM3530_PWM_POL_SHIFT) |
-                               (LM3530_ENABLE_PWM_SIMPLE);
-
-       brt_ramp = (pltfm->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) |
-                       (pltfm->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT);
+       brt_ramp = (pdata->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) |
+                       (pdata->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT);
 
        if (drvdata->brightness)
                brightness = drvdata->brightness;
        else
-               brightness = drvdata->brightness = pltfm->brt_val;
+               brightness = drvdata->brightness = pdata->brt_val;
+
+       if (brightness > drvdata->led_dev.max_brightness)
+               brightness = drvdata->led_dev.max_brightness;
 
        reg_val[0] = gen_config;        /* LM3530_GEN_CONFIG */
        reg_val[1] = als_config;        /* LM3530_ALS_CONFIG */
        reg_val[2] = brt_ramp;          /* LM3530_BRT_RAMP_RATE */
-       reg_val[3] = 0x00;              /* LM3530_ALS_ZONE_REG */
-       reg_val[4] = als_imp_sel;       /* LM3530_ALS_IMP_SELECT */
-       reg_val[5] = brightness;        /* LM3530_BRT_CTRL_REG */
-       reg_val[6] = zones[0];          /* LM3530_ALS_ZB0_REG */
-       reg_val[7] = zones[1];          /* LM3530_ALS_ZB1_REG */
-       reg_val[8] = zones[2];          /* LM3530_ALS_ZB2_REG */
-       reg_val[9] = zones[3];          /* LM3530_ALS_ZB3_REG */
-       reg_val[10] = LM3530_DEF_ZT_0;  /* LM3530_ALS_Z0T_REG */
-       reg_val[11] = LM3530_DEF_ZT_1;  /* LM3530_ALS_Z1T_REG */
-       reg_val[12] = LM3530_DEF_ZT_2;  /* LM3530_ALS_Z2T_REG */
-       reg_val[13] = LM3530_DEF_ZT_3;  /* LM3530_ALS_Z3T_REG */
-       reg_val[14] = LM3530_DEF_ZT_4;  /* LM3530_ALS_Z4T_REG */
+       reg_val[3] = als_imp_sel;       /* LM3530_ALS_IMP_SELECT */
+       reg_val[4] = brightness;        /* LM3530_BRT_CTRL_REG */
+       reg_val[5] = zones[0];          /* LM3530_ALS_ZB0_REG */
+       reg_val[6] = zones[1];          /* LM3530_ALS_ZB1_REG */
+       reg_val[7] = zones[2];          /* LM3530_ALS_ZB2_REG */
+       reg_val[8] = zones[3];          /* LM3530_ALS_ZB3_REG */
+       reg_val[9] = LM3530_DEF_ZT_0;   /* LM3530_ALS_Z0T_REG */
+       reg_val[10] = LM3530_DEF_ZT_1;  /* LM3530_ALS_Z1T_REG */
+       reg_val[11] = LM3530_DEF_ZT_2;  /* LM3530_ALS_Z2T_REG */
+       reg_val[12] = LM3530_DEF_ZT_3;  /* LM3530_ALS_Z3T_REG */
+       reg_val[13] = LM3530_DEF_ZT_4;  /* LM3530_ALS_Z4T_REG */
 
        if (!drvdata->enable) {
                ret = regulator_enable(drvdata->regulator);
@@ -234,6 +240,15 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
        }
 
        for (i = 0; i < LM3530_REG_MAX; i++) {
+               /* do not update brightness register when pwm mode */
+               if (lm3530_reg[i] == LM3530_BRT_CTRL_REG &&
+                   drvdata->mode == LM3530_BL_MODE_PWM) {
+                       if (pwm->pwm_set_intensity)
+                               pwm->pwm_set_intensity(reg_val[i],
+                                       drvdata->led_dev.max_brightness);
+                       continue;
+               }
+
                ret = i2c_smbus_write_byte_data(client,
                                lm3530_reg[i], reg_val[i]);
                if (ret)
@@ -249,6 +264,9 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
        int err;
        struct lm3530_data *drvdata =
            container_of(led_cdev, struct lm3530_data, led_dev);
+       struct lm3530_platform_data *pdata = drvdata->pdata;
+       struct lm3530_pwm_data *pwm = &pdata->pwm_data;
+       u8 max_brightness = led_cdev->max_brightness;
 
        switch (drvdata->mode) {
        case LM3530_BL_MODE_MANUAL:
@@ -264,12 +282,12 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
 
                /* set the brightness in brightness control register*/
                err = i2c_smbus_write_byte_data(drvdata->client,
-                               LM3530_BRT_CTRL_REG, brt_val / 2);
+                               LM3530_BRT_CTRL_REG, brt_val);
                if (err)
                        dev_err(&drvdata->client->dev,
                                "Unable to set brightness: %d\n", err);
                else
-                       drvdata->brightness = brt_val / 2;
+                       drvdata->brightness = brt_val;
 
                if (brt_val == 0) {
                        err = regulator_disable(drvdata->regulator);
@@ -282,6 +300,8 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
        case LM3530_BL_MODE_ALS:
                break;
        case LM3530_BL_MODE_PWM:
+               if (pwm->pwm_set_intensity)
+                       pwm->pwm_set_intensity(brt_val, max_brightness);
                break;
        default:
                break;
@@ -291,11 +311,11 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
 static ssize_t lm3530_mode_get(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
-       struct i2c_client *client = container_of(
-                                       dev->parent, struct i2c_client, dev);
-       struct lm3530_data *drvdata = i2c_get_clientdata(client);
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
+       struct lm3530_data *drvdata;
        int i, len = 0;
 
+       drvdata = container_of(led_cdev, struct lm3530_data, led_dev);
        for (i = 0; i < ARRAY_SIZE(mode_map); i++)
                if (drvdata->mode == mode_map[i].mode_val)
                        len += sprintf(buf + len, "[%s] ", mode_map[i].mode);
@@ -310,26 +330,26 @@ static ssize_t lm3530_mode_get(struct device *dev,
 static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute
                                   *attr, const char *buf, size_t size)
 {
-       int err;
-       struct i2c_client *client = container_of(
-                                       dev->parent, struct i2c_client, dev);
-       struct lm3530_data *drvdata = i2c_get_clientdata(client);
-       int mode;
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
+       struct lm3530_data *drvdata;
+       struct lm3530_pwm_data *pwm;
+       u8 max_brightness;
+       int mode, err;
 
+       drvdata = container_of(led_cdev, struct lm3530_data, led_dev);
+       pwm = &drvdata->pdata->pwm_data;
+       max_brightness = led_cdev->max_brightness;
        mode = lm3530_get_mode_from_str(buf);
        if (mode < 0) {
                dev_err(dev, "Invalid mode\n");
                return -EINVAL;
        }
 
-       if (mode == LM3530_BL_MODE_MANUAL)
-               drvdata->mode = LM3530_BL_MODE_MANUAL;
-       else if (mode == LM3530_BL_MODE_ALS)
-               drvdata->mode = LM3530_BL_MODE_ALS;
-       else if (mode == LM3530_BL_MODE_PWM) {
-               dev_err(dev, "PWM mode not supported\n");
-               return -EINVAL;
-       }
+       drvdata->mode = mode;
+
+       /* set pwm to low if unnecessary */
+       if (mode != LM3530_BL_MODE_PWM && pwm->pwm_set_intensity)
+               pwm->pwm_set_intensity(0, max_brightness);
 
        err = lm3530_init_registers(drvdata);
        if (err) {
@@ -380,6 +400,7 @@ static int __devinit lm3530_probe(struct i2c_client *client,
        drvdata->enable = false;
        drvdata->led_dev.name = LM3530_LED_DEV;
        drvdata->led_dev.brightness_set = lm3530_brightness_set;
+       drvdata->led_dev.max_brightness = MAX_BRIGHTNESS;
 
        i2c_set_clientdata(client, drvdata);
 
index d62a798..410a723 100644 (file)
 #define LP5521_MASTER_ENABLE           0x40    /* Chip master enable */
 #define LP5521_LOGARITHMIC_PWM         0x80    /* Logarithmic PWM adjustment */
 #define LP5521_EXEC_RUN                        0x2A
-
-/* Bits in CONFIG register */
-#define LP5521_PWM_HF                  0x40    /* PWM: 0 = 256Hz, 1 = 558Hz */
-#define LP5521_PWRSAVE_EN              0x20    /* 1 = Power save mode */
-#define LP5521_CP_MODE_OFF             0       /* Charge pump (CP) off */
-#define LP5521_CP_MODE_BYPASS          8       /* CP forced to bypass mode */
-#define LP5521_CP_MODE_1X5             0x10    /* CP forced to 1.5x mode */
-#define LP5521_CP_MODE_AUTO            0x18    /* Automatic mode selection */
-#define LP5521_R_TO_BATT               4       /* R out: 0 = CP, 1 = Vbat */
-#define LP5521_CLK_SRC_EXT             0       /* Ext-clk source (CLK_32K) */
-#define LP5521_CLK_INT                 1       /* Internal clock */
-#define LP5521_CLK_AUTO                        2       /* Automatic clock selection */
+#define LP5521_ENABLE_DEFAULT  \
+       (LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM)
+#define LP5521_ENABLE_RUN_PROGRAM      \
+       (LP5521_ENABLE_DEFAULT | LP5521_EXEC_RUN)
 
 /* Status */
 #define LP5521_EXT_CLK_USED            0x08
 /* default R channel current register value */
 #define LP5521_REG_R_CURR_DEFAULT      0xAF
 
+/* Pattern Mode */
+#define PATTERN_OFF    0
+
 struct lp5521_engine {
        int             id;
        u8              mode;
@@ -241,15 +236,16 @@ static int lp5521_configure(struct i2c_client *client)
 {
        struct lp5521_chip *chip = i2c_get_clientdata(client);
        int ret;
+       u8 cfg;
 
        lp5521_init_engine(chip);
 
        /* Set all PWMs to direct control mode */
-       ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F);
+       ret = lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
 
-       /* Enable auto-powersave, set charge pump to auto, red to battery */
-       ret |= lp5521_write(client, LP5521_REG_CONFIG,
-               LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT);
+       cfg = chip->pdata->update_config ?
+               : (LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT);
+       ret |= lp5521_write(client, LP5521_REG_CONFIG, cfg);
 
        /* Initialize all channels PWM to zero -> leds off */
        ret |= lp5521_write(client, LP5521_REG_R_PWM, 0);
@@ -258,8 +254,7 @@ static int lp5521_configure(struct i2c_client *client)
 
        /* Set engines are set to run state when OP_MODE enables engines */
        ret |= lp5521_write(client, LP5521_REG_ENABLE,
-                       LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM |
-                       LP5521_EXEC_RUN);
+                       LP5521_ENABLE_RUN_PROGRAM);
        /* enable takes 500us. 1 - 2 ms leaves some margin */
        usleep_range(1000, 2000);
 
@@ -310,8 +305,7 @@ static int lp5521_detect(struct i2c_client *client)
        int ret;
        u8 buf;
 
-       ret = lp5521_write(client, LP5521_REG_ENABLE,
-                       LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM);
+       ret = lp5521_write(client, LP5521_REG_ENABLE, LP5521_ENABLE_DEFAULT);
        if (ret)
                return ret;
        /* enable takes 500us. 1 - 2 ms leaves some margin */
@@ -319,7 +313,7 @@ static int lp5521_detect(struct i2c_client *client)
        ret = lp5521_read(client, LP5521_REG_ENABLE, &buf);
        if (ret)
                return ret;
-       if (buf != (LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM))
+       if (buf != LP5521_ENABLE_DEFAULT)
                return -ENODEV;
 
        return 0;
@@ -504,7 +498,7 @@ static ssize_t store_current(struct device *dev,
        ssize_t ret;
        unsigned long curr;
 
-       if (strict_strtoul(buf, 0, &curr))
+       if (kstrtoul(buf, 0, &curr))
                return -EINVAL;
 
        if (curr > led->max_current)
@@ -536,6 +530,97 @@ static ssize_t lp5521_selftest(struct device *dev,
        return sprintf(buf, "%s\n", ret ? "FAIL" : "OK");
 }
 
+static void lp5521_clear_program_memory(struct i2c_client *cl)
+{
+       int i;
+       u8 rgb_mem[] = {
+               LP5521_REG_R_PROG_MEM,
+               LP5521_REG_G_PROG_MEM,
+               LP5521_REG_B_PROG_MEM,
+       };
+
+       for (i = 0; i < ARRAY_SIZE(rgb_mem); i++) {
+               lp5521_write(cl, rgb_mem[i], 0);
+               lp5521_write(cl, rgb_mem[i] + 1, 0);
+       }
+}
+
+static void lp5521_write_program_memory(struct i2c_client *cl,
+                               u8 base, u8 *rgb, int size)
+{
+       int i;
+
+       if (!rgb || size <= 0)
+               return;
+
+       for (i = 0; i < size; i++)
+               lp5521_write(cl, base + i, *(rgb + i));
+
+       lp5521_write(cl, base + i, 0);
+       lp5521_write(cl, base + i + 1, 0);
+}
+
+static inline struct lp5521_led_pattern *lp5521_get_pattern
+                                       (struct lp5521_chip *chip, u8 offset)
+{
+       struct lp5521_led_pattern *ptn;
+       ptn = chip->pdata->patterns + (offset - 1);
+       return ptn;
+}
+
+static void lp5521_run_led_pattern(int mode, struct lp5521_chip *chip)
+{
+       struct lp5521_led_pattern *ptn;
+       struct i2c_client *cl = chip->client;
+       int num_patterns = chip->pdata->num_patterns;
+
+       if (mode > num_patterns || !(chip->pdata->patterns))
+               return;
+
+       if (mode == PATTERN_OFF) {
+               lp5521_write(cl, LP5521_REG_ENABLE, LP5521_ENABLE_DEFAULT);
+               usleep_range(1000, 2000);
+               lp5521_write(cl, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
+       } else {
+               ptn = lp5521_get_pattern(chip, mode);
+               if (!ptn)
+                       return;
+
+               lp5521_write(cl, LP5521_REG_OP_MODE, LP5521_CMD_LOAD);
+               usleep_range(1000, 2000);
+
+               lp5521_clear_program_memory(cl);
+
+               lp5521_write_program_memory(cl, LP5521_REG_R_PROG_MEM,
+                                       ptn->r, ptn->size_r);
+               lp5521_write_program_memory(cl, LP5521_REG_G_PROG_MEM,
+                                       ptn->g, ptn->size_g);
+               lp5521_write_program_memory(cl, LP5521_REG_B_PROG_MEM,
+                                       ptn->b, ptn->size_b);
+
+               lp5521_write(cl, LP5521_REG_OP_MODE, LP5521_CMD_RUN);
+               usleep_range(1000, 2000);
+               lp5521_write(cl, LP5521_REG_ENABLE, LP5521_ENABLE_RUN_PROGRAM);
+       }
+}
+
+static ssize_t store_led_pattern(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t len)
+{
+       struct lp5521_chip *chip = i2c_get_clientdata(to_i2c_client(dev));
+       unsigned long val;
+       int ret;
+
+       ret = strict_strtoul(buf, 16, &val);
+       if (ret)
+               return ret;
+
+       lp5521_run_led_pattern(val, chip);
+
+       return len;
+}
+
 /* led class device attributes */
 static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, show_current, store_current);
 static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL);
@@ -561,6 +646,7 @@ static DEVICE_ATTR(engine1_load, S_IWUSR, NULL, store_engine1_load);
 static DEVICE_ATTR(engine2_load, S_IWUSR, NULL, store_engine2_load);
 static DEVICE_ATTR(engine3_load, S_IWUSR, NULL, store_engine3_load);
 static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL);
+static DEVICE_ATTR(led_pattern, S_IWUSR, NULL, store_led_pattern);
 
 static struct attribute *lp5521_attributes[] = {
        &dev_attr_engine1_mode.attr,
@@ -570,6 +656,7 @@ static struct attribute *lp5521_attributes[] = {
        &dev_attr_engine1_load.attr,
        &dev_attr_engine2_load.attr,
        &dev_attr_engine3_load.attr,
+       &dev_attr_led_pattern.attr,
        NULL
 };
 
@@ -620,10 +707,15 @@ static int __devinit lp5521_init_led(struct lp5521_led *led,
                return -EINVAL;
        }
 
-       snprintf(name, sizeof(name), "%s:channel%d",
-                       pdata->label ?: client->name, chan);
        led->cdev.brightness_set = lp5521_set_brightness;
-       led->cdev.name = name;
+       if (pdata->led_config[chan].name) {
+               led->cdev.name = pdata->led_config[chan].name;
+       } else {
+               snprintf(name, sizeof(name), "%s:channel%d",
+                       pdata->label ?: client->name, chan);
+               led->cdev.name = name;
+       }
+
        res = led_classdev_register(dev, &led->cdev);
        if (res < 0) {
                dev_err(dev, "couldn't register led on channel %d\n", chan);
@@ -692,9 +784,9 @@ static int __devinit lp5521_probe(struct i2c_client *client,
         * otherwise further access to the R G B channels in the
         * LP5521_REG_ENABLE register will not have any effect - strange!
         */
-       lp5521_read(client, LP5521_REG_R_CURRENT, &buf);
+       ret = lp5521_read(client, LP5521_REG_R_CURRENT, &buf);
        if (buf != LP5521_REG_R_CURR_DEFAULT) {
-               dev_err(&client->dev, "error in reseting chip\n");
+               dev_err(&client->dev, "error in resetting chip\n");
                goto fail2;
        }
        usleep_range(10000, 20000);
@@ -767,6 +859,7 @@ static int __devexit lp5521_remove(struct i2c_client *client)
        struct lp5521_chip *chip = i2c_get_clientdata(client);
        int i;
 
+       lp5521_run_led_pattern(PATTERN_OFF, chip);
        lp5521_unregister_sysfs(client);
 
        for (i = 0; i < chip->num_leds; i++) {
index 73e791a..857a3e1 100644 (file)
@@ -152,7 +152,7 @@ static inline struct lp5523_chip *led_to_lp5523(struct lp5523_led *led)
 
 static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode);
 static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode);
-static int lp5523_load_program(struct lp5523_engine *engine, u8 *pattern);
+static int lp5523_load_program(struct lp5523_engine *engine, const u8 *pattern);
 
 static void lp5523_led_brightness_work(struct work_struct *work);
 
@@ -196,7 +196,7 @@ static int lp5523_configure(struct i2c_client *client)
        u8 status;
 
        /* one pattern per engine setting led mux start and stop addresses */
-       u8 pattern[][LP5523_PROGRAM_LENGTH] =  {
+       static const u8 pattern[][LP5523_PROGRAM_LENGTH] =  {
                { 0x9c, 0x30, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0},
                { 0x9c, 0x40, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0},
                { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0},
@@ -301,7 +301,7 @@ static int lp5523_load_mux(struct lp5523_engine *engine, u16 mux)
        return ret;
 }
 
-static int lp5523_load_program(struct lp5523_engine *engine, u8 *pattern)
+static int lp5523_load_program(struct lp5523_engine *engine, const u8 *pattern)
 {
        struct lp5523_chip *chip = engine_to_lp5523(engine);
        struct i2c_client *client = chip->client;
diff --git a/drivers/leds/leds-pca9633.c b/drivers/leds/leds-pca9633.c
new file mode 100644 (file)
index 0000000..d8926fd
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2011 bct electronic GmbH
+ *
+ * Author: Peter Meerwald <p.meerwald@bct-electronic.com>
+ *
+ * Based on leds-pca955x.c
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License.  See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * LED driver for the PCA9633 I2C LED driver (7-bit slave address 0x62)
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/workqueue.h>
+#include <linux/slab.h>
+
+/* LED select registers determine the source that drives LED outputs */
+#define PCA9633_LED_OFF                0x0     /* LED driver off */
+#define PCA9633_LED_ON         0x1     /* LED driver on */
+#define PCA9633_LED_PWM                0x2     /* Controlled through PWM */
+#define PCA9633_LED_GRP_PWM    0x3     /* Controlled through PWM/GRPPWM */
+
+#define PCA9633_MODE1          0x00
+#define PCA9633_MODE2          0x01
+#define PCA9633_PWM_BASE       0x02
+#define PCA9633_LEDOUT         0x08
+
+static const struct i2c_device_id pca9633_id[] = {
+       { "pca9633", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, pca9633_id);
+
+struct pca9633_led {
+       struct i2c_client *client;
+       struct work_struct work;
+       enum led_brightness brightness;
+       struct led_classdev led_cdev;
+       int led_num; /* 0 .. 3 potentially */
+       char name[32];
+};
+
+static void pca9633_led_work(struct work_struct *work)
+{
+       struct pca9633_led *pca9633 = container_of(work,
+               struct pca9633_led, work);
+       u8 ledout = i2c_smbus_read_byte_data(pca9633->client, PCA9633_LEDOUT);
+       int shift = 2 * pca9633->led_num;
+       u8 mask = 0x3 << shift;
+
+       switch (pca9633->brightness) {
+       case LED_FULL:
+               i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
+                       (ledout & ~mask) | (PCA9633_LED_ON << shift));
+               break;
+       case LED_OFF:
+               i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
+                       ledout & ~mask);
+               break;
+       default:
+               i2c_smbus_write_byte_data(pca9633->client,
+                       PCA9633_PWM_BASE + pca9633->led_num,
+                       pca9633->brightness);
+               i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
+                       (ledout & ~mask) | (PCA9633_LED_PWM << shift));
+               break;
+       }
+}
+
+static void pca9633_led_set(struct led_classdev *led_cdev,
+       enum led_brightness value)
+{
+       struct pca9633_led *pca9633;
+
+       pca9633 = container_of(led_cdev, struct pca9633_led, led_cdev);
+
+       pca9633->brightness = value;
+
+       /*
+        * Must use workqueue for the actual I/O since I2C operations
+        * can sleep.
+        */
+       schedule_work(&pca9633->work);
+}
+
+static int __devinit pca9633_probe(struct i2c_client *client,
+                                       const struct i2c_device_id *id)
+{
+       struct pca9633_led *pca9633;
+       struct led_platform_data *pdata;
+       int i, err;
+
+       pdata = client->dev.platform_data;
+
+       if (pdata) {
+               if (pdata->num_leds <= 0 || pdata->num_leds > 4) {
+                       dev_err(&client->dev, "board info must claim at most 4 LEDs");
+                       return -EINVAL;
+               }
+       }
+
+       pca9633 = kcalloc(4, sizeof(*pca9633), GFP_KERNEL);
+       if (!pca9633)
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, pca9633);
+
+       for (i = 0; i < 4; i++) {
+               pca9633[i].client = client;
+               pca9633[i].led_num = i;
+
+               /* Platform data can specify LED names and default triggers */
+               if (pdata && i < pdata->num_leds) {
+                       if (pdata->leds[i].name)
+                               snprintf(pca9633[i].name,
+                                        sizeof(pca9633[i].name), "pca9633:%s",
+                                        pdata->leds[i].name);
+                       if (pdata->leds[i].default_trigger)
+                               pca9633[i].led_cdev.default_trigger =
+                                       pdata->leds[i].default_trigger;
+               } else {
+                       snprintf(pca9633[i].name, sizeof(pca9633[i].name),
+                                "pca9633:%d", i);
+               }
+
+               pca9633[i].led_cdev.name = pca9633[i].name;
+               pca9633[i].led_cdev.brightness_set = pca9633_led_set;
+
+               INIT_WORK(&pca9633[i].work, pca9633_led_work);
+
+               err = led_classdev_register(&client->dev, &pca9633[i].led_cdev);
+               if (err < 0)
+                       goto exit;
+       }
+
+       /* Disable LED all-call address and set normal mode */
+       i2c_smbus_write_byte_data(client, PCA9633_MODE1, 0x00);
+
+       /* Turn off LEDs */
+       i2c_smbus_write_byte_data(client, PCA9633_LEDOUT, 0x00);
+
+       return 0;
+
+exit:
+       while (i--) {
+               led_classdev_unregister(&pca9633[i].led_cdev);
+               cancel_work_sync(&pca9633[i].work);
+       }
+
+       kfree(pca9633);
+
+       return err;
+}
+
+static int __devexit pca9633_remove(struct i2c_client *client)
+{
+       struct pca9633_led *pca9633 = i2c_get_clientdata(client);
+       int i;
+
+       for (i = 0; i < 4; i++) {
+               led_classdev_unregister(&pca9633[i].led_cdev);
+               cancel_work_sync(&pca9633[i].work);
+       }
+
+       kfree(pca9633);
+
+       return 0;
+}
+
+static struct i2c_driver pca9633_driver = {
+       .driver = {
+               .name   = "leds-pca9633",
+               .owner  = THIS_MODULE,
+       },
+       .probe  = pca9633_probe,
+       .remove = __devexit_p(pca9633_remove),
+       .id_table = pca9633_id,
+};
+
+module_i2c_driver(pca9633_driver);
+
+MODULE_AUTHOR("Peter Meerwald <p.meerwald@bct-electronic.com>");
+MODULE_DESCRIPTION("PCA9633 LED driver");
+MODULE_LICENSE("GPL v2");
index 133f89f..6c1c14f 100644 (file)
@@ -687,10 +687,9 @@ static int __devinit tca6507_probe(struct i2c_client *client,
                        NUM_LEDS);
                return -ENODEV;
        }
-       err = -ENOMEM;
        tca = kzalloc(sizeof(*tca), GFP_KERNEL);
        if (!tca)
-               goto exit;
+               return -ENOMEM;
 
        tca->client = client;
        INIT_WORK(&tca->work, tca6507_work);
@@ -724,11 +723,10 @@ static int __devinit tca6507_probe(struct i2c_client *client,
 
        return 0;
 exit:
-       while (i--)
+       while (i--) {
                if (tca->leds[i].led_cdev.name)
                        led_classdev_unregister(&tca->leds[i].led_cdev);
-       cancel_work_sync(&tca->work);
-       i2c_set_clientdata(client, NULL);
+       }
        kfree(tca);
        return err;
 }
@@ -745,7 +743,6 @@ static int __devexit tca6507_remove(struct i2c_client *client)
        }
        tca6507_remove_gpio(tca);
        cancel_work_sync(&tca->work);
-       i2c_set_clientdata(client, NULL);
        kfree(tca);
 
        return 0;
index e1e122f..9bcd1f4 100644 (file)
@@ -2526,12 +2526,10 @@ static void cfi_intelext_restore_locks(struct mtd_info *mtd)
                if (!region->lockmap)
                        continue;
 
-               for (block = 0; block < region->numblocks; block++) {
+               for_each_clear_bit(block, region->lockmap, region->numblocks) {
                        len = region->erasesize;
                        adr = region->offset + block * len;
-
-                       if (!test_bit(block, region->lockmap))
-                               cfi_intelext_unlock(mtd, adr, len);
+                       cfi_intelext_unlock(mtd, adr, len);
                }
        }
 }
index 50c6a1e..c57ae92 100644 (file)
 #include <linux/compat.h>
 #include <linux/mount.h>
 #include <linux/blkpg.h>
+#include <linux/magic.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/map.h>
 
 #include <asm/uaccess.h>
 
-#define MTD_INODE_FS_MAGIC 0x11307854
 static DEFINE_MUTEX(mtd_mutex);
 static struct vfsmount *mtd_inode_mnt __read_mostly;
 
index 3a125b8..4f9fb25 100644 (file)
@@ -554,6 +554,13 @@ config RTC_DRV_DS1742
          This driver can also be built as a module. If so, the module
          will be called rtc-ds1742.
 
+config RTC_DRV_DA9052
+       tristate "Dialog DA9052/DA9053 RTC"
+       depends on PMIC_DA9052
+       help
+         Say y here to support the RTC driver for Dialog Semiconductor
+         DA9052-BC and DA9053-AA/Bx PMICs.
+
 config RTC_DRV_EFI
        tristate "EFI RTC"
        depends on IA64
@@ -1070,4 +1077,14 @@ config RTC_DRV_PUV3
          This drive can also be built as a module. If so, the module
          will be called rtc-puv3.
 
+config RTC_DRV_LOONGSON1
+       tristate "loongson1 RTC support"
+       depends on MACH_LOONGSON1
+       help
+         This is a driver for the loongson1 on-chip Counter0 (Time-Of-Year
+         counter) to be used as a RTC.
+
+         This driver can also be built as a module. If so, the module
+         will be called rtc-ls1x.
+
 endif # RTC_CLASS
index 6e69823..727ae77 100644 (file)
@@ -27,6 +27,7 @@ obj-$(CONFIG_RTC_DRV_BQ32K)   += rtc-bq32k.o
 obj-$(CONFIG_RTC_DRV_BQ4802)   += rtc-bq4802.o
 obj-$(CONFIG_RTC_DRV_CMOS)     += rtc-cmos.o
 obj-$(CONFIG_RTC_DRV_COH901331)        += rtc-coh901331.o
+obj-$(CONFIG_RTC_DRV_DA9052)   += rtc-da9052.o
 obj-$(CONFIG_RTC_DRV_DAVINCI)  += rtc-davinci.o
 obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o
 obj-$(CONFIG_RTC_DRV_VRTC)     += rtc-mrst.o
@@ -53,6 +54,7 @@ obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
 obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o
 obj-$(CONFIG_RTC_DRV_JZ4740)   += rtc-jz4740.o
 obj-$(CONFIG_RTC_DRV_LPC32XX)  += rtc-lpc32xx.o
+obj-$(CONFIG_RTC_DRV_LOONGSON1)        += rtc-ls1x.o
 obj-$(CONFIG_RTC_DRV_M41T80)   += rtc-m41t80.o
 obj-$(CONFIG_RTC_DRV_M41T93)   += rtc-m41t93.o
 obj-$(CONFIG_RTC_DRV_M41T94)   += rtc-m41t94.o
index ee3c122..274a0aa 100644 (file)
@@ -335,7 +335,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
 
        /* register irq handler after we know what name we'll use */
        ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt,
-                               IRQF_DISABLED | IRQF_SHARED,
+                               IRQF_SHARED,
                                dev_name(&rtc->rtcdev->dev), rtc);
        if (ret) {
                dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS);
index 408cc8f..f090159 100644 (file)
@@ -187,17 +187,7 @@ static struct i2c_driver bq32k_driver = {
        .id_table       = bq32k_id,
 };
 
-static __init int bq32k_init(void)
-{
-       return i2c_add_driver(&bq32k_driver);
-}
-module_init(bq32k_init);
-
-static __exit void bq32k_exit(void)
-{
-       i2c_del_driver(&bq32k_driver);
-}
-module_exit(bq32k_exit);
+module_i2c_driver(bq32k_driver);
 
 MODULE_AUTHOR("Semihalf, Piotr Ziecik <kosmo@semihalf.com>");
 MODULE_DESCRIPTION("TI BQ32000 I2C RTC driver");
index d7782aa..7d5f56e 100644 (file)
@@ -714,7 +714,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
                        rtc_cmos_int_handler = cmos_interrupt;
 
                retval = request_irq(rtc_irq, rtc_cmos_int_handler,
-                               IRQF_DISABLED, dev_name(&cmos_rtc.rtc->dev),
+                               0, dev_name(&cmos_rtc.rtc->dev),
                                cmos_rtc.rtc);
                if (retval < 0) {
                        dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
index 80f9c88..a5b8a0c 100644 (file)
@@ -199,7 +199,7 @@ static int __init coh901331_probe(struct platform_device *pdev)
        }
 
        rtap->irq = platform_get_irq(pdev, 0);
-       if (request_irq(rtap->irq, coh901331_interrupt, IRQF_DISABLED,
+       if (request_irq(rtap->irq, coh901331_interrupt, 0,
                        "RTC COH 901 331 Alarm", rtap)) {
                ret = -EIO;
                goto out_no_irq;
diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c
new file mode 100644 (file)
index 0000000..da6ab52
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * Real time clock driver for DA9052
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: Dajun Dajun Chen <dajun.chen@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/reg.h>
+
+#define rtc_err(da9052, fmt, ...) \
+               dev_err(da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__)
+
+struct da9052_rtc {
+       struct rtc_device *rtc;
+       struct da9052 *da9052;
+       int irq;
+};
+
+static int da9052_rtc_enable_alarm(struct da9052 *da9052, bool enable)
+{
+       int ret;
+       if (enable) {
+               ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG,
+                                       DA9052_ALARM_Y_ALARM_ON,
+                                       DA9052_ALARM_Y_ALARM_ON);
+               if (ret != 0)
+                       rtc_err(da9052, "Failed to enable ALM: %d\n", ret);
+       } else {
+               ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG,
+                                       DA9052_ALARM_Y_ALARM_ON, 0);
+               if (ret != 0)
+                       rtc_err(da9052, "Write error: %d\n", ret);
+       }
+       return ret;
+}
+
+static irqreturn_t da9052_rtc_irq(int irq, void *data)
+{
+       struct da9052_rtc *rtc = data;
+       int ret;
+
+       ret = da9052_reg_read(rtc->da9052, DA9052_ALARM_MI_REG);
+       if (ret < 0) {
+               rtc_err(rtc->da9052, "Read error: %d\n", ret);
+               return IRQ_NONE;
+       }
+
+       if (ret & DA9052_ALARMMI_ALARMTYPE) {
+               da9052_rtc_enable_alarm(rtc->da9052, 0);
+               rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
+       } else
+               rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_PF);
+
+       return IRQ_HANDLED;
+}
+
+static int da9052_read_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm)
+{
+       int ret;
+       uint8_t v[5];
+
+       ret = da9052_group_read(da9052, DA9052_ALARM_MI_REG, 5, v);
+       if (ret != 0) {
+               rtc_err(da9052, "Failed to group read ALM: %d\n", ret);
+               return ret;
+       }
+
+       rtc_tm->tm_year = (v[4] & DA9052_RTC_YEAR) + 100;
+       rtc_tm->tm_mon  = (v[3] & DA9052_RTC_MONTH) - 1;
+       rtc_tm->tm_mday = v[2] & DA9052_RTC_DAY;
+       rtc_tm->tm_hour = v[1] & DA9052_RTC_HOUR;
+       rtc_tm->tm_min  = v[0] & DA9052_RTC_MIN;
+
+       ret = rtc_valid_tm(rtc_tm);
+       if (ret != 0)
+               return ret;
+       return ret;
+}
+
+static int da9052_set_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm)
+{
+       int ret;
+       uint8_t v[3];
+
+       rtc_tm->tm_year -= 100;
+       rtc_tm->tm_mon += 1;
+
+       ret = da9052_reg_update(da9052, DA9052_ALARM_MI_REG,
+                               DA9052_RTC_MIN, rtc_tm->tm_min);
+       if (ret != 0) {
+               rtc_err(da9052, "Failed to write ALRM MIN: %d\n", ret);
+               return ret;
+       }
+
+       v[0] = rtc_tm->tm_hour;
+       v[1] = rtc_tm->tm_mday;
+       v[2] = rtc_tm->tm_mon;
+
+       ret = da9052_group_write(da9052, DA9052_ALARM_H_REG, 3, v);
+       if (ret < 0)
+               return ret;
+
+       ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG,
+                               DA9052_RTC_YEAR, rtc_tm->tm_year);
+       if (ret != 0)
+               rtc_err(da9052, "Failed to write ALRM YEAR: %d\n", ret);
+
+       return ret;
+}
+
+static int da9052_rtc_get_alarm_status(struct da9052 *da9052)
+{
+       int ret;
+
+       ret = da9052_reg_read(da9052, DA9052_ALARM_Y_REG);
+       if (ret < 0) {
+               rtc_err(da9052, "Failed to read ALM: %d\n", ret);
+               return ret;
+       }
+       ret &= DA9052_ALARM_Y_ALARM_ON;
+       return (ret > 0) ? 1 : 0;
+}
+
+static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
+{
+       struct da9052_rtc *rtc = dev_get_drvdata(dev);
+       uint8_t v[6];
+       int ret;
+
+       ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, v);
+       if (ret < 0) {
+               rtc_err(rtc->da9052, "Failed to read RTC time : %d\n", ret);
+               return ret;
+       }
+
+       rtc_tm->tm_year = (v[5] & DA9052_RTC_YEAR) + 100;
+       rtc_tm->tm_mon  = (v[4] & DA9052_RTC_MONTH) - 1;
+       rtc_tm->tm_mday = v[3] & DA9052_RTC_DAY;
+       rtc_tm->tm_hour = v[2] & DA9052_RTC_HOUR;
+       rtc_tm->tm_min  = v[1] & DA9052_RTC_MIN;
+       rtc_tm->tm_sec  = v[0] & DA9052_RTC_SEC;
+
+       ret = rtc_valid_tm(rtc_tm);
+       if (ret != 0) {
+               rtc_err(rtc->da9052, "rtc_valid_tm failed: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+       struct da9052_rtc *rtc;
+       uint8_t v[6];
+
+       rtc = dev_get_drvdata(dev);
+
+       v[0] = tm->tm_sec;
+       v[1] = tm->tm_min;
+       v[2] = tm->tm_hour;
+       v[3] = tm->tm_mday;
+       v[4] = tm->tm_mon + 1;
+       v[5] = tm->tm_year - 100;
+
+       return da9052_group_write(rtc->da9052, DA9052_COUNT_S_REG, 6, v);
+}
+
+static int da9052_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+       int ret;
+       struct rtc_time *tm = &alrm->time;
+       struct da9052_rtc *rtc = dev_get_drvdata(dev);
+
+       ret = da9052_read_alarm(rtc->da9052, tm);
+
+       if (ret)
+               return ret;
+
+       alrm->enabled = da9052_rtc_get_alarm_status(rtc->da9052);
+
+       return 0;
+}
+
+static int da9052_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+       int ret;
+       struct rtc_time *tm = &alrm->time;
+       struct da9052_rtc *rtc = dev_get_drvdata(dev);
+
+       ret = da9052_rtc_enable_alarm(rtc->da9052, 0);
+       if (ret < 0)
+               return ret;
+
+       ret = da9052_set_alarm(rtc->da9052, tm);
+       if (ret)
+               return ret;
+
+       ret = da9052_rtc_enable_alarm(rtc->da9052, 1);
+
+       return ret;
+}
+
+static int da9052_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+       struct da9052_rtc *rtc = dev_get_drvdata(dev);
+
+       return da9052_rtc_enable_alarm(rtc->da9052, enabled);
+}
+
+static const struct rtc_class_ops da9052_rtc_ops = {
+       .read_time      = da9052_rtc_read_time,
+       .set_time       = da9052_rtc_set_time,
+       .read_alarm     = da9052_rtc_read_alarm,
+       .set_alarm      = da9052_rtc_set_alarm,
+       .alarm_irq_enable = da9052_rtc_alarm_irq_enable,
+};
+
+static int __devinit da9052_rtc_probe(struct platform_device *pdev)
+{
+       struct da9052_rtc *rtc;
+       int ret;
+
+       rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9052_rtc), GFP_KERNEL);
+       if (!rtc)
+               return -ENOMEM;
+
+       rtc->da9052 = dev_get_drvdata(pdev->dev.parent);
+       platform_set_drvdata(pdev, rtc);
+       rtc->irq = platform_get_irq_byname(pdev, "ALM");
+       ret = request_threaded_irq(rtc->irq, NULL, da9052_rtc_irq,
+                                  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+                                  "ALM", rtc);
+       if (ret != 0) {
+               rtc_err(rtc->da9052, "irq registration failed: %d\n", ret);
+               goto err_mem;
+       }
+
+       rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+                                      &da9052_rtc_ops, THIS_MODULE);
+       if (IS_ERR(rtc->rtc)) {
+               ret = PTR_ERR(rtc->rtc);
+               goto err_free_irq;
+       }
+
+       return 0;
+
+err_free_irq:
+       free_irq(rtc->irq, rtc);
+err_mem:
+       devm_kfree(&pdev->dev, rtc);
+       return ret;
+}
+
+static int __devexit da9052_rtc_remove(struct platform_device *pdev)
+{
+       struct da9052_rtc *rtc = pdev->dev.platform_data;
+
+       rtc_device_unregister(rtc->rtc);
+       free_irq(rtc->irq, rtc);
+       platform_set_drvdata(pdev, NULL);
+       devm_kfree(&pdev->dev, rtc);
+
+       return 0;
+}
+
+static struct platform_driver da9052_rtc_driver = {
+       .probe  = da9052_rtc_probe,
+       .remove = __devexit_p(da9052_rtc_remove),
+       .driver = {
+               .name   = "da9052-rtc",
+               .owner  = THIS_MODULE,
+       },
+};
+
+module_platform_driver(da9052_rtc_driver);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("RTC driver for Dialog DA9052 PMIC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9052-rtc");
index 755e1fe..14c2109 100644 (file)
@@ -542,7 +542,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
        rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL);
 
        ret = request_irq(davinci_rtc->irq, davinci_rtc_interrupt,
-                         IRQF_DISABLED, "davinci_rtc", davinci_rtc);
+                         0, "davinci_rtc", davinci_rtc);
        if (ret < 0) {
                dev_err(dev, "unable to register davinci RTC interrupt\n");
                goto fail4;
index 3a33b1f..686a865 100644 (file)
@@ -814,17 +814,7 @@ static struct spi_driver ds1305_driver = {
        /* REVISIT add suspend/resume */
 };
 
-static int __init ds1305_init(void)
-{
-       return spi_register_driver(&ds1305_driver);
-}
-module_init(ds1305_init);
-
-static void __exit ds1305_exit(void)
-{
-       spi_unregister_driver(&ds1305_driver);
-}
-module_exit(ds1305_exit);
+module_spi_driver(ds1305_driver);
 
 MODULE_DESCRIPTION("RTC driver for DS1305 and DS1306 chips");
 MODULE_LICENSE("GPL");
index 62b0763..cd188ab 100644 (file)
@@ -20,7 +20,8 @@
 
 
 
-/* We can't determine type by probing, but if we expect pre-Linux code
+/*
+ * We can't determine type by probing, but if we expect pre-Linux code
  * to have set the chip up as a clock (turning on the oscillator and
  * setting the date and time), Linux can ignore the non-clock features.
  * That's a natural job for a factory or repair bench.
@@ -36,7 +37,8 @@ enum ds_type {
        m41t00,
        mcp7941x,
        rx_8025,
-       // rs5c372 too?  different address...
+       last_ds_type /* always last */
+       /* rs5c372 too?  different address... */
 };
 
 
@@ -58,7 +60,8 @@ enum ds_type {
 #      define DS1337_BIT_CENTURY       0x80    /* in REG_MONTH */
 #define DS1307_REG_YEAR                0x06    /* 00-99 */
 
-/* Other registers (control, status, alarms, trickle charge, NVRAM, etc)
+/*
+ * Other registers (control, status, alarms, trickle charge, NVRAM, etc)
  * start at 7, and they differ a LOT. Only control and status matter for
  * basic RTC date and time functionality; be careful using them.
  */
@@ -102,6 +105,8 @@ enum ds_type {
 struct ds1307 {
        u8                      offset; /* register's offset */
        u8                      regs[11];
+       u16                     nvram_offset;
+       struct bin_attribute    *nvram;
        enum ds_type            type;
        unsigned long           flags;
 #define HAS_NVRAM      0               /* bit 0 == sysfs file active */
@@ -116,34 +121,35 @@ struct ds1307 {
 };
 
 struct chip_desc {
-       unsigned                nvram56:1;
        unsigned                alarm:1;
+       u16                     nvram_offset;
+       u16                     nvram_size;
 };
 
-static const struct chip_desc chips[] = {
-[ds_1307] = {
-       .nvram56        = 1,
-},
-[ds_1337] = {
-       .alarm          = 1,
-},
-[ds_1338] = {
-       .nvram56        = 1,
-},
-[ds_1339] = {
-       .alarm          = 1,
-},
-[ds_1340] = {
-},
-[ds_3231] = {
-       .alarm          = 1,
-},
-[m41t00] = {
-},
-[mcp7941x] = {
-},
-[rx_8025] = {
-}, };
+static const struct chip_desc chips[last_ds_type] = {
+       [ds_1307] = {
+               .nvram_offset   = 8,
+               .nvram_size     = 56,
+       },
+       [ds_1337] = {
+               .alarm          = 1,
+       },
+       [ds_1338] = {
+               .nvram_offset   = 8,
+               .nvram_size     = 56,
+       },
+       [ds_1339] = {
+               .alarm          = 1,
+       },
+       [ds_3231] = {
+               .alarm          = 1,
+       },
+       [mcp7941x] = {
+               /* this is battery backed SRAM */
+               .nvram_offset   = 0x20,
+               .nvram_size     = 0x40,
+       },
+};
 
 static const struct i2c_device_id ds1307_id[] = {
        { "ds1307", ds_1307 },
@@ -372,6 +378,11 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
                                | DS1340_BIT_CENTURY;
                break;
        case mcp7941x:
+               /*
+                * these bits were cleared when preparing the date/time
+                * values and need to be set again before writing the
+                * buffer out to the device.
+                */
                buf[DS1307_REG_SECS] |= MCP7941X_BIT_ST;
                buf[DS1307_REG_WDAY] |= MCP7941X_BIT_VBATEN;
                break;
@@ -417,7 +428,8 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
                        ds1307->regs[6], ds1307->regs[7],
                        ds1307->regs[8]);
 
-       /* report alarm time (ALARM1); assume 24 hour and day-of-month modes,
+       /*
+        * report alarm time (ALARM1); assume 24 hour and day-of-month modes,
         * and that all four fields are checked matches
         */
        t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f);
@@ -445,7 +457,7 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
 
 static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 {
-       struct i2c_client       *client = to_i2c_client(dev);
+       struct i2c_client       *client = to_i2c_client(dev);
        struct ds1307           *ds1307 = i2c_get_clientdata(client);
        unsigned char           *buf = ds1307->regs;
        u8                      control, status;
@@ -541,8 +553,6 @@ static const struct rtc_class_ops ds13xx_rtc_ops = {
 
 /*----------------------------------------------------------------------*/
 
-#define NVRAM_SIZE     56
-
 static ssize_t
 ds1307_nvram_read(struct file *filp, struct kobject *kobj,
                struct bin_attribute *attr,
@@ -555,14 +565,15 @@ ds1307_nvram_read(struct file *filp, struct kobject *kobj,
        client = kobj_to_i2c_client(kobj);
        ds1307 = i2c_get_clientdata(client);
 
-       if (unlikely(off >= NVRAM_SIZE))
+       if (unlikely(off >= ds1307->nvram->size))
                return 0;
-       if ((off + count) > NVRAM_SIZE)
-               count = NVRAM_SIZE - off;
+       if ((off + count) > ds1307->nvram->size)
+               count = ds1307->nvram->size - off;
        if (unlikely(!count))
                return count;
 
-       result = ds1307->read_block_data(client, 8 + off, count, buf);
+       result = ds1307->read_block_data(client, ds1307->nvram_offset + off,
+                                                               count, buf);
        if (result < 0)
                dev_err(&client->dev, "%s error %d\n", "nvram read", result);
        return result;
@@ -580,14 +591,15 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj,
        client = kobj_to_i2c_client(kobj);
        ds1307 = i2c_get_clientdata(client);
 
-       if (unlikely(off >= NVRAM_SIZE))
+       if (unlikely(off >= ds1307->nvram->size))
                return -EFBIG;
-       if ((off + count) > NVRAM_SIZE)
-               count = NVRAM_SIZE - off;
+       if ((off + count) > ds1307->nvram->size)
+               count = ds1307->nvram->size - off;
        if (unlikely(!count))
                return count;
 
-       result = ds1307->write_block_data(client, 8 + off, count, buf);
+       result = ds1307->write_block_data(client, ds1307->nvram_offset + off,
+                                                               count, buf);
        if (result < 0) {
                dev_err(&client->dev, "%s error %d\n", "nvram write", result);
                return result;
@@ -595,21 +607,8 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj,
        return count;
 }
 
-static struct bin_attribute nvram = {
-       .attr = {
-               .name   = "nvram",
-               .mode   = S_IRUGO | S_IWUSR,
-       },
-
-       .read   = ds1307_nvram_read,
-       .write  = ds1307_nvram_write,
-       .size   = NVRAM_SIZE,
-};
-
 /*----------------------------------------------------------------------*/
 
-static struct i2c_driver ds1307_driver;
-
 static int __devinit ds1307_probe(struct i2c_client *client,
                                  const struct i2c_device_id *id)
 {
@@ -630,7 +629,8 @@ static int __devinit ds1307_probe(struct i2c_client *client,
            && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
                return -EIO;
 
-       if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL)))
+       ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL);
+       if (!ds1307)
                return -ENOMEM;
 
        i2c_set_clientdata(client, ds1307);
@@ -652,11 +652,6 @@ static int __devinit ds1307_probe(struct i2c_client *client,
        case ds_1337:
        case ds_1339:
        case ds_3231:
-               /* has IRQ? */
-               if (ds1307->client->irq > 0 && chip->alarm) {
-                       INIT_WORK(&ds1307->work, ds1307_work);
-                       want_irq = true;
-               }
                /* get registers that the "rtc" read below won't read... */
                tmp = ds1307->read_block_data(ds1307->client,
                                DS1337_REG_CONTROL, 2, buf);
@@ -670,14 +665,19 @@ static int __devinit ds1307_probe(struct i2c_client *client,
                if (ds1307->regs[0] & DS1337_BIT_nEOSC)
                        ds1307->regs[0] &= ~DS1337_BIT_nEOSC;
 
-               /* Using IRQ?  Disable the square wave and both alarms.
+               /*
+                * Using IRQ?  Disable the square wave and both alarms.
                 * For some variants, be sure alarms can trigger when we're
                 * running on Vbackup (BBSQI/BBSQW)
                 */
-               if (want_irq) {
+               if (ds1307->client->irq > 0 && chip->alarm) {
+                       INIT_WORK(&ds1307->work, ds1307_work);
+
                        ds1307->regs[0] |= DS1337_BIT_INTCN
                                        | bbsqi_bitpos[ds1307->type];
                        ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
+
+                       want_irq = true;
                }
 
                i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
@@ -772,7 +772,8 @@ read_rtc:
                goto exit_free;
        }
 
-       /* minimal sanity checking; some chips (like DS1340) don't
+       /*
+        * minimal sanity checking; some chips (like DS1340) don't
         * specify the extra bits as must-be-zero, but there are
         * still a few values that are clearly out-of-range.
         */
@@ -836,11 +837,7 @@ read_rtc:
                }
 
                break;
-       case rx_8025:
-       case ds_1337:
-       case ds_1339:
-       case ds_1388:
-       case ds_3231:
+       default:
                break;
        }
 
@@ -848,7 +845,8 @@ read_rtc:
        switch (ds1307->type) {
        case ds_1340:
        case m41t00:
-               /* NOTE: ignores century bits; fix before deploying
+               /*
+                * NOTE: ignores century bits; fix before deploying
                 * systems that will run through year 2100.
                 */
                break;
@@ -858,7 +856,8 @@ read_rtc:
                if (!(tmp & DS1307_BIT_12HR))
                        break;
 
-               /* Be sure we're in 24 hour mode.  Multi-master systems
+               /*
+                * Be sure we're in 24 hour mode.  Multi-master systems
                 * take note...
                 */
                tmp = bcd2bin(tmp & 0x1f);
@@ -894,16 +893,31 @@ read_rtc:
                dev_dbg(&client->dev, "got IRQ %d\n", client->irq);
        }
 
-       if (chip->nvram56) {
-               err = sysfs_create_bin_file(&client->dev.kobj, &nvram);
-               if (err == 0) {
-                       set_bit(HAS_NVRAM, &ds1307->flags);
-                       dev_info(&client->dev, "56 bytes nvram\n");
+       if (chip->nvram_size) {
+               ds1307->nvram = kzalloc(sizeof(struct bin_attribute),
+                                                       GFP_KERNEL);
+               if (!ds1307->nvram) {
+                       err = -ENOMEM;
+                       goto exit_nvram;
+               }
+               ds1307->nvram->attr.name = "nvram";
+               ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR;
+               ds1307->nvram->read = ds1307_nvram_read,
+               ds1307->nvram->write = ds1307_nvram_write,
+               ds1307->nvram->size = chip->nvram_size;
+               ds1307->nvram_offset = chip->nvram_offset;
+               err = sysfs_create_bin_file(&client->dev.kobj, ds1307->nvram);
+               if (err) {
+                       kfree(ds1307->nvram);
+                       goto exit_nvram;
                }
+               set_bit(HAS_NVRAM, &ds1307->flags);
+               dev_info(&client->dev, "%zu bytes nvram\n", ds1307->nvram->size);
        }
 
        return 0;
 
+exit_nvram:
 exit_irq:
        rtc_device_unregister(ds1307->rtc);
 exit_free:
@@ -913,15 +927,17 @@ exit_free:
 
 static int __devexit ds1307_remove(struct i2c_client *client)
 {
-       struct ds1307           *ds1307 = i2c_get_clientdata(client);
+       struct ds1307 *ds1307 = i2c_get_clientdata(client);
 
        if (test_and_clear_bit(HAS_ALARM, &ds1307->flags)) {
                free_irq(client->irq, client);
                cancel_work_sync(&ds1307->work);
        }
 
-       if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags))
-               sysfs_remove_bin_file(&client->dev.kobj, &nvram);
+       if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags)) {
+               sysfs_remove_bin_file(&client->dev.kobj, ds1307->nvram);
+               kfree(ds1307->nvram);
+       }
 
        rtc_device_unregister(ds1307->rtc);
        kfree(ds1307);
@@ -938,17 +954,7 @@ static struct i2c_driver ds1307_driver = {
        .id_table       = ds1307_id,
 };
 
-static int __init ds1307_init(void)
-{
-       return i2c_add_driver(&ds1307_driver);
-}
-module_init(ds1307_init);
-
-static void __exit ds1307_exit(void)
-{
-       i2c_del_driver(&ds1307_driver);
-}
-module_exit(ds1307_exit);
+module_i2c_driver(ds1307_driver);
 
 MODULE_DESCRIPTION("RTC driver for DS1307 and similar chips");
 MODULE_LICENSE("GPL");
index e6e71de..9663160 100644 (file)
@@ -446,18 +446,7 @@ static struct i2c_driver ds1374_driver = {
        .id_table = ds1374_id,
 };
 
-static int __init ds1374_init(void)
-{
-       return i2c_add_driver(&ds1374_driver);
-}
-
-static void __exit ds1374_exit(void)
-{
-       i2c_del_driver(&ds1374_driver);
-}
-
-module_init(ds1374_init);
-module_exit(ds1374_exit);
+module_i2c_driver(ds1374_driver);
 
 MODULE_AUTHOR("Scott Wood <scottwood@freescale.com>");
 MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC Driver");
index b038d2c..b0a99e1 100644 (file)
@@ -175,17 +175,7 @@ static struct spi_driver ds1390_driver = {
        .remove = __devexit_p(ds1390_remove),
 };
 
-static __init int ds1390_init(void)
-{
-       return spi_register_driver(&ds1390_driver);
-}
-module_init(ds1390_init);
-
-static __exit void ds1390_exit(void)
-{
-       spi_unregister_driver(&ds1390_driver);
-}
-module_exit(ds1390_exit);
+module_spi_driver(ds1390_driver);
 
 MODULE_DESCRIPTION("Dallas/Maxim DS1390/93/94 SPI RTC driver");
 MODULE_AUTHOR("Mark Jackson <mpfj@mimc.co.uk>");
index 761f36b..1f675f5 100644 (file)
@@ -532,7 +532,7 @@ ds1511_rtc_probe(struct platform_device *pdev)
        if (pdata->irq > 0) {
                rtc_read(RTC_CMD1);
                if (devm_request_irq(&pdev->dev, pdata->irq, ds1511_interrupt,
-                       IRQF_DISABLED | IRQF_SHARED, pdev->name, pdev) < 0) {
+                       IRQF_SHARED, pdev->name, pdev) < 0) {
 
                        dev_warn(&pdev->dev, "interrupt not available.\n");
                        pdata->irq = 0;
index 6f0a1b5..6ccedbb 100644 (file)
@@ -320,7 +320,7 @@ static int __devinit ds1553_rtc_probe(struct platform_device *pdev)
                writeb(0, ioaddr + RTC_INTERRUPTS);
                if (devm_request_irq(&pdev->dev, pdata->irq,
                                ds1553_rtc_interrupt,
-                               IRQF_DISABLED, pdev->name, pdev) < 0) {
+                               0, pdev->name, pdev) < 0) {
                        dev_warn(&pdev->dev, "interrupt not available.\n");
                        pdata->irq = 0;
                }
index a319402..7fa67d0 100644 (file)
@@ -202,20 +202,9 @@ static struct i2c_driver ds1672_driver = {
        .id_table = ds1672_id,
 };
 
-static int __init ds1672_init(void)
-{
-       return i2c_add_driver(&ds1672_driver);
-}
-
-static void __exit ds1672_exit(void)
-{
-       i2c_del_driver(&ds1672_driver);
-}
+module_i2c_driver(ds1672_driver);
 
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(ds1672_init);
-module_exit(ds1672_exit);
index 27b7bf6..e194509 100644 (file)
@@ -473,18 +473,7 @@ static struct i2c_driver ds3232_driver = {
        .id_table = ds3232_id,
 };
 
-static int __init ds3232_init(void)
-{
-       return i2c_add_driver(&ds3232_driver);
-}
-
-static void __exit ds3232_exit(void)
-{
-       i2c_del_driver(&ds3232_driver);
-}
-
-module_init(ds3232_init);
-module_exit(ds3232_exit);
+module_i2c_driver(ds3232_driver);
 
 MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>");
 MODULE_DESCRIPTION("Maxim/Dallas DS3232 RTC Driver");
index bbd2622..fda7079 100644 (file)
@@ -173,17 +173,7 @@ static struct spi_driver ds3234_driver = {
        .remove = __devexit_p(ds3234_remove),
 };
 
-static __init int ds3234_init(void)
-{
-       return spi_register_driver(&ds3234_driver);
-}
-module_init(ds3234_init);
-
-static __exit void ds3234_exit(void)
-{
-       spi_unregister_driver(&ds3234_driver);
-}
-module_exit(ds3234_exit);
+module_spi_driver(ds3234_driver);
 
 MODULE_DESCRIPTION("DS3234 SPI RTC driver");
 MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>");
index 8414dea..0104ea7 100644 (file)
@@ -144,19 +144,8 @@ static struct i2c_driver em3027_driver = {
        .id_table = em3027_id,
 };
 
-static int __init em3027_init(void)
-{
-       return i2c_add_driver(&em3027_driver);
-}
-
-static void __exit em3027_exit(void)
-{
-       i2c_del_driver(&em3027_driver);
-}
+module_i2c_driver(em3027_driver);
 
 MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
 MODULE_DESCRIPTION("EM Microelectronic EM3027 RTC driver");
 MODULE_LICENSE("GPL");
-
-module_init(em3027_init);
-module_exit(em3027_exit);
index 4cf2e70..86b6ecc 100644 (file)
@@ -565,17 +565,7 @@ static struct i2c_driver fm3130_driver = {
        .id_table       = fm3130_id,
 };
 
-static int __init fm3130_init(void)
-{
-       return i2c_add_driver(&fm3130_driver);
-}
-module_init(fm3130_init);
-
-static void __exit fm3130_exit(void)
-{
-       i2c_del_driver(&fm3130_driver);
-}
-module_exit(fm3130_exit);
+module_i2c_driver(fm3130_driver);
 
 MODULE_DESCRIPTION("RTC driver for FM3130");
 MODULE_AUTHOR("Sergey Lapin <slapin@ossfans.org>");
index 6186833..1850104 100644 (file)
@@ -309,18 +309,7 @@ static struct i2c_driver isl12022_driver = {
        .id_table       = isl12022_id,
 };
 
-static int __init isl12022_init(void)
-{
-       return i2c_add_driver(&isl12022_driver);
-}
-
-static void __exit isl12022_exit(void)
-{
-       i2c_del_driver(&isl12022_driver);
-}
-
-module_init(isl12022_init);
-module_exit(isl12022_exit);
+module_i2c_driver(isl12022_driver);
 
 MODULE_AUTHOR("roman.fietze@telemotive.de");
 MODULE_DESCRIPTION("ISL 12022 RTC driver");
index da8beb8..dd2aeee 100644 (file)
@@ -710,22 +710,9 @@ static struct i2c_driver isl1208_driver = {
        .id_table = isl1208_id,
 };
 
-static int __init
-isl1208_init(void)
-{
-       return i2c_add_driver(&isl1208_driver);
-}
-
-static void __exit
-isl1208_exit(void)
-{
-       i2c_del_driver(&isl1208_driver);
-}
+module_i2c_driver(isl1208_driver);
 
 MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>");
 MODULE_DESCRIPTION("Intersil ISL1208 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(isl1208_init);
-module_exit(isl1208_exit);
index ecc1713..63c7218 100644 (file)
@@ -287,7 +287,7 @@ static int __devinit lpc32xx_rtc_probe(struct platform_device *pdev)
        if (rtc->irq >= 0) {
                if (devm_request_irq(&pdev->dev, rtc->irq,
                                     lpc32xx_rtc_alarm_interrupt,
-                                    IRQF_DISABLED, pdev->name, rtc) < 0) {
+                                    0, pdev->name, rtc) < 0) {
                        dev_warn(&pdev->dev, "Can't request interrupt.\n");
                        rtc->irq = -1;
                } else {
diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c
new file mode 100644 (file)
index 0000000..07e81c5
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2011 Zhao Zhang <zhzhl555@gmail.com>
+ *
+ * Derived from driver/rtc/rtc-au1xxx.c
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/rtc.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/io.h>
+#include <asm/mach-loongson1/loongson1.h>
+
+#define LS1X_RTC_REG_OFFSET    (LS1X_RTC_BASE + 0x20)
+#define LS1X_RTC_REGS(x) \
+               ((void __iomem *)KSEG1ADDR(LS1X_RTC_REG_OFFSET + (x)))
+
+/*RTC programmable counters 0 and 1*/
+#define SYS_COUNTER_CNTRL              (LS1X_RTC_REGS(0x20))
+#define SYS_CNTRL_ERS                  (1 << 23)
+#define SYS_CNTRL_RTS                  (1 << 20)
+#define SYS_CNTRL_RM2                  (1 << 19)
+#define SYS_CNTRL_RM1                  (1 << 18)
+#define SYS_CNTRL_RM0                  (1 << 17)
+#define SYS_CNTRL_RS                   (1 << 16)
+#define SYS_CNTRL_BP                   (1 << 14)
+#define SYS_CNTRL_REN                  (1 << 13)
+#define SYS_CNTRL_BRT                  (1 << 12)
+#define SYS_CNTRL_TEN                  (1 << 11)
+#define SYS_CNTRL_BTT                  (1 << 10)
+#define SYS_CNTRL_E0                   (1 << 8)
+#define SYS_CNTRL_ETS                  (1 << 7)
+#define SYS_CNTRL_32S                  (1 << 5)
+#define SYS_CNTRL_TTS                  (1 << 4)
+#define SYS_CNTRL_TM2                  (1 << 3)
+#define SYS_CNTRL_TM1                  (1 << 2)
+#define SYS_CNTRL_TM0                  (1 << 1)
+#define SYS_CNTRL_TS                   (1 << 0)
+
+/* Programmable Counter 0 Registers */
+#define SYS_TOYTRIM            (LS1X_RTC_REGS(0))
+#define SYS_TOYWRITE0          (LS1X_RTC_REGS(4))
+#define SYS_TOYWRITE1          (LS1X_RTC_REGS(8))
+#define SYS_TOYREAD0           (LS1X_RTC_REGS(0xC))
+#define SYS_TOYREAD1           (LS1X_RTC_REGS(0x10))
+#define SYS_TOYMATCH0          (LS1X_RTC_REGS(0x14))
+#define SYS_TOYMATCH1          (LS1X_RTC_REGS(0x18))
+#define SYS_TOYMATCH2          (LS1X_RTC_REGS(0x1C))
+
+/* Programmable Counter 1 Registers */
+#define SYS_RTCTRIM            (LS1X_RTC_REGS(0x40))
+#define SYS_RTCWRITE0          (LS1X_RTC_REGS(0x44))
+#define SYS_RTCREAD0           (LS1X_RTC_REGS(0x48))
+#define SYS_RTCMATCH0          (LS1X_RTC_REGS(0x4C))
+#define SYS_RTCMATCH1          (LS1X_RTC_REGS(0x50))
+#define SYS_RTCMATCH2          (LS1X_RTC_REGS(0x54))
+
+#define LS1X_SEC_OFFSET                (4)
+#define LS1X_MIN_OFFSET                (10)
+#define LS1X_HOUR_OFFSET       (16)
+#define LS1X_DAY_OFFSET                (21)
+#define LS1X_MONTH_OFFSET      (26)
+
+
+#define LS1X_SEC_MASK          (0x3f)
+#define LS1X_MIN_MASK          (0x3f)
+#define LS1X_HOUR_MASK         (0x1f)
+#define LS1X_DAY_MASK          (0x1f)
+#define LS1X_MONTH_MASK                (0x3f)
+#define LS1X_YEAR_MASK         (0xffffffff)
+
+#define ls1x_get_sec(t)                (((t) >> LS1X_SEC_OFFSET) & LS1X_SEC_MASK)
+#define ls1x_get_min(t)                (((t) >> LS1X_MIN_OFFSET) & LS1X_MIN_MASK)
+#define ls1x_get_hour(t)       (((t) >> LS1X_HOUR_OFFSET) & LS1X_HOUR_MASK)
+#define ls1x_get_day(t)                (((t) >> LS1X_DAY_OFFSET) & LS1X_DAY_MASK)
+#define ls1x_get_month(t)      (((t) >> LS1X_MONTH_OFFSET) & LS1X_MONTH_MASK)
+
+#define RTC_CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S)
+
+static int ls1x_rtc_read_time(struct device *dev, struct rtc_time *rtm)
+{
+       unsigned long v, t;
+
+       v = readl(SYS_TOYREAD0);
+       t = readl(SYS_TOYREAD1);
+
+       memset(rtm, 0, sizeof(struct rtc_time));
+       t  = mktime((t & LS1X_YEAR_MASK), ls1x_get_month(v),
+                       ls1x_get_day(v), ls1x_get_hour(v),
+                       ls1x_get_min(v), ls1x_get_sec(v));
+       rtc_time_to_tm(t, rtm);
+
+       return rtc_valid_tm(rtm);
+}
+
+static int ls1x_rtc_set_time(struct device *dev, struct  rtc_time *rtm)
+{
+       unsigned long v, t, c;
+       int ret = -ETIMEDOUT;
+
+       v = ((rtm->tm_mon + 1)  << LS1X_MONTH_OFFSET)
+               | (rtm->tm_mday << LS1X_DAY_OFFSET)
+               | (rtm->tm_hour << LS1X_HOUR_OFFSET)
+               | (rtm->tm_min  << LS1X_MIN_OFFSET)
+               | (rtm->tm_sec  << LS1X_SEC_OFFSET);
+
+       writel(v, SYS_TOYWRITE0);
+       c = 0x10000;
+       /* add timeout check counter, for more safe */
+       while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TS) && --c)
+               usleep_range(1000, 3000);
+
+       if (!c) {
+               dev_err(dev, "set time timeout!\n");
+               goto err;
+       }
+
+       t = rtm->tm_year + 1900;
+       writel(t, SYS_TOYWRITE1);
+       c = 0x10000;
+       while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TS) && --c)
+               usleep_range(1000, 3000);
+
+       if (!c) {
+               dev_err(dev, "set time timeout!\n");
+               goto err;
+       }
+       return 0;
+err:
+       return ret;
+}
+
+static struct rtc_class_ops  ls1x_rtc_ops = {
+       .read_time      = ls1x_rtc_read_time,
+       .set_time       = ls1x_rtc_set_time,
+};
+
+static int __devinit ls1x_rtc_probe(struct platform_device *pdev)
+{
+       struct rtc_device *rtcdev;
+       unsigned long v;
+       int ret;
+
+       v = readl(SYS_COUNTER_CNTRL);
+       if (!(v & RTC_CNTR_OK)) {
+               dev_err(&pdev->dev, "rtc counters not working\n");
+               ret = -ENODEV;
+               goto err;
+       }
+       ret = -ETIMEDOUT;
+       /* set to 1 HZ if needed */
+       if (readl(SYS_TOYTRIM) != 32767) {
+               v = 0x100000;
+               while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS) && --v)
+                       usleep_range(1000, 3000);
+
+               if (!v) {
+                       dev_err(&pdev->dev, "time out\n");
+                       goto err;
+               }
+               writel(32767, SYS_TOYTRIM);
+       }
+       /* this loop coundn't be endless */
+       while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS)
+               usleep_range(1000, 3000);
+
+       rtcdev = rtc_device_register("ls1x-rtc", &pdev->dev,
+                                       &ls1x_rtc_ops , THIS_MODULE);
+       if (IS_ERR(rtcdev)) {
+               ret = PTR_ERR(rtcdev);
+               goto err;
+       }
+
+       platform_set_drvdata(pdev, rtcdev);
+       return 0;
+err:
+       return ret;
+}
+
+static int __devexit ls1x_rtc_remove(struct platform_device *pdev)
+{
+       struct rtc_device *rtcdev = platform_get_drvdata(pdev);
+
+       rtc_device_unregister(rtcdev);
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+static struct platform_driver  ls1x_rtc_driver = {
+       .driver         = {
+               .name   = "ls1x-rtc",
+               .owner  = THIS_MODULE,
+       },
+       .remove         = __devexit_p(ls1x_rtc_remove),
+       .probe          = ls1x_rtc_probe,
+};
+
+module_platform_driver(ls1x_rtc_driver);
+
+MODULE_AUTHOR("zhao zhang <zhzhl555@gmail.com>");
+MODULE_LICENSE("GPL");
index 64aedd8..4e0f84a 100644 (file)
@@ -900,20 +900,9 @@ static struct i2c_driver m41t80_driver = {
        .id_table = m41t80_id,
 };
 
-static int __init m41t80_rtc_init(void)
-{
-       return i2c_add_driver(&m41t80_driver);
-}
-
-static void __exit m41t80_rtc_exit(void)
-{
-       i2c_del_driver(&m41t80_driver);
-}
+module_i2c_driver(m41t80_driver);
 
 MODULE_AUTHOR("Alexander Bigga <ab@mycable.de>");
 MODULE_DESCRIPTION("ST Microelectronics M41T80 series RTC I2C Client Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(m41t80_rtc_init);
-module_exit(m41t80_rtc_exit);
index ef71132..10f1c29 100644 (file)
@@ -206,17 +206,7 @@ static struct spi_driver m41t93_driver = {
        .remove = __devexit_p(m41t93_remove),
 };
 
-static __init int m41t93_init(void)
-{
-       return spi_register_driver(&m41t93_driver);
-}
-module_init(m41t93_init);
-
-static __exit void m41t93_exit(void)
-{
-       spi_unregister_driver(&m41t93_driver);
-}
-module_exit(m41t93_exit);
+module_spi_driver(m41t93_driver);
 
 MODULE_AUTHOR("Nikolaus Voss <n.voss@weinmann.de>");
 MODULE_DESCRIPTION("Driver for ST M41T93 SPI RTC");
index 2a4721f..6e78193 100644 (file)
@@ -153,19 +153,7 @@ static struct spi_driver m41t94_driver = {
        .remove = __devexit_p(m41t94_remove),
 };
 
-static __init int m41t94_init(void)
-{
-       return spi_register_driver(&m41t94_driver);
-}
-
-module_init(m41t94_init);
-
-static __exit void m41t94_exit(void)
-{
-       spi_unregister_driver(&m41t94_driver);
-}
-
-module_exit(m41t94_exit);
+module_spi_driver(m41t94_driver);
 
 MODULE_AUTHOR("Kim B. Heino <Kim.Heino@bluegiga.com>");
 MODULE_DESCRIPTION("Driver for ST M41T94 SPI RTC");
index 486142c..a00e332 100644 (file)
@@ -261,20 +261,9 @@ static struct i2c_driver max6900_driver = {
        .id_table = max6900_id,
 };
 
-static int __init max6900_init(void)
-{
-       return i2c_add_driver(&max6900_driver);
-}
-
-static void __exit max6900_exit(void)
-{
-       i2c_del_driver(&max6900_driver);
-}
+module_i2c_driver(max6900_driver);
 
 MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
 MODULE_AUTHOR("Dale Farnsworth <dale@farnsworth.org>");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(max6900_init);
-module_exit(max6900_exit);
index 1f6b3cc..36c74d2 100644 (file)
@@ -160,17 +160,7 @@ static struct spi_driver max6902_driver = {
        .remove = __devexit_p(max6902_remove),
 };
 
-static __init int max6902_init(void)
-{
-       return spi_register_driver(&max6902_driver);
-}
-module_init(max6902_init);
-
-static __exit void max6902_exit(void)
-{
-       spi_unregister_driver(&max6902_driver);
-}
-module_exit(max6902_exit);
+module_spi_driver(max6902_driver);
 
 MODULE_DESCRIPTION ("max6902 spi RTC driver");
 MODULE_AUTHOR ("Raphael Assenat");
index 2d71943..1459055 100644 (file)
@@ -193,10 +193,17 @@ static int max8925_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
        ret = max8925_reg_read(info->rtc, MAX8925_RTC_IRQ_MASK);
        if (ret < 0)
                goto out;
-       if ((ret & ALARM0_IRQ) == 0)
-               alrm->enabled = 1;
-       else
+       if (ret & ALARM0_IRQ) {
                alrm->enabled = 0;
+       } else {
+               ret = max8925_reg_read(info->rtc, MAX8925_ALARM0_CNTL);
+               if (ret < 0)
+                       goto out;
+               if (!ret)
+                       alrm->enabled = 0;
+               else
+                       alrm->enabled = 1;
+       }
        ret = max8925_reg_read(info->rtc, MAX8925_RTC_STATUS);
        if (ret < 0)
                goto out;
@@ -204,6 +211,7 @@ static int max8925_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
                alrm->pending = 1;
        else
                alrm->pending = 0;
+       return 0;
 out:
        return ret;
 }
@@ -220,8 +228,11 @@ static int max8925_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
        ret = max8925_bulk_write(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf);
        if (ret < 0)
                goto out;
-       /* only enable alarm on year/month/day/hour/min/sec */
-       ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77);
+       if (alrm->enabled)
+               /* only enable alarm on year/month/day/hour/min/sec */
+               ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77);
+       else
+               ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x0);
        if (ret < 0)
                goto out;
 out:
index 9d3cacc..e954a75 100644 (file)
@@ -327,7 +327,7 @@ static int __devinit mpc5121_rtc_probe(struct platform_device *op)
        dev_set_drvdata(&op->dev, rtc);
 
        rtc->irq = irq_of_parse_and_map(op->dev.of_node, 1);
-       err = request_irq(rtc->irq, mpc5121_rtc_handler, IRQF_DISABLED,
+       err = request_irq(rtc->irq, mpc5121_rtc_handler, 0,
                                                "mpc5121-rtc", &op->dev);
        if (err) {
                dev_err(&op->dev, "%s: could not request irq: %i\n",
@@ -337,7 +337,7 @@ static int __devinit mpc5121_rtc_probe(struct platform_device *op)
 
        rtc->irq_periodic = irq_of_parse_and_map(op->dev.of_node, 0);
        err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd,
-                               IRQF_DISABLED, "mpc5121-rtc_upd", &op->dev);
+                               0, "mpc5121-rtc_upd", &op->dev);
        if (err) {
                dev_err(&op->dev, "%s: could not request irq: %i\n",
                                                __func__, rtc->irq_periodic);
index 6cd6c72..f51719b 100644 (file)
@@ -366,7 +366,7 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
 
        if (rtc_irq) {
                retval = request_irq(rtc_irq, mrst_rtc_irq,
-                               IRQF_DISABLED, dev_name(&mrst_rtc.rtc->dev),
+                               0, dev_name(&mrst_rtc.rtc->dev),
                                mrst_rtc.rtc);
                if (retval < 0) {
                        dev_dbg(dev, "IRQ %d is already in use, err %d\n",
index 768e2ed..1300962 100644 (file)
@@ -273,7 +273,7 @@ static int __devinit mv_rtc_probe(struct platform_device *pdev)
        if (pdata->irq >= 0) {
                writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
                if (devm_request_irq(&pdev->dev, pdata->irq, mv_rtc_interrupt,
-                                    IRQF_DISABLED | IRQF_SHARED,
+                                    IRQF_SHARED,
                                     pdev->name, pdata) < 0) {
                        dev_warn(&pdev->dev, "interrupt not available.\n");
                        pdata->irq = -1;
index 781068d..b790109 100644 (file)
@@ -269,7 +269,7 @@ static int __devinit nuc900_rtc_probe(struct platform_device *pdev)
 
        nuc900_rtc->irq_num = platform_get_irq(pdev, 0);
        if (request_irq(nuc900_rtc->irq_num, nuc900_rtc_interrupt,
-                               IRQF_DISABLED, "nuc900rtc", nuc900_rtc)) {
+                               0, "nuc900rtc", nuc900_rtc)) {
                dev_err(&pdev->dev, "NUC900 RTC request irq failed\n");
                err = -EBUSY;
                goto fail4;
index 7789002..0b614e3 100644 (file)
@@ -348,14 +348,14 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
                rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG);
 
        /* handle periodic and alarm irqs */
-       if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED,
+       if (request_irq(omap_rtc_timer, rtc_irq, 0,
                        dev_name(&rtc->dev), rtc)) {
                pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
                        pdev->name, omap_rtc_timer);
                goto fail1;
        }
        if ((omap_rtc_timer != omap_rtc_alarm) &&
-               (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED,
+               (request_irq(omap_rtc_alarm, rtc_irq, 0,
                        dev_name(&rtc->dev), rtc))) {
                pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
                        pdev->name, omap_rtc_alarm);
index b46c400..8361187 100644 (file)
@@ -346,20 +346,9 @@ static struct spi_driver pcf2123_driver = {
        .remove = __devexit_p(pcf2123_remove),
 };
 
-static int __init pcf2123_init(void)
-{
-       return spi_register_driver(&pcf2123_driver);
-}
-
-static void __exit pcf2123_exit(void)
-{
-       spi_unregister_driver(&pcf2123_driver);
-}
+module_spi_driver(pcf2123_driver);
 
 MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>");
 MODULE_DESCRIPTION("NXP PCF2123 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(pcf2123_init);
-module_exit(pcf2123_exit);
index 606fdfa..bc0677d 100644 (file)
@@ -252,20 +252,9 @@ static struct i2c_driver pcf8563_driver = {
        .id_table       = pcf8563_id,
 };
 
-static int __init pcf8563_init(void)
-{
-       return i2c_add_driver(&pcf8563_driver);
-}
-
-static void __exit pcf8563_exit(void)
-{
-       i2c_del_driver(&pcf8563_driver);
-}
+module_i2c_driver(pcf8563_driver);
 
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(pcf8563_init);
-module_exit(pcf8563_exit);
index 2d201af..019ff35 100644 (file)
@@ -320,18 +320,7 @@ static struct i2c_driver pcf8583_driver = {
        .id_table       = pcf8583_id,
 };
 
-static __init int pcf8583_init(void)
-{
-       return i2c_add_driver(&pcf8583_driver);
-}
-
-static __exit void pcf8583_exit(void)
-{
-       i2c_del_driver(&pcf8583_driver);
-}
-
-module_init(pcf8583_init);
-module_exit(pcf8583_exit);
+module_i2c_driver(pcf8583_driver);
 
 MODULE_AUTHOR("Russell King");
 MODULE_DESCRIPTION("PCF8583 I2C RTC driver");
index 02111fe..a4a1e53 100644 (file)
@@ -123,7 +123,7 @@ static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
 
        amba_set_drvdata(dev, rtc);
 
-       ret = request_irq(dev->irq[0], pl030_interrupt, IRQF_DISABLED,
+       ret = request_irq(dev->irq[0], pl030_interrupt, 0,
                          "rtc-pl030", rtc);
        if (ret)
                goto err_irq;
index a952c8d..3a470e2 100644 (file)
@@ -352,7 +352,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
        }
 
        if (request_irq(adev->irq[0], pl031_interrupt,
-                       IRQF_DISABLED, "rtc-pl031", ldata)) {
+                       0, "rtc-pl031", ldata)) {
                ret = -EIO;
                goto out_no_irq;
        }
index 9f1d6bc..d00bd24 100644 (file)
@@ -520,7 +520,7 @@ static int pm8xxx_rtc_suspend(struct device *dev)
 }
 #endif
 
-SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops, pm8xxx_rtc_suspend, pm8xxx_rtc_resume);
+static SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops, pm8xxx_rtc_suspend, pm8xxx_rtc_resume);
 
 static struct platform_driver pm8xxx_rtc_driver = {
        .probe          = pm8xxx_rtc_probe,
index fc9f499..0075c8f 100644 (file)
@@ -174,14 +174,14 @@ static int pxa_rtc_open(struct device *dev)
        struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev);
        int ret;
 
-       ret = request_irq(pxa_rtc->irq_1Hz, pxa_rtc_irq, IRQF_DISABLED,
+       ret = request_irq(pxa_rtc->irq_1Hz, pxa_rtc_irq, 0,
                          "rtc 1Hz", dev);
        if (ret < 0) {
                dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_1Hz,
                        ret);
                goto err_irq_1Hz;
        }
-       ret = request_irq(pxa_rtc->irq_Alrm, pxa_rtc_irq, IRQF_DISABLED,
+       ret = request_irq(pxa_rtc->irq_Alrm, pxa_rtc_irq, 0,
                          "rtc Alrm", dev);
        if (ret < 0) {
                dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_Alrm,
index 2853c2a..7f8e6c2 100644 (file)
@@ -159,17 +159,7 @@ static struct spi_driver r9701_driver = {
        .remove = __devexit_p(r9701_remove),
 };
 
-static __init int r9701_init(void)
-{
-       return spi_register_driver(&r9701_driver);
-}
-module_init(r9701_init);
-
-static __exit void r9701_exit(void)
-{
-       spi_unregister_driver(&r9701_driver);
-}
-module_exit(r9701_exit);
+module_spi_driver(r9701_driver);
 
 MODULE_DESCRIPTION("r9701 spi RTC driver");
 MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
index ce2ca85..77074cc 100644 (file)
@@ -235,18 +235,7 @@ static struct spi_driver rs5c348_driver = {
        .remove = __devexit_p(rs5c348_remove),
 };
 
-static __init int rs5c348_init(void)
-{
-       return spi_register_driver(&rs5c348_driver);
-}
-
-static __exit void rs5c348_exit(void)
-{
-       spi_unregister_driver(&rs5c348_driver);
-}
-
-module_init(rs5c348_init);
-module_exit(rs5c348_exit);
+module_spi_driver(rs5c348_driver);
 
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver");
index d29f543..fb4842c 100644 (file)
@@ -689,18 +689,7 @@ static struct i2c_driver rs5c372_driver = {
        .id_table       = rs5c372_id,
 };
 
-static __init int rs5c372_init(void)
-{
-       return i2c_add_driver(&rs5c372_driver);
-}
-
-static __exit void rs5c372_exit(void)
-{
-       i2c_del_driver(&rs5c372_driver);
-}
-
-module_init(rs5c372_init);
-module_exit(rs5c372_exit);
+module_i2c_driver(rs5c372_driver);
 
 MODULE_AUTHOR(
                "Pavel Mironchik <pmironchik@optifacio.net>, "
index ea09ff2..0fbe57b 100644 (file)
@@ -436,18 +436,7 @@ static struct i2c_driver rv3029c2_driver = {
        .id_table = rv3029c2_id,
 };
 
-static int __init rv3029c2_init(void)
-{
-       return i2c_add_driver(&rv3029c2_driver);
-}
-
-static void __exit rv3029c2_exit(void)
-{
-       i2c_del_driver(&rv3029c2_driver);
-}
-
-module_init(rv3029c2_init);
-module_exit(rv3029c2_exit);
+module_i2c_driver(rv3029c2_driver);
 
 MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");
 MODULE_DESCRIPTION("Micro Crystal RV3029C2 RTC driver");
index fde172f..0de902d 100644 (file)
@@ -644,19 +644,8 @@ static struct i2c_driver rx8025_driver = {
        .id_table       = rx8025_id,
 };
 
-static int __init rx8025_init(void)
-{
-       return i2c_add_driver(&rx8025_driver);
-}
-
-static void __exit rx8025_exit(void)
-{
-       i2c_del_driver(&rx8025_driver);
-}
+module_i2c_driver(rx8025_driver);
 
 MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
 MODULE_DESCRIPTION("RX-8025 SA/NB RTC driver");
 MODULE_LICENSE("GPL");
-
-module_init(rx8025_init);
-module_exit(rx8025_exit);
index 600b890..d848251 100644 (file)
@@ -276,20 +276,9 @@ static struct i2c_driver rx8581_driver = {
        .id_table       = rx8581_id,
 };
 
-static int __init rx8581_init(void)
-{
-       return i2c_add_driver(&rx8581_driver);
-}
-
-static void __exit rx8581_exit(void)
-{
-       i2c_del_driver(&rx8581_driver);
-}
+module_i2c_driver(rx8581_driver);
 
 MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
 MODULE_DESCRIPTION("Epson RX-8581 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(rx8581_init);
-module_exit(rx8581_exit);
index f789e00..c9562ce 100644 (file)
@@ -304,19 +304,8 @@ static struct i2c_driver s35390a_driver = {
        .id_table       = s35390a_id,
 };
 
-static int __init s35390a_rtc_init(void)
-{
-       return i2c_add_driver(&s35390a_driver);
-}
-
-static void __exit s35390a_rtc_exit(void)
-{
-       i2c_del_driver(&s35390a_driver);
-}
+module_i2c_driver(s35390a_driver);
 
 MODULE_AUTHOR("Byron Bradley <byron.bbradley@gmail.com>");
 MODULE_DESCRIPTION("S35390A RTC driver");
 MODULE_LICENSE("GPL");
-
-module_init(s35390a_rtc_init);
-module_exit(s35390a_rtc_exit);
index aef40bd..c543f6f 100644 (file)
@@ -543,14 +543,14 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
        s3c_rtc_setfreq(&pdev->dev, 1);
 
        ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq,
-                         IRQF_DISABLED,  "s3c2410-rtc alarm", rtc);
+                         0,  "s3c2410-rtc alarm", rtc);
        if (ret) {
                dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret);
                goto err_alarm_irq;
        }
 
        ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq,
-                         IRQF_DISABLED,  "s3c2410-rtc tick", rtc);
+                         0,  "s3c2410-rtc tick", rtc);
        if (ret) {
                dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret);
                free_irq(s3c_rtc_alarmno, rtc);
index cb9a585..fb758db 100644 (file)
@@ -160,14 +160,13 @@ static int sa1100_rtc_open(struct device *dev)
        struct platform_device *plat_dev = to_platform_device(dev);
        struct rtc_device *rtc = platform_get_drvdata(plat_dev);
 
-       ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED,
-               "rtc 1Hz", dev);
+       ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, 0, "rtc 1Hz", dev);
        if (ret) {
                dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz);
                goto fail_ui;
        }
-       ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED,
-               "rtc Alrm", dev);
+       ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, 0,
+                         "rtc Alrm", dev);
        if (ret) {
                dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm);
                goto fail_ai;
index 6ac55fd..e55a763 100644 (file)
@@ -666,7 +666,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
        if (rtc->carry_irq <= 0) {
                /* register shared periodic/carry/alarm irq */
                ret = request_irq(rtc->periodic_irq, sh_rtc_shared,
-                                 IRQF_DISABLED, "sh-rtc", rtc);
+                                 0, "sh-rtc", rtc);
                if (unlikely(ret)) {
                        dev_err(&pdev->dev,
                                "request IRQ failed with %d, IRQ %d\n", ret,
@@ -676,7 +676,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
        } else {
                /* register periodic/carry/alarm irqs */
                ret = request_irq(rtc->periodic_irq, sh_rtc_periodic,
-                                 IRQF_DISABLED, "sh-rtc period", rtc);
+                                 0, "sh-rtc period", rtc);
                if (unlikely(ret)) {
                        dev_err(&pdev->dev,
                                "request period IRQ failed with %d, IRQ %d\n",
@@ -685,7 +685,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
                }
 
                ret = request_irq(rtc->carry_irq, sh_rtc_interrupt,
-                                 IRQF_DISABLED, "sh-rtc carry", rtc);
+                                 0, "sh-rtc carry", rtc);
                if (unlikely(ret)) {
                        dev_err(&pdev->dev,
                                "request carry IRQ failed with %d, IRQ %d\n",
@@ -695,7 +695,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
                }
 
                ret = request_irq(rtc->alarm_irq, sh_rtc_alarm,
-                                 IRQF_DISABLED, "sh-rtc alarm", rtc);
+                                 0, "sh-rtc alarm", rtc);
                if (unlikely(ret)) {
                        dev_err(&pdev->dev,
                                "request alarm IRQ failed with %d, IRQ %d\n",
index 19a28a6..e38da0d 100644 (file)
 #define STATUS_FAIL            (LOST_WR_TIME | LOST_WR_DATE)
 
 struct spear_rtc_config {
+       struct rtc_device *rtc;
        struct clk *clk;
        spinlock_t lock;
        void __iomem *ioaddr;
+       unsigned int irq_wake;
 };
 
 static inline void spear_rtc_clear_interrupt(struct spear_rtc_config *config)
@@ -149,8 +151,7 @@ static void rtc_wait_not_busy(struct spear_rtc_config *config)
 
 static irqreturn_t spear_rtc_irq(int irq, void *dev_id)
 {
-       struct rtc_device *rtc = (struct rtc_device *)dev_id;
-       struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+       struct spear_rtc_config *config = dev_id;
        unsigned long flags, events = 0;
        unsigned int irq_data;
 
@@ -161,7 +162,7 @@ static irqreturn_t spear_rtc_irq(int irq, void *dev_id)
        if ((irq_data & RTC_INT_MASK)) {
                spear_rtc_clear_interrupt(config);
                events = RTC_IRQF | RTC_AF;
-               rtc_update_irq(rtc, 1, events);
+               rtc_update_irq(config->rtc, 1, events);
                return IRQ_HANDLED;
        } else
                return IRQ_NONE;
@@ -203,9 +204,7 @@ static void bcd2tm(struct rtc_time *tm)
  */
 static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct rtc_device *rtc = platform_get_drvdata(pdev);
-       struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+       struct spear_rtc_config *config = dev_get_drvdata(dev);
        unsigned int time, date;
 
        /* we don't report wday/yday/isdst ... */
@@ -234,9 +233,7 @@ static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm)
  */
 static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct rtc_device *rtc = platform_get_drvdata(pdev);
-       struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+       struct spear_rtc_config *config = dev_get_drvdata(dev);
        unsigned int time, date, err = 0;
 
        if (tm2bcd(tm) < 0)
@@ -266,9 +263,7 @@ static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
  */
 static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct rtc_device *rtc = platform_get_drvdata(pdev);
-       struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+       struct spear_rtc_config *config = dev_get_drvdata(dev);
        unsigned int time, date;
 
        rtc_wait_not_busy(config);
@@ -298,9 +293,7 @@ static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
  */
 static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct rtc_device *rtc = platform_get_drvdata(pdev);
-       struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+       struct spear_rtc_config *config = dev_get_drvdata(dev);
        unsigned int time, date, err = 0;
 
        if (tm2bcd(&alm->time) < 0)
@@ -326,17 +319,42 @@ static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 
        return 0;
 }
+
+static int spear_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+       struct spear_rtc_config *config = dev_get_drvdata(dev);
+       int ret = 0;
+
+       spear_rtc_clear_interrupt(config);
+
+       switch (enabled) {
+       case 0:
+               /* alarm off */
+               spear_rtc_disable_interrupt(config);
+               break;
+       case 1:
+               /* alarm on */
+               spear_rtc_enable_interrupt(config);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       return ret;
+}
+
 static struct rtc_class_ops spear_rtc_ops = {
        .read_time = spear_rtc_read_time,
        .set_time = spear_rtc_set_time,
        .read_alarm = spear_rtc_read_alarm,
        .set_alarm = spear_rtc_set_alarm,
+       .alarm_irq_enable = spear_alarm_irq_enable,
 };
 
 static int __devinit spear_rtc_probe(struct platform_device *pdev)
 {
        struct resource *res;
-       struct rtc_device *rtc;
        struct spear_rtc_config *config;
        unsigned int status = 0;
        int irq;
@@ -376,19 +394,17 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev)
        }
 
        spin_lock_init(&config->lock);
+       platform_set_drvdata(pdev, config);
 
-       rtc = rtc_device_register(pdev->name, &pdev->dev, &spear_rtc_ops,
-                       THIS_MODULE);
-       if (IS_ERR(rtc)) {
+       config->rtc = rtc_device_register(pdev->name, &pdev->dev,
+                       &spear_rtc_ops, THIS_MODULE);
+       if (IS_ERR(config->rtc)) {
                dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
-                               PTR_ERR(rtc));
-               status = PTR_ERR(rtc);
+                               PTR_ERR(config->rtc));
+               status = PTR_ERR(config->rtc);
                goto err_iounmap;
        }
 
-       platform_set_drvdata(pdev, rtc);
-       dev_set_drvdata(&rtc->dev, config);
-
        /* alarm irqs */
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
@@ -397,7 +413,7 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev)
                goto err_clear_platdata;
        }
 
-       status = request_irq(irq, spear_rtc_irq, 0, pdev->name, rtc);
+       status = request_irq(irq, spear_rtc_irq, 0, pdev->name, config);
        if (status) {
                dev_err(&pdev->dev, "Alarm interrupt IRQ%d already \
                                claimed\n", irq);
@@ -411,8 +427,7 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev)
 
 err_clear_platdata:
        platform_set_drvdata(pdev, NULL);
-       dev_set_drvdata(&rtc->dev, NULL);
-       rtc_device_unregister(rtc);
+       rtc_device_unregister(config->rtc);
 err_iounmap:
        iounmap(config->ioaddr);
 err_disable_clock:
@@ -429,8 +444,7 @@ err_release_region:
 
 static int __devexit spear_rtc_remove(struct platform_device *pdev)
 {
-       struct rtc_device *rtc = platform_get_drvdata(pdev);
-       struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+       struct spear_rtc_config *config = platform_get_drvdata(pdev);
        int irq;
        struct resource *res;
 
@@ -448,8 +462,7 @@ static int __devexit spear_rtc_remove(struct platform_device *pdev)
        if (res)
                release_mem_region(res->start, resource_size(res));
        platform_set_drvdata(pdev, NULL);
-       dev_set_drvdata(&rtc->dev, NULL);
-       rtc_device_unregister(rtc);
+       rtc_device_unregister(config->rtc);
 
        return 0;
 }
@@ -458,14 +471,14 @@ static int __devexit spear_rtc_remove(struct platform_device *pdev)
 
 static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state)
 {
-       struct rtc_device *rtc = platform_get_drvdata(pdev);
-       struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+       struct spear_rtc_config *config = platform_get_drvdata(pdev);
        int irq;
 
        irq = platform_get_irq(pdev, 0);
-       if (device_may_wakeup(&pdev->dev))
-               enable_irq_wake(irq);
-       else {
+       if (device_may_wakeup(&pdev->dev)) {
+               if (!enable_irq_wake(irq))
+                       config->irq_wake = 1;
+       } else {
                spear_rtc_disable_interrupt(config);
                clk_disable(config->clk);
        }
@@ -475,15 +488,17 @@ static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state)
 
 static int spear_rtc_resume(struct platform_device *pdev)
 {
-       struct rtc_device *rtc = platform_get_drvdata(pdev);
-       struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+       struct spear_rtc_config *config = platform_get_drvdata(pdev);
        int irq;
 
        irq = platform_get_irq(pdev, 0);
 
-       if (device_may_wakeup(&pdev->dev))
-               disable_irq_wake(irq);
-       else {
+       if (device_may_wakeup(&pdev->dev)) {
+               if (config->irq_wake) {
+                       disable_irq_wake(irq);
+                       config->irq_wake = 0;
+               }
+       } else {
                clk_enable(config->clk);
                spear_rtc_enable_interrupt(config);
        }
@@ -498,8 +513,7 @@ static int spear_rtc_resume(struct platform_device *pdev)
 
 static void spear_rtc_shutdown(struct platform_device *pdev)
 {
-       struct rtc_device *rtc = platform_get_drvdata(pdev);
-       struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+       struct spear_rtc_config *config = platform_get_drvdata(pdev);
 
        spear_rtc_disable_interrupt(config);
        clk_disable(config->clk);
index 7621116..279f5cf 100644 (file)
@@ -329,7 +329,7 @@ static int __devinit stk17ta8_rtc_probe(struct platform_device *pdev)
                writeb(0, ioaddr + RTC_INTERRUPTS);
                if (devm_request_irq(&pdev->dev, pdata->irq,
                                stk17ta8_rtc_interrupt,
-                               IRQF_DISABLED | IRQF_SHARED,
+                               IRQF_SHARED,
                                pdev->name, pdev) < 0) {
                        dev_warn(&pdev->dev, "interrupt not available.\n");
                        pdata->irq = 0;
index d43b4f6..4c2c6df 100644 (file)
@@ -176,6 +176,10 @@ static int set_rtc_irq_bit(unsigned char bit)
        unsigned char val;
        int ret;
 
+       /* if the bit is set, return from here */
+       if (rtc_irq_bits & bit)
+               return 0;
+
        val = rtc_irq_bits | bit;
        val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M;
        ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
@@ -193,6 +197,10 @@ static int mask_rtc_irq_bit(unsigned char bit)
        unsigned char val;
        int ret;
 
+       /* if the bit is clear, return from here */
+       if (!(rtc_irq_bits & bit))
+               return 0;
+
        val = rtc_irq_bits & ~bit;
        ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
        if (ret == 0)
@@ -357,7 +365,7 @@ out:
 
 static irqreturn_t twl_rtc_interrupt(int irq, void *rtc)
 {
-       unsigned long events = 0;
+       unsigned long events;
        int ret = IRQ_NONE;
        int res;
        u8 rd_reg;
@@ -372,11 +380,11 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc)
         * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM]
         */
        if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
-               events |= RTC_IRQF | RTC_AF;
+               events = RTC_IRQF | RTC_AF;
        else
-               events |= RTC_IRQF | RTC_UF;
+               events = RTC_IRQF | RTC_PF;
 
-       res = twl_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M,
+       res = twl_rtc_write_u8(BIT_RTC_STATUS_REG_ALARM_M,
                                   REG_RTC_STATUS_REG);
        if (res)
                goto out;
@@ -449,19 +457,11 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
                        REG_INT_MSK_STS_A);
        }
 
-       /* Check RTC module status, Enable if it is off */
-       ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
+       dev_info(&pdev->dev, "Enabling TWL-RTC\n");
+       ret = twl_rtc_write_u8(BIT_RTC_CTRL_REG_STOP_RTC_M, REG_RTC_CTRL_REG);
        if (ret < 0)
                goto out1;
 
-       if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
-               dev_info(&pdev->dev, "Enabling TWL-RTC.\n");
-               rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
-               ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
-               if (ret < 0)
-                       goto out1;
-       }
-
        /* init cached IRQ enable bits */
        ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
        if (ret < 0)
index aac0ffe..a12bfac 100644 (file)
@@ -266,7 +266,7 @@ static int __init tx4939_rtc_probe(struct platform_device *pdev)
        spin_lock_init(&pdata->lock);
        tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP);
        if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt,
-                            IRQF_DISABLED, pdev->name, &pdev->dev) < 0)
+                            0, pdev->name, &pdev->dev) < 0)
                return -EBUSY;
        rtc = rtc_device_register(pdev->name, &pdev->dev,
                                  &tx4939_rtc_ops, THIS_MODULE);
index fcbfdda..5f60a7c 100644 (file)
@@ -333,7 +333,7 @@ static int __devinit rtc_probe(struct platform_device *pdev)
                goto err_device_unregister;
        }
 
-       retval = request_irq(aie_irq, elapsedtime_interrupt, IRQF_DISABLED,
+       retval = request_irq(aie_irq, elapsedtime_interrupt, 0,
                             "elapsed_time", pdev);
        if (retval < 0)
                goto err_device_unregister;
@@ -342,7 +342,7 @@ static int __devinit rtc_probe(struct platform_device *pdev)
        if (pie_irq <= 0)
                goto err_free_irq;
 
-       retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED,
+       retval = request_irq(pie_irq, rtclong1_interrupt, 0,
                             "rtclong1", pdev);
        if (retval < 0)
                goto err_free_irq;
index 8c051d3..403b3d4 100644 (file)
@@ -623,15 +623,7 @@ static struct i2c_driver x1205_driver = {
        .id_table       = x1205_id,
 };
 
-static int __init x1205_init(void)
-{
-       return i2c_add_driver(&x1205_driver);
-}
-
-static void __exit x1205_exit(void)
-{
-       i2c_del_driver(&x1205_driver);
-}
+module_i2c_driver(x1205_driver);
 
 MODULE_AUTHOR(
        "Karen Spearel <kas111 at gmail dot com>, "
@@ -639,6 +631,3 @@ MODULE_AUTHOR(
 MODULE_DESCRIPTION("Xicor/Intersil X1205 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(x1205_init);
-module_exit(x1205_exit);
index 0b54a91..168525a 100644 (file)
@@ -441,9 +441,8 @@ static int sclp_mem_notifier(struct notifier_block *nb,
        start = arg->start_pfn << PAGE_SHIFT;
        size = arg->nr_pages << PAGE_SHIFT;
        mutex_lock(&sclp_mem_mutex);
-       for (id = 0; id <= sclp_max_storage_id; id++)
-               if (!test_bit(id, sclp_storage_ids))
-                       sclp_attach_storage(id);
+       for_each_clear_bit(id, sclp_storage_ids, sclp_max_storage_id + 1)
+               sclp_attach_storage(id);
        switch (action) {
        case MEM_ONLINE:
        case MEM_GOING_OFFLINE:
index e4ade55..4fe52f6 100644 (file)
@@ -4159,7 +4159,7 @@ void GPIOChangeRFWorkItemCallBack(struct work_struct *work)
                argv[0] = RadioPowerPath;
                argv[2] = NULL;
 
-               call_usermodehelper(RadioPowerPath, argv, envp, 1);
+               call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
        }
 }
 
index a7fa9aa..f026b71 100644 (file)
@@ -208,7 +208,7 @@ static void dm_check_ac_dc_power(struct net_device *dev)
 
        if (priv->rtllib->state != RTLLIB_LINKED)
                return;
-       call_usermodehelper(ac_dc_check_script_path, argv, envp, 1);
+       call_usermodehelper(ac_dc_check_script_path, argv, envp, UMH_WAIT_PROC);
 
        return;
 };
@@ -2296,7 +2296,7 @@ void dm_CheckRfCtrlGPIO(void *data)
 
                argv[0] = RadioPowerPath;
                argv[2] = NULL;
-               call_usermodehelper(RadioPowerPath, argv, envp, 1);
+               call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
        }
 }
 
index d5f923b..f960279 100644 (file)
@@ -5927,7 +5927,8 @@ static void add_caps(IXJ *j)
        j->caplist[j->caps].cap = PHONE_VENDOR_QUICKNET;
        strcpy(j->caplist[j->caps].desc, "Quicknet Technologies, Inc. (www.quicknet.net)");
        j->caplist[j->caps].captype = vendor;
-       j->caplist[j->caps].handle = j->caps++;
+       j->caplist[j->caps].handle = j->caps;
+       j->caps++;
        j->caplist[j->caps].captype = device;
        switch (j->cardtype) {
        case QTI_PHONEJACK:
@@ -5947,11 +5948,13 @@ static void add_caps(IXJ *j)
                break;
        }
        j->caplist[j->caps].cap = j->cardtype;
-       j->caplist[j->caps].handle = j->caps++;
+       j->caplist[j->caps].handle = j->caps;
+       j->caps++;
        strcpy(j->caplist[j->caps].desc, "POTS");
        j->caplist[j->caps].captype = port;
        j->caplist[j->caps].cap = pots;
-       j->caplist[j->caps].handle = j->caps++;
+       j->caplist[j->caps].handle = j->caps;
+       j->caps++;
 
        /* add devices that can do speaker/mic */
        switch (j->cardtype) {
@@ -5962,7 +5965,8 @@ static void add_caps(IXJ *j)
                strcpy(j->caplist[j->caps].desc, "SPEAKER");
                j->caplist[j->caps].captype = port;
                j->caplist[j->caps].cap = speaker;
-               j->caplist[j->caps].handle = j->caps++;
+               j->caplist[j->caps].handle = j->caps;
+               j->caps++;
         default:
                break;
        }
@@ -5973,7 +5977,8 @@ static void add_caps(IXJ *j)
                strcpy(j->caplist[j->caps].desc, "HANDSET");
                j->caplist[j->caps].captype = port;
                j->caplist[j->caps].cap = handset;
-               j->caplist[j->caps].handle = j->caps++;
+               j->caplist[j->caps].handle = j->caps;
+               j->caps++;
                break;
         default:
                break;
@@ -5985,7 +5990,8 @@ static void add_caps(IXJ *j)
                strcpy(j->caplist[j->caps].desc, "PSTN");
                j->caplist[j->caps].captype = port;
                j->caplist[j->caps].cap = pstn;
-               j->caplist[j->caps].handle = j->caps++;
+               j->caplist[j->caps].handle = j->caps;
+               j->caps++;
                break;
         default:
                break;
@@ -5995,50 +6001,59 @@ static void add_caps(IXJ *j)
        strcpy(j->caplist[j->caps].desc, "ULAW");
        j->caplist[j->caps].captype = codec;
        j->caplist[j->caps].cap = ULAW;
-       j->caplist[j->caps].handle = j->caps++;
+       j->caplist[j->caps].handle = j->caps;
+       j->caps++;
 
        strcpy(j->caplist[j->caps].desc, "LINEAR 16 bit");
        j->caplist[j->caps].captype = codec;
        j->caplist[j->caps].cap = LINEAR16;
-       j->caplist[j->caps].handle = j->caps++;
+       j->caplist[j->caps].handle = j->caps;
+       j->caps++;
 
        strcpy(j->caplist[j->caps].desc, "LINEAR 8 bit");
        j->caplist[j->caps].captype = codec;
        j->caplist[j->caps].cap = LINEAR8;
-       j->caplist[j->caps].handle = j->caps++;
+       j->caplist[j->caps].handle = j->caps;
+       j->caps++;
 
        strcpy(j->caplist[j->caps].desc, "Windows Sound System");
        j->caplist[j->caps].captype = codec;
        j->caplist[j->caps].cap = WSS;
-       j->caplist[j->caps].handle = j->caps++;
+       j->caplist[j->caps].handle = j->caps;
+       j->caps++;
 
        /* software ALAW codec, made from ULAW */
        strcpy(j->caplist[j->caps].desc, "ALAW");
        j->caplist[j->caps].captype = codec;
        j->caplist[j->caps].cap = ALAW;
-       j->caplist[j->caps].handle = j->caps++;
+       j->caplist[j->caps].handle = j->caps;
+       j->caps++;
 
        /* version 12 of the 8020 does the following codecs in a broken way */
        if (j->dsp.low != 0x20 || j->ver.low != 0x12) {
                strcpy(j->caplist[j->caps].desc, "G.723.1 6.3kbps");
                j->caplist[j->caps].captype = codec;
                j->caplist[j->caps].cap = G723_63;
-               j->caplist[j->caps].handle = j->caps++;
+               j->caplist[j->caps].handle = j->caps;
+               j->caps++;
 
                strcpy(j->caplist[j->caps].desc, "G.723.1 5.3kbps");
                j->caplist[j->caps].captype = codec;
                j->caplist[j->caps].cap = G723_53;
-               j->caplist[j->caps].handle = j->caps++;
+               j->caplist[j->caps].handle = j->caps;
+               j->caps++;
 
                strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8kbps");
                j->caplist[j->caps].captype = codec;
                j->caplist[j->caps].cap = TS48;
-               j->caplist[j->caps].handle = j->caps++;
+               j->caplist[j->caps].handle = j->caps;
+               j->caps++;
 
                strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1kbps");
                j->caplist[j->caps].captype = codec;
                j->caplist[j->caps].cap = TS41;
-               j->caplist[j->caps].handle = j->caps++;
+               j->caplist[j->caps].handle = j->caps;
+               j->caps++;
        }
 
        /* 8020 chips can do TS8.5 native, and 8021/8022 can load it */
@@ -6046,7 +6061,8 @@ static void add_caps(IXJ *j)
                strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5kbps");
                j->caplist[j->caps].captype = codec;
                j->caplist[j->caps].cap = TS85;
-               j->caplist[j->caps].handle = j->caps++;
+               j->caplist[j->caps].handle = j->caps;
+               j->caps++;
        }
 
        /* 8021 chips can do G728 */
@@ -6054,7 +6070,8 @@ static void add_caps(IXJ *j)
                strcpy(j->caplist[j->caps].desc, "G.728 16kbps");
                j->caplist[j->caps].captype = codec;
                j->caplist[j->caps].cap = G728;
-               j->caplist[j->caps].handle = j->caps++;
+               j->caplist[j->caps].handle = j->caps;
+               j->caps++;
        }
 
        /* 8021/8022 chips can do G729 if loaded */
@@ -6062,13 +6079,15 @@ static void add_caps(IXJ *j)
                strcpy(j->caplist[j->caps].desc, "G.729A 8kbps");
                j->caplist[j->caps].captype = codec;
                j->caplist[j->caps].cap = G729;
-               j->caplist[j->caps].handle = j->caps++;
+               j->caplist[j->caps].handle = j->caps;
+               j->caps++;
        }
        if (j->dsp.low != 0x20 && j->flags.g729_loaded) {
                strcpy(j->caplist[j->caps].desc, "G.729B 8kbps");
                j->caplist[j->caps].captype = codec;
                j->caplist[j->caps].cap = G729B;
-               j->caplist[j->caps].handle = j->caps++;
+               j->caplist[j->caps].handle = j->caps;
+               j->caps++;
        }
 }
 
index e45e673..6e3e713 100644 (file)
@@ -334,10 +334,8 @@ int uwb_rsv_find_best_allocation(struct uwb_rsv *rsv, struct uwb_mas_bm *availab
 
 
        /* fill the not available vector from the available bm */
-       for (bit_index = 0; bit_index < UWB_NUM_MAS; bit_index++) {
-               if (!test_bit(bit_index, available->bm))
-                       ai->bm[bit_index] = UWB_RSV_MAS_NOT_AVAIL;
-       }
+       for_each_clear_bit(bit_index, available->bm, UWB_NUM_MAS)
+               ai->bm[bit_index] = UWB_RSV_MAS_NOT_AVAIL;
 
        if (ai->max_interval == 1) {
                get_row_descriptors(ai);
index a1376dc..915943a 100644 (file)
@@ -187,7 +187,8 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       data = kzalloc(sizeof(struct pm860x_backlight_data), GFP_KERNEL);
+       data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_backlight_data),
+                           GFP_KERNEL);
        if (data == NULL)
                return -ENOMEM;
        strncpy(name, res->name, MFD_NAME_SIZE);
@@ -200,7 +201,6 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
        data->port = pdata->flags;
        if (data->port < 0) {
                dev_err(&pdev->dev, "wrong platform data is assigned");
-               kfree(data);
                return -EINVAL;
        }
 
@@ -211,7 +211,6 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
                                        &pm860x_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
-               kfree(data);
                return PTR_ERR(bl);
        }
        bl->props.brightness = MAX_BRIGHTNESS;
@@ -247,17 +246,14 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
        return 0;
 out:
        backlight_device_unregister(bl);
-       kfree(data);
        return ret;
 }
 
 static int pm860x_backlight_remove(struct platform_device *pdev)
 {
        struct backlight_device *bl = platform_get_drvdata(pdev);
-       struct pm860x_backlight_data *data = bl_get_data(bl);
 
        backlight_device_unregister(bl);
-       kfree(data);
        return 0;
 }
 
index 681b369..7ed9991 100644 (file)
@@ -334,6 +334,27 @@ config BACKLIGHT_AAT2870
          If you have a AnalogicTech AAT2870 say Y to enable the
          backlight driver.
 
+config BACKLIGHT_LP855X
+       tristate "Backlight driver for TI LP855X"
+       depends on BACKLIGHT_CLASS_DEVICE && I2C
+       help
+         This supports TI LP8550, LP8551, LP8552, LP8553 and LP8556
+         backlight driver.
+
+config BACKLIGHT_OT200
+       tristate "Backlight driver for ot200 visualisation device"
+       depends on BACKLIGHT_CLASS_DEVICE && CS5535_MFGPT && GPIO_CS5535
+       help
+         To compile this driver as a module, choose M here: the module will be
+         called ot200_bl.
+
+config BACKLIGHT_PANDORA
+       tristate "Backlight driver for Pandora console"
+       depends on TWL4030_CORE
+       help
+         If you have a Pandora console, say Y to enable the
+         backlight driver.
+
 endif # BACKLIGHT_CLASS_DEVICE
 
 endif # BACKLIGHT_LCD_SUPPORT
index af5cf65..8071eb6 100644 (file)
@@ -22,7 +22,9 @@ obj-$(CONFIG_BACKLIGHT_GENERIC)       += generic_bl.o
 obj-$(CONFIG_BACKLIGHT_HP700)  += jornada720_bl.o
 obj-$(CONFIG_BACKLIGHT_HP680)  += hp680_bl.o
 obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
+obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
 obj-$(CONFIG_BACKLIGHT_OMAP1)  += omap1_bl.o
+obj-$(CONFIG_BACKLIGHT_PANDORA)        += pandora_bl.o
 obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
 obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
 obj-$(CONFIG_BACKLIGHT_PWM)    += pwm_bl.o
@@ -38,4 +40,4 @@ obj-$(CONFIG_BACKLIGHT_ADP8870)       += adp8870_bl.o
 obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
 obj-$(CONFIG_BACKLIGHT_PCF50633)       += pcf50633-backlight.o
 obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
-
+obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o
index 331f1ef..7ff7522 100644 (file)
@@ -145,7 +145,9 @@ static int aat2870_bl_probe(struct platform_device *pdev)
                goto out;
        }
 
-       aat2870_bl = kzalloc(sizeof(struct aat2870_bl_driver_data), GFP_KERNEL);
+       aat2870_bl = devm_kzalloc(&pdev->dev,
+                                 sizeof(struct aat2870_bl_driver_data),
+                                 GFP_KERNEL);
        if (!aat2870_bl) {
                dev_err(&pdev->dev,
                        "Failed to allocate memory for aat2870 backlight\n");
@@ -162,7 +164,7 @@ static int aat2870_bl_probe(struct platform_device *pdev)
                dev_err(&pdev->dev,
                        "Failed allocate memory for backlight device\n");
                ret = PTR_ERR(bd);
-               goto out_kfree;
+               goto out;
        }
 
        aat2870_bl->pdev = pdev;
@@ -199,8 +201,6 @@ static int aat2870_bl_probe(struct platform_device *pdev)
 
 out_bl_dev_unregister:
        backlight_device_unregister(bd);
-out_kfree:
-       kfree(aat2870_bl);
 out:
        return ret;
 }
@@ -215,7 +215,6 @@ static int aat2870_bl_remove(struct platform_device *pdev)
        backlight_update_status(bd);
 
        backlight_device_unregister(bd);
-       kfree(aat2870_bl);
 
        return 0;
 }
index 2e630bf..4911ea7 100644 (file)
@@ -289,7 +289,7 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
        struct adp5520_bl *data;
        int ret = 0;
 
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
        if (data == NULL)
                return -ENOMEM;
 
@@ -298,7 +298,6 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
 
        if (data->pdata  == NULL) {
                dev_err(&pdev->dev, "missing platform data\n");
-               kfree(data);
                return -ENODEV;
        }
 
@@ -314,7 +313,6 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
                                       &adp5520_bl_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
-               kfree(data);
                return PTR_ERR(bl);
        }
 
@@ -326,7 +324,6 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
        if (ret) {
                dev_err(&pdev->dev, "failed to register sysfs\n");
                backlight_device_unregister(bl);
-               kfree(data);
        }
 
        platform_set_drvdata(pdev, bl);
@@ -348,7 +345,6 @@ static int __devexit adp5520_bl_remove(struct platform_device *pdev)
                                &adp5520_bl_attr_group);
 
        backlight_device_unregister(bl);
-       kfree(data);
 
        return 0;
 }
index 378276c..550dbf0 100644 (file)
@@ -819,17 +819,7 @@ static struct i2c_driver adp8860_driver = {
        .id_table = adp8860_id,
 };
 
-static int __init adp8860_init(void)
-{
-       return i2c_add_driver(&adp8860_driver);
-}
-module_init(adp8860_init);
-
-static void __exit adp8860_exit(void)
-{
-       i2c_del_driver(&adp8860_driver);
-}
-module_exit(adp8860_exit);
+module_i2c_driver(adp8860_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
index 6735059..9be58c6 100644 (file)
@@ -991,17 +991,7 @@ static struct i2c_driver adp8870_driver = {
        .id_table = adp8870_id,
 };
 
-static int __init adp8870_init(void)
-{
-       return i2c_add_driver(&adp8870_driver);
-}
-module_init(adp8870_init);
-
-static void __exit adp8870_exit(void)
-{
-       i2c_del_driver(&adp8870_driver);
-}
-module_exit(adp8870_exit);
+module_i2c_driver(adp8870_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
index 7838a23..7bdadc7 100644 (file)
@@ -629,18 +629,7 @@ static struct spi_driver ams369fg06_driver = {
        .resume         = ams369fg06_resume,
 };
 
-static int __init ams369fg06_init(void)
-{
-       return spi_register_driver(&ams369fg06_driver);
-}
-
-static void __exit ams369fg06_exit(void)
-{
-       spi_unregister_driver(&ams369fg06_driver);
-}
-
-module_init(ams369fg06_init);
-module_exit(ams369fg06_exit);
+module_spi_driver(ams369fg06_driver);
 
 MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
 MODULE_DESCRIPTION("ams369fg06 LCD Driver");
index c6533ba..6dab13f 100644 (file)
@@ -629,17 +629,7 @@ static struct spi_driver corgi_lcd_driver = {
        .resume         = corgi_lcd_resume,
 };
 
-static int __init corgi_lcd_init(void)
-{
-       return spi_register_driver(&corgi_lcd_driver);
-}
-module_init(corgi_lcd_init);
-
-static void __exit corgi_lcd_exit(void)
-{
-       spi_unregister_driver(&corgi_lcd_driver);
-}
-module_exit(corgi_lcd_exit);
+module_spi_driver(corgi_lcd_driver);
 
 MODULE_DESCRIPTION("LCD and backlight driver for SHARP C7x0/Cxx00");
 MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
index 6c8c540..22489eb 100644 (file)
@@ -212,7 +212,7 @@ static int cr_backlight_probe(struct platform_device *pdev)
                              &gpio_bar);
        gpio_bar &= ~0x3F;
 
-       crp = kzalloc(sizeof(*crp), GFP_KERNEL);
+       crp = devm_kzalloc(&pdev->dev, sizeof(*crp), GFP_KERNEL);
        if (!crp) {
                lcd_device_unregister(ldp);
                backlight_device_unregister(bdp);
@@ -243,7 +243,6 @@ static int cr_backlight_remove(struct platform_device *pdev)
        backlight_device_unregister(crp->cr_backlight_device);
        lcd_device_unregister(crp->cr_lcd_device);
        pci_dev_put(lpc_dev);
-       kfree(crp);
 
        return 0;
 }
index abb4a06..30e1968 100644 (file)
@@ -110,7 +110,7 @@ static int da903x_backlight_probe(struct platform_device *pdev)
        struct backlight_properties props;
        int max_brightness;
 
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
        if (data == NULL)
                return -ENOMEM;
 
@@ -124,7 +124,6 @@ static int da903x_backlight_probe(struct platform_device *pdev)
        default:
                dev_err(&pdev->dev, "invalid backlight device ID(%d)\n",
                                pdev->id);
-               kfree(data);
                return -EINVAL;
        }
 
@@ -143,7 +142,6 @@ static int da903x_backlight_probe(struct platform_device *pdev)
                                       &da903x_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
-               kfree(data);
                return PTR_ERR(bl);
        }
 
@@ -157,10 +155,8 @@ static int da903x_backlight_probe(struct platform_device *pdev)
 static int da903x_backlight_remove(struct platform_device *pdev)
 {
        struct backlight_device *bl = platform_get_drvdata(pdev);
-       struct da903x_backlight_data *data = bl_get_data(bl);
 
        backlight_device_unregister(bl);
-       kfree(data);
        return 0;
 }
 
index 27d1d7a..6022b67 100644 (file)
@@ -274,18 +274,7 @@ static struct spi_driver l4f00242t03_driver = {
        .shutdown       = l4f00242t03_shutdown,
 };
 
-static __init int l4f00242t03_init(void)
-{
-       return spi_register_driver(&l4f00242t03_driver);
-}
-
-static __exit void l4f00242t03_exit(void)
-{
-       spi_unregister_driver(&l4f00242t03_driver);
-}
-
-module_init(l4f00242t03_init);
-module_exit(l4f00242t03_exit);
+module_spi_driver(l4f00242t03_driver);
 
 MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>");
 MODULE_DESCRIPTION("EPSON L4F00242T03 LCD");
index 78dafc0..efd352b 100644 (file)
@@ -856,18 +856,7 @@ static struct spi_driver ld9040_driver = {
        .resume         = ld9040_resume,
 };
 
-static int __init ld9040_init(void)
-{
-       return spi_register_driver(&ld9040_driver);
-}
-
-static void __exit ld9040_exit(void)
-{
-       spi_unregister_driver(&ld9040_driver);
-}
-
-module_init(ld9040_init);
-module_exit(ld9040_exit);
+module_spi_driver(ld9040_driver);
 
 MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
 MODULE_DESCRIPTION("ld9040 LCD Driver");
index 4ec78cf..4161f9e 100644 (file)
@@ -226,18 +226,7 @@ static struct spi_driver lms283gf05_driver = {
        .remove         = __devexit_p(lms283gf05_remove),
 };
 
-static __init int lms283gf05_init(void)
-{
-       return spi_register_driver(&lms283gf05_driver);
-}
-
-static __exit void lms283gf05_exit(void)
-{
-       spi_unregister_driver(&lms283gf05_driver);
-}
-
-module_init(lms283gf05_init);
-module_exit(lms283gf05_exit);
+module_spi_driver(lms283gf05_driver);
 
 MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
 MODULE_DESCRIPTION("LCD283GF05 LCD");
diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c
new file mode 100644 (file)
index 0000000..72a0e0c
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * TI LP855x Backlight Driver
+ *
+ *                     Copyright (C) 2011 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/lp855x.h>
+
+/* Registers */
+#define BRIGHTNESS_CTRL                (0x00)
+#define DEVICE_CTRL            (0x01)
+
+#define BUF_SIZE               20
+#define DEFAULT_BL_NAME                "lcd-backlight"
+#define MAX_BRIGHTNESS         255
+
+struct lp855x {
+       const char *chipname;
+       enum lp855x_chip_id chip_id;
+       struct i2c_client *client;
+       struct backlight_device *bl;
+       struct device *dev;
+       struct mutex xfer_lock;
+       struct lp855x_platform_data *pdata;
+};
+
+static int lp855x_read_byte(struct lp855x *lp, u8 reg, u8 *data)
+{
+       int ret;
+
+       mutex_lock(&lp->xfer_lock);
+       ret = i2c_smbus_read_byte_data(lp->client, reg);
+       if (ret < 0) {
+               mutex_unlock(&lp->xfer_lock);
+               dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
+               return ret;
+       }
+       mutex_unlock(&lp->xfer_lock);
+
+       *data = (u8)ret;
+       return 0;
+}
+
+static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data)
+{
+       int ret;
+
+       mutex_lock(&lp->xfer_lock);
+       ret = i2c_smbus_write_byte_data(lp->client, reg, data);
+       mutex_unlock(&lp->xfer_lock);
+
+       return ret;
+}
+
+static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
+{
+       u8 start, end;
+
+       switch (lp->chip_id) {
+       case LP8550:
+       case LP8551:
+       case LP8552:
+       case LP8553:
+               start = EEPROM_START;
+               end = EEPROM_END;
+               break;
+       case LP8556:
+               start = EPROM_START;
+               end = EPROM_END;
+               break;
+       default:
+               return false;
+       }
+
+       return (addr >= start && addr <= end);
+}
+
+static int lp855x_init_registers(struct lp855x *lp)
+{
+       u8 val, addr;
+       int i, ret;
+       struct lp855x_platform_data *pd = lp->pdata;
+
+       val = pd->initial_brightness;
+       ret = lp855x_write_byte(lp, BRIGHTNESS_CTRL, val);
+       if (ret)
+               return ret;
+
+       val = pd->device_control;
+       ret = lp855x_write_byte(lp, DEVICE_CTRL, val);
+       if (ret)
+               return ret;
+
+       if (pd->load_new_rom_data && pd->size_program) {
+               for (i = 0; i < pd->size_program; i++) {
+                       addr = pd->rom_data[i].addr;
+                       val = pd->rom_data[i].val;
+                       if (!lp855x_is_valid_rom_area(lp, addr))
+                               continue;
+
+                       ret = lp855x_write_byte(lp, addr, val);
+                       if (ret)
+                               return ret;
+               }
+       }
+
+       return ret;
+}
+
+static int lp855x_bl_update_status(struct backlight_device *bl)
+{
+       struct lp855x *lp = bl_get_data(bl);
+       enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+
+       if (bl->props.state & BL_CORE_SUSPENDED)
+               bl->props.brightness = 0;
+
+       if (mode == PWM_BASED) {
+               struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
+               int br = bl->props.brightness;
+               int max_br = bl->props.max_brightness;
+
+               if (pd->pwm_set_intensity)
+                       pd->pwm_set_intensity(br, max_br);
+
+       } else if (mode == REGISTER_BASED) {
+               u8 val = bl->props.brightness;
+               lp855x_write_byte(lp, BRIGHTNESS_CTRL, val);
+       }
+
+       return 0;
+}
+
+static int lp855x_bl_get_brightness(struct backlight_device *bl)
+{
+       struct lp855x *lp = bl_get_data(bl);
+       enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+
+       if (mode == PWM_BASED) {
+               struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
+               int max_br = bl->props.max_brightness;
+
+               if (pd->pwm_get_intensity)
+                       bl->props.brightness = pd->pwm_get_intensity(max_br);
+
+       } else if (mode == REGISTER_BASED) {
+               u8 val = 0;
+
+               lp855x_read_byte(lp, BRIGHTNESS_CTRL, &val);
+               bl->props.brightness = val;
+       }
+
+       return bl->props.brightness;
+}
+
+static const struct backlight_ops lp855x_bl_ops = {
+       .options = BL_CORE_SUSPENDRESUME,
+       .update_status = lp855x_bl_update_status,
+       .get_brightness = lp855x_bl_get_brightness,
+};
+
+static int lp855x_backlight_register(struct lp855x *lp)
+{
+       struct backlight_device *bl;
+       struct backlight_properties props;
+       struct lp855x_platform_data *pdata = lp->pdata;
+       char *name = pdata->name ? : DEFAULT_BL_NAME;
+
+       props.type = BACKLIGHT_PLATFORM;
+       props.max_brightness = MAX_BRIGHTNESS;
+
+       if (pdata->initial_brightness > props.max_brightness)
+               pdata->initial_brightness = props.max_brightness;
+
+       props.brightness = pdata->initial_brightness;
+
+       bl = backlight_device_register(name, lp->dev, lp,
+                                      &lp855x_bl_ops, &props);
+       if (IS_ERR(bl))
+               return PTR_ERR(bl);
+
+       lp->bl = bl;
+
+       return 0;
+}
+
+static void lp855x_backlight_unregister(struct lp855x *lp)
+{
+       if (lp->bl)
+               backlight_device_unregister(lp->bl);
+}
+
+static ssize_t lp855x_get_chip_id(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct lp855x *lp = dev_get_drvdata(dev);
+       return scnprintf(buf, BUF_SIZE, "%s\n", lp->chipname);
+}
+
+static ssize_t lp855x_get_bl_ctl_mode(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
+       struct lp855x *lp = dev_get_drvdata(dev);
+       enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+       char *strmode = NULL;
+
+       if (mode == PWM_BASED)
+               strmode = "pwm based";
+       else if (mode == REGISTER_BASED)
+               strmode = "register based";
+
+       return scnprintf(buf, BUF_SIZE, "%s\n", strmode);
+}
+
+static DEVICE_ATTR(chip_id, S_IRUGO, lp855x_get_chip_id, NULL);
+static DEVICE_ATTR(bl_ctl_mode, S_IRUGO, lp855x_get_bl_ctl_mode, NULL);
+
+static struct attribute *lp855x_attributes[] = {
+       &dev_attr_chip_id.attr,
+       &dev_attr_bl_ctl_mode.attr,
+       NULL,
+};
+
+static const struct attribute_group lp855x_attr_group = {
+       .attrs = lp855x_attributes,
+};
+
+static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+{
+       struct lp855x *lp;
+       struct lp855x_platform_data *pdata = cl->dev.platform_data;
+       enum lp855x_brightness_ctrl_mode mode;
+       int ret;
+
+       if (!pdata) {
+               dev_err(&cl->dev, "no platform data supplied\n");
+               return -EINVAL;
+       }
+
+       if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
+               return -EIO;
+
+       lp = devm_kzalloc(&cl->dev, sizeof(struct lp855x), GFP_KERNEL);
+       if (!lp)
+               return -ENOMEM;
+
+       mode = pdata->mode;
+       lp->client = cl;
+       lp->dev = &cl->dev;
+       lp->pdata = pdata;
+       lp->chipname = id->name;
+       lp->chip_id = id->driver_data;
+       i2c_set_clientdata(cl, lp);
+
+       mutex_init(&lp->xfer_lock);
+
+       ret = lp855x_init_registers(lp);
+       if (ret) {
+               dev_err(lp->dev, "i2c communication err: %d", ret);
+               if (mode == REGISTER_BASED)
+                       goto err_dev;
+       }
+
+       ret = lp855x_backlight_register(lp);
+       if (ret) {
+               dev_err(lp->dev,
+                       "failed to register backlight. err: %d\n", ret);
+               goto err_dev;
+       }
+
+       ret = sysfs_create_group(&lp->dev->kobj, &lp855x_attr_group);
+       if (ret) {
+               dev_err(lp->dev, "failed to register sysfs. err: %d\n", ret);
+               goto err_sysfs;
+       }
+
+       backlight_update_status(lp->bl);
+       return 0;
+
+err_sysfs:
+       lp855x_backlight_unregister(lp);
+err_dev:
+       return ret;
+}
+
+static int __devexit lp855x_remove(struct i2c_client *cl)
+{
+       struct lp855x *lp = i2c_get_clientdata(cl);
+
+       lp->bl->props.brightness = 0;
+       backlight_update_status(lp->bl);
+       sysfs_remove_group(&lp->dev->kobj, &lp855x_attr_group);
+       lp855x_backlight_unregister(lp);
+
+       return 0;
+}
+
+static const struct i2c_device_id lp855x_ids[] = {
+       {"lp8550", LP8550},
+       {"lp8551", LP8551},
+       {"lp8552", LP8552},
+       {"lp8553", LP8553},
+       {"lp8556", LP8556},
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, lp855x_ids);
+
+static struct i2c_driver lp855x_driver = {
+       .driver = {
+                  .name = "lp855x",
+                  },
+       .probe = lp855x_probe,
+       .remove = __devexit_p(lp855x_remove),
+       .id_table = lp855x_ids,
+};
+
+module_i2c_driver(lp855x_driver);
+
+MODULE_DESCRIPTION("Texas Instruments LP855x Backlight driver");
+MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
+MODULE_LICENSE("GPL");
index cca43c0..333949f 100644 (file)
@@ -321,17 +321,7 @@ static struct spi_driver ltv350qv_driver = {
        .resume         = ltv350qv_resume,
 };
 
-static int __init ltv350qv_init(void)
-{
-       return spi_register_driver(&ltv350qv_driver);
-}
-
-static void __exit ltv350qv_exit(void)
-{
-       spi_unregister_driver(&ltv350qv_driver);
-}
-module_init(ltv350qv_init);
-module_exit(ltv350qv_exit);
+module_spi_driver(ltv350qv_driver);
 
 MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
 MODULE_DESCRIPTION("Samsung LTV350QV LCD Driver");
index c915e3b..e833ac7 100644 (file)
@@ -129,7 +129,8 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       data = kzalloc(sizeof(struct max8925_backlight_data), GFP_KERNEL);
+       data = devm_kzalloc(&pdev->dev, sizeof(struct max8925_backlight_data),
+                           GFP_KERNEL);
        if (data == NULL)
                return -ENOMEM;
        strncpy(name, res->name, MAX8925_NAME_SIZE);
@@ -143,7 +144,6 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
                                        &max8925_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
-               kfree(data);
                return PTR_ERR(bl);
        }
        bl->props.brightness = MAX_BRIGHTNESS;
@@ -165,17 +165,14 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
        return 0;
 out:
        backlight_device_unregister(bl);
-       kfree(data);
        return ret;
 }
 
 static int __devexit max8925_backlight_remove(struct platform_device *pdev)
 {
        struct backlight_device *bl = platform_get_drvdata(pdev);
-       struct max8925_backlight_data *data = bl_get_data(bl);
 
        backlight_device_unregister(bl);
-       kfree(data);
        return 0;
 }
 
index d8cde27..0175bfb 100644 (file)
@@ -141,7 +141,8 @@ static int omapbl_probe(struct platform_device *pdev)
        if (!pdata)
                return -ENXIO;
 
-       bl = kzalloc(sizeof(struct omap_backlight), GFP_KERNEL);
+       bl = devm_kzalloc(&pdev->dev, sizeof(struct omap_backlight),
+                         GFP_KERNEL);
        if (unlikely(!bl))
                return -ENOMEM;
 
@@ -150,10 +151,8 @@ static int omapbl_probe(struct platform_device *pdev)
        props.max_brightness = OMAPBL_MAX_INTENSITY;
        dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops,
                                        &props);
-       if (IS_ERR(dev)) {
-               kfree(bl);
+       if (IS_ERR(dev))
                return PTR_ERR(dev);
-       }
 
        bl->powermode = FB_BLANK_POWERDOWN;
        bl->current_intensity = 0;
@@ -177,10 +176,8 @@ static int omapbl_probe(struct platform_device *pdev)
 static int omapbl_remove(struct platform_device *pdev)
 {
        struct backlight_device *dev = platform_get_drvdata(pdev);
-       struct omap_backlight *bl = dev_get_drvdata(&dev->dev);
 
        backlight_device_unregister(dev);
-       kfree(bl);
 
        return 0;
 }
diff --git a/drivers/video/backlight/ot200_bl.c b/drivers/video/backlight/ot200_bl.c
new file mode 100644 (file)
index 0000000..f519d55
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2012 Bachmann electronic GmbH
+ *     Christian Gmeiner <christian.gmeiner@gmail.com>
+ *
+ * Backlight driver for ot200 visualisation device from
+ * Bachmann electronic GmbH.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/gpio.h>
+#include <linux/cs5535.h>
+
+static struct cs5535_mfgpt_timer *pwm_timer;
+
+/* this array defines the mapping of brightness in % to pwm frequency */
+static const u8 dim_table[101] = {0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+                                 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
+                                 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9,
+                                 10, 10, 11, 11, 12, 12, 13, 14, 15, 15, 16,
+                                 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28,
+                                 30, 31, 33, 35, 37, 39, 41, 43, 45, 47, 50,
+                                 53, 55, 58, 61, 65, 68, 72, 75, 79, 84, 88,
+                                 93, 97, 103, 108, 114, 120, 126, 133, 140,
+                                 147, 155, 163};
+
+struct ot200_backlight_data {
+       int current_brightness;
+};
+
+#define GPIO_DIMM      27
+#define SCALE          1
+#define CMP1MODE       0x2     /* compare on GE; output high on compare
+                                * greater than or equal */
+#define PWM_SETUP      (SCALE | CMP1MODE << 6 | MFGPT_SETUP_CNTEN)
+#define MAX_COMP2      163
+
+static int ot200_backlight_update_status(struct backlight_device *bl)
+{
+       struct ot200_backlight_data *data = bl_get_data(bl);
+       int brightness = bl->props.brightness;
+
+       if (bl->props.state & BL_CORE_FBBLANK)
+               brightness = 0;
+
+       /* enable or disable PWM timer */
+       if (brightness == 0)
+               cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, 0);
+       else if (data->current_brightness == 0) {
+               cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0);
+               cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP,
+                       MFGPT_SETUP_CNTEN);
+       }
+
+       /* apply new brightness value */
+       cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1,
+               MAX_COMP2 - dim_table[brightness]);
+       data->current_brightness = brightness;
+
+       return 0;
+}
+
+static int ot200_backlight_get_brightness(struct backlight_device *bl)
+{
+       struct ot200_backlight_data *data = bl_get_data(bl);
+       return data->current_brightness;
+}
+
+static const struct backlight_ops ot200_backlight_ops = {
+       .update_status  = ot200_backlight_update_status,
+       .get_brightness = ot200_backlight_get_brightness,
+};
+
+static int ot200_backlight_probe(struct platform_device *pdev)
+{
+       struct backlight_device *bl;
+       struct ot200_backlight_data *data;
+       struct backlight_properties props;
+       int retval = 0;
+
+       /* request gpio */
+       if (gpio_request(GPIO_DIMM, "ot200 backlight dimmer") < 0) {
+               dev_err(&pdev->dev, "failed to request GPIO %d\n", GPIO_DIMM);
+               return -ENODEV;
+       }
+
+       /* request timer */
+       pwm_timer = cs5535_mfgpt_alloc_timer(7, MFGPT_DOMAIN_ANY);
+       if (!pwm_timer) {
+               dev_err(&pdev->dev, "MFGPT 7 not available\n");
+               retval = -ENODEV;
+               goto error_mfgpt_alloc;
+       }
+
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data) {
+               retval = -ENOMEM;
+               goto error_kzalloc;
+       }
+
+       /* setup gpio */
+       cs5535_gpio_set(GPIO_DIMM, GPIO_OUTPUT_ENABLE);
+       cs5535_gpio_set(GPIO_DIMM, GPIO_OUTPUT_AUX1);
+
+       /* setup timer */
+       cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1, 0);
+       cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP2, MAX_COMP2);
+       cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, PWM_SETUP);
+
+       data->current_brightness = 100;
+       props.max_brightness = 100;
+       props.brightness = 100;
+       props.type = BACKLIGHT_RAW;
+
+       bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, data,
+                                       &ot200_backlight_ops, &props);
+       if (IS_ERR(bl)) {
+               dev_err(&pdev->dev, "failed to register backlight\n");
+               retval = PTR_ERR(bl);
+               goto error_backlight_device_register;
+       }
+
+       platform_set_drvdata(pdev, bl);
+
+       return 0;
+
+error_backlight_device_register:
+       kfree(data);
+error_kzalloc:
+       cs5535_mfgpt_free_timer(pwm_timer);
+error_mfgpt_alloc:
+       gpio_free(GPIO_DIMM);
+       return retval;
+}
+
+static int ot200_backlight_remove(struct platform_device *pdev)
+{
+       struct backlight_device *bl = platform_get_drvdata(pdev);
+       struct ot200_backlight_data *data = bl_get_data(bl);
+
+       backlight_device_unregister(bl);
+
+       /* on module unload set brightness to 100% */
+       cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0);
+       cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN);
+       cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1,
+               MAX_COMP2 - dim_table[100]);
+
+       cs5535_mfgpt_free_timer(pwm_timer);
+       gpio_free(GPIO_DIMM);
+
+       kfree(data);
+       return 0;
+}
+
+static struct platform_driver ot200_backlight_driver = {
+       .driver         = {
+               .name   = "ot200-backlight",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = ot200_backlight_probe,
+       .remove         = ot200_backlight_remove,
+};
+
+module_platform_driver(ot200_backlight_driver);
+
+MODULE_DESCRIPTION("backlight driver for ot200 visualisation device");
+MODULE_AUTHOR("Christian Gmeiner <christian.gmeiner@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ot200-backlight");
diff --git a/drivers/video/backlight/pandora_bl.c b/drivers/video/backlight/pandora_bl.c
new file mode 100644 (file)
index 0000000..4ec3074
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Backlight driver for Pandora handheld.
+ * Pandora uses TWL4030 PWM0 -> TPS61161 combo for control backlight.
+ * Based on pwm_bl.c
+ *
+ * Copyright 2009,2012 Gražvydas Ignotas <notasas@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/i2c/twl.h>
+#include <linux/err.h>
+
+#define TWL_PWM0_ON            0x00
+#define TWL_PWM0_OFF           0x01
+
+#define TWL_INTBR_GPBR1                0x0c
+#define TWL_INTBR_PMBR1                0x0d
+
+#define TWL_PMBR1_PWM0_MUXMASK 0x0c
+#define TWL_PMBR1_PWM0         0x04
+#define PWM0_CLK_ENABLE                BIT(0)
+#define PWM0_ENABLE            BIT(2)
+
+/* range accepted by hardware */
+#define MIN_VALUE 9
+#define MAX_VALUE 63
+#define MAX_USER_VALUE (MAX_VALUE - MIN_VALUE)
+
+#define PANDORABL_WAS_OFF BL_CORE_DRIVER1
+
+static int pandora_backlight_update_status(struct backlight_device *bl)
+{
+       int brightness = bl->props.brightness;
+       u8 r;
+
+       if (bl->props.power != FB_BLANK_UNBLANK)
+               brightness = 0;
+       if (bl->props.state & BL_CORE_FBBLANK)
+               brightness = 0;
+       if (bl->props.state & BL_CORE_SUSPENDED)
+               brightness = 0;
+
+       if ((unsigned int)brightness > MAX_USER_VALUE)
+               brightness = MAX_USER_VALUE;
+
+       if (brightness == 0) {
+               if (bl->props.state & PANDORABL_WAS_OFF)
+                       goto done;
+
+               /* first disable PWM0 output, then clock */
+               twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1);
+               r &= ~PWM0_ENABLE;
+               twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+               r &= ~PWM0_CLK_ENABLE;
+               twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+
+               goto done;
+       }
+
+       if (bl->props.state & PANDORABL_WAS_OFF) {
+               /*
+                * set PWM duty cycle to max. TPS61161 seems to use this
+                * to calibrate it's PWM sensitivity when it starts.
+                */
+               twl_i2c_write_u8(TWL4030_MODULE_PWM0, MAX_VALUE,
+                                       TWL_PWM0_OFF);
+
+               /* first enable clock, then PWM0 out */
+               twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1);
+               r &= ~PWM0_ENABLE;
+               r |= PWM0_CLK_ENABLE;
+               twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+               r |= PWM0_ENABLE;
+               twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+
+               /*
+                * TI made it very easy to enable digital control, so easy that
+                * it often triggers unintentionally and disabes PWM control,
+                * so wait until 1 wire mode detection window ends.
+                */
+               usleep_range(2000, 10000);
+       }
+
+       twl_i2c_write_u8(TWL4030_MODULE_PWM0, MIN_VALUE + brightness,
+                               TWL_PWM0_OFF);
+
+done:
+       if (brightness != 0)
+               bl->props.state &= ~PANDORABL_WAS_OFF;
+       else
+               bl->props.state |= PANDORABL_WAS_OFF;
+
+       return 0;
+}
+
+static int pandora_backlight_get_brightness(struct backlight_device *bl)
+{
+       return bl->props.brightness;
+}
+
+static const struct backlight_ops pandora_backlight_ops = {
+       .options        = BL_CORE_SUSPENDRESUME,
+       .update_status  = pandora_backlight_update_status,
+       .get_brightness = pandora_backlight_get_brightness,
+};
+
+static int pandora_backlight_probe(struct platform_device *pdev)
+{
+       struct backlight_properties props;
+       struct backlight_device *bl;
+       u8 r;
+
+       memset(&props, 0, sizeof(props));
+       props.max_brightness = MAX_USER_VALUE;
+       props.type = BACKLIGHT_RAW;
+       bl = backlight_device_register(pdev->name, &pdev->dev,
+                       NULL, &pandora_backlight_ops, &props);
+       if (IS_ERR(bl)) {
+               dev_err(&pdev->dev, "failed to register backlight\n");
+               return PTR_ERR(bl);
+       }
+
+       platform_set_drvdata(pdev, bl);
+
+       /* 64 cycle period, ON position 0 */
+       twl_i2c_write_u8(TWL4030_MODULE_PWM0, 0x80, TWL_PWM0_ON);
+
+       bl->props.state |= PANDORABL_WAS_OFF;
+       bl->props.brightness = MAX_USER_VALUE;
+       backlight_update_status(bl);
+
+       /* enable PWM function in pin mux */
+       twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_PMBR1);
+       r &= ~TWL_PMBR1_PWM0_MUXMASK;
+       r |= TWL_PMBR1_PWM0;
+       twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_PMBR1);
+
+       return 0;
+}
+
+static int pandora_backlight_remove(struct platform_device *pdev)
+{
+       struct backlight_device *bl = platform_get_drvdata(pdev);
+       backlight_device_unregister(bl);
+       return 0;
+}
+
+static struct platform_driver pandora_backlight_driver = {
+       .driver         = {
+               .name   = "pandora-backlight",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = pandora_backlight_probe,
+       .remove         = pandora_backlight_remove,
+};
+
+module_platform_driver(pandora_backlight_driver);
+
+MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
+MODULE_DESCRIPTION("Pandora Backlight Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pandora-backlight");
index 13e88b7..c65853c 100644 (file)
@@ -101,14 +101,13 @@ static const struct backlight_ops pcf50633_bl_ops = {
 
 static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
 {
-       int ret;
        struct pcf50633_bl *pcf_bl;
        struct device *parent = pdev->dev.parent;
        struct pcf50633_platform_data *pcf50633_data = parent->platform_data;
        struct pcf50633_bl_platform_data *pdata = pcf50633_data->backlight_data;
        struct backlight_properties bl_props;
 
-       pcf_bl = kzalloc(sizeof(*pcf_bl), GFP_KERNEL);
+       pcf_bl = devm_kzalloc(&pdev->dev, sizeof(*pcf_bl), GFP_KERNEL);
        if (!pcf_bl)
                return -ENOMEM;
 
@@ -129,10 +128,8 @@ static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
        pcf_bl->bl = backlight_device_register(pdev->name, &pdev->dev, pcf_bl,
                                                &pcf50633_bl_ops, &bl_props);
 
-       if (IS_ERR(pcf_bl->bl)) {
-               ret = PTR_ERR(pcf_bl->bl);
-               goto err_free;
-       }
+       if (IS_ERR(pcf_bl->bl))
+               return PTR_ERR(pcf_bl->bl);
 
        platform_set_drvdata(pdev, pcf_bl);
 
@@ -145,11 +142,6 @@ static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
        backlight_update_status(pcf_bl->bl);
 
        return 0;
-
-err_free:
-       kfree(pcf_bl);
-
-       return ret;
 }
 
 static int __devexit pcf50633_bl_remove(struct platform_device *pdev)
@@ -160,8 +152,6 @@ static int __devexit pcf50633_bl_remove(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, NULL);
 
-       kfree(pcf_bl);
-
        return 0;
 }
 
index f0bf491..b667234 100644 (file)
@@ -121,9 +121,9 @@ static int __devexit platform_lcd_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM
-static int platform_lcd_suspend(struct platform_device *pdev, pm_message_t st)
+static int platform_lcd_suspend(struct device *dev)
 {
-       struct platform_lcd *plcd = platform_get_drvdata(pdev);
+       struct platform_lcd *plcd = dev_get_drvdata(dev);
 
        plcd->suspended = 1;
        platform_lcd_set_power(plcd->lcd, plcd->power);
@@ -131,29 +131,30 @@ static int platform_lcd_suspend(struct platform_device *pdev, pm_message_t st)
        return 0;
 }
 
-static int platform_lcd_resume(struct platform_device *pdev)
+static int platform_lcd_resume(struct device *dev)
 {
-       struct platform_lcd *plcd = platform_get_drvdata(pdev);
+       struct platform_lcd *plcd = dev_get_drvdata(dev);
 
        plcd->suspended = 0;
        platform_lcd_set_power(plcd->lcd, plcd->power);
 
        return 0;
 }
-#else
-#define platform_lcd_suspend NULL
-#define platform_lcd_resume NULL
+
+static SIMPLE_DEV_PM_OPS(platform_lcd_pm_ops, platform_lcd_suspend,
+                       platform_lcd_resume);
 #endif
 
 static struct platform_driver platform_lcd_driver = {
        .driver         = {
                .name   = "platform-lcd",
                .owner  = THIS_MODULE,
+#ifdef CONFIG_PM
+               .pm     = &platform_lcd_pm_ops,
+#endif
        },
        .probe          = platform_lcd_probe,
        .remove         = __devexit_p(platform_lcd_remove),
-       .suspend        = platform_lcd_suspend,
-       .resume         = platform_lcd_resume,
 };
 
 module_platform_driver(platform_lcd_driver);
index 7496d04..342b7d7 100644 (file)
@@ -102,7 +102,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
                        return ret;
        }
 
-       pb = kzalloc(sizeof(*pb), GFP_KERNEL);
+       pb = devm_kzalloc(&pdev->dev, sizeof(*pb), GFP_KERNEL);
        if (!pb) {
                dev_err(&pdev->dev, "no memory for state\n");
                ret = -ENOMEM;
@@ -121,7 +121,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
        if (IS_ERR(pb->pwm)) {
                dev_err(&pdev->dev, "unable to request PWM for backlight\n");
                ret = PTR_ERR(pb->pwm);
-               goto err_pwm;
+               goto err_alloc;
        } else
                dev_dbg(&pdev->dev, "got pwm for backlight\n");
 
@@ -144,8 +144,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 
 err_bl:
        pwm_free(pb->pwm);
-err_pwm:
-       kfree(pb);
 err_alloc:
        if (data->exit)
                data->exit(&pdev->dev);
@@ -162,7 +160,6 @@ static int pwm_backlight_remove(struct platform_device *pdev)
        pwm_config(pb->pwm, 0, pb->period);
        pwm_disable(pb->pwm);
        pwm_free(pb->pwm);
-       kfree(pb);
        if (data->exit)
                data->exit(&pdev->dev);
        return 0;
index 516db70..e264f55 100644 (file)
@@ -909,18 +909,7 @@ static struct spi_driver s6e63m0_driver = {
        .resume         = s6e63m0_resume,
 };
 
-static int __init s6e63m0_init(void)
-{
-       return spi_register_driver(&s6e63m0_driver);
-}
-
-static void __exit s6e63m0_exit(void)
-{
-       spi_unregister_driver(&s6e63m0_driver);
-}
-
-module_init(s6e63m0_init);
-module_exit(s6e63m0_exit);
+module_spi_driver(s6e63m0_driver);
 
 MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
 MODULE_DESCRIPTION("S6E63M0 LCD Driver");
index 1997e12..2368b8e 100644 (file)
@@ -459,17 +459,7 @@ static struct spi_driver tdo24m_driver = {
        .resume         = tdo24m_resume,
 };
 
-static int __init tdo24m_init(void)
-{
-       return spi_register_driver(&tdo24m_driver);
-}
-module_init(tdo24m_init);
-
-static void __exit tdo24m_exit(void)
-{
-       spi_unregister_driver(&tdo24m_driver);
-}
-module_exit(tdo24m_exit);
+module_spi_driver(tdo24m_driver);
 
 MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
 MODULE_DESCRIPTION("Driver for Toppoly TDO24M LCD Panel");
index 425a736..2b241ab 100644 (file)
@@ -181,18 +181,7 @@ static struct i2c_driver tosa_bl_driver = {
        .id_table       = tosa_bl_id,
 };
 
-static int __init tosa_bl_init(void)
-{
-       return i2c_add_driver(&tosa_bl_driver);
-}
-
-static void __exit tosa_bl_exit(void)
-{
-       i2c_del_driver(&tosa_bl_driver);
-}
-
-module_init(tosa_bl_init);
-module_exit(tosa_bl_exit);
+module_i2c_driver(tosa_bl_driver);
 
 MODULE_AUTHOR("Dmitry Baryshkov");
 MODULE_LICENSE("GPL v2");
index 772f601..a2161f6 100644 (file)
@@ -285,18 +285,7 @@ static struct spi_driver tosa_lcd_driver = {
        .resume         = tosa_lcd_resume,
 };
 
-static int __init tosa_lcd_init(void)
-{
-       return spi_register_driver(&tosa_lcd_driver);
-}
-
-static void __exit tosa_lcd_exit(void)
-{
-       spi_unregister_driver(&tosa_lcd_driver);
-}
-
-module_init(tosa_lcd_init);
-module_exit(tosa_lcd_exit);
+module_spi_driver(tosa_lcd_driver);
 
 MODULE_AUTHOR("Dmitry Baryshkov");
 MODULE_LICENSE("GPL v2");
index b49063c..b617fae 100644 (file)
@@ -262,20 +262,7 @@ static struct spi_driver vgg2432a4_driver = {
        .resume         = vgg2432a4_resume,
 };
 
-/* Device driver initialisation */
-
-static int __init vgg2432a4_init(void)
-{
-       return spi_register_driver(&vgg2432a4_driver);
-}
-
-static void __exit vgg2432a4_exit(void)
-{
-       spi_unregister_driver(&vgg2432a4_driver);
-}
-
-module_init(vgg2432a4_init);
-module_exit(vgg2432a4_exit);
+module_spi_driver(vgg2432a4_driver);
 
 MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
 MODULE_DESCRIPTION("VGG2432A4 LCD Driver");
index 4e915f5..5d365de 100644 (file)
@@ -186,7 +186,7 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
        if (ret < 0)
                return ret;
 
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
        if (data == NULL)
                return -ENOMEM;
 
@@ -200,7 +200,6 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
                                       &wm831x_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
-               kfree(data);
                return PTR_ERR(bl);
        }
 
@@ -211,7 +210,6 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
        /* Disable the DCDC if it was started so we can bootstrap */
        wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, WM831X_DC4_ENA, 0);
 
-
        backlight_update_status(bl);
 
        return 0;
@@ -220,10 +218,8 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
 static int wm831x_backlight_remove(struct platform_device *pdev)
 {
        struct backlight_device *bl = platform_get_drvdata(pdev);
-       struct wm831x_backlight_data *data = bl_get_data(bl);
 
        backlight_device_unregister(bl);
-       kfree(data);
        return 0;
 }
 
index 9db3de3..260cca7 100644 (file)
@@ -121,7 +121,7 @@ static int uvesafb_helper_start(void)
                NULL,
        };
 
-       return call_usermodehelper(v86d_path, argv, envp, 1);
+       return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
 }
 
 /*
index 81878b7..504b6ee 100644 (file)
@@ -1093,6 +1093,29 @@ out:
  */
 
 /*
+ * The purpose of always_dump_vma() is to make sure that special kernel mappings
+ * that are useful for post-mortem analysis are included in every core dump.
+ * In that way we ensure that the core dump is fully interpretable later
+ * without matching up the same kernel and hardware config to see what PC values
+ * meant. These special mappings include - vDSO, vsyscall, and other
+ * architecture specific mappings
+ */
+static bool always_dump_vma(struct vm_area_struct *vma)
+{
+       /* Any vsyscall mappings? */
+       if (vma == get_gate_vma(vma->vm_mm))
+               return true;
+       /*
+        * arch_vma_name() returns non-NULL for special architecture mappings,
+        * such as vDSO sections.
+        */
+       if (arch_vma_name(vma))
+               return true;
+
+       return false;
+}
+
+/*
  * Decide what to dump of a segment, part, all or none.
  */
 static unsigned long vma_dump_size(struct vm_area_struct *vma,
@@ -1100,10 +1123,13 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
 {
 #define FILTER(type)   (mm_flags & (1UL << MMF_DUMP_##type))
 
-       /* The vma can be set up to tell us the answer directly.  */
-       if (vma->vm_flags & VM_ALWAYSDUMP)
+       /* always dump the vdso and vsyscall sections */
+       if (always_dump_vma(vma))
                goto whole;
 
+       if (vma->vm_flags & VM_NODUMP)
+               return 0;
+
        /* Hugetlb memory check */
        if (vma->vm_flags & VM_HUGETLB) {
                if ((vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_SHARED))
index 1ffb603..613aa06 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/magic.h>
 #include <linux/binfmts.h>
 #include <linux/slab.h>
 #include <linux/ctype.h>
@@ -699,7 +700,7 @@ static int bm_fill_super(struct super_block * sb, void * data, int silent)
                [3] = {"register", &bm_register_operations, S_IWUSR},
                /* last one */ {""}
        };
-       int err = simple_fill_super(sb, 0x42494e4d, bm_files);
+       int err = simple_fill_super(sb, BINFMTFS_MAGIC, bm_files);
        if (!err)
                sb->s_op = &s_ops;
        return err;
index a9ff300..e08f6a2 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/blkdev.h>
 #include <linux/module.h>
 #include <linux/blkpg.h>
+#include <linux/magic.h>
 #include <linux/buffer_head.h>
 #include <linux/swap.h>
 #include <linux/pagevec.h>
@@ -506,7 +507,7 @@ static const struct super_operations bdev_sops = {
 static struct dentry *bd_mount(struct file_system_type *fs_type,
        int flags, const char *dev_name, void *data)
 {
-       return mount_pseudo(fs_type, "bdev:", &bdev_sops, NULL, 0x62646576);
+       return mount_pseudo(fs_type, "bdev:", &bdev_sops, NULL, BDEVFS_MAGIC);
 }
 
 static struct file_system_type bd_type = {
index 4d9d3a4..629e9ed 100644 (file)
@@ -427,6 +427,31 @@ out_unlock:
        return error;
 }
 
+/*
+ * As described in commit 0ccf831cb lockdep: annotate epoll
+ * the use of wait queues used by epoll is done in a very controlled
+ * manner. Wake ups can nest inside each other, but are never done
+ * with the same locking. For example:
+ *
+ *   dfd = socket(...);
+ *   efd1 = epoll_create();
+ *   efd2 = epoll_create();
+ *   epoll_ctl(efd1, EPOLL_CTL_ADD, dfd, ...);
+ *   epoll_ctl(efd2, EPOLL_CTL_ADD, efd1, ...);
+ *
+ * When a packet arrives to the device underneath "dfd", the net code will
+ * issue a wake_up() on its poll wake list. Epoll (efd1) has installed a
+ * callback wakeup entry on that queue, and the wake_up() performed by the
+ * "dfd" net code will end up in ep_poll_callback(). At this point epoll
+ * (efd1) notices that it may have some event ready, so it needs to wake up
+ * the waiters on its poll wait list (efd2). So it calls ep_poll_safewake()
+ * that ends up in another wake_up(), after having checked about the
+ * recursion constraints. That are, no more than EP_MAX_POLLWAKE_NESTS, to
+ * avoid stack blasting.
+ *
+ * When CONFIG_DEBUG_LOCK_ALLOC is enabled, make sure lockdep can handle
+ * this special case of epoll.
+ */
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static inline void ep_wake_up_nested(wait_queue_head_t *wqueue,
                                     unsigned long events, int subclass)
@@ -699,9 +724,12 @@ static int ep_read_events_proc(struct eventpoll *ep, struct list_head *head,
                               void *priv)
 {
        struct epitem *epi, *tmp;
+       poll_table pt;
 
+       init_poll_funcptr(&pt, NULL);
        list_for_each_entry_safe(epi, tmp, head, rdllink) {
-               if (epi->ffd.file->f_op->poll(epi->ffd.file, NULL) &
+               pt._key = epi->event.events;
+               if (epi->ffd.file->f_op->poll(epi->ffd.file, &pt) &
                    epi->event.events)
                        return POLLIN | POLLRDNORM;
                else {
@@ -1049,13 +1077,11 @@ static int reverse_path_check_proc(void *priv, void *cookie, int call_nests)
  */
 static int reverse_path_check(void)
 {
-       int length = 0;
        int error = 0;
        struct file *current_file;
 
        /* let's call this for all tfiles */
        list_for_each_entry(current_file, &tfile_check_list, f_tfile_llink) {
-               length++;
                path_count_init();
                error = ep_call_nested(&poll_loop_ncalls, EP_MAX_NESTS,
                                        reverse_path_check_proc, current_file,
@@ -1097,6 +1123,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
        /* Initialize the poll table using the queue callback */
        epq.epi = epi;
        init_poll_funcptr(&epq.pt, ep_ptable_queue_proc);
+       epq.pt._key = event->events;
 
        /*
         * Attach the item to the poll hooks and get current event bits.
@@ -1191,6 +1218,9 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even
 {
        int pwake = 0;
        unsigned int revents;
+       poll_table pt;
+
+       init_poll_funcptr(&pt, NULL);
 
        /*
         * Set the new event interest mask before calling f_op->poll();
@@ -1198,13 +1228,14 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even
         * f_op->poll() call and the new event set registering.
         */
        epi->event.events = event->events;
+       pt._key = event->events;
        epi->event.data = event->data; /* protected by mtx */
 
        /*
         * Get current event bits. We can safely use the file* here because
         * its usage count has been increased by the caller of this function.
         */
-       revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL);
+       revents = epi->ffd.file->f_op->poll(epi->ffd.file, &pt);
 
        /*
         * If the item is "hot" and it is not registered inside the ready
@@ -1239,6 +1270,9 @@ static int ep_send_events_proc(struct eventpoll *ep, struct list_head *head,
        unsigned int revents;
        struct epitem *epi;
        struct epoll_event __user *uevent;
+       poll_table pt;
+
+       init_poll_funcptr(&pt, NULL);
 
        /*
         * We can loop without lock because we are passed a task private list.
@@ -1251,7 +1285,8 @@ static int ep_send_events_proc(struct eventpoll *ep, struct list_head *head,
 
                list_del_init(&epi->rdllink);
 
-               revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL) &
+               pt._key = epi->event.events;
+               revents = epi->ffd.file->f_op->poll(epi->ffd.file, &pt) &
                        epi->event.events;
 
                /*
index a81eb23..98ae804 100644 (file)
@@ -521,57 +521,46 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname,
 
                op = &outname[*outlen * sizeof(wchar_t)];
        } else {
-               if (nls) {
-                       for (i = 0, ip = name, op = outname, *outlen = 0;
-                            i < len && *outlen <= FAT_LFN_LEN;
-                            *outlen += 1)
-                       {
-                               if (escape && (*ip == ':')) {
-                                       if (i > len - 5)
-                                               return -EINVAL;
-                                       ec = 0;
-                                       for (k = 1; k < 5; k++) {
-                                               nc = ip[k];
-                                               ec <<= 4;
-                                               if (nc >= '0' && nc <= '9') {
-                                                       ec |= nc - '0';
-                                                       continue;
-                                               }
-                                               if (nc >= 'a' && nc <= 'f') {
-                                                       ec |= nc - ('a' - 10);
-                                                       continue;
-                                               }
-                                               if (nc >= 'A' && nc <= 'F') {
-                                                       ec |= nc - ('A' - 10);
-                                                       continue;
-                                               }
-                                               return -EINVAL;
+               for (i = 0, ip = name, op = outname, *outlen = 0;
+                        i < len && *outlen < FAT_LFN_LEN;
+                        *outlen += 1) {
+                       if (escape && (*ip == ':')) {
+                               if (i > len - 5)
+                                       return -EINVAL;
+                               ec = 0;
+                               for (k = 1; k < 5; k++) {
+                                       nc = ip[k];
+                                       ec <<= 4;
+                                       if (nc >= '0' && nc <= '9') {
+                                               ec |= nc - '0';
+                                               continue;
                                        }
-                                       *op++ = ec & 0xFF;
-                                       *op++ = ec >> 8;
-                                       ip += 5;
-                                       i += 5;
-                               } else {
-                                       if ((charlen = nls->char2uni(ip, len - i, (wchar_t *)op)) < 0)
-                                               return -EINVAL;
-                                       ip += charlen;
-                                       i += charlen;
-                                       op += 2;
+                                       if (nc >= 'a' && nc <= 'f') {
+                                               ec |= nc - ('a' - 10);
+                                               continue;
+                                       }
+                                       if (nc >= 'A' && nc <= 'F') {
+                                               ec |= nc - ('A' - 10);
+                                               continue;
+                                       }
+                                       return -EINVAL;
                                }
+                               *op++ = ec & 0xFF;
+                               *op++ = ec >> 8;
+                               ip += 5;
+                               i += 5;
+                       } else {
+                               charlen = nls->char2uni(ip, len - i,
+                                                                       (wchar_t *)op);
+                               if (charlen < 0)
+                                       return -EINVAL;
+                               ip += charlen;
+                               i += charlen;
+                               op += 2;
                        }
-                       if (i < len)
-                               return -ENAMETOOLONG;
-               } else {
-                       for (i = 0, ip = name, op = outname, *outlen = 0;
-                            i < len && *outlen <= FAT_LFN_LEN;
-                            i++, *outlen += 1)
-                       {
-                               *op++ = *ip++;
-                               *op++ = 0;
-                       }
-                       if (i < len)
-                               return -ENAMETOOLONG;
                }
+               if (i < len)
+                       return -ENAMETOOLONG;
        }
 
        *longlen = *outlen;
index ee18815..c887b13 100644 (file)
@@ -447,7 +447,7 @@ struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask,
        return event;
 }
 
-__init int fsnotify_notification_init(void)
+static __init int fsnotify_notification_init(void)
 {
        fsnotify_event_cachep = KMEM_CACHE(fsnotify_event, SLAB_PANIC);
        fsnotify_event_holder_cachep = KMEM_CACHE(fsnotify_event_holder, SLAB_PANIC);
@@ -461,4 +461,3 @@ __init int fsnotify_notification_init(void)
        return 0;
 }
 subsys_initcall(fsnotify_notification_init);
-
index fe0502f..25feaa3 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -13,6 +13,7 @@
 #include <linux/fs.h>
 #include <linux/log2.h>
 #include <linux/mount.h>
+#include <linux/magic.h>
 #include <linux/pipe_fs_i.h>
 #include <linux/uio.h>
 #include <linux/highmem.h>
index c602b8d..fbb53c2 100644 (file)
@@ -462,59 +462,56 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
        /* convert nsec -> ticks */
        start_time = nsec_to_clock_t(start_time);
 
-       seq_printf(m, "%d (%s) %c %d %d %d %d %d %u %lu \
-%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
-%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld %lu %lu %lu\n",
-               pid_nr_ns(pid, ns),
-               tcomm,
-               state,
-               ppid,
-               pgid,
-               sid,
-               tty_nr,
-               tty_pgrp,
-               task->flags,
-               min_flt,
-               cmin_flt,
-               maj_flt,
-               cmaj_flt,
-               cputime_to_clock_t(utime),
-               cputime_to_clock_t(stime),
-               cputime_to_clock_t(cutime),
-               cputime_to_clock_t(cstime),
-               priority,
-               nice,
-               num_threads,
-               start_time,
-               vsize,
-               mm ? get_mm_rss(mm) : 0,
-               rsslim,
-               mm ? (permitted ? mm->start_code : 1) : 0,
-               mm ? (permitted ? mm->end_code : 1) : 0,
-               (permitted && mm) ? mm->start_stack : 0,
-               esp,
-               eip,
-               /* The signal information here is obsolete.
-                * It must be decimal for Linux 2.0 compatibility.
-                * Use /proc/#/status for real-time signals.
-                */
-               task->pending.signal.sig[0] & 0x7fffffffUL,
-               task->blocked.sig[0] & 0x7fffffffUL,
-               sigign      .sig[0] & 0x7fffffffUL,
-               sigcatch    .sig[0] & 0x7fffffffUL,
-               wchan,
-               0UL,
-               0UL,
-               task->exit_signal,
-               task_cpu(task),
-               task->rt_priority,
-               task->policy,
-               (unsigned long long)delayacct_blkio_ticks(task),
-               cputime_to_clock_t(gtime),
-               cputime_to_clock_t(cgtime),
-               (mm && permitted) ? mm->start_data : 0,
-               (mm && permitted) ? mm->end_data : 0,
-               (mm && permitted) ? mm->start_brk : 0);
+       seq_printf(m, "%d (%s) %c", pid_nr_ns(pid, ns), tcomm, state);
+       seq_put_decimal_ll(m, ' ', ppid);
+       seq_put_decimal_ll(m, ' ', pgid);
+       seq_put_decimal_ll(m, ' ', sid);
+       seq_put_decimal_ll(m, ' ', tty_nr);
+       seq_put_decimal_ll(m, ' ', tty_pgrp);
+       seq_put_decimal_ull(m, ' ', task->flags);
+       seq_put_decimal_ull(m, ' ', min_flt);
+       seq_put_decimal_ull(m, ' ', cmin_flt);
+       seq_put_decimal_ull(m, ' ', maj_flt);
+       seq_put_decimal_ull(m, ' ', cmaj_flt);
+       seq_put_decimal_ull(m, ' ', cputime_to_clock_t(utime));
+       seq_put_decimal_ull(m, ' ', cputime_to_clock_t(stime));
+       seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cutime));
+       seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cstime));
+       seq_put_decimal_ll(m, ' ', priority);
+       seq_put_decimal_ll(m, ' ', nice);
+       seq_put_decimal_ll(m, ' ', num_threads);
+       seq_put_decimal_ull(m, ' ', 0);
+       seq_put_decimal_ull(m, ' ', start_time);
+       seq_put_decimal_ull(m, ' ', vsize);
+       seq_put_decimal_ll(m, ' ', mm ? get_mm_rss(mm) : 0);
+       seq_put_decimal_ull(m, ' ', rsslim);
+       seq_put_decimal_ull(m, ' ', mm ? (permitted ? mm->start_code : 1) : 0);
+       seq_put_decimal_ull(m, ' ', mm ? (permitted ? mm->end_code : 1) : 0);
+       seq_put_decimal_ull(m, ' ', (permitted && mm) ? mm->start_stack : 0);
+       seq_put_decimal_ull(m, ' ', esp);
+       seq_put_decimal_ull(m, ' ', eip);
+       /* The signal information here is obsolete.
+        * It must be decimal for Linux 2.0 compatibility.
+        * Use /proc/#/status for real-time signals.
+        */
+       seq_put_decimal_ull(m, ' ', task->pending.signal.sig[0] & 0x7fffffffUL);
+       seq_put_decimal_ull(m, ' ', task->blocked.sig[0] & 0x7fffffffUL);
+       seq_put_decimal_ull(m, ' ', sigign.sig[0] & 0x7fffffffUL);
+       seq_put_decimal_ull(m, ' ', sigcatch.sig[0] & 0x7fffffffUL);
+       seq_put_decimal_ull(m, ' ', wchan);
+       seq_put_decimal_ull(m, ' ', 0);
+       seq_put_decimal_ull(m, ' ', 0);
+       seq_put_decimal_ll(m, ' ', task->exit_signal);
+       seq_put_decimal_ll(m, ' ', task_cpu(task));
+       seq_put_decimal_ull(m, ' ', task->rt_priority);
+       seq_put_decimal_ull(m, ' ', task->policy);
+       seq_put_decimal_ull(m, ' ', delayacct_blkio_ticks(task));
+       seq_put_decimal_ull(m, ' ', cputime_to_clock_t(gtime));
+       seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cgtime));
+       seq_put_decimal_ull(m, ' ', (mm && permitted) ? mm->start_data : 0);
+       seq_put_decimal_ull(m, ' ', (mm && permitted) ? mm->end_data : 0);
+       seq_put_decimal_ull(m, ' ', (mm && permitted) ? mm->start_brk : 0);
+       seq_putc(m, '\n');
        if (mm)
                mmput(mm);
        return 0;
@@ -542,8 +539,20 @@ int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
                size = task_statm(mm, &shared, &text, &data, &resident);
                mmput(mm);
        }
-       seq_printf(m, "%lu %lu %lu %lu 0 %lu 0\n",
-                       size, resident, shared, text, data);
+       /*
+        * For quick read, open code by putting numbers directly
+        * expected format is
+        * seq_printf(m, "%lu %lu %lu %lu 0 %lu 0\n",
+        *               size, resident, shared, text, data);
+        */
+       seq_put_decimal_ull(m, 0, size);
+       seq_put_decimal_ull(m, ' ', resident);
+       seq_put_decimal_ull(m, ' ', shared);
+       seq_put_decimal_ull(m, ' ', text);
+       seq_put_decimal_ull(m, ' ', 0);
+       seq_put_decimal_ull(m, ' ', text);
+       seq_put_decimal_ull(m, ' ', 0);
+       seq_putc(m, '\n');
 
        return 0;
 }
index e5e69af..86c67ee 100644 (file)
@@ -157,7 +157,8 @@ static int kcore_update_ram(void)
 
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 /* calculate vmemmap's address from given system ram pfn and register it */
-int get_sparsemem_vmemmap_info(struct kcore_list *ent, struct list_head *head)
+static int
+get_sparsemem_vmemmap_info(struct kcore_list *ent, struct list_head *head)
 {
        unsigned long pfn = __pa(ent->addr) >> PAGE_SHIFT;
        unsigned long nr_pages = ent->size >> PAGE_SHIFT;
@@ -189,7 +190,8 @@ int get_sparsemem_vmemmap_info(struct kcore_list *ent, struct list_head *head)
 
 }
 #else
-int get_sparsemem_vmemmap_info(struct kcore_list *ent, struct list_head *head)
+static int
+get_sparsemem_vmemmap_info(struct kcore_list *ent, struct list_head *head)
 {
        return 1;
 }
index 27da860..3551f1f 100644 (file)
@@ -53,7 +53,7 @@ static struct dentry *proc_ns_instantiate(struct inode *dir,
        ei->ns_ops    = ns_ops;
        ei->ns        = ns;
 
-       dentry->d_op = &pid_dentry_operations;
+       d_set_d_op(dentry, &pid_dentry_operations);
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
        if (pid_revalidate(dentry, NULL))
index 121f77c..6a0c62d 100644 (file)
@@ -89,18 +89,19 @@ static int show_stat(struct seq_file *p, void *v)
        }
        sum += arch_irq_stat();
 
-       seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu %llu %llu "
-               "%llu\n",
-               (unsigned long long)cputime64_to_clock_t(user),
-               (unsigned long long)cputime64_to_clock_t(nice),
-               (unsigned long long)cputime64_to_clock_t(system),
-               (unsigned long long)cputime64_to_clock_t(idle),
-               (unsigned long long)cputime64_to_clock_t(iowait),
-               (unsigned long long)cputime64_to_clock_t(irq),
-               (unsigned long long)cputime64_to_clock_t(softirq),
-               (unsigned long long)cputime64_to_clock_t(steal),
-               (unsigned long long)cputime64_to_clock_t(guest),
-               (unsigned long long)cputime64_to_clock_t(guest_nice));
+       seq_puts(p, "cpu ");
+       seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(user));
+       seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(nice));
+       seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(system));
+       seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(idle));
+       seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(iowait));
+       seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(irq));
+       seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(softirq));
+       seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(steal));
+       seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest));
+       seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest_nice));
+       seq_putc(p, '\n');
+
        for_each_online_cpu(i) {
                /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
                user = kcpustat_cpu(i).cpustat[CPUTIME_USER];
@@ -113,26 +114,24 @@ static int show_stat(struct seq_file *p, void *v)
                steal = kcpustat_cpu(i).cpustat[CPUTIME_STEAL];
                guest = kcpustat_cpu(i).cpustat[CPUTIME_GUEST];
                guest_nice = kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE];
-               seq_printf(p,
-                       "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu "
-                       "%llu\n",
-                       i,
-                       (unsigned long long)cputime64_to_clock_t(user),
-                       (unsigned long long)cputime64_to_clock_t(nice),
-                       (unsigned long long)cputime64_to_clock_t(system),
-                       (unsigned long long)cputime64_to_clock_t(idle),
-                       (unsigned long long)cputime64_to_clock_t(iowait),
-                       (unsigned long long)cputime64_to_clock_t(irq),
-                       (unsigned long long)cputime64_to_clock_t(softirq),
-                       (unsigned long long)cputime64_to_clock_t(steal),
-                       (unsigned long long)cputime64_to_clock_t(guest),
-                       (unsigned long long)cputime64_to_clock_t(guest_nice));
+               seq_printf(p, "cpu%d", i);
+               seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(user));
+               seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(nice));
+               seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(system));
+               seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(idle));
+               seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(iowait));
+               seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(irq));
+               seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(softirq));
+               seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(steal));
+               seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest));
+               seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest_nice));
+               seq_putc(p, '\n');
        }
        seq_printf(p, "intr %llu", (unsigned long long)sum);
 
        /* sum again ? it could be updated? */
        for_each_irq_nr(j)
-               seq_printf(p, " %u", kstat_irqs(j));
+               seq_put_decimal_ull(p, ' ', kstat_irqs(j));
 
        seq_printf(p,
                "\nctxt %llu\n"
@@ -149,7 +148,7 @@ static int show_stat(struct seq_file *p, void *v)
        seq_printf(p, "softirq %llu", (unsigned long long)sum_softirq);
 
        for (i = 0; i < NR_SOFTIRQS; i++)
-               seq_printf(p, " %u", per_softirq_sums[i]);
+               seq_put_decimal_ull(p, ' ', per_softirq_sums[i]);
        seq_putc(p, '\n');
 
        return 0;
@@ -157,11 +156,14 @@ static int show_stat(struct seq_file *p, void *v)
 
 static int stat_open(struct inode *inode, struct file *file)
 {
-       unsigned size = 4096 * (1 + num_possible_cpus() / 32);
+       unsigned size = 1024 + 128 * num_possible_cpus();
        char *buf;
        struct seq_file *m;
        int res;
 
+       /* minimum size to display an interrupt count : 2 bytes */
+       size += 2 * nr_irqs;
+
        /* don't ask for more than the kmalloc() max size */
        if (size > KMALLOC_MAX_SIZE)
                size = KMALLOC_MAX_SIZE;
@@ -173,7 +175,7 @@ static int stat_open(struct inode *inode, struct file *file)
        if (!res) {
                m = file->private_data;
                m->buf = buf;
-               m->size = size;
+               m->size = ksize(buf);
        } else
                kfree(buf);
        return res;
index e782258..ecfd0b1 100644 (file)
@@ -223,7 +223,7 @@ static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
        get_file(filp);
        entry->filp = filp;
        entry->wait_address = wait_address;
-       entry->key = p->key;
+       entry->key = p->_key;
        init_waitqueue_func_entry(&entry->wait, pollwake);
        entry->wait.private = pwq;
        add_wait_queue(wait_address, &entry->wait);
@@ -386,13 +386,11 @@ get_max:
 static inline void wait_key_set(poll_table *wait, unsigned long in,
                                unsigned long out, unsigned long bit)
 {
-       if (wait) {
-               wait->key = POLLEX_SET;
-               if (in & bit)
-                       wait->key |= POLLIN_SET;
-               if (out & bit)
-                       wait->key |= POLLOUT_SET;
-       }
+       wait->_key = POLLEX_SET;
+       if (in & bit)
+               wait->_key |= POLLIN_SET;
+       if (out & bit)
+               wait->_key |= POLLOUT_SET;
 }
 
 int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
@@ -414,7 +412,7 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
        poll_initwait(&table);
        wait = &table.pt;
        if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
-               wait = NULL;
+               wait->_qproc = NULL;
                timed_out = 1;
        }
 
@@ -459,17 +457,17 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
                                        if ((mask & POLLIN_SET) && (in & bit)) {
                                                res_in |= bit;
                                                retval++;
-                                               wait = NULL;
+                                               wait->_qproc = NULL;
                                        }
                                        if ((mask & POLLOUT_SET) && (out & bit)) {
                                                res_out |= bit;
                                                retval++;
-                                               wait = NULL;
+                                               wait->_qproc = NULL;
                                        }
                                        if ((mask & POLLEX_SET) && (ex & bit)) {
                                                res_ex |= bit;
                                                retval++;
-                                               wait = NULL;
+                                               wait->_qproc = NULL;
                                        }
                                }
                        }
@@ -481,7 +479,7 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time)
                                *rexp = res_ex;
                        cond_resched();
                }
-               wait = NULL;
+               wait->_qproc = NULL;
                if (retval || timed_out || signal_pending(current))
                        break;
                if (table.error) {
@@ -720,7 +718,7 @@ struct poll_list {
  * interested in events matching the pollfd->events mask, and the result
  * matching that mask is both recorded in pollfd->revents and returned. The
  * pwait poll_table will be used by the fd-provided poll handler for waiting,
- * if non-NULL.
+ * if pwait->_qproc is non-NULL.
  */
 static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait)
 {
@@ -738,9 +736,7 @@ static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait)
                if (file != NULL) {
                        mask = DEFAULT_POLLMASK;
                        if (file->f_op && file->f_op->poll) {
-                               if (pwait)
-                                       pwait->key = pollfd->events |
-                                                       POLLERR | POLLHUP;
+                               pwait->_key = pollfd->events|POLLERR|POLLHUP;
                                mask = file->f_op->poll(file, pwait);
                        }
                        /* Mask out unneeded events. */
@@ -763,7 +759,7 @@ static int do_poll(unsigned int nfds,  struct poll_list *list,
 
        /* Optimise the no-wait case */
        if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
-               pt = NULL;
+               pt->_qproc = NULL;
                timed_out = 1;
        }
 
@@ -781,22 +777,22 @@ static int do_poll(unsigned int nfds,  struct poll_list *list,
                        for (; pfd != pfd_end; pfd++) {
                                /*
                                 * Fish for events. If we found one, record it
-                                * and kill the poll_table, so we don't
+                                * and kill poll_table->_qproc, so we don't
                                 * needlessly register any other waiters after
                                 * this. They'll get immediately deregistered
                                 * when we break out and return.
                                 */
                                if (do_pollfd(pfd, pt)) {
                                        count++;
-                                       pt = NULL;
+                                       pt->_qproc = NULL;
                                }
                        }
                }
                /*
                 * All waiters have already been registered, so don't provide
-                * a poll_table to them on the next loop iteration.
+                * a poll_table->_qproc to them on the next loop iteration.
                 */
-               pt = NULL;
+               pt->_qproc = NULL;
                if (!count) {
                        count = wait->error;
                        if (signal_pending(current))
index aa242dc..46cfb06 100644 (file)
 #include <asm/uaccess.h>
 #include <asm/page.h>
 
+
+/*
+ * seq_files have a buffer which can may overflow. When this happens a larger
+ * buffer is reallocated and all the data will be printed again.
+ * The overflow state is true when m->count == m->size.
+ */
+static bool seq_overflow(struct seq_file *m)
+{
+       return m->count == m->size;
+}
+
+static void seq_set_overflow(struct seq_file *m)
+{
+       m->count = m->size;
+}
+
 /**
  *     seq_open -      initialize sequential file
  *     @file: file we initialize
@@ -92,7 +108,7 @@ static int traverse(struct seq_file *m, loff_t offset)
                        error = 0;
                        m->count = 0;
                }
-               if (m->count == m->size)
+               if (seq_overflow(m))
                        goto Eoverflow;
                if (pos + m->count > offset) {
                        m->from = offset - pos;
@@ -234,7 +250,7 @@ Fill:
                        break;
                }
                err = m->op->show(m, p);
-               if (m->count == m->size || err) {
+               if (seq_overflow(m) || err) {
                        m->count = offs;
                        if (likely(err <= 0))
                                break;
@@ -361,7 +377,7 @@ int seq_escape(struct seq_file *m, const char *s, const char *esc)
                        *p++ = '0' + (c & 07);
                        continue;
                }
-               m->count = m->size;
+               seq_set_overflow(m);
                return -1;
         }
        m->count = p - m->buf;
@@ -383,7 +399,7 @@ int seq_printf(struct seq_file *m, const char *f, ...)
                        return 0;
                }
        }
-       m->count = m->size;
+       seq_set_overflow(m);
        return -1;
 }
 EXPORT_SYMBOL(seq_printf);
@@ -512,7 +528,7 @@ int seq_bitmap(struct seq_file *m, const unsigned long *bits,
                        return 0;
                }
        }
-       m->count = m->size;
+       seq_set_overflow(m);
        return -1;
 }
 EXPORT_SYMBOL(seq_bitmap);
@@ -528,7 +544,7 @@ int seq_bitmap_list(struct seq_file *m, const unsigned long *bits,
                        return 0;
                }
        }
-       m->count = m->size;
+       seq_set_overflow(m);
        return -1;
 }
 EXPORT_SYMBOL(seq_bitmap_list);
@@ -639,11 +655,63 @@ int seq_puts(struct seq_file *m, const char *s)
                m->count += len;
                return 0;
        }
-       m->count = m->size;
+       seq_set_overflow(m);
        return -1;
 }
 EXPORT_SYMBOL(seq_puts);
 
+/*
+ * A helper routine for putting decimal numbers without rich format of printf().
+ * only 'unsigned long long' is supported.
+ * This routine will put one byte delimiter + number into seq_file.
+ * This routine is very quick when you show lots of numbers.
+ * In usual cases, it will be better to use seq_printf(). It's easier to read.
+ */
+int seq_put_decimal_ull(struct seq_file *m, char delimiter,
+                       unsigned long long num)
+{
+       int len;
+
+       if (m->count + 2 >= m->size) /* we'll write 2 bytes at least */
+               goto overflow;
+
+       if (delimiter)
+               m->buf[m->count++] = delimiter;
+
+       if (num < 10) {
+               m->buf[m->count++] = num + '0';
+               return 0;
+       }
+
+       len = num_to_str(m->buf + m->count, m->size - m->count, num);
+       if (!len)
+               goto overflow;
+       m->count += len;
+       return 0;
+overflow:
+       seq_set_overflow(m);
+       return -1;
+}
+EXPORT_SYMBOL(seq_put_decimal_ull);
+
+int seq_put_decimal_ll(struct seq_file *m, char delimiter,
+                       long long num)
+{
+       if (num < 0) {
+               if (m->count + 3 >= m->size) {
+                       seq_set_overflow(m);
+                       return -1;
+               }
+               if (delimiter)
+                       m->buf[m->count++] = delimiter;
+               num = -num;
+               delimiter = '-';
+       }
+       return seq_put_decimal_ull(m, delimiter, num);
+
+}
+EXPORT_SYMBOL(seq_put_decimal_ll);
+
 /**
  * seq_write - write arbitrary data to buffer
  * @seq: seq_file identifying the buffer to which data should be written
@@ -659,7 +727,7 @@ int seq_write(struct seq_file *seq, const void *data, size_t len)
                seq->count += len;
                return 0;
        }
-       seq->count = seq->size;
+       seq_set_overflow(seq);
        return -1;
 }
 EXPORT_SYMBOL(seq_write);
index 84458b0..2520a6e 100644 (file)
@@ -134,7 +134,7 @@ extern void warn_slowpath_null(const char *file, const int line);
 #endif
 
 #define WARN_ON_ONCE(condition)        ({                              \
-       static bool __warned;                                   \
+       static bool __section(.data.unlikely) __warned;         \
        int __ret_warn_once = !!(condition);                    \
                                                                \
        if (unlikely(__ret_warn_once))                          \
@@ -144,7 +144,7 @@ extern void warn_slowpath_null(const char *file, const int line);
 })
 
 #define WARN_ONCE(condition, format...)        ({                      \
-       static bool __warned;                                   \
+       static bool __section(.data.unlikely) __warned;         \
        int __ret_warn_once = !!(condition);                    \
                                                                \
        if (unlikely(__ret_warn_once))                          \
@@ -154,7 +154,7 @@ extern void warn_slowpath_null(const char *file, const int line);
 })
 
 #define WARN_TAINT_ONCE(condition, taint, format...)   ({      \
-       static bool __warned;                                   \
+       static bool __section(.data.unlikely) __warned;         \
        int __ret_warn_once = !!(condition);                    \
                                                                \
        if (unlikely(__ret_warn_once))                          \
index 787abbb..d030d2c 100644 (file)
 #define MADV_HUGEPAGE  14              /* Worth backing with hugepages */
 #define MADV_NOHUGEPAGE        15              /* Not worth backing with hugepages */
 
+#define MADV_DONTDUMP   16             /* Explicity exclude from the core dump,
+                                          overrides the coredump filter bits */
+#define MADV_DODUMP    17              /* Clear the MADV_NODUMP flag */
+
 /* compatibility flags */
 #define MAP_FILE       0
 
index b5e2e4c..798603e 100644 (file)
        CPU_KEEP(exit.data)                                             \
        MEM_KEEP(init.data)                                             \
        MEM_KEEP(exit.data)                                             \
+       *(.data.unlikely)                                               \
        STRUCT_ALIGN();                                                 \
        *(__tracepoints)                                                \
        /* implement dynamic printk debug */                            \
index 2a2acda..4a0aae3 100644 (file)
@@ -27,6 +27,8 @@
 #ifndef _DRM_MODE_H
 #define _DRM_MODE_H
 
+#include <linux/types.h>
+
 #define DRM_DISPLAY_INFO_LEN   32
 #define DRM_CONNECTOR_NAME_LEN 32
 #define DRM_DISPLAY_MODE_LEN   32
index 94300fe..a3b6b82 100644 (file)
@@ -27,11 +27,22 @@ extern unsigned long __sw_hweight64(__u64 w);
             (bit) = find_next_bit((addr), (size), (bit) + 1))
 
 /* same as for_each_set_bit() but use bit as value to start with */
-#define for_each_set_bit_cont(bit, addr, size) \
+#define for_each_set_bit_from(bit, addr, size) \
        for ((bit) = find_next_bit((addr), (size), (bit));      \
             (bit) < (size);                                    \
             (bit) = find_next_bit((addr), (size), (bit) + 1))
 
+#define for_each_clear_bit(bit, addr, size) \
+       for ((bit) = find_first_zero_bit((addr), (size));       \
+            (bit) < (size);                                    \
+            (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
+
+/* same as for_each_clear_bit() but use bit as value to start with */
+#define for_each_clear_bit_from(bit, addr, size) \
+       for ((bit) = find_next_zero_bit((addr), (size), (bit)); \
+            (bit) < (size);                                    \
+            (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
+
 static __inline__ int get_bitmask_order(unsigned int count)
 {
        int order;
index 3fd17c2..e5834aa 100644 (file)
@@ -87,7 +87,8 @@
  */
 #define __pure                         __attribute__((pure))
 #define __aligned(x)                   __attribute__((aligned(x)))
-#define __printf(a,b)                  __attribute__((format(printf,a,b)))
+#define __printf(a, b)                 __attribute__((format(printf, a, b)))
+#define __scanf(a, b)                  __attribute__((format(scanf, a, b)))
 #define  noinline                      __attribute__((noinline))
 #define __attribute_const__            __attribute__((__const__))
 #define __maybe_unused                 __attribute__((unused))
index 391a259..68267b6 100644 (file)
@@ -11,6 +11,8 @@
 extern u32  crc32_le(u32 crc, unsigned char const *p, size_t len);
 extern u32  crc32_be(u32 crc, unsigned char const *p, size_t len);
 
+extern u32  __crc32c_le(u32 crc, unsigned char const *p, size_t len);
+
 #define crc32(seed, data, length)  crc32_le(seed, (unsigned char const *)(data), length)
 
 /*
index d801acb..3e140ad 100644 (file)
@@ -312,6 +312,8 @@ extern long long simple_strtoll(const char *,char **,unsigned int);
 #define strict_strtoull        kstrtoull
 #define strict_strtoll kstrtoll
 
+extern int num_to_str(char *buf, int size, unsigned long long num);
+
 /* lib/printf utilities */
 
 extern __printf(2, 3) int sprintf(char *buf, const char * fmt, ...);
@@ -328,10 +330,10 @@ extern __printf(2, 3)
 char *kasprintf(gfp_t gfp, const char *fmt, ...);
 extern char *kvasprintf(gfp_t gfp, const char *fmt, va_list args);
 
-extern int sscanf(const char *, const char *, ...)
-       __attribute__ ((format (scanf, 2, 3)));
-extern int vsscanf(const char *, const char *, va_list)
-       __attribute__ ((format (scanf, 2, 0)));
+extern __scanf(2, 3)
+int sscanf(const char *, const char *, ...);
+extern __scanf(2, 0)
+int vsscanf(const char *, const char *, va_list);
 
 extern int get_option(char **str, int *pint);
 extern char *get_options(const char *str, int nints, int *ints);
index 722f477..9efeae6 100644 (file)
@@ -48,11 +48,10 @@ static inline int request_module_nowait(const char *name, ...) { return -ENOSYS;
 struct cred;
 struct file;
 
-enum umh_wait {
-       UMH_NO_WAIT = -1,       /* don't wait at all */
-       UMH_WAIT_EXEC = 0,      /* wait for the exec, but not the process */
-       UMH_WAIT_PROC = 1,      /* wait for the process to complete */
-};
+#define UMH_NO_WAIT    0       /* don't wait at all */
+#define UMH_WAIT_EXEC  1       /* wait for the exec, but not the process */
+#define UMH_WAIT_PROC  2       /* wait for the process to complete */
+#define UMH_KILLABLE   4       /* wait for EXEC/PROC killable */
 
 struct subprocess_info {
        struct work_struct work;
@@ -60,7 +59,7 @@ struct subprocess_info {
        char *path;
        char **argv;
        char **envp;
-       enum umh_wait wait;
+       int wait;
        int retval;
        int (*init)(struct subprocess_info *info, struct cred *new);
        void (*cleanup)(struct subprocess_info *info);
@@ -78,15 +77,14 @@ void call_usermodehelper_setfns(struct subprocess_info *info,
                    void *data);
 
 /* Actually execute the sub-process */
-int call_usermodehelper_exec(struct subprocess_info *info, enum umh_wait wait);
+int call_usermodehelper_exec(struct subprocess_info *info, int wait);
 
 /* Free the subprocess_info. This is only needed if you're not going
    to call call_usermodehelper_exec */
 void call_usermodehelper_freeinfo(struct subprocess_info *info);
 
 static inline int
-call_usermodehelper_fns(char *path, char **argv, char **envp,
-                       enum umh_wait wait,
+call_usermodehelper_fns(char *path, char **argv, char **envp, int wait,
                        int (*init)(struct subprocess_info *info, struct cred *new),
                        void (*cleanup)(struct subprocess_info *), void *data)
 {
@@ -104,7 +102,7 @@ call_usermodehelper_fns(char *path, char **argv, char **envp,
 }
 
 static inline int
-call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait)
+call_usermodehelper(char *path, char **argv, char **envp, int wait)
 {
        return call_usermodehelper_fns(path, argv, envp, wait,
                                       NULL, NULL, NULL);
index 8eb1235..eeae6e7 100644 (file)
@@ -72,6 +72,12 @@ enum lm3530_als_mode {
        LM3530_INPUT_CEIL,      /* Max of ALS1 and ALS2 */
 };
 
+/* PWM Platform Specific Data */
+struct lm3530_pwm_data {
+       void (*pwm_set_intensity) (int brightness, int max_brightness);
+       int (*pwm_get_intensity) (int max_brightness);
+};
+
 /**
  * struct lm3530_platform_data
  * @mode: mode of operation i.e. Manual, ALS or PWM
@@ -87,6 +93,7 @@ enum lm3530_als_mode {
  * @als_vmin: als input voltage calibrated for max brightness in mV
  * @als_vmax: als input voltage calibrated for min brightness in mV
  * @brt_val: brightness value (0-255)
+ * @pwm_data: PWM control functions (only valid when the mode is PWM)
  */
 struct lm3530_platform_data {
        enum lm3530_mode mode;
@@ -107,6 +114,8 @@ struct lm3530_platform_data {
        u32 als_vmax;
 
        u8 brt_val;
+
+       struct lm3530_pwm_data pwm_data;
 };
 
 #endif /* _LINUX_LED_LM3530_H__ */
index fd548d2..3f071ec 100644 (file)
 /* See Documentation/leds/leds-lp5521.txt */
 
 struct lp5521_led_config {
+       char            *name;
        u8              chan_nr;
        u8              led_current; /* mA x10, 0 if led is not connected */
        u8              max_current;
 };
 
+struct lp5521_led_pattern {
+       u8 *r;
+       u8 *g;
+       u8 *b;
+       u8 size_r;
+       u8 size_g;
+       u8 size_b;
+};
+
 #define LP5521_CLOCK_AUTO      0
 #define LP5521_CLOCK_INT       1
 #define LP5521_CLOCK_EXT       2
 
+/* Bits in CONFIG register */
+#define LP5521_PWM_HF                  0x40    /* PWM: 0 = 256Hz, 1 = 558Hz */
+#define LP5521_PWRSAVE_EN              0x20    /* 1 = Power save mode */
+#define LP5521_CP_MODE_OFF             0       /* Charge pump (CP) off */
+#define LP5521_CP_MODE_BYPASS          8       /* CP forced to bypass mode */
+#define LP5521_CP_MODE_1X5             0x10    /* CP forced to 1.5x mode */
+#define LP5521_CP_MODE_AUTO            0x18    /* Automatic mode selection */
+#define LP5521_R_TO_BATT               4       /* R out: 0 = CP, 1 = Vbat */
+#define LP5521_CLK_SRC_EXT             0       /* Ext-clk source (CLK_32K) */
+#define LP5521_CLK_INT                 1       /* Internal clock */
+#define LP5521_CLK_AUTO                        2       /* Automatic clock selection */
+
 struct lp5521_platform_data {
        struct lp5521_led_config *led_config;
        u8      num_channels;
@@ -43,6 +65,9 @@ struct lp5521_platform_data {
        void    (*release_resources)(void);
        void    (*enable)(bool state);
        const char *label;
+       u8      update_config;
+       struct lp5521_led_pattern *patterns;
+       int num_patterns;
 };
 
 #endif /* __LINUX_LP5521_H */
diff --git a/include/linux/lp855x.h b/include/linux/lp855x.h
new file mode 100644 (file)
index 0000000..781a490
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * LP855x Backlight Driver
+ *
+ *                     Copyright (C) 2011 Texas Instruments
+ *
+ * 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 _LP855X_H
+#define _LP855X_H
+
+#define BL_CTL_SHFT    (0)
+#define BRT_MODE_SHFT  (1)
+#define BRT_MODE_MASK  (0x06)
+
+/* Enable backlight. Only valid when BRT_MODE=10(I2C only) */
+#define ENABLE_BL      (1)
+#define DISABLE_BL     (0)
+
+#define I2C_CONFIG(id) id ## _I2C_CONFIG
+#define PWM_CONFIG(id) id ## _PWM_CONFIG
+
+/* DEVICE CONTROL register - LP8550 */
+#define LP8550_PWM_CONFIG      (LP8550_PWM_ONLY << BRT_MODE_SHFT)
+#define LP8550_I2C_CONFIG      ((ENABLE_BL << BL_CTL_SHFT) | \
+                               (LP8550_I2C_ONLY << BRT_MODE_SHFT))
+
+/* DEVICE CONTROL register - LP8551 */
+#define LP8551_PWM_CONFIG      LP8550_PWM_CONFIG
+#define LP8551_I2C_CONFIG      LP8550_I2C_CONFIG
+
+/* DEVICE CONTROL register - LP8552 */
+#define LP8552_PWM_CONFIG      LP8550_PWM_CONFIG
+#define LP8552_I2C_CONFIG      LP8550_I2C_CONFIG
+
+/* DEVICE CONTROL register - LP8553 */
+#define LP8553_PWM_CONFIG      LP8550_PWM_CONFIG
+#define LP8553_I2C_CONFIG      LP8550_I2C_CONFIG
+
+/* DEVICE CONTROL register - LP8556 */
+#define LP8556_PWM_CONFIG      (LP8556_PWM_ONLY << BRT_MODE_SHFT)
+#define LP8556_COMB1_CONFIG    (LP8556_COMBINED1 << BRT_MODE_SHFT)
+#define LP8556_I2C_CONFIG      ((ENABLE_BL << BL_CTL_SHFT) | \
+                               (LP8556_I2C_ONLY << BRT_MODE_SHFT))
+#define LP8556_COMB2_CONFIG    (LP8556_COMBINED2 << BRT_MODE_SHFT)
+
+/* ROM area boundary */
+#define EEPROM_START   (0xA0)
+#define EEPROM_END     (0xA7)
+#define EPROM_START    (0xA0)
+#define EPROM_END      (0xAF)
+
+enum lp855x_chip_id {
+       LP8550,
+       LP8551,
+       LP8552,
+       LP8553,
+       LP8556,
+};
+
+enum lp855x_brightness_ctrl_mode {
+       PWM_BASED = 1,
+       REGISTER_BASED,
+};
+
+enum lp8550_brighntess_source {
+       LP8550_PWM_ONLY,
+       LP8550_I2C_ONLY = 2,
+};
+
+enum lp8551_brighntess_source {
+       LP8551_PWM_ONLY = LP8550_PWM_ONLY,
+       LP8551_I2C_ONLY = LP8550_I2C_ONLY,
+};
+
+enum lp8552_brighntess_source {
+       LP8552_PWM_ONLY = LP8550_PWM_ONLY,
+       LP8552_I2C_ONLY = LP8550_I2C_ONLY,
+};
+
+enum lp8553_brighntess_source {
+       LP8553_PWM_ONLY = LP8550_PWM_ONLY,
+       LP8553_I2C_ONLY = LP8550_I2C_ONLY,
+};
+
+enum lp8556_brightness_source {
+       LP8556_PWM_ONLY,
+       LP8556_COMBINED1,       /* pwm + i2c before the shaper block */
+       LP8556_I2C_ONLY,
+       LP8556_COMBINED2,       /* pwm + i2c after the shaper block */
+};
+
+struct lp855x_pwm_data {
+       void (*pwm_set_intensity) (int brightness, int max_brightness);
+       int (*pwm_get_intensity) (int max_brightness);
+};
+
+struct lp855x_rom_data {
+       u8 addr;
+       u8 val;
+};
+
+/**
+ * struct lp855x_platform_data
+ * @name : Backlight driver name. If it is not defined, default name is set.
+ * @mode : brightness control by pwm or lp855x register
+ * @device_control : value of DEVICE CONTROL register
+ * @initial_brightness : initial value of backlight brightness
+ * @pwm_data : platform specific pwm generation functions.
+               Only valid when mode is PWM_BASED.
+ * @load_new_rom_data :
+       0 : use default configuration data
+       1 : update values of eeprom or eprom registers on loading driver
+ * @size_program : total size of lp855x_rom_data
+ * @rom_data : list of new eeprom/eprom registers
+ */
+struct lp855x_platform_data {
+       char *name;
+       enum lp855x_brightness_ctrl_mode mode;
+       u8 device_control;
+       int initial_brightness;
+       struct lp855x_pwm_data pwm_data;
+       u8 load_new_rom_data;
+       int size_program;
+       struct lp855x_rom_data *rom_data;
+};
+
+#endif
index b7ed475..e15192c 100644 (file)
@@ -9,7 +9,6 @@
 #define CRAMFS_MAGIC           0x28cd3d45      /* some random number */
 #define CRAMFS_MAGIC_WEND      0x453dcd28      /* magic number with the wrong endianess */
 #define DEBUGFS_MAGIC          0x64626720
-#define SYSFS_MAGIC            0x62656572
 #define SECURITYFS_MAGIC       0x73636673
 #define SELINUX_MAGIC          0xf97cff8c
 #define RAMFS_MAGIC            0x858458f6      /* some random number */
@@ -27,7 +26,6 @@
 #define HPFS_SUPER_MAGIC       0xf995e849
 #define ISOFS_SUPER_MAGIC      0x9660
 #define JFFS2_SUPER_MAGIC      0x72b6
-#define ANON_INODE_FS_MAGIC    0x09041934
 #define PSTOREFS_MAGIC         0x6165676C
 
 #define MINIX_SUPER_MAGIC      0x137F          /* minix v1 fs, 14 char names */
@@ -40,7 +38,6 @@
 #define NCP_SUPER_MAGIC                0x564c          /* Guess, what 0x564c is :-) */
 #define NFS_SUPER_MAGIC                0x6969
 #define OPENPROM_SUPER_MAGIC   0x9fa1
-#define PROC_SUPER_MAGIC       0x9fa0
 #define QNX4_SUPER_MAGIC       0x002f          /* qnx4 fs detection */
 #define QNX6_SUPER_MAGIC       0x68191122      /* qnx6 fs detection */
 
 #define REISER2FS_JR_SUPER_MAGIC_STRING        "ReIsEr3Fs"
 
 #define SMB_SUPER_MAGIC                0x517B
-#define USBDEVICE_SUPER_MAGIC  0x9fa2
 #define CGROUP_SUPER_MAGIC     0x27e0eb
 
-#define FUTEXFS_SUPER_MAGIC    0xBAD1DEA
 
 #define STACK_END_MAGIC                0x57AC6E9D
 
+#define V9FS_MAGIC             0x01021997
+
+#define BDEVFS_MAGIC            0x62646576
+#define BINFMTFS_MAGIC          0x42494e4d
 #define DEVPTS_SUPER_MAGIC     0x1cd1
+#define FUTEXFS_SUPER_MAGIC    0xBAD1DEA
+#define PIPEFS_MAGIC            0x50495045
+#define PROC_SUPER_MAGIC       0x9fa0
 #define SOCKFS_MAGIC           0x534F434B
-#define V9FS_MAGIC             0x01021997
+#define SYSFS_MAGIC            0x62656572
+#define USBDEVICE_SUPER_MAGIC  0x9fa2
+#define MTD_INODE_FS_MAGIC      0x11307854
+#define ANON_INODE_FS_MAGIC    0x09041934
+
 
 #endif /* __LINUX_MAGIC_H__ */
index 7330742..a6fabdf 100644 (file)
@@ -111,7 +111,7 @@ extern unsigned int kobjsize(const void *objp);
 #define VM_HUGEPAGE    0x01000000      /* MADV_HUGEPAGE marked this vma */
 #endif
 #define VM_INSERTPAGE  0x02000000      /* The vma has had "vm_insert_page()" done on it */
-#define VM_ALWAYSDUMP  0x04000000      /* Always include in core dumps */
+#define VM_NODUMP      0x04000000      /* Do not include in the core dump */
 
 #define VM_CAN_NONLINEAR 0x08000000    /* Has ->fault & does nonlinear pages */
 #define VM_MIXEDMAP    0x10000000      /* Can contain "struct page" and pure PFN pages */
index 8fa5bc5..1f5e689 100644 (file)
@@ -1,5 +1,8 @@
 #ifndef LINUX_MMC_IOCTL_H
 #define LINUX_MMC_IOCTL_H
+
+#include <linux/types.h>
+
 struct mmc_ioc_cmd {
        /* Implies direction of data.  true = write, false = read */
        int write_flag;
index 2d304ef..db50840 100644 (file)
@@ -14,7 +14,7 @@
  * may be used to reset the timeout - for code which intentionally
  * disables interrupts for a long time. This call is stateless.
  */
-#if defined(ARCH_HAS_NMI_WATCHDOG) || defined(CONFIG_HARDLOCKUP_DETECTOR)
+#if defined(CONFIG_HAVE_NMI_WATCHDOG) || defined(CONFIG_HARDLOCKUP_DETECTOR)
 #include <asm/nmi.h>
 extern void touch_nmi_watchdog(void);
 #else
index 77257c9..6d626ff 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef _LINUX_PIPE_FS_I_H
 #define _LINUX_PIPE_FS_I_H
 
-#define PIPEFS_MAGIC 0x50495045
-
 #define PIPE_DEF_BUFFERS       16
 
 #define PIPE_BUF_FLAG_LRU      0x01    /* page is on the LRU */
index cf40010..48fe8bc 100644 (file)
@@ -32,21 +32,46 @@ struct poll_table_struct;
  */
 typedef void (*poll_queue_proc)(struct file *, wait_queue_head_t *, struct poll_table_struct *);
 
+/*
+ * Do not touch the structure directly, use the access functions
+ * poll_does_not_wait() and poll_requested_events() instead.
+ */
 typedef struct poll_table_struct {
-       poll_queue_proc qproc;
-       unsigned long key;
+       poll_queue_proc _qproc;
+       unsigned long _key;
 } poll_table;
 
 static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
 {
-       if (p && wait_address)
-               p->qproc(filp, wait_address, p);
+       if (p && p->_qproc && wait_address)
+               p->_qproc(filp, wait_address, p);
+}
+
+/*
+ * Return true if it is guaranteed that poll will not wait. This is the case
+ * if the poll() of another file descriptor in the set got an event, so there
+ * is no need for waiting.
+ */
+static inline bool poll_does_not_wait(const poll_table *p)
+{
+       return p == NULL || p->_qproc == NULL;
+}
+
+/*
+ * Return the set of events that the application wants to poll for.
+ * This is useful for drivers that need to know whether a DMA transfer has
+ * to be started implicitly on poll(). You typically only want to do that
+ * if the application is actually polling for POLLIN and/or POLLOUT.
+ */
+static inline unsigned long poll_requested_events(const poll_table *p)
+{
+       return p ? p->_key : ~0UL;
 }
 
 static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc)
 {
-       pt->qproc = qproc;
-       pt->key   = ~0UL; /* all events enabled */
+       pt->_qproc = qproc;
+       pt->_key   = ~0UL; /* all events enabled */
 }
 
 struct poll_table_entry {
index a0413ac..e0cfec2 100644 (file)
 #define PR_SET_PTRACER 0x59616d61
 # define PR_SET_PTRACER_ANY ((unsigned long)-1)
 
+#define PR_SET_CHILD_SUBREAPER 36
+#define PR_GET_CHILD_SUBREAPER 37
+
 #endif /* _LINUX_PRCTL_H */
index c2f1f6a..407c678 100644 (file)
 #define PTRACE_INTERRUPT       0x4207
 #define PTRACE_LISTEN          0x4208
 
-/* flags in @data for PTRACE_SEIZE */
-#define PTRACE_SEIZE_DEVEL     0x80000000 /* temp flag for development */
-
-/* options set using PTRACE_SETOPTIONS */
-#define PTRACE_O_TRACESYSGOOD  0x00000001
-#define PTRACE_O_TRACEFORK     0x00000002
-#define PTRACE_O_TRACEVFORK    0x00000004
-#define PTRACE_O_TRACECLONE    0x00000008
-#define PTRACE_O_TRACEEXEC     0x00000010
-#define PTRACE_O_TRACEVFORKDONE        0x00000020
-#define PTRACE_O_TRACEEXIT     0x00000040
-
-#define PTRACE_O_MASK          0x0000007f
-
 /* Wait extended result codes for the above trace options.  */
 #define PTRACE_EVENT_FORK      1
 #define PTRACE_EVENT_VFORK     2
 #define PTRACE_EVENT_EXEC      4
 #define PTRACE_EVENT_VFORK_DONE        5
 #define PTRACE_EVENT_EXIT      6
-#define PTRACE_EVENT_STOP      7
+/* Extended result codes which enabled by means other than options.  */
+#define PTRACE_EVENT_STOP      128
+
+/* Options set using PTRACE_SETOPTIONS or using PTRACE_SEIZE @data param */
+#define PTRACE_O_TRACESYSGOOD  1
+#define PTRACE_O_TRACEFORK     (1 << PTRACE_EVENT_FORK)
+#define PTRACE_O_TRACEVFORK    (1 << PTRACE_EVENT_VFORK)
+#define PTRACE_O_TRACECLONE    (1 << PTRACE_EVENT_CLONE)
+#define PTRACE_O_TRACEEXEC     (1 << PTRACE_EVENT_EXEC)
+#define PTRACE_O_TRACEVFORKDONE        (1 << PTRACE_EVENT_VFORK_DONE)
+#define PTRACE_O_TRACEEXIT     (1 << PTRACE_EVENT_EXIT)
+
+#define PTRACE_O_MASK          0x0000007f
 
 #include <asm/ptrace.h>
 
 #define PT_SEIZED      0x00010000      /* SEIZE used, enable new behavior */
 #define PT_PTRACED     0x00000001
 #define PT_DTRACE      0x00000002      /* delayed trace (used on m68k, i386) */
-#define PT_TRACESYSGOOD        0x00000004
-#define PT_PTRACE_CAP  0x00000008      /* ptracer can follow suid-exec */
+#define PT_PTRACE_CAP  0x00000004      /* ptracer can follow suid-exec */
 
+#define PT_OPT_FLAG_SHIFT      3
 /* PT_TRACE_* event enable flags */
-#define PT_EVENT_FLAG_SHIFT    4
-#define PT_EVENT_FLAG(event)   (1 << (PT_EVENT_FLAG_SHIFT + (event) - 1))
-
+#define PT_EVENT_FLAG(event)   (1 << (PT_OPT_FLAG_SHIFT + (event)))
+#define PT_TRACESYSGOOD                PT_EVENT_FLAG(0)
 #define PT_TRACE_FORK          PT_EVENT_FLAG(PTRACE_EVENT_FORK)
 #define PT_TRACE_VFORK         PT_EVENT_FLAG(PTRACE_EVENT_VFORK)
 #define PT_TRACE_CLONE         PT_EVENT_FLAG(PTRACE_EVENT_CLONE)
 #define PT_TRACE_VFORK_DONE    PT_EVENT_FLAG(PTRACE_EVENT_VFORK_DONE)
 #define PT_TRACE_EXIT          PT_EVENT_FLAG(PTRACE_EVENT_EXIT)
 
-#define PT_TRACE_MASK  0x000003f4
-
 /* single stepping state bits (used on ARM and PA-RISC) */
 #define PT_SINGLESTEP_BIT      31
 #define PT_SINGLESTEP          (1<<PT_SINGLESTEP_BIT)
@@ -199,9 +194,10 @@ static inline void ptrace_event(int event, unsigned long message)
        if (unlikely(ptrace_event_enabled(current, event))) {
                current->ptrace_message = message;
                ptrace_notify((event << 8) | SIGTRAP);
-       } else if (event == PTRACE_EVENT_EXEC && unlikely(current->ptrace)) {
+       } else if (event == PTRACE_EVENT_EXEC) {
                /* legacy EXEC report via SIGTRAP */
-               send_sig(SIGTRAP, current, 0);
+               if ((current->ptrace & (PT_PTRACED|PT_SEIZED)) == PT_PTRACED)
+                       send_sig(SIGTRAP, current, 0);
        }
 }
 
index 9372174..2c62594 100644 (file)
@@ -418,7 +418,7 @@ extern int rcu_my_thread_group_empty(void);
  */
 #define rcu_lockdep_assert(c, s)                                       \
        do {                                                            \
-               static bool __warned;                                   \
+               static bool __section(.data.unlikely) __warned;         \
                if (debug_lockdep_rcu_enabled() && !__warned && !(c)) { \
                        __warned = true;                                \
                        lockdep_rcu_suspicious(__FILE__, __LINE__, s);  \
index 0c147a4..0c3854b 100644 (file)
@@ -553,6 +553,18 @@ struct signal_struct {
        int                     group_stop_count;
        unsigned int            flags; /* see SIGNAL_* flags below */
 
+       /*
+        * PR_SET_CHILD_SUBREAPER marks a process, like a service
+        * manager, to re-parent orphan (double-forking) child processes
+        * to this process instead of 'init'. The service manager is
+        * able to receive SIGCHLD signals and is able to investigate
+        * the process until it calls wait(). All children of this
+        * process will inherit a flag if they should look for a
+        * child_subreaper process at exit.
+        */
+       unsigned int            is_child_subreaper:1;
+       unsigned int            has_child_subreaper:1;
+
        /* POSIX.1b Interval Timers */
        struct list_head posix_timers;
 
index 44f1514..54e5ae7 100644 (file)
@@ -121,9 +121,12 @@ int single_release(struct inode *, struct file *);
 void *__seq_open_private(struct file *, const struct seq_operations *, int);
 int seq_open_private(struct file *, const struct seq_operations *, int);
 int seq_release_private(struct inode *, struct file *);
+int seq_put_decimal_ull(struct seq_file *m, char delimiter,
+                       unsigned long long num);
+int seq_put_decimal_ll(struct seq_file *m, char delimiter,
+                       long long num);
 
 #define SEQ_START_TOKEN ((void *)1)
-
 /*
  * Helpers for iteration over list_head-s in seq_files
  */
index a71a292..51bd91d 100644 (file)
@@ -54,12 +54,12 @@ struct linux_binprm;
 /*
  * ptrace report for syscall entry and exit looks identical.
  */
-static inline void ptrace_report_syscall(struct pt_regs *regs)
+static inline int ptrace_report_syscall(struct pt_regs *regs)
 {
        int ptrace = current->ptrace;
 
        if (!(ptrace & PT_PTRACED))
-               return;
+               return 0;
 
        ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
 
@@ -72,6 +72,8 @@ static inline void ptrace_report_syscall(struct pt_regs *regs)
                send_sig(current->exit_code, current, 1);
                current->exit_code = 0;
        }
+
+       return fatal_signal_pending(current);
 }
 
 /**
@@ -96,8 +98,7 @@ static inline void ptrace_report_syscall(struct pt_regs *regs)
 static inline __must_check int tracehook_report_syscall_entry(
        struct pt_regs *regs)
 {
-       ptrace_report_syscall(regs);
-       return 0;
+       return ptrace_report_syscall(regs);
 }
 
 /**
index 04bc0b3..a6ba1f8 100644 (file)
@@ -1854,7 +1854,7 @@ static inline bool wq_has_sleeper(struct socket_wq *wq)
 static inline void sock_poll_wait(struct file *filp,
                wait_queue_head_t *wait_address, poll_table *p)
 {
-       if (p && wait_address) {
+       if (!poll_does_not_wait(p) && wait_address) {
                poll_wait(filp, wait_address, p);
                /*
                 * We need to be sure we are in sync with the
index 58ce8fe..5cb20cc 100644 (file)
@@ -23,7 +23,7 @@
 #define SCSI_NETLINK_H
 
 #include <linux/netlink.h>
-
+#include <linux/types.h>
 
 /*
  * This file intended to be included by both kernel and user space
index d97d69f..da4a456 100644 (file)
@@ -51,6 +51,8 @@
 #ifndef __SND_COMPRESS_PARAMS_H
 #define __SND_COMPRESS_PARAMS_H
 
+#include <linux/types.h>
+
 /* AUDIO CODECS SUPPORTED */
 #define MAX_NUM_CODECS 32
 #define MAX_NUM_CODEC_DESCRIPTORS 32
index e8c599b..0a7515c 100644 (file)
@@ -139,9 +139,9 @@ int xenbus_transaction_start(struct xenbus_transaction *t);
 int xenbus_transaction_end(struct xenbus_transaction t, int abort);
 
 /* Single read and scanf: returns -errno or num scanned if > 0. */
+__scanf(4, 5)
 int xenbus_scanf(struct xenbus_transaction t,
-                const char *dir, const char *node, const char *fmt, ...)
-       __attribute__((format(scanf, 4, 5)));
+                const char *dir, const char *node, const char *fmt, ...);
 
 /* Single printf and write: returns -errno or 0. */
 __printf(4, 5)
index 5f117ca..fda0a7b 100644 (file)
@@ -267,7 +267,8 @@ void __cpuinit calibrate_delay(void)
 
        if (per_cpu(cpu_loops_per_jiffy, this_cpu)) {
                lpj = per_cpu(cpu_loops_per_jiffy, this_cpu);
-               pr_info("Calibrating delay loop (skipped) "
+               if (!printed)
+                       pr_info("Calibrating delay loop (skipped) "
                                "already calibrated this CPU");
        } else if (preset_lpj) {
                lpj = preset_lpj;
index 2974c8b..0e93f92 100644 (file)
@@ -373,8 +373,8 @@ retry:
 #ifdef CONFIG_BLOCK
                __bdevname(ROOT_DEV, b);
 #endif
-               printk("VFS: Cannot open root device \"%s\" or %s\n",
-                               root_device_name, b);
+               printk("VFS: Cannot open root device \"%s\" or %s: error %d\n",
+                               root_device_name, b, err);
                printk("Please append a correct \"root=\" boot option; here are the available partitions:\n");
 
                printk_all_partitions();
index 16b07bf..3db1909 100644 (file)
@@ -687,11 +687,11 @@ static void exit_mm(struct task_struct * tsk)
 }
 
 /*
- * When we die, we re-parent all our children.
- * Try to give them to another thread in our thread
- * group, and if no such member exists, give it to
- * the child reaper process (ie "init") in our pid
- * space.
+ * When we die, we re-parent all our children, and try to:
+ * 1. give them to another thread in our thread group, if such a member exists
+ * 2. give it to the first ancestor process which prctl'd itself as a
+ *    child_subreaper for its children (like a service manager)
+ * 3. give it to the init process (PID 1) in our pid namespace
  */
 static struct task_struct *find_new_reaper(struct task_struct *father)
        __releases(&tasklist_lock)
@@ -711,8 +711,11 @@ static struct task_struct *find_new_reaper(struct task_struct *father)
 
        if (unlikely(pid_ns->child_reaper == father)) {
                write_unlock_irq(&tasklist_lock);
-               if (unlikely(pid_ns == &init_pid_ns))
-                       panic("Attempted to kill init!");
+               if (unlikely(pid_ns == &init_pid_ns)) {
+                       panic("Attempted to kill init! exitcode=0x%08x\n",
+                               father->signal->group_exit_code ?:
+                                       father->exit_code);
+               }
 
                zap_pid_ns_processes(pid_ns);
                write_lock_irq(&tasklist_lock);
@@ -722,6 +725,29 @@ static struct task_struct *find_new_reaper(struct task_struct *father)
                 * forget_original_parent() must move them somewhere.
                 */
                pid_ns->child_reaper = init_pid_ns.child_reaper;
+       } else if (father->signal->has_child_subreaper) {
+               struct task_struct *reaper;
+
+               /*
+                * Find the first ancestor marked as child_subreaper.
+                * Note that the code below checks same_thread_group(reaper,
+                * pid_ns->child_reaper).  This is what we need to DTRT in a
+                * PID namespace. However we still need the check above, see
+                * http://marc.info/?l=linux-kernel&m=131385460420380
+                */
+               for (reaper = father->real_parent;
+                    reaper != &init_task;
+                    reaper = reaper->real_parent) {
+                       if (same_thread_group(reaper, pid_ns->child_reaper))
+                               break;
+                       if (!reaper->signal->is_child_subreaper)
+                               continue;
+                       thread = reaper;
+                       do {
+                               if (!(thread->flags & PF_EXITING))
+                                       return reaper;
+                       } while_each_thread(reaper, thread);
+               }
        }
 
        return pid_ns->child_reaper;
index 37674ec..b9372a0 100644 (file)
@@ -1051,6 +1051,9 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
        sig->oom_score_adj = current->signal->oom_score_adj;
        sig->oom_score_adj_min = current->signal->oom_score_adj_min;
 
+       sig->has_child_subreaper = current->signal->has_child_subreaper ||
+                                  current->signal->is_child_subreaper;
+
        mutex_init(&sig->cred_guard_mutex);
 
        return 0;
index a0a8854..957a7aa 100644 (file)
@@ -60,6 +60,43 @@ static DECLARE_RWSEM(umhelper_sem);
 */
 char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
 
+static void free_modprobe_argv(struct subprocess_info *info)
+{
+       kfree(info->argv[3]); /* check call_modprobe() */
+       kfree(info->argv);
+}
+
+static int call_modprobe(char *module_name, int wait)
+{
+       static char *envp[] = {
+               "HOME=/",
+               "TERM=linux",
+               "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
+               NULL
+       };
+
+       char **argv = kmalloc(sizeof(char *[5]), GFP_KERNEL);
+       if (!argv)
+               goto out;
+
+       module_name = kstrdup(module_name, GFP_KERNEL);
+       if (!module_name)
+               goto free_argv;
+
+       argv[0] = modprobe_path;
+       argv[1] = "-q";
+       argv[2] = "--";
+       argv[3] = module_name;  /* check free_modprobe_argv() */
+       argv[4] = NULL;
+
+       return call_usermodehelper_fns(modprobe_path, argv, envp,
+               wait | UMH_KILLABLE, NULL, free_modprobe_argv, NULL);
+free_argv:
+       kfree(argv);
+out:
+       return -ENOMEM;
+}
+
 /**
  * __request_module - try to load a kernel module
  * @wait: wait (or not) for the operation to complete
@@ -81,11 +118,6 @@ int __request_module(bool wait, const char *fmt, ...)
        char module_name[MODULE_NAME_LEN];
        unsigned int max_modprobes;
        int ret;
-       char *argv[] = { modprobe_path, "-q", "--", module_name, NULL };
-       static char *envp[] = { "HOME=/",
-                               "TERM=linux",
-                               "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
-                               NULL };
        static atomic_t kmod_concurrent = ATOMIC_INIT(0);
 #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */
        static int kmod_loop_msg;
@@ -128,9 +160,7 @@ int __request_module(bool wait, const char *fmt, ...)
 
        trace_module_request(module_name, wait, _RET_IP_);
 
-       ret = call_usermodehelper_fns(modprobe_path, argv, envp,
-                       wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC,
-                       NULL, NULL, NULL);
+       ret = call_modprobe(module_name, wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC);
 
        atomic_dec(&kmod_concurrent);
        return ret;
@@ -188,7 +218,7 @@ static int ____call_usermodehelper(void *data)
        /* Exec failed? */
 fail:
        sub_info->retval = retval;
-       do_exit(0);
+       return 0;
 }
 
 void call_usermodehelper_freeinfo(struct subprocess_info *info)
@@ -199,6 +229,19 @@ void call_usermodehelper_freeinfo(struct subprocess_info *info)
 }
 EXPORT_SYMBOL(call_usermodehelper_freeinfo);
 
+static void umh_complete(struct subprocess_info *sub_info)
+{
+       struct completion *comp = xchg(&sub_info->complete, NULL);
+       /*
+        * See call_usermodehelper_exec(). If xchg() returns NULL
+        * we own sub_info, the UMH_KILLABLE caller has gone away.
+        */
+       if (comp)
+               complete(comp);
+       else
+               call_usermodehelper_freeinfo(sub_info);
+}
+
 /* Keventd can't block, but this (a child) can. */
 static int wait_for_helper(void *data)
 {
@@ -235,7 +278,7 @@ static int wait_for_helper(void *data)
                        sub_info->retval = ret;
        }
 
-       complete(sub_info->complete);
+       umh_complete(sub_info);
        return 0;
 }
 
@@ -244,7 +287,7 @@ static void __call_usermodehelper(struct work_struct *work)
 {
        struct subprocess_info *sub_info =
                container_of(work, struct subprocess_info, work);
-       enum umh_wait wait = sub_info->wait;
+       int wait = sub_info->wait & ~UMH_KILLABLE;
        pid_t pid;
 
        /* CLONE_VFORK: wait until the usermode helper has execve'd
@@ -269,7 +312,7 @@ static void __call_usermodehelper(struct work_struct *work)
        case UMH_WAIT_EXEC:
                if (pid < 0)
                        sub_info->retval = pid;
-               complete(sub_info->complete);
+               umh_complete(sub_info);
        }
 }
 
@@ -435,8 +478,7 @@ EXPORT_SYMBOL(call_usermodehelper_setfns);
  * asynchronously if wait is not set, and runs as a child of keventd.
  * (ie. it runs with full root capabilities).
  */
-int call_usermodehelper_exec(struct subprocess_info *sub_info,
-                            enum umh_wait wait)
+int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait)
 {
        DECLARE_COMPLETION_ONSTACK(done);
        int retval = 0;
@@ -456,9 +498,21 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
        queue_work(khelper_wq, &sub_info->work);
        if (wait == UMH_NO_WAIT)        /* task has freed sub_info */
                goto unlock;
+
+       if (wait & UMH_KILLABLE) {
+               retval = wait_for_completion_killable(&done);
+               if (!retval)
+                       goto wait_done;
+
+               /* umh_complete() will see NULL and free sub_info */
+               if (xchg(&sub_info->complete, NULL))
+                       goto unlock;
+               /* fallthrough, umh_complete() was already called */
+       }
+
        wait_for_completion(&done);
+wait_done:
        retval = sub_info->retval;
-
 out:
        call_usermodehelper_freeinfo(sub_info);
 unlock:
index a896839..17b2328 100644 (file)
@@ -168,13 +168,9 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)
        while (nr > 0) {
                rcu_read_lock();
 
-               /*
-                * Any nested-container's init processes won't ignore the
-                * SEND_SIG_NOINFO signal, see send_signal()->si_fromuser().
-                */
                task = pid_task(find_vpid(nr), PIDTYPE_PID);
-               if (task)
-                       send_sig_info(SIGKILL, SEND_SIG_NOINFO, task);
+               if (task && !__fatal_signal_pending(task))
+                       send_sig_info(SIGKILL, SEND_SIG_FORCED, task);
 
                rcu_read_unlock();
 
index 00ab2ca..ee8d49b 100644 (file)
@@ -231,26 +231,22 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode)
 }
 
 static int ptrace_attach(struct task_struct *task, long request,
+                        unsigned long addr,
                         unsigned long flags)
 {
        bool seize = (request == PTRACE_SEIZE);
        int retval;
 
-       /*
-        * SEIZE will enable new ptrace behaviors which will be implemented
-        * gradually.  SEIZE_DEVEL is used to prevent applications
-        * expecting full SEIZE behaviors trapping on kernel commits which
-        * are still in the process of implementing them.
-        *
-        * Only test programs for new ptrace behaviors being implemented
-        * should set SEIZE_DEVEL.  If unset, SEIZE will fail with -EIO.
-        *
-        * Once SEIZE behaviors are completely implemented, this flag and
-        * the following test will be removed.
-        */
        retval = -EIO;
-       if (seize && !(flags & PTRACE_SEIZE_DEVEL))
-               goto out;
+       if (seize) {
+               if (addr != 0)
+                       goto out;
+               if (flags & ~(unsigned long)PTRACE_O_MASK)
+                       goto out;
+               flags = PT_PTRACED | PT_SEIZED | (flags << PT_OPT_FLAG_SHIFT);
+       } else {
+               flags = PT_PTRACED;
+       }
 
        audit_ptrace(task);
 
@@ -262,7 +258,7 @@ static int ptrace_attach(struct task_struct *task, long request,
 
        /*
         * Protect exec's credential calculations against our interference;
-        * interference; SUID, SGID and LSM creds get determined differently
+        * SUID, SGID and LSM creds get determined differently
         * under ptrace.
         */
        retval = -ERESTARTNOINTR;
@@ -282,11 +278,11 @@ static int ptrace_attach(struct task_struct *task, long request,
        if (task->ptrace)
                goto unlock_tasklist;
 
-       task->ptrace = PT_PTRACED;
        if (seize)
-               task->ptrace |= PT_SEIZED;
+               flags |= PT_SEIZED;
        if (ns_capable(task_user_ns(task), CAP_SYS_PTRACE))
-               task->ptrace |= PT_PTRACE_CAP;
+               flags |= PT_PTRACE_CAP;
+       task->ptrace = flags;
 
        __ptrace_link(task, current);
 
@@ -528,30 +524,18 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds
 
 static int ptrace_setoptions(struct task_struct *child, unsigned long data)
 {
-       child->ptrace &= ~PT_TRACE_MASK;
+       unsigned flags;
 
-       if (data & PTRACE_O_TRACESYSGOOD)
-               child->ptrace |= PT_TRACESYSGOOD;
-
-       if (data & PTRACE_O_TRACEFORK)
-               child->ptrace |= PT_TRACE_FORK;
-
-       if (data & PTRACE_O_TRACEVFORK)
-               child->ptrace |= PT_TRACE_VFORK;
-
-       if (data & PTRACE_O_TRACECLONE)
-               child->ptrace |= PT_TRACE_CLONE;
-
-       if (data & PTRACE_O_TRACEEXEC)
-               child->ptrace |= PT_TRACE_EXEC;
-
-       if (data & PTRACE_O_TRACEVFORKDONE)
-               child->ptrace |= PT_TRACE_VFORK_DONE;
+       if (data & ~(unsigned long)PTRACE_O_MASK)
+               return -EINVAL;
 
-       if (data & PTRACE_O_TRACEEXIT)
-               child->ptrace |= PT_TRACE_EXIT;
+       /* Avoid intermediate state when all opts are cleared */
+       flags = child->ptrace;
+       flags &= ~(PTRACE_O_MASK << PT_OPT_FLAG_SHIFT);
+       flags |= (data << PT_OPT_FLAG_SHIFT);
+       child->ptrace = flags;
 
-       return (data & ~PTRACE_O_MASK) ? -EINVAL : 0;
+       return 0;
 }
 
 static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info)
@@ -891,7 +875,7 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
        }
 
        if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) {
-               ret = ptrace_attach(child, request, data);
+               ret = ptrace_attach(child, request, addr, data);
                /*
                 * Some architectures need to do book-keeping after
                 * a ptrace attach.
@@ -1034,7 +1018,7 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
        }
 
        if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) {
-               ret = ptrace_attach(child, request, data);
+               ret = ptrace_attach(child, request, addr, data);
                /*
                 * Some architectures need to do book-keeping after
                 * a ptrace attach.
index e76001c..d523da0 100644 (file)
@@ -58,21 +58,20 @@ static int sig_handler_ignored(void __user *handler, int sig)
                (handler == SIG_DFL && sig_kernel_ignore(sig));
 }
 
-static int sig_task_ignored(struct task_struct *t, int sig,
-               int from_ancestor_ns)
+static int sig_task_ignored(struct task_struct *t, int sig, bool force)
 {
        void __user *handler;
 
        handler = sig_handler(t, sig);
 
        if (unlikely(t->signal->flags & SIGNAL_UNKILLABLE) &&
-                       handler == SIG_DFL && !from_ancestor_ns)
+                       handler == SIG_DFL && !force)
                return 1;
 
        return sig_handler_ignored(handler, sig);
 }
 
-static int sig_ignored(struct task_struct *t, int sig, int from_ancestor_ns)
+static int sig_ignored(struct task_struct *t, int sig, bool force)
 {
        /*
         * Blocked signals are never ignored, since the
@@ -82,7 +81,7 @@ static int sig_ignored(struct task_struct *t, int sig, int from_ancestor_ns)
        if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig))
                return 0;
 
-       if (!sig_task_ignored(t, sig, from_ancestor_ns))
+       if (!sig_task_ignored(t, sig, force))
                return 0;
 
        /*
@@ -855,7 +854,7 @@ static void ptrace_trap_notify(struct task_struct *t)
  * Returns true if the signal should be actually delivered, otherwise
  * it should be dropped.
  */
-static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns)
+static int prepare_signal(int sig, struct task_struct *p, bool force)
 {
        struct signal_struct *signal = p->signal;
        struct task_struct *t;
@@ -915,7 +914,7 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns)
                }
        }
 
-       return !sig_ignored(p, sig, from_ancestor_ns);
+       return !sig_ignored(p, sig, force);
 }
 
 /*
@@ -1059,7 +1058,8 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
        assert_spin_locked(&t->sighand->siglock);
 
        result = TRACE_SIGNAL_IGNORED;
-       if (!prepare_signal(sig, t, from_ancestor_ns))
+       if (!prepare_signal(sig, t,
+                       from_ancestor_ns || (info == SEND_SIG_FORCED)))
                goto ret;
 
        pending = group ? &t->signal->shared_pending : &t->pending;
@@ -1601,7 +1601,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
 
        ret = 1; /* the signal is ignored */
        result = TRACE_SIGNAL_IGNORED;
-       if (!prepare_signal(sig, t, 0))
+       if (!prepare_signal(sig, t, false))
                goto out;
 
        ret = 0;
index 888d227..9eb7fca 100644 (file)
@@ -1962,6 +1962,14 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
                case PR_SET_MM:
                        error = prctl_set_mm(arg2, arg3, arg4, arg5);
                        break;
+               case PR_SET_CHILD_SUBREAPER:
+                       me->signal->is_child_subreaper = !!arg2;
+                       error = 0;
+                       break;
+               case PR_GET_CHILD_SUBREAPER:
+                       error = put_user(me->signal->is_child_subreaper,
+                                        (int __user *) arg2);
+                       break;
                default:
                        error = -EINVAL;
                        break;
index 14bc092..df30ee0 100644 (file)
@@ -9,6 +9,8 @@
  * to those contributors as well.
  */
 
+#define pr_fmt(fmt) "NMI watchdog: " fmt
+
 #include <linux/mm.h>
 #include <linux/cpu.h>
 #include <linux/nmi.h>
@@ -319,11 +321,9 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
  */
 static int watchdog(void *unused)
 {
-       struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
+       struct sched_param param = { .sched_priority = 0 };
        struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer);
 
-       sched_setscheduler(current, SCHED_FIFO, &param);
-
        /* initialize timestamp */
        __touch_watchdog();
 
@@ -349,8 +349,11 @@ static int watchdog(void *unused)
 
                set_current_state(TASK_INTERRUPTIBLE);
        }
+       /*
+        * Drop the policy/priority elevation during thread exit to avoid a
+        * scheduling latency spike.
+        */
        __set_current_state(TASK_RUNNING);
-       param.sched_priority = 0;
        sched_setscheduler(current, SCHED_NORMAL, &param);
        return 0;
 }
@@ -376,18 +379,20 @@ static int watchdog_nmi_enable(int cpu)
        /* Try to register using hardware perf events */
        event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL);
        if (!IS_ERR(event)) {
-               printk(KERN_INFO "NMI watchdog enabled, takes one hw-pmu counter.\n");
+               pr_info("enabled, takes one hw-pmu counter.\n");
                goto out_save;
        }
 
 
        /* vary the KERN level based on the returned errno */
        if (PTR_ERR(event) == -EOPNOTSUPP)
-               printk(KERN_INFO "NMI watchdog disabled (cpu%i): not supported (no LAPIC?)\n", cpu);
+               pr_info("disabled (cpu%i): not supported (no LAPIC?)\n", cpu);
        else if (PTR_ERR(event) == -ENOENT)
-               printk(KERN_WARNING "NMI watchdog disabled (cpu%i): hardware events not enabled\n", cpu);
+               pr_warning("disabled (cpu%i): hardware events not enabled\n",
+                        cpu);
        else
-               printk(KERN_ERR "NMI watchdog disabled (cpu%i): unable to create perf event: %ld\n", cpu, PTR_ERR(event));
+               pr_err("disabled (cpu%i): unable to create perf event: %ld\n",
+                       cpu, PTR_ERR(event));
        return PTR_ERR(event);
 
        /* success path */
@@ -439,9 +444,10 @@ static int watchdog_enable(int cpu)
 
        /* create the watchdog thread */
        if (!p) {
+               struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
                p = kthread_create_on_node(watchdog, NULL, cpu_to_node(cpu), "watchdog/%d", cpu);
                if (IS_ERR(p)) {
-                       printk(KERN_ERR "softlockup watchdog for %i failed\n", cpu);
+                       pr_err("softlockup watchdog for %i failed\n", cpu);
                        if (!err) {
                                /* if hardlockup hasn't already set this */
                                err = PTR_ERR(p);
@@ -450,6 +456,7 @@ static int watchdog_enable(int cpu)
                        }
                        goto out;
                }
+               sched_setscheduler(p, SCHED_FIFO, &param);
                kthread_bind(p, cpu);
                per_cpu(watchdog_touch_ts, cpu) = 0;
                per_cpu(softlockup_watchdog, cpu) = p;
@@ -496,7 +503,7 @@ static void watchdog_enable_all_cpus(void)
                        watchdog_enabled = 1;
 
        if (!watchdog_enabled)
-               printk(KERN_ERR "watchdog: failed to be enabled on some cpus\n");
+               pr_err("failed to be enabled on some cpus\n");
 
 }
 
index 028aba9..43359bb 100644 (file)
@@ -61,14 +61,67 @@ config CRC_ITU_T
          functions require M here.
 
 config CRC32
-       tristate "CRC32 functions"
+       tristate "CRC32/CRC32c functions"
        default y
        select BITREVERSE
        help
          This option is provided for the case where no in-kernel-tree
-         modules require CRC32 functions, but a module built outside the
-         kernel tree does. Such modules that use library CRC32 functions
-         require M here.
+         modules require CRC32/CRC32c functions, but a module built outside
+         the kernel tree does. Such modules that use library CRC32/CRC32c
+         functions require M here.
+
+config CRC32_SELFTEST
+       bool "CRC32 perform self test on init"
+       default n
+       depends on CRC32
+       help
+         This option enables the CRC32 library functions to perform a
+         self test on initialization. The self test computes crc32_le
+         and crc32_be over byte strings with random alignment and length
+         and computes the total elapsed time and number of bytes processed.
+
+choice
+       prompt "CRC32 implementation"
+       depends on CRC32
+       default CRC32_SLICEBY8
+
+config CRC32_SLICEBY8
+       bool "Slice by 8 bytes"
+       help
+         Calculate checksum 8 bytes at a time with a clever slicing algorithm.
+         This is the fastest algorithm, but comes with a 8KiB lookup table.
+         Most modern processors have enough cache to hold this table without
+         thrashing the cache.
+
+         This is the default implementation choice.  Choose this one unless
+         you have a good reason not to.
+
+config CRC32_SLICEBY4
+       bool "Slice by 4 bytes"
+       help
+         Calculate checksum 4 bytes at a time with a clever slicing algorithm.
+         This is a bit slower than slice by 8, but has a smaller 4KiB lookup
+         table.
+
+         Only choose this option if you know what you are doing.
+
+config CRC32_SARWATE
+       bool "Sarwate's Algorithm (one byte at a time)"
+       help
+         Calculate checksum a byte at a time using Sarwate's algorithm.  This
+         is not particularly fast, but has a small 256 byte lookup table.
+
+         Only choose this option if you know what you are doing.
+
+config CRC32_BIT
+       bool "Classic Algorithm (one bit at a time)"
+       help
+         Calculate checksum one bit at a time.  This is VERY slow, but has
+         no lookup table.  This is provided as a debugging option.
+
+         Only choose this option if you are debugging crc32.
+
+endchoice
 
 config CRC7
        tristate "CRC7 functions"
index 05037dc..391003f 100644 (file)
@@ -184,7 +184,7 @@ config LOCKUP_DETECTOR
 
 config HARDLOCKUP_DETECTOR
        def_bool LOCKUP_DETECTOR && PERF_EVENTS && HAVE_PERF_EVENTS_NMI && \
-                !ARCH_HAS_NMI_WATCHDOG
+                !HAVE_NMI_WATCHDOG
 
 config BOOTPARAM_HARDLOCKUP_PANIC
        bool "Panic (Reboot) On Hard Lockups"
index 4b35d2b..b0d278f 100644 (file)
@@ -1,4 +1,8 @@
 /*
+ * Aug 8, 2011 Bob Pearson with help from Joakim Tjernlund and George Spelvin
+ * cleaned up code to current version of sparse and added the slicing-by-8
+ * algorithm to the closely similar existing slicing-by-4 algorithm.
+ *
  * Oct 15, 2000 Matt Domsch <Matt_Domsch@dell.com>
  * Nicer crc32 functions/docs submitted by linux@horizon.com.  Thanks!
  * Code was from the public domain, copyright abandoned.  Code was
  * Version 2.  See the file COPYING for more details.
  */
 
+/* see: Documentation/crc32.txt for a description of algorithms */
+
 #include <linux/crc32.h>
-#include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/compiler.h>
 #include <linux/types.h>
-#include <linux/init.h>
-#include <linux/atomic.h>
 #include "crc32defs.h"
-#if CRC_LE_BITS == 8
-# define tole(x) __constant_cpu_to_le32(x)
+
+#if CRC_LE_BITS > 8
+# define tole(x) ((__force u32) __constant_cpu_to_le32(x))
 #else
 # define tole(x) (x)
 #endif
 
-#if CRC_BE_BITS == 8
-# define tobe(x) __constant_cpu_to_be32(x)
+#if CRC_BE_BITS > 8
+# define tobe(x) ((__force u32) __constant_cpu_to_be32(x))
 #else
 # define tobe(x) (x)
 #endif
+
 #include "crc32table.h"
 
 MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>");
-MODULE_DESCRIPTION("Ethernet CRC32 calculations");
+MODULE_DESCRIPTION("Various CRC32 calculations");
 MODULE_LICENSE("GPL");
 
-#if CRC_LE_BITS == 8 || CRC_BE_BITS == 8
+#if CRC_LE_BITS > 8 || CRC_BE_BITS > 8
 
+/* implements slicing-by-4 or slicing-by-8 algorithm */
 static inline u32
 crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256])
 {
 # ifdef __LITTLE_ENDIAN
 #  define DO_CRC(x) crc = t0[(crc ^ (x)) & 255] ^ (crc >> 8)
-#  define DO_CRC4 crc = t3[(crc) & 255] ^ \
-               t2[(crc >> 8) & 255] ^ \
-               t1[(crc >> 16) & 255] ^ \
-               t0[(crc >> 24) & 255]
+#  define DO_CRC4 (t3[(q) & 255] ^ t2[(q >> 8) & 255] ^ \
+                  t1[(q >> 16) & 255] ^ t0[(q >> 24) & 255])
+#  define DO_CRC8 (t7[(q) & 255] ^ t6[(q >> 8) & 255] ^ \
+                  t5[(q >> 16) & 255] ^ t4[(q >> 24) & 255])
 # else
 #  define DO_CRC(x) crc = t0[((crc >> 24) ^ (x)) & 255] ^ (crc << 8)
-#  define DO_CRC4 crc = t0[(crc) & 255] ^ \
-               t1[(crc >> 8) & 255] ^  \
-               t2[(crc >> 16) & 255] ^ \
-               t3[(crc >> 24) & 255]
+#  define DO_CRC4 (t0[(q) & 255] ^ t1[(q >> 8) & 255] ^ \
+                  t2[(q >> 16) & 255] ^ t3[(q >> 24) & 255])
+#  define DO_CRC8 (t4[(q) & 255] ^ t5[(q >> 8) & 255] ^ \
+                  t6[(q >> 16) & 255] ^ t7[(q >> 24) & 255])
 # endif
        const u32 *b;
        size_t    rem_len;
+# ifdef CONFIG_X86
+       size_t i;
+# endif
        const u32 *t0=tab[0], *t1=tab[1], *t2=tab[2], *t3=tab[3];
+       const u32 *t4 = tab[4], *t5 = tab[5], *t6 = tab[6], *t7 = tab[7];
+       u32 q;
 
        /* Align it */
        if (unlikely((long)buf & 3 && len)) {
@@ -73,27 +83,51 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256])
                        DO_CRC(*buf++);
                } while ((--len) && ((long)buf)&3);
        }
+
+# if CRC_LE_BITS == 32
        rem_len = len & 3;
-       /* load data 32 bits wide, xor data 32 bits wide. */
        len = len >> 2;
+# else
+       rem_len = len & 7;
+       len = len >> 3;
+# endif
+
        b = (const u32 *)buf;
+# ifdef CONFIG_X86
+       --b;
+       for (i = 0; i < len; i++) {
+# else
        for (--b; len; --len) {
-               crc ^= *++b; /* use pre increment for speed */
-               DO_CRC4;
+# endif
+               q = crc ^ *++b; /* use pre increment for speed */
+# if CRC_LE_BITS == 32
+               crc = DO_CRC4;
+# else
+               crc = DO_CRC8;
+               q = *++b;
+               crc ^= DO_CRC4;
+# endif
        }
        len = rem_len;
        /* And the last few bytes */
        if (len) {
                u8 *p = (u8 *)(b + 1) - 1;
+# ifdef CONFIG_X86
+               for (i = 0; i < len; i++)
+                       DO_CRC(*++p); /* use pre increment for speed */
+# else
                do {
                        DO_CRC(*++p); /* use pre increment for speed */
                } while (--len);
+# endif
        }
        return crc;
 #undef DO_CRC
 #undef DO_CRC4
+#undef DO_CRC8
 }
 #endif
+
 /**
  * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32
  * @crc: seed value for computation.  ~0 for Ethernet, sometimes 0 for
@@ -101,53 +135,66 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256])
  * @p: pointer to buffer over which CRC is run
  * @len: length of buffer @p
  */
-u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len);
-
-#if CRC_LE_BITS == 1
-/*
- * In fact, the table-based code will work in this case, but it can be
- * simplified by inlining the table in ?: form.
- */
-
-u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
+static inline u32 __pure crc32_le_generic(u32 crc, unsigned char const *p,
+                                         size_t len, const u32 (*tab)[256],
+                                         u32 polynomial)
 {
+#if CRC_LE_BITS == 1
        int i;
        while (len--) {
                crc ^= *p++;
                for (i = 0; i < 8; i++)
-                       crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
+                       crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0);
+       }
+# elif CRC_LE_BITS == 2
+       while (len--) {
+               crc ^= *p++;
+               crc = (crc >> 2) ^ tab[0][crc & 3];
+               crc = (crc >> 2) ^ tab[0][crc & 3];
+               crc = (crc >> 2) ^ tab[0][crc & 3];
+               crc = (crc >> 2) ^ tab[0][crc & 3];
        }
-       return crc;
-}
-#else                          /* Table-based approach */
-
-u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
-{
-# if CRC_LE_BITS == 8
-       const u32      (*tab)[] = crc32table_le;
-
-       crc = __cpu_to_le32(crc);
-       crc = crc32_body(crc, p, len, tab);
-       return __le32_to_cpu(crc);
 # elif CRC_LE_BITS == 4
        while (len--) {
                crc ^= *p++;
-               crc = (crc >> 4) ^ crc32table_le[crc & 15];
-               crc = (crc >> 4) ^ crc32table_le[crc & 15];
+               crc = (crc >> 4) ^ tab[0][crc & 15];
+               crc = (crc >> 4) ^ tab[0][crc & 15];
        }
-       return crc;
-# elif CRC_LE_BITS == 2
+# elif CRC_LE_BITS == 8
+       /* aka Sarwate algorithm */
        while (len--) {
                crc ^= *p++;
-               crc = (crc >> 2) ^ crc32table_le[crc & 3];
-               crc = (crc >> 2) ^ crc32table_le[crc & 3];
-               crc = (crc >> 2) ^ crc32table_le[crc & 3];
-               crc = (crc >> 2) ^ crc32table_le[crc & 3];
+               crc = (crc >> 8) ^ tab[0][crc & 255];
        }
+# else
+       crc = (__force u32) __cpu_to_le32(crc);
+       crc = crc32_body(crc, p, len, tab);
+       crc = __le32_to_cpu((__force __le32)crc);
+#endif
        return crc;
-# endif
+}
+
+#if CRC_LE_BITS == 1
+u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
+{
+       return crc32_le_generic(crc, p, len, NULL, CRCPOLY_LE);
+}
+u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
+{
+       return crc32_le_generic(crc, p, len, NULL, CRC32C_POLY_LE);
+}
+#else
+u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
+{
+       return crc32_le_generic(crc, p, len, crc32table_le, CRCPOLY_LE);
+}
+u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
+{
+       return crc32_le_generic(crc, p, len, crc32ctable_le, CRC32C_POLY_LE);
 }
 #endif
+EXPORT_SYMBOL(crc32_le);
+EXPORT_SYMBOL(__crc32c_le);
 
 /**
  * crc32_be() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32
@@ -156,317 +203,913 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
  * @p: pointer to buffer over which CRC is run
  * @len: length of buffer @p
  */
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len);
-
-#if CRC_BE_BITS == 1
-/*
- * In fact, the table-based code will work in this case, but it can be
- * simplified by inlining the table in ?: form.
- */
-
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+static inline u32 __pure crc32_be_generic(u32 crc, unsigned char const *p,
+                                         size_t len, const u32 (*tab)[256],
+                                         u32 polynomial)
 {
+#if CRC_BE_BITS == 1
        int i;
        while (len--) {
                crc ^= *p++ << 24;
                for (i = 0; i < 8; i++)
                        crc =
-                           (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE :
+                           (crc << 1) ^ ((crc & 0x80000000) ? polynomial :
                                          0);
        }
-       return crc;
-}
-
-#else                          /* Table-based approach */
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
-{
-# if CRC_BE_BITS == 8
-       const u32      (*tab)[] = crc32table_be;
-
-       crc = __cpu_to_be32(crc);
-       crc = crc32_body(crc, p, len, tab);
-       return __be32_to_cpu(crc);
+# elif CRC_BE_BITS == 2
+       while (len--) {
+               crc ^= *p++ << 24;
+               crc = (crc << 2) ^ tab[0][crc >> 30];
+               crc = (crc << 2) ^ tab[0][crc >> 30];
+               crc = (crc << 2) ^ tab[0][crc >> 30];
+               crc = (crc << 2) ^ tab[0][crc >> 30];
+       }
 # elif CRC_BE_BITS == 4
        while (len--) {
                crc ^= *p++ << 24;
-               crc = (crc << 4) ^ crc32table_be[crc >> 28];
-               crc = (crc << 4) ^ crc32table_be[crc >> 28];
+               crc = (crc << 4) ^ tab[0][crc >> 28];
+               crc = (crc << 4) ^ tab[0][crc >> 28];
        }
-       return crc;
-# elif CRC_BE_BITS == 2
+# elif CRC_BE_BITS == 8
        while (len--) {
                crc ^= *p++ << 24;
-               crc = (crc << 2) ^ crc32table_be[crc >> 30];
-               crc = (crc << 2) ^ crc32table_be[crc >> 30];
-               crc = (crc << 2) ^ crc32table_be[crc >> 30];
-               crc = (crc << 2) ^ crc32table_be[crc >> 30];
+               crc = (crc << 8) ^ tab[0][crc >> 24];
        }
-       return crc;
+# else
+       crc = (__force u32) __cpu_to_be32(crc);
+       crc = crc32_body(crc, p, len, tab);
+       crc = __be32_to_cpu((__force __be32)crc);
 # endif
+       return crc;
 }
-#endif
 
-EXPORT_SYMBOL(crc32_le);
+#if CRC_LE_BITS == 1
+u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+{
+       return crc32_be_generic(crc, p, len, NULL, CRCPOLY_BE);
+}
+#else
+u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+{
+       return crc32_be_generic(crc, p, len, crc32table_be, CRCPOLY_BE);
+}
+#endif
 EXPORT_SYMBOL(crc32_be);
 
-/*
- * A brief CRC tutorial.
- *
- * A CRC is a long-division remainder.  You add the CRC to the message,
- * and the whole thing (message+CRC) is a multiple of the given
- * CRC polynomial.  To check the CRC, you can either check that the
- * CRC matches the recomputed value, *or* you can check that the
- * remainder computed on the message+CRC is 0.  This latter approach
- * is used by a lot of hardware implementations, and is why so many
- * protocols put the end-of-frame flag after the CRC.
- *
- * It's actually the same long division you learned in school, except that
- * - We're working in binary, so the digits are only 0 and 1, and
- * - When dividing polynomials, there are no carries.  Rather than add and
- *   subtract, we just xor.  Thus, we tend to get a bit sloppy about
- *   the difference between adding and subtracting.
- *
- * A 32-bit CRC polynomial is actually 33 bits long.  But since it's
- * 33 bits long, bit 32 is always going to be set, so usually the CRC
- * is written in hex with the most significant bit omitted.  (If you're
- * familiar with the IEEE 754 floating-point format, it's the same idea.)
- *
- * Note that a CRC is computed over a string of *bits*, so you have
- * to decide on the endianness of the bits within each byte.  To get
- * the best error-detecting properties, this should correspond to the
- * order they're actually sent.  For example, standard RS-232 serial is
- * little-endian; the most significant bit (sometimes used for parity)
- * is sent last.  And when appending a CRC word to a message, you should
- * do it in the right order, matching the endianness.
- *
- * Just like with ordinary division, the remainder is always smaller than
- * the divisor (the CRC polynomial) you're dividing by.  Each step of the
- * division, you take one more digit (bit) of the dividend and append it
- * to the current remainder.  Then you figure out the appropriate multiple
- * of the divisor to subtract to being the remainder back into range.
- * In binary, it's easy - it has to be either 0 or 1, and to make the
- * XOR cancel, it's just a copy of bit 32 of the remainder.
- *
- * When computing a CRC, we don't care about the quotient, so we can
- * throw the quotient bit away, but subtract the appropriate multiple of
- * the polynomial from the remainder and we're back to where we started,
- * ready to process the next bit.
- *
- * A big-endian CRC written this way would be coded like:
- * for (i = 0; i < input_bits; i++) {
- *     multiple = remainder & 0x80000000 ? CRCPOLY : 0;
- *     remainder = (remainder << 1 | next_input_bit()) ^ multiple;
- * }
- * Notice how, to get at bit 32 of the shifted remainder, we look
- * at bit 31 of the remainder *before* shifting it.
- *
- * But also notice how the next_input_bit() bits we're shifting into
- * the remainder don't actually affect any decision-making until
- * 32 bits later.  Thus, the first 32 cycles of this are pretty boring.
- * Also, to add the CRC to a message, we need a 32-bit-long hole for it at
- * the end, so we have to add 32 extra cycles shifting in zeros at the
- * end of every message,
- *
- * So the standard trick is to rearrage merging in the next_input_bit()
- * until the moment it's needed.  Then the first 32 cycles can be precomputed,
- * and merging in the final 32 zero bits to make room for the CRC can be
- * skipped entirely.
- * This changes the code to:
- * for (i = 0; i < input_bits; i++) {
- *      remainder ^= next_input_bit() << 31;
- *     multiple = (remainder & 0x80000000) ? CRCPOLY : 0;
- *     remainder = (remainder << 1) ^ multiple;
- * }
- * With this optimization, the little-endian code is simpler:
- * for (i = 0; i < input_bits; i++) {
- *      remainder ^= next_input_bit();
- *     multiple = (remainder & 1) ? CRCPOLY : 0;
- *     remainder = (remainder >> 1) ^ multiple;
- * }
- *
- * Note that the other details of endianness have been hidden in CRCPOLY
- * (which must be bit-reversed) and next_input_bit().
- *
- * However, as long as next_input_bit is returning the bits in a sensible
- * order, we can actually do the merging 8 or more bits at a time rather
- * than one bit at a time:
- * for (i = 0; i < input_bytes; i++) {
- *     remainder ^= next_input_byte() << 24;
- *     for (j = 0; j < 8; j++) {
- *             multiple = (remainder & 0x80000000) ? CRCPOLY : 0;
- *             remainder = (remainder << 1) ^ multiple;
- *     }
- * }
- * Or in little-endian:
- * for (i = 0; i < input_bytes; i++) {
- *     remainder ^= next_input_byte();
- *     for (j = 0; j < 8; j++) {
- *             multiple = (remainder & 1) ? CRCPOLY : 0;
- *             remainder = (remainder << 1) ^ multiple;
- *     }
- * }
- * If the input is a multiple of 32 bits, you can even XOR in a 32-bit
- * word at a time and increase the inner loop count to 32.
- *
- * You can also mix and match the two loop styles, for example doing the
- * bulk of a message byte-at-a-time and adding bit-at-a-time processing
- * for any fractional bytes at the end.
- *
- * The only remaining optimization is to the byte-at-a-time table method.
- * Here, rather than just shifting one bit of the remainder to decide
- * in the correct multiple to subtract, we can shift a byte at a time.
- * This produces a 40-bit (rather than a 33-bit) intermediate remainder,
- * but again the multiple of the polynomial to subtract depends only on
- * the high bits, the high 8 bits in this case.  
- *
- * The multiple we need in that case is the low 32 bits of a 40-bit
- * value whose high 8 bits are given, and which is a multiple of the
- * generator polynomial.  This is simply the CRC-32 of the given
- * one-byte message.
- *
- * Two more details: normally, appending zero bits to a message which
- * is already a multiple of a polynomial produces a larger multiple of that
- * polynomial.  To enable a CRC to detect this condition, it's common to
- * invert the CRC before appending it.  This makes the remainder of the
- * message+crc come out not as zero, but some fixed non-zero value.
- *
- * The same problem applies to zero bits prepended to the message, and
- * a similar solution is used.  Instead of starting with a remainder of
- * 0, an initial remainder of all ones is used.  As long as you start
- * the same way on decoding, it doesn't make a difference.
- */
-
-#ifdef UNITTEST
+#ifdef CONFIG_CRC32_SELFTEST
 
-#include <stdlib.h>
-#include <stdio.h>
+/* 4096 random bytes */
+static u8 __attribute__((__aligned__(8))) test_buf[] =
+{
+       0x5b, 0x85, 0x21, 0xcb, 0x09, 0x68, 0x7d, 0x30,
+       0xc7, 0x69, 0xd7, 0x30, 0x92, 0xde, 0x59, 0xe4,
+       0xc9, 0x6e, 0x8b, 0xdb, 0x98, 0x6b, 0xaa, 0x60,
+       0xa8, 0xb5, 0xbc, 0x6c, 0xa9, 0xb1, 0x5b, 0x2c,
+       0xea, 0xb4, 0x92, 0x6a, 0x3f, 0x79, 0x91, 0xe4,
+       0xe9, 0x70, 0x51, 0x8c, 0x7f, 0x95, 0x6f, 0x1a,
+       0x56, 0xa1, 0x5c, 0x27, 0x03, 0x67, 0x9f, 0x3a,
+       0xe2, 0x31, 0x11, 0x29, 0x6b, 0x98, 0xfc, 0xc4,
+       0x53, 0x24, 0xc5, 0x8b, 0xce, 0x47, 0xb2, 0xb9,
+       0x32, 0xcb, 0xc1, 0xd0, 0x03, 0x57, 0x4e, 0xd4,
+       0xe9, 0x3c, 0xa1, 0x63, 0xcf, 0x12, 0x0e, 0xca,
+       0xe1, 0x13, 0xd1, 0x93, 0xa6, 0x88, 0x5c, 0x61,
+       0x5b, 0xbb, 0xf0, 0x19, 0x46, 0xb4, 0xcf, 0x9e,
+       0xb6, 0x6b, 0x4c, 0x3a, 0xcf, 0x60, 0xf9, 0x7a,
+       0x8d, 0x07, 0x63, 0xdb, 0x40, 0xe9, 0x0b, 0x6f,
+       0xad, 0x97, 0xf1, 0xed, 0xd0, 0x1e, 0x26, 0xfd,
+       0xbf, 0xb7, 0xc8, 0x04, 0x94, 0xf8, 0x8b, 0x8c,
+       0xf1, 0xab, 0x7a, 0xd4, 0xdd, 0xf3, 0xe8, 0x88,
+       0xc3, 0xed, 0x17, 0x8a, 0x9b, 0x40, 0x0d, 0x53,
+       0x62, 0x12, 0x03, 0x5f, 0x1b, 0x35, 0x32, 0x1f,
+       0xb4, 0x7b, 0x93, 0x78, 0x0d, 0xdb, 0xce, 0xa4,
+       0xc0, 0x47, 0xd5, 0xbf, 0x68, 0xe8, 0x5d, 0x74,
+       0x8f, 0x8e, 0x75, 0x1c, 0xb2, 0x4f, 0x9a, 0x60,
+       0xd1, 0xbe, 0x10, 0xf4, 0x5c, 0xa1, 0x53, 0x09,
+       0xa5, 0xe0, 0x09, 0x54, 0x85, 0x5c, 0xdc, 0x07,
+       0xe7, 0x21, 0x69, 0x7b, 0x8a, 0xfd, 0x90, 0xf1,
+       0x22, 0xd0, 0xb4, 0x36, 0x28, 0xe6, 0xb8, 0x0f,
+       0x39, 0xde, 0xc8, 0xf3, 0x86, 0x60, 0x34, 0xd2,
+       0x5e, 0xdf, 0xfd, 0xcf, 0x0f, 0xa9, 0x65, 0xf0,
+       0xd5, 0x4d, 0x96, 0x40, 0xe3, 0xdf, 0x3f, 0x95,
+       0x5a, 0x39, 0x19, 0x93, 0xf4, 0x75, 0xce, 0x22,
+       0x00, 0x1c, 0x93, 0xe2, 0x03, 0x66, 0xf4, 0x93,
+       0x73, 0x86, 0x81, 0x8e, 0x29, 0x44, 0x48, 0x86,
+       0x61, 0x7c, 0x48, 0xa3, 0x43, 0xd2, 0x9c, 0x8d,
+       0xd4, 0x95, 0xdd, 0xe1, 0x22, 0x89, 0x3a, 0x40,
+       0x4c, 0x1b, 0x8a, 0x04, 0xa8, 0x09, 0x69, 0x8b,
+       0xea, 0xc6, 0x55, 0x8e, 0x57, 0xe6, 0x64, 0x35,
+       0xf0, 0xc7, 0x16, 0x9f, 0x5d, 0x5e, 0x86, 0x40,
+       0x46, 0xbb, 0xe5, 0x45, 0x88, 0xfe, 0xc9, 0x63,
+       0x15, 0xfb, 0xf5, 0xbd, 0x71, 0x61, 0xeb, 0x7b,
+       0x78, 0x70, 0x07, 0x31, 0x03, 0x9f, 0xb2, 0xc8,
+       0xa7, 0xab, 0x47, 0xfd, 0xdf, 0xa0, 0x78, 0x72,
+       0xa4, 0x2a, 0xe4, 0xb6, 0xba, 0xc0, 0x1e, 0x86,
+       0x71, 0xe6, 0x3d, 0x18, 0x37, 0x70, 0xe6, 0xff,
+       0xe0, 0xbc, 0x0b, 0x22, 0xa0, 0x1f, 0xd3, 0xed,
+       0xa2, 0x55, 0x39, 0xab, 0xa8, 0x13, 0x73, 0x7c,
+       0x3f, 0xb2, 0xd6, 0x19, 0xac, 0xff, 0x99, 0xed,
+       0xe8, 0xe6, 0xa6, 0x22, 0xe3, 0x9c, 0xf1, 0x30,
+       0xdc, 0x01, 0x0a, 0x56, 0xfa, 0xe4, 0xc9, 0x99,
+       0xdd, 0xa8, 0xd8, 0xda, 0x35, 0x51, 0x73, 0xb4,
+       0x40, 0x86, 0x85, 0xdb, 0x5c, 0xd5, 0x85, 0x80,
+       0x14, 0x9c, 0xfd, 0x98, 0xa9, 0x82, 0xc5, 0x37,
+       0xff, 0x32, 0x5d, 0xd0, 0x0b, 0xfa, 0xdc, 0x04,
+       0x5e, 0x09, 0xd2, 0xca, 0x17, 0x4b, 0x1a, 0x8e,
+       0x15, 0xe1, 0xcc, 0x4e, 0x52, 0x88, 0x35, 0xbd,
+       0x48, 0xfe, 0x15, 0xa0, 0x91, 0xfd, 0x7e, 0x6c,
+       0x0e, 0x5d, 0x79, 0x1b, 0x81, 0x79, 0xd2, 0x09,
+       0x34, 0x70, 0x3d, 0x81, 0xec, 0xf6, 0x24, 0xbb,
+       0xfb, 0xf1, 0x7b, 0xdf, 0x54, 0xea, 0x80, 0x9b,
+       0xc7, 0x99, 0x9e, 0xbd, 0x16, 0x78, 0x12, 0x53,
+       0x5e, 0x01, 0xa7, 0x4e, 0xbd, 0x67, 0xe1, 0x9b,
+       0x4c, 0x0e, 0x61, 0x45, 0x97, 0xd2, 0xf0, 0x0f,
+       0xfe, 0x15, 0x08, 0xb7, 0x11, 0x4c, 0xe7, 0xff,
+       0x81, 0x53, 0xff, 0x91, 0x25, 0x38, 0x7e, 0x40,
+       0x94, 0xe5, 0xe0, 0xad, 0xe6, 0xd9, 0x79, 0xb6,
+       0x92, 0xc9, 0xfc, 0xde, 0xc3, 0x1a, 0x23, 0xbb,
+       0xdd, 0xc8, 0x51, 0x0c, 0x3a, 0x72, 0xfa, 0x73,
+       0x6f, 0xb7, 0xee, 0x61, 0x39, 0x03, 0x01, 0x3f,
+       0x7f, 0x94, 0x2e, 0x2e, 0xba, 0x3a, 0xbb, 0xb4,
+       0xfa, 0x6a, 0x17, 0xfe, 0xea, 0xef, 0x5e, 0x66,
+       0x97, 0x3f, 0x32, 0x3d, 0xd7, 0x3e, 0xb1, 0xf1,
+       0x6c, 0x14, 0x4c, 0xfd, 0x37, 0xd3, 0x38, 0x80,
+       0xfb, 0xde, 0xa6, 0x24, 0x1e, 0xc8, 0xca, 0x7f,
+       0x3a, 0x93, 0xd8, 0x8b, 0x18, 0x13, 0xb2, 0xe5,
+       0xe4, 0x93, 0x05, 0x53, 0x4f, 0x84, 0x66, 0xa7,
+       0x58, 0x5c, 0x7b, 0x86, 0x52, 0x6d, 0x0d, 0xce,
+       0xa4, 0x30, 0x7d, 0xb6, 0x18, 0x9f, 0xeb, 0xff,
+       0x22, 0xbb, 0x72, 0x29, 0xb9, 0x44, 0x0b, 0x48,
+       0x1e, 0x84, 0x71, 0x81, 0xe3, 0x6d, 0x73, 0x26,
+       0x92, 0xb4, 0x4d, 0x2a, 0x29, 0xb8, 0x1f, 0x72,
+       0xed, 0xd0, 0xe1, 0x64, 0x77, 0xea, 0x8e, 0x88,
+       0x0f, 0xef, 0x3f, 0xb1, 0x3b, 0xad, 0xf9, 0xc9,
+       0x8b, 0xd0, 0xac, 0xc6, 0xcc, 0xa9, 0x40, 0xcc,
+       0x76, 0xf6, 0x3b, 0x53, 0xb5, 0x88, 0xcb, 0xc8,
+       0x37, 0xf1, 0xa2, 0xba, 0x23, 0x15, 0x99, 0x09,
+       0xcc, 0xe7, 0x7a, 0x3b, 0x37, 0xf7, 0x58, 0xc8,
+       0x46, 0x8c, 0x2b, 0x2f, 0x4e, 0x0e, 0xa6, 0x5c,
+       0xea, 0x85, 0x55, 0xba, 0x02, 0x0e, 0x0e, 0x48,
+       0xbc, 0xe1, 0xb1, 0x01, 0x35, 0x79, 0x13, 0x3d,
+       0x1b, 0xc0, 0x53, 0x68, 0x11, 0xe7, 0x95, 0x0f,
+       0x9d, 0x3f, 0x4c, 0x47, 0x7b, 0x4d, 0x1c, 0xae,
+       0x50, 0x9b, 0xcb, 0xdd, 0x05, 0x8d, 0x9a, 0x97,
+       0xfd, 0x8c, 0xef, 0x0c, 0x1d, 0x67, 0x73, 0xa8,
+       0x28, 0x36, 0xd5, 0xb6, 0x92, 0x33, 0x40, 0x75,
+       0x0b, 0x51, 0xc3, 0x64, 0xba, 0x1d, 0xc2, 0xcc,
+       0xee, 0x7d, 0x54, 0x0f, 0x27, 0x69, 0xa7, 0x27,
+       0x63, 0x30, 0x29, 0xd9, 0xc8, 0x84, 0xd8, 0xdf,
+       0x9f, 0x68, 0x8d, 0x04, 0xca, 0xa6, 0xc5, 0xc7,
+       0x7a, 0x5c, 0xc8, 0xd1, 0xcb, 0x4a, 0xec, 0xd0,
+       0xd8, 0x20, 0x69, 0xc5, 0x17, 0xcd, 0x78, 0xc8,
+       0x75, 0x23, 0x30, 0x69, 0xc9, 0xd4, 0xea, 0x5c,
+       0x4f, 0x6b, 0x86, 0x3f, 0x8b, 0xfe, 0xee, 0x44,
+       0xc9, 0x7c, 0xb7, 0xdd, 0x3e, 0xe5, 0xec, 0x54,
+       0x03, 0x3e, 0xaa, 0x82, 0xc6, 0xdf, 0xb2, 0x38,
+       0x0e, 0x5d, 0xb3, 0x88, 0xd9, 0xd3, 0x69, 0x5f,
+       0x8f, 0x70, 0x8a, 0x7e, 0x11, 0xd9, 0x1e, 0x7b,
+       0x38, 0xf1, 0x42, 0x1a, 0xc0, 0x35, 0xf5, 0xc7,
+       0x36, 0x85, 0xf5, 0xf7, 0xb8, 0x7e, 0xc7, 0xef,
+       0x18, 0xf1, 0x63, 0xd6, 0x7a, 0xc6, 0xc9, 0x0e,
+       0x4d, 0x69, 0x4f, 0x84, 0xef, 0x26, 0x41, 0x0c,
+       0xec, 0xc7, 0xe0, 0x7e, 0x3c, 0x67, 0x01, 0x4c,
+       0x62, 0x1a, 0x20, 0x6f, 0xee, 0x47, 0x4d, 0xc0,
+       0x99, 0x13, 0x8d, 0x91, 0x4a, 0x26, 0xd4, 0x37,
+       0x28, 0x90, 0x58, 0x75, 0x66, 0x2b, 0x0a, 0xdf,
+       0xda, 0xee, 0x92, 0x25, 0x90, 0x62, 0x39, 0x9e,
+       0x44, 0x98, 0xad, 0xc1, 0x88, 0xed, 0xe4, 0xb4,
+       0xaf, 0xf5, 0x8c, 0x9b, 0x48, 0x4d, 0x56, 0x60,
+       0x97, 0x0f, 0x61, 0x59, 0x9e, 0xa6, 0x27, 0xfe,
+       0xc1, 0x91, 0x15, 0x38, 0xb8, 0x0f, 0xae, 0x61,
+       0x7d, 0x26, 0x13, 0x5a, 0x73, 0xff, 0x1c, 0xa3,
+       0x61, 0x04, 0x58, 0x48, 0x55, 0x44, 0x11, 0xfe,
+       0x15, 0xca, 0xc3, 0xbd, 0xca, 0xc5, 0xb4, 0x40,
+       0x5d, 0x1b, 0x7f, 0x39, 0xb5, 0x9c, 0x35, 0xec,
+       0x61, 0x15, 0x32, 0x32, 0xb8, 0x4e, 0x40, 0x9f,
+       0x17, 0x1f, 0x0a, 0x4d, 0xa9, 0x91, 0xef, 0xb7,
+       0xb0, 0xeb, 0xc2, 0x83, 0x9a, 0x6c, 0xd2, 0x79,
+       0x43, 0x78, 0x5e, 0x2f, 0xe5, 0xdd, 0x1a, 0x3c,
+       0x45, 0xab, 0x29, 0x40, 0x3a, 0x37, 0x5b, 0x6f,
+       0xd7, 0xfc, 0x48, 0x64, 0x3c, 0x49, 0xfb, 0x21,
+       0xbe, 0xc3, 0xff, 0x07, 0xfb, 0x17, 0xe9, 0xc9,
+       0x0c, 0x4c, 0x5c, 0x15, 0x9e, 0x8e, 0x22, 0x30,
+       0x0a, 0xde, 0x48, 0x7f, 0xdb, 0x0d, 0xd1, 0x2b,
+       0x87, 0x38, 0x9e, 0xcc, 0x5a, 0x01, 0x16, 0xee,
+       0x75, 0x49, 0x0d, 0x30, 0x01, 0x34, 0x6a, 0xb6,
+       0x9a, 0x5a, 0x2a, 0xec, 0xbb, 0x48, 0xac, 0xd3,
+       0x77, 0x83, 0xd8, 0x08, 0x86, 0x4f, 0x48, 0x09,
+       0x29, 0x41, 0x79, 0xa1, 0x03, 0x12, 0xc4, 0xcd,
+       0x90, 0x55, 0x47, 0x66, 0x74, 0x9a, 0xcc, 0x4f,
+       0x35, 0x8c, 0xd6, 0x98, 0xef, 0xeb, 0x45, 0xb9,
+       0x9a, 0x26, 0x2f, 0x39, 0xa5, 0x70, 0x6d, 0xfc,
+       0xb4, 0x51, 0xee, 0xf4, 0x9c, 0xe7, 0x38, 0x59,
+       0xad, 0xf4, 0xbc, 0x46, 0xff, 0x46, 0x8e, 0x60,
+       0x9c, 0xa3, 0x60, 0x1d, 0xf8, 0x26, 0x72, 0xf5,
+       0x72, 0x9d, 0x68, 0x80, 0x04, 0xf6, 0x0b, 0xa1,
+       0x0a, 0xd5, 0xa7, 0x82, 0x3a, 0x3e, 0x47, 0xa8,
+       0x5a, 0xde, 0x59, 0x4f, 0x7b, 0x07, 0xb3, 0xe9,
+       0x24, 0x19, 0x3d, 0x34, 0x05, 0xec, 0xf1, 0xab,
+       0x6e, 0x64, 0x8f, 0xd3, 0xe6, 0x41, 0x86, 0x80,
+       0x70, 0xe3, 0x8d, 0x60, 0x9c, 0x34, 0x25, 0x01,
+       0x07, 0x4d, 0x19, 0x41, 0x4e, 0x3d, 0x5c, 0x7e,
+       0xa8, 0xf5, 0xcc, 0xd5, 0x7b, 0xe2, 0x7d, 0x3d,
+       0x49, 0x86, 0x7d, 0x07, 0xb7, 0x10, 0xe3, 0x35,
+       0xb8, 0x84, 0x6d, 0x76, 0xab, 0x17, 0xc6, 0x38,
+       0xb4, 0xd3, 0x28, 0x57, 0xad, 0xd3, 0x88, 0x5a,
+       0xda, 0xea, 0xc8, 0x94, 0xcc, 0x37, 0x19, 0xac,
+       0x9c, 0x9f, 0x4b, 0x00, 0x15, 0xc0, 0xc8, 0xca,
+       0x1f, 0x15, 0xaa, 0xe0, 0xdb, 0xf9, 0x2f, 0x57,
+       0x1b, 0x24, 0xc7, 0x6f, 0x76, 0x29, 0xfb, 0xed,
+       0x25, 0x0d, 0xc0, 0xfe, 0xbd, 0x5a, 0xbf, 0x20,
+       0x08, 0x51, 0x05, 0xec, 0x71, 0xa3, 0xbf, 0xef,
+       0x5e, 0x99, 0x75, 0xdb, 0x3c, 0x5f, 0x9a, 0x8c,
+       0xbb, 0x19, 0x5c, 0x0e, 0x93, 0x19, 0xf8, 0x6a,
+       0xbc, 0xf2, 0x12, 0x54, 0x2f, 0xcb, 0x28, 0x64,
+       0x88, 0xb3, 0x92, 0x0d, 0x96, 0xd1, 0xa6, 0xe4,
+       0x1f, 0xf1, 0x4d, 0xa4, 0xab, 0x1c, 0xee, 0x54,
+       0xf2, 0xad, 0x29, 0x6d, 0x32, 0x37, 0xb2, 0x16,
+       0x77, 0x5c, 0xdc, 0x2e, 0x54, 0xec, 0x75, 0x26,
+       0xc6, 0x36, 0xd9, 0x17, 0x2c, 0xf1, 0x7a, 0xdc,
+       0x4b, 0xf1, 0xe2, 0xd9, 0x95, 0xba, 0xac, 0x87,
+       0xc1, 0xf3, 0x8e, 0x58, 0x08, 0xd8, 0x87, 0x60,
+       0xc9, 0xee, 0x6a, 0xde, 0xa4, 0xd2, 0xfc, 0x0d,
+       0xe5, 0x36, 0xc4, 0x5c, 0x52, 0xb3, 0x07, 0x54,
+       0x65, 0x24, 0xc1, 0xb1, 0xd1, 0xb1, 0x53, 0x13,
+       0x31, 0x79, 0x7f, 0x05, 0x76, 0xeb, 0x37, 0x59,
+       0x15, 0x2b, 0xd1, 0x3f, 0xac, 0x08, 0x97, 0xeb,
+       0x91, 0x98, 0xdf, 0x6c, 0x09, 0x0d, 0x04, 0x9f,
+       0xdc, 0x3b, 0x0e, 0x60, 0x68, 0x47, 0x23, 0x15,
+       0x16, 0xc6, 0x0b, 0x35, 0xf8, 0x77, 0xa2, 0x78,
+       0x50, 0xd4, 0x64, 0x22, 0x33, 0xff, 0xfb, 0x93,
+       0x71, 0x46, 0x50, 0x39, 0x1b, 0x9c, 0xea, 0x4e,
+       0x8d, 0x0c, 0x37, 0xe5, 0x5c, 0x51, 0x3a, 0x31,
+       0xb2, 0x85, 0x84, 0x3f, 0x41, 0xee, 0xa2, 0xc1,
+       0xc6, 0x13, 0x3b, 0x54, 0x28, 0xd2, 0x18, 0x37,
+       0xcc, 0x46, 0x9f, 0x6a, 0x91, 0x3d, 0x5a, 0x15,
+       0x3c, 0x89, 0xa3, 0x61, 0x06, 0x7d, 0x2e, 0x78,
+       0xbe, 0x7d, 0x40, 0xba, 0x2f, 0x95, 0xb1, 0x2f,
+       0x87, 0x3b, 0x8a, 0xbe, 0x6a, 0xf4, 0xc2, 0x31,
+       0x74, 0xee, 0x91, 0xe0, 0x23, 0xaa, 0x5d, 0x7f,
+       0xdd, 0xf0, 0x44, 0x8c, 0x0b, 0x59, 0x2b, 0xfc,
+       0x48, 0x3a, 0xdf, 0x07, 0x05, 0x38, 0x6c, 0xc9,
+       0xeb, 0x18, 0x24, 0x68, 0x8d, 0x58, 0x98, 0xd3,
+       0x31, 0xa3, 0xe4, 0x70, 0x59, 0xb1, 0x21, 0xbe,
+       0x7e, 0x65, 0x7d, 0xb8, 0x04, 0xab, 0xf6, 0xe4,
+       0xd7, 0xda, 0xec, 0x09, 0x8f, 0xda, 0x6d, 0x24,
+       0x07, 0xcc, 0x29, 0x17, 0x05, 0x78, 0x1a, 0xc1,
+       0xb1, 0xce, 0xfc, 0xaa, 0x2d, 0xe7, 0xcc, 0x85,
+       0x84, 0x84, 0x03, 0x2a, 0x0c, 0x3f, 0xa9, 0xf8,
+       0xfd, 0x84, 0x53, 0x59, 0x5c, 0xf0, 0xd4, 0x09,
+       0xf0, 0xd2, 0x6c, 0x32, 0x03, 0xb0, 0xa0, 0x8c,
+       0x52, 0xeb, 0x23, 0x91, 0x88, 0x43, 0x13, 0x46,
+       0xf6, 0x1e, 0xb4, 0x1b, 0xf5, 0x8e, 0x3a, 0xb5,
+       0x3d, 0x00, 0xf6, 0xe5, 0x08, 0x3d, 0x5f, 0x39,
+       0xd3, 0x21, 0x69, 0xbc, 0x03, 0x22, 0x3a, 0xd2,
+       0x5c, 0x84, 0xf8, 0x15, 0xc4, 0x80, 0x0b, 0xbc,
+       0x29, 0x3c, 0xf3, 0x95, 0x98, 0xcd, 0x8f, 0x35,
+       0xbc, 0xa5, 0x3e, 0xfc, 0xd4, 0x13, 0x9e, 0xde,
+       0x4f, 0xce, 0x71, 0x9d, 0x09, 0xad, 0xf2, 0x80,
+       0x6b, 0x65, 0x7f, 0x03, 0x00, 0x14, 0x7c, 0x15,
+       0x85, 0x40, 0x6d, 0x70, 0xea, 0xdc, 0xb3, 0x63,
+       0x35, 0x4f, 0x4d, 0xe0, 0xd9, 0xd5, 0x3c, 0x58,
+       0x56, 0x23, 0x80, 0xe2, 0x36, 0xdd, 0x75, 0x1d,
+       0x94, 0x11, 0x41, 0x8e, 0xe0, 0x81, 0x8e, 0xcf,
+       0xe0, 0xe5, 0xf6, 0xde, 0xd1, 0xe7, 0x04, 0x12,
+       0x79, 0x92, 0x2b, 0x71, 0x2a, 0x79, 0x8b, 0x7c,
+       0x44, 0x79, 0x16, 0x30, 0x4e, 0xf4, 0xf6, 0x9b,
+       0xb7, 0x40, 0xa3, 0x5a, 0xa7, 0x69, 0x3e, 0xc1,
+       0x3a, 0x04, 0xd0, 0x88, 0xa0, 0x3b, 0xdd, 0xc6,
+       0x9e, 0x7e, 0x1e, 0x1e, 0x8f, 0x44, 0xf7, 0x73,
+       0x67, 0x1e, 0x1a, 0x78, 0xfa, 0x62, 0xf4, 0xa9,
+       0xa8, 0xc6, 0x5b, 0xb8, 0xfa, 0x06, 0x7d, 0x5e,
+       0x38, 0x1c, 0x9a, 0x39, 0xe9, 0x39, 0x98, 0x22,
+       0x0b, 0xa7, 0xac, 0x0b, 0xf3, 0xbc, 0xf1, 0xeb,
+       0x8c, 0x81, 0xe3, 0x48, 0x8a, 0xed, 0x42, 0xc2,
+       0x38, 0xcf, 0x3e, 0xda, 0xd2, 0x89, 0x8d, 0x9c,
+       0x53, 0xb5, 0x2f, 0x41, 0x01, 0x26, 0x84, 0x9c,
+       0xa3, 0x56, 0xf6, 0x49, 0xc7, 0xd4, 0x9f, 0x93,
+       0x1b, 0x96, 0x49, 0x5e, 0xad, 0xb3, 0x84, 0x1f,
+       0x3c, 0xa4, 0xe0, 0x9b, 0xd1, 0x90, 0xbc, 0x38,
+       0x6c, 0xdd, 0x95, 0x4d, 0x9d, 0xb1, 0x71, 0x57,
+       0x2d, 0x34, 0xe8, 0xb8, 0x42, 0xc7, 0x99, 0x03,
+       0xc7, 0x07, 0x30, 0x65, 0x91, 0x55, 0xd5, 0x90,
+       0x70, 0x97, 0x37, 0x68, 0xd4, 0x11, 0xf9, 0xe8,
+       0xce, 0xec, 0xdc, 0x34, 0xd5, 0xd3, 0xb7, 0xc4,
+       0xb8, 0x97, 0x05, 0x92, 0xad, 0xf8, 0xe2, 0x36,
+       0x64, 0x41, 0xc9, 0xc5, 0x41, 0x77, 0x52, 0xd7,
+       0x2c, 0xa5, 0x24, 0x2f, 0xd9, 0x34, 0x0b, 0x47,
+       0x35, 0xa7, 0x28, 0x8b, 0xc5, 0xcd, 0xe9, 0x46,
+       0xac, 0x39, 0x94, 0x3c, 0x10, 0xc6, 0x29, 0x73,
+       0x0e, 0x0e, 0x5d, 0xe0, 0x71, 0x03, 0x8a, 0x72,
+       0x0e, 0x26, 0xb0, 0x7d, 0x84, 0xed, 0x95, 0x23,
+       0x49, 0x5a, 0x45, 0x83, 0x45, 0x60, 0x11, 0x4a,
+       0x46, 0x31, 0xd4, 0xd8, 0x16, 0x54, 0x98, 0x58,
+       0xed, 0x6d, 0xcc, 0x5d, 0xd6, 0x50, 0x61, 0x9f,
+       0x9d, 0xc5, 0x3e, 0x9d, 0x32, 0x47, 0xde, 0x96,
+       0xe1, 0x5d, 0xd8, 0xf8, 0xb4, 0x69, 0x6f, 0xb9,
+       0x15, 0x90, 0x57, 0x7a, 0xf6, 0xad, 0xb0, 0x5b,
+       0xf5, 0xa6, 0x36, 0x94, 0xfd, 0x84, 0xce, 0x1c,
+       0x0f, 0x4b, 0xd0, 0xc2, 0x5b, 0x6b, 0x56, 0xef,
+       0x73, 0x93, 0x0b, 0xc3, 0xee, 0xd9, 0xcf, 0xd3,
+       0xa4, 0x22, 0x58, 0xcd, 0x50, 0x6e, 0x65, 0xf4,
+       0xe9, 0xb7, 0x71, 0xaf, 0x4b, 0xb3, 0xb6, 0x2f,
+       0x0f, 0x0e, 0x3b, 0xc9, 0x85, 0x14, 0xf5, 0x17,
+       0xe8, 0x7a, 0x3a, 0xbf, 0x5f, 0x5e, 0xf8, 0x18,
+       0x48, 0xa6, 0x72, 0xab, 0x06, 0x95, 0xe9, 0xc8,
+       0xa7, 0xf4, 0x32, 0x44, 0x04, 0x0c, 0x84, 0x98,
+       0x73, 0xe3, 0x89, 0x8d, 0x5f, 0x7e, 0x4a, 0x42,
+       0x8f, 0xc5, 0x28, 0xb1, 0x82, 0xef, 0x1c, 0x97,
+       0x31, 0x3b, 0x4d, 0xe0, 0x0e, 0x10, 0x10, 0x97,
+       0x93, 0x49, 0x78, 0x2f, 0x0d, 0x86, 0x8b, 0xa1,
+       0x53, 0xa9, 0x81, 0x20, 0x79, 0xe7, 0x07, 0x77,
+       0xb6, 0xac, 0x5e, 0xd2, 0x05, 0xcd, 0xe9, 0xdb,
+       0x8a, 0x94, 0x82, 0x8a, 0x23, 0xb9, 0x3d, 0x1c,
+       0xa9, 0x7d, 0x72, 0x4a, 0xed, 0x33, 0xa3, 0xdb,
+       0x21, 0xa7, 0x86, 0x33, 0x45, 0xa5, 0xaa, 0x56,
+       0x45, 0xb5, 0x83, 0x29, 0x40, 0x47, 0x79, 0x04,
+       0x6e, 0xb9, 0x95, 0xd0, 0x81, 0x77, 0x2d, 0x48,
+       0x1e, 0xfe, 0xc3, 0xc2, 0x1e, 0xe5, 0xf2, 0xbe,
+       0xfd, 0x3b, 0x94, 0x9f, 0xc4, 0xc4, 0x26, 0x9d,
+       0xe4, 0x66, 0x1e, 0x19, 0xee, 0x6c, 0x79, 0x97,
+       0x11, 0x31, 0x4b, 0x0d, 0x01, 0xcb, 0xde, 0xa8,
+       0xf6, 0x6d, 0x7c, 0x39, 0x46, 0x4e, 0x7e, 0x3f,
+       0x94, 0x17, 0xdf, 0xa1, 0x7d, 0xd9, 0x1c, 0x8e,
+       0xbc, 0x7d, 0x33, 0x7d, 0xe3, 0x12, 0x40, 0xca,
+       0xab, 0x37, 0x11, 0x46, 0xd4, 0xae, 0xef, 0x44,
+       0xa2, 0xb3, 0x6a, 0x66, 0x0e, 0x0c, 0x90, 0x7f,
+       0xdf, 0x5c, 0x66, 0x5f, 0xf2, 0x94, 0x9f, 0xa6,
+       0x73, 0x4f, 0xeb, 0x0d, 0xad, 0xbf, 0xc0, 0x63,
+       0x5c, 0xdc, 0x46, 0x51, 0xe8, 0x8e, 0x90, 0x19,
+       0xa8, 0xa4, 0x3c, 0x91, 0x79, 0xfa, 0x7e, 0x58,
+       0x85, 0x13, 0x55, 0xc5, 0x19, 0x82, 0x37, 0x1b,
+       0x0a, 0x02, 0x1f, 0x99, 0x6b, 0x18, 0xf1, 0x28,
+       0x08, 0xa2, 0x73, 0xb8, 0x0f, 0x2e, 0xcd, 0xbf,
+       0xf3, 0x86, 0x7f, 0xea, 0xef, 0xd0, 0xbb, 0xa6,
+       0x21, 0xdf, 0x49, 0x73, 0x51, 0xcc, 0x36, 0xd3,
+       0x3e, 0xa0, 0xf8, 0x44, 0xdf, 0xd3, 0xa6, 0xbe,
+       0x8a, 0xd4, 0x57, 0xdd, 0x72, 0x94, 0x61, 0x0f,
+       0x82, 0xd1, 0x07, 0xb8, 0x7c, 0x18, 0x83, 0xdf,
+       0x3a, 0xe5, 0x50, 0x6a, 0x82, 0x20, 0xac, 0xa9,
+       0xa8, 0xff, 0xd9, 0xf3, 0x77, 0x33, 0x5a, 0x9e,
+       0x7f, 0x6d, 0xfe, 0x5d, 0x33, 0x41, 0x42, 0xe7,
+       0x6c, 0x19, 0xe0, 0x44, 0x8a, 0x15, 0xf6, 0x70,
+       0x98, 0xb7, 0x68, 0x4d, 0xfa, 0x97, 0x39, 0xb0,
+       0x8e, 0xe8, 0x84, 0x8b, 0x75, 0x30, 0xb7, 0x7d,
+       0x92, 0x69, 0x20, 0x9c, 0x81, 0xfb, 0x4b, 0xf4,
+       0x01, 0x50, 0xeb, 0xce, 0x0c, 0x1c, 0x6c, 0xb5,
+       0x4a, 0xd7, 0x27, 0x0c, 0xce, 0xbb, 0xe5, 0x85,
+       0xf0, 0xb6, 0xee, 0xd5, 0x70, 0xdd, 0x3b, 0xfc,
+       0xd4, 0x99, 0xf1, 0x33, 0xdd, 0x8b, 0xc4, 0x2f,
+       0xae, 0xab, 0x74, 0x96, 0x32, 0xc7, 0x4c, 0x56,
+       0x3c, 0x89, 0x0f, 0x96, 0x0b, 0x42, 0xc0, 0xcb,
+       0xee, 0x0f, 0x0b, 0x8c, 0xfb, 0x7e, 0x47, 0x7b,
+       0x64, 0x48, 0xfd, 0xb2, 0x00, 0x80, 0x89, 0xa5,
+       0x13, 0x55, 0x62, 0xfc, 0x8f, 0xe2, 0x42, 0x03,
+       0xb7, 0x4e, 0x2a, 0x79, 0xb4, 0x82, 0xea, 0x23,
+       0x49, 0xda, 0xaf, 0x52, 0x63, 0x1e, 0x60, 0x03,
+       0x89, 0x06, 0x44, 0x46, 0x08, 0xc3, 0xc4, 0x87,
+       0x70, 0x2e, 0xda, 0x94, 0xad, 0x6b, 0xe0, 0xe4,
+       0xd1, 0x8a, 0x06, 0xc2, 0xa8, 0xc0, 0xa7, 0x43,
+       0x3c, 0x47, 0x52, 0x0e, 0xc3, 0x77, 0x81, 0x11,
+       0x67, 0x0e, 0xa0, 0x70, 0x04, 0x47, 0x29, 0x40,
+       0x86, 0x0d, 0x34, 0x56, 0xa7, 0xc9, 0x35, 0x59,
+       0x68, 0xdc, 0x93, 0x81, 0x70, 0xee, 0x86, 0xd9,
+       0x80, 0x06, 0x40, 0x4f, 0x1a, 0x0d, 0x40, 0x30,
+       0x0b, 0xcb, 0x96, 0x47, 0xc1, 0xb7, 0x52, 0xfd,
+       0x56, 0xe0, 0x72, 0x4b, 0xfb, 0xbd, 0x92, 0x45,
+       0x61, 0x71, 0xc2, 0x33, 0x11, 0xbf, 0x52, 0x83,
+       0x79, 0x26, 0xe0, 0x49, 0x6b, 0xb7, 0x05, 0x8b,
+       0xe8, 0x0e, 0x87, 0x31, 0xd7, 0x9d, 0x8a, 0xf5,
+       0xc0, 0x5f, 0x2e, 0x58, 0x4a, 0xdb, 0x11, 0xb3,
+       0x6c, 0x30, 0x2a, 0x46, 0x19, 0xe3, 0x27, 0x84,
+       0x1f, 0x63, 0x6e, 0xf6, 0x57, 0xc7, 0xc9, 0xd8,
+       0x5e, 0xba, 0xb3, 0x87, 0xd5, 0x83, 0x26, 0x34,
+       0x21, 0x9e, 0x65, 0xde, 0x42, 0xd3, 0xbe, 0x7b,
+       0xbc, 0x91, 0x71, 0x44, 0x4d, 0x99, 0x3b, 0x31,
+       0xe5, 0x3f, 0x11, 0x4e, 0x7f, 0x13, 0x51, 0x3b,
+       0xae, 0x79, 0xc9, 0xd3, 0x81, 0x8e, 0x25, 0x40,
+       0x10, 0xfc, 0x07, 0x1e, 0xf9, 0x7b, 0x9a, 0x4b,
+       0x6c, 0xe3, 0xb3, 0xad, 0x1a, 0x0a, 0xdd, 0x9e,
+       0x59, 0x0c, 0xa2, 0xcd, 0xae, 0x48, 0x4a, 0x38,
+       0x5b, 0x47, 0x41, 0x94, 0x65, 0x6b, 0xbb, 0xeb,
+       0x5b, 0xe3, 0xaf, 0x07, 0x5b, 0xd4, 0x4a, 0xa2,
+       0xc9, 0x5d, 0x2f, 0x64, 0x03, 0xd7, 0x3a, 0x2c,
+       0x6e, 0xce, 0x76, 0x95, 0xb4, 0xb3, 0xc0, 0xf1,
+       0xe2, 0x45, 0x73, 0x7a, 0x5c, 0xab, 0xc1, 0xfc,
+       0x02, 0x8d, 0x81, 0x29, 0xb3, 0xac, 0x07, 0xec,
+       0x40, 0x7d, 0x45, 0xd9, 0x7a, 0x59, 0xee, 0x34,
+       0xf0, 0xe9, 0xd5, 0x7b, 0x96, 0xb1, 0x3d, 0x95,
+       0xcc, 0x86, 0xb5, 0xb6, 0x04, 0x2d, 0xb5, 0x92,
+       0x7e, 0x76, 0xf4, 0x06, 0xa9, 0xa3, 0x12, 0x0f,
+       0xb1, 0xaf, 0x26, 0xba, 0x7c, 0xfc, 0x7e, 0x1c,
+       0xbc, 0x2c, 0x49, 0x97, 0x53, 0x60, 0x13, 0x0b,
+       0xa6, 0x61, 0x83, 0x89, 0x42, 0xd4, 0x17, 0x0c,
+       0x6c, 0x26, 0x52, 0xc3, 0xb3, 0xd4, 0x67, 0xf5,
+       0xe3, 0x04, 0xb7, 0xf4, 0xcb, 0x80, 0xb8, 0xcb,
+       0x77, 0x56, 0x3e, 0xaa, 0x57, 0x54, 0xee, 0xb4,
+       0x2c, 0x67, 0xcf, 0xf2, 0xdc, 0xbe, 0x55, 0xf9,
+       0x43, 0x1f, 0x6e, 0x22, 0x97, 0x67, 0x7f, 0xc4,
+       0xef, 0xb1, 0x26, 0x31, 0x1e, 0x27, 0xdf, 0x41,
+       0x80, 0x47, 0x6c, 0xe2, 0xfa, 0xa9, 0x8c, 0x2a,
+       0xf6, 0xf2, 0xab, 0xf0, 0x15, 0xda, 0x6c, 0xc8,
+       0xfe, 0xb5, 0x23, 0xde, 0xa9, 0x05, 0x3f, 0x06,
+       0x54, 0x4c, 0xcd, 0xe1, 0xab, 0xfc, 0x0e, 0x62,
+       0x33, 0x31, 0x73, 0x2c, 0x76, 0xcb, 0xb4, 0x47,
+       0x1e, 0x20, 0xad, 0xd8, 0xf2, 0x31, 0xdd, 0xc4,
+       0x8b, 0x0c, 0x77, 0xbe, 0xe1, 0x8b, 0x26, 0x00,
+       0x02, 0x58, 0xd6, 0x8d, 0xef, 0xad, 0x74, 0x67,
+       0xab, 0x3f, 0xef, 0xcb, 0x6f, 0xb0, 0xcc, 0x81,
+       0x44, 0x4c, 0xaf, 0xe9, 0x49, 0x4f, 0xdb, 0xa0,
+       0x25, 0xa4, 0xf0, 0x89, 0xf1, 0xbe, 0xd8, 0x10,
+       0xff, 0xb1, 0x3b, 0x4b, 0xfa, 0x98, 0xf5, 0x79,
+       0x6d, 0x1e, 0x69, 0x4d, 0x57, 0xb1, 0xc8, 0x19,
+       0x1b, 0xbd, 0x1e, 0x8c, 0x84, 0xb7, 0x7b, 0xe8,
+       0xd2, 0x2d, 0x09, 0x41, 0x41, 0x37, 0x3d, 0xb1,
+       0x6f, 0x26, 0x5d, 0x71, 0x16, 0x3d, 0xb7, 0x83,
+       0x27, 0x2c, 0xa7, 0xb6, 0x50, 0xbd, 0x91, 0x86,
+       0xab, 0x24, 0xa1, 0x38, 0xfd, 0xea, 0x71, 0x55,
+       0x7e, 0x9a, 0x07, 0x77, 0x4b, 0xfa, 0x61, 0x66,
+       0x20, 0x1e, 0x28, 0x95, 0x18, 0x1b, 0xa4, 0xa0,
+       0xfd, 0xc0, 0x89, 0x72, 0x43, 0xd9, 0x3b, 0x49,
+       0x5a, 0x3f, 0x9d, 0xbf, 0xdb, 0xb4, 0x46, 0xea,
+       0x42, 0x01, 0x77, 0x23, 0x68, 0x95, 0xb6, 0x24,
+       0xb3, 0xa8, 0x6c, 0x28, 0x3b, 0x11, 0x40, 0x7e,
+       0x18, 0x65, 0x6d, 0xd8, 0x24, 0x42, 0x7d, 0x88,
+       0xc0, 0x52, 0xd9, 0x05, 0xe4, 0x95, 0x90, 0x87,
+       0x8c, 0xf4, 0xd0, 0x6b, 0xb9, 0x83, 0x99, 0x34,
+       0x6d, 0xfe, 0x54, 0x40, 0x94, 0x52, 0x21, 0x4f,
+       0x14, 0x25, 0xc5, 0xd6, 0x5e, 0x95, 0xdc, 0x0a,
+       0x2b, 0x89, 0x20, 0x11, 0x84, 0x48, 0xd6, 0x3a,
+       0xcd, 0x5c, 0x24, 0xad, 0x62, 0xe3, 0xb1, 0x93,
+       0x25, 0x8d, 0xcd, 0x7e, 0xfc, 0x27, 0xa3, 0x37,
+       0xfd, 0x84, 0xfc, 0x1b, 0xb2, 0xf1, 0x27, 0x38,
+       0x5a, 0xb7, 0xfc, 0xf2, 0xfa, 0x95, 0x66, 0xd4,
+       0xfb, 0xba, 0xa7, 0xd7, 0xa3, 0x72, 0x69, 0x48,
+       0x48, 0x8c, 0xeb, 0x28, 0x89, 0xfe, 0x33, 0x65,
+       0x5a, 0x36, 0x01, 0x7e, 0x06, 0x79, 0x0a, 0x09,
+       0x3b, 0x74, 0x11, 0x9a, 0x6e, 0xbf, 0xd4, 0x9e,
+       0x58, 0x90, 0x49, 0x4f, 0x4d, 0x08, 0xd4, 0xe5,
+       0x4a, 0x09, 0x21, 0xef, 0x8b, 0xb8, 0x74, 0x3b,
+       0x91, 0xdd, 0x36, 0x85, 0x60, 0x2d, 0xfa, 0xd4,
+       0x45, 0x7b, 0x45, 0x53, 0xf5, 0x47, 0x87, 0x7e,
+       0xa6, 0x37, 0xc8, 0x78, 0x7a, 0x68, 0x9d, 0x8d,
+       0x65, 0x2c, 0x0e, 0x91, 0x5c, 0xa2, 0x60, 0xf0,
+       0x8e, 0x3f, 0xe9, 0x1a, 0xcd, 0xaa, 0xe7, 0xd5,
+       0x77, 0x18, 0xaf, 0xc9, 0xbc, 0x18, 0xea, 0x48,
+       0x1b, 0xfb, 0x22, 0x48, 0x70, 0x16, 0x29, 0x9e,
+       0x5b, 0xc1, 0x2c, 0x66, 0x23, 0xbc, 0xf0, 0x1f,
+       0xef, 0xaf, 0xe4, 0xd6, 0x04, 0x19, 0x82, 0x7a,
+       0x0b, 0xba, 0x4b, 0x46, 0xb1, 0x6a, 0x85, 0x5d,
+       0xb4, 0x73, 0xd6, 0x21, 0xa1, 0x71, 0x60, 0x14,
+       0xee, 0x0a, 0x77, 0xc4, 0x66, 0x2e, 0xf9, 0x69,
+       0x30, 0xaf, 0x41, 0x0b, 0xc8, 0x83, 0x3c, 0x53,
+       0x99, 0x19, 0x27, 0x46, 0xf7, 0x41, 0x6e, 0x56,
+       0xdc, 0x94, 0x28, 0x67, 0x4e, 0xb7, 0x25, 0x48,
+       0x8a, 0xc2, 0xe0, 0x60, 0x96, 0xcc, 0x18, 0xf4,
+       0x84, 0xdd, 0xa7, 0x5e, 0x3e, 0x05, 0x0b, 0x26,
+       0x26, 0xb2, 0x5c, 0x1f, 0x57, 0x1a, 0x04, 0x7e,
+       0x6a, 0xe3, 0x2f, 0xb4, 0x35, 0xb6, 0x38, 0x40,
+       0x40, 0xcd, 0x6f, 0x87, 0x2e, 0xef, 0xa3, 0xd7,
+       0xa9, 0xc2, 0xe8, 0x0d, 0x27, 0xdf, 0x44, 0x62,
+       0x99, 0xa0, 0xfc, 0xcf, 0x81, 0x78, 0xcb, 0xfe,
+       0xe5, 0xa0, 0x03, 0x4e, 0x6c, 0xd7, 0xf4, 0xaf,
+       0x7a, 0xbb, 0x61, 0x82, 0xfe, 0x71, 0x89, 0xb2,
+       0x22, 0x7c, 0x8e, 0x83, 0x04, 0xce, 0xf6, 0x5d,
+       0x84, 0x8f, 0x95, 0x6a, 0x7f, 0xad, 0xfd, 0x32,
+       0x9c, 0x5e, 0xe4, 0x9c, 0x89, 0x60, 0x54, 0xaa,
+       0x96, 0x72, 0xd2, 0xd7, 0x36, 0x85, 0xa9, 0x45,
+       0xd2, 0x2a, 0xa1, 0x81, 0x49, 0x6f, 0x7e, 0x04,
+       0xfa, 0xe2, 0xfe, 0x90, 0x26, 0x77, 0x5a, 0x33,
+       0xb8, 0x04, 0x9a, 0x7a, 0xe6, 0x4c, 0x4f, 0xad,
+       0x72, 0x96, 0x08, 0x28, 0x58, 0x13, 0xf8, 0xc4,
+       0x1c, 0xf0, 0xc3, 0x45, 0x95, 0x49, 0x20, 0x8c,
+       0x9f, 0x39, 0x70, 0xe1, 0x77, 0xfe, 0xd5, 0x4b,
+       0xaf, 0x86, 0xda, 0xef, 0x22, 0x06, 0x83, 0x36,
+       0x29, 0x12, 0x11, 0x40, 0xbc, 0x3b, 0x86, 0xaa,
+       0xaa, 0x65, 0x60, 0xc3, 0x80, 0xca, 0xed, 0xa9,
+       0xf3, 0xb0, 0x79, 0x96, 0xa2, 0x55, 0x27, 0x28,
+       0x55, 0x73, 0x26, 0xa5, 0x50, 0xea, 0x92, 0x4b,
+       0x3c, 0x5c, 0x82, 0x33, 0xf0, 0x01, 0x3f, 0x03,
+       0xc1, 0x08, 0x05, 0xbf, 0x98, 0xf4, 0x9b, 0x6d,
+       0xa5, 0xa8, 0xb4, 0x82, 0x0c, 0x06, 0xfa, 0xff,
+       0x2d, 0x08, 0xf3, 0x05, 0x4f, 0x57, 0x2a, 0x39,
+       0xd4, 0x83, 0x0d, 0x75, 0x51, 0xd8, 0x5b, 0x1b,
+       0xd3, 0x51, 0x5a, 0x32, 0x2a, 0x9b, 0x32, 0xb2,
+       0xf2, 0xa4, 0x96, 0x12, 0xf2, 0xae, 0x40, 0x34,
+       0x67, 0xa8, 0xf5, 0x44, 0xd5, 0x35, 0x53, 0xfe,
+       0xa3, 0x60, 0x96, 0x63, 0x0f, 0x1f, 0x6e, 0xb0,
+       0x5a, 0x42, 0xa6, 0xfc, 0x51, 0x0b, 0x60, 0x27,
+       0xbc, 0x06, 0x71, 0xed, 0x65, 0x5b, 0x23, 0x86,
+       0x4a, 0x07, 0x3b, 0x22, 0x07, 0x46, 0xe6, 0x90,
+       0x3e, 0xf3, 0x25, 0x50, 0x1b, 0x4c, 0x7f, 0x03,
+       0x08, 0xa8, 0x36, 0x6b, 0x87, 0xe5, 0xe3, 0xdb,
+       0x9a, 0x38, 0x83, 0xff, 0x9f, 0x1a, 0x9f, 0x57,
+       0xa4, 0x2a, 0xf6, 0x37, 0xbc, 0x1a, 0xff, 0xc9,
+       0x1e, 0x35, 0x0c, 0xc3, 0x7c, 0xa3, 0xb2, 0xe5,
+       0xd2, 0xc6, 0xb4, 0x57, 0x47, 0xe4, 0x32, 0x16,
+       0x6d, 0xa9, 0xae, 0x64, 0xe6, 0x2d, 0x8d, 0xc5,
+       0x8d, 0x50, 0x8e, 0xe8, 0x1a, 0x22, 0x34, 0x2a,
+       0xd9, 0xeb, 0x51, 0x90, 0x4a, 0xb1, 0x41, 0x7d,
+       0x64, 0xf9, 0xb9, 0x0d, 0xf6, 0x23, 0x33, 0xb0,
+       0x33, 0xf4, 0xf7, 0x3f, 0x27, 0x84, 0xc6, 0x0f,
+       0x54, 0xa5, 0xc0, 0x2e, 0xec, 0x0b, 0x3a, 0x48,
+       0x6e, 0x80, 0x35, 0x81, 0x43, 0x9b, 0x90, 0xb1,
+       0xd0, 0x2b, 0xea, 0x21, 0xdc, 0xda, 0x5b, 0x09,
+       0xf4, 0xcc, 0x10, 0xb4, 0xc7, 0xfe, 0x79, 0x51,
+       0xc3, 0xc5, 0xac, 0x88, 0x74, 0x84, 0x0b, 0x4b,
+       0xca, 0x79, 0x16, 0x29, 0xfb, 0x69, 0x54, 0xdf,
+       0x41, 0x7e, 0xe9, 0xc7, 0x8e, 0xea, 0xa5, 0xfe,
+       0xfc, 0x76, 0x0e, 0x90, 0xc4, 0x92, 0x38, 0xad,
+       0x7b, 0x48, 0xe6, 0x6e, 0xf7, 0x21, 0xfd, 0x4e,
+       0x93, 0x0a, 0x7b, 0x41, 0x83, 0x68, 0xfb, 0x57,
+       0x51, 0x76, 0x34, 0xa9, 0x6c, 0x00, 0xaa, 0x4f,
+       0x66, 0x65, 0x98, 0x4a, 0x4f, 0xa3, 0xa0, 0xef,
+       0x69, 0x3f, 0xe3, 0x1c, 0x92, 0x8c, 0xfd, 0xd8,
+       0xe8, 0xde, 0x7c, 0x7f, 0x3e, 0x84, 0x8e, 0x69,
+       0x3c, 0xf1, 0xf2, 0x05, 0x46, 0xdc, 0x2f, 0x9d,
+       0x5e, 0x6e, 0x4c, 0xfb, 0xb5, 0x99, 0x2a, 0x59,
+       0x63, 0xc1, 0x34, 0xbc, 0x57, 0xc0, 0x0d, 0xb9,
+       0x61, 0x25, 0xf3, 0x33, 0x23, 0x51, 0xb6, 0x0d,
+       0x07, 0xa6, 0xab, 0x94, 0x4a, 0xb7, 0x2a, 0xea,
+       0xee, 0xac, 0xa3, 0xc3, 0x04, 0x8b, 0x0e, 0x56,
+       0xfe, 0x44, 0xa7, 0x39, 0xe2, 0xed, 0xed, 0xb4,
+       0x22, 0x2b, 0xac, 0x12, 0x32, 0x28, 0x91, 0xd8,
+       0xa5, 0xab, 0xff, 0x5f, 0xe0, 0x4b, 0xda, 0x78,
+       0x17, 0xda, 0xf1, 0x01, 0x5b, 0xcd, 0xe2, 0x5f,
+       0x50, 0x45, 0x73, 0x2b, 0xe4, 0x76, 0x77, 0xf4,
+       0x64, 0x1d, 0x43, 0xfb, 0x84, 0x7a, 0xea, 0x91,
+       0xae, 0xf9, 0x9e, 0xb7, 0xb4, 0xb0, 0x91, 0x5f,
+       0x16, 0x35, 0x9a, 0x11, 0xb8, 0xc7, 0xc1, 0x8c,
+       0xc6, 0x10, 0x8d, 0x2f, 0x63, 0x4a, 0xa7, 0x57,
+       0x3a, 0x51, 0xd6, 0x32, 0x2d, 0x64, 0x72, 0xd4,
+       0x66, 0xdc, 0x10, 0xa6, 0x67, 0xd6, 0x04, 0x23,
+       0x9d, 0x0a, 0x11, 0x77, 0xdd, 0x37, 0x94, 0x17,
+       0x3c, 0xbf, 0x8b, 0x65, 0xb0, 0x2e, 0x5e, 0x66,
+       0x47, 0x64, 0xac, 0xdd, 0xf0, 0x84, 0xfd, 0x39,
+       0xfa, 0x15, 0x5d, 0xef, 0xae, 0xca, 0xc1, 0x36,
+       0xa7, 0x5c, 0xbf, 0xc7, 0x08, 0xc2, 0x66, 0x00,
+       0x74, 0x74, 0x4e, 0x27, 0x3f, 0x55, 0x8a, 0xb7,
+       0x38, 0x66, 0x83, 0x6d, 0xcf, 0x99, 0x9e, 0x60,
+       0x8f, 0xdd, 0x2e, 0x62, 0x22, 0x0e, 0xef, 0x0c,
+       0x98, 0xa7, 0x85, 0x74, 0x3b, 0x9d, 0xec, 0x9e,
+       0xa9, 0x19, 0x72, 0xa5, 0x7f, 0x2c, 0x39, 0xb7,
+       0x7d, 0xb7, 0xf1, 0x12, 0x65, 0x27, 0x4b, 0x5a,
+       0xde, 0x17, 0xfe, 0xad, 0x44, 0xf3, 0x20, 0x4d,
+       0xfd, 0xe4, 0x1f, 0xb5, 0x81, 0xb0, 0x36, 0x37,
+       0x08, 0x6f, 0xc3, 0x0c, 0xe9, 0x85, 0x98, 0x82,
+       0xa9, 0x62, 0x0c, 0xc4, 0x97, 0xc0, 0x50, 0xc8,
+       0xa7, 0x3c, 0x50, 0x9f, 0x43, 0xb9, 0xcd, 0x5e,
+       0x4d, 0xfa, 0x1c, 0x4b, 0x0b, 0xa9, 0x98, 0x85,
+       0x38, 0x92, 0xac, 0x8d, 0xe4, 0xad, 0x9b, 0x98,
+       0xab, 0xd9, 0x38, 0xac, 0x62, 0x52, 0xa3, 0x22,
+       0x63, 0x0f, 0xbf, 0x95, 0x48, 0xdf, 0x69, 0xe7,
+       0x8b, 0x33, 0xd5, 0xb2, 0xbd, 0x05, 0x49, 0x49,
+       0x9d, 0x57, 0x73, 0x19, 0x33, 0xae, 0xfa, 0x33,
+       0xf1, 0x19, 0xa8, 0x80, 0xce, 0x04, 0x9f, 0xbc,
+       0x1d, 0x65, 0x82, 0x1b, 0xe5, 0x3a, 0x51, 0xc8,
+       0x1c, 0x21, 0xe3, 0x5d, 0xf3, 0x7d, 0x9b, 0x2f,
+       0x2c, 0x1d, 0x4a, 0x7f, 0x9b, 0x68, 0x35, 0xa3,
+       0xb2, 0x50, 0xf7, 0x62, 0x79, 0xcd, 0xf4, 0x98,
+       0x4f, 0xe5, 0x63, 0x7c, 0x3e, 0x45, 0x31, 0x8c,
+       0x16, 0xa0, 0x12, 0xc8, 0x58, 0xce, 0x39, 0xa6,
+       0xbc, 0x54, 0xdb, 0xc5, 0xe0, 0xd5, 0xba, 0xbc,
+       0xb9, 0x04, 0xf4, 0x8d, 0xe8, 0x2f, 0x15, 0x9d,
+};
 
-#if 0                          /*Not used at present */
-static void
-buf_dump(char const *prefix, unsigned char const *buf, size_t len)
+/* 100 test cases */
+static struct crc_test {
+       u32 crc;        /* random starting crc */
+       u32 start;      /* random 6 bit offset in buf */
+       u32 length;     /* random 11 bit length of test */
+       u32 crc_le;     /* expected crc32_le result */
+       u32 crc_be;     /* expected crc32_be result */
+       u32 crc32c_le;  /* expected crc32c_le result */
+} test[] =
 {
-       fputs(prefix, stdout);
-       while (len--)
-               printf(" %02x", *buf++);
-       putchar('\n');
+       {0x674bf11d, 0x00000038, 0x00000542, 0x0af6d466, 0xd8b6e4c1,
+        0xf6e93d6c},
+       {0x35c672c6, 0x0000003a, 0x000001aa, 0xc6d3dfba, 0x28aaf3ad,
+        0x0fe92aca},
+       {0x496da28e, 0x00000039, 0x000005af, 0xd933660f, 0x5d57e81f,
+        0x52e1ebb8},
+       {0x09a9b90e, 0x00000027, 0x000001f8, 0xb45fe007, 0xf45fca9a,
+        0x0798af9a},
+       {0xdc97e5a9, 0x00000025, 0x000003b6, 0xf81a3562, 0xe0126ba2,
+        0x18eb3152},
+       {0x47c58900, 0x0000000a, 0x000000b9, 0x8e58eccf, 0xf3afc793,
+        0xd00d08c7},
+       {0x292561e8, 0x0000000c, 0x00000403, 0xa2ba8aaf, 0x0b797aed,
+        0x8ba966bc},
+       {0x415037f6, 0x00000003, 0x00000676, 0xa17d52e8, 0x7f0fdf35,
+        0x11d694a2},
+       {0x3466e707, 0x00000026, 0x00000042, 0x258319be, 0x75c484a2,
+        0x6ab3208d},
+       {0xafd1281b, 0x00000023, 0x000002ee, 0x4428eaf8, 0x06c7ad10,
+        0xba4603c5},
+       {0xd3857b18, 0x00000028, 0x000004a2, 0x5c430821, 0xb062b7cb,
+        0xe6071c6f},
+       {0x1d825a8f, 0x0000002b, 0x0000050b, 0xd2c45f0c, 0xd68634e0,
+        0x179ec30a},
+       {0x5033e3bc, 0x0000000b, 0x00000078, 0xa3ea4113, 0xac6d31fb,
+        0x0903beb8},
+       {0x94f1fb5e, 0x0000000f, 0x000003a2, 0xfbfc50b1, 0x3cfe50ed,
+        0x6a7cb4fa},
+       {0xc9a0fe14, 0x00000009, 0x00000473, 0x5fb61894, 0x87070591,
+        0xdb535801},
+       {0x88a034b1, 0x0000001c, 0x000005ad, 0xc1b16053, 0x46f95c67,
+        0x92bed597},
+       {0xf0f72239, 0x00000020, 0x0000026d, 0xa6fa58f3, 0xf8c2c1dd,
+        0x192a3f1b},
+       {0xcc20a5e3, 0x0000003b, 0x0000067a, 0x7740185a, 0x308b979a,
+        0xccbaec1a},
+       {0xce589c95, 0x0000002b, 0x00000641, 0xd055e987, 0x40aae25b,
+        0x7eabae4d},
+       {0x78edc885, 0x00000035, 0x000005be, 0xa39cb14b, 0x035b0d1f,
+        0x28c72982},
+       {0x9d40a377, 0x0000003b, 0x00000038, 0x1f47ccd2, 0x197fbc9d,
+        0xc3cd4d18},
+       {0x703d0e01, 0x0000003c, 0x000006f1, 0x88735e7c, 0xfed57c5a,
+        0xbca8f0e7},
+       {0x776bf505, 0x0000000f, 0x000005b2, 0x5cc4fc01, 0xf32efb97,
+        0x713f60b3},
+       {0x4a3e7854, 0x00000027, 0x000004b8, 0x8d923c82, 0x0cbfb4a2,
+        0xebd08fd5},
+       {0x209172dd, 0x0000003b, 0x00000356, 0xb89e9c2b, 0xd7868138,
+        0x64406c59},
+       {0x3ba4cc5b, 0x0000002f, 0x00000203, 0xe51601a9, 0x5b2a1032,
+        0x7421890e},
+       {0xfc62f297, 0x00000000, 0x00000079, 0x71a8e1a2, 0x5d88685f,
+        0xe9347603},
+       {0x64280b8b, 0x00000016, 0x000007ab, 0x0fa7a30c, 0xda3a455f,
+        0x1bef9060},
+       {0x97dd724b, 0x00000033, 0x000007ad, 0x5788b2f4, 0xd7326d32,
+        0x34720072},
+       {0x61394b52, 0x00000035, 0x00000571, 0xc66525f1, 0xcabe7fef,
+        0x48310f59},
+       {0x29b4faff, 0x00000024, 0x0000006e, 0xca13751e, 0x993648e0,
+        0x783a4213},
+       {0x29bfb1dc, 0x0000000b, 0x00000244, 0x436c43f7, 0x429f7a59,
+        0x9e8efd41},
+       {0x86ae934b, 0x00000035, 0x00000104, 0x0760ec93, 0x9cf7d0f4,
+        0xfc3d34a5},
+       {0xc4c1024e, 0x0000002e, 0x000006b1, 0x6516a3ec, 0x19321f9c,
+        0x17a52ae2},
+       {0x3287a80a, 0x00000026, 0x00000496, 0x0b257eb1, 0x754ebd51,
+        0x886d935a},
+       {0xa4db423e, 0x00000023, 0x0000045d, 0x9b3a66dc, 0x873e9f11,
+        0xeaaeaeb2},
+       {0x7a1078df, 0x00000015, 0x0000014a, 0x8c2484c5, 0x6a628659,
+        0x8e900a4b},
+       {0x6048bd5b, 0x00000006, 0x0000006a, 0x897e3559, 0xac9961af,
+        0xd74662b1},
+       {0xd8f9ea20, 0x0000003d, 0x00000277, 0x60eb905b, 0xed2aaf99,
+        0xd26752ba},
+       {0xea5ec3b4, 0x0000002a, 0x000004fe, 0x869965dc, 0x6c1f833b,
+        0x8b1fcd62},
+       {0x2dfb005d, 0x00000016, 0x00000345, 0x6a3b117e, 0xf05e8521,
+        0xf54342fe},
+       {0x5a214ade, 0x00000020, 0x000005b6, 0x467f70be, 0xcb22ccd3,
+        0x5b95b988},
+       {0xf0ab9cca, 0x00000032, 0x00000515, 0xed223df3, 0x7f3ef01d,
+        0x2e1176be},
+       {0x91b444f9, 0x0000002e, 0x000007f8, 0x84e9a983, 0x5676756f,
+        0x66120546},
+       {0x1b5d2ddb, 0x0000002e, 0x0000012c, 0xba638c4c, 0x3f42047b,
+        0xf256a5cc},
+       {0xd824d1bb, 0x0000003a, 0x000007b5, 0x6288653b, 0x3a3ebea0,
+        0x4af1dd69},
+       {0x0470180c, 0x00000034, 0x000001f0, 0x9d5b80d6, 0x3de08195,
+        0x56f0a04a},
+       {0xffaa3a3f, 0x00000036, 0x00000299, 0xf3a82ab8, 0x53e0c13d,
+        0x74f6b6b2},
+       {0x6406cfeb, 0x00000023, 0x00000600, 0xa920b8e8, 0xe4e2acf4,
+        0x085951fd},
+       {0xb24aaa38, 0x0000003e, 0x000004a1, 0x657cc328, 0x5077b2c3,
+        0xc65387eb},
+       {0x58b2ab7c, 0x00000039, 0x000002b4, 0x3a17ee7e, 0x9dcb3643,
+        0x1ca9257b},
+       {0x3db85970, 0x00000006, 0x000002b6, 0x95268b59, 0xb9812c10,
+        0xfd196d76},
+       {0x857830c5, 0x00000003, 0x00000590, 0x4ef439d5, 0xf042161d,
+        0x5ef88339},
+       {0xe1fcd978, 0x0000003e, 0x000007d8, 0xae8d8699, 0xce0a1ef5,
+        0x2c3714d9},
+       {0xb982a768, 0x00000016, 0x000006e0, 0x62fad3df, 0x5f8a067b,
+        0x58576548},
+       {0x1d581ce8, 0x0000001e, 0x0000058b, 0xf0f5da53, 0x26e39eee,
+        0xfd7c57de},
+       {0x2456719b, 0x00000025, 0x00000503, 0x4296ac64, 0xd50e4c14,
+        0xd5fedd59},
+       {0xfae6d8f2, 0x00000000, 0x0000055d, 0x057fdf2e, 0x2a31391a,
+        0x1cc3b17b},
+       {0xcba828e3, 0x00000039, 0x000002ce, 0xe3f22351, 0x8f00877b,
+        0x270eed73},
+       {0x13d25952, 0x0000000a, 0x0000072d, 0x76d4b4cc, 0x5eb67ec3,
+        0x91ecbb11},
+       {0x0342be3f, 0x00000015, 0x00000599, 0xec75d9f1, 0x9d4d2826,
+        0x05ed8d0c},
+       {0xeaa344e0, 0x00000014, 0x000004d8, 0x72a4c981, 0x2064ea06,
+        0x0b09ad5b},
+       {0xbbb52021, 0x0000003b, 0x00000272, 0x04af99fc, 0xaf042d35,
+        0xf8d511fb},
+       {0xb66384dc, 0x0000001d, 0x000007fc, 0xd7629116, 0x782bd801,
+        0x5ad832cc},
+       {0x616c01b6, 0x00000022, 0x000002c8, 0x5b1dab30, 0x783ce7d2,
+        0x1214d196},
+       {0xce2bdaad, 0x00000016, 0x0000062a, 0x932535c8, 0x3f02926d,
+        0x5747218a},
+       {0x00fe84d7, 0x00000005, 0x00000205, 0x850e50aa, 0x753d649c,
+        0xde8f14de},
+       {0xbebdcb4c, 0x00000006, 0x0000055d, 0xbeaa37a2, 0x2d8c9eba,
+        0x3563b7b9},
+       {0xd8b1a02a, 0x00000010, 0x00000387, 0x5017d2fc, 0x503541a5,
+        0x071475d0},
+       {0x3b96cad2, 0x00000036, 0x00000347, 0x1d2372ae, 0x926cd90b,
+        0x54c79d60},
+       {0xc94c1ed7, 0x00000005, 0x0000038b, 0x9e9fdb22, 0x144a9178,
+        0x4c53eee6},
+       {0x1aad454e, 0x00000025, 0x000002b2, 0xc3f6315c, 0x5c7a35b3,
+        0x10137a3c},
+       {0xa4fec9a6, 0x00000000, 0x000006d6, 0x90be5080, 0xa4107605,
+        0xaa9d6c73},
+       {0x1bbe71e2, 0x0000001f, 0x000002fd, 0x4e504c3b, 0x284ccaf1,
+        0xb63d23e7},
+       {0x4201c7e4, 0x00000002, 0x000002b7, 0x7822e3f9, 0x0cc912a9,
+        0x7f53e9cf},
+       {0x23fddc96, 0x00000003, 0x00000627, 0x8a385125, 0x07767e78,
+        0x13c1cd83},
+       {0xd82ba25c, 0x00000016, 0x0000063e, 0x98e4148a, 0x283330c9,
+        0x49ff5867},
+       {0x786f2032, 0x0000002d, 0x0000060f, 0xf201600a, 0xf561bfcd,
+        0x8467f211},
+       {0xfebe4e1f, 0x0000002a, 0x000004f2, 0x95e51961, 0xfd80dcab,
+        0x3f9683b2},
+       {0x1a6e0a39, 0x00000008, 0x00000672, 0x8af6c2a5, 0x78dd84cb,
+        0x76a3f874},
+       {0x56000ab8, 0x0000000e, 0x000000e5, 0x36bacb8f, 0x22ee1f77,
+        0x863b702f},
+       {0x4717fe0c, 0x00000000, 0x000006ec, 0x8439f342, 0x5c8e03da,
+        0xdc6c58ff},
+       {0xd5d5d68e, 0x0000003c, 0x000003a3, 0x46fff083, 0x177d1b39,
+        0x0622cc95},
+       {0xc25dd6c6, 0x00000024, 0x000006c0, 0x5ceb8eb4, 0x892b0d16,
+        0xe85605cd},
+       {0xe9b11300, 0x00000023, 0x00000683, 0x07a5d59a, 0x6c6a3208,
+        0x31da5f06},
+       {0x95cd285e, 0x00000001, 0x00000047, 0x7b3a4368, 0x0202c07e,
+        0xa1f2e784},
+       {0xd9245a25, 0x0000001e, 0x000003a6, 0xd33c1841, 0x1936c0d5,
+        0xb07cc616},
+       {0x103279db, 0x00000006, 0x0000039b, 0xca09b8a0, 0x77d62892,
+        0xbf943b6c},
+       {0x1cba3172, 0x00000027, 0x000001c8, 0xcb377194, 0xebe682db,
+        0x2c01af1c},
+       {0x8f613739, 0x0000000c, 0x000001df, 0xb4b0bc87, 0x7710bd43,
+        0x0fe5f56d},
+       {0x1c6aa90d, 0x0000001b, 0x0000053c, 0x70559245, 0xda7894ac,
+        0xf8943b2d},
+       {0xaabe5b93, 0x0000003d, 0x00000715, 0xcdbf42fa, 0x0c3b99e7,
+        0xe4d89272},
+       {0xf15dd038, 0x00000006, 0x000006db, 0x6e104aea, 0x8d5967f2,
+        0x7c2f6bbb},
+       {0x584dd49c, 0x00000020, 0x000007bc, 0x36b6cfd6, 0xad4e23b2,
+        0xabbf388b},
+       {0x5d8c9506, 0x00000020, 0x00000470, 0x4c62378e, 0x31d92640,
+        0x1dca1f4e},
+       {0xb80d17b0, 0x00000032, 0x00000346, 0x22a5bb88, 0x9a7ec89f,
+        0x5c170e23},
+       {0xdaf0592e, 0x00000023, 0x000007b0, 0x3cab3f99, 0x9b1fdd99,
+        0xc0e9d672},
+       {0x4793cc85, 0x0000000d, 0x00000706, 0xe82e04f6, 0xed3db6b7,
+        0xc18bdc86},
+       {0x82ebf64e, 0x00000009, 0x000007c3, 0x69d590a9, 0x9efa8499,
+        0xa874fcdd},
+       {0xb18a0319, 0x00000026, 0x000007db, 0x1cf98dcc, 0x8fa9ad6a,
+        0x9dc0bb48},
+};
 
-}
-#endif
+#include <linux/time.h>
 
-static void bytereverse(unsigned char *buf, size_t len)
+static int __init crc32c_test(void)
 {
-       while (len--) {
-               unsigned char x = bitrev8(*buf);
-               *buf++ = x;
+       int i;
+       int errors = 0;
+       int bytes = 0;
+       struct timespec start, stop;
+       u64 nsec;
+       unsigned long flags;
+
+       /* keep static to prevent cache warming code from
+        * getting eliminated by the compiler */
+       static u32 crc;
+
+       /* pre-warm the cache */
+       for (i = 0; i < 100; i++) {
+               bytes += 2*test[i].length;
+
+               crc ^= __crc32c_le(test[i].crc, test_buf +
+                   test[i].start, test[i].length);
        }
-}
 
-static void random_garbage(unsigned char *buf, size_t len)
-{
-       while (len--)
-               *buf++ = (unsigned char) random();
-}
+       /* reduce OS noise */
+       local_irq_save(flags);
+       local_irq_disable();
 
-#if 0                          /* Not used at present */
-static void store_le(u32 x, unsigned char *buf)
-{
-       buf[0] = (unsigned char) x;
-       buf[1] = (unsigned char) (x >> 8);
-       buf[2] = (unsigned char) (x >> 16);
-       buf[3] = (unsigned char) (x >> 24);
-}
-#endif
+       getnstimeofday(&start);
+       for (i = 0; i < 100; i++) {
+               if (test[i].crc32c_le != __crc32c_le(test[i].crc, test_buf +
+                   test[i].start, test[i].length))
+                       errors++;
+       }
+       getnstimeofday(&stop);
 
-static void store_be(u32 x, unsigned char *buf)
-{
-       buf[0] = (unsigned char) (x >> 24);
-       buf[1] = (unsigned char) (x >> 16);
-       buf[2] = (unsigned char) (x >> 8);
-       buf[3] = (unsigned char) x;
+       local_irq_restore(flags);
+       local_irq_enable();
+
+       nsec = stop.tv_nsec - start.tv_nsec +
+               1000000000 * (stop.tv_sec - start.tv_sec);
+
+       pr_info("crc32c: CRC_LE_BITS = %d\n", CRC_LE_BITS);
+
+       if (errors)
+               pr_warn("crc32c: %d self tests failed\n", errors);
+       else {
+               pr_info("crc32c: self tests passed, processed %d bytes in %lld nsec\n",
+                       bytes, nsec);
+       }
+
+       return 0;
 }
 
-/*
- * This checks that CRC(buf + CRC(buf)) = 0, and that
- * CRC commutes with bit-reversal.  This has the side effect
- * of bytewise bit-reversing the input buffer, and returns
- * the CRC of the reversed buffer.
- */
-static u32 test_step(u32 init, unsigned char *buf, size_t len)
+static int __init crc32_test(void)
 {
-       u32 crc1, crc2;
-       size_t i;
+       int i;
+       int errors = 0;
+       int bytes = 0;
+       struct timespec start, stop;
+       u64 nsec;
+       unsigned long flags;
+
+       /* keep static to prevent cache warming code from
+        * getting eliminated by the compiler */
+       static u32 crc;
+
+       /* pre-warm the cache */
+       for (i = 0; i < 100; i++) {
+               bytes += 2*test[i].length;
 
-       crc1 = crc32_be(init, buf, len);
-       store_be(crc1, buf + len);
-       crc2 = crc32_be(init, buf, len + 4);
-       if (crc2)
-               printf("\nCRC cancellation fail: 0x%08x should be 0\n",
-                      crc2);
-
-       for (i = 0; i <= len + 4; i++) {
-               crc2 = crc32_be(init, buf, i);
-               crc2 = crc32_be(crc2, buf + i, len + 4 - i);
-               if (crc2)
-                       printf("\nCRC split fail: 0x%08x\n", crc2);
+               crc ^= crc32_le(test[i].crc, test_buf +
+                   test[i].start, test[i].length);
+
+               crc ^= crc32_be(test[i].crc, test_buf +
+                   test[i].start, test[i].length);
        }
 
-       /* Now swap it around for the other test */
-
-       bytereverse(buf, len + 4);
-       init = bitrev32(init);
-       crc2 = bitrev32(crc1);
-       if (crc1 != bitrev32(crc2))
-               printf("\nBit reversal fail: 0x%08x -> 0x%08x -> 0x%08x\n",
-                      crc1, crc2, bitrev32(crc2));
-       crc1 = crc32_le(init, buf, len);
-       if (crc1 != crc2)
-               printf("\nCRC endianness fail: 0x%08x != 0x%08x\n", crc1,
-                      crc2);
-       crc2 = crc32_le(init, buf, len + 4);
-       if (crc2)
-               printf("\nCRC cancellation fail: 0x%08x should be 0\n",
-                      crc2);
-
-       for (i = 0; i <= len + 4; i++) {
-               crc2 = crc32_le(init, buf, i);
-               crc2 = crc32_le(crc2, buf + i, len + 4 - i);
-               if (crc2)
-                       printf("\nCRC split fail: 0x%08x\n", crc2);
+       /* reduce OS noise */
+       local_irq_save(flags);
+       local_irq_disable();
+
+       getnstimeofday(&start);
+       for (i = 0; i < 100; i++) {
+               if (test[i].crc_le != crc32_le(test[i].crc, test_buf +
+                   test[i].start, test[i].length))
+                       errors++;
+
+               if (test[i].crc_be != crc32_be(test[i].crc, test_buf +
+                   test[i].start, test[i].length))
+                       errors++;
        }
+       getnstimeofday(&stop);
 
-       return crc1;
-}
+       local_irq_restore(flags);
+       local_irq_enable();
 
-#define SIZE 64
-#define INIT1 0
-#define INIT2 0
+       nsec = stop.tv_nsec - start.tv_nsec +
+               1000000000 * (stop.tv_sec - start.tv_sec);
 
-int main(void)
-{
-       unsigned char buf1[SIZE + 4];
-       unsigned char buf2[SIZE + 4];
-       unsigned char buf3[SIZE + 4];
-       int i, j;
-       u32 crc1, crc2, crc3;
-
-       for (i = 0; i <= SIZE; i++) {
-               printf("\rTesting length %d...", i);
-               fflush(stdout);
-               random_garbage(buf1, i);
-               random_garbage(buf2, i);
-               for (j = 0; j < i; j++)
-                       buf3[j] = buf1[j] ^ buf2[j];
-
-               crc1 = test_step(INIT1, buf1, i);
-               crc2 = test_step(INIT2, buf2, i);
-               /* Now check that CRC(buf1 ^ buf2) = CRC(buf1) ^ CRC(buf2) */
-               crc3 = test_step(INIT1 ^ INIT2, buf3, i);
-               if (crc3 != (crc1 ^ crc2))
-                       printf("CRC XOR fail: 0x%08x != 0x%08x ^ 0x%08x\n",
-                              crc3, crc1, crc2);
+       pr_info("crc32: CRC_LE_BITS = %d, CRC_BE BITS = %d\n",
+                CRC_LE_BITS, CRC_BE_BITS);
+
+       if (errors)
+               pr_warn("crc32: %d self tests failed\n", errors);
+       else {
+               pr_info("crc32: self tests passed, processed %d bytes in %lld nsec\n",
+                       bytes, nsec);
        }
-       printf("\nAll test complete.  No failures expected.\n");
+
        return 0;
 }
 
-#endif                         /* UNITTEST */
+static int __init crc32test_init(void)
+{
+       crc32_test();
+       crc32c_test();
+       return 0;
+}
+
+static void __exit crc32_exit(void)
+{
+}
+
+module_init(crc32test_init);
+module_exit(crc32_exit);
+#endif /* CONFIG_CRC32_SELFTEST */
index 9b6773d..64cba2c 100644 (file)
@@ -6,27 +6,67 @@
 #define CRCPOLY_LE 0xedb88320
 #define CRCPOLY_BE 0x04c11db7
 
-/* How many bits at a time to use.  Requires a table of 4<<CRC_xx_BITS bytes. */
-/* For less performance-sensitive, use 4 */
-#ifndef CRC_LE_BITS 
+/*
+ * This is the CRC32c polynomial, as outlined by Castagnoli.
+ * x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+
+ * x^8+x^6+x^0
+ */
+#define CRC32C_POLY_LE 0x82F63B78
+
+/* Try to choose an implementation variant via Kconfig */
+#ifdef CONFIG_CRC32_SLICEBY8
+# define CRC_LE_BITS 64
+# define CRC_BE_BITS 64
+#endif
+#ifdef CONFIG_CRC32_SLICEBY4
+# define CRC_LE_BITS 32
+# define CRC_BE_BITS 32
+#endif
+#ifdef CONFIG_CRC32_SARWATE
 # define CRC_LE_BITS 8
+# define CRC_BE_BITS 8
+#endif
+#ifdef CONFIG_CRC32_BIT
+# define CRC_LE_BITS 1
+# define CRC_BE_BITS 1
+#endif
+
+/*
+ * How many bits at a time to use.  Valid values are 1, 2, 4, 8, 32 and 64.
+ * For less performance-sensitive, use 4 or 8 to save table size.
+ * For larger systems choose same as CPU architecture as default.
+ * This works well on X86_64, SPARC64 systems. This may require some
+ * elaboration after experiments with other architectures.
+ */
+#ifndef CRC_LE_BITS
+#  ifdef CONFIG_64BIT
+#  define CRC_LE_BITS 64
+#  else
+#  define CRC_LE_BITS 32
+#  endif
 #endif
 #ifndef CRC_BE_BITS
-# define CRC_BE_BITS 8
+#  ifdef CONFIG_64BIT
+#  define CRC_BE_BITS 64
+#  else
+#  define CRC_BE_BITS 32
+#  endif
 #endif
 
 /*
  * Little-endian CRC computation.  Used with serial bit streams sent
  * lsbit-first.  Be sure to use cpu_to_le32() to append the computed CRC.
  */
-#if CRC_LE_BITS > 8 || CRC_LE_BITS < 1 || CRC_LE_BITS & CRC_LE_BITS-1
-# error CRC_LE_BITS must be a power of 2 between 1 and 8
+#if CRC_LE_BITS > 64 || CRC_LE_BITS < 1 || CRC_LE_BITS == 16 || \
+       CRC_LE_BITS & CRC_LE_BITS-1
+# error "CRC_LE_BITS must be one of {1, 2, 4, 8, 32, 64}"
 #endif
 
 /*
  * Big-endian CRC computation.  Used with serial bit streams sent
  * msbit-first.  Be sure to use cpu_to_be32() to append the computed CRC.
  */
-#if CRC_BE_BITS > 8 || CRC_BE_BITS < 1 || CRC_BE_BITS & CRC_BE_BITS-1
-# error CRC_BE_BITS must be a power of 2 between 1 and 8
+#if CRC_BE_BITS > 64 || CRC_BE_BITS < 1 || CRC_BE_BITS == 16 || \
+       CRC_BE_BITS & CRC_BE_BITS-1
+# error "CRC_BE_BITS must be one of {1, 2, 4, 8, 32, 64}"
 #endif
index 85d0e41..8f8d543 100644 (file)
@@ -1,14 +1,29 @@
 #include <stdio.h>
+#include "../include/generated/autoconf.h"
 #include "crc32defs.h"
 #include <inttypes.h>
 
 #define ENTRIES_PER_LINE 4
 
-#define LE_TABLE_SIZE (1 << CRC_LE_BITS)
-#define BE_TABLE_SIZE (1 << CRC_BE_BITS)
+#if CRC_LE_BITS > 8
+# define LE_TABLE_ROWS (CRC_LE_BITS/8)
+# define LE_TABLE_SIZE 256
+#else
+# define LE_TABLE_ROWS 1
+# define LE_TABLE_SIZE (1 << CRC_LE_BITS)
+#endif
 
-static uint32_t crc32table_le[4][LE_TABLE_SIZE];
-static uint32_t crc32table_be[4][BE_TABLE_SIZE];
+#if CRC_BE_BITS > 8
+# define BE_TABLE_ROWS (CRC_BE_BITS/8)
+# define BE_TABLE_SIZE 256
+#else
+# define BE_TABLE_ROWS 1
+# define BE_TABLE_SIZE (1 << CRC_BE_BITS)
+#endif
+
+static uint32_t crc32table_le[LE_TABLE_ROWS][256];
+static uint32_t crc32table_be[BE_TABLE_ROWS][256];
+static uint32_t crc32ctable_le[LE_TABLE_ROWS][256];
 
 /**
  * crc32init_le() - allocate and initialize LE table data
@@ -17,27 +32,38 @@ static uint32_t crc32table_be[4][BE_TABLE_SIZE];
  * fact that crctable[i^j] = crctable[i] ^ crctable[j].
  *
  */
-static void crc32init_le(void)
+static void crc32init_le_generic(const uint32_t polynomial,
+                                uint32_t (*tab)[256])
 {
        unsigned i, j;
        uint32_t crc = 1;
 
-       crc32table_le[0][0] = 0;
+       tab[0][0] = 0;
 
-       for (i = 1 << (CRC_LE_BITS - 1); i; i >>= 1) {
-               crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
+       for (i = LE_TABLE_SIZE >> 1; i; i >>= 1) {
+               crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0);
                for (j = 0; j < LE_TABLE_SIZE; j += 2 * i)
-                       crc32table_le[0][i + j] = crc ^ crc32table_le[0][j];
+                       tab[0][i + j] = crc ^ tab[0][j];
        }
        for (i = 0; i < LE_TABLE_SIZE; i++) {
-               crc = crc32table_le[0][i];
-               for (j = 1; j < 4; j++) {
-                       crc = crc32table_le[0][crc & 0xff] ^ (crc >> 8);
-                       crc32table_le[j][i] = crc;
+               crc = tab[0][i];
+               for (j = 1; j < LE_TABLE_ROWS; j++) {
+                       crc = tab[0][crc & 0xff] ^ (crc >> 8);
+                       tab[j][i] = crc;
                }
        }
 }
 
+static void crc32init_le(void)
+{
+       crc32init_le_generic(CRCPOLY_LE, crc32table_le);
+}
+
+static void crc32cinit_le(void)
+{
+       crc32init_le_generic(CRC32C_POLY_LE, crc32ctable_le);
+}
+
 /**
  * crc32init_be() - allocate and initialize BE table data
  */
@@ -55,18 +81,18 @@ static void crc32init_be(void)
        }
        for (i = 0; i < BE_TABLE_SIZE; i++) {
                crc = crc32table_be[0][i];
-               for (j = 1; j < 4; j++) {
+               for (j = 1; j < BE_TABLE_ROWS; j++) {
                        crc = crc32table_be[0][(crc >> 24) & 0xff] ^ (crc << 8);
                        crc32table_be[j][i] = crc;
                }
        }
 }
 
-static void output_table(uint32_t table[4][256], int len, char *trans)
+static void output_table(uint32_t (*table)[256], int rows, int len, char *trans)
 {
        int i, j;
 
-       for (j = 0 ; j < 4; j++) {
+       for (j = 0 ; j < rows; j++) {
                printf("{");
                for (i = 0; i < len - 1; i++) {
                        if (i % ENTRIES_PER_LINE == 0)
@@ -83,15 +109,30 @@ int main(int argc, char** argv)
 
        if (CRC_LE_BITS > 1) {
                crc32init_le();
-               printf("static const u32 crc32table_le[4][256] = {");
-               output_table(crc32table_le, LE_TABLE_SIZE, "tole");
+               printf("static const u32 __cacheline_aligned "
+                      "crc32table_le[%d][%d] = {",
+                      LE_TABLE_ROWS, LE_TABLE_SIZE);
+               output_table(crc32table_le, LE_TABLE_ROWS,
+                            LE_TABLE_SIZE, "tole");
                printf("};\n");
        }
 
        if (CRC_BE_BITS > 1) {
                crc32init_be();
-               printf("static const u32 crc32table_be[4][256] = {");
-               output_table(crc32table_be, BE_TABLE_SIZE, "tobe");
+               printf("static const u32 __cacheline_aligned "
+                      "crc32table_be[%d][%d] = {",
+                      BE_TABLE_ROWS, BE_TABLE_SIZE);
+               output_table(crc32table_be, LE_TABLE_ROWS,
+                            BE_TABLE_SIZE, "tobe");
+               printf("};\n");
+       }
+       if (CRC_LE_BITS > 1) {
+               crc32cinit_le();
+               printf("static const u32 __cacheline_aligned "
+                      "crc32ctable_le[%d][%d] = {",
+                      LE_TABLE_ROWS, LE_TABLE_SIZE);
+               output_table(crc32ctable_le, LE_TABLE_ROWS,
+                            LE_TABLE_SIZE, "tole");
                printf("};\n");
        }
 
index ccfd850..8d443af 100644 (file)
@@ -85,6 +85,17 @@ static inline unsigned long prio_tree_maxindex(unsigned int bits)
        return index_bits_to_maxindex[bits - 1];
 }
 
+static void prio_set_parent(struct prio_tree_node *parent,
+                           struct prio_tree_node *child, bool left)
+{
+       if (left)
+               parent->left = child;
+       else
+               parent->right = child;
+
+       child->parent = parent;
+}
+
 /*
  * Extend a priority search tree so that it can store a node with heap_index
  * max_heap_index. In the worst case, this algorithm takes O((log n)^2).
@@ -94,45 +105,32 @@ static inline unsigned long prio_tree_maxindex(unsigned int bits)
 static struct prio_tree_node *prio_tree_expand(struct prio_tree_root *root,
                struct prio_tree_node *node, unsigned long max_heap_index)
 {
-       struct prio_tree_node *first = NULL, *prev, *last = NULL;
+       struct prio_tree_node *prev;
 
        if (max_heap_index > prio_tree_maxindex(root->index_bits))
                root->index_bits++;
 
+       prev = node;
+       INIT_PRIO_TREE_NODE(node);
+
        while (max_heap_index > prio_tree_maxindex(root->index_bits)) {
+               struct prio_tree_node *tmp = root->prio_tree_node;
+
                root->index_bits++;
 
                if (prio_tree_empty(root))
                        continue;
 
-               if (first == NULL) {
-                       first = root->prio_tree_node;
-                       prio_tree_remove(root, root->prio_tree_node);
-                       INIT_PRIO_TREE_NODE(first);
-                       last = first;
-               } else {
-                       prev = last;
-                       last = root->prio_tree_node;
-                       prio_tree_remove(root, root->prio_tree_node);
-                       INIT_PRIO_TREE_NODE(last);
-                       prev->left = last;
-                       last->parent = prev;
-               }
-       }
-
-       INIT_PRIO_TREE_NODE(node);
-
-       if (first) {
-               node->left = first;
-               first->parent = node;
-       } else
-               last = node;
+               prio_tree_remove(root, root->prio_tree_node);
+               INIT_PRIO_TREE_NODE(tmp);
 
-       if (!prio_tree_empty(root)) {
-               last->left = root->prio_tree_node;
-               last->left->parent = last;
+               prio_set_parent(prev, tmp, true);
+               prev = tmp;
        }
 
+       if (!prio_tree_empty(root))
+               prio_set_parent(prev, root->prio_tree_node, true);
+
        root->prio_tree_node = node;
        return node;
 }
@@ -151,25 +149,15 @@ struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
                 * We can reduce root->index_bits here. However, it is complex
                 * and does not help much to improve performance (IMO).
                 */
-               node->parent = node;
                root->prio_tree_node = node;
-       } else {
-               node->parent = old->parent;
-               if (old->parent->left == old)
-                       old->parent->left = node;
-               else
-                       old->parent->right = node;
-       }
+       } else
+               prio_set_parent(old->parent, node, old->parent->left == old);
 
-       if (!prio_tree_left_empty(old)) {
-               node->left = old->left;
-               old->left->parent = node;
-       }
+       if (!prio_tree_left_empty(old))
+               prio_set_parent(node, old->left, true);
 
-       if (!prio_tree_right_empty(old)) {
-               node->right = old->right;
-               old->right->parent = node;
-       }
+       if (!prio_tree_right_empty(old))
+               prio_set_parent(node, old->right, false);
 
        return old;
 }
@@ -229,16 +217,14 @@ struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
                if (index & mask) {
                        if (prio_tree_right_empty(cur)) {
                                INIT_PRIO_TREE_NODE(node);
-                               cur->right = node;
-                               node->parent = cur;
+                               prio_set_parent(cur, node, false);
                                return res;
                        } else
                                cur = cur->right;
                } else {
                        if (prio_tree_left_empty(cur)) {
                                INIT_PRIO_TREE_NODE(node);
-                               cur->left = node;
-                               node->parent = cur;
+                               prio_set_parent(cur, node, true);
                                return res;
                        } else
                                cur = cur->left;
@@ -305,6 +291,40 @@ void prio_tree_remove(struct prio_tree_root *root, struct prio_tree_node *node)
                cur = prio_tree_replace(root, cur->parent, cur);
 }
 
+static void iter_walk_down(struct prio_tree_iter *iter)
+{
+       iter->mask >>= 1;
+       if (iter->mask) {
+               if (iter->size_level)
+                       iter->size_level++;
+               return;
+       }
+
+       if (iter->size_level) {
+               BUG_ON(!prio_tree_left_empty(iter->cur));
+               BUG_ON(!prio_tree_right_empty(iter->cur));
+               iter->size_level++;
+               iter->mask = ULONG_MAX;
+       } else {
+               iter->size_level = 1;
+               iter->mask = 1UL << (BITS_PER_LONG - 1);
+       }
+}
+
+static void iter_walk_up(struct prio_tree_iter *iter)
+{
+       if (iter->mask == ULONG_MAX)
+               iter->mask = 1UL;
+       else if (iter->size_level == 1)
+               iter->mask = 1UL;
+       else
+               iter->mask <<= 1;
+       if (iter->size_level)
+               iter->size_level--;
+       if (!iter->size_level && (iter->value & iter->mask))
+               iter->value ^= iter->mask;
+}
+
 /*
  * Following functions help to enumerate all prio_tree_nodes in the tree that
  * overlap with the input interval X [radix_index, heap_index]. The enumeration
@@ -323,21 +343,7 @@ static struct prio_tree_node *prio_tree_left(struct prio_tree_iter *iter,
 
        if (iter->r_index <= *h_index) {
                iter->cur = iter->cur->left;
-               iter->mask >>= 1;
-               if (iter->mask) {
-                       if (iter->size_level)
-                               iter->size_level++;
-               } else {
-                       if (iter->size_level) {
-                               BUG_ON(!prio_tree_left_empty(iter->cur));
-                               BUG_ON(!prio_tree_right_empty(iter->cur));
-                               iter->size_level++;
-                               iter->mask = ULONG_MAX;
-                       } else {
-                               iter->size_level = 1;
-                               iter->mask = 1UL << (BITS_PER_LONG - 1);
-                       }
-               }
+               iter_walk_down(iter);
                return iter->cur;
        }
 
@@ -364,22 +370,7 @@ static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter,
 
        if (iter->r_index <= *h_index) {
                iter->cur = iter->cur->right;
-               iter->mask >>= 1;
-               iter->value = value;
-               if (iter->mask) {
-                       if (iter->size_level)
-                               iter->size_level++;
-               } else {
-                       if (iter->size_level) {
-                               BUG_ON(!prio_tree_left_empty(iter->cur));
-                               BUG_ON(!prio_tree_right_empty(iter->cur));
-                               iter->size_level++;
-                               iter->mask = ULONG_MAX;
-                       } else {
-                               iter->size_level = 1;
-                               iter->mask = 1UL << (BITS_PER_LONG - 1);
-                       }
-               }
+               iter_walk_down(iter);
                return iter->cur;
        }
 
@@ -389,16 +380,7 @@ static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter,
 static struct prio_tree_node *prio_tree_parent(struct prio_tree_iter *iter)
 {
        iter->cur = iter->cur->parent;
-       if (iter->mask == ULONG_MAX)
-               iter->mask = 1UL;
-       else if (iter->size_level == 1)
-               iter->mask = 1UL;
-       else
-               iter->mask <<= 1;
-       if (iter->size_level)
-               iter->size_level--;
-       if (!iter->size_level && (iter->value & iter->mask))
-               iter->value ^= iter->mask;
+       iter_walk_up(iter);
        return iter->cur;
 }
 
index dc4a863..3a03782 100644 (file)
@@ -785,12 +785,24 @@ void *memchr_inv(const void *start, int c, size_t bytes)
        if (bytes <= 16)
                return check_bytes8(start, value, bytes);
 
-       value64 = value | value << 8 | value << 16 | value << 24;
-       value64 = (value64 & 0xffffffff) | value64 << 32;
-       prefix = 8 - ((unsigned long)start) % 8;
+       value64 = value;
+#if defined(ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
+       value64 *= 0x0101010101010101;
+#elif defined(ARCH_HAS_FAST_MULTIPLIER)
+       value64 *= 0x01010101;
+       value64 |= value64 << 32;
+#else
+       value64 |= value64 << 8;
+       value64 |= value64 << 16;
+       value64 |= value64 << 32;
+#endif
 
+       prefix = (unsigned long)start % 8;
        if (prefix) {
-               u8 *r = check_bytes8(start, value, prefix);
+               u8 *r;
+
+               prefix = 8 - prefix;
+               r = check_bytes8(start, value, prefix);
                if (r)
                        return r;
                start += prefix;
index 38e612e..385c402 100644 (file)
@@ -212,6 +212,26 @@ char *put_dec(char *buf, unsigned long long num)
        }
 }
 
+/*
+ * Convert passed number to decimal string.
+ * Returns the length of string.  On buffer overflow, returns 0.
+ *
+ * If speed is not important, use snprintf(). It's easy to read the code.
+ */
+int num_to_str(char *buf, int size, unsigned long long num)
+{
+       char tmp[21];           /* Enough for 2^64 in decimal */
+       int idx, len;
+
+       len = put_dec(tmp, num) - tmp;
+
+       if (len > size)
+               return 0;
+       for (idx = 0; idx < len; ++idx)
+               buf[idx] = tmp[len - idx - 1];
+       return  len;
+}
+
 #define ZEROPAD        1               /* pad with zero */
 #define SIGN   2               /* unsigned/signed long */
 #define PLUS   4               /* show plus */
index afa057a..b8ce6f4 100644 (file)
@@ -2331,16 +2331,23 @@ void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
                if (huge_pmd_unshare(mm, &address, ptep))
                        continue;
 
+               pte = huge_ptep_get(ptep);
+               if (huge_pte_none(pte))
+                       continue;
+
+               /*
+                * HWPoisoned hugepage is already unmapped and dropped reference
+                */
+               if (unlikely(is_hugetlb_entry_hwpoisoned(pte)))
+                       continue;
+
+               page = pte_page(pte);
                /*
                 * If a reference page is supplied, it is because a specific
                 * page is being unmapped, not a range. Ensure the page we
                 * are about to unmap is the actual page of interest.
                 */
                if (ref_page) {
-                       pte = huge_ptep_get(ptep);
-                       if (huge_pte_none(pte))
-                               continue;
-                       page = pte_page(pte);
                        if (page != ref_page)
                                continue;
 
@@ -2353,16 +2360,6 @@ void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
                }
 
                pte = huge_ptep_get_and_clear(mm, address, ptep);
-               if (huge_pte_none(pte))
-                       continue;
-
-               /*
-                * HWPoisoned hugepage is already unmapped and dropped reference
-                */
-               if (unlikely(is_hugetlb_entry_hwpoisoned(pte)))
-                       continue;
-
-               page = pte_page(pte);
                if (pte_dirty(pte))
                        set_page_dirty(page);
                list_add(&page->lru, &page_list);
index f5ab745..1ccbba5 100644 (file)
@@ -65,6 +65,12 @@ static long madvise_behavior(struct vm_area_struct * vma,
                }
                new_flags &= ~VM_DONTCOPY;
                break;
+       case MADV_DONTDUMP:
+               new_flags |= VM_NODUMP;
+               break;
+       case MADV_DODUMP:
+               new_flags &= ~VM_NODUMP;
+               break;
        case MADV_MERGEABLE:
        case MADV_UNMERGEABLE:
                error = ksm_madvise(vma, start, end, behavior, &new_flags);
@@ -293,6 +299,8 @@ madvise_behavior_valid(int behavior)
        case MADV_HUGEPAGE:
        case MADV_NOHUGEPAGE:
 #endif
+       case MADV_DONTDUMP:
+       case MADV_DODUMP:
                return 1;
 
        default:
index 3416b6e..6105f47 100644 (file)
@@ -3623,13 +3623,7 @@ static int __init gate_vma_init(void)
        gate_vma.vm_end = FIXADDR_USER_END;
        gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
        gate_vma.vm_page_prot = __P101;
-       /*
-        * Make sure the vDSO gets into every core dump.
-        * Dumping its contents makes post-mortem fully interpretable later
-        * without matching up the same kernel and hardware config to see
-        * what PC values meant.
-        */
-       gate_vma.vm_flags |= VM_ALWAYSDUMP;
+
        return 0;
 }
 __initcall(gate_vma_init);
index 4198e00..46bf2ed 100644 (file)
@@ -521,11 +521,11 @@ static void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
                        pr_err("Kill process %d (%s) sharing same memory\n",
                                task_pid_nr(p), p->comm);
                        task_unlock(p);
-                       force_sig(SIGKILL, p);
+                       do_send_sig_info(SIGKILL, SEND_SIG_FORCED, p, true);
                }
 
        set_tsk_thread_flag(victim, TIF_MEMDIE);
-       force_sig(SIGKILL, victim);
+       do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, true);
 }
 #undef K
 
index eb4277c..d510353 100644 (file)
@@ -2206,7 +2206,7 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
        }
 
        /* No write status requested, avoid expensive OUT tests. */
-       if (wait && !(wait->key & (POLLWRBAND | POLLWRNORM | POLLOUT)))
+       if (!(poll_requested_events(wait) & (POLLWRBAND|POLLWRNORM|POLLOUT)))
                return mask;
 
        writable = unix_writable(sk);
index a3b9782..de639ee 100755 (executable)
@@ -323,17 +323,22 @@ sub build_types {
                  }x;
        $Type   = qr{
                        $NonptrType
-                       (?:[\s\*]+\s*const|[\s\*]+|(?:\s*\[\s*\])+)?
+                       (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)?
                        (?:\s+$Inline|\s+$Modifier)*
                  }x;
        $Declare        = qr{(?:$Storage\s+)?$Type};
 }
 build_types();
 
-our $match_balanced_parentheses = qr/(\((?:[^\(\)]+|(-1))*\))/;
 
 our $Typecast  = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
-our $LvalOrFunc        = qr{($Lval)\s*($match_balanced_parentheses{0,1})\s*};
+
+# Using $balanced_parens, $LvalOrFunc, or $FuncArg
+# requires at least perl version v5.10.0
+# Any use must be runtime checked with $^V
+
+our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
+our $LvalOrFunc        = qr{($Lval)\s*($balanced_parens{0,1})\s*};
 our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)};
 
 sub deparenthesize {
@@ -1330,6 +1335,36 @@ sub check_absolute_file {
        }
 }
 
+sub pos_last_openparen {
+       my ($line) = @_;
+
+       my $pos = 0;
+
+       my $opens = $line =~ tr/\(/\(/;
+       my $closes = $line =~ tr/\)/\)/;
+
+       my $last_openparen = 0;
+
+       if (($opens == 0) || ($closes >= $opens)) {
+               return -1;
+       }
+
+       my $len = length($line);
+
+       for ($pos = 0; $pos < $len; $pos++) {
+               my $string = substr($line, $pos);
+               if ($string =~ /^($FuncArg|$balanced_parens)/) {
+                       $pos += length($1) - 1;
+               } elsif (substr($line, $pos, 1) eq '(') {
+                       $last_openparen = $pos;
+               } elsif (index($string, '(') == -1) {
+                       last;
+               }
+       }
+
+       return $last_openparen + 1;
+}
+
 sub process {
        my $filename = shift;
 
@@ -1737,6 +1772,21 @@ sub process {
                             "line over 80 characters\n" . $herecurr);
                }
 
+# Check for user-visible strings broken across lines, which breaks the ability
+# to grep for the string.  Limited to strings used as parameters (those
+# following an open parenthesis), which almost completely eliminates false
+# positives, as well as warning only once per parameter rather than once per
+# line of the string.  Make an exception when the previous string ends in a
+# newline (multiple lines in one string constant) or \n\t (common in inline
+# assembly to indent the instruction on the following line).
+               if ($line =~ /^\+\s*"/ &&
+                   $prevline =~ /"\s*$/ &&
+                   $prevline =~ /\(/ &&
+                   $prevrawline !~ /\\n(?:\\t)*"\s*$/) {
+                       WARN("SPLIT_STRING",
+                            "quoted string split across lines\n" . $hereprev);
+               }
+
 # check for spaces before a quoted newline
                if ($rawline =~ /^.*\".*\s\\n/) {
                        WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
@@ -1783,6 +1833,48 @@ sub process {
                             "please, no space before tabs\n" . $herevet);
                }
 
+# check for && or || at the start of a line
+               if ($rawline =~ /^\+\s*(&&|\|\|)/) {
+                       CHK("LOGICAL_CONTINUATIONS",
+                           "Logical continuations should be on the previous line\n" . $hereprev);
+               }
+
+# check multi-line statement indentation matches previous line
+               if ($^V && $^V ge 5.10.0 &&
+                   $prevline =~ /^\+(\t*)(if \(|$Ident\().*(\&\&|\|\||,)\s*$/) {
+                       $prevline =~ /^\+(\t*)(.*)$/;
+                       my $oldindent = $1;
+                       my $rest = $2;
+
+                       my $pos = pos_last_openparen($rest);
+                       if ($pos >= 0) {
+                               $line =~ /^\+([ \t]*)/;
+                               my $newindent = $1;
+
+                               my $goodtabindent = $oldindent .
+                                       "\t" x ($pos / 8) .
+                                       " "  x ($pos % 8);
+                               my $goodspaceindent = $oldindent . " "  x $pos;
+
+                               if ($newindent ne $goodtabindent &&
+                                   $newindent ne $goodspaceindent) {
+                                       CHK("PARENTHESIS_ALIGNMENT",
+                                           "Alignment should match open parenthesis\n" . $hereprev);
+                               }
+                       }
+               }
+
+               if ($line =~ /^\+.*\*[ \t]*\)[ \t]+/) {
+                       CHK("SPACING",
+                           "No space is necessary after a cast\n" . $hereprev);
+               }
+
+               if ($rawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
+                   $prevrawline =~ /^\+[ \t]*$/) {
+                       CHK("BLOCK_COMMENT_STYLE",
+                           "Don't begin block comments with only a /* line, use /* comment...\n" . $hereprev);
+               }
+
 # check for spaces at the beginning of a line.
 # Exceptions:
 #  1) within comments
@@ -2325,7 +2417,7 @@ sub process {
                        my ($where, $prefix) = ($-[1], $1);
                        if ($prefix !~ /$Type\s+$/ &&
                            ($where != 0 || $prefix !~ /^.\s+$/) &&
-                           $prefix !~ /{\s+$/) {
+                           $prefix !~ /[{,]\s+$/) {
                                ERROR("BRACKET_SPACE",
                                      "space prohibited before open square bracket '['\n" . $herecurr);
                        }
@@ -2828,6 +2920,12 @@ sub process {
                        {
                        }
 
+                       # Flatten any obvious string concatentation.
+                       while ($dstat =~ s/("X*")\s*$Ident/$1/ ||
+                              $dstat =~ s/$Ident\s*("X*")/$1/)
+                       {
+                       }
+
                        my $exceptions = qr{
                                $Declare|
                                module_param_named|
@@ -2844,7 +2942,8 @@ sub process {
                        if ($dstat ne '' &&
                            $dstat !~ /^(?:$Ident|-?$Constant),$/ &&                    # 10, // foo(),
                            $dstat !~ /^(?:$Ident|-?$Constant);$/ &&                    # foo();
-                           $dstat !~ /^(?:$Ident|-?$Constant)$/ &&                     # 10 // foo()
+                           $dstat !~ /^[!~-]?(?:$Ident|$Constant)$/ &&         # 10 // foo() // !foo // ~foo // -foo
+                           $dstat !~ /^'X'$/ &&                                        # character constants
                            $dstat !~ /$exceptions/ &&
                            $dstat !~ /^\.$Ident\s*=/ &&                                # .foo =
                            $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&       # do {...} while (...); // do {...} while (...)
@@ -2888,7 +2987,8 @@ sub process {
                        #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
                        #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
                        if ($#chunks > 0 && $level == 0) {
-                               my $allowed = 0;
+                               my @allowed = ();
+                               my $allow = 0;
                                my $seen = 0;
                                my $herectx = $here . "\n";
                                my $ln = $linenr - 1;
@@ -2899,6 +2999,7 @@ sub process {
                                        my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
                                        my $offset = statement_rawlines($whitespace) - 1;
 
+                                       $allowed[$allow] = 0;
                                        #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
 
                                        # We have looked at and allowed this specific line.
@@ -2911,23 +3012,34 @@ sub process {
 
                                        $seen++ if ($block =~ /^\s*{/);
 
-                                       #print "cond<$cond> block<$block> allowed<$allowed>\n";
+                                       #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
                                        if (statement_lines($cond) > 1) {
                                                #print "APW: ALLOWED: cond<$cond>\n";
-                                               $allowed = 1;
+                                               $allowed[$allow] = 1;
                                        }
                                        if ($block =~/\b(?:if|for|while)\b/) {
                                                #print "APW: ALLOWED: block<$block>\n";
-                                               $allowed = 1;
+                                               $allowed[$allow] = 1;
                                        }
                                        if (statement_block_size($block) > 1) {
                                                #print "APW: ALLOWED: lines block<$block>\n";
-                                               $allowed = 1;
+                                               $allowed[$allow] = 1;
                                        }
+                                       $allow++;
                                }
-                               if ($seen && !$allowed) {
-                                       WARN("BRACES",
-                                            "braces {} are not necessary for any arm of this statement\n" . $herectx);
+                               if ($seen) {
+                                       my $sum_allowed = 0;
+                                       foreach (@allowed) {
+                                               $sum_allowed += $_;
+                                       }
+                                       if ($sum_allowed == 0) {
+                                               WARN("BRACES",
+                                                    "braces {} are not necessary for any arm of this statement\n" . $herectx);
+                                       } elsif ($sum_allowed != $allow &&
+                                                $seen != $allow) {
+                                               CHK("BRACES",
+                                                   "braces {} should be used on all arms of this statement\n" . $herectx);
+                                       }
                                }
                        }
                }
@@ -3123,6 +3235,12 @@ sub process {
                             "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr);
                }
 
+# Check for __attribute__ format(scanf, prefer __scanf
+               if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
+                       WARN("PREFER_SCANF",
+                            "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr);
+               }
+
 # check for sizeof(&)
                if ($line =~ /\bsizeof\s*\(\s*\&/) {
                        WARN("SIZEOF_ADDRESS",
@@ -3136,12 +3254,13 @@ sub process {
                }
 
 # Check for misused memsets
-               if (defined $stat &&
+               if ($^V && $^V ge 5.10.0 &&
+                   defined $stat &&
                    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) {
 
                        my $ms_addr = $2;
-                       my $ms_val = $8;
-                       my $ms_size = $14;
+                       my $ms_val = $7;
+                       my $ms_size = $12;
 
                        if ($ms_size =~ /^(0x|)0$/i) {
                                ERROR("MEMSET",
@@ -3153,17 +3272,18 @@ sub process {
                }
 
 # typecasts on min/max could be min_t/max_t
-               if (defined $stat &&
+               if ($^V && $^V ge 5.10.0 &&
+                   defined $stat &&
                    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
-                       if (defined $2 || defined $8) {
+                       if (defined $2 || defined $7) {
                                my $call = $1;
                                my $cast1 = deparenthesize($2);
                                my $arg1 = $3;
-                               my $cast2 = deparenthesize($8);
-                               my $arg2 = $9;
+                               my $cast2 = deparenthesize($7);
+                               my $arg2 = $8;
                                my $cast;
 
-                               if ($cast1 ne "" && $cast2 ne "") {
+                               if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
                                        $cast = "$cast1 or $cast2";
                                } elsif ($cast1 ne "") {
                                        $cast = $cast1;
@@ -3233,22 +3353,30 @@ sub process {
                             "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr);
                }
 
+# check for use of yield()
+               if ($line =~ /\byield\s*\(\s*\)/) {
+                       WARN("YIELD",
+                            "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
+               }
+
 # check for semaphores initialized locked
                if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
                        WARN("CONSIDER_COMPLETION",
                             "consider using a completion\n" . $herecurr);
-
                }
+
 # recommend kstrto* over simple_strto* and strict_strto*
                if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
                        WARN("CONSIDER_KSTRTO",
                             "$1 is obsolete, use k$3 instead\n" . $herecurr);
                }
+
 # check for __initcall(), use device_initcall() explicitly please
                if ($line =~ /^.\s*__initcall\s*\(/) {
                        WARN("USE_DEVICE_INITCALL",
                             "please use device_initcall() instead of __initcall()\n" . $herecurr);
                }
+
 # check for various ops structs, ensure they are const.
                my $struct_ops = qr{acpi_dock_ops|
                                address_space_operations|
@@ -3385,6 +3513,12 @@ sub process {
        }
 
        if ($quiet == 0) {
+
+               if ($^V lt 5.10.0) {
+                       print("NOTE: perl $^V is not modern enough to detect all possible issues.\n");
+                       print("An upgrade to at least perl v5.10.0 is suggested.\n\n");
+               }
+
                # If there were whitespace errors which cleanpatch can fix
                # then suggest that.
                if ($rpt_cleaners) {
@@ -3394,13 +3528,12 @@ sub process {
                }
        }
 
-       if (keys %ignore_type) {
+       if ($quiet == 0 && keys %ignore_type) {
            print "NOTE: Ignored message types:";
            foreach my $ignore (sort keys %ignore_type) {
                print " $ignore";
            }
-           print "\n";
-           print "\n" if ($quiet == 0);
+           print "\n\n";
        }
 
        if ($clean == 1 && $quiet == 0) {
index f32a04c..0948c6b 100755 (executable)
@@ -931,7 +931,7 @@ sub get_maintainer_role {
     my $start = find_starting_index($index);
     my $end = find_ending_index($index);
 
-    my $role;
+    my $role = "unknown";
     my $subsystem = $typevalue[$start];
     if (length($subsystem) > 20) {
        $subsystem = substr($subsystem, 0, 17);
@@ -1027,8 +1027,13 @@ sub add_categories {
                    if ($email_list) {
                        if (!$hash_list_to{lc($list_address)}) {
                            $hash_list_to{lc($list_address)} = 1;
-                           push(@list_to, [$list_address,
-                                           "open list${list_role}"]);
+                           if ($list_additional =~ m/moderated/) {
+                               push(@list_to, [$list_address,
+                                               "moderated list${list_role}"]);
+                           } else {
+                               push(@list_to, [$list_address,
+                                               "open list${list_role}"]);
+                           }
                        }
                    }
                }
index 8246532..cc37903 100644 (file)
@@ -91,7 +91,7 @@ static void umh_keys_cleanup(struct subprocess_info *info)
  * Call a usermode helper with a specific session keyring.
  */
 static int call_usermodehelper_keys(char *path, char **argv, char **envp,
-                        struct key *session_keyring, enum umh_wait wait)
+                                       struct key *session_keyring, int wait)
 {
        gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
        struct subprocess_info *info =
index 6797540..078fac0 100644 (file)
@@ -102,7 +102,7 @@ void tomoyo_load_policy(const char *filename)
        envp[0] = "HOME=/";
        envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
        envp[2] = NULL;
-       call_usermodehelper(argv[0], argv, envp, 1);
+       call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
        tomoyo_check_profile();
 }
 
index 62cdee7..f158483 100644 (file)
@@ -15,7 +15,7 @@
             (bit) = find_next_bit((addr), (size), (bit) + 1))
 
 /* same as for_each_set_bit() but use bit as value to start with */
-#define for_each_set_bit_cont(bit, addr, size) \
+#define for_each_set_bit_from(bit, addr, size) \
        for ((bit) = find_next_bit((addr), (size), (bit));      \
             (bit) < (size);                                    \
             (bit) = find_next_bit((addr), (size), (bit) + 1))