Merge branch 'akpm' (Andrew's patch-bomb)
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() ...
This commit is contained in:
commit
8e3ade251b
|
@ -104,6 +104,8 @@ cpuidle/
|
||||||
- info on CPU_IDLE, CPU idle state management subsystem.
|
- info on CPU_IDLE, CPU idle state management subsystem.
|
||||||
cputopology.txt
|
cputopology.txt
|
||||||
- documentation on how CPU topology info is exported via sysfs.
|
- documentation on how CPU topology info is exported via sysfs.
|
||||||
|
crc32.txt
|
||||||
|
- brief tutorial on CRC computation
|
||||||
cris/
|
cris/
|
||||||
- directory with info about Linux on CRIS architecture.
|
- directory with info about Linux on CRIS architecture.
|
||||||
crypto/
|
crypto/
|
||||||
|
|
|
@ -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,
|
||||||
|
},
|
||||||
|
};
|
|
@ -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.
|
|
@ -43,17 +43,23 @@ Format: 10x mA i.e 10 means 1.0 mA
|
||||||
example platform data:
|
example platform data:
|
||||||
|
|
||||||
Note: chan_nr can have values between 0 and 2.
|
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[] = {
|
static struct lp5521_led_config lp5521_led_config[] = {
|
||||||
{
|
{
|
||||||
|
.name = "red",
|
||||||
.chan_nr = 0,
|
.chan_nr = 0,
|
||||||
.led_current = 50,
|
.led_current = 50,
|
||||||
.max_current = 130,
|
.max_current = 130,
|
||||||
}, {
|
}, {
|
||||||
|
.name = "green",
|
||||||
.chan_nr = 1,
|
.chan_nr = 1,
|
||||||
.led_current = 0,
|
.led_current = 0,
|
||||||
.max_current = 130,
|
.max_current = 130,
|
||||||
}, {
|
}, {
|
||||||
|
.name = "blue",
|
||||||
.chan_nr = 2,
|
.chan_nr = 2,
|
||||||
.led_current = 0,
|
.led_current = 0,
|
||||||
.max_current = 130,
|
.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
|
If the current is set to 0 in the platform data, that channel is
|
||||||
disabled and it is not visible in the sysfs.
|
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
|
||||||
|
|
124
MAINTAINERS
124
MAINTAINERS
|
@ -163,7 +163,7 @@ M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
L: linux-serial@vger.kernel.org
|
L: linux-serial@vger.kernel.org
|
||||||
W: http://serial.sourceforge.net
|
W: http://serial.sourceforge.net
|
||||||
S: Maintained
|
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: drivers/tty/serial/8250*
|
||||||
F: include/linux/serial_8250.h
|
F: include/linux/serial_8250.h
|
||||||
|
|
||||||
|
@ -464,6 +464,7 @@ ALPHA PORT
|
||||||
M: Richard Henderson <rth@twiddle.net>
|
M: Richard Henderson <rth@twiddle.net>
|
||||||
M: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
|
M: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
|
||||||
M: Matt Turner <mattst88@gmail.com>
|
M: Matt Turner <mattst88@gmail.com>
|
||||||
|
S: Odd Fixes
|
||||||
L: linux-alpha@vger.kernel.org
|
L: linux-alpha@vger.kernel.org
|
||||||
F: arch/alpha/
|
F: arch/alpha/
|
||||||
|
|
||||||
|
@ -715,6 +716,7 @@ S: Maintained
|
||||||
ARM/CLKDEV SUPPORT
|
ARM/CLKDEV SUPPORT
|
||||||
M: Russell King <linux@arm.linux.org.uk>
|
M: Russell King <linux@arm.linux.org.uk>
|
||||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
|
S: Maintained
|
||||||
F: arch/arm/include/asm/clkdev.h
|
F: arch/arm/include/asm/clkdev.h
|
||||||
F: drivers/clk/clkdev.c
|
F: drivers/clk/clkdev.c
|
||||||
|
|
||||||
|
@ -1502,7 +1504,7 @@ F: drivers/i2c/busses/i2c-bfin-twi.c
|
||||||
|
|
||||||
BLOCK LAYER
|
BLOCK LAYER
|
||||||
M: Jens Axboe <axboe@kernel.dk>
|
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
|
S: Maintained
|
||||||
F: block/
|
F: block/
|
||||||
|
|
||||||
|
@ -1640,7 +1642,7 @@ BTTV VIDEO4LINUX DRIVER
|
||||||
M: Mauro Carvalho Chehab <mchehab@infradead.org>
|
M: Mauro Carvalho Chehab <mchehab@infradead.org>
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
W: http://linuxtv.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
|
S: Maintained
|
||||||
F: Documentation/video4linux/bttv/
|
F: Documentation/video4linux/bttv/
|
||||||
F: drivers/media/video/bt8xx/bttv*
|
F: drivers/media/video/bt8xx/bttv*
|
||||||
|
@ -1670,7 +1672,7 @@ F: fs/cachefiles/
|
||||||
CAFE CMOS INTEGRATED CAMERA CONTROLLER DRIVER
|
CAFE CMOS INTEGRATED CAMERA CONTROLLER DRIVER
|
||||||
M: Jonathan Corbet <corbet@lwn.net>
|
M: Jonathan Corbet <corbet@lwn.net>
|
||||||
L: linux-media@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
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/video4linux/cafe_ccic
|
F: Documentation/video4linux/cafe_ccic
|
||||||
F: drivers/media/video/marvell-ccic/
|
F: drivers/media/video/marvell-ccic/
|
||||||
|
@ -1841,6 +1843,7 @@ F: include/linux/cleancache.h
|
||||||
|
|
||||||
CLK API
|
CLK API
|
||||||
M: Russell King <linux@arm.linux.org.uk>
|
M: Russell King <linux@arm.linux.org.uk>
|
||||||
|
S: Maintained
|
||||||
F: include/linux/clk.h
|
F: include/linux/clk.h
|
||||||
|
|
||||||
CISCO FCOE HBA DRIVER
|
CISCO FCOE HBA DRIVER
|
||||||
|
@ -2036,7 +2039,7 @@ CX18 VIDEO4LINUX DRIVER
|
||||||
M: Andy Walls <awalls@md.metrocast.net>
|
M: Andy Walls <awalls@md.metrocast.net>
|
||||||
L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
|
L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
|
||||||
L: linux-media@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://linuxtv.org
|
W: http://linuxtv.org
|
||||||
W: http://www.ivtvdriver.org/index.php/Cx18
|
W: http://www.ivtvdriver.org/index.php/Cx18
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
@ -2350,7 +2353,7 @@ F: Documentation/blockdev/drbd/
|
||||||
|
|
||||||
DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
|
DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
|
||||||
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
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
|
S: Supported
|
||||||
F: Documentation/kobject.txt
|
F: Documentation/kobject.txt
|
||||||
F: drivers/base/
|
F: drivers/base/
|
||||||
|
@ -2372,7 +2375,7 @@ INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
|
||||||
M: Keith Packard <keithp@keithp.com>
|
M: Keith Packard <keithp@keithp.com>
|
||||||
L: intel-gfx@lists.freedesktop.org (subscribers-only)
|
L: intel-gfx@lists.freedesktop.org (subscribers-only)
|
||||||
L: dri-devel@lists.freedesktop.org
|
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
|
S: Supported
|
||||||
F: drivers/gpu/drm/i915
|
F: drivers/gpu/drm/i915
|
||||||
F: include/drm/i915*
|
F: include/drm/i915*
|
||||||
|
@ -2966,8 +2969,8 @@ GFS2 FILE SYSTEM
|
||||||
M: Steven Whitehouse <swhiteho@redhat.com>
|
M: Steven Whitehouse <swhiteho@redhat.com>
|
||||||
L: cluster-devel@redhat.com
|
L: cluster-devel@redhat.com
|
||||||
W: http://sources.redhat.com/cluster/
|
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-3.0-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-nmw.git
|
||||||
S: Supported
|
S: Supported
|
||||||
F: Documentation/filesystems/gfs2*.txt
|
F: Documentation/filesystems/gfs2*.txt
|
||||||
F: fs/gfs2/
|
F: fs/gfs2/
|
||||||
|
@ -3008,42 +3011,42 @@ F: drivers/net/ethernet/aeroflex/
|
||||||
GSPCA FINEPIX SUBDRIVER
|
GSPCA FINEPIX SUBDRIVER
|
||||||
M: Frank Zago <frank@zago.net>
|
M: Frank Zago <frank@zago.net>
|
||||||
L: linux-media@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
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/media/video/gspca/finepix.c
|
F: drivers/media/video/gspca/finepix.c
|
||||||
|
|
||||||
GSPCA GL860 SUBDRIVER
|
GSPCA GL860 SUBDRIVER
|
||||||
M: Olivier Lorin <o.lorin@laposte.net>
|
M: Olivier Lorin <o.lorin@laposte.net>
|
||||||
L: linux-media@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
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/media/video/gspca/gl860/
|
F: drivers/media/video/gspca/gl860/
|
||||||
|
|
||||||
GSPCA M5602 SUBDRIVER
|
GSPCA M5602 SUBDRIVER
|
||||||
M: Erik Andren <erik.andren@gmail.com>
|
M: Erik Andren <erik.andren@gmail.com>
|
||||||
L: linux-media@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
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/media/video/gspca/m5602/
|
F: drivers/media/video/gspca/m5602/
|
||||||
|
|
||||||
GSPCA PAC207 SONIXB SUBDRIVER
|
GSPCA PAC207 SONIXB SUBDRIVER
|
||||||
M: Hans de Goede <hdegoede@redhat.com>
|
M: Hans de Goede <hdegoede@redhat.com>
|
||||||
L: linux-media@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
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/media/video/gspca/pac207.c
|
F: drivers/media/video/gspca/pac207.c
|
||||||
|
|
||||||
GSPCA SN9C20X SUBDRIVER
|
GSPCA SN9C20X SUBDRIVER
|
||||||
M: Brian Johnson <brijohn@gmail.com>
|
M: Brian Johnson <brijohn@gmail.com>
|
||||||
L: linux-media@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
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/media/video/gspca/sn9c20x.c
|
F: drivers/media/video/gspca/sn9c20x.c
|
||||||
|
|
||||||
GSPCA T613 SUBDRIVER
|
GSPCA T613 SUBDRIVER
|
||||||
M: Leandro Costantino <lcostantino@gmail.com>
|
M: Leandro Costantino <lcostantino@gmail.com>
|
||||||
L: linux-media@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
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/media/video/gspca/t613.c
|
F: drivers/media/video/gspca/t613.c
|
||||||
|
|
||||||
|
@ -3051,7 +3054,7 @@ GSPCA USB WEBCAM DRIVER
|
||||||
M: Jean-Francois Moine <moinejf@free.fr>
|
M: Jean-Francois Moine <moinejf@free.fr>
|
||||||
W: http://moinejf.free.fr
|
W: http://moinejf.free.fr
|
||||||
L: linux-media@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
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/media/video/gspca/
|
F: drivers/media/video/gspca/
|
||||||
|
|
||||||
|
@ -3337,7 +3340,7 @@ IDE SUBSYSTEM
|
||||||
M: "David S. Miller" <davem@davemloft.net>
|
M: "David S. Miller" <davem@davemloft.net>
|
||||||
L: linux-ide@vger.kernel.org
|
L: linux-ide@vger.kernel.org
|
||||||
Q: http://patchwork.ozlabs.org/project/linux-ide/list/
|
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
|
S: Maintained
|
||||||
F: Documentation/ide/
|
F: Documentation/ide/
|
||||||
F: drivers/ide/
|
F: drivers/ide/
|
||||||
|
@ -3449,7 +3452,7 @@ F: firmware/isci/
|
||||||
INTEL IDLE DRIVER
|
INTEL IDLE DRIVER
|
||||||
M: Len Brown <lenb@kernel.org>
|
M: Len Brown <lenb@kernel.org>
|
||||||
L: linux-pm@vger.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
|
S: Supported
|
||||||
F: drivers/idle/intel_idle.c
|
F: drivers/idle/intel_idle.c
|
||||||
|
|
||||||
|
@ -3756,7 +3759,7 @@ IVTV VIDEO4LINUX DRIVER
|
||||||
M: Andy Walls <awalls@md.metrocast.net>
|
M: Andy Walls <awalls@md.metrocast.net>
|
||||||
L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
|
L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
|
||||||
L: linux-media@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.ivtvdriver.org
|
W: http://www.ivtvdriver.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/video4linux/*.ivtv
|
F: Documentation/video4linux/*.ivtv
|
||||||
|
@ -3852,8 +3855,8 @@ F: fs/autofs4/
|
||||||
|
|
||||||
KERNEL BUILD + files below scripts/ (unless maintained elsewhere)
|
KERNEL BUILD + files below scripts/ (unless maintained elsewhere)
|
||||||
M: Michal Marek <mmarek@suse.cz>
|
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.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 rc-fixes
|
||||||
L: linux-kbuild@vger.kernel.org
|
L: linux-kbuild@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/kbuild/
|
F: Documentation/kbuild/
|
||||||
|
@ -4233,12 +4236,14 @@ F: Documentation/hwmon/ltc4261
|
||||||
F: drivers/hwmon/ltc4261.c
|
F: drivers/hwmon/ltc4261.c
|
||||||
|
|
||||||
LTP (Linux Test Project)
|
LTP (Linux Test Project)
|
||||||
M: Rishikesh K Rajak <risrajak@linux.vnet.ibm.com>
|
M: Shubham Goyal <shubham@linux.vnet.ibm.com>
|
||||||
M: Garrett Cooper <yanegomi@gmail.com>
|
|
||||||
M: Mike Frysinger <vapier@gentoo.org>
|
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)
|
L: ltp-list@lists.sourceforge.net (subscribers-only)
|
||||||
W: http://ltp.sourceforge.net/
|
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
|
T: git git://ltp.git.sourceforge.net/gitroot/ltp/ltp-dev
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
@ -4276,7 +4281,7 @@ MAC80211
|
||||||
M: Johannes Berg <johannes@sipsolutions.net>
|
M: Johannes Berg <johannes@sipsolutions.net>
|
||||||
L: linux-wireless@vger.kernel.org
|
L: linux-wireless@vger.kernel.org
|
||||||
W: http://linuxwireless.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
|
S: Maintained
|
||||||
F: Documentation/networking/mac80211-injection.txt
|
F: Documentation/networking/mac80211-injection.txt
|
||||||
F: include/net/mac80211.h
|
F: include/net/mac80211.h
|
||||||
|
@ -4287,7 +4292,7 @@ M: Stefano Brivio <stefano.brivio@polimi.it>
|
||||||
M: Mattias Nissler <mattias.nissler@gmx.de>
|
M: Mattias Nissler <mattias.nissler@gmx.de>
|
||||||
L: linux-wireless@vger.kernel.org
|
L: linux-wireless@vger.kernel.org
|
||||||
W: http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/PID
|
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
|
S: Maintained
|
||||||
F: net/mac80211/rc80211_pid*
|
F: net/mac80211/rc80211_pid*
|
||||||
|
|
||||||
|
@ -4359,7 +4364,7 @@ P: LinuxTV.org Project
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
W: http://linuxtv.org
|
W: http://linuxtv.org
|
||||||
Q: http://patchwork.kernel.org/project/linux-media/list/
|
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
|
S: Maintained
|
||||||
F: Documentation/dvb/
|
F: Documentation/dvb/
|
||||||
F: Documentation/video4linux/
|
F: Documentation/video4linux/
|
||||||
|
@ -4416,6 +4421,13 @@ T: git git://git.monstr.eu/linux-2.6-microblaze.git
|
||||||
S: Supported
|
S: Supported
|
||||||
F: arch/microblaze/
|
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
|
MICROTEK X6 SCANNER
|
||||||
M: Oliver Neukum <oliver@neukum.name>
|
M: Oliver Neukum <oliver@neukum.name>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
@ -4431,14 +4443,6 @@ S: Supported
|
||||||
F: Documentation/mips/
|
F: Documentation/mips/
|
||||||
F: arch/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
|
MODULE SUPPORT
|
||||||
M: Rusty Russell <rusty@rustcorp.com.au>
|
M: Rusty Russell <rusty@rustcorp.com.au>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
@ -4646,7 +4650,7 @@ M: James Morris <jmorris@namei.org>
|
||||||
M: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
|
M: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
|
||||||
M: Patrick McHardy <kaber@trash.net>
|
M: Patrick McHardy <kaber@trash.net>
|
||||||
L: netdev@vger.kernel.org
|
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
|
S: Maintained
|
||||||
F: net/ipv4/
|
F: net/ipv4/
|
||||||
F: net/ipv6/
|
F: net/ipv6/
|
||||||
|
@ -4662,7 +4666,7 @@ NETWORKING [WIRELESS]
|
||||||
M: "John W. Linville" <linville@tuxdriver.com>
|
M: "John W. Linville" <linville@tuxdriver.com>
|
||||||
L: linux-wireless@vger.kernel.org
|
L: linux-wireless@vger.kernel.org
|
||||||
Q: http://patchwork.kernel.org/project/linux-wireless/list/
|
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
|
S: Maintained
|
||||||
F: net/mac80211/
|
F: net/mac80211/
|
||||||
F: net/rfkill/
|
F: net/rfkill/
|
||||||
|
@ -4675,8 +4679,8 @@ F: drivers/net/wireless/
|
||||||
NETWORKING DRIVERS
|
NETWORKING DRIVERS
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
W: http://www.linuxfoundation.org/en/Net
|
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.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-next.git
|
||||||
S: Odd Fixes
|
S: Odd Fixes
|
||||||
F: drivers/net/
|
F: drivers/net/
|
||||||
F: include/linux/if_*
|
F: include/linux/if_*
|
||||||
|
@ -4892,7 +4896,7 @@ F: drivers/char/pcmcia/cm4040_cs.*
|
||||||
OMNIVISION OV7670 SENSOR DRIVER
|
OMNIVISION OV7670 SENSOR DRIVER
|
||||||
M: Jonathan Corbet <corbet@lwn.net>
|
M: Jonathan Corbet <corbet@lwn.net>
|
||||||
L: linux-media@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
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/media/video/ov7670.c
|
F: drivers/media/video/ov7670.c
|
||||||
|
|
||||||
|
@ -5067,7 +5071,7 @@ M: Helge Deller <deller@gmx.de>
|
||||||
L: linux-parisc@vger.kernel.org
|
L: linux-parisc@vger.kernel.org
|
||||||
W: http://www.parisc-linux.org/
|
W: http://www.parisc-linux.org/
|
||||||
Q: http://patchwork.kernel.org/project/linux-parisc/list/
|
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
|
S: Maintained
|
||||||
F: arch/parisc/
|
F: arch/parisc/
|
||||||
F: drivers/parisc/
|
F: drivers/parisc/
|
||||||
|
@ -5123,7 +5127,7 @@ PCI SUBSYSTEM
|
||||||
M: Bjorn Helgaas <bhelgaas@google.com>
|
M: Bjorn Helgaas <bhelgaas@google.com>
|
||||||
L: linux-pci@vger.kernel.org
|
L: linux-pci@vger.kernel.org
|
||||||
Q: http://patchwork.kernel.org/project/linux-pci/list/
|
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
|
S: Supported
|
||||||
F: Documentation/PCI/
|
F: Documentation/PCI/
|
||||||
F: drivers/pci/
|
F: drivers/pci/
|
||||||
|
@ -5408,7 +5412,7 @@ M: Mike Isely <isely@pobox.com>
|
||||||
L: pvrusb2@isely.net (subscribers-only)
|
L: pvrusb2@isely.net (subscribers-only)
|
||||||
L: linux-media@vger.kernel.org
|
L: linux-media@vger.kernel.org
|
||||||
W: http://www.isely.net/pvrusb2/
|
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
|
S: Maintained
|
||||||
F: Documentation/video4linux/README.pvrusb2
|
F: Documentation/video4linux/README.pvrusb2
|
||||||
F: drivers/media/video/pvrusb2/
|
F: drivers/media/video/pvrusb2/
|
||||||
|
@ -5574,7 +5578,7 @@ RCUTORTURE MODULE
|
||||||
M: Josh Triplett <josh@freedesktop.org>
|
M: Josh Triplett <josh@freedesktop.org>
|
||||||
M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
|
M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
|
||||||
S: Supported
|
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: Documentation/RCU/torture.txt
|
||||||
F: kernel/rcutorture.c
|
F: kernel/rcutorture.c
|
||||||
|
|
||||||
|
@ -5599,7 +5603,7 @@ M: Dipankar Sarma <dipankar@in.ibm.com>
|
||||||
M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
|
M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
|
||||||
W: http://www.rdrop.com/users/paulmck/rclock/
|
W: http://www.rdrop.com/users/paulmck/rclock/
|
||||||
S: Supported
|
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: Documentation/RCU/
|
||||||
F: include/linux/rcu*
|
F: include/linux/rcu*
|
||||||
F: include/linux/srcu*
|
F: include/linux/srcu*
|
||||||
|
@ -5753,7 +5757,7 @@ F: drivers/mmc/host/s3cmci.*
|
||||||
SAA7146 VIDEO4LINUX-2 DRIVER
|
SAA7146 VIDEO4LINUX-2 DRIVER
|
||||||
M: Michael Hunold <michael@mihu.de>
|
M: Michael Hunold <michael@mihu.de>
|
||||||
L: linux-media@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.mihu.de/linux/saa7146
|
W: http://www.mihu.de/linux/saa7146
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/media/common/saa7146*
|
F: drivers/media/common/saa7146*
|
||||||
|
@ -6176,7 +6180,7 @@ F: arch/ia64/sn/
|
||||||
SOC-CAMERA V4L2 SUBSYSTEM
|
SOC-CAMERA V4L2 SUBSYSTEM
|
||||||
M: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
|
M: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
|
||||||
L: linux-media@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
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: include/media/v4l2*
|
F: include/media/v4l2*
|
||||||
F: drivers/media/video/v4l2*
|
F: drivers/media/video/v4l2*
|
||||||
|
@ -6248,8 +6252,8 @@ SPARC + UltraSPARC (sparc/sparc64)
|
||||||
M: "David S. Miller" <davem@davemloft.net>
|
M: "David S. Miller" <davem@davemloft.net>
|
||||||
L: sparclinux@vger.kernel.org
|
L: sparclinux@vger.kernel.org
|
||||||
Q: http://patchwork.ozlabs.org/project/sparclinux/list/
|
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.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-next.git
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: arch/sparc/
|
F: arch/sparc/
|
||||||
F: drivers/sbus/
|
F: drivers/sbus/
|
||||||
|
@ -6257,8 +6261,8 @@ F: drivers/sbus/
|
||||||
SPARC SERIAL DRIVERS
|
SPARC SERIAL DRIVERS
|
||||||
M: "David S. Miller" <davem@davemloft.net>
|
M: "David S. Miller" <davem@davemloft.net>
|
||||||
L: sparclinux@vger.kernel.org
|
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.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-next.git
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: include/linux/sunserialcore.h
|
F: include/linux/sunserialcore.h
|
||||||
F: drivers/tty/serial/suncore.c
|
F: drivers/tty/serial/suncore.c
|
||||||
|
@ -6563,7 +6567,7 @@ L: linux-scsi@vger.kernel.org
|
||||||
L: target-devel@vger.kernel.org
|
L: target-devel@vger.kernel.org
|
||||||
L: http://groups.google.com/group/linux-iscsi-target-dev
|
L: http://groups.google.com/group/linux-iscsi-target-dev
|
||||||
W: http://www.linux-iscsi.org
|
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
|
S: Supported
|
||||||
F: drivers/target/
|
F: drivers/target/
|
||||||
F: include/target/
|
F: include/target/
|
||||||
|
@ -6754,7 +6758,7 @@ K: ^Subject:.*(?i)trivial
|
||||||
TTY LAYER
|
TTY LAYER
|
||||||
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
S: Supported
|
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/
|
||||||
F: drivers/tty/serial/serial_core.c
|
F: drivers/tty/serial/serial_core.c
|
||||||
F: include/linux/serial_core.h
|
F: include/linux/serial_core.h
|
||||||
|
@ -6922,7 +6926,7 @@ USB ET61X[12]51 DRIVER
|
||||||
M: Luca Risolia <luca.risolia@studio.unibo.it>
|
M: Luca Risolia <luca.risolia@studio.unibo.it>
|
||||||
L: linux-usb@vger.kernel.org
|
L: linux-usb@vger.kernel.org
|
||||||
L: linux-media@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
|
W: http://www.linux-projects.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/media/video/et61x251/
|
F: drivers/media/video/et61x251/
|
||||||
|
@ -7078,7 +7082,7 @@ USB SN9C1xx DRIVER
|
||||||
M: Luca Risolia <luca.risolia@studio.unibo.it>
|
M: Luca Risolia <luca.risolia@studio.unibo.it>
|
||||||
L: linux-usb@vger.kernel.org
|
L: linux-usb@vger.kernel.org
|
||||||
L: linux-media@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
|
W: http://www.linux-projects.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/video4linux/sn9c102.txt
|
F: Documentation/video4linux/sn9c102.txt
|
||||||
|
@ -7088,7 +7092,7 @@ USB SUBSYSTEM
|
||||||
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||||
L: linux-usb@vger.kernel.org
|
L: linux-usb@vger.kernel.org
|
||||||
W: http://www.linux-usb.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
|
S: Supported
|
||||||
F: Documentation/usb/
|
F: Documentation/usb/
|
||||||
F: drivers/net/usb/
|
F: drivers/net/usb/
|
||||||
|
@ -7114,7 +7118,7 @@ USB VIDEO CLASS
|
||||||
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||||
L: linux-uvc-devel@lists.berlios.de (subscribers-only)
|
L: linux-uvc-devel@lists.berlios.de (subscribers-only)
|
||||||
L: linux-media@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.ideasonboard.org/uvc/
|
W: http://www.ideasonboard.org/uvc/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/media/video/uvc/
|
F: drivers/media/video/uvc/
|
||||||
|
@ -7123,7 +7127,7 @@ USB W996[87]CF DRIVER
|
||||||
M: Luca Risolia <luca.risolia@studio.unibo.it>
|
M: Luca Risolia <luca.risolia@studio.unibo.it>
|
||||||
L: linux-usb@vger.kernel.org
|
L: linux-usb@vger.kernel.org
|
||||||
L: linux-media@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
|
W: http://www.linux-projects.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/video4linux/w9968cf.txt
|
F: Documentation/video4linux/w9968cf.txt
|
||||||
|
@ -7152,7 +7156,7 @@ USB ZR364XX DRIVER
|
||||||
M: Antoine Jacquet <royale@zerezo.com>
|
M: Antoine Jacquet <royale@zerezo.com>
|
||||||
L: linux-usb@vger.kernel.org
|
L: linux-usb@vger.kernel.org
|
||||||
L: linux-media@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/
|
W: http://royale.zerezo.com/zr364xx/
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/video4linux/zr364xx.txt
|
F: Documentation/video4linux/zr364xx.txt
|
||||||
|
@ -7302,7 +7306,7 @@ M: Liam Girdwood <lrg@ti.com>
|
||||||
M: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
M: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||||
W: http://opensource.wolfsonmicro.com/node/15
|
W: http://opensource.wolfsonmicro.com/node/15
|
||||||
W: http://www.slimlogic.co.uk/?p=48
|
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
|
S: Supported
|
||||||
F: drivers/regulator/
|
F: drivers/regulator/
|
||||||
F: include/linux/regulator/
|
F: include/linux/regulator/
|
||||||
|
|
|
@ -120,6 +120,9 @@ config HAVE_KRETPROBES
|
||||||
|
|
||||||
config HAVE_OPTPROBES
|
config HAVE_OPTPROBES
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config HAVE_NMI_WATCHDOG
|
||||||
|
bool
|
||||||
#
|
#
|
||||||
# An arch should select this if it provides all these things:
|
# An arch should select this if it provides all these things:
|
||||||
#
|
#
|
||||||
|
|
|
@ -56,6 +56,10 @@
|
||||||
#define MADV_HUGEPAGE 14 /* Worth backing with hugepages */
|
#define MADV_HUGEPAGE 14 /* Worth backing with hugepages */
|
||||||
#define MADV_NOHUGEPAGE 15 /* Not 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 */
|
/* compatibility flags */
|
||||||
#define MAP_FILE 0
|
#define MAP_FILE 0
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,6 @@ extern unsigned int kobjsize(const void *objp);
|
||||||
* No page table caches to initialise.
|
* No page table caches to initialise.
|
||||||
*/
|
*/
|
||||||
#define pgtable_cache_init() do { } while (0)
|
#define pgtable_cache_init() do { } while (0)
|
||||||
#define io_remap_page_range remap_page_range
|
|
||||||
#define io_remap_pfn_range remap_pfn_range
|
#define io_remap_pfn_range remap_pfn_range
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -533,8 +533,7 @@ int vectors_user_mapping(void)
|
||||||
struct mm_struct *mm = current->mm;
|
struct mm_struct *mm = current->mm;
|
||||||
return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
|
return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
|
||||||
VM_READ | VM_EXEC |
|
VM_READ | VM_EXEC |
|
||||||
VM_MAYREAD | VM_MAYEXEC |
|
VM_MAYREAD | VM_MAYEXEC | VM_RESERVED,
|
||||||
VM_ALWAYSDUMP | VM_RESERVED,
|
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ config BLACKFIN
|
||||||
select GENERIC_ATOMIC64
|
select GENERIC_ATOMIC64
|
||||||
select GENERIC_IRQ_PROBE
|
select GENERIC_IRQ_PROBE
|
||||||
select IRQ_PER_CPU if SMP
|
select IRQ_PER_CPU if SMP
|
||||||
|
select HAVE_NMI_WATCHDOG if NMI_WATCHDOG
|
||||||
|
|
||||||
config GENERIC_CSUM
|
config GENERIC_CSUM
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
|
@ -38,8 +38,4 @@
|
||||||
|
|
||||||
#include <asm-generic/irq.h>
|
#include <asm-generic/irq.h>
|
||||||
|
|
||||||
#ifdef CONFIG_NMI_WATCHDOG
|
|
||||||
# define ARCH_HAS_NMI_WATCHDOG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _BFIN_IRQ_H_ */
|
#endif /* _BFIN_IRQ_H_ */
|
||||||
|
|
|
@ -73,9 +73,6 @@ extern unsigned long empty_zero_page;
|
||||||
#define pgtable_cache_init() do { } while (0)
|
#define pgtable_cache_init() do { } while (0)
|
||||||
#define io_remap_pfn_range remap_pfn_range
|
#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>
|
#include <asm-generic/pgtable.h>
|
||||||
|
|
||||||
#endif /* _ASM_C6X_PGTABLE_H */
|
#endif /* _ASM_C6X_PGTABLE_H */
|
||||||
|
|
|
@ -192,12 +192,7 @@ static int handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
spin_lock_irq(¤t->sighand->siglock);
|
block_sigmask(ka, sig);
|
||||||
sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask);
|
|
||||||
if (!(ka->sa.sa_flags & SA_NODEFER))
|
|
||||||
sigaddset(¤t->blocked, sig);
|
|
||||||
recalc_sigpending();
|
|
||||||
spin_unlock_irq(¤t->sighand->siglock);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -305,10 +300,7 @@ asmlinkage int sys_rt_sigreturn(void)
|
||||||
goto badframe;
|
goto badframe;
|
||||||
|
|
||||||
sigdelsetmask(&blocked, ~_BLOCKABLE);
|
sigdelsetmask(&blocked, ~_BLOCKABLE);
|
||||||
spin_lock_irq(¤t->sighand->siglock);
|
set_current_blocked(&blocked);
|
||||||
current->blocked = blocked;
|
|
||||||
recalc_sigpending();
|
|
||||||
spin_unlock_irq(¤t->sighand->siglock);
|
|
||||||
|
|
||||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
|
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
|
||||||
goto badframe;
|
goto badframe;
|
||||||
|
|
|
@ -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. */
|
/* MAYWRITE to allow gdb to COW and set breakpoints. */
|
||||||
ret = install_special_mapping(mm, vdso_base, PAGE_SIZE,
|
ret = install_special_mapping(mm, vdso_base, PAGE_SIZE,
|
||||||
VM_READ|VM_EXEC|
|
VM_READ|VM_EXEC|
|
||||||
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
|
||||||
VM_ALWAYSDUMP,
|
|
||||||
&vdso_page);
|
&vdso_page);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -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 */
|
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
|
||||||
#define kern_addr_valid(addr) (1)
|
#define kern_addr_valid(addr) (1)
|
||||||
|
|
||||||
#define io_remap_page_range remap_page_range
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No page table caches to initialise
|
* No page table caches to initialise
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -80,6 +80,10 @@
|
||||||
#define MADV_HUGEPAGE 14 /* Worth backing with hugepages */
|
#define MADV_HUGEPAGE 14 /* Worth backing with hugepages */
|
||||||
#define MADV_NOHUGEPAGE 15 /* Not 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 */
|
/* compatibility flags */
|
||||||
#define MAP_FILE 0
|
#define MAP_FILE 0
|
||||||
|
|
||||||
|
|
|
@ -88,8 +88,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
||||||
|
|
||||||
ret = install_special_mapping(mm, addr, PAGE_SIZE,
|
ret = install_special_mapping(mm, addr, PAGE_SIZE,
|
||||||
VM_READ|VM_EXEC|
|
VM_READ|VM_EXEC|
|
||||||
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
|
||||||
VM_ALWAYSDUMP,
|
|
||||||
&vdso_page);
|
&vdso_page);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -5,6 +5,7 @@ config MN10300
|
||||||
select GENERIC_IRQ_SHOW
|
select GENERIC_IRQ_SHOW
|
||||||
select HAVE_ARCH_TRACEHOOK
|
select HAVE_ARCH_TRACEHOOK
|
||||||
select HAVE_ARCH_KGDB
|
select HAVE_ARCH_KGDB
|
||||||
|
select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER
|
||||||
|
|
||||||
config AM33_2
|
config AM33_2
|
||||||
def_bool n
|
def_bool n
|
||||||
|
|
|
@ -17,10 +17,6 @@
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
#ifdef CONFIG_MN10300_WD_TIMER
|
|
||||||
#define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* watchdog timer registers
|
* watchdog timer registers
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -455,7 +455,6 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
|
||||||
* No page table caches to initialise
|
* No page table caches to initialise
|
||||||
*/
|
*/
|
||||||
#define pgtable_cache_init() do { } while (0)
|
#define pgtable_cache_init() do { } while (0)
|
||||||
#define io_remap_page_range remap_page_range
|
|
||||||
|
|
||||||
typedef pte_t *pte_addr_t;
|
typedef pte_t *pte_addr_t;
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,10 @@
|
||||||
#define MADV_HUGEPAGE 67 /* Worth backing with hugepages */
|
#define MADV_HUGEPAGE 67 /* Worth backing with hugepages */
|
||||||
#define MADV_NOHUGEPAGE 68 /* Not 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 */
|
/* compatibility flags */
|
||||||
#define MAP_FILE 0
|
#define MAP_FILE 0
|
||||||
#define MAP_VARIABLE 0
|
#define MAP_VARIABLE 0
|
||||||
|
|
|
@ -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
|
* the "data" page of the vDSO or you'll stop getting kernel updates
|
||||||
* and your nice userland gettimeofday will be totally dead.
|
* and your nice userland gettimeofday will be totally dead.
|
||||||
* It's fine to use that for setting breakpoints in the vDSO code
|
* It's fine to use that for setting breakpoints in the vDSO code
|
||||||
* pages though
|
* 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.
|
|
||||||
*/
|
*/
|
||||||
rc = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
|
rc = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
|
||||||
VM_READ|VM_EXEC|
|
VM_READ|VM_EXEC|
|
||||||
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
|
||||||
VM_ALWAYSDUMP,
|
|
||||||
vdso_pagelist);
|
vdso_pagelist);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
current->mm->context.vdso_base = 0;
|
current->mm->context.vdso_base = 0;
|
||||||
|
|
|
@ -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
|
* on the "data" page of the vDSO or you'll stop getting kernel
|
||||||
* updates and your nice userland gettimeofday will be totally dead.
|
* updates and your nice userland gettimeofday will be totally dead.
|
||||||
* It's fine to use that for setting breakpoints in the vDSO code
|
* It's fine to use that for setting breakpoints in the vDSO code
|
||||||
* pages though
|
* 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.
|
|
||||||
*/
|
*/
|
||||||
rc = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
|
rc = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
|
||||||
VM_READ|VM_EXEC|
|
VM_READ|VM_EXEC|
|
||||||
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
|
||||||
VM_ALWAYSDUMP,
|
|
||||||
vdso_pagelist);
|
vdso_pagelist);
|
||||||
if (rc)
|
if (rc)
|
||||||
current->mm->context.vdso_base = 0;
|
current->mm->context.vdso_base = 0;
|
||||||
|
|
|
@ -73,8 +73,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
||||||
|
|
||||||
ret = install_special_mapping(mm, addr, PAGE_SIZE,
|
ret = install_special_mapping(mm, addr, PAGE_SIZE,
|
||||||
VM_READ | VM_EXEC |
|
VM_READ | VM_EXEC |
|
||||||
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC |
|
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
|
||||||
VM_ALWAYSDUMP,
|
|
||||||
syscall_pages);
|
syscall_pages);
|
||||||
if (unlikely(ret))
|
if (unlikely(ret))
|
||||||
goto up_fail;
|
goto up_fail;
|
||||||
|
|
|
@ -29,6 +29,7 @@ config SPARC
|
||||||
select GENERIC_IRQ_SHOW
|
select GENERIC_IRQ_SHOW
|
||||||
select USE_GENERIC_SMP_HELPERS if SMP
|
select USE_GENERIC_SMP_HELPERS if SMP
|
||||||
select GENERIC_PCI_IOMAP
|
select GENERIC_PCI_IOMAP
|
||||||
|
select HAVE_NMI_WATCHDOG if SPARC64
|
||||||
|
|
||||||
config SPARC32
|
config SPARC32
|
||||||
def_bool !64BIT
|
def_bool !64BIT
|
||||||
|
|
|
@ -95,7 +95,6 @@ void arch_trigger_all_cpu_backtrace(void);
|
||||||
extern void *hardirq_stack[NR_CPUS];
|
extern void *hardirq_stack[NR_CPUS];
|
||||||
extern void *softirq_stack[NR_CPUS];
|
extern void *softirq_stack[NR_CPUS];
|
||||||
#define __ARCH_HAS_DO_SOFTIRQ
|
#define __ARCH_HAS_DO_SOFTIRQ
|
||||||
#define ARCH_HAS_NMI_WATCHDOG
|
|
||||||
|
|
||||||
#define NO_IRQ 0xffffffff
|
#define NO_IRQ 0xffffffff
|
||||||
|
|
||||||
|
|
|
@ -117,17 +117,11 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MAYWRITE to allow gdb to COW and set breakpoints
|
* 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;
|
vdso_base = VDSO_BASE;
|
||||||
retval = install_special_mapping(mm, vdso_base, PAGE_SIZE,
|
retval = install_special_mapping(mm, vdso_base, PAGE_SIZE,
|
||||||
VM_READ|VM_EXEC|
|
VM_READ|VM_EXEC|
|
||||||
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
|
||||||
VM_ALWAYSDUMP,
|
|
||||||
vdso_pages);
|
vdso_pages);
|
||||||
|
|
||||||
#ifndef __tilegx__
|
#ifndef __tilegx__
|
||||||
|
|
|
@ -65,21 +65,10 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
|
||||||
#endif
|
#endif
|
||||||
err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
|
err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
|
||||||
|
|
||||||
if (err) {
|
if (err)
|
||||||
spin_lock_irq(¤t->sighand->siglock);
|
|
||||||
current->blocked = *oldset;
|
|
||||||
recalc_sigpending();
|
|
||||||
spin_unlock_irq(¤t->sighand->siglock);
|
|
||||||
force_sigsegv(signr, current);
|
force_sigsegv(signr, current);
|
||||||
} else {
|
else
|
||||||
spin_lock_irq(¤t->sighand->siglock);
|
block_sigmask(ka, signr);
|
||||||
sigorsets(¤t->blocked, ¤t->blocked,
|
|
||||||
&ka->sa.sa_mask);
|
|
||||||
if (!(ka->sa.sa_flags & SA_NODEFER))
|
|
||||||
sigaddset(¤t->blocked, signr);
|
|
||||||
recalc_sigpending();
|
|
||||||
spin_unlock_irq(¤t->sighand->siglock);
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -162,12 +151,11 @@ int do_signal(void)
|
||||||
*/
|
*/
|
||||||
long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
|
long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
|
||||||
{
|
{
|
||||||
|
sigset_t blocked;
|
||||||
|
|
||||||
mask &= _BLOCKABLE;
|
mask &= _BLOCKABLE;
|
||||||
spin_lock_irq(¤t->sighand->siglock);
|
siginitset(&blocked, mask);
|
||||||
current->saved_sigmask = current->blocked;
|
set_current_blocked(&blocked);
|
||||||
siginitset(¤t->blocked, mask);
|
|
||||||
recalc_sigpending();
|
|
||||||
spin_unlock_irq(¤t->sighand->siglock);
|
|
||||||
|
|
||||||
current->state = TASK_INTERRUPTIBLE;
|
current->state = TASK_INTERRUPTIBLE;
|
||||||
schedule();
|
schedule();
|
||||||
|
|
|
@ -381,7 +381,7 @@ int vectors_user_mapping(void)
|
||||||
return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
|
return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
|
||||||
VM_READ | VM_EXEC |
|
VM_READ | VM_EXEC |
|
||||||
VM_MAYREAD | VM_MAYEXEC |
|
VM_MAYREAD | VM_MAYEXEC |
|
||||||
VM_ALWAYSDUMP | VM_RESERVED,
|
VM_RESERVED,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -643,14 +643,14 @@ static bool __perf_sched_find_counter(struct perf_sched *sched)
|
||||||
/* Prefer fixed purpose counters */
|
/* Prefer fixed purpose counters */
|
||||||
if (x86_pmu.num_counters_fixed) {
|
if (x86_pmu.num_counters_fixed) {
|
||||||
idx = X86_PMC_IDX_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))
|
if (!__test_and_set_bit(idx, sched->state.used))
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Grab the first unused counter starting with idx */
|
/* Grab the first unused counter starting with idx */
|
||||||
idx = sched->state.counter;
|
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))
|
if (!__test_and_set_bit(idx, sched->state.used))
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
@ -306,10 +306,10 @@ void __init native_init_IRQ(void)
|
||||||
* us. (some of these will be overridden and become
|
* us. (some of these will be overridden and become
|
||||||
* 'special' SMP interrupts)
|
* '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. */
|
/* 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)
|
if (!acpi_ioapic && !of_ioapic)
|
||||||
|
|
|
@ -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_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
|
||||||
gate_vma.vm_page_prot = __P101;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
__initcall(gate_vma_init);
|
__initcall(gate_vma_init);
|
||||||
|
|
|
@ -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,
|
err = install_special_mapping(mm, um_vdso_addr, PAGE_SIZE,
|
||||||
VM_READ|VM_EXEC|
|
VM_READ|VM_EXEC|
|
||||||
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
|
||||||
VM_ALWAYSDUMP,
|
|
||||||
vdsop);
|
vdsop);
|
||||||
|
|
||||||
up_write(&mm->mmap_sem);
|
up_write(&mm->mmap_sem);
|
||||||
|
|
|
@ -250,13 +250,7 @@ static int __init gate_vma_init(void)
|
||||||
gate_vma.vm_end = FIXADDR_USER_END;
|
gate_vma.vm_end = FIXADDR_USER_END;
|
||||||
gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
|
gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
|
||||||
gate_vma.vm_page_prot = __P101;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,17 +337,10 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
||||||
if (compat_uses_vma || !compat) {
|
if (compat_uses_vma || !compat) {
|
||||||
/*
|
/*
|
||||||
* MAYWRITE to allow gdb to COW and set breakpoints
|
* 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,
|
ret = install_special_mapping(mm, addr, PAGE_SIZE,
|
||||||
VM_READ|VM_EXEC|
|
VM_READ|VM_EXEC|
|
||||||
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
|
||||||
VM_ALWAYSDUMP,
|
|
||||||
vdso32_pages);
|
vdso32_pages);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -124,8 +124,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
||||||
|
|
||||||
ret = install_special_mapping(mm, addr, vdso_size,
|
ret = install_special_mapping(mm, addr, vdso_size,
|
||||||
VM_READ|VM_EXEC|
|
VM_READ|VM_EXEC|
|
||||||
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
|
||||||
VM_ALWAYSDUMP,
|
|
||||||
vdso_pages);
|
vdso_pages);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
current->mm->context.vdso = NULL;
|
current->mm->context.vdso = NULL;
|
||||||
|
|
|
@ -86,6 +86,10 @@
|
||||||
#define MADV_HUGEPAGE 14 /* Worth backing with hugepages */
|
#define MADV_HUGEPAGE 14 /* Worth backing with hugepages */
|
||||||
#define MADV_NOHUGEPAGE 15 /* Not 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 */
|
/* compatibility flags */
|
||||||
#define MAP_FILE 0
|
#define MAP_FILE 0
|
||||||
|
|
||||||
|
|
|
@ -308,6 +308,7 @@ comment "Digest"
|
||||||
config CRYPTO_CRC32C
|
config CRYPTO_CRC32C
|
||||||
tristate "CRC32c CRC algorithm"
|
tristate "CRC32c CRC algorithm"
|
||||||
select CRYPTO_HASH
|
select CRYPTO_HASH
|
||||||
|
select CRC32
|
||||||
help
|
help
|
||||||
Castagnoli, et al Cyclic Redundancy-Check Algorithm. Used
|
Castagnoli, et al Cyclic Redundancy-Check Algorithm. Used
|
||||||
by iSCSI for header and data digests and by others.
|
by iSCSI for header and data digests and by others.
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/crc32.h>
|
||||||
|
|
||||||
#define CHKSUM_BLOCK_SIZE 1
|
#define CHKSUM_BLOCK_SIZE 1
|
||||||
#define CHKSUM_DIGEST_SIZE 4
|
#define CHKSUM_DIGEST_SIZE 4
|
||||||
|
@ -52,95 +53,6 @@ struct chksum_desc_ctx {
|
||||||
u32 crc;
|
u32 crc;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
* Steps through buffer one byte at at time, calculates reflected
|
||||||
* crc using table.
|
* 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);
|
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;
|
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)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -341,7 +341,7 @@ static int regcache_lzo_sync(struct regmap *map, unsigned int min,
|
||||||
|
|
||||||
lzo_blocks = map->cache;
|
lzo_blocks = map->cache;
|
||||||
i = min;
|
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) {
|
lzo_blocks[0]->sync_bmp_nbits) {
|
||||||
if (i > max)
|
if (i > max)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -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);
|
dev_info(DEV, "helper command: %s %s %s\n", usermode_helper, cmd, mb);
|
||||||
|
|
||||||
drbd_bcast_ev_helper(mdev, cmd);
|
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)
|
if (ret)
|
||||||
dev_warn(DEV, "helper command: %s %s %s exit code %u (0x%x)\n",
|
dev_warn(DEV, "helper command: %s %s %s exit code %u (0x%x)\n",
|
||||||
usermode_helper, cmd, mb,
|
usermode_helper, cmd, mb,
|
||||||
|
|
|
@ -17,7 +17,7 @@ menuconfig NEW_LEDS
|
||||||
if NEW_LEDS
|
if NEW_LEDS
|
||||||
|
|
||||||
config LEDS_CLASS
|
config LEDS_CLASS
|
||||||
bool "LED Class Support"
|
tristate "LED Class Support"
|
||||||
help
|
help
|
||||||
This option enables the led sysfs class in /sys/class/leds. You'll
|
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.
|
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
|
LED driver chips accessed via the I2C bus. Supported
|
||||||
devices include PCA9550, PCA9551, PCA9552, and PCA9553.
|
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
|
config LEDS_WM831X_STATUS
|
||||||
tristate "LED support for status LEDs on WM831x PMICs"
|
tristate "LED support for status LEDs on WM831x PMICs"
|
||||||
depends on LEDS_CLASS
|
depends on LEDS_CLASS
|
||||||
|
|
|
@ -30,6 +30,7 @@ obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o
|
||||||
obj-$(CONFIG_LEDS_OT200) += leds-ot200.o
|
obj-$(CONFIG_LEDS_OT200) += leds-ot200.o
|
||||||
obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
|
obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
|
||||||
obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.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_DA903X) += leds-da903x.o
|
||||||
obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o
|
obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o
|
||||||
obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o
|
obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o
|
||||||
|
|
|
@ -110,50 +110,6 @@ static void led_timer_function(unsigned long data)
|
||||||
mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
|
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_classdev_suspend - suspend an led_classdev.
|
||||||
* @led_cdev: the led_classdev to suspend.
|
* @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);
|
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)
|
static int __init leds_init(void)
|
||||||
{
|
{
|
||||||
leds_class = class_create(THIS_MODULE, "leds");
|
leds_class = class_create(THIS_MODULE, "leds");
|
||||||
|
|
|
@ -23,3 +23,73 @@ EXPORT_SYMBOL_GPL(leds_list_lock);
|
||||||
|
|
||||||
LIST_HEAD(leds_list);
|
LIST_HEAD(leds_list);
|
||||||
EXPORT_SYMBOL_GPL(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);
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
#include <linux/leds.h>
|
#include <linux/leds.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
#include <linux/of_gpio.h>
|
#include <linux/of_gpio.h>
|
||||||
|
@ -20,8 +21,6 @@
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
#include <asm/gpio.h>
|
|
||||||
|
|
||||||
struct gpio_led_data {
|
struct gpio_led_data {
|
||||||
struct led_classdev cdev;
|
struct led_classdev cdev;
|
||||||
unsigned gpio;
|
unsigned gpio;
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#define LM3530_GEN_CONFIG 0x10
|
#define LM3530_GEN_CONFIG 0x10
|
||||||
#define LM3530_ALS_CONFIG 0x20
|
#define LM3530_ALS_CONFIG 0x20
|
||||||
#define LM3530_BRT_RAMP_RATE 0x30
|
#define LM3530_BRT_RAMP_RATE 0x30
|
||||||
#define LM3530_ALS_ZONE_REG 0x40
|
|
||||||
#define LM3530_ALS_IMP_SELECT 0x41
|
#define LM3530_ALS_IMP_SELECT 0x41
|
||||||
#define LM3530_BRT_CTRL_REG 0xA0
|
#define LM3530_BRT_CTRL_REG 0xA0
|
||||||
#define LM3530_ALS_ZB0_REG 0x60
|
#define LM3530_ALS_ZB0_REG 0x60
|
||||||
|
@ -38,7 +37,7 @@
|
||||||
#define LM3530_ALS_Z2T_REG 0x72
|
#define LM3530_ALS_Z2T_REG 0x72
|
||||||
#define LM3530_ALS_Z3T_REG 0x73
|
#define LM3530_ALS_Z3T_REG 0x73
|
||||||
#define LM3530_ALS_Z4T_REG 0x74
|
#define LM3530_ALS_Z4T_REG 0x74
|
||||||
#define LM3530_REG_MAX 15
|
#define LM3530_REG_MAX 14
|
||||||
|
|
||||||
/* General Control Register */
|
/* General Control Register */
|
||||||
#define LM3530_EN_I2C_SHIFT (0)
|
#define LM3530_EN_I2C_SHIFT (0)
|
||||||
|
@ -80,6 +79,9 @@
|
||||||
#define LM3530_DEF_ZT_3 (0x33)
|
#define LM3530_DEF_ZT_3 (0x33)
|
||||||
#define LM3530_DEF_ZT_4 (0x19)
|
#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 {
|
struct lm3530_mode_map {
|
||||||
const char *mode;
|
const char *mode;
|
||||||
enum lm3530_mode mode_val;
|
enum lm3530_mode mode_val;
|
||||||
|
@ -115,7 +117,6 @@ static const u8 lm3530_reg[LM3530_REG_MAX] = {
|
||||||
LM3530_GEN_CONFIG,
|
LM3530_GEN_CONFIG,
|
||||||
LM3530_ALS_CONFIG,
|
LM3530_ALS_CONFIG,
|
||||||
LM3530_BRT_RAMP_RATE,
|
LM3530_BRT_RAMP_RATE,
|
||||||
LM3530_ALS_ZONE_REG,
|
|
||||||
LM3530_ALS_IMP_SELECT,
|
LM3530_ALS_IMP_SELECT,
|
||||||
LM3530_BRT_CTRL_REG,
|
LM3530_BRT_CTRL_REG,
|
||||||
LM3530_ALS_ZB0_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 reg_val[LM3530_REG_MAX];
|
||||||
u8 zones[LM3530_ALS_ZB_MAX];
|
u8 zones[LM3530_ALS_ZB_MAX];
|
||||||
u32 als_vmin, als_vmax, als_vstep;
|
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 i2c_client *client = drvdata->client;
|
||||||
|
struct lm3530_pwm_data *pwm = &pdata->pwm_data;
|
||||||
|
|
||||||
gen_config = (pltfm->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) |
|
gen_config = (pdata->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) |
|
||||||
((pltfm->max_current & 7) << LM3530_MAX_CURR_SHIFT);
|
((pdata->max_current & 7) << LM3530_MAX_CURR_SHIFT);
|
||||||
|
|
||||||
if (drvdata->mode == LM3530_BL_MODE_MANUAL ||
|
switch (drvdata->mode) {
|
||||||
drvdata->mode == LM3530_BL_MODE_ALS)
|
case LM3530_BL_MODE_MANUAL:
|
||||||
gen_config |= (LM3530_ENABLE_I2C);
|
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 (drvdata->mode == LM3530_BL_MODE_ALS) {
|
||||||
if (pltfm->als_vmax == 0) {
|
if (pdata->als_vmax == 0) {
|
||||||
pltfm->als_vmin = 0;
|
pdata->als_vmin = 0;
|
||||||
pltfm->als_vmax = LM3530_ALS_WINDOW_mV;
|
pdata->als_vmax = LM3530_ALS_WINDOW_mV;
|
||||||
}
|
}
|
||||||
|
|
||||||
als_vmin = pltfm->als_vmin;
|
als_vmin = pdata->als_vmin;
|
||||||
als_vmax = pltfm->als_vmax;
|
als_vmax = pdata->als_vmax;
|
||||||
|
|
||||||
if ((als_vmax - als_vmin) > LM3530_ALS_WINDOW_mV)
|
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;
|
als_vmin + LM3530_ALS_WINDOW_mV;
|
||||||
|
|
||||||
/* n zone boundary makes n+1 zones */
|
/* n zone boundary makes n+1 zones */
|
||||||
|
@ -184,44 +193,41 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
|
||||||
/ 1000;
|
/ 1000;
|
||||||
|
|
||||||
als_config =
|
als_config =
|
||||||
(pltfm->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) |
|
(pdata->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) |
|
||||||
(LM3530_ENABLE_ALS) |
|
(LM3530_ENABLE_ALS) |
|
||||||
(pltfm->als_input_mode << LM3530_ALS_SEL_SHIFT);
|
(pdata->als_input_mode << LM3530_ALS_SEL_SHIFT);
|
||||||
|
|
||||||
als_imp_sel =
|
als_imp_sel =
|
||||||
(pltfm->als1_resistor_sel << LM3530_ALS1_IMP_SHIFT) |
|
(pdata->als1_resistor_sel << LM3530_ALS1_IMP_SHIFT) |
|
||||||
(pltfm->als2_resistor_sel << LM3530_ALS2_IMP_SHIFT);
|
(pdata->als2_resistor_sel << LM3530_ALS2_IMP_SHIFT);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drvdata->mode == LM3530_BL_MODE_PWM)
|
brt_ramp = (pdata->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) |
|
||||||
gen_config |= (LM3530_ENABLE_PWM) |
|
(pdata->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT);
|
||||||
(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);
|
|
||||||
|
|
||||||
if (drvdata->brightness)
|
if (drvdata->brightness)
|
||||||
brightness = drvdata->brightness;
|
brightness = drvdata->brightness;
|
||||||
else
|
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[0] = gen_config; /* LM3530_GEN_CONFIG */
|
||||||
reg_val[1] = als_config; /* LM3530_ALS_CONFIG */
|
reg_val[1] = als_config; /* LM3530_ALS_CONFIG */
|
||||||
reg_val[2] = brt_ramp; /* LM3530_BRT_RAMP_RATE */
|
reg_val[2] = brt_ramp; /* LM3530_BRT_RAMP_RATE */
|
||||||
reg_val[3] = 0x00; /* LM3530_ALS_ZONE_REG */
|
reg_val[3] = als_imp_sel; /* LM3530_ALS_IMP_SELECT */
|
||||||
reg_val[4] = als_imp_sel; /* LM3530_ALS_IMP_SELECT */
|
reg_val[4] = brightness; /* LM3530_BRT_CTRL_REG */
|
||||||
reg_val[5] = brightness; /* LM3530_BRT_CTRL_REG */
|
reg_val[5] = zones[0]; /* LM3530_ALS_ZB0_REG */
|
||||||
reg_val[6] = zones[0]; /* LM3530_ALS_ZB0_REG */
|
reg_val[6] = zones[1]; /* LM3530_ALS_ZB1_REG */
|
||||||
reg_val[7] = zones[1]; /* LM3530_ALS_ZB1_REG */
|
reg_val[7] = zones[2]; /* LM3530_ALS_ZB2_REG */
|
||||||
reg_val[8] = zones[2]; /* LM3530_ALS_ZB2_REG */
|
reg_val[8] = zones[3]; /* LM3530_ALS_ZB3_REG */
|
||||||
reg_val[9] = zones[3]; /* LM3530_ALS_ZB3_REG */
|
reg_val[9] = LM3530_DEF_ZT_0; /* LM3530_ALS_Z0T_REG */
|
||||||
reg_val[10] = 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_1; /* LM3530_ALS_Z1T_REG */
|
reg_val[11] = LM3530_DEF_ZT_2; /* LM3530_ALS_Z2T_REG */
|
||||||
reg_val[12] = 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_3; /* LM3530_ALS_Z3T_REG */
|
reg_val[13] = LM3530_DEF_ZT_4; /* LM3530_ALS_Z4T_REG */
|
||||||
reg_val[14] = LM3530_DEF_ZT_4; /* LM3530_ALS_Z4T_REG */
|
|
||||||
|
|
||||||
if (!drvdata->enable) {
|
if (!drvdata->enable) {
|
||||||
ret = regulator_enable(drvdata->regulator);
|
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++) {
|
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,
|
ret = i2c_smbus_write_byte_data(client,
|
||||||
lm3530_reg[i], reg_val[i]);
|
lm3530_reg[i], reg_val[i]);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -249,6 +264,9 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
|
||||||
int err;
|
int err;
|
||||||
struct lm3530_data *drvdata =
|
struct lm3530_data *drvdata =
|
||||||
container_of(led_cdev, struct lm3530_data, led_dev);
|
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) {
|
switch (drvdata->mode) {
|
||||||
case LM3530_BL_MODE_MANUAL:
|
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*/
|
/* set the brightness in brightness control register*/
|
||||||
err = i2c_smbus_write_byte_data(drvdata->client,
|
err = i2c_smbus_write_byte_data(drvdata->client,
|
||||||
LM3530_BRT_CTRL_REG, brt_val / 2);
|
LM3530_BRT_CTRL_REG, brt_val);
|
||||||
if (err)
|
if (err)
|
||||||
dev_err(&drvdata->client->dev,
|
dev_err(&drvdata->client->dev,
|
||||||
"Unable to set brightness: %d\n", err);
|
"Unable to set brightness: %d\n", err);
|
||||||
else
|
else
|
||||||
drvdata->brightness = brt_val / 2;
|
drvdata->brightness = brt_val;
|
||||||
|
|
||||||
if (brt_val == 0) {
|
if (brt_val == 0) {
|
||||||
err = regulator_disable(drvdata->regulator);
|
err = regulator_disable(drvdata->regulator);
|
||||||
|
@ -282,6 +300,8 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
|
||||||
case LM3530_BL_MODE_ALS:
|
case LM3530_BL_MODE_ALS:
|
||||||
break;
|
break;
|
||||||
case LM3530_BL_MODE_PWM:
|
case LM3530_BL_MODE_PWM:
|
||||||
|
if (pwm->pwm_set_intensity)
|
||||||
|
pwm->pwm_set_intensity(brt_val, max_brightness);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -291,11 +311,11 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
|
||||||
static ssize_t lm3530_mode_get(struct device *dev,
|
static ssize_t lm3530_mode_get(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
struct i2c_client *client = container_of(
|
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||||
dev->parent, struct i2c_client, dev);
|
struct lm3530_data *drvdata;
|
||||||
struct lm3530_data *drvdata = i2c_get_clientdata(client);
|
|
||||||
int i, len = 0;
|
int i, len = 0;
|
||||||
|
|
||||||
|
drvdata = container_of(led_cdev, struct lm3530_data, led_dev);
|
||||||
for (i = 0; i < ARRAY_SIZE(mode_map); i++)
|
for (i = 0; i < ARRAY_SIZE(mode_map); i++)
|
||||||
if (drvdata->mode == mode_map[i].mode_val)
|
if (drvdata->mode == mode_map[i].mode_val)
|
||||||
len += sprintf(buf + len, "[%s] ", mode_map[i].mode);
|
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
|
static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute
|
||||||
*attr, const char *buf, size_t size)
|
*attr, const char *buf, size_t size)
|
||||||
{
|
{
|
||||||
int err;
|
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||||
struct i2c_client *client = container_of(
|
struct lm3530_data *drvdata;
|
||||||
dev->parent, struct i2c_client, dev);
|
struct lm3530_pwm_data *pwm;
|
||||||
struct lm3530_data *drvdata = i2c_get_clientdata(client);
|
u8 max_brightness;
|
||||||
int mode;
|
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);
|
mode = lm3530_get_mode_from_str(buf);
|
||||||
if (mode < 0) {
|
if (mode < 0) {
|
||||||
dev_err(dev, "Invalid mode\n");
|
dev_err(dev, "Invalid mode\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == LM3530_BL_MODE_MANUAL)
|
drvdata->mode = mode;
|
||||||
drvdata->mode = LM3530_BL_MODE_MANUAL;
|
|
||||||
else if (mode == LM3530_BL_MODE_ALS)
|
/* set pwm to low if unnecessary */
|
||||||
drvdata->mode = LM3530_BL_MODE_ALS;
|
if (mode != LM3530_BL_MODE_PWM && pwm->pwm_set_intensity)
|
||||||
else if (mode == LM3530_BL_MODE_PWM) {
|
pwm->pwm_set_intensity(0, max_brightness);
|
||||||
dev_err(dev, "PWM mode not supported\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = lm3530_init_registers(drvdata);
|
err = lm3530_init_registers(drvdata);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -380,6 +400,7 @@ static int __devinit lm3530_probe(struct i2c_client *client,
|
||||||
drvdata->enable = false;
|
drvdata->enable = false;
|
||||||
drvdata->led_dev.name = LM3530_LED_DEV;
|
drvdata->led_dev.name = LM3530_LED_DEV;
|
||||||
drvdata->led_dev.brightness_set = lm3530_brightness_set;
|
drvdata->led_dev.brightness_set = lm3530_brightness_set;
|
||||||
|
drvdata->led_dev.max_brightness = MAX_BRIGHTNESS;
|
||||||
|
|
||||||
i2c_set_clientdata(client, drvdata);
|
i2c_set_clientdata(client, drvdata);
|
||||||
|
|
||||||
|
|
|
@ -81,18 +81,10 @@
|
||||||
#define LP5521_MASTER_ENABLE 0x40 /* Chip master enable */
|
#define LP5521_MASTER_ENABLE 0x40 /* Chip master enable */
|
||||||
#define LP5521_LOGARITHMIC_PWM 0x80 /* Logarithmic PWM adjustment */
|
#define LP5521_LOGARITHMIC_PWM 0x80 /* Logarithmic PWM adjustment */
|
||||||
#define LP5521_EXEC_RUN 0x2A
|
#define LP5521_EXEC_RUN 0x2A
|
||||||
|
#define LP5521_ENABLE_DEFAULT \
|
||||||
/* Bits in CONFIG register */
|
(LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM)
|
||||||
#define LP5521_PWM_HF 0x40 /* PWM: 0 = 256Hz, 1 = 558Hz */
|
#define LP5521_ENABLE_RUN_PROGRAM \
|
||||||
#define LP5521_PWRSAVE_EN 0x20 /* 1 = Power save mode */
|
(LP5521_ENABLE_DEFAULT | LP5521_EXEC_RUN)
|
||||||
#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 */
|
|
||||||
|
|
||||||
/* Status */
|
/* Status */
|
||||||
#define LP5521_EXT_CLK_USED 0x08
|
#define LP5521_EXT_CLK_USED 0x08
|
||||||
|
@ -100,6 +92,9 @@
|
||||||
/* default R channel current register value */
|
/* default R channel current register value */
|
||||||
#define LP5521_REG_R_CURR_DEFAULT 0xAF
|
#define LP5521_REG_R_CURR_DEFAULT 0xAF
|
||||||
|
|
||||||
|
/* Pattern Mode */
|
||||||
|
#define PATTERN_OFF 0
|
||||||
|
|
||||||
struct lp5521_engine {
|
struct lp5521_engine {
|
||||||
int id;
|
int id;
|
||||||
u8 mode;
|
u8 mode;
|
||||||
|
@ -241,15 +236,16 @@ static int lp5521_configure(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct lp5521_chip *chip = i2c_get_clientdata(client);
|
struct lp5521_chip *chip = i2c_get_clientdata(client);
|
||||||
int ret;
|
int ret;
|
||||||
|
u8 cfg;
|
||||||
|
|
||||||
lp5521_init_engine(chip);
|
lp5521_init_engine(chip);
|
||||||
|
|
||||||
/* Set all PWMs to direct control mode */
|
/* 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 */
|
cfg = chip->pdata->update_config ?
|
||||||
ret |= lp5521_write(client, LP5521_REG_CONFIG,
|
: (LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT);
|
||||||
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 */
|
/* Initialize all channels PWM to zero -> leds off */
|
||||||
ret |= lp5521_write(client, LP5521_REG_R_PWM, 0);
|
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 */
|
/* Set engines are set to run state when OP_MODE enables engines */
|
||||||
ret |= lp5521_write(client, LP5521_REG_ENABLE,
|
ret |= lp5521_write(client, LP5521_REG_ENABLE,
|
||||||
LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM |
|
LP5521_ENABLE_RUN_PROGRAM);
|
||||||
LP5521_EXEC_RUN);
|
|
||||||
/* enable takes 500us. 1 - 2 ms leaves some margin */
|
/* enable takes 500us. 1 - 2 ms leaves some margin */
|
||||||
usleep_range(1000, 2000);
|
usleep_range(1000, 2000);
|
||||||
|
|
||||||
|
@ -310,8 +305,7 @@ static int lp5521_detect(struct i2c_client *client)
|
||||||
int ret;
|
int ret;
|
||||||
u8 buf;
|
u8 buf;
|
||||||
|
|
||||||
ret = lp5521_write(client, LP5521_REG_ENABLE,
|
ret = lp5521_write(client, LP5521_REG_ENABLE, LP5521_ENABLE_DEFAULT);
|
||||||
LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
/* enable takes 500us. 1 - 2 ms leaves some margin */
|
/* 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);
|
ret = lp5521_read(client, LP5521_REG_ENABLE, &buf);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (buf != (LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM))
|
if (buf != LP5521_ENABLE_DEFAULT)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -504,7 +498,7 @@ static ssize_t store_current(struct device *dev,
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
unsigned long curr;
|
unsigned long curr;
|
||||||
|
|
||||||
if (strict_strtoul(buf, 0, &curr))
|
if (kstrtoul(buf, 0, &curr))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (curr > led->max_current)
|
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");
|
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 */
|
/* led class device attributes */
|
||||||
static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, show_current, store_current);
|
static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, show_current, store_current);
|
||||||
static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL);
|
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(engine2_load, S_IWUSR, NULL, store_engine2_load);
|
||||||
static DEVICE_ATTR(engine3_load, S_IWUSR, NULL, store_engine3_load);
|
static DEVICE_ATTR(engine3_load, S_IWUSR, NULL, store_engine3_load);
|
||||||
static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL);
|
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[] = {
|
static struct attribute *lp5521_attributes[] = {
|
||||||
&dev_attr_engine1_mode.attr,
|
&dev_attr_engine1_mode.attr,
|
||||||
|
@ -570,6 +656,7 @@ static struct attribute *lp5521_attributes[] = {
|
||||||
&dev_attr_engine1_load.attr,
|
&dev_attr_engine1_load.attr,
|
||||||
&dev_attr_engine2_load.attr,
|
&dev_attr_engine2_load.attr,
|
||||||
&dev_attr_engine3_load.attr,
|
&dev_attr_engine3_load.attr,
|
||||||
|
&dev_attr_led_pattern.attr,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -620,10 +707,15 @@ static int __devinit lp5521_init_led(struct lp5521_led *led,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(name, sizeof(name), "%s:channel%d",
|
|
||||||
pdata->label ?: client->name, chan);
|
|
||||||
led->cdev.brightness_set = lp5521_set_brightness;
|
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);
|
res = led_classdev_register(dev, &led->cdev);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
dev_err(dev, "couldn't register led on channel %d\n", chan);
|
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
|
* otherwise further access to the R G B channels in the
|
||||||
* LP5521_REG_ENABLE register will not have any effect - strange!
|
* 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) {
|
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;
|
goto fail2;
|
||||||
}
|
}
|
||||||
usleep_range(10000, 20000);
|
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);
|
struct lp5521_chip *chip = i2c_get_clientdata(client);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
lp5521_run_led_pattern(PATTERN_OFF, chip);
|
||||||
lp5521_unregister_sysfs(client);
|
lp5521_unregister_sysfs(client);
|
||||||
|
|
||||||
for (i = 0; i < chip->num_leds; i++) {
|
for (i = 0; i < chip->num_leds; i++) {
|
||||||
|
|
|
@ -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_mode(struct lp5523_engine *engine, u8 mode);
|
||||||
static int lp5523_set_engine_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);
|
static void lp5523_led_brightness_work(struct work_struct *work);
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ static int lp5523_configure(struct i2c_client *client)
|
||||||
u8 status;
|
u8 status;
|
||||||
|
|
||||||
/* one pattern per engine setting led mux start and stop addresses */
|
/* 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, 0x30, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0},
|
||||||
{ 0x9c, 0x40, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0},
|
{ 0x9c, 0x40, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0},
|
||||||
{ 0x9c, 0x50, 0x9c, 0xd0, 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;
|
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 lp5523_chip *chip = engine_to_lp5523(engine);
|
||||||
struct i2c_client *client = chip->client;
|
struct i2c_client *client = chip->client;
|
||||||
|
|
|
@ -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");
|
|
@ -687,10 +687,9 @@ static int __devinit tca6507_probe(struct i2c_client *client,
|
||||||
NUM_LEDS);
|
NUM_LEDS);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
err = -ENOMEM;
|
|
||||||
tca = kzalloc(sizeof(*tca), GFP_KERNEL);
|
tca = kzalloc(sizeof(*tca), GFP_KERNEL);
|
||||||
if (!tca)
|
if (!tca)
|
||||||
goto exit;
|
return -ENOMEM;
|
||||||
|
|
||||||
tca->client = client;
|
tca->client = client;
|
||||||
INIT_WORK(&tca->work, tca6507_work);
|
INIT_WORK(&tca->work, tca6507_work);
|
||||||
|
@ -724,11 +723,10 @@ static int __devinit tca6507_probe(struct i2c_client *client,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
exit:
|
exit:
|
||||||
while (i--)
|
while (i--) {
|
||||||
if (tca->leds[i].led_cdev.name)
|
if (tca->leds[i].led_cdev.name)
|
||||||
led_classdev_unregister(&tca->leds[i].led_cdev);
|
led_classdev_unregister(&tca->leds[i].led_cdev);
|
||||||
cancel_work_sync(&tca->work);
|
}
|
||||||
i2c_set_clientdata(client, NULL);
|
|
||||||
kfree(tca);
|
kfree(tca);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -745,7 +743,6 @@ static int __devexit tca6507_remove(struct i2c_client *client)
|
||||||
}
|
}
|
||||||
tca6507_remove_gpio(tca);
|
tca6507_remove_gpio(tca);
|
||||||
cancel_work_sync(&tca->work);
|
cancel_work_sync(&tca->work);
|
||||||
i2c_set_clientdata(client, NULL);
|
|
||||||
kfree(tca);
|
kfree(tca);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -2526,12 +2526,10 @@ static void cfi_intelext_restore_locks(struct mtd_info *mtd)
|
||||||
if (!region->lockmap)
|
if (!region->lockmap)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (block = 0; block < region->numblocks; block++) {
|
for_each_clear_bit(block, region->lockmap, region->numblocks) {
|
||||||
len = region->erasesize;
|
len = region->erasesize;
|
||||||
adr = region->offset + block * len;
|
adr = region->offset + block * len;
|
||||||
|
cfi_intelext_unlock(mtd, adr, len);
|
||||||
if (!test_bit(block, region->lockmap))
|
|
||||||
cfi_intelext_unlock(mtd, adr, len);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,13 +31,13 @@
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <linux/mount.h>
|
#include <linux/mount.h>
|
||||||
#include <linux/blkpg.h>
|
#include <linux/blkpg.h>
|
||||||
|
#include <linux/magic.h>
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/partitions.h>
|
#include <linux/mtd/partitions.h>
|
||||||
#include <linux/mtd/map.h>
|
#include <linux/mtd/map.h>
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
#define MTD_INODE_FS_MAGIC 0x11307854
|
|
||||||
static DEFINE_MUTEX(mtd_mutex);
|
static DEFINE_MUTEX(mtd_mutex);
|
||||||
static struct vfsmount *mtd_inode_mnt __read_mostly;
|
static struct vfsmount *mtd_inode_mnt __read_mostly;
|
||||||
|
|
||||||
|
|
|
@ -554,6 +554,13 @@ config RTC_DRV_DS1742
|
||||||
This driver can also be built as a module. If so, the module
|
This driver can also be built as a module. If so, the module
|
||||||
will be called rtc-ds1742.
|
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
|
config RTC_DRV_EFI
|
||||||
tristate "EFI RTC"
|
tristate "EFI RTC"
|
||||||
depends on IA64
|
depends on IA64
|
||||||
|
@ -1070,4 +1077,14 @@ config RTC_DRV_PUV3
|
||||||
This drive can also be built as a module. If so, the module
|
This drive can also be built as a module. If so, the module
|
||||||
will be called rtc-puv3.
|
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
|
endif # RTC_CLASS
|
||||||
|
|
|
@ -27,6 +27,7 @@ obj-$(CONFIG_RTC_DRV_BQ32K) += rtc-bq32k.o
|
||||||
obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o
|
obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o
|
||||||
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
|
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
|
||||||
obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.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_DAVINCI) += rtc-davinci.o
|
||||||
obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o
|
obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o
|
||||||
obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.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_ISL12022) += rtc-isl12022.o
|
||||||
obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o
|
obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o
|
||||||
obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.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_M41T80) += rtc-m41t80.o
|
||||||
obj-$(CONFIG_RTC_DRV_M41T93) += rtc-m41t93.o
|
obj-$(CONFIG_RTC_DRV_M41T93) += rtc-m41t93.o
|
||||||
obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o
|
obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o
|
||||||
|
|
|
@ -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 */
|
/* register irq handler after we know what name we'll use */
|
||||||
ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt,
|
ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt,
|
||||||
IRQF_DISABLED | IRQF_SHARED,
|
IRQF_SHARED,
|
||||||
dev_name(&rtc->rtcdev->dev), rtc);
|
dev_name(&rtc->rtcdev->dev), rtc);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS);
|
dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS);
|
||||||
|
|
|
@ -187,17 +187,7 @@ static struct i2c_driver bq32k_driver = {
|
||||||
.id_table = bq32k_id,
|
.id_table = bq32k_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static __init int bq32k_init(void)
|
module_i2c_driver(bq32k_driver);
|
||||||
{
|
|
||||||
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_AUTHOR("Semihalf, Piotr Ziecik <kosmo@semihalf.com>");
|
MODULE_AUTHOR("Semihalf, Piotr Ziecik <kosmo@semihalf.com>");
|
||||||
MODULE_DESCRIPTION("TI BQ32000 I2C RTC driver");
|
MODULE_DESCRIPTION("TI BQ32000 I2C RTC driver");
|
||||||
|
|
|
@ -714,7 +714,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
|
||||||
rtc_cmos_int_handler = cmos_interrupt;
|
rtc_cmos_int_handler = cmos_interrupt;
|
||||||
|
|
||||||
retval = request_irq(rtc_irq, rtc_cmos_int_handler,
|
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);
|
cmos_rtc.rtc);
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
|
dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
|
||||||
|
|
|
@ -199,7 +199,7 @@ static int __init coh901331_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
rtap->irq = platform_get_irq(pdev, 0);
|
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)) {
|
"RTC COH 901 331 Alarm", rtap)) {
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
goto out_no_irq;
|
goto out_no_irq;
|
||||||
|
|
|
@ -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");
|
|
@ -542,7 +542,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
|
||||||
rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL);
|
rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL);
|
||||||
|
|
||||||
ret = request_irq(davinci_rtc->irq, davinci_rtc_interrupt,
|
ret = request_irq(davinci_rtc->irq, davinci_rtc_interrupt,
|
||||||
IRQF_DISABLED, "davinci_rtc", davinci_rtc);
|
0, "davinci_rtc", davinci_rtc);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(dev, "unable to register davinci RTC interrupt\n");
|
dev_err(dev, "unable to register davinci RTC interrupt\n");
|
||||||
goto fail4;
|
goto fail4;
|
||||||
|
|
|
@ -814,17 +814,7 @@ static struct spi_driver ds1305_driver = {
|
||||||
/* REVISIT add suspend/resume */
|
/* REVISIT add suspend/resume */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init ds1305_init(void)
|
module_spi_driver(ds1305_driver);
|
||||||
{
|
|
||||||
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_DESCRIPTION("RTC driver for DS1305 and DS1306 chips");
|
MODULE_DESCRIPTION("RTC driver for DS1305 and DS1306 chips");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -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
|
* 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.
|
* setting the date and time), Linux can ignore the non-clock features.
|
||||||
* That's a natural job for a factory or repair bench.
|
* That's a natural job for a factory or repair bench.
|
||||||
|
@ -36,7 +37,8 @@ enum ds_type {
|
||||||
m41t00,
|
m41t00,
|
||||||
mcp7941x,
|
mcp7941x,
|
||||||
rx_8025,
|
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 DS1337_BIT_CENTURY 0x80 /* in REG_MONTH */
|
||||||
#define DS1307_REG_YEAR 0x06 /* 00-99 */
|
#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
|
* start at 7, and they differ a LOT. Only control and status matter for
|
||||||
* basic RTC date and time functionality; be careful using them.
|
* basic RTC date and time functionality; be careful using them.
|
||||||
*/
|
*/
|
||||||
|
@ -102,6 +105,8 @@ enum ds_type {
|
||||||
struct ds1307 {
|
struct ds1307 {
|
||||||
u8 offset; /* register's offset */
|
u8 offset; /* register's offset */
|
||||||
u8 regs[11];
|
u8 regs[11];
|
||||||
|
u16 nvram_offset;
|
||||||
|
struct bin_attribute *nvram;
|
||||||
enum ds_type type;
|
enum ds_type type;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
#define HAS_NVRAM 0 /* bit 0 == sysfs file active */
|
#define HAS_NVRAM 0 /* bit 0 == sysfs file active */
|
||||||
|
@ -116,34 +121,35 @@ struct ds1307 {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chip_desc {
|
struct chip_desc {
|
||||||
unsigned nvram56:1;
|
|
||||||
unsigned alarm:1;
|
unsigned alarm:1;
|
||||||
|
u16 nvram_offset;
|
||||||
|
u16 nvram_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct chip_desc chips[] = {
|
static const struct chip_desc chips[last_ds_type] = {
|
||||||
[ds_1307] = {
|
[ds_1307] = {
|
||||||
.nvram56 = 1,
|
.nvram_offset = 8,
|
||||||
},
|
.nvram_size = 56,
|
||||||
[ds_1337] = {
|
},
|
||||||
.alarm = 1,
|
[ds_1337] = {
|
||||||
},
|
.alarm = 1,
|
||||||
[ds_1338] = {
|
},
|
||||||
.nvram56 = 1,
|
[ds_1338] = {
|
||||||
},
|
.nvram_offset = 8,
|
||||||
[ds_1339] = {
|
.nvram_size = 56,
|
||||||
.alarm = 1,
|
},
|
||||||
},
|
[ds_1339] = {
|
||||||
[ds_1340] = {
|
.alarm = 1,
|
||||||
},
|
},
|
||||||
[ds_3231] = {
|
[ds_3231] = {
|
||||||
.alarm = 1,
|
.alarm = 1,
|
||||||
},
|
},
|
||||||
[m41t00] = {
|
[mcp7941x] = {
|
||||||
},
|
/* this is battery backed SRAM */
|
||||||
[mcp7941x] = {
|
.nvram_offset = 0x20,
|
||||||
},
|
.nvram_size = 0x40,
|
||||||
[rx_8025] = {
|
},
|
||||||
}, };
|
};
|
||||||
|
|
||||||
static const struct i2c_device_id ds1307_id[] = {
|
static const struct i2c_device_id ds1307_id[] = {
|
||||||
{ "ds1307", ds_1307 },
|
{ "ds1307", ds_1307 },
|
||||||
|
@ -372,6 +378,11 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
|
||||||
| DS1340_BIT_CENTURY;
|
| DS1340_BIT_CENTURY;
|
||||||
break;
|
break;
|
||||||
case mcp7941x:
|
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_SECS] |= MCP7941X_BIT_ST;
|
||||||
buf[DS1307_REG_WDAY] |= MCP7941X_BIT_VBATEN;
|
buf[DS1307_REG_WDAY] |= MCP7941X_BIT_VBATEN;
|
||||||
break;
|
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[6], ds1307->regs[7],
|
||||||
ds1307->regs[8]);
|
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
|
* and that all four fields are checked matches
|
||||||
*/
|
*/
|
||||||
t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f);
|
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)
|
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);
|
struct ds1307 *ds1307 = i2c_get_clientdata(client);
|
||||||
unsigned char *buf = ds1307->regs;
|
unsigned char *buf = ds1307->regs;
|
||||||
u8 control, status;
|
u8 control, status;
|
||||||
|
@ -541,8 +553,6 @@ static const struct rtc_class_ops ds13xx_rtc_ops = {
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define NVRAM_SIZE 56
|
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
ds1307_nvram_read(struct file *filp, struct kobject *kobj,
|
ds1307_nvram_read(struct file *filp, struct kobject *kobj,
|
||||||
struct bin_attribute *attr,
|
struct bin_attribute *attr,
|
||||||
|
@ -555,14 +565,15 @@ ds1307_nvram_read(struct file *filp, struct kobject *kobj,
|
||||||
client = kobj_to_i2c_client(kobj);
|
client = kobj_to_i2c_client(kobj);
|
||||||
ds1307 = i2c_get_clientdata(client);
|
ds1307 = i2c_get_clientdata(client);
|
||||||
|
|
||||||
if (unlikely(off >= NVRAM_SIZE))
|
if (unlikely(off >= ds1307->nvram->size))
|
||||||
return 0;
|
return 0;
|
||||||
if ((off + count) > NVRAM_SIZE)
|
if ((off + count) > ds1307->nvram->size)
|
||||||
count = NVRAM_SIZE - off;
|
count = ds1307->nvram->size - off;
|
||||||
if (unlikely(!count))
|
if (unlikely(!count))
|
||||||
return 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)
|
if (result < 0)
|
||||||
dev_err(&client->dev, "%s error %d\n", "nvram read", result);
|
dev_err(&client->dev, "%s error %d\n", "nvram read", result);
|
||||||
return result;
|
return result;
|
||||||
|
@ -580,14 +591,15 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj,
|
||||||
client = kobj_to_i2c_client(kobj);
|
client = kobj_to_i2c_client(kobj);
|
||||||
ds1307 = i2c_get_clientdata(client);
|
ds1307 = i2c_get_clientdata(client);
|
||||||
|
|
||||||
if (unlikely(off >= NVRAM_SIZE))
|
if (unlikely(off >= ds1307->nvram->size))
|
||||||
return -EFBIG;
|
return -EFBIG;
|
||||||
if ((off + count) > NVRAM_SIZE)
|
if ((off + count) > ds1307->nvram->size)
|
||||||
count = NVRAM_SIZE - off;
|
count = ds1307->nvram->size - off;
|
||||||
if (unlikely(!count))
|
if (unlikely(!count))
|
||||||
return 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) {
|
if (result < 0) {
|
||||||
dev_err(&client->dev, "%s error %d\n", "nvram write", result);
|
dev_err(&client->dev, "%s error %d\n", "nvram write", result);
|
||||||
return result;
|
return result;
|
||||||
|
@ -595,21 +607,8 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj,
|
||||||
return count;
|
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,
|
static int __devinit ds1307_probe(struct i2c_client *client,
|
||||||
const struct i2c_device_id *id)
|
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))
|
&& !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL)))
|
ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL);
|
||||||
|
if (!ds1307)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
i2c_set_clientdata(client, ds1307);
|
i2c_set_clientdata(client, ds1307);
|
||||||
|
@ -652,11 +652,6 @@ static int __devinit ds1307_probe(struct i2c_client *client,
|
||||||
case ds_1337:
|
case ds_1337:
|
||||||
case ds_1339:
|
case ds_1339:
|
||||||
case ds_3231:
|
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... */
|
/* get registers that the "rtc" read below won't read... */
|
||||||
tmp = ds1307->read_block_data(ds1307->client,
|
tmp = ds1307->read_block_data(ds1307->client,
|
||||||
DS1337_REG_CONTROL, 2, buf);
|
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)
|
if (ds1307->regs[0] & DS1337_BIT_nEOSC)
|
||||||
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
|
* For some variants, be sure alarms can trigger when we're
|
||||||
* running on Vbackup (BBSQI/BBSQW)
|
* 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
|
ds1307->regs[0] |= DS1337_BIT_INTCN
|
||||||
| bbsqi_bitpos[ds1307->type];
|
| bbsqi_bitpos[ds1307->type];
|
||||||
ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
|
ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
|
||||||
|
|
||||||
|
want_irq = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
|
i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
|
||||||
|
@ -772,7 +772,8 @@ read_rtc:
|
||||||
goto exit_free;
|
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
|
* specify the extra bits as must-be-zero, but there are
|
||||||
* still a few values that are clearly out-of-range.
|
* still a few values that are clearly out-of-range.
|
||||||
*/
|
*/
|
||||||
|
@ -836,11 +837,7 @@ read_rtc:
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case rx_8025:
|
default:
|
||||||
case ds_1337:
|
|
||||||
case ds_1339:
|
|
||||||
case ds_1388:
|
|
||||||
case ds_3231:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,7 +845,8 @@ read_rtc:
|
||||||
switch (ds1307->type) {
|
switch (ds1307->type) {
|
||||||
case ds_1340:
|
case ds_1340:
|
||||||
case m41t00:
|
case m41t00:
|
||||||
/* NOTE: ignores century bits; fix before deploying
|
/*
|
||||||
|
* NOTE: ignores century bits; fix before deploying
|
||||||
* systems that will run through year 2100.
|
* systems that will run through year 2100.
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
|
@ -858,7 +856,8 @@ read_rtc:
|
||||||
if (!(tmp & DS1307_BIT_12HR))
|
if (!(tmp & DS1307_BIT_12HR))
|
||||||
break;
|
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...
|
* take note...
|
||||||
*/
|
*/
|
||||||
tmp = bcd2bin(tmp & 0x1f);
|
tmp = bcd2bin(tmp & 0x1f);
|
||||||
|
@ -894,16 +893,31 @@ read_rtc:
|
||||||
dev_dbg(&client->dev, "got IRQ %d\n", client->irq);
|
dev_dbg(&client->dev, "got IRQ %d\n", client->irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chip->nvram56) {
|
if (chip->nvram_size) {
|
||||||
err = sysfs_create_bin_file(&client->dev.kobj, &nvram);
|
ds1307->nvram = kzalloc(sizeof(struct bin_attribute),
|
||||||
if (err == 0) {
|
GFP_KERNEL);
|
||||||
set_bit(HAS_NVRAM, &ds1307->flags);
|
if (!ds1307->nvram) {
|
||||||
dev_info(&client->dev, "56 bytes nvram\n");
|
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;
|
return 0;
|
||||||
|
|
||||||
|
exit_nvram:
|
||||||
exit_irq:
|
exit_irq:
|
||||||
rtc_device_unregister(ds1307->rtc);
|
rtc_device_unregister(ds1307->rtc);
|
||||||
exit_free:
|
exit_free:
|
||||||
|
@ -913,15 +927,17 @@ exit_free:
|
||||||
|
|
||||||
static int __devexit ds1307_remove(struct i2c_client *client)
|
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)) {
|
if (test_and_clear_bit(HAS_ALARM, &ds1307->flags)) {
|
||||||
free_irq(client->irq, client);
|
free_irq(client->irq, client);
|
||||||
cancel_work_sync(&ds1307->work);
|
cancel_work_sync(&ds1307->work);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags))
|
if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags)) {
|
||||||
sysfs_remove_bin_file(&client->dev.kobj, &nvram);
|
sysfs_remove_bin_file(&client->dev.kobj, ds1307->nvram);
|
||||||
|
kfree(ds1307->nvram);
|
||||||
|
}
|
||||||
|
|
||||||
rtc_device_unregister(ds1307->rtc);
|
rtc_device_unregister(ds1307->rtc);
|
||||||
kfree(ds1307);
|
kfree(ds1307);
|
||||||
|
@ -938,17 +954,7 @@ static struct i2c_driver ds1307_driver = {
|
||||||
.id_table = ds1307_id,
|
.id_table = ds1307_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init ds1307_init(void)
|
module_i2c_driver(ds1307_driver);
|
||||||
{
|
|
||||||
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_DESCRIPTION("RTC driver for DS1307 and similar chips");
|
MODULE_DESCRIPTION("RTC driver for DS1307 and similar chips");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -446,18 +446,7 @@ static struct i2c_driver ds1374_driver = {
|
||||||
.id_table = ds1374_id,
|
.id_table = ds1374_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init ds1374_init(void)
|
module_i2c_driver(ds1374_driver);
|
||||||
{
|
|
||||||
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_AUTHOR("Scott Wood <scottwood@freescale.com>");
|
MODULE_AUTHOR("Scott Wood <scottwood@freescale.com>");
|
||||||
MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC Driver");
|
MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC Driver");
|
||||||
|
|
|
@ -175,17 +175,7 @@ static struct spi_driver ds1390_driver = {
|
||||||
.remove = __devexit_p(ds1390_remove),
|
.remove = __devexit_p(ds1390_remove),
|
||||||
};
|
};
|
||||||
|
|
||||||
static __init int ds1390_init(void)
|
module_spi_driver(ds1390_driver);
|
||||||
{
|
|
||||||
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_DESCRIPTION("Dallas/Maxim DS1390/93/94 SPI RTC driver");
|
MODULE_DESCRIPTION("Dallas/Maxim DS1390/93/94 SPI RTC driver");
|
||||||
MODULE_AUTHOR("Mark Jackson <mpfj@mimc.co.uk>");
|
MODULE_AUTHOR("Mark Jackson <mpfj@mimc.co.uk>");
|
||||||
|
|
|
@ -532,7 +532,7 @@ ds1511_rtc_probe(struct platform_device *pdev)
|
||||||
if (pdata->irq > 0) {
|
if (pdata->irq > 0) {
|
||||||
rtc_read(RTC_CMD1);
|
rtc_read(RTC_CMD1);
|
||||||
if (devm_request_irq(&pdev->dev, pdata->irq, ds1511_interrupt,
|
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");
|
dev_warn(&pdev->dev, "interrupt not available.\n");
|
||||||
pdata->irq = 0;
|
pdata->irq = 0;
|
||||||
|
|
|
@ -320,7 +320,7 @@ static int __devinit ds1553_rtc_probe(struct platform_device *pdev)
|
||||||
writeb(0, ioaddr + RTC_INTERRUPTS);
|
writeb(0, ioaddr + RTC_INTERRUPTS);
|
||||||
if (devm_request_irq(&pdev->dev, pdata->irq,
|
if (devm_request_irq(&pdev->dev, pdata->irq,
|
||||||
ds1553_rtc_interrupt,
|
ds1553_rtc_interrupt,
|
||||||
IRQF_DISABLED, pdev->name, pdev) < 0) {
|
0, pdev->name, pdev) < 0) {
|
||||||
dev_warn(&pdev->dev, "interrupt not available.\n");
|
dev_warn(&pdev->dev, "interrupt not available.\n");
|
||||||
pdata->irq = 0;
|
pdata->irq = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,20 +202,9 @@ static struct i2c_driver ds1672_driver = {
|
||||||
.id_table = ds1672_id,
|
.id_table = ds1672_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init ds1672_init(void)
|
module_i2c_driver(ds1672_driver);
|
||||||
{
|
|
||||||
return i2c_add_driver(&ds1672_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit ds1672_exit(void)
|
|
||||||
{
|
|
||||||
i2c_del_driver(&ds1672_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
|
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
|
||||||
MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver");
|
MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_VERSION(DRV_VERSION);
|
MODULE_VERSION(DRV_VERSION);
|
||||||
|
|
||||||
module_init(ds1672_init);
|
|
||||||
module_exit(ds1672_exit);
|
|
||||||
|
|
|
@ -473,18 +473,7 @@ static struct i2c_driver ds3232_driver = {
|
||||||
.id_table = ds3232_id,
|
.id_table = ds3232_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init ds3232_init(void)
|
module_i2c_driver(ds3232_driver);
|
||||||
{
|
|
||||||
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_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>");
|
MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>");
|
||||||
MODULE_DESCRIPTION("Maxim/Dallas DS3232 RTC Driver");
|
MODULE_DESCRIPTION("Maxim/Dallas DS3232 RTC Driver");
|
||||||
|
|
|
@ -173,17 +173,7 @@ static struct spi_driver ds3234_driver = {
|
||||||
.remove = __devexit_p(ds3234_remove),
|
.remove = __devexit_p(ds3234_remove),
|
||||||
};
|
};
|
||||||
|
|
||||||
static __init int ds3234_init(void)
|
module_spi_driver(ds3234_driver);
|
||||||
{
|
|
||||||
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_DESCRIPTION("DS3234 SPI RTC driver");
|
MODULE_DESCRIPTION("DS3234 SPI RTC driver");
|
||||||
MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>");
|
MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>");
|
||||||
|
|
|
@ -144,19 +144,8 @@ static struct i2c_driver em3027_driver = {
|
||||||
.id_table = em3027_id,
|
.id_table = em3027_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init em3027_init(void)
|
module_i2c_driver(em3027_driver);
|
||||||
{
|
|
||||||
return i2c_add_driver(&em3027_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit em3027_exit(void)
|
|
||||||
{
|
|
||||||
i2c_del_driver(&em3027_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
|
MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
|
||||||
MODULE_DESCRIPTION("EM Microelectronic EM3027 RTC driver");
|
MODULE_DESCRIPTION("EM Microelectronic EM3027 RTC driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
module_init(em3027_init);
|
|
||||||
module_exit(em3027_exit);
|
|
||||||
|
|
|
@ -565,17 +565,7 @@ static struct i2c_driver fm3130_driver = {
|
||||||
.id_table = fm3130_id,
|
.id_table = fm3130_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init fm3130_init(void)
|
module_i2c_driver(fm3130_driver);
|
||||||
{
|
|
||||||
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_DESCRIPTION("RTC driver for FM3130");
|
MODULE_DESCRIPTION("RTC driver for FM3130");
|
||||||
MODULE_AUTHOR("Sergey Lapin <slapin@ossfans.org>");
|
MODULE_AUTHOR("Sergey Lapin <slapin@ossfans.org>");
|
||||||
|
|
|
@ -309,18 +309,7 @@ static struct i2c_driver isl12022_driver = {
|
||||||
.id_table = isl12022_id,
|
.id_table = isl12022_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init isl12022_init(void)
|
module_i2c_driver(isl12022_driver);
|
||||||
{
|
|
||||||
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_AUTHOR("roman.fietze@telemotive.de");
|
MODULE_AUTHOR("roman.fietze@telemotive.de");
|
||||||
MODULE_DESCRIPTION("ISL 12022 RTC driver");
|
MODULE_DESCRIPTION("ISL 12022 RTC driver");
|
||||||
|
|
|
@ -710,22 +710,9 @@ static struct i2c_driver isl1208_driver = {
|
||||||
.id_table = isl1208_id,
|
.id_table = isl1208_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init
|
module_i2c_driver(isl1208_driver);
|
||||||
isl1208_init(void)
|
|
||||||
{
|
|
||||||
return i2c_add_driver(&isl1208_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit
|
|
||||||
isl1208_exit(void)
|
|
||||||
{
|
|
||||||
i2c_del_driver(&isl1208_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>");
|
MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>");
|
||||||
MODULE_DESCRIPTION("Intersil ISL1208 RTC driver");
|
MODULE_DESCRIPTION("Intersil ISL1208 RTC driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_VERSION(DRV_VERSION);
|
MODULE_VERSION(DRV_VERSION);
|
||||||
|
|
||||||
module_init(isl1208_init);
|
|
||||||
module_exit(isl1208_exit);
|
|
||||||
|
|
|
@ -287,7 +287,7 @@ static int __devinit lpc32xx_rtc_probe(struct platform_device *pdev)
|
||||||
if (rtc->irq >= 0) {
|
if (rtc->irq >= 0) {
|
||||||
if (devm_request_irq(&pdev->dev, rtc->irq,
|
if (devm_request_irq(&pdev->dev, rtc->irq,
|
||||||
lpc32xx_rtc_alarm_interrupt,
|
lpc32xx_rtc_alarm_interrupt,
|
||||||
IRQF_DISABLED, pdev->name, rtc) < 0) {
|
0, pdev->name, rtc) < 0) {
|
||||||
dev_warn(&pdev->dev, "Can't request interrupt.\n");
|
dev_warn(&pdev->dev, "Can't request interrupt.\n");
|
||||||
rtc->irq = -1;
|
rtc->irq = -1;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -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");
|
|
@ -900,20 +900,9 @@ static struct i2c_driver m41t80_driver = {
|
||||||
.id_table = m41t80_id,
|
.id_table = m41t80_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init m41t80_rtc_init(void)
|
module_i2c_driver(m41t80_driver);
|
||||||
{
|
|
||||||
return i2c_add_driver(&m41t80_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit m41t80_rtc_exit(void)
|
|
||||||
{
|
|
||||||
i2c_del_driver(&m41t80_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Alexander Bigga <ab@mycable.de>");
|
MODULE_AUTHOR("Alexander Bigga <ab@mycable.de>");
|
||||||
MODULE_DESCRIPTION("ST Microelectronics M41T80 series RTC I2C Client Driver");
|
MODULE_DESCRIPTION("ST Microelectronics M41T80 series RTC I2C Client Driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_VERSION(DRV_VERSION);
|
MODULE_VERSION(DRV_VERSION);
|
||||||
|
|
||||||
module_init(m41t80_rtc_init);
|
|
||||||
module_exit(m41t80_rtc_exit);
|
|
||||||
|
|
|
@ -206,17 +206,7 @@ static struct spi_driver m41t93_driver = {
|
||||||
.remove = __devexit_p(m41t93_remove),
|
.remove = __devexit_p(m41t93_remove),
|
||||||
};
|
};
|
||||||
|
|
||||||
static __init int m41t93_init(void)
|
module_spi_driver(m41t93_driver);
|
||||||
{
|
|
||||||
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_AUTHOR("Nikolaus Voss <n.voss@weinmann.de>");
|
MODULE_AUTHOR("Nikolaus Voss <n.voss@weinmann.de>");
|
||||||
MODULE_DESCRIPTION("Driver for ST M41T93 SPI RTC");
|
MODULE_DESCRIPTION("Driver for ST M41T93 SPI RTC");
|
||||||
|
|
|
@ -153,19 +153,7 @@ static struct spi_driver m41t94_driver = {
|
||||||
.remove = __devexit_p(m41t94_remove),
|
.remove = __devexit_p(m41t94_remove),
|
||||||
};
|
};
|
||||||
|
|
||||||
static __init int m41t94_init(void)
|
module_spi_driver(m41t94_driver);
|
||||||
{
|
|
||||||
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_AUTHOR("Kim B. Heino <Kim.Heino@bluegiga.com>");
|
MODULE_AUTHOR("Kim B. Heino <Kim.Heino@bluegiga.com>");
|
||||||
MODULE_DESCRIPTION("Driver for ST M41T94 SPI RTC");
|
MODULE_DESCRIPTION("Driver for ST M41T94 SPI RTC");
|
||||||
|
|
|
@ -261,20 +261,9 @@ static struct i2c_driver max6900_driver = {
|
||||||
.id_table = max6900_id,
|
.id_table = max6900_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init max6900_init(void)
|
module_i2c_driver(max6900_driver);
|
||||||
{
|
|
||||||
return i2c_add_driver(&max6900_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit max6900_exit(void)
|
|
||||||
{
|
|
||||||
i2c_del_driver(&max6900_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
|
MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
|
||||||
MODULE_AUTHOR("Dale Farnsworth <dale@farnsworth.org>");
|
MODULE_AUTHOR("Dale Farnsworth <dale@farnsworth.org>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_VERSION(DRV_VERSION);
|
MODULE_VERSION(DRV_VERSION);
|
||||||
|
|
||||||
module_init(max6900_init);
|
|
||||||
module_exit(max6900_exit);
|
|
||||||
|
|
|
@ -160,17 +160,7 @@ static struct spi_driver max6902_driver = {
|
||||||
.remove = __devexit_p(max6902_remove),
|
.remove = __devexit_p(max6902_remove),
|
||||||
};
|
};
|
||||||
|
|
||||||
static __init int max6902_init(void)
|
module_spi_driver(max6902_driver);
|
||||||
{
|
|
||||||
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_DESCRIPTION ("max6902 spi RTC driver");
|
MODULE_DESCRIPTION ("max6902 spi RTC driver");
|
||||||
MODULE_AUTHOR ("Raphael Assenat");
|
MODULE_AUTHOR ("Raphael Assenat");
|
||||||
|
|
|
@ -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);
|
ret = max8925_reg_read(info->rtc, MAX8925_RTC_IRQ_MASK);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
if ((ret & ALARM0_IRQ) == 0)
|
if (ret & ALARM0_IRQ) {
|
||||||
alrm->enabled = 1;
|
|
||||||
else
|
|
||||||
alrm->enabled = 0;
|
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);
|
ret = max8925_reg_read(info->rtc, MAX8925_RTC_STATUS);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -204,6 +211,7 @@ static int max8925_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||||
alrm->pending = 1;
|
alrm->pending = 1;
|
||||||
else
|
else
|
||||||
alrm->pending = 0;
|
alrm->pending = 0;
|
||||||
|
return 0;
|
||||||
out:
|
out:
|
||||||
return ret;
|
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);
|
ret = max8925_bulk_write(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
/* only enable alarm on year/month/day/hour/min/sec */
|
if (alrm->enabled)
|
||||||
ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77);
|
/* 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)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -327,7 +327,7 @@ static int __devinit mpc5121_rtc_probe(struct platform_device *op)
|
||||||
dev_set_drvdata(&op->dev, rtc);
|
dev_set_drvdata(&op->dev, rtc);
|
||||||
|
|
||||||
rtc->irq = irq_of_parse_and_map(op->dev.of_node, 1);
|
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);
|
"mpc5121-rtc", &op->dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&op->dev, "%s: could not request irq: %i\n",
|
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);
|
rtc->irq_periodic = irq_of_parse_and_map(op->dev.of_node, 0);
|
||||||
err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd,
|
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) {
|
if (err) {
|
||||||
dev_err(&op->dev, "%s: could not request irq: %i\n",
|
dev_err(&op->dev, "%s: could not request irq: %i\n",
|
||||||
__func__, rtc->irq_periodic);
|
__func__, rtc->irq_periodic);
|
||||||
|
|
|
@ -366,7 +366,7 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
|
||||||
|
|
||||||
if (rtc_irq) {
|
if (rtc_irq) {
|
||||||
retval = request_irq(rtc_irq, mrst_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);
|
mrst_rtc.rtc);
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
dev_dbg(dev, "IRQ %d is already in use, err %d\n",
|
dev_dbg(dev, "IRQ %d is already in use, err %d\n",
|
||||||
|
|
|
@ -273,7 +273,7 @@ static int __devinit mv_rtc_probe(struct platform_device *pdev)
|
||||||
if (pdata->irq >= 0) {
|
if (pdata->irq >= 0) {
|
||||||
writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
|
writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
|
||||||
if (devm_request_irq(&pdev->dev, pdata->irq, mv_rtc_interrupt,
|
if (devm_request_irq(&pdev->dev, pdata->irq, mv_rtc_interrupt,
|
||||||
IRQF_DISABLED | IRQF_SHARED,
|
IRQF_SHARED,
|
||||||
pdev->name, pdata) < 0) {
|
pdev->name, pdata) < 0) {
|
||||||
dev_warn(&pdev->dev, "interrupt not available.\n");
|
dev_warn(&pdev->dev, "interrupt not available.\n");
|
||||||
pdata->irq = -1;
|
pdata->irq = -1;
|
||||||
|
|
|
@ -269,7 +269,7 @@ static int __devinit nuc900_rtc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
nuc900_rtc->irq_num = platform_get_irq(pdev, 0);
|
nuc900_rtc->irq_num = platform_get_irq(pdev, 0);
|
||||||
if (request_irq(nuc900_rtc->irq_num, nuc900_rtc_interrupt,
|
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");
|
dev_err(&pdev->dev, "NUC900 RTC request irq failed\n");
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
goto fail4;
|
goto fail4;
|
||||||
|
|
|
@ -348,14 +348,14 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
|
||||||
rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG);
|
rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG);
|
||||||
|
|
||||||
/* handle periodic and alarm irqs */
|
/* 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)) {
|
dev_name(&rtc->dev), rtc)) {
|
||||||
pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
|
pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
|
||||||
pdev->name, omap_rtc_timer);
|
pdev->name, omap_rtc_timer);
|
||||||
goto fail1;
|
goto fail1;
|
||||||
}
|
}
|
||||||
if ((omap_rtc_timer != omap_rtc_alarm) &&
|
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))) {
|
dev_name(&rtc->dev), rtc))) {
|
||||||
pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
|
pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
|
||||||
pdev->name, omap_rtc_alarm);
|
pdev->name, omap_rtc_alarm);
|
||||||
|
|
|
@ -346,20 +346,9 @@ static struct spi_driver pcf2123_driver = {
|
||||||
.remove = __devexit_p(pcf2123_remove),
|
.remove = __devexit_p(pcf2123_remove),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init pcf2123_init(void)
|
module_spi_driver(pcf2123_driver);
|
||||||
{
|
|
||||||
return spi_register_driver(&pcf2123_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit pcf2123_exit(void)
|
|
||||||
{
|
|
||||||
spi_unregister_driver(&pcf2123_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>");
|
MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>");
|
||||||
MODULE_DESCRIPTION("NXP PCF2123 RTC driver");
|
MODULE_DESCRIPTION("NXP PCF2123 RTC driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_VERSION(DRV_VERSION);
|
MODULE_VERSION(DRV_VERSION);
|
||||||
|
|
||||||
module_init(pcf2123_init);
|
|
||||||
module_exit(pcf2123_exit);
|
|
||||||
|
|
|
@ -252,20 +252,9 @@ static struct i2c_driver pcf8563_driver = {
|
||||||
.id_table = pcf8563_id,
|
.id_table = pcf8563_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init pcf8563_init(void)
|
module_i2c_driver(pcf8563_driver);
|
||||||
{
|
|
||||||
return i2c_add_driver(&pcf8563_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit pcf8563_exit(void)
|
|
||||||
{
|
|
||||||
i2c_del_driver(&pcf8563_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
|
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
|
||||||
MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver");
|
MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_VERSION(DRV_VERSION);
|
MODULE_VERSION(DRV_VERSION);
|
||||||
|
|
||||||
module_init(pcf8563_init);
|
|
||||||
module_exit(pcf8563_exit);
|
|
||||||
|
|
|
@ -320,18 +320,7 @@ static struct i2c_driver pcf8583_driver = {
|
||||||
.id_table = pcf8583_id,
|
.id_table = pcf8583_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static __init int pcf8583_init(void)
|
module_i2c_driver(pcf8583_driver);
|
||||||
{
|
|
||||||
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_AUTHOR("Russell King");
|
MODULE_AUTHOR("Russell King");
|
||||||
MODULE_DESCRIPTION("PCF8583 I2C RTC driver");
|
MODULE_DESCRIPTION("PCF8583 I2C RTC driver");
|
||||||
|
|
|
@ -123,7 +123,7 @@ static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
|
||||||
|
|
||||||
amba_set_drvdata(dev, rtc);
|
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);
|
"rtc-pl030", rtc);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_irq;
|
goto err_irq;
|
||||||
|
|
|
@ -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,
|
if (request_irq(adev->irq[0], pl031_interrupt,
|
||||||
IRQF_DISABLED, "rtc-pl031", ldata)) {
|
0, "rtc-pl031", ldata)) {
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
goto out_no_irq;
|
goto out_no_irq;
|
||||||
}
|
}
|
||||||
|
|
|
@ -520,7 +520,7 @@ static int pm8xxx_rtc_suspend(struct device *dev)
|
||||||
}
|
}
|
||||||
#endif
|
#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 = {
|
static struct platform_driver pm8xxx_rtc_driver = {
|
||||||
.probe = pm8xxx_rtc_probe,
|
.probe = pm8xxx_rtc_probe,
|
||||||
|
|
|
@ -174,14 +174,14 @@ static int pxa_rtc_open(struct device *dev)
|
||||||
struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev);
|
struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev);
|
||||||
int ret;
|
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);
|
"rtc 1Hz", dev);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_1Hz,
|
dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_1Hz,
|
||||||
ret);
|
ret);
|
||||||
goto err_irq_1Hz;
|
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);
|
"rtc Alrm", dev);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_Alrm,
|
dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_Alrm,
|
||||||
|
|
|
@ -159,17 +159,7 @@ static struct spi_driver r9701_driver = {
|
||||||
.remove = __devexit_p(r9701_remove),
|
.remove = __devexit_p(r9701_remove),
|
||||||
};
|
};
|
||||||
|
|
||||||
static __init int r9701_init(void)
|
module_spi_driver(r9701_driver);
|
||||||
{
|
|
||||||
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_DESCRIPTION("r9701 spi RTC driver");
|
MODULE_DESCRIPTION("r9701 spi RTC driver");
|
||||||
MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
|
MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
|
||||||
|
|
|
@ -235,18 +235,7 @@ static struct spi_driver rs5c348_driver = {
|
||||||
.remove = __devexit_p(rs5c348_remove),
|
.remove = __devexit_p(rs5c348_remove),
|
||||||
};
|
};
|
||||||
|
|
||||||
static __init int rs5c348_init(void)
|
module_spi_driver(rs5c348_driver);
|
||||||
{
|
|
||||||
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_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
|
MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
|
||||||
MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver");
|
MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver");
|
||||||
|
|
|
@ -689,18 +689,7 @@ static struct i2c_driver rs5c372_driver = {
|
||||||
.id_table = rs5c372_id,
|
.id_table = rs5c372_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static __init int rs5c372_init(void)
|
module_i2c_driver(rs5c372_driver);
|
||||||
{
|
|
||||||
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_AUTHOR(
|
MODULE_AUTHOR(
|
||||||
"Pavel Mironchik <pmironchik@optifacio.net>, "
|
"Pavel Mironchik <pmironchik@optifacio.net>, "
|
||||||
|
|
|
@ -436,18 +436,7 @@ static struct i2c_driver rv3029c2_driver = {
|
||||||
.id_table = rv3029c2_id,
|
.id_table = rv3029c2_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init rv3029c2_init(void)
|
module_i2c_driver(rv3029c2_driver);
|
||||||
{
|
|
||||||
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_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");
|
MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");
|
||||||
MODULE_DESCRIPTION("Micro Crystal RV3029C2 RTC driver");
|
MODULE_DESCRIPTION("Micro Crystal RV3029C2 RTC driver");
|
||||||
|
|
|
@ -644,19 +644,8 @@ static struct i2c_driver rx8025_driver = {
|
||||||
.id_table = rx8025_id,
|
.id_table = rx8025_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init rx8025_init(void)
|
module_i2c_driver(rx8025_driver);
|
||||||
{
|
|
||||||
return i2c_add_driver(&rx8025_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit rx8025_exit(void)
|
|
||||||
{
|
|
||||||
i2c_del_driver(&rx8025_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
|
MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
|
||||||
MODULE_DESCRIPTION("RX-8025 SA/NB RTC driver");
|
MODULE_DESCRIPTION("RX-8025 SA/NB RTC driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
module_init(rx8025_init);
|
|
||||||
module_exit(rx8025_exit);
|
|
||||||
|
|
|
@ -276,20 +276,9 @@ static struct i2c_driver rx8581_driver = {
|
||||||
.id_table = rx8581_id,
|
.id_table = rx8581_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init rx8581_init(void)
|
module_i2c_driver(rx8581_driver);
|
||||||
{
|
|
||||||
return i2c_add_driver(&rx8581_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit rx8581_exit(void)
|
|
||||||
{
|
|
||||||
i2c_del_driver(&rx8581_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
|
MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
|
||||||
MODULE_DESCRIPTION("Epson RX-8581 RTC driver");
|
MODULE_DESCRIPTION("Epson RX-8581 RTC driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_VERSION(DRV_VERSION);
|
MODULE_VERSION(DRV_VERSION);
|
||||||
|
|
||||||
module_init(rx8581_init);
|
|
||||||
module_exit(rx8581_exit);
|
|
||||||
|
|
|
@ -304,19 +304,8 @@ static struct i2c_driver s35390a_driver = {
|
||||||
.id_table = s35390a_id,
|
.id_table = s35390a_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init s35390a_rtc_init(void)
|
module_i2c_driver(s35390a_driver);
|
||||||
{
|
|
||||||
return i2c_add_driver(&s35390a_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit s35390a_rtc_exit(void)
|
|
||||||
{
|
|
||||||
i2c_del_driver(&s35390a_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Byron Bradley <byron.bbradley@gmail.com>");
|
MODULE_AUTHOR("Byron Bradley <byron.bbradley@gmail.com>");
|
||||||
MODULE_DESCRIPTION("S35390A RTC driver");
|
MODULE_DESCRIPTION("S35390A RTC driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
module_init(s35390a_rtc_init);
|
|
||||||
module_exit(s35390a_rtc_exit);
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue